aboutsummaryrefslogtreecommitdiff
path: root/cmd/acme/config.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2015-12-17 15:50:01 +0100
committerDimitri Sokolyuk <demon@dim13.org>2015-12-17 15:50:01 +0100
commite180142d73a37fcce5b4857ddef6e713f7ae2492 (patch)
tree1753a40cb46d71c656bb98e503cfcddc64a0c3d0 /cmd/acme/config.go
parent3e1a89a27dcd7847e80dd717bbed8360b322240c (diff)
Rename files
Diffstat (limited to 'cmd/acme/config.go')
-rw-r--r--cmd/acme/config.go154
1 files changed, 154 insertions, 0 deletions
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
+}