Commit 04db842d authored by Chris Busbey's avatar Chris Busbey

added ready for meta data exchange at end of gss handshake

parent 761508bf
......@@ -32,8 +32,7 @@
#include "wire.hpp"
zmq::gssapi_client_t::gssapi_client_t (const options_t &options_) :
gssapi_mechanism_base_t (),
mechanism_t (options_),
gssapi_mechanism_base_t (options_),
state (call_next_init),
token_ptr (GSS_C_NO_BUFFER),
mechs (),
......@@ -55,6 +54,14 @@ zmq::gssapi_client_t::~gssapi_client_t ()
int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
{
if (state == send_ready) {
int rc = produce_ready(msg_);
if (rc == 0)
state = connected;
return rc;
}
if (security_context_established) {
state = connected;
return 0;
......@@ -74,8 +81,10 @@ int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
if (maj_stat != GSS_S_CONTINUE_NEEDED && maj_stat != GSS_S_COMPLETE)
return -1;
if (maj_stat == GSS_S_COMPLETE)
if (maj_stat == GSS_S_COMPLETE) {
security_context_established = true;
state = recv_ready;
}
else
state = recv_next_token;
......@@ -84,6 +93,14 @@ int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
{
if (state == recv_ready) {
int rc = process_ready(msg_);
if (rc == 0)
state = send_ready;
return rc;
}
if (state != recv_next_token) {
errno = EPROTO;
return -1;
......@@ -92,13 +109,11 @@ int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
if (process_next_token (msg_) < 0)
return -1;
if (maj_stat == GSS_S_COMPLETE)
security_context_established = true;
else if (maj_stat == GSS_S_CONTINUE_NEEDED)
state = call_next_init;
else
if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
return -1;
state = call_next_init;
errno_assert (msg_->close () == 0);
errno_assert (msg_->init () == 0);
......
......@@ -21,8 +21,6 @@
#define __ZMQ_GSSAPI_CLIENT_HPP_INCLUDED__
#include "gssapi_mechanism_base.hpp"
#include "mechanism.hpp"
#include "options.hpp"
namespace zmq
{
......@@ -30,8 +28,7 @@ namespace zmq
class msg_t;
class gssapi_client_t :
public gssapi_mechanism_base_t,
public mechanism_t
public gssapi_mechanism_base_t
{
public:
......@@ -51,6 +48,8 @@ namespace zmq
call_next_init,
send_next_token,
recv_next_token,
send_ready,
recv_ready,
connected
};
......
......@@ -31,7 +31,8 @@
#include "gssapi_mechanism_base.hpp"
#include "wire.hpp"
zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t () :
zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t (const options_t & options_) :
mechanism_t(options_),
send_tok (),
recv_tok (),
/// FIXME remove? in_buf (),
......@@ -235,6 +236,52 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
return 0;
}
int zmq::gssapi_mechanism_base_t::produce_ready (msg_t *msg_) const
{
unsigned char * const command_buffer = (unsigned char *) malloc (512);
alloc_assert (command_buffer);
unsigned char *ptr = command_buffer;
// Add command name
memcpy (ptr, "\x05READY", 6);
ptr += 6;
// Add socket type property
const char *socket_type = socket_type_string (options.type);
ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type));
// Add identity property
if (options.type == ZMQ_REQ
|| options.type == ZMQ_DEALER
|| options.type == ZMQ_ROUTER) {
ptr += add_property (ptr, "Identity",
options.identity, options.identity_size);
}
const size_t command_size = ptr - command_buffer;
const int rc = msg_->init_size (command_size);
errno_assert (rc == 0);
memcpy (msg_->data (), command_buffer, command_size);
free (command_buffer);
return 0;
}
int zmq::gssapi_mechanism_base_t::process_ready (msg_t *msg_)
{
const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
size_t bytes_left = msg_->size ();
if (bytes_left < 6 || memcmp (ptr, "\x05READY", 6)) {
errno = EPROTO;
return -1;
}
ptr += 6;
bytes_left -= 6;
return parse_metadata (ptr, bytes_left);
}
int zmq::gssapi_mechanism_base_t::acquire_credentials (char * service_name_, gss_cred_id_t * cred_)
{
OM_uint32 maj_stat;
......
......@@ -22,7 +22,9 @@
#include <gssapi/gssapi_generic.h>
#include <gssapi/gssapi_krb5.h>
#include <gssapi/gssapi_ext.h>
#include "mechanism.hpp"
#include "options.hpp"
namespace zmq
{
......@@ -33,10 +35,11 @@ namespace zmq
/// For example, clients and servers both need to produce and
/// process context-level GSSAPI tokens (via INITIATE commands)
/// and per-message GSSAPI tokens (via MESSAGE commands).
class gssapi_mechanism_base_t
class gssapi_mechanism_base_t:
public mechanism_t
{
public:
gssapi_mechanism_base_t ();
gssapi_mechanism_base_t (const options_t &options_);
virtual ~gssapi_mechanism_base_t () = 0;
protected:
......@@ -47,6 +50,12 @@ namespace zmq
// Process a context-level GSSAPI token (INITIATE command)
// during security context initialization.
int process_initiate (msg_t *msg_, void **data_, size_t &data_len_);
// Produce a metadata ready msg (READY) to conclude handshake
int produce_ready (msg_t *msg_) const;
// Process a metadata ready msg (READY)
int process_ready (msg_t *msg_);
// Encode a per-message GSSAPI token (MESSAGE command) using
// the established security context.
......
......@@ -34,8 +34,7 @@
zmq::gssapi_server_t::gssapi_server_t (session_base_t *session_,
const std::string &peer_address_,
const options_t &options_) :
gssapi_mechanism_base_t (),
mechanism_t (options_),
gssapi_mechanism_base_t (options_),
session (session_),
peer_address (peer_address_),
state (recv_next_token),
......@@ -57,6 +56,14 @@ zmq::gssapi_server_t::~gssapi_server_t ()
int zmq::gssapi_server_t::next_handshake_command (msg_t *msg_)
{
if (state == send_ready) {
int rc = produce_ready(msg_);
if (rc == 0)
state = recv_ready;
return rc;
}
if (state != send_next_token) {
errno = EAGAIN;
return -1;
......@@ -71,22 +78,33 @@ int zmq::gssapi_server_t::next_handshake_command (msg_t *msg_)
if (maj_stat == GSS_S_COMPLETE) {
gss_release_name(&min_stat, &target_name);
security_context_established = true;
state = connected;
}
else {
state = recv_next_token;
}
state = recv_next_token;
return 0;
}
int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
{
if (state == recv_ready) {
int rc = process_ready(msg_);
if (rc == 0)
state = connected;
return rc;
}
if (state != recv_next_token) {
errno = EPROTO;
return -1;
}
if (security_context_established) {
state = send_ready;
return 0;
}
if (process_next_token (msg_) < 0)
return -1;
......
......@@ -21,8 +21,6 @@
#define __ZMQ_GSSAPI_SERVER_HPP_INCLUDED__
#include "gssapi_mechanism_base.hpp"
#include "mechanism.hpp"
#include "options.hpp"
namespace zmq
{
......@@ -31,8 +29,7 @@ namespace zmq
class session_base_t;
class gssapi_server_t :
public gssapi_mechanism_base_t,
public mechanism_t
public gssapi_mechanism_base_t
{
public:
......@@ -54,6 +51,8 @@ namespace zmq
enum state_t {
send_next_token,
recv_next_token,
send_ready,
recv_ready,
connected
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment