-
Notifications
You must be signed in to change notification settings - Fork 0
/
update.go
156 lines (141 loc) · 3.7 KB
/
update.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package updater
import (
"crypto/x509"
"encoding/json"
"encoding/pem"
"fmt"
"github.com/COSAE-FR/ripradius/pkg/freeradius"
"github.com/COSAE-FR/ripradius/pkg/updater/binding"
"github.com/COSAE-FR/riputils/common"
"io/ioutil"
"os"
"path/filepath"
)
func (s *Server) update() {
}
func (s *Server) fetchUpdate() {
}
func (s *Server) applyUpdate() error {
cert, err := s.getRemoteCertificate()
if err != nil {
cert, err = s.getLocalCertificate()
if err != nil {
return err
}
} else {
if err := s.writeCache(*cert); err != nil {
s.log.Errorf("cannot write new certificates to cache: %s", err)
}
}
cfg := *s.config.Radius
cfg.CA = cert.CA
cfg.Certificate = cert.Certificate
cfg.Key = cert.Key
return s.configureAndStartRadius(&cfg)
}
func (s *Server) startWithoutRemote() error{
cert, err := s.getLocalCertificate()
if err != nil {
return err
}
cfg := *s.config.Radius
cfg.CA = cert.CA
cfg.Certificate = cert.Certificate
cfg.Key = cert.Key
return s.configureAndStartRadius(&cfg)
}
func (s *Server) configureAndStartRadius(config *freeradius.Configuration) error {
var err error
var radius *freeradius.Freeradius
defer func() {
// If no error the new configuration is OK, save it
if err == nil {
s.config.Radius = config
s.radius = radius
}
}()
radius, err = freeradius.New(s.log, config)
if err != nil {
return err
}
if s.radius != nil {
if err := s.radius.Stop(); err != nil {
s.log.Errorf("cannot stop freeradius server: %s", err)
}
}
err = radius.Configure()
if err != nil {
return err
}
return radius.Start()
}
func (s *Server) createCacheDirectory() error {
if common.IsDirectory(s.config.CacheDir) {
return nil
}
if err := os.MkdirAll(s.config.CacheDir, 0700); err != nil {
s.log.Errorf("cannot create cache directory %s: %s", s.config.CacheDir, err)
return err
}
return nil
}
func (s *Server) writeCache(certificate binding.RadiusCertificate) error {
if err := s.createCacheDirectory(); err != nil {
return err
}
target := filepath.Join(s.config.CacheDir, "certificate.json")
data, err := json.Marshal(&certificate)
if err != nil {
s.log.Errorf("cannot marshall certificate: %s", err)
return err
}
return ioutil.WriteFile(target, data, 0600)
}
func (s *Server) readCache() (*binding.RadiusCertificate, error) {
target := filepath.Join(s.config.CacheDir, "certificate.json")
if !common.FileExists(target) {
return nil, fmt.Errorf("no cache file at: %s", target)
}
data, err := ioutil.ReadFile(target)
if err != nil {
return nil, err
}
var certificate *binding.RadiusCertificate
err = json.Unmarshal(data, certificate)
return certificate, err
}
func (s *Server) getConfigCertificate() (*binding.RadiusCertificate, error) {
if s.config.Radius == nil {
return nil, fmt.Errorf("no Radius configuration")
}
if s.config.Radius.Certificate == "" {
return nil, fmt.Errorf("no certificate in Radius configuration")
}
if s.config.Radius.Key == "" {
return nil, fmt.Errorf("no private key in Radius configuration")
}
block, _ := pem.Decode([]byte(s.config.Radius.Certificate))
if block == nil {
return nil, fmt.Errorf("cannot decode certificate")
}
certObject, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
return &binding.RadiusCertificate{
SignatureDate: &certObject.NotBefore,
CA: s.config.Radius.CA,
Certificate: s.config.Radius.Certificate,
Key: s.config.Radius.Key,
}, nil
}
func (s *Server) getLocalCertificate() (*binding.RadiusCertificate, error) {
cert, err := s.readCache()
if err == nil {
return cert, nil
}
return s.getConfigCertificate()
}
func (s *Server) getRemoteCertificate() (*binding.RadiusCertificate, error) {
return s.fetcher.GetRemoteCertificate()
}