31 #include "platform.hpp" 33 #ifdef HAVE_LIBGSSAPI_KRB5 35 #ifdef ZMQ_HAVE_WINDOWS 48 zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t (
const options_t & options_) :
49 mechanism_t(options_),
53 target_name (GSS_C_NO_NAME),
54 principal_name (NULL),
55 maj_stat (GSS_S_COMPLETE),
57 init_sec_min_stat (0),
59 gss_flags (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG),
60 cred (GSS_C_NO_CREDENTIAL),
61 context (GSS_C_NO_CONTEXT),
62 do_encryption (!options_.gss_plaintext)
66 zmq::gssapi_mechanism_base_t::~gssapi_mechanism_base_t ()
69 gss_release_name(&min_stat, &target_name);
71 gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
74 int zmq::gssapi_mechanism_base_t::encode_message (msg_t *msg_)
78 gss_buffer_desc plaintext;
79 gss_buffer_desc wrapped;
87 uint8_t *plaintext_buffer = static_cast <uint8_t *>(malloc(msg_->size ()+1));
88 plaintext_buffer[0] = flags;
89 memcpy (plaintext_buffer+1, msg_->data(), msg_->size());
91 plaintext.value = plaintext_buffer;
92 plaintext.length = msg_->size ()+1;
94 maj_stat = gss_wrap(&min_stat, context, 1, GSS_C_QOP_DEFAULT,
95 &plaintext, &state, &wrapped);
101 int rc = msg_->close ();
104 rc = msg_->init_size (8 + 4 + wrapped.length);
107 uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
110 memcpy (ptr,
"\x07MESSAGE", 8);
114 put_uint32 (ptr, static_cast <uint32_t> (wrapped.length));
118 memcpy (ptr, wrapped.value, wrapped.length);
119 ptr += wrapped.length;
121 gss_release_buffer (&min_stat, &wrapped);
126 int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
128 const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
129 size_t bytes_left = msg_->size ();
132 if (bytes_left < 8 || memcmp (ptr,
"\x07MESSAGE", 8)) {
140 if (bytes_left < 4) {
144 gss_buffer_desc wrapped;
150 if (bytes_left < wrapped.length) {
155 const size_t alloc_length = wrapped.length? wrapped.length: 1;
156 wrapped.value = static_cast <
char *> (malloc (alloc_length));
157 if (wrapped.length) {
159 memcpy(wrapped.value, ptr, wrapped.length);
160 ptr += wrapped.length;
161 bytes_left -= wrapped.length;
166 gss_buffer_desc plaintext;
167 maj_stat = gss_unwrap(&min_stat, context, &wrapped, &plaintext,
168 &state, (gss_qop_t *) NULL);
174 int rc = msg_->close ();
177 rc = msg_->init_size (plaintext.length-1);
180 const uint8_t flags = static_cast <
char *> (plaintext.value)[0];
186 memcpy (msg_->data (), static_cast <
char *> (plaintext.value)+1, plaintext.length-1);
188 gss_release_buffer (&min_stat, &plaintext);
189 gss_release_buffer (&min_stat, &wrapped);
191 if (bytes_left > 0) {
199 int zmq::gssapi_mechanism_base_t::produce_initiate (msg_t *msg_,
void *token_value_,
size_t token_length_)
204 const size_t command_size = 9 + 4 + token_length_;
206 const int rc = msg_->init_size (command_size);
209 uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
212 memcpy (ptr,
"\x08INITIATE", 9);
216 put_uint32 (ptr, static_cast <uint32_t> (token_length_));
220 memcpy (ptr, token_value_, token_length_);
221 ptr += token_length_;
226 int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_,
void **token_value_,
size_t &token_length_)
230 const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
231 size_t bytes_left = msg_->size ();
234 if (bytes_left < 9 || memcmp (ptr,
"\x08INITIATE", 9)) {
242 if (bytes_left < 4) {
251 if (bytes_left < token_length_) {
255 *token_value_ = static_cast <
char *> (malloc (token_length_ ? token_length_ : 1));
258 memcpy(*token_value_, ptr, token_length_);
259 ptr += token_length_;
260 bytes_left -= token_length_;
263 if (bytes_left > 0) {
271 int zmq::gssapi_mechanism_base_t::produce_ready (msg_t *msg_)
273 unsigned char *
const command_buffer = (
unsigned char *) malloc (512);
276 unsigned char *ptr = command_buffer;
279 memcpy (ptr,
"\x05READY", 6);
283 const char *socket_type = socket_type_string (
options.
type);
284 ptr += add_property (ptr,
"Socket-Type", socket_type, strlen (socket_type));
292 const size_t command_size = ptr - command_buffer;
293 const int rc = msg_->init_size (command_size);
295 memcpy (msg_->data (), command_buffer, command_size);
296 free (command_buffer);
299 return encode_message (msg_);
304 int zmq::gssapi_mechanism_base_t::process_ready (msg_t *msg_)
307 const int rc = decode_message (msg_);
312 const unsigned char *ptr = static_cast <
unsigned char *> (msg_->data ());
313 size_t bytes_left = msg_->size ();
315 if (bytes_left < 6 || memcmp (ptr,
"\x05READY", 6)) {
321 return parse_metadata (ptr, bytes_left);
324 int zmq::gssapi_mechanism_base_t::acquire_credentials (
char * service_name_, gss_cred_id_t * cred_)
328 gss_name_t server_name;
330 gss_buffer_desc name_buf;
331 name_buf.value = service_name_;
332 name_buf.length = strlen ((
char *) name_buf.value) + 1;
334 maj_stat = gss_import_name (&min_stat, &name_buf,
335 GSS_C_NT_HOSTBASED_SERVICE, &server_name);
337 if (maj_stat != GSS_S_COMPLETE)
340 maj_stat = gss_acquire_cred (&min_stat, server_name, 0,
341 GSS_C_NO_OID_SET, GSS_C_ACCEPT,
344 if (maj_stat != GSS_S_COMPLETE)
347 gss_release_name(&min_stat, &server_name);
void put_uint32(unsigned char *buffer_, uint32_t value)
uint32_t get_uint32(const unsigned char *buffer_)
unsigned char identity[256]
unsigned char identity_size