auth: config for a non dev mode,

self gen tls certs, force https in non dev

Change-Id: I7faa6b35f44a7925b06d22ade7f5986a12728362
This commit is contained in:
mpl 2011-11-10 16:20:22 +01:00
parent edf4da987e
commit e233c981e0
4 changed files with 351 additions and 5 deletions

View File

@ -1,6 +1,7 @@
{ "_for-emacs": "-*- mode: js2;-*-", { "_for-emacs": "-*- mode: js2;-*-",
"baseURL": ["_env", "${CAMLI_BASEURL}"], "baseURL": ["_env", "${CAMLI_BASEURL}"],
"password": ["_env", "${CAMLI_PASSWORD}"], "password": ["_env", "${CAMLI_PASSWORD}"],
"httpsOnly": false,
"prefixes": { "prefixes": {
"/": { "/": {
"handler": "root", "handler": "root",

179
config/server-config.json Normal file
View File

@ -0,0 +1,179 @@
{ "_for-emacs": "-*- mode: js2;-*-",
"baseURL": ["_env", "${CAMLI_BASEURL}"],
"password": ["_env", "${CAMLI_PASSWORD}"],
"httpsOnly": true,
"TLSCertFile": "config/selfgen_cert.pem",
"TLSKeyFile": "config/selfgen_key.pem",
"prefixes": {
"/": {
"handler": "root",
"handlerArgs": {
"stealth": false
}
},
"/blog/": {
"handler": "publish",
"handlerArgs": {
"rootName": "dev-blog-root",
"blobRoot": "/bs/",
"searchRoot": "/my-search/",
"cache": "/cache/",
"devBootstrapPermanodeUsing": "/sighelper/"
}
},
"/pics/": {
"handler": "publish",
"handlerArgs": {
"rootName": "dev-pics-root",
"blobRoot": "/bs/",
"searchRoot": "/my-search/",
"cache": "/cache/",
"scaledImage": "lrucache",
"css": ["pics.css"],
"js": ["camli.js", "pics.js"],
"devBootstrapPermanodeUsing": "/sighelper/"
}
},
"/stub-test-disable/": {
"handler": "publish",
"enabled": false,
"handlerArgs": {
}
},
"/ui/": {
"handler": "ui",
"handlerArgs": {
"blobRoot": "/bs-and-maybe-also-index/",
"searchRoot": "/my-search/",
"jsonSignRoot": "/sighelper/",
"cache": "/cache/",
"scaledImage": "lrucache",
"publishRoots": ["/blog/", "/pics/"]
}
},
"/sync/": {
"handler": "sync",
"handlerArgs": {
"from": "/bs/",
"to": "/indexer/"
}
},
"/sighelper/": {
"handler": "jsonsign",
"handlerArgs": {
"secretRing": ["_env", "${CAMLI_SECRET_RING}"],
"keyId": "26F5ABDA",
"publicKeyDest": "/bs/"
}
},
"/bs-and-index/": {
"handler": "storage-replica",
"handlerArgs": {
"backends": ["/bs/", "/indexer/"]
}
},
"/bs-and-maybe-also-index/": {
"handler": "storage-cond",
"handlerArgs": {
"write": {
"if": "isSchema",
"then": "/bs-and-index/",
"else": "/bs/"
},
"read": "/bs/"
}
},
"/bs/": {
"handler": "storage-filesystem",
"handlerArgs": {
"path": ["_env", "${CAMLI_ROOT}"]
}
},
"/cache/": {
"handler": "storage-filesystem",
"handlerArgs": {
"path": ["_env", "${CAMLI_ROOT_CACHE}"]
}
},
"/sharder/": {
"handler": "storage-shard",
"handlerArgs": {
"backends": ["/s1/", "/s2/"]
}
},
"/s1/": {
"handler": "storage-filesystem",
"handlerArgs": {
"path": ["_env", "${CAMLI_ROOT_SHARD1}"]
}
},
"/s2/": {
"handler": "storage-filesystem",
"handlerArgs": {
"path": ["_env", "${CAMLI_ROOT_SHARD2}"]
}
},
"/repl/": {
"handler": "storage-replica",
"handlerArgs": {
"backends": ["/r1/", "/r2/", "/r3/"],
"minWritesForSuccess": 2
}
},
"/r1/": {
"handler": "storage-filesystem",
"handlerArgs": {
"path": ["_env", "${CAMLI_ROOT_REPLICA1}"]
}
},
"/r2/": {
"handler": "storage-filesystem",
"handlerArgs": {
"path": ["_env", "${CAMLI_ROOT_REPLICA2}"]
}
},
"/r3/": {
"handler": "storage-filesystem",
"handlerArgs": {
"path": ["_env", "${CAMLI_ROOT_REPLICA3}"]
}
},
"/indexer/": {
"handler": "storage-mysqlindexer",
"handlerArgs": {
"database": ["_env", "${CAMLI_DBNAME}"],
"user": "root",
"password": "root",
"host": "127.0.0.1",
"blobSource": "/bs/"
}
},
"/my-search/": {
"handler": "search",
"handlerArgs": {
"index": "/indexer/",
"owner": "sha1-ad87ca5c78bd0ce1195c46f7c98e6025abbaf007"
}
}
}
}

View File

@ -17,11 +17,18 @@ limitations under the License.
package main package main
import ( import (
"big"
"crypto/x509/pkix"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"flag" "flag"
"fmt" "fmt"
"log" "log"
"runtime" "runtime"
"strings" "strings"
"time"
"os" "os"
"path/filepath" "path/filepath"
@ -42,6 +49,9 @@ import (
_ "camli/server" // UI, publish, etc _ "camli/server" // UI, publish, etc
) )
const defCert = "config/selfgen_cert.pem"
const defKey = "config/selfgen_key.pem"
var flagConfigFile = flag.String("configfile", "serverconfig", var flagConfigFile = flag.String("configfile", "serverconfig",
"Config file to use, relative to camli config dir root, or blank to not use config files.") "Config file to use, relative to camli config dir root, or blank to not use config files.")
@ -53,6 +63,60 @@ func exitFailure(pattern string, args ...interface{}) {
os.Exit(1) os.Exit(1)
} }
// Mostly copied from $GOROOT/src/pkg/crypto/tls/generate_cert.go
func genSelfTLS() os.Error {
priv, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
return fmt.Errorf("failed to generate private key: %s", err)
}
now := time.Seconds()
baseurl := os.Getenv("CAMLI_BASEURL")
if baseurl == "" {
return fmt.Errorf("CAMLI_BASEURL is not set")
}
split := strings.Split(baseurl, ":")
hostname := split[1]
hostname = hostname[2:len(hostname)]
println(hostname)
template := x509.Certificate{
SerialNumber: new(big.Int).SetInt64(0),
Subject: pkix.Name{
CommonName: hostname,
Organization: []string{hostname},
},
NotBefore: time.SecondsToUTC(now - 300),
NotAfter: time.SecondsToUTC(now + 60*60*24*365), // valid for 1 year.
SubjectKeyId: []byte{1, 2, 3, 4},
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
return fmt.Errorf("Failed to create certificate: %s", err)
}
certOut, err := os.Create(defCert)
if err != nil {
return fmt.Errorf("failed to open %s for writing: %s", defCert, err)
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
log.Printf("written %s\n", defCert)
keyOut, err := os.OpenFile(defKey, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return fmt.Errorf("failed to open %s for writing:", defKey, err)
}
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
keyOut.Close()
log.Printf("written %s\n", defKey)
return nil
}
func main() { func main() {
flag.Parse() flag.Parse()
@ -69,11 +133,21 @@ func main() {
baseURL := ws.BaseURL() baseURL := ws.BaseURL()
{ {
cert, key := config.OptionalString("TLSCertFile", ""), config.OptionalString("TLSKeyFile", "") secure := config.OptionalBool("httpsOnly", true)
if (cert != "") != (key != "") { if secure {
exitFailure("TLSCertFile and TLSKeyFile must both be either present or absent") cert, key := config.OptionalString("TLSCertFile", ""), config.OptionalString("TLSKeyFile", "")
} if (cert != "") != (key != "") {
if cert != "" { exitFailure("TLSCertFile and TLSKeyFile must both be either present or absent")
}
if cert == "" && key == "" {
err = genSelfTLS()
if err != nil {
exitFailure("pb generating the self signed creds: %q", err)
}
cert = defCert
key = defKey
}
ws.SetTLS(cert, key) ws.SetTLS(cert, key)
} }
} }

92
start-server Executable file
View File

@ -0,0 +1,92 @@
#!/usr/bin/perl
use strict;
use FindBin qw($Bin);
use Getopt::Long;
sub usage {
die "Usage: server [--wipe] <portnumber> -- [other_blobserver_opts]";
}
my $opt_wipe;
my $opt_nobuild;
my $opt_all; # listen on all interfaces
GetOptions("wipe" => \$opt_wipe,
"all" => \$opt_all,
"nobuild" => \$opt_nobuild,
)
or usage();
my $port = shift;
$port = "3179" unless defined($port);
usage() unless $port =~ /^\d+$/;
unless ($opt_nobuild) {
system("./build.pl", "server/go/camlistored") and die "Failed to build camlistored";
system("./build.pl", "clients/go/camdbinit") and die "Failed to build camdbinit";
}
my $root = "/tmp/camliroot-$ENV{USER}/port$port/";
if ($opt_wipe && -d $root) {
print "Wiping $root\n";
system("rm", "-rf", $root) and die "Failed to wipe $root.\n";
}
my $suffixdir = sub {
my $suffix = shift;
my $root = "$root/$suffix";
unless (-d $root) {
system("mkdir", "-p", $root) and die "Failed to create $root.\n";
}
return $root;
};
my $DBNAME = "devcamli$ENV{USER}";
my @opts;
if ($opt_wipe) {
push @opts, "-wipe";
} else {
push @opts, "-ignoreexists";
}
system("./clients/go/camdbinit/camdbinit",
"-user=root",
"-password=root",
"-host=localhost",
"-database=$DBNAME",
@opts) and die "Failed to run camdbinit.\n";
my $base = "https://localhost:$port";
my $listen = "127.0.0.1:$port";
if ($opt_all) {
$listen = "0.0.0.0:$port";
my $host = `hostname`;
chomp $host;
$base = "https://$host:$port";
}
print "Starting dev server on $base/ui/ with password \"pass$port\"\n";
$ENV{CAMLI_BASEURL} = $base;
$ENV{CAMLI_PASSWORD} = "pass$port";
# do we simply set that one to empty in non dev, or do we deal with it in auth/auth.go ?
$ENV{CAMLI_ADVERTISED_PASSWORD} = ""; # public password
$ENV{CAMLI_ROOT} = $suffixdir->("bs");
$ENV{CAMLI_ROOT_SHARD1} = $suffixdir->("s1");
$ENV{CAMLI_ROOT_SHARD2} = $suffixdir->("s2");
$ENV{CAMLI_ROOT_REPLICA1} = $suffixdir->("r1");
$ENV{CAMLI_ROOT_REPLICA2} = $suffixdir->("r2");
$ENV{CAMLI_ROOT_REPLICA3} = $suffixdir->("r3");
$ENV{CAMLI_ROOT_CACHE} = $suffixdir->("cache");
$ENV{CAMLI_PORT} = $port;
$ENV{CAMLI_SECRET_RING} = "$Bin/lib/go/camli/jsonsign/testdata/test-secring.gpg";
$ENV{CAMLI_DBNAME} = $DBNAME;
# To use resources from disk, instead of the copies linked into the
# binary:
$ENV{CAMLI_DEV_UI_FILES} = "$FindBin::Bin/server/go/camlistored/ui"; # set in server/go/camlistored/ui/fileembed.go
exec("$FindBin::Bin/server/go/camlistored/camlistored",
"-configfile=$Bin/config/server-config.json",
"-listen=$listen",
@ARGV);