diff --git a/include/zmq.h b/include/zmq.h index 404da968..a660341c 100644 --- a/include/zmq.h +++ b/include/zmq.h @@ -297,7 +297,8 @@ ZMQ_EXPORT char *zmq_msg_gets (zmq_msg_t *msg, char *property); #define ZMQ_IPC_FILTER_GID 60 #define ZMQ_CONNECT_RID 61 #define ZMQ_GSSAPI_SERVER 62 -#define ZMQ_GSSAPI_CLIENT 63 +#define ZMQ_GSSAPI_PRINCIPLE 63 +#define ZMQ_GSSAPI_SERVICE_PRINCIPLE 64 /* Message options */ #define ZMQ_MORE 1 diff --git a/src/gssapi_client.cpp b/src/gssapi_client.cpp index 490e8a87..4d6ee73b 100644 --- a/src/gssapi_client.cpp +++ b/src/gssapi_client.cpp @@ -38,8 +38,10 @@ zmq::gssapi_client_t::gssapi_client_t (const options_t &options_) : mechs (), security_context_established (false) { - maj_stat = GSS_S_COMPLETE; - service_name = strdup("host"); // TODO: add service_name to options + const std::string::size_type service_size = options_.gss_service_principle.size(); + service_name = new char[service_size+1]; + memcpy(service_name, options_.gss_service_principle.c_str(), service_size+1 ); + mechs.elements = NULL; mechs.count = 0; } diff --git a/src/gssapi_client.hpp b/src/gssapi_client.hpp index d08c7afd..387665f5 100644 --- a/src/gssapi_client.hpp +++ b/src/gssapi_client.hpp @@ -53,6 +53,9 @@ namespace zmq connected }; + // Human-readable principle name of the service we are connecting to + char * service_name; + // Current FSM state state_t state; diff --git a/src/gssapi_mechanism_base.cpp b/src/gssapi_mechanism_base.cpp index edd34529..c09b302b 100644 --- a/src/gssapi_mechanism_base.cpp +++ b/src/gssapi_mechanism_base.cpp @@ -37,8 +37,8 @@ zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t (const options_t & options recv_tok (), /// FIXME remove? in_buf (), target_name (GSS_C_NO_NAME), - service_name (NULL), - maj_stat (GSS_S_COMPLETE), + principle_name (NULL), + maj_stat (GSS_S_CONTINUE_NEEDED), min_stat (0), init_sec_min_stat (0), ret_flags (0), @@ -46,6 +46,15 @@ zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t (const options_t & options cred (GSS_C_NO_CREDENTIAL), context (GSS_C_NO_CONTEXT) { + if(!options_.gss_principle.empty()) + { + const std::string::size_type principle_size = options_.gss_principle.size(); + principle_name = new char[principle_size+1]; + memcpy(principle_name, options_.gss_principle.c_str(), principle_size+1 ); + + if (acquire_credentials (principle_name, &cred) != 0) + maj_stat = GSS_S_FAILURE; + } } zmq::gssapi_mechanism_base_t::~gssapi_mechanism_base_t () diff --git a/src/gssapi_mechanism_base.hpp b/src/gssapi_mechanism_base.hpp index d84bdc85..4d5543dd 100644 --- a/src/gssapi_mechanism_base.hpp +++ b/src/gssapi_mechanism_base.hpp @@ -67,7 +67,7 @@ namespace zmq // Acquire security context credentials from the // underlying mechanism. - static int acquire_credentials (char * service_name_, + static int acquire_credentials (char * principle_name_, gss_cred_id_t * cred_); protected: @@ -77,11 +77,11 @@ namespace zmq // Opaque GSSAPI token for incoming data gss_buffer_desc recv_tok; - // Opaque GSSAPI representation of service_name + // Opaque GSSAPI representation of principle gss_name_t target_name; - // Human-readable service principal name - char * service_name; + // Human-readable principal name + char * principle_name; // Status code returned by GSSAPI functions OM_uint32 maj_stat; diff --git a/src/gssapi_server.cpp b/src/gssapi_server.cpp index 67c39c56..02959b7e 100644 --- a/src/gssapi_server.cpp +++ b/src/gssapi_server.cpp @@ -42,12 +42,6 @@ zmq::gssapi_server_t::gssapi_server_t (session_base_t *session_, state (recv_next_token), security_context_established (false) { - service_name = (char *) "host"; // TODO: add service_name to options - int rc = acquire_credentials (service_name, &cred); // TODO: add creds to options too? - if (rc == 0) - maj_stat = GSS_S_CONTINUE_NEEDED; - else - maj_stat = GSS_S_FAILURE; } zmq::gssapi_server_t::~gssapi_server_t () diff --git a/src/options.cpp b/src/options.cpp index 44e7d417..aa0d4040 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -410,14 +410,23 @@ int zmq::options_t::setsockopt (int option_, const void *optval_, } break; - case ZMQ_GSSAPI_CLIENT: - if (is_int && (value == 0 || value == 1)) { - as_server = (value == 0); + case ZMQ_GSSAPI_PRINCIPLE: + if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) { + gss_principle.assign ((const char *) optval_, optvallen_); mechanism = ZMQ_GSSAPI; return 0; } break; + case ZMQ_GSSAPI_SERVICE_PRINCIPLE: + if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL) { + gss_service_principle.assign ((const char *) optval_, optvallen_); + mechanism = ZMQ_GSSAPI; + as_server = 1; + return 0; + } + break; + default: break; } @@ -704,14 +713,22 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_) return 0; } break; - - case ZMQ_GSSAPI_CLIENT: - if (is_int) { - *value = (as_server == 0) && mechanism == ZMQ_GSSAPI; + + case ZMQ_GSSAPI_PRINCIPLE: + if (*optvallen_ >= gss_principle.size () + 1) { + memcpy (optval_, gss_principle.c_str (), gss_principle.size () + 1); + *optvallen_ = gss_principle.size () + 1; return 0; } break; + case ZMQ_GSSAPI_SERVICE_PRINCIPLE: + if (*optvallen_ >= gss_service_principle.size () + 1) { + memcpy (optval_, gss_service_principle.c_str (), gss_service_principle.size () + 1); + *optvallen_ = gss_service_principle.size () + 1; + return 0; + } + break; } errno = EINVAL; diff --git a/src/options.hpp b/src/options.hpp index d4c7190b..e1b156b1 100644 --- a/src/options.hpp +++ b/src/options.hpp @@ -156,6 +156,10 @@ namespace zmq uint8_t curve_secret_key [CURVE_KEYSIZE]; uint8_t curve_server_key [CURVE_KEYSIZE]; + // Principles for GSSAPI mechanism + std::string gss_principle; + std::string gss_service_principle; + // ID of the socket. int socket_id;