#include "AuthProtocol.h"
#include "AuthClientHandler.h"
+#include "messages/MAuth.h"
#include "messages/MAuthReply.h"
-#if 0
+
int AuthClientHandler::generate_request(bufferlist& bl)
{
dout(0) << "status=" << status << dendl;
}
-int AuthClientHandler::handle_response(int ret, bufferlist& bl)
+int AuthClientHandler::handle_response(Message *response)
{
-char buf[4096];
+ bufferlist bl;
+ int ret;
+
+#if 1
+ char buf[4096];
const char *s = bl.c_str();
int pos = 0;
for (unsigned int i=0; i<bl.length() && pos<sizeof(buf) - 8; i++) {
pos += snprintf(&buf[pos], sizeof(buf)-pos, "\n");
}
dout(0) << "result_buf=" << buf << dendl;
+#endif
+ MAuthReply* m = (MAuthReply *)response;
+ bl = m->result_bl;
+ ret = m->result;
+
+ got_response = true;
bufferlist::iterator iter = bl.begin();
if (ret != 0 && ret != -EAGAIN) {
response_state = request_state;
cephx_response_state = cephx_request_state;
- status = ret;
return ret;
}
{
CephXEnvResponse1 response;
+ response_state++;
::decode(response, iter);
server_challenge = response.server_challenge;
}
default:
return handle_cephx_protocol_response(iter);
}
- response_state++;
- return -EAGAIN;
+ return -EAGAIN;
}
int AuthClientHandler::generate_cephx_protocol_request(bufferlist& bl)
return 0;
}
- dout(0) << "want_keys=" << hex << want_keys << " have_keys=" << have_keys << dec << dendl;
+ dout(0) << "want=" << hex << want << " have=" << have << dec << dendl;
cephx_request_state = 2;
- if (want_keys == have_keys) {
+ if (want == have) {
cephx_response_state = 2;
return 0;
}
header.request_type = CEPHX_GET_PRINCIPAL_SESSION_KEY;
::encode(header, bl);
- build_service_ticket_request(name, addr, want_keys,
+ build_service_ticket_request(name, addr, want,
true, ticket_handler.session_key, ticket_handler.ticket, bl);
return 0;
return -EPERM;
}
- if (want_keys)
+ if (want)
ret = -EAGAIN;
}
break;
return (request_state != response_state) || (cephx_request_state != cephx_response_state);
}
-#endif
// -----------
-void AuthClientHandler::handle_auth_reply(MAuthReply *m)
+int AuthClientHandler::start_session(AuthClient *client, double timeout)
{
Mutex::Locker l(lock);
- dout(10) << "handle_auth_reply " << *m << dendl;
+ this->client = client;
+ dout(10) << "start_session" << dendl;
+ _reset();
+ do {
+ status = 0;
+ int err = _do_request(timeout);
+ dout(0) << "_do_request returned " << err << dendl;
+ if (err < 0)
+ return err;
+
+ } while (status == -EAGAIN);
+
+ return status;
}
-void AuthClientHandler::start_session()
+void AuthClientHandler::tick()
{
Mutex::Locker l(lock);
- dout(10) << "start_session" << dendl;
- _reset();
+ // do i need to renew any tickets?
// ...
+
}
-void AuthClientHandler::tick()
+Message *AuthClientHandler::build_request()
+{
+ MAuth *msg = new MAuth;
+ if (!msg)
+ return NULL;
+ bufferlist& bl = msg->get_auth_payload();
+
+ if (generate_request(bl) < 0) {
+ delete msg;
+ return NULL;
+ }
+
+ return msg;
+}
+
+int AuthClientHandler::_do_request(double timeout)
+{
+ Message *msg = build_request();
+
+ if (!msg)
+ return -EIO;
+
+ got_response = false;
+
+ client->send_message(msg);
+
+ // schedule timeout?
+ assert(timeout_event == 0);
+ timeout_event = new C_OpTimeout(this, timeout);
+ timer.add_event_after(timeout, timeout_event);
+
+ Cond request_cond;
+
+ cur_request_cond = &request_cond;
+
+ dout(0) << "got_response=" << got_response << " got_timeout=" << got_timeout << dendl;
+
+ while (!got_response && !got_timeout) {
+ request_cond.Wait(lock);
+ }
+
+ cur_request_cond = NULL;
+
+ // finish.
+ timer.cancel_event(timeout_event);
+ timeout_event = 0;
+
+ return 0;
+}
+
+void AuthClientHandler::_request_timeout(double timeout)
{
Mutex::Locker l(lock);
+ dout(10) << "_op_timeout" << dendl;
+ timeout_event = 0;
+ if (!got_response) {
+ got_timeout = 1;
+ assert(cur_request_cond);
+ cur_request_cond->Signal();
+ }
+ status = -ETIMEDOUT;
+}
- // do i need to renew any tickets?
- // ...
+void AuthClientHandler::handle_auth_reply(MAuthReply *m)
+{
+ Mutex::Locker l(lock);
+ status = handle_response(m);
+ cur_request_cond->Signal();
}
+
#include "auth/Auth.h"
+#include "auth/AuthClient.h"
#include "common/Mutex.h"
#include "common/Cond.h"
+#include "common/Timer.h"
+
class MAuthReply;
+class Message;
+class AuthClient;
class AuthClientHandler {
Mutex lock;
- Cond cond;
+ Cond keys_cond;
+ Cond *cur_request_cond;
+ Context *timeout_event;
uint32_t want;
uint32_t have;
int cephx_request_state;
int cephx_response_state;
+ bool got_response;
+ bool got_timeout;
+
EntityName name;
entity_addr_t addr;
CryptoKey secret;
+ AuthClient *client;
+
+ bool request_pending();
+ Message *build_request();
+
+ int generate_request(bufferlist& bl);
+ int handle_response(Message *response);
int generate_cephx_protocol_request(bufferlist& bl);
int handle_cephx_protocol_response(bufferlist::iterator& indata);
status = 0;
cephx_request_state = 0;
cephx_response_state = 0;
+ got_response = false;
+ got_timeout = false;
+ timeout_event = NULL;
+ cur_request_cond = NULL;
}
+ SafeTimer timer;
+
+ class C_OpTimeout : public Context {
+ protected:
+ AuthClientHandler *client_handler;
+ double timeout;
+ public:
+ C_OpTimeout(AuthClientHandler *handler, double to) :
+ client_handler(handler), timeout(to) {
+ }
+ void finish(int r) {
+ if (r >= 0) client_handler->_request_timeout(timeout);
+ }
+ };
+
+ void _request_timeout(double timeout);
+ int _do_request(double timeout);
public:
AuthClientHandler() : lock("AuthClientHandler::lock"),
- want(0), have(0) {
+ want(0), have(0), client(NULL), timer(lock) {
_reset();
}
utime_t t;
t += timeout;
while ((want & have) != have)
- cond.WaitInterval(lock, t);
+ keys_cond.WaitInterval(lock, t);
return (want & have) == have;
}
- void start_session();
+ int start_session(AuthClient *client, double timeout);
void handle_auth_reply(MAuthReply *m);
void tick();
};