Commit 6290ba16 authored by Mike Gatny's avatar Mike Gatny Committed by Chris Busbey

Added gss produce/process routines.

For exchanging tokens.
parent c00b8c34
......@@ -58,7 +58,7 @@ int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
state = waiting_for_token;
break;
case sending_token:
rc = produce_token (msg_);
rc = produce_token (msg_, 0, (char *) "o, hai!", 7);
if (rc == 0)
state = waiting_for_ready; //state = expecting_another_token? waiting_for_token: waiting_for_ready;
break;
......@@ -72,6 +72,10 @@ int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
{
int rc = 0;
int flags = 0;
gss_buffer_desc buf;
buf.value = NULL;
buf.length = 0;
switch (state) {
case waiting_for_welcome:
......@@ -80,7 +84,7 @@ int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
state = sending_initiate;
break;
case waiting_for_token:
rc = process_token (msg_);
rc = process_token (msg_, flags, &buf.value, buf.length);
if (rc == 0)
state = sending_token; // state = expecting_another_token? sending_token: sending_ready;
break;
......@@ -94,12 +98,18 @@ int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
rc = -1;
break;
}
if (buf.value) {
free (buf.value);
}
if (rc == 0) {
rc = msg_->close ();
errno_assert (rc == 0);
rc = msg_->init ();
errno_assert (rc == 0);
}
return rc;
}
......
......@@ -28,7 +28,6 @@ namespace zmq
{
class msg_t;
class session_base_t;
class gssapi_client_t :
public gssapi_mechanism_base_t,
......@@ -45,7 +44,7 @@ namespace zmq
virtual bool is_handshake_complete () const;
private:
enum state_t {
sending_hello,
waiting_for_welcome,
......
......@@ -31,8 +31,7 @@
#include "gssapi_mechanism_base.hpp"
#include "wire.hpp"
zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t () :
gss_continue_needed (false)
zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t ()
{
}
......@@ -40,37 +39,91 @@ zmq::gssapi_mechanism_base_t::~gssapi_mechanism_base_t ()
{
}
int zmq::gssapi_mechanism_base_t::produce_token (msg_t *msg_) const
int zmq::gssapi_mechanism_base_t::produce_token (msg_t *msg_, int flags_, void *token_value_, size_t token_length_)
{
unsigned char * const command_buffer = (unsigned char *) malloc (512);
alloc_assert (command_buffer);
zmq_assert (token_value_);
zmq_assert (token_length_ <= 0xFFFFFFFFUL);
unsigned char *ptr = command_buffer;
const size_t cmd_len = 6 + 1 + 4 + token_length_;
uint8_t *cmd_buf = static_cast <uint8_t *> (malloc (cmd_len));
alloc_assert (cmd_buf);
uint8_t *ptr = cmd_buf;
// Add command name
memcpy (ptr, "\x05TOKEN", 6);
ptr += 6;
const size_t command_size = ptr - command_buffer;
const int rc = msg_->init_size (command_size);
// Add gss flags
put_uint8 (ptr, static_cast <uint8_t> (flags_));
ptr += 1;
// Add token length
put_uint32 (ptr, static_cast <uint32_t> (token_length_));
ptr += 4;
// Add token value
memcpy (ptr, token_value_, token_length_);
ptr += token_length_;
const int rc = msg_->init_size (cmd_len);
errno_assert (rc == 0);
memcpy (msg_->data (), command_buffer, command_size);
free (command_buffer);
memcpy (msg_->data (), cmd_buf, cmd_len);
free (cmd_buf);
return 0;
}
int zmq::gssapi_mechanism_base_t::process_token (msg_t *msg_)
int zmq::gssapi_mechanism_base_t::process_token (msg_t *msg_, int &flags_, void **token_value_, size_t &token_length_)
{
const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
zmq_assert (token_value_);
uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
size_t bytes_left = msg_->size ();
// Get command name
if (bytes_left < 6 || memcmp (ptr, "\x05TOKEN", 6)) {
errno = EPROTO;
return -1;
}
ptr += 6;
bytes_left -= 6;
// Get flags
if (bytes_left < 1) {
errno = EPROTO;
return -1;
}
flags_ = static_cast <int> (get_uint8 (ptr));
ptr += 1;
bytes_left -= 1;
// Get token length
if (bytes_left < 4) {
errno = EPROTO;
return -1;
}
token_length_ = get_uint32 (ptr);
ptr += 4;
bytes_left -= 4;
// Get token value
if (bytes_left < token_length_) {
errno = EPROTO;
return -1;
}
*token_value_ = static_cast <char *> (malloc (token_length_ ? token_length_ : 1));
if (token_length_) {
alloc_assert (*token_value_);
memcpy(*token_value_, ptr, token_length_);
ptr += token_length_;
bytes_left -= token_length_;
}
if (bytes_left > 0) {
errno = EPROTO;
return -1;
}
return 0;
}
......
......@@ -20,6 +20,10 @@
#ifndef __ZMQ_GSSAPI_MECHANISM_BASE_HPP_INCLUDED__
#define __ZMQ_GSSAPI_MECHANISM_BASE_HPP_INCLUDED__
#include <gssapi/gssapi_generic.h>
#include <gssapi/gssapi_krb5.h>
#include <gssapi/gssapi_ext.h>
namespace zmq
{
......@@ -35,12 +39,8 @@ namespace zmq
virtual ~gssapi_mechanism_base_t () = 0;
protected:
// True iff we are awaiting another GSSAPI token.
bool gss_continue_needed;
int produce_token (msg_t *msg_) const;
int process_token (msg_t *msg_);
int produce_token (msg_t *msg_, int flags_, void *token_value_, size_t token_length_);
int process_token (msg_t *msg_, int &flags_, void **token_value_, size_t &token_length_);
};
}
......
......@@ -58,7 +58,7 @@ int zmq::gssapi_server_t::next_handshake_command (msg_t *msg_)
state = waiting_for_initiate;
break;
case sending_token:
rc = produce_token (msg_);
rc = produce_token (msg_, 0, (char *) "kthx! bye!", 10);
if (rc == 0)
state = waiting_for_token; //state = expecting_another_token? waiting_for_token: waiting_for_ready;
break;
......@@ -77,6 +77,10 @@ int zmq::gssapi_server_t::next_handshake_command (msg_t *msg_)
int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
{
int rc = 0;
int flags = 0;
gss_buffer_desc buf;
buf.value = NULL;
buf.length = 0;
switch (state) {
case waiting_for_hello:
......@@ -90,7 +94,7 @@ int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
state = sending_token;
break;
case waiting_for_token:
rc = process_token (msg_);
rc = process_token (msg_, flags, &buf.value, buf.length);
if (rc == 0)
state = sending_ready; // state = expecting_another_token? sending_token: sending_ready;
break;
......@@ -99,12 +103,18 @@ int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
rc = -1;
break;
}
if (buf.value) {
free (buf.value);
}
if (rc == 0) {
rc = msg_->close ();
errno_assert (rc == 0);
rc = msg_->init ();
errno_assert (rc == 0);
}
return rc;
}
......
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