5 #ifdef HAVE_LIBGSSAPI_KRB5
16 zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t (
17 session_base_t *session_,
const options_t &
options_) :
18 mechanism_base_t (session_,
options_),
22 target_name (GSS_C_NO_NAME),
23 principal_name (
NULL),
24 maj_stat (GSS_S_COMPLETE),
26 init_sec_min_stat (0),
28 gss_flags (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG),
29 cred (GSS_C_NO_CREDENTIAL),
30 context (GSS_C_NO_CONTEXT),
31 do_encryption (!
options_.gss_plaintext)
35 zmq::gssapi_mechanism_base_t::~gssapi_mechanism_base_t ()
38 gss_release_name (&min_stat, &target_name);
40 gss_delete_sec_context (&min_stat, &context, GSS_C_NO_BUFFER);
43 int zmq::gssapi_mechanism_base_t::encode_message (msg_t *msg_)
48 gss_buffer_desc wrapped;
51 if (msg_->flags () & msg_t::more)
53 if (msg_->flags () & msg_t::command)
56 uint8_t *plaintext_buffer =
57 static_cast<uint8_t *
> (malloc (msg_->size () + 1));
60 plaintext_buffer[0] =
flags;
61 memcpy (plaintext_buffer + 1, msg_->data (), msg_->size ());
66 maj_stat = gss_wrap (&min_stat, context, 1, GSS_C_QOP_DEFAULT, &
plaintext,
73 int rc = msg_->close ();
76 rc = msg_->init_size (8 + 4 + wrapped.length);
79 uint8_t *ptr =
static_cast<uint8_t *
> (msg_->data ());
82 memcpy (ptr,
"\x07MESSAGE", 8);
86 put_uint32 (ptr,
static_cast<uint32_t
> (wrapped.length));
90 memcpy (ptr, wrapped.value, wrapped.length);
91 ptr += wrapped.length;
93 gss_release_buffer (&min_stat, &wrapped);
98 int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
100 const uint8_t *ptr =
static_cast<uint8_t *
> (msg_->data ());
101 size_t bytes_left = msg_->size ();
103 int rc = check_basic_command_structure (msg_);
108 if (bytes_left < 8 || memcmp (ptr,
"\x07MESSAGE", 8)) {
109 session->get_socket ()->event_handshake_failed_protocol (
118 if (bytes_left < 4) {
119 session->get_socket ()->event_handshake_failed_protocol (
120 session->get_endpoint (),
125 gss_buffer_desc wrapped;
131 if (bytes_left < wrapped.length) {
132 session->get_socket ()->event_handshake_failed_protocol (
133 session->get_endpoint (),
139 const size_t alloc_length = wrapped.length ? wrapped.length : 1;
140 wrapped.value =
static_cast<char *
> (malloc (alloc_length));
143 if (wrapped.length) {
144 memcpy (wrapped.value, ptr, wrapped.length);
145 ptr += wrapped.length;
146 bytes_left -= wrapped.length;
152 maj_stat = gss_unwrap (&min_stat, context, &wrapped, &
plaintext, &state,
155 if (maj_stat != GSS_S_COMPLETE) {
156 gss_release_buffer (&min_stat, &
plaintext);
157 free (wrapped.value);
158 session->get_socket ()->event_handshake_failed_protocol (
169 rc = msg_->init_size (
plaintext.length - 1);
174 msg_->set_flags (msg_t::more);
176 msg_->set_flags (msg_t::command);
178 memcpy (msg_->data (),
static_cast<char *
> (
plaintext.value) + 1,
181 gss_release_buffer (&min_stat, &
plaintext);
182 free (wrapped.value);
184 if (bytes_left > 0) {
185 session->get_socket ()->event_handshake_failed_protocol (
186 session->get_endpoint (),
195 int zmq::gssapi_mechanism_base_t::produce_initiate (msg_t *msg_,
197 size_t token_length_)
202 const size_t command_size = 9 + 4 + token_length_;
204 const int rc = msg_->init_size (command_size);
207 uint8_t *ptr =
static_cast<uint8_t *
> (msg_->data ());
210 memcpy (ptr,
"\x08INITIATE", 9);
214 put_uint32 (ptr,
static_cast<uint32_t
> (token_length_));
218 memcpy (ptr, token_value_, token_length_);
219 ptr += token_length_;
224 int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_,
226 size_t &token_length_)
230 const uint8_t *ptr =
static_cast<uint8_t *
> (msg_->data ());
231 size_t bytes_left = msg_->size ();
233 int rc = check_basic_command_structure (msg_);
238 if (bytes_left < 9 || memcmp (ptr,
"\x08INITIATE", 9)) {
239 session->get_socket ()->event_handshake_failed_protocol (
248 if (bytes_left < 4) {
249 session->get_socket ()->event_handshake_failed_protocol (
250 session->get_endpoint (),
260 if (bytes_left < token_length_) {
261 session->get_socket ()->event_handshake_failed_protocol (
262 session->get_endpoint (),
269 static_cast<char *
> (malloc (token_length_ ? token_length_ : 1));
273 memcpy (*token_value_, ptr, token_length_);
274 ptr += token_length_;
275 bytes_left -= token_length_;
278 if (bytes_left > 0) {
279 session->get_socket ()->event_handshake_failed_protocol (
280 session->get_endpoint (),
289 int zmq::gssapi_mechanism_base_t::produce_ready (msg_t *msg_)
291 make_command_with_basic_properties (msg_,
"\5READY", 6);
294 return encode_message (msg_);
299 int zmq::gssapi_mechanism_base_t::process_ready (msg_t *msg_)
302 const int rc = decode_message (msg_);
307 const unsigned char *ptr =
static_cast<unsigned char *
> (msg_->data ());
308 size_t bytes_left = msg_->size ();
310 int rc = check_basic_command_structure (msg_);
314 if (bytes_left < 6 || memcmp (ptr,
"\x05READY", 6)) {
315 session->get_socket ()->event_handshake_failed_protocol (
322 rc = parse_metadata (ptr, bytes_left);
324 session->get_socket ()->event_handshake_failed_protocol (
330 const gss_OID zmq::gssapi_mechanism_base_t::convert_nametype (
int zmq_nametype)
332 switch (zmq_nametype) {
334 return GSS_C_NT_HOSTBASED_SERVICE;
336 return GSS_C_NT_USER_NAME;
338 #ifdef GSS_KRB5_NT_PRINCIPAL_NAME
339 return (gss_OID) GSS_KRB5_NT_PRINCIPAL_NAME;
341 return GSS_C_NT_USER_NAME;
347 int zmq::gssapi_mechanism_base_t::acquire_credentials (
char *service_name_,
348 gss_cred_id_t *cred_,
353 gss_name_t server_name;
355 gss_buffer_desc name_buf;
356 name_buf.value = service_name_;
357 name_buf.length = strlen ((
char *) name_buf.value) + 1;
359 maj_stat = gss_import_name (&min_stat, &name_buf, name_type_, &server_name);
361 if (maj_stat != GSS_S_COMPLETE)
364 maj_stat = gss_acquire_cred (&min_stat, server_name, 0, GSS_C_NO_OID_SET,
367 if (maj_stat != GSS_S_COMPLETE)
370 gss_release_name (&min_stat, &server_name);