]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
auth: merge envelope, cephx handshake
authorSage Weil <sage@newdream.net>
Thu, 22 Oct 2009 23:16:06 +0000 (16:16 -0700)
committerSage Weil <sage@newdream.net>
Thu, 22 Oct 2009 23:51:20 +0000 (16:51 -0700)
src/auth/AuthClientHandler.cc
src/auth/AuthClientHandler.h
src/auth/AuthServiceHandler.cc

index 38fe33d0e46a73fc8d864db6ff13a78b899dedb5..b2a24f21eaef40e3e66a544858f9b144654546ad 100644 (file)
@@ -77,7 +77,7 @@ int AuthClientAuthenticateHandler::generate_authenticate_request(bufferlist& bl)
     return -EINVAL;
   }
 
-  switch(request_state) {
+  switch (request_state) {
   case 0:
     /* initialize  */
     { 
@@ -90,7 +90,7 @@ int AuthClientAuthenticateHandler::generate_authenticate_request(bufferlist& bl)
     }
     break;
   case 1:
-   /* authenticate */
+    /* authenticate */
     {
       /* FIXME: init req fields */
       CephXEnvRequest2 req;
@@ -110,113 +110,83 @@ int AuthClientAuthenticateHandler::generate_authenticate_request(bufferlist& bl)
       }
       req.piggyback = 1;
       ::encode(req, bl);
-      request_state++;
-      return generate_cephx_authenticate_request(bl);
+
+      /* we first need to get the principle/auth session key */
+      CephXRequestHeader header;
+      header.request_type = CEPHX_GET_AUTH_SESSION_KEY;
+      ::encode(header, bl);
+      build_authenticate_request(client->name, bl);
+      request_state = 2;
+      return 0;
+    }
+    break;
+
+  case 2:
+    /* get service tickets */
+    {
+      dout(0) << "want=" << hex << want << " have=" << have << dec << dendl;
+      if (want == have) {
+       response_state = 2;
+       return 0;
+      }
+
+      AuthTicketHandler& ticket_handler = client->tickets.get_handler(CEPH_ENTITY_TYPE_AUTH);
+      if (!ticket_handler.build_authorizer(authorizer))
+       return -EINVAL;
+
+      CephXRequestHeader header;
+      header.request_type = CEPHX_GET_PRINCIPAL_SESSION_KEY;
+      ::encode(header, bl);
+      
+      bl.claim_append(authorizer.bl);
+      build_service_ticket_request(want, bl);
     }
     break;
+
   default:
-    return generate_cephx_authenticate_request(bl);
+    assert(0);
   }
   request_state++;
   return 0;
 }
 
-int AuthClientAuthenticateHandler::_handle_response(int ret, bufferlist::iterator& iter)
+int AuthClientAuthenticateHandler::_handle_response(int ret, bufferlist::iterator& indata)
 {
-
   if (ret != 0 && ret != -EAGAIN) {
     response_state = request_state;
-    cephx_response_state = cephx_request_state;
     return ret;
   }
 
   dout(0) << "AuthClientHandler::handle_response()" << dendl;
-  switch(response_state) {
+  switch (response_state) {
   case 0:
     /* initialize  */
     { 
       CephXEnvResponse1 response;
 
       response_state++;
-      ::decode(response, iter);
+      ::decode(response, indata);
       server_challenge = response.server_challenge;
     }
     break;
   case 1:
     /* authenticate */
     {
-      response_state++;
-      return handle_cephx_response(iter);
-    }
-    break;
-  default:
-    return handle_cephx_response(iter);
-  }
-  return -EAGAIN;
-}
-
-int AuthClientAuthenticateHandler::generate_cephx_authenticate_request(bufferlist& bl)
-{
-  CephXRequestHeader header;
-  AuthTicketHandler& ticket_handler = client->tickets.get_handler(CEPH_ENTITY_TYPE_AUTH);
-
-  if (!ticket_handler.has_key()) {
-    dout(0) << "auth ticket: doesn't have key" << dendl;
-    /* we first need to get the principle/auth session key */
-
-    header.request_type = CEPHX_GET_AUTH_SESSION_KEY;
-
-    ::encode(header, bl);
-
-    build_authenticate_request(client->name, bl);
-    cephx_request_state = 1;
-    return 0;
-  }
-
-  dout(0) << "want=" << hex << want << " have=" << have << dec << dendl;
-
-  cephx_request_state = 2;
-
-  if (want == have) {
-    cephx_response_state = 2;
-    return 0;
-  }
-
-  header.request_type = CEPHX_GET_PRINCIPAL_SESSION_KEY;
-
-  ::encode(header, bl);
-
-  if (!ticket_handler.build_authorizer(authorizer))
-    return -EINVAL;
-
-  bl.claim_append(authorizer.bl);
-
-  build_service_ticket_request(want, bl);
-  
-  return 0;
-}
-
-int AuthClientAuthenticateHandler::handle_cephx_response(bufferlist::iterator& indata)
-{
-  int ret = 0;
-  struct CephXResponseHeader header;
-  ::decode(header, indata);
-
-  dout(0) << "request_type=" << hex << header.request_type << dec << dendl;
-  dout(0) << "handle_cephx_response()" << dendl;
+      struct CephXResponseHeader header;
+      ::decode(header, indata);
 
-  switch (header.request_type & CEPHX_REQUEST_TYPE_MASK) {
-  case CEPHX_GET_AUTH_SESSION_KEY:
-    cephx_response_state = 1;
-    dout(0) << "CEPHX_GET_AUTH_SESSION_KEY" << dendl;
+      dout(0) << "request_type=" << hex << header.request_type << dec << dendl;
+      dout(0) << "handle_cephx_response()" << dendl;
 
-    {
+      response_state = 2;
+      dout(0) << "CEPHX_GET_AUTH_SESSION_KEY" << dendl;
+      
       CryptoKey secret;
       g_keyring.get_master(secret);
-
+       
       if (!client->tickets.verify_service_ticket_reply(secret, indata)) {
-        dout(0) << "could not verify service_ticket reply" << dendl;
-        return -EPERM;
+       dout(0) << "could not verify service_ticket reply" << dendl;
+       return -EPERM;
       }
       dout(0) << "want=" << want << " have=" << have << dendl;
       if (want != have)
@@ -224,34 +194,29 @@ int AuthClientAuthenticateHandler::handle_cephx_response(bufferlist::iterator& i
     }
     break;
 
-  case CEPHX_GET_PRINCIPAL_SESSION_KEY:
-    cephx_response_state = 2;
-    dout(0) << "CEPHX_GET_PRINCIPAL_SESSION_KEY" << dendl;
+  case 2:
     {
+      struct CephXResponseHeader header;
+      ::decode(header, indata);
+      response_state = 3;
+      dout(0) << "CEPHX_GET_PRINCIPAL_SESSION_KEY" << dendl;
+
       AuthTicketHandler& ticket_handler = client->tickets.get_handler(CEPH_ENTITY_TYPE_AUTH);
   
       if (!client->tickets.verify_service_ticket_reply(ticket_handler.session_key, indata)) {
         dout(0) << "could not verify service_ticket reply" << dendl;
         return -EPERM;
       }
+      ret = 0;
     }
-    ret = 0;
     break;
 
   default:
-    dout(0) << "header.request_type = " << hex << header.request_type << dec << dendl;
-    ret = -EINVAL;
-    break;
+    assert(0);
   }
-
   return ret;
 }
 
-bool AuthClientAuthenticateHandler::request_pending() {
-  dout(0) << "request_pending(): request_state=" << cephx_request_state << " cephx_response_state=" << cephx_response_state << dendl;
-  return (request_state != response_state) || (cephx_request_state != cephx_response_state);
-}
-
 int AuthClientAuthenticateHandler::_build_request()
 {
   MAuth *m = (MAuth *)msg;
index a14ed240c549ad68de52cf298b49bcdfe8a3c6f4..917c08d13ab68466062b08851c0ab1d6ff9aca72 100644 (file)
@@ -69,17 +69,10 @@ class AuthClientAuthenticateHandler : public AuthClientProtocolHandler {
   int request_state;
   int response_state;
 
-  int cephx_request_state;
-  int cephx_response_state;
-
   /* envelope protocol parameters */
   uint64_t server_challenge;
 
-  /* envelope protocol */
   int generate_authenticate_request(bufferlist& bl);
-  /* auth protocol */
-  int generate_cephx_authenticate_request(bufferlist& bl);
-  int handle_cephx_response(bufferlist::iterator& indata);
 
   uint32_t want;
   uint32_t have;
@@ -88,12 +81,8 @@ protected:
   void _reset() {
     request_state = 0;
     response_state = 0;
-    cephx_request_state = 0;
-    cephx_response_state = 0;
   }
 
-  bool request_pending();
-
   int _build_request();
   int _handle_response(int ret, bufferlist::iterator& iter);
   Message *_get_new_msg();
index 7b150112d4b4e4cdf00bc3e45f069e51f8eb4b60..735bca2a8b02f7bace1b796210b623de250c5d91 100644 (file)
@@ -46,12 +46,11 @@ public:
 int CephAuthService_X::handle_request(bufferlist::iterator& indata, bufferlist& result_bl)
 {
   int ret = 0;
-  bool piggyback = false;
 
   dout(0) << "CephAuthService_X: handle request" << dendl;
   dout(0) << "state=" << state << dendl;
 
-  switch(state) {
+  switch (state) {
   case 0:
     {
       CephXEnvRequest1 req;
@@ -92,59 +91,26 @@ int CephAuthService_X::handle_request(bufferlist::iterator& indata, bufferlist&
       if (req.key != expected_key) {
         dout(0) << "unexpected key: req.key=" << req.key << " expected_key=" << expected_key << dendl;
         ret = -EPERM;
-      } else {
-       ret = 0;
-        piggyback = req.piggyback;
+       break;
       }
-    }
-    break;
-
-  case 2:
-    return handle_cephx_protocol(indata, result_bl);
-  default:
-    return -EINVAL;
-  }
-
-  if (!ret && piggyback) {
-    ret = handle_cephx_protocol(indata, result_bl);
-  }
-
-  if (!ret || (ret == -EAGAIN)) {
-    state++;
-  }
-  dout(0) << "returning with state=" << state << dendl;
-  return ret;
-}
 
-int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, bufferlist& result_bl)
-{
-  struct CephXRequestHeader cephx_header;
-
-  ::decode(cephx_header, indata);
-
-  uint16_t request_type = cephx_header.request_type & CEPHX_REQUEST_TYPE_MASK;
-  int ret = -EAGAIN;
-
-  dout(0) << "request_type=" << request_type << dendl;
-
-  switch (request_type) {
-  case CEPHX_GET_AUTH_SESSION_KEY:
-    {
       dout(0) << "CEPHX_GET_AUTH_SESSION_KEY" << dendl;
+      struct CephXRequestHeader cephx_header;
+      ::decode(cephx_header, indata);
 
-      AuthAuthenticateRequest req;
-      ::decode(req, indata);
+      AuthAuthenticateRequest areq;
+      ::decode(areq, indata);
 
       CryptoKey session_key;
       SessionAuthInfo info;
 
       CryptoKey principal_secret;
-      if (mon->key_server.get_secret(req.name, principal_secret) < 0) {
+      if (mon->key_server.get_secret(areq.name, principal_secret) < 0) {
        ret = -EPERM;
        break;
       }
 
-      info.ticket.name = req.name;
+      info.ticket.name = areq.name;
       info.ticket.init_timestamps(g_clock.now(), g_conf.auth_mon_ticket_ttl);
 
       mon->key_server.generate_secret(session_key);
@@ -160,7 +126,7 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe
       vector<SessionAuthInfo> info_vec;
       info_vec.push_back(info);
 
-      build_cephx_response_header(request_type, 0, result_bl);
+      build_cephx_response_header(cephx_header.request_type, 0, result_bl);
       if (!build_service_ticket_reply(principal_secret, info_vec, result_bl)) {
         ret = -EIO;
         break;
@@ -168,9 +134,12 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe
     }
     break;
 
-  case CEPHX_GET_PRINCIPAL_SESSION_KEY:
-    dout(0) << "CEPHX_GET_PRINCIPAL_SESSION_KEY " << cephx_header.request_type << dendl;
+  case 2:
     {
+      struct CephXRequestHeader cephx_header;
+      ::decode(cephx_header, indata);
+      dout(0) << "CEPHX_GET_PRINCIPAL_SESSION_KEY " << cephx_header.request_type << dendl;
+
       bufferlist tmp_bl;
       AuthServiceTicketInfo auth_ticket_info;
       if (!verify_authorizer(mon->key_server, indata, auth_ticket_info, tmp_bl)) {
@@ -197,16 +166,19 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe
           info_vec.push_back(info);
         }
       }
-      build_cephx_response_header(request_type, ret, result_bl);
+      build_cephx_response_header(cephx_header.request_type, ret, result_bl);
       build_service_ticket_reply(auth_ticket_info.session_key, info_vec, result_bl);
     }
     break;
+
   default:
-    ret = -EINVAL;
-    build_cephx_response_header(request_type, -EINVAL, result_bl);
-    break;
+    return -EINVAL;
   }
 
+  if (!ret || (ret == -EAGAIN)) {
+    state++;
+  }
+  dout(0) << "returning with state=" << state << dendl;
   return ret;
 }