Skip to content
This repository has been archived by the owner on Jun 14, 2018. It is now read-only.

Commit

Permalink
molesrv -init-store
Browse files Browse the repository at this point in the history
  • Loading branch information
calmh committed Dec 7, 2013
1 parent 5ef2542 commit 3c01d81
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 22 deletions.
14 changes: 13 additions & 1 deletion cmd/molesrv/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"os/exec"
)

func commit(dir, comment, user string) {
func gitCommit(dir, comment, user string) {
var cmd *exec.Cmd

cmd = exec.Command("git", "add", "-A")
Expand All @@ -26,3 +26,15 @@ func commit(dir, comment, user string) {
return
}
}

func gitInit(dir string) {
var cmd *exec.Cmd

cmd = exec.Command("git", "init")
cmd.Dir = dir
_, err := cmd.CombinedOutput()
if err != nil {
log.Println("git:", err)
return
}
}
2 changes: 1 addition & 1 deletion cmd/molesrv/hndl-store-file-put.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@ func putFile(rw http.ResponseWriter, req *http.Request) {
// Commit
dir := path.Join(storeDir, "data")
user := req.Header.Get("X-Mole-Authenticated")
commit(dir, "push "+tun, user)
gitCommit(dir, "push "+tun, user)
}
}
2 changes: 1 addition & 1 deletion cmd/molesrv/hndl-store-file-rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ func rmFile(rw http.ResponseWriter, req *http.Request) {
// Commit
dir := path.Join(storeDir, "data")
user := req.Header.Get("X-Mole-Authenticated")
commit(dir, "rm "+tun, user)
gitCommit(dir, "rm "+tun, user)
}
}
140 changes: 121 additions & 19 deletions cmd/molesrv/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package main

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"flag"
"io/ioutil"
"log"
"math/big"
"net/http"
"os"
"path"
Expand All @@ -25,16 +32,17 @@ var (
handlers = map[string][]handler{}

// CLI options
listenAddr = ":9443"
storeDir = "~/mole-store"
certFile = "cert.pem"
keyFile = "key.pem"
auditFile = "audit.log"
auditIntv = 86400 * time.Second
auth = "none"
readOnly = false
disableGit = false
canonicalHostname = ""
certFile = "cert.pem"
disableGit = false
initStore = false
keyFile = "key.pem"
listenAddr = ":9443"
readOnly = false
storeDir = "~/mole-store"
ticketKeyFile = ""
)

Expand All @@ -44,18 +52,19 @@ var globalFlags = flag.NewFlagSet("molesrv", flag.ExitOnError)

func init() {
globalFlags.Usage = usageFor(globalFlags, "molesrv [options]")
globalFlags.StringVar(&listenAddr, "listen", listenAddr, "HTTPS listen address")
globalFlags.StringVar(&storeDir, "store-dir", storeDir, "Mole store directory")
globalFlags.StringVar(&certFile, "cert-file", certFile, "Certificate file (relative to store directory)")
globalFlags.StringVar(&keyFile, "key-file", keyFile, "Key file (relative to store directory)")
globalFlags.StringVar(&auditFile, "audit-file", auditFile, "Audit file (relative to store directory)")
globalFlags.DurationVar(&auditIntv, "audit-intv", auditIntv, "Audit file creation interval")
globalFlags.StringVar(&auth, "auth", auth, "Authentication backend")
globalFlags.BoolVar(&readOnly, "no-write", readOnly, "Disallow writable client operations (push, rm, etc)")
globalFlags.BoolVar(&disableGit, "no-git", disableGit, "Do not treat the store as a git repository")
globalFlags.StringVar(&canonicalHostname, "canonical-hostname", canonicalHostname, "Server hostname to advertise as canonical")
globalFlags.StringVar(&buildVersion, "version", buildVersion, "Version string to advertise")
globalFlags.StringVar(&certFile, "cert-file", certFile, "Certificate file (relative to store directory)")
globalFlags.BoolVar(&initStore, "init-store", initStore, "Initialize store directory and certificates")
globalFlags.StringVar(&keyFile, "key-file", keyFile, "Key file (relative to store directory)")
globalFlags.StringVar(&listenAddr, "listen", listenAddr, "HTTPS listen address")
globalFlags.BoolVar(&disableGit, "no-git", disableGit, "Do not treat the store as a git repository")
globalFlags.BoolVar(&readOnly, "no-write", readOnly, "Disallow writable client operations (push, rm, etc)")
globalFlags.StringVar(&storeDir, "store-dir", storeDir, "Mole store directory")
globalFlags.StringVar(&ticketKeyFile, "ticket-file", ticketKeyFile, "Ticket key file. Leave blank to autogenerate key on startup.")
globalFlags.StringVar(&buildVersion, "version", buildVersion, "Version string to advertise")
}

func addHandler(hnd handler) {
Expand All @@ -68,6 +77,62 @@ func main() {
log.Fatalf("Unrecognized extra arguments: %q", strings.Join(globalFlags.Args(), " "))
}

if strings.HasPrefix(storeDir, "~/") {
home := getHomeDir()
storeDir = strings.Replace(storeDir, "~", home, 1)
}

if initStore {
dataDir := path.Join(storeDir, "data")
err := os.MkdirAll(dataDir, 0700)
if err != nil {
log.Fatal(err)
}

keys = make(map[string]string)
err = saveKeys()
if err != nil {
log.Fatal(err)
}

newCertificate()

if !disableGit {
gitInit(dataDir)
gitCommit(dataDir, "Initial", "server")
}

extraDir := path.Join(storeDir, "extra")
err = os.MkdirAll(extraDir, 0700)
if err != nil {
log.Fatal(err)
}

err = ioutil.WriteFile(path.Join(extraDir, "upgrades.json"), []byte("{}"), 0644)
if err != nil {
log.Fatal(err)
}

err = ioutil.WriteFile(path.Join(extraDir, "packages.json"), []byte("{}"), 0644)
if err != nil {
log.Fatal(err)
}

err = ioutil.WriteFile(path.Join(extraDir, "packages.json.example"), []byte(`{
"darwin-amd64": [
{"package":"tun", "description":"Tunnel driver (required by vpnc, openconnect)"},
{"package":"openconnect", "description":"OpenConnect client support"},
{"package":"vpnc", "description":"VPNC client support"}
]
}`), 0644)
if err != nil {
log.Fatal(err)
}

log.Println("OK: Initialized store directory", storeDir)
return
}

if _, ok := authBackends[auth]; !ok {
log.Fatalf("Unknown auth backend %q", auth)
}
Expand All @@ -78,14 +143,9 @@ func main() {

log.Println("mole server", buildVersion)

if strings.HasPrefix(storeDir, "~/") {
home := getHomeDir()
storeDir = strings.Replace(storeDir, "~", home, 1)
}

err := loadKeys()
if err != nil {
log.Println("Warning: ", err)
log.Println("Warning:", err)
}
if keys == nil {
keys = make(map[string]string)
Expand Down Expand Up @@ -154,3 +214,45 @@ func getHomeDir() string {
}
return home
}

func newCertificate() {
priv, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
log.Fatal(err)
}

notBefore := time.Now()
notAfter := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC)

template := x509.Certificate{
SerialNumber: new(big.Int).SetInt64(0),
Subject: pkix.Name{
CommonName: "mole",
},
NotBefore: notBefore,
NotAfter: notAfter,

KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}

derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
log.Fatal(err)
}

certOut, err := os.Create(path.Join(storeDir, certFile))
if err != nil {
log.Fatal(err)
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()

keyOut, err := os.OpenFile(path.Join(storeDir, keyFile), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatal(err)
}
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
keyOut.Close()
}

0 comments on commit 3c01d81

Please sign in to comment.