]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: some code cleanup
authorYehuda Sadeh <yehuda@inktank.com>
Thu, 23 May 2013 19:29:42 +0000 (12:29 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Thu, 23 May 2013 19:29:42 +0000 (12:29 -0700)
move s3 signing code to a different common file.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/Makefile.am
src/rgw/rgw_auth_s3.cc [new file with mode: 0644]
src/rgw/rgw_auth_s3.h [new file with mode: 0644]
src/rgw/rgw_rest_client.cc
src/rgw/rgw_rest_s3.cc

index 360722e2b0186732059e51702a2b66b5e8fcb6b2..7762cbb50fcad5af0ad92396095bea9592df2a74 100644 (file)
@@ -398,6 +398,7 @@ librgw_a_SOURCES =  \
        rgw/rgw_env.cc \
        rgw/rgw_cors.cc \
        rgw/rgw_cors_s3.cc \
+        rgw/rgw_auth_s3.cc \
        rgw/rgw_metadata.cc
 librgw_a_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS}
 librgw_a_CXXFLAGS = -Woverloaded-virtual ${AM_CXXFLAGS}
@@ -2076,6 +2077,7 @@ noinst_HEADERS = \
        rgw/rgw_rest.h\
        rgw/rgw_rest_swift.h\
        rgw/rgw_rest_s3.h\
+       rgw/rgw_auth_s3.h\
        rgw/rgw_rest_admin.h\
        rgw/rgw_rest_usage.h\
        rgw/rgw_rest_user.h\
diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc
new file mode 100644 (file)
index 0000000..e3c08e7
--- /dev/null
@@ -0,0 +1,137 @@
+
+#include "common/armor.h"
+#include "rgw_common.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+static const char *signed_subresources[] = {
+  "acl",
+  "lifecycle",
+  "location",
+  "logging",
+  "notification",
+  "partNumber",
+  "policy",
+  "requestPayment",
+  "torrent",
+  "uploadId",
+  "uploads",
+  "versionId",
+  "versioning",
+  "versions",
+  "website",
+  NULL
+};
+
+/*
+ * ?get the canonical amazon-style header for something?
+ */
+
+static void get_canon_amz_hdr(map<string, string>& meta_map, string& dest)
+{
+  dest = "";
+  map<string, string>::iterator iter;
+  for (iter = meta_map.begin(); iter != meta_map.end(); ++iter) {
+    dest.append(iter->first);
+    dest.append(":");
+    dest.append(iter->second);
+    dest.append("\n");
+  }
+}
+
+/*
+ * ?get the canonical representation of the object's location
+ */
+static void get_canon_resource(const char *request_uri, map<string, string>& sub_resources, string& dest)
+{
+  string s;
+
+  if (request_uri)
+    s.append(request_uri);
+
+  string append_str;
+
+  const char **p = signed_subresources;
+
+  for (; *p; ++p) {
+    map<string, string>::iterator iter = sub_resources.find(*p);
+    if (iter == sub_resources.end())
+      continue;
+    
+    if (append_str.empty())
+      append_str.append("?");
+    else
+      append_str.append("&");     
+    append_str.append(iter->first);
+    if (!iter->second.empty()) {
+      append_str.append("=");
+      append_str.append(iter->second);
+    }
+  }
+  if (!append_str.empty()) {
+    s.append(append_str);
+  }
+  dout(10) << "get_canon_resource(): dest=" << dest << dendl;
+
+  dest = s;
+}
+
+/*
+ * get the header authentication  information required to
+ * compute a request's signature
+ */
+void rgw_create_s3_canonical_header(const char *method, const char *content_md5, const char *content_type, const char *date,
+                            map<string, string>& meta_map, const char *request_uri, map<string, string>& sub_resources,
+                            string& dest_str)
+{
+  string dest;
+
+  if (method)
+    dest = method;
+  dest.append("\n");
+  
+  if (content_md5) {
+    dest.append(content_md5);
+  }
+  dest.append("\n");
+
+  if (content_type)
+    dest.append(content_type);
+  dest.append("\n");
+
+  if (date)
+    dest.append(date);
+  dest.append("\n");
+
+  string canon_amz_hdr;
+  get_canon_amz_hdr(meta_map, canon_amz_hdr);
+  dest.append(canon_amz_hdr);
+
+  string canon_resource;
+  get_canon_resource(request_uri, sub_resources, canon_resource);
+
+  dest.append(canon_resource);
+
+  dest_str = dest;
+}
+
+int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest)
+{
+  char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
+  calc_hmac_sha1(key.c_str(), key.size(), auth_hdr.c_str(), auth_hdr.size(), hmac_sha1);
+
+  char b64[64]; /* 64 is really enough */
+  int ret = ceph_armor(b64, b64 + 64, hmac_sha1,
+                      hmac_sha1 + CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
+  if (ret < 0) {
+    dout(10) << "ceph_armor failed" << dendl;
+    return ret;
+  }
+  b64[ret] = '\0';
+
+  dest = b64;
+
+  return 0;
+}
+
+
diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h
new file mode 100644 (file)
index 0000000..63813b9
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef CEPH_RGW_AUTH_S3_H
+#define CEPH_RGW_AUTH_S3_H
+
+
+#include "rgw_common.h"
+
+void rgw_create_s3_canonical_header(const char *method, const char *content_md5, const char *content_type, const char *date,
+                            map<string, string>& meta_map, const char *request_uri, map<string, string>& sub_resources,
+                            string& dest_str);
+int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest);
+
+
+
+#endif
index d3caaa5c849648140fbfbfc615ad6dcb6f74a06d..80d58388a899d2c14e42a47cd33edbf4ae309071 100644 (file)
@@ -1,5 +1,6 @@
 #include "rgw_common.h"
 #include "rgw_rest_client.h"
+#include "rgw_auth_s3.h"
 #include "rgw_http_errors.h"
 
 #include "common/ceph_crypto_cms.h"
@@ -64,46 +65,28 @@ int RGWRESTClient::execute(RGWAccessKey& key, const char *method, const char *re
   }
   new_url.append(new_resource);
 
-  if (params.size()) {
-    new_url.append("?");
-
-    list<pair<string, string> >::iterator iter;
-    for (iter = params.begin(); iter != params.end(); ++iter) {
-      if (iter != params.begin())
-        new_url.append("?");
-      new_url.append(iter->first + "=" + iter->second);
-    }
-  }
-
   utime_t tm = ceph_clock_now(cct);
   stringstream s;
   tm.gmtime(s);
   string date_str = s.str();
   headers.push_back(make_pair<string, string>("HTTP_DATE", date_str));
 
-  string canonical_header = string(method) + " " +
-                            "\n" + /* CONTENT_MD5 */
-                            "\n" + /* CONTENT_TYPE */
-                            date_str + "\n" +
-                            "\n" + /* amz headers */
-                            new_resource;
+  string canonical_header;
+  map<string, string> meta_map;
+  map<string, string> sub_resources;
+  rgw_create_s3_canonical_header(method, NULL, NULL, date_str.c_str(),
+                            meta_map, new_url.c_str(), sub_resources,
+                            canonical_header);
 
-  string& k = key.key;
-  
-  char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
-  calc_hmac_sha1(k.c_str(), k.size(), canonical_header.c_str(), canonical_header.size(), hmac_sha1);
-
-#define ARMOR_LEN 64
-  char b64[ARMOR_LEN]; /* 64 is really enough */
-  int ret = ceph_armor(b64, b64 + ARMOR_LEN, hmac_sha1,
-                      hmac_sha1 + CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
+  string digest;
+  int ret = rgw_get_s3_header_digest(canonical_header, key.key, digest);
   if (ret < 0) {
-    dout(10) << "ceph_armor failed" << dendl;
-    return -EPERM;
+    return ret;
   }
-  b64[ret] = '\0';
 
-  string auth_hdr = "AWS " + key.id + ":" + b64;
+  string auth_hdr = "AWS " + key.id + ":" + digest;
+
+  ldout(cct, 15) << "generated auth header: " << auth_hdr << dendl;
 
   headers.push_back(make_pair<string, string>("AUTHORIZATION", auth_hdr));
   int r = process(method, new_url.c_str());
@@ -113,4 +96,3 @@ int RGWRESTClient::execute(RGWAccessKey& key, const char *method, const char *re
   return rgw_http_error_to_errno(status);
 }
 
-
index 51ce032678a85b3fabec94e8181bd5b88bc97f7e..082b310f351d8a2385504b14654ab0467ca82209 100644 (file)
@@ -7,13 +7,12 @@
 
 #include "rgw_rest.h"
 #include "rgw_rest_s3.h"
+#include "rgw_auth_s3.h"
 #include "rgw_acl.h"
 #include "rgw_policy_s3.h"
 #include "rgw_user.h"
 #include "rgw_cors.h"
 
-#include "common/armor.h"
-
 #include "rgw_client_io.h"
 
 #define dout_subsys ceph_subsys_rgw
@@ -1901,121 +1900,10 @@ int RGWHandler_ObjStore_S3::init(RGWRados *store, struct req_state *s, RGWClient
   return RGWHandler_ObjStore::init(store, s, cio);
 }
 
-static const char *signed_subresources[] = {
-  "acl",
-  "lifecycle",
-  "location",
-  "logging",
-  "notification",
-  "partNumber",
-  "policy",
-  "requestPayment",
-  "torrent",
-  "uploadId",
-  "uploads",
-  "versionId",
-  "versioning",
-  "versions",
-  "website",
-  NULL
-};
-
-/*
- * ?get the canonical amazon-style header for something?
- */
-
-static void get_canon_amz_hdr(map<string, string>& meta_map, string& dest)
-{
-  dest = "";
-  map<string, string>::iterator iter;
-  for (iter = meta_map.begin(); iter != meta_map.end(); ++iter) {
-    dest.append(iter->first);
-    dest.append(":");
-    dest.append(iter->second);
-    dest.append("\n");
-  }
-}
-
-/*
- * ?get the canonical representation of the object's location
- */
-static void get_canon_resource(const char *request_uri, map<string, string>& sub_resources, string& dest)
-{
-  string s;
-
-  if (request_uri)
-    s.append(request_uri);
-
-  string append_str;
-
-  const char **p = signed_subresources;
-
-  for (; *p; ++p) {
-    map<string, string>::iterator iter = sub_resources.find(*p);
-    if (iter == sub_resources.end())
-      continue;
-    
-    if (append_str.empty())
-      append_str.append("?");
-    else
-      append_str.append("&");     
-    append_str.append(iter->first);
-    if (!iter->second.empty()) {
-      append_str.append("=");
-      append_str.append(iter->second);
-    }
-  }
-  if (!append_str.empty()) {
-    s.append(append_str);
-  }
-  dout(10) << "get_canon_resource(): dest=" << dest << dendl;
-
-  dest = s;
-}
-
 static inline bool is_base64_for_content_md5(unsigned char c) {
   return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '='));
 }
 
-/*
- * get the header authentication  information required to
- * compute a request's signature
- */
-void rgw_create_s3_auth_header(const char *method, const char *content_md5, const char *content_type, const char *date,
-                            map<string, string>& meta_map, const char *request_uri, map<string, string>& sub_resources,
-                            string& dest_str)
-{
-  string dest;
-
-  if (method)
-    dest = method;
-  dest.append("\n");
-  
-  if (content_md5) {
-    dest.append(content_md5);
-  }
-  dest.append("\n");
-
-  if (content_type)
-    dest.append(content_type);
-  dest.append("\n");
-
-  if (date)
-    dest.append(date);
-  dest.append("\n");
-
-  string canon_amz_hdr;
-  get_canon_amz_hdr(meta_map, canon_amz_hdr);
-  dest.append(canon_amz_hdr);
-
-  string canon_resource;
-  get_canon_resource(request_uri, sub_resources, canon_resource);
-
-  dest.append(canon_resource);
-
-  dest_str = dest;
-}
-
 /*
  * get the header authentication  information required to
  * compute a request's signature
@@ -2065,7 +1953,7 @@ static bool get_auth_header(req_info& info, utime_t& header_time, string& dest,
   map<string, string>& meta_map = info.x_meta_map;
   map<string, string>& sub_resources = info.args.get_sub_resources();
 
-  rgw_create_s3_auth_header(info.method, content_md5, content_type, date.c_str(),
+  rgw_create_s3_canonical_header(info.method, content_md5, content_type, date.c_str(),
                             meta_map, info.request_uri.c_str(), sub_resources,
                             dest);
 
@@ -2147,8 +2035,6 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
     return -EPERM;
   }
   RGWAccessKey& k = iter->second;
-  const char *key = k.key.c_str();
-  int key_len = k.key.size();
 
   if (!k.subuser.empty()) {
     map<string, RGWSubUser>::iterator uiter = s->user.subusers.find(k.subuser);
@@ -2161,23 +2047,17 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
   } else
     s->perm_mask = RGW_PERM_FULL_CONTROL;
 
-  char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
-  calc_hmac_sha1(key, key_len, auth_hdr.c_str(), auth_hdr.size(), hmac_sha1);
-
-  char b64[64]; /* 64 is really enough */
-  int ret = ceph_armor(b64, b64 + 64, hmac_sha1,
-                      hmac_sha1 + CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
+  string digest;
+  int ret = rgw_get_s3_header_digest(auth_hdr, k.key, digest);
   if (ret < 0) {
-    dout(10) << "ceph_armor failed" << dendl;
     return -EPERM;
   }
-  b64[ret] = '\0';
 
-  dout(15) << "b64=" << b64 << dendl;
+  dout(15) << "calculated digest=" << digest << dendl;
   dout(15) << "auth_sign=" << auth_sign << dendl;
-  dout(15) << "compare=" << auth_sign.compare(b64) << dendl;
+  dout(15) << "compare=" << auth_sign.compare(digest) << dendl;
 
-  if (auth_sign.compare(b64) != 0)
+  if (auth_sign != digest)
     return -EPERM;
 
   if (s->user.system) {