[ARVADOS] updated: 8c5b4f6d87cec17f915802e3c5f14695611eba7f

git at public.curoverse.com git at public.curoverse.com
Fri May 2 18:26:43 EDT 2014


Summary of changes:
 services/keep/src/keep/perms.go      |   38 +++++++++++++++++++++++++--------
 services/keep/src/keep/perms_test.go |   29 ++++++++++++++++---------
 2 files changed, 47 insertions(+), 20 deletions(-)

       via  8c5b4f6d87cec17f915802e3c5f14695611eba7f (commit)
      from  aeff59bfaf199eec6884ccf3ff60968bec81f581 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 8c5b4f6d87cec17f915802e3c5f14695611eba7f
Author: Tim Pierce <twp at curoverse.com>
Date:   Fri May 2 18:26:08 2014 -0400

    Incorporating code review. (refs #2328)

diff --git a/services/keep/src/keep/perms.go b/services/keep/src/keep/perms.go
index 217afb4..f3ff001 100644
--- a/services/keep/src/keep/perms.go
+++ b/services/keep/src/keep/perms.go
@@ -15,9 +15,9 @@ expressed as a hexadecimal number.  e.g.:
     acbd18db4cc2f85cedef654fccc4a4d8+3+A257f3f5f5f0a4e4626a18fc74bd42ec34dcb228a at 7fffffff
 
 The signature represents a guarantee that this locator was generated
-by either Keep or the API server for the user with the supplied API
-token.  If a request to Keep includes a locator with a valid signature
-and is accompanied by the proper API token, the user has permission to
+by either Keep or the API server for use with the supplied API token.
+If a request to Keep includes a locator with a valid signature and is
+accompanied by the proper API token, the user has permission to
 perform any action on that object (GET, PUT or DELETE).
 
 The signature may be generated either by Keep (after the user writes a
@@ -40,7 +40,9 @@ import (
 	"crypto/sha1"
 	"fmt"
 	"regexp"
+	"strconv"
 	"strings"
+	"time"
 )
 
 // The PermissionSecret is the secret key used to generate SHA1
@@ -48,9 +50,9 @@ import (
 // key.
 var PermissionSecret []byte
 
-// GeneratePerms returns a string representing the signed permission
+// makePermSignature returns a string representing the signed permission
 // hint for the blob identified by blob_hash, api_token and timestamp.
-func GeneratePerms(blob_hash string, api_token string, timestamp string) string {
+func makePermSignature(blob_hash string, api_token string, timestamp string) string {
 	hmac := hmac.New(sha1.New, PermissionSecret)
 	hmac.Write([]byte(blob_hash))
 	hmac.Write([]byte("@"))
@@ -63,11 +65,14 @@ func GeneratePerms(blob_hash string, api_token string, timestamp string) string
 
 // SignLocator takes a blob_locator, an api_token and a timestamp, and
 // returns a signed locator string.
-func SignLocator(blob_locator string, api_token string, timestamp string) string {
+func SignLocator(blob_locator string, api_token string, timestamp time.Time) string {
 	// Extract the hash from the blob locator, omitting any size hint that may be present.
 	blob_hash := strings.Split(blob_locator, "+")[0]
 	// Return the signed locator string.
-	return blob_locator + "+A" + GeneratePerms(blob_hash, api_token, timestamp) + "@" + timestamp
+	timestamp_hex := fmt.Sprintf("%08x", timestamp.Unix())
+	return blob_locator +
+		"+A" + makePermSignature(blob_hash, api_token, timestamp_hex) +
+		"@" + timestamp_hex
 }
 
 // VerifySignature returns true if the signature on the signed_locator
@@ -76,9 +81,24 @@ func VerifySignature(signed_locator string, api_token string) bool {
 	if re, err := regexp.Compile(`^(.*)\+A(.*)@(.*)$`); err == nil {
 		if matches := re.FindStringSubmatch(signed_locator); matches != nil {
 			blob_locator := matches[1]
-			timestamp := matches[3]
-			return signed_locator == SignLocator(blob_locator, api_token, timestamp)
+			timestamp_hex := matches[3]
+			if expire_ts, err := ParseHexTimestamp(timestamp_hex); err == nil {
+				// Fail signatures with expired timestamps.
+				if expire_ts.Before(time.Now()) {
+					return false
+				}
+				return signed_locator == SignLocator(blob_locator, api_token, expire_ts)
+			}
 		}
 	}
 	return false
 }
+
+func ParseHexTimestamp(timestamp_hex string) (ts time.Time, err error) {
+	if ts_int, e := strconv.ParseInt(timestamp_hex, 16, 0); e == nil {
+		ts = time.Unix(ts_int, 0)
+	} else {
+		err = e
+	}
+	return ts, err
+}
diff --git a/services/keep/src/keep/perms_test.go b/services/keep/src/keep/perms_test.go
index fcd17e1..d1c6b50 100644
--- a/services/keep/src/keep/perms_test.go
+++ b/services/keep/src/keep/perms_test.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"testing"
+	"time"
 )
 
 var (
@@ -20,21 +21,16 @@ var (
 	known_signed_locator = known_locator + "+A" + known_signature + "@" + known_timestamp
 )
 
-func TestGeneratePerms(t *testing.T) {
-	PermissionSecret = []byte(known_key)
-	defer func() { PermissionSecret = nil }()
-
-	if known_signature != GeneratePerms(known_hash, known_token, known_timestamp) {
-		t.Fail()
-	}
-}
-
 func TestSignLocator(t *testing.T) {
 	PermissionSecret = []byte(known_key)
 	defer func() { PermissionSecret = nil }()
 
-	if known_signed_locator != SignLocator(known_locator, known_token, known_timestamp) {
-		t.Fail()
+	if ts, err := ParseHexTimestamp(known_timestamp); err != nil {
+		t.Errorf("bad known_timestamp %s", known_timestamp)
+	} else {
+		if known_signed_locator != SignLocator(known_locator, known_token, ts) {
+			t.Fail()
+		}
 	}
 }
 
@@ -95,3 +91,14 @@ func TestVerifySignatureBadToken(t *testing.T) {
 		t.Fail()
 	}
 }
+
+func TestVerifySignatureExpired(t *testing.T) {
+	PermissionSecret = []byte(known_key)
+	defer func() { PermissionSecret = nil }()
+
+	yesterday := time.Now().AddDate(0, 0, -1)
+	expired_locator := SignLocator(known_hash, known_token, yesterday)
+	if VerifySignature(expired_locator, known_token) {
+		t.Fail()
+	}
+}

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list