From e180142d73a37fcce5b4857ddef6e713f7ae2492 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 17 Dec 2015 15:50:01 +0100 Subject: Rename files --- cmd/acme/config.go | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/acme/main.go | 112 +++++++++++++++++++++++++++++--------- cmd/acmed/config.go | 154 ---------------------------------------------------- cmd/acmed/main.go | 107 ------------------------------------ 4 files changed, 240 insertions(+), 287 deletions(-) create mode 100644 cmd/acme/config.go delete mode 100644 cmd/acmed/config.go delete mode 100644 cmd/acmed/main.go (limited to 'cmd') diff --git a/cmd/acme/config.go b/cmd/acme/config.go new file mode 100644 index 0000000..7f5ffbe --- /dev/null +++ b/cmd/acme/config.go @@ -0,0 +1,154 @@ +package main + +import ( + "crypto/rsa" + "errors" + "path" + "strings" + "time" + + "github.com/BurntSushi/toml" +) + +type Config struct { + Defaults defaults + Provider map[string]*provider + Account map[string]*account + Hook map[string]*hook + Desire map[string]*desire +} + +type defaults struct { + Gracetime duration + Listen string + Provider string + Account string + Basedir string + KeySize int +} + +type provider struct { + Directory string +} + +type account struct { + Mail string + Phone string + Key string + KeySize int + key *rsa.PrivateKey +} + +type hook struct { + CMD string +} + +type desire struct { + Provider string + Account string + Altnames []string + Key string + KeySize int + Cert string + Webroot string + Hooks []string + key *rsa.PrivateKey `toml:"-"` + account *account + provider *provider +} + +var ( + errNoProvider = errors.New("no provider specified") + errNoAccount = errors.New("no account specified") + errNoKey = errors.New("no key specified") + errNoCert = errors.New("no cert specified") + errNoAltNames = errors.New("no altnames specified") + errNoMail = errors.New("no mail specified") +) + +func LoadConfig(fname string) (*Config, error) { + c := &Config{} + _, err := toml.DecodeFile(fname, c) + if err != nil { + return nil, err + } + // apply defaults + if c.Defaults.KeySize == 0 { + c.Defaults.KeySize = 2048 + } + for k, v := range c.Account { + if v.KeySize == 0 { + v.KeySize = c.Defaults.KeySize + } + if v.Mail == "" { + return nil, errNoMail + } + if v.Key == "" { + return nil, errNoKey + } + if c.Defaults.Basedir != "" { + v.Key = path.Join(c.Defaults.Basedir, v.Key) + } + c.Account[k] = v + } + for k, v := range c.Desire { + if v.Provider == "" { + if c.Defaults.Provider != "" { + v.Provider = c.Defaults.Provider + } else { + return nil, errNoProvider + } + } + v.provider = c.Provider[v.Provider] + if v.Account == "" { + if c.Defaults.Account != "" { + v.Account = c.Defaults.Account + } else { + return nil, errNoAccount + } + } + v.account = c.Account[v.Account] + if v.KeySize == 0 { + v.KeySize = c.Defaults.KeySize + } + if v.Key == "" { + return nil, errNoKey + } + if v.Cert == "" { + return nil, errNoCert + } + if c.Defaults.Basedir != "" { + v.Key = path.Join(c.Defaults.Basedir, v.Key) + v.Cert = path.Join(c.Defaults.Basedir, v.Cert) + } + switch len(v.Altnames) { + case 0: + return nil, errNoAltNames + case 1: + an := v.Altnames[0] + if strings.HasPrefix(an, "www.") { + v.Altnames = append(v.Altnames, an[4:]) + } + } + c.Desire[k] = v + } + return c, nil +} + +type PrivKey interface { + Path() string + Size() int +} + +func (d desire) Path() string { return d.Key } +func (d desire) Size() int { return d.KeySize } +func (a account) Path() string { return a.Key } +func (a account) Size() int { return a.KeySize } + +type duration struct{ time.Duration } + +func (d *duration) UnmarshalText(s []byte) error { + var err error + d.Duration, err = time.ParseDuration(string(s)) + return err +} diff --git a/cmd/acme/main.go b/cmd/acme/main.go index c9faa85..058eefb 100644 --- a/cmd/acme/main.go +++ b/cmd/acme/main.go @@ -1,47 +1,107 @@ package main import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" "flag" + "io" + "io/ioutil" "log" + "os" + "path" "dim13.org/acme" ) -func must(err error) { +var confName = flag.String("conf", "acme.toml", "configuration file") + +func newKey(w io.Writer, size int) (*rsa.PrivateKey, error) { + key, err := rsa.GenerateKey(rand.Reader, size) if err != nil { - log.Fatal("must:", err) + return nil, err + } + block := &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(key), } + return key, pem.Encode(w, block) } -var ( - config = flag.String("config", "acme.toml", "configuration file") - port = flag.Int("port", 8443, "port to listen") -) +func chkKey(k PrivKey) (*rsa.PrivateKey, error) { + key := k.Path() + if _, err := os.Stat(key); os.IsNotExist(err) { + log.Println("allocating", key, k.Size()) + if err := os.MkdirAll(path.Dir(key), 0700); err != nil { + return nil, err + } + flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC + fd, err := os.OpenFile(key, flags, 0600) + if err != nil { + return nil, err + } + defer fd.Close() + return newKey(fd, k.Size()) + } else { + der, err := ioutil.ReadFile(key) + if err != nil { + return nil, err + } + block, _ := pem.Decode(der) + return x509.ParsePKCS1PrivateKey(block.Bytes) + } +} -func init() { - flag.Parse() +func chkKeys(c *Config) error { + var err error + for k, acc := range c.Account { + acc.key, err = chkKey(acc) + if err != nil { + return err + } + c.Account[k] = acc + } + for k, des := range c.Desire { + des.key, err = chkKey(des) + if err != nil { + return err + } + c.Desire[k] = des + } + return nil } func main() { - conf, err := acme.LoadConfig(*config) - must(err) - log.Printf("%+v\n", conf) - - for _, v := range conf.Desire { - acc := conf.Account[v.Account] - prov := conf.Provider[v.Provider] - a, err := acme.NewAccount(acc.Mail, acme.KeySize) - must(err) - - c, err := acme.NewClient(prov.Directory) - must(err) + flag.Parse() + conf, err := LoadConfig(*confName) + if err != nil { + log.Fatal(err) + } + err = chkKeys(conf) + if err != nil { + log.Fatal(err) + } - re, err := c.Register(a) - must(err) - log.Printf("%+v\n", re) + log.Println(conf) + for k, des := range conf.Desire { + log.Println(k, des.account) + } + return - re, err = c.Agree(a) - must(err) - log.Printf("%+v\n", re) + for k, des := range conf.Desire { + a, _ := acme.NewAccount(des.account.Mail, des.account.Phone, des.account.key) + log.Println(k, a) + c, err := acme.NewClient(des.provider.Directory) + if err != nil { + log.Println(err) + } + log.Println(k, c) + az, err := c.Authorize(a, des.Altnames[0]) + if err != nil { + log.Println(err) + } + log.Println(k, az) } + } diff --git a/cmd/acmed/config.go b/cmd/acmed/config.go deleted file mode 100644 index 7f5ffbe..0000000 --- a/cmd/acmed/config.go +++ /dev/null @@ -1,154 +0,0 @@ -package main - -import ( - "crypto/rsa" - "errors" - "path" - "strings" - "time" - - "github.com/BurntSushi/toml" -) - -type Config struct { - Defaults defaults - Provider map[string]*provider - Account map[string]*account - Hook map[string]*hook - Desire map[string]*desire -} - -type defaults struct { - Gracetime duration - Listen string - Provider string - Account string - Basedir string - KeySize int -} - -type provider struct { - Directory string -} - -type account struct { - Mail string - Phone string - Key string - KeySize int - key *rsa.PrivateKey -} - -type hook struct { - CMD string -} - -type desire struct { - Provider string - Account string - Altnames []string - Key string - KeySize int - Cert string - Webroot string - Hooks []string - key *rsa.PrivateKey `toml:"-"` - account *account - provider *provider -} - -var ( - errNoProvider = errors.New("no provider specified") - errNoAccount = errors.New("no account specified") - errNoKey = errors.New("no key specified") - errNoCert = errors.New("no cert specified") - errNoAltNames = errors.New("no altnames specified") - errNoMail = errors.New("no mail specified") -) - -func LoadConfig(fname string) (*Config, error) { - c := &Config{} - _, err := toml.DecodeFile(fname, c) - if err != nil { - return nil, err - } - // apply defaults - if c.Defaults.KeySize == 0 { - c.Defaults.KeySize = 2048 - } - for k, v := range c.Account { - if v.KeySize == 0 { - v.KeySize = c.Defaults.KeySize - } - if v.Mail == "" { - return nil, errNoMail - } - if v.Key == "" { - return nil, errNoKey - } - if c.Defaults.Basedir != "" { - v.Key = path.Join(c.Defaults.Basedir, v.Key) - } - c.Account[k] = v - } - for k, v := range c.Desire { - if v.Provider == "" { - if c.Defaults.Provider != "" { - v.Provider = c.Defaults.Provider - } else { - return nil, errNoProvider - } - } - v.provider = c.Provider[v.Provider] - if v.Account == "" { - if c.Defaults.Account != "" { - v.Account = c.Defaults.Account - } else { - return nil, errNoAccount - } - } - v.account = c.Account[v.Account] - if v.KeySize == 0 { - v.KeySize = c.Defaults.KeySize - } - if v.Key == "" { - return nil, errNoKey - } - if v.Cert == "" { - return nil, errNoCert - } - if c.Defaults.Basedir != "" { - v.Key = path.Join(c.Defaults.Basedir, v.Key) - v.Cert = path.Join(c.Defaults.Basedir, v.Cert) - } - switch len(v.Altnames) { - case 0: - return nil, errNoAltNames - case 1: - an := v.Altnames[0] - if strings.HasPrefix(an, "www.") { - v.Altnames = append(v.Altnames, an[4:]) - } - } - c.Desire[k] = v - } - return c, nil -} - -type PrivKey interface { - Path() string - Size() int -} - -func (d desire) Path() string { return d.Key } -func (d desire) Size() int { return d.KeySize } -func (a account) Path() string { return a.Key } -func (a account) Size() int { return a.KeySize } - -type duration struct{ time.Duration } - -func (d *duration) UnmarshalText(s []byte) error { - var err error - d.Duration, err = time.ParseDuration(string(s)) - return err -} diff --git a/cmd/acmed/main.go b/cmd/acmed/main.go deleted file mode 100644 index 08a62f3..0000000 --- a/cmd/acmed/main.go +++ /dev/null @@ -1,107 +0,0 @@ -package main - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "flag" - "io" - "io/ioutil" - "log" - "os" - "path" - - "dim13.org/acme" -) - -var confName = flag.String("conf", "acme.toml", "configuration file") - -func newKey(w io.Writer, size int) (*rsa.PrivateKey, error) { - key, err := rsa.GenerateKey(rand.Reader, size) - if err != nil { - return nil, err - } - block := &pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(key), - } - return key, pem.Encode(w, block) -} - -func chkKey(k PrivKey) (*rsa.PrivateKey, error) { - key := k.Path() - flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC - if _, err := os.Stat(key); os.IsNotExist(err) { - log.Println("allocating", key, k.Size()) - if err := os.MkdirAll(path.Dir(key), 0700); err != nil { - return nil, err - } - fd, err := os.OpenFile(key, flags, 0600) - if err != nil { - return nil, err - } - defer fd.Close() - return newKey(fd, k.Size()) - } else { - der, err := ioutil.ReadFile(key) - if err != nil { - return nil, err - } - block, _ := pem.Decode(der) - return x509.ParsePKCS1PrivateKey(block.Bytes) - } -} - -func chkKeys(c *Config) error { - var err error - for k, acc := range c.Account { - acc.key, err = chkKey(acc) - if err != nil { - return err - } - c.Account[k] = acc - } - for k, des := range c.Desire { - des.key, err = chkKey(des) - if err != nil { - return err - } - c.Desire[k] = des - } - return nil -} - -func main() { - flag.Parse() - conf, err := LoadConfig(*confName) - if err != nil { - log.Fatal(err) - } - err = chkKeys(conf) - if err != nil { - log.Fatal(err) - } - - log.Println(conf) - for k, des := range conf.Desire { - log.Println(k, des.account) - } - return - - for k, des := range conf.Desire { - a, _ := acme.NewAccount(des.account.Mail, des.account.Phone, des.account.key) - log.Println(k, a) - c, err := acme.NewClient(des.provider.Directory) - if err != nil { - log.Println(err) - } - log.Println(k, c) - az, err := c.Authorize(a, des.Altnames[0]) - if err != nil { - log.Println(err) - } - log.Println(k, az) - } - -} -- cgit v1.2.3