mirror of
https://github.com/cloudflare/redoctober.git
synced 2026-01-09 07:33:47 +00:00
Add CLI support for restore endpoint.
+ Add the relevant parts to the command line tool and the client package. + Small improvements to cryptor's restore function: + Don't try to restore if the store is already active. + Flush the persistence key cache once the restoration occurs. + The redoctober program now explicitly mentions that a config file is invalid when that's the case.
This commit is contained in:
@@ -387,3 +387,20 @@ func (c *RemoteServer) Status(req core.StatusRequest) (*core.ResponseData, error
|
||||
|
||||
return unmarshalResponseData(respBytes)
|
||||
}
|
||||
|
||||
// Restore issues a restore request to the server. Note that a restore
|
||||
// request is the same as a delegation request, except that the user
|
||||
// and label lists are ignored.
|
||||
func (c *RemoteServer) Restore(req core.DelegateRequest) (*core.ResponseData, error) {
|
||||
reqBytes, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respBytes, err := c.doAction("restore", reqBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return unmarshalResponseData(respBytes)
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ var commandSet = map[string]command{
|
||||
"order": command{Run: runOrder, Desc: "place an order for delegations"},
|
||||
"owners": command{Run: runOwner, Desc: "show owners list"},
|
||||
"status": command{Run: runStatus, Desc: "show Red October persistent delegation state"},
|
||||
"restore": command{Run: runRestore, Desc: "perform a restore delegation"},
|
||||
}
|
||||
|
||||
func registerFlags() {
|
||||
@@ -132,6 +133,29 @@ func runDelegate() {
|
||||
fmt.Println(resp.Status)
|
||||
}
|
||||
|
||||
func runRestore() {
|
||||
req := core.DelegateRequest{
|
||||
Name: user,
|
||||
Password: pswd,
|
||||
Uses: uses,
|
||||
Time: duration,
|
||||
}
|
||||
|
||||
resp, err := roServer.Restore(req)
|
||||
processError(err)
|
||||
|
||||
if resp.Status != "ok" {
|
||||
fmt.Fprintf(os.Stderr, "failed: %s\n", resp.Status)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var st core.StatusData
|
||||
err = json.Unmarshal(resp.Response, &st)
|
||||
processError(err)
|
||||
|
||||
fmt.Println("Restore delegation complete; persistence is now", st.Status)
|
||||
}
|
||||
|
||||
// TODO: summary response needs better formatting
|
||||
func runSummary() {
|
||||
req := core.SummaryRequest{
|
||||
|
||||
@@ -742,6 +742,11 @@ var ErrRestoreDelegations = errors.New("cryptor: need more delegations")
|
||||
// enough delegations are present to restore the cache, the current
|
||||
// Red October key cache is replaced with the persisted one.
|
||||
func (c *Cryptor) Restore(name, password string, uses int, slot, durationString string) error {
|
||||
// If the persistence store is already active, don't proceed.
|
||||
if st := c.persist.Status(); st != nil && st.State == persist.Active {
|
||||
return nil
|
||||
}
|
||||
|
||||
record, ok := c.records.GetRecord(name)
|
||||
if !ok {
|
||||
return errors.New("Missing user on disk")
|
||||
@@ -774,6 +779,7 @@ func (c *Cryptor) Restore(name, password string, uses int, slot, durationString
|
||||
|
||||
c.cache = keycache.NewFrom(uk)
|
||||
c.persist.Persist()
|
||||
c.persist.Cache().Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -304,6 +304,9 @@ func main() {
|
||||
}
|
||||
|
||||
if vaultPath == "" || !cfg.Valid() {
|
||||
if !cfg.Valid() {
|
||||
fmt.Fprintf(os.Stderr, "Invalid config.\n")
|
||||
}
|
||||
fmt.Fprint(os.Stderr, usage)
|
||||
flag.PrintDefaults()
|
||||
os.Exit(2)
|
||||
|
||||
Reference in New Issue
Block a user