2015-03-12 06:05:16 +00:00
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
2015-03-12 18:12:44 +00:00
|
|
|
"encoding/hex"
|
2015-03-12 06:05:16 +00:00
|
|
|
"errors"
|
2015-03-31 06:36:03 +00:00
|
|
|
"fmt"
|
2015-03-12 06:05:16 +00:00
|
|
|
"net/http"
|
|
|
|
|
2015-03-12 18:26:59 +00:00
|
|
|
"github.com/hashicorp/errwrap"
|
2015-03-31 18:45:44 +00:00
|
|
|
"github.com/hashicorp/vault/logical"
|
2015-03-12 06:05:16 +00:00
|
|
|
"github.com/hashicorp/vault/vault"
|
|
|
|
)
|
|
|
|
|
|
|
|
func handleSysSeal(core *vault.Core) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2015-08-31 21:55:22 +00:00
|
|
|
switch r.Method {
|
|
|
|
case "PUT":
|
|
|
|
case "POST":
|
|
|
|
default:
|
2015-03-12 06:05:16 +00:00
|
|
|
respondError(w, http.StatusMethodNotAllowed, nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-03-31 18:45:44 +00:00
|
|
|
// Get the auth for the request so we can access the token directly
|
|
|
|
req := requestAuth(r, &logical.Request{})
|
|
|
|
|
|
|
|
// Seal with the token above
|
|
|
|
if err := core.Seal(req.ClientToken); err != nil {
|
2015-03-12 06:05:16 +00:00
|
|
|
respondError(w, http.StatusInternalServerError, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
respondOk(w, nil)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-02-27 00:43:55 +00:00
|
|
|
func handleSysStepDown(core *vault.Core) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
switch r.Method {
|
|
|
|
case "PUT":
|
|
|
|
case "POST":
|
|
|
|
default:
|
|
|
|
respondError(w, http.StatusMethodNotAllowed, nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the auth for the request so we can access the token directly
|
|
|
|
req := requestAuth(r, &logical.Request{})
|
|
|
|
|
|
|
|
// Seal with the token above
|
|
|
|
if err := core.StepDown(req.ClientToken); err != nil {
|
|
|
|
respondError(w, http.StatusInternalServerError, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
respondOk(w, nil)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-03-12 06:05:16 +00:00
|
|
|
func handleSysUnseal(core *vault.Core) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2015-08-31 21:55:22 +00:00
|
|
|
switch r.Method {
|
|
|
|
case "PUT":
|
|
|
|
case "POST":
|
|
|
|
default:
|
2015-03-12 06:05:16 +00:00
|
|
|
respondError(w, http.StatusMethodNotAllowed, nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the request
|
|
|
|
var req UnsealRequest
|
2015-03-12 18:12:44 +00:00
|
|
|
if err := parseRequest(r, &req); err != nil {
|
2015-03-12 06:05:16 +00:00
|
|
|
respondError(w, http.StatusBadRequest, err)
|
|
|
|
return
|
|
|
|
}
|
2015-10-28 19:59:39 +00:00
|
|
|
if !req.Reset && req.Key == "" {
|
2015-03-12 06:05:16 +00:00
|
|
|
respondError(
|
|
|
|
w, http.StatusBadRequest,
|
2015-10-28 19:59:39 +00:00
|
|
|
errors.New("'key' must specified in request body as JSON, or 'reset' set to true"))
|
2015-03-12 06:05:16 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-10-28 19:59:39 +00:00
|
|
|
if req.Reset {
|
|
|
|
sealed, err := core.Sealed()
|
|
|
|
if err != nil {
|
2015-03-12 18:26:59 +00:00
|
|
|
respondError(w, http.StatusInternalServerError, err)
|
|
|
|
return
|
|
|
|
}
|
2015-10-28 19:59:39 +00:00
|
|
|
if !sealed {
|
|
|
|
respondError(w, http.StatusBadRequest, errors.New("vault is unsealed"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
core.ResetUnsealProcess()
|
|
|
|
} else {
|
|
|
|
// Decode the key, which is hex encoded
|
|
|
|
key, err := hex.DecodeString(req.Key)
|
|
|
|
if err != nil {
|
|
|
|
respondError(
|
|
|
|
w, http.StatusBadRequest,
|
|
|
|
errors.New("'key' must be a valid hex-string"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Attempt the unseal
|
|
|
|
if _, err := core.Unseal(key); err != nil {
|
|
|
|
// Ignore ErrInvalidKey because its a user error that we
|
|
|
|
// mask away. We just show them the seal status.
|
|
|
|
if !errwrap.ContainsType(err, new(vault.ErrInvalidKey)) {
|
|
|
|
respondError(w, http.StatusInternalServerError, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2015-03-12 06:05:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the seal status
|
|
|
|
handleSysSealStatusRaw(core, w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleSysSealStatus(core *vault.Core) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if r.Method != "GET" {
|
|
|
|
respondError(w, http.StatusMethodNotAllowed, nil)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
handleSysSealStatusRaw(core, w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleSysSealStatusRaw(core *vault.Core, w http.ResponseWriter, r *http.Request) {
|
|
|
|
sealed, err := core.Sealed()
|
|
|
|
if err != nil {
|
|
|
|
respondError(w, http.StatusInternalServerError, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-04-04 14:44:22 +00:00
|
|
|
sealConfig, err := core.SealAccess().BarrierConfig()
|
2015-03-12 06:05:16 +00:00
|
|
|
if err != nil {
|
|
|
|
respondError(w, http.StatusInternalServerError, err)
|
|
|
|
return
|
|
|
|
}
|
2015-03-31 06:36:03 +00:00
|
|
|
if sealConfig == nil {
|
|
|
|
respondError(w, http.StatusBadRequest, fmt.Errorf(
|
|
|
|
"server is not yet initialized"))
|
|
|
|
return
|
|
|
|
}
|
2015-03-12 06:05:16 +00:00
|
|
|
|
|
|
|
respondOk(w, &SealStatusResponse{
|
|
|
|
Sealed: sealed,
|
|
|
|
T: sealConfig.SecretThreshold,
|
|
|
|
N: sealConfig.SecretShares,
|
|
|
|
Progress: core.SecretProgress(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
type SealStatusResponse struct {
|
|
|
|
Sealed bool `json:"sealed"`
|
|
|
|
T int `json:"t"`
|
|
|
|
N int `json:"n"`
|
|
|
|
Progress int `json:"progress"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type UnsealRequest struct {
|
2015-10-28 19:59:39 +00:00
|
|
|
Key string
|
|
|
|
Reset bool
|
2015-03-12 06:05:16 +00:00
|
|
|
}
|