aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go44
1 files changed, 41 insertions, 3 deletions
diff --git a/main.go b/main.go
index 9d12c9f..2f61cff 100644
--- a/main.go
+++ b/main.go
@@ -9,6 +9,7 @@ import (
9 "errors" 9 "errors"
10 "flag" 10 "flag"
11 "fmt" 11 "fmt"
12 "io"
12 "io/ioutil" 13 "io/ioutil"
13 "net" 14 "net"
14 "net/http" 15 "net/http"
@@ -29,6 +30,17 @@ var (
29 DEFAULT_VALUES map[string]*string 30 DEFAULT_VALUES map[string]*string
30) 31)
31 32
33const (
34 METADATA_FILE = "/etc/mmds/bootstrap-cred.json"
35)
36
37type FileLike interface {
38 io.Reader
39 io.Writer
40 io.Seeker
41 Truncate(int64) error
42}
43
32func init() { 44func init() {
33 DEFAULT_VALUES = map[string]*string{ 45 DEFAULT_VALUES = map[string]*string{
34 "domain": StringPtr("amazonaws.com"), 46 "domain": StringPtr("amazonaws.com"),
@@ -60,6 +72,7 @@ type appContext struct {
60 RoleARN *string 72 RoleARN *string
61 BootstrapSecret *string 73 BootstrapSecret *string
62 CredentialHandler CredentialHandler 74 CredentialHandler CredentialHandler
75 CredentialFile FileLike
63} 76}
64 77
65func (c *appContext) FormatAZ() string { 78func (c *appContext) FormatAZ() string {
@@ -139,6 +152,7 @@ func BootstrapCredentialHandler(w http.ResponseWriter, r *http.Request) {
139 if err != nil { 152 if err != nil {
140 jww.ERROR.Printf("Error decoding bootstrap JSON: %s", err) 153 jww.ERROR.Printf("Error decoding bootstrap JSON: %s", err)
141 http.Error(w, err.Error(), http.StatusInternalServerError) 154 http.Error(w, err.Error(), http.StatusInternalServerError)
155 return
142 } 156 }
143 157
144 if !validateSignature(&cred, ctx.BootstrapSecret) { 158 if !validateSignature(&cred, ctx.BootstrapSecret) {
@@ -149,6 +163,19 @@ func BootstrapCredentialHandler(w http.ResponseWriter, r *http.Request) {
149 163
150 creds := credentials.NewStaticCredentials(cred.AccessKeyId, cred.SecretAccessKey, cred.Token) 164 creds := credentials.NewStaticCredentials(cred.AccessKeyId, cred.SecretAccessKey, cred.Token)
151 ctx.CredentialHandler.SetBootstrapCredential(creds) 165 ctx.CredentialHandler.SetBootstrapCredential(creds)
166
167 jd, err := json.MarshalIndent(cred, "", " ")
168 if err != nil {
169 jww.ERROR.Printf("Unable to marshal credential for writing to file")
170 http.Error(w, err.Error(), http.StatusInternalServerError)
171 return
172 }
173
174 // Truncate credential file and update with new credentials
175 // TODO: Should validate the the credentials worked first
176 ctx.CredentialFile.Seek(0, 0)
177 ctx.CredentialFile.Truncate(0)
178 ctx.CredentialFile.Write(jd)
152} 179}
153 180
154func IAMInfoHandler(w http.ResponseWriter, r *http.Request) { 181func IAMInfoHandler(w http.ResponseWriter, r *http.Request) {
@@ -295,8 +322,8 @@ func parseArgs() (*UserArgs, error) {
295 return a, nil 322 return a, nil
296} 323}
297 324
298func initialBootstrap(file string, handler CredentialHandler) { 325func initialBootstrap(file FileLike, handler CredentialHandler) {
299 bd, err := ioutil.ReadFile(file) 326 bd, err := ioutil.ReadAll(file)
300 if err != nil { 327 if err != nil {
301 jww.ERROR.Printf("Error reading bootstrap file: %s", err.Error()) 328 jww.ERROR.Printf("Error reading bootstrap file: %s", err.Error())
302 return 329 return
@@ -330,6 +357,16 @@ func main() {
330 return 357 return
331 } 358 }
332 359
360 // Open this before dropping privileges because only root can update the
361 // file but the service may need to update it at some future point if a new
362 // credential is provided.
363 credfile, err := os.OpenFile(METADATA_FILE, os.O_RDWR, 0600)
364 if err != nil {
365 jww.FATAL.Printf("Unable to open bootstrap credential file")
366 return
367 }
368 defer credfile.Close()
369
333 if err := drop.DropPrivileges(args.User); err != nil { 370 if err := drop.DropPrivileges(args.User); err != nil {
334 jww.FATAL.Printf("Unable to drop privileges") 371 jww.FATAL.Printf("Unable to drop privileges")
335 return 372 return
@@ -362,9 +399,10 @@ func main() {
362 RoleARN: &args.RoleARN, 399 RoleARN: &args.RoleARN,
363 BootstrapSecret: &args.BootstrapSecret, 400 BootstrapSecret: &args.BootstrapSecret,
364 CredentialHandler: credHandler, 401 CredentialHandler: credHandler,
402 CredentialFile: credfile,
365 } 403 }
366 404
367 initialBootstrap("/etc/mmds/bootstrap-cred.json", credHandler) 405 initialBootstrap(credfile, credHandler)
368 406
369 go credHandler.Start() 407 go credHandler.Start()
370 go http.ListenAndServe(":8000", buildAdminHandler(ctx)) 408 go http.ListenAndServe(":8000", buildAdminHandler(ctx))