From e46cc7cc8766637f13e44e471a03aeecac7eaf11 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 30 Mar 2015 12:21:06 -0700 Subject: [PATCH] http: start implementing /sys/login (incomplete) --- http/handler.go | 1 + http/sys_login.go | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 http/sys_login.go diff --git a/http/handler.go b/http/handler.go index 6b31f4025..f4a1d6486 100644 --- a/http/handler.go +++ b/http/handler.go @@ -19,6 +19,7 @@ func Handler(core *vault.Core) http.Handler { mux.Handle("/v1/sys/seal-status", handleSysSealStatus(core)) mux.Handle("/v1/sys/seal", handleSysSeal(core)) mux.Handle("/v1/sys/unseal", handleSysUnseal(core)) + mux.Handle("/v1/sys/login/", handleSysLogin(core)) mux.Handle("/v1/sys/mounts/", handleSysMounts(core)) mux.Handle("/v1/", handleLogical(core)) return mux diff --git a/http/sys_login.go b/http/sys_login.go new file mode 100644 index 000000000..69fbea288 --- /dev/null +++ b/http/sys_login.go @@ -0,0 +1,64 @@ +package http + +import ( + "net" + "net/http" + "strings" + + "github.com/hashicorp/vault/credential" + "github.com/hashicorp/vault/vault" +) + +func handleSysLogin(core *vault.Core) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "PUT" { + respondError(w, http.StatusMethodNotAllowed, nil) + return + } + + // Determine the path... + prefix := "/v1/sys/login/" + if !strings.HasPrefix(r.URL.Path, prefix) { + respondError(w, http.StatusNotFound, nil) + return + } + path := r.URL.Path[len(prefix):] + if path == "" { + respondError(w, http.StatusNotFound, nil) + return + } + + // Parse the IP address + ipaddr, err := net.ResolveIPAddr("ip", r.RemoteAddr) + if err != nil { + respondError(w, http.StatusInternalServerError, err) + return + } + + // Do the login request + resp, err := core.HandleLogin(&credential.Request{ + Path: path, + RemoteAddr: ipaddr, + ConnState: r.TLS, + }) + + // Determine the response to send. If we were given a secret, + // then we add the secret to the response. + var httpResp interface{} + if resp != nil { + // TODO: redirect + + logicalResp := &LogicalResponse{Data: resp.Data} + if resp.Secret != nil { + logicalResp.VaultId = resp.Secret.VaultID + logicalResp.Renewable = resp.Secret.Renewable + logicalResp.LeaseDuration = int(resp.Secret.Lease.Seconds()) + } + + httpResp = logicalResp + } + + // Respond with the secret and/or data + respondOk(w, httpResp) + }) +}