diff --git a/README.md b/README.md index b90d8c9..7eed5e8 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Example query: If there aren't enough keys delegated you'll see: - {"Status":"Need more delegated keys"} + {"Status":"need more delegated keys"} ### Owners diff --git a/client/client.go b/client/client.go index a907954..43e2f26 100644 --- a/client/client.go +++ b/client/client.go @@ -8,11 +8,8 @@ import ( "errors" "fmt" "io/ioutil" - "log" "net/http" - "time" - "github.com/cloudflare/backoff" "github.com/cloudflare/redoctober/core" ) @@ -62,17 +59,9 @@ func (c *RemoteServer) getURL(path string) string { func (c *RemoteServer) doAction(action string, req []byte) ([]byte, error) { buf := bytes.NewBuffer(req) url := c.getURL("/" + action) - b := backoff.Backoff{} - var resp *http.Response - var err error - for { - resp, err = c.client.Post(url, "application/json", buf) - if err == nil { - break - } - delay := b.Duration() - log.Printf("Request to server failed. Will try again in %s", delay) - <-time.After(delay) + resp, err := c.client.Post(url, "application/json", buf) + if err != nil { + return nil, err } body, err := ioutil.ReadAll(resp.Body) diff --git a/cmd/ro/main.go b/cmd/ro/main.go index 1218382..f9ccd55 100644 --- a/cmd/ro/main.go +++ b/cmd/ro/main.go @@ -8,12 +8,16 @@ import ( "io/ioutil" "log" "os" + "os/signal" "strings" + "syscall" "time" "github.com/cloudflare/redoctober/client" "github.com/cloudflare/redoctober/cmd/ro/gopass" "github.com/cloudflare/redoctober/core" + "github.com/cloudflare/redoctober/cryptor" + "github.com/cloudflare/redoctober/msp" "github.com/cloudflare/redoctober/order" ) @@ -244,11 +248,39 @@ func runDecrypt() { } resp, err := roServer.Decrypt(req) - processError(err) - if resp.Status != "ok" { - log.Fatal("response status error:", resp.Status) - return + if err != nil { + switch err.Error() { + case cryptor.ErrNotEnoughDelegations.Error(), + msp.ErrNotEnoughShares.Error(), + "Need more delegated keys": + // retry forever unless keyboard interrupt + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + + for i := 0; i < 20; i++ { + resp, err = roServer.Decrypt(req) + if err == nil { + break + } + log.Println("retry after 30 seconds due to error: ", err) + + select { + case <-sigChan: + log.Fatal("process is interrupted") + return + + case <-time.After(30 * time.Second): + } + } + default: + processError(err) + } } + + if resp == nil { + log.Fatal("response status error:", resp.Status) + } + fmt.Println("Response Status:", resp.Status) var msg core.DecryptWithDelegates err = json.Unmarshal(resp.Response, &msg) diff --git a/cryptor/cryptor.go b/cryptor/cryptor.go index 0a80c1a..e8aabf4 100644 --- a/cryptor/cryptor.go +++ b/cryptor/cryptor.go @@ -456,7 +456,7 @@ func (encrypted *EncryptedData) unwrapKey(cache *keycache.Cache, user string) (u } if !fullMatch { - err = errors.New("Need more delegated keys") + err = ErrNotEnoughDelegations return } @@ -738,6 +738,9 @@ func (c *Cryptor) store() error { // delegations are needed for the restore to continue. var ErrRestoreDelegations = errors.New("cryptor: need more delegations") +// ErrNotEnoughDelegations is a error returned by Decrypt. +var ErrNotEnoughDelegations = errors.New("need more delegated keys") + // Restore delegates the named user to the persistence key cache. If // enough delegations are present to restore the cache, the current // Red October key cache is replaced with the persisted one. diff --git a/msp/msp.go b/msp/msp.go index 3e11621..cb3f0ce 100644 --- a/msp/msp.go +++ b/msp/msp.go @@ -214,7 +214,7 @@ func (m MSP) DistributeShares(sec []byte, db UserDatabase) (map[string][][]byte, // ErrNotEnoughShares is returned if there aren't enough shares to // decrypt the secret. -var ErrNotEnoughShares = errors.New("Not enough shares to recover.") +var ErrNotEnoughShares = errors.New("not enough shares to recover") // RecoverSecret takes a user database storing secret shares as input and returns the original secret. func (m MSP) RecoverSecret(db UserDatabase) ([]byte, error) { diff --git a/redoctober_test.go b/redoctober_test.go index 306507e..de0ec18 100644 --- a/redoctober_test.go +++ b/redoctober_test.go @@ -385,7 +385,7 @@ func TestDecrypt(t *testing.T) { } // Check the first decrypt command (where not enough owners have decrypted yet). - if err := postAndTest("decrypt", decryptInput, 200, "Need more delegated keys"); err != nil { + if err := postAndTest("decrypt", decryptInput, 200, "need more delegated keys"); err != nil { t.Fatalf("Error decrypting data, %v", err) } diff --git a/testdata/server.crt b/testdata/server.crt index aba0b59..a6c1ed8 100644 --- a/testdata/server.crt +++ b/testdata/server.crt @@ -1,19 +1,20 @@ -----BEGIN CERTIFICATE----- -MIIDEjCCAfoCCQC9ZDaVRNmxOjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJV -UzETMBEGA1UECBMKQ2FsaWZvcm5pYTETMBEGA1UEBxMKRXZlcnl3aGVyZTESMBAG -A1UEAxMJbG9jYWxob3N0MB4XDTE1MTAwOTE3NDUyNVoXDTE2MTAwODE3NDUyNVow -SzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEzARBgNVBAcTCkV2 -ZXJ5d2hlcmUxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAOTJ3CZZ+55TI+mfv7w3xAjlS4cqO2gc8jQOkWMMeSd7P7pE -U3SOA1mWA7vDnd6MtlV/sWyz9/ZgWXk0RUmGAM+YEpdZs+i2749rh70fRIF+2wIk -bCy1Rc00cAoIpsglTvAqIOSIVX2k5DOBEb1U878vuv6kJ9lzrA48xtxQ4XIVPoTX -5a4tY9oaslB9aeaRxuMJHiy5YcpQ1xnppPpkbMVFmZmbDzmKUkKBzNdPKxADAEsU -PGB74T8p72KKbTXbZnTPFxysNMNfNf3DuTkRcxWCQgNa68X8oTXuT1H7PVgg213z -sXulkOphUIqZTX3xgb/EQHIM/EZgTyvZ+KdacDECAwEAATANBgkqhkiG9w0BAQUF -AAOCAQEAbyw1udm2tQQQ/27Ok2aOvWWlvY7N2WKSM6z0x/IKpeyEmh/e1YAjOM8M -/AzZn4q9LgXIZqYiidXV9h7+N4utR44ajKaJkr4RH1h3PW0SS4JhKDhwMIT9LmVw -WOGrb+wM8k7T5s2lFpIgtAayNeTZuJS4Ltd4oF9k7VQ6HE2w3wNiP/J4Ud3uv0Xr -b1PO1U+N0jqLfGBf+y5enx8AtyHPKR/DW34xlFoZpsAedPG/YFcxuO3kudHqfDZi -pYf73eNtuMfNXl+muju5/UC/NoAFQlkfASbsz25n7q5DumXOlrK0QDQSfqYYG/5Z -WOnEaAg2q3sMgyMgZw4GG7WRdxcOGg== +MIIDSjCCAjICCQCPi3Zin7S81jANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJV +UzELMAkGA1UECAwCQ0ExEzARBgNVBAcMCkV2ZXJ5d2hlcmUxITAfBgNVBAoMGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE2 +MTAxMjEyMTk0MFoYDzIxMTYwOTE4MTIxOTQwWjBmMQswCQYDVQQGEwJVUzELMAkG +A1UECAwCQ0ExEzARBgNVBAcMCkV2ZXJ5d2hlcmUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5MncJln7nlMj6Z+/vDfECOVLhyo7aBzyNA6R +Ywx5J3s/ukRTdI4DWZYDu8Od3oy2VX+xbLP39mBZeTRFSYYAz5gSl1mz6Lbvj2uH +vR9EgX7bAiRsLLVFzTRwCgimyCVO8Cog5IhVfaTkM4ERvVTzvy+6/qQn2XOsDjzG +3FDhchU+hNflri1j2hqyUH1p5pHG4wkeLLlhylDXGemk+mRsxUWZmZsPOYpSQoHM +108rEAMASxQ8YHvhPynvYoptNdtmdM8XHKw0w181/cO5ORFzFYJCA1rrxfyhNe5P +Ufs9WCDbXfOxe6WQ6mFQiplNffGBv8RAcgz8RmBPK9n4p1pwMQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQC70dOBTcY1vbqiMq3ojSzPrw37ZwOytFdT4f67QGU5Vxhs +tdwoO0T7p/YePn8/+3dKPVhOdTPoTHyLf8SQ9n2EMGN9g2tDovjsdynX6Pqc3xxi +6w2xT8U/LCeq4VTMaI7hBWqh5nNGUqeJxkotNASCN9hKnZxo1qXhc1tuZNy4U9Dd +c/Xn1WU0FR2s9IC6EpkSHn9qm/vx7wX9AtXxXbI74UQff2SYa4EoqHTM3YAx4d8g +ZoxcKoZa4JJzJIWNVPQ4bKc2DkaxjwRySpKYPOG5MTwx0O4UWn65dlPD+sOUX2go +ITqeyFA5PONg9Gp5pBFNWkzItYyJGPEsvENHGBJq -----END CERTIFICATE-----