31 #include "platform.hpp" 33 #ifdef HAVE_LIBGSSAPI_KRB5 35 #ifdef ZMQ_HAVE_WINDOWS 48 #include <gssapi/gssapi.h> 50 zmq::gssapi_server_t::gssapi_server_t (session_base_t *session_,
51 const std::string &peer_address_,
52 const options_t &options_) :
53 gssapi_mechanism_base_t (options_),
55 peer_address (peer_address_),
56 state (recv_next_token),
57 security_context_established (false)
59 maj_stat = GSS_S_CONTINUE_NEEDED;
60 if(!options_.gss_principal.empty())
62 const std::string::size_type principal_size = options_.gss_principal.size();
63 principal_name = static_cast <
char *>(malloc(principal_size+1));
64 assert(principal_name);
65 memcpy(principal_name, options_.gss_principal.c_str(), principal_size+1 );
67 if (acquire_credentials (principal_name, &cred) != 0)
68 maj_stat = GSS_S_FAILURE;
72 zmq::gssapi_server_t::~gssapi_server_t ()
75 gss_release_cred(&min_stat, &cred);
78 gss_release_name(&min_stat, &target_name);
81 int zmq::gssapi_server_t::next_handshake_command (msg_t *msg_)
83 if (state == send_ready) {
84 int rc = produce_ready(msg_);
91 if (state != send_next_token) {
96 if (produce_next_token (msg_) < 0)
99 if (maj_stat != GSS_S_CONTINUE_NEEDED && maj_stat != GSS_S_COMPLETE)
102 if (maj_stat == GSS_S_COMPLETE) {
103 security_context_established =
true;
106 state = recv_next_token;
111 int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
113 if (state == recv_ready) {
114 int rc = process_ready(msg_);
121 if (state != recv_next_token) {
126 if (security_context_established) {
128 bool expecting_zap_reply =
false;
129 int rc = session->zap_connect ();
132 rc = receive_and_process_zap_reply ();
136 expecting_zap_reply =
true;
139 state = expecting_zap_reply? expect_zap_reply: send_ready;
143 if (process_next_token (msg_) < 0)
147 state = send_next_token;
155 void zmq::gssapi_server_t::send_zap_request ()
164 rc = session->write_zap_msg (&msg);
168 rc = msg.init_size (3);
170 memcpy (msg.data (),
"1.0", 3);
172 rc = session->write_zap_msg (&msg);
176 rc = msg.init_size (1);
178 memcpy (msg.data (),
"1", 1);
180 rc = session->write_zap_msg (&msg);
188 rc = session->write_zap_msg (&msg);
192 rc = msg.init_size (peer_address.length ());
194 memcpy (msg.data (), peer_address.c_str (), peer_address.length ());
196 rc = session->write_zap_msg (&msg);
204 rc = session->write_zap_msg (&msg);
208 rc = msg.init_size (6);
210 memcpy (msg.data (),
"GSSAPI", 6);
212 rc = session->write_zap_msg (&msg);
216 gss_buffer_desc principal;
217 gss_display_name(&min_stat, target_name, &principal, NULL);
219 rc = msg.init_size (principal.length);
221 memcpy (msg.data (), principal.value, principal.length);
222 rc = session->write_zap_msg (&msg);
224 gss_release_buffer(&min_stat, &principal);
227 int zmq::gssapi_server_t::receive_and_process_zap_reply ()
233 for (
int i = 0; i < 7; i++) {
234 rc = msg [i].init ();
238 for (
int i = 0; i < 7; i++) {
239 rc = session->read_zap_msg (&msg [i]);
253 if (msg [0].
size () > 0) {
260 if (msg [1].
size () != 3 || memcmp (msg [1].data (),
"1.0", 3)) {
267 if (msg [2].
size () != 1 || memcmp (msg [2].data (),
"1", 1)) {
274 if (msg [3].
size () != 3 || memcmp (msg [3].data (),
"200", 3)) {
281 set_user_id (msg [5].data (), msg [5].
size ());
284 rc = parse_metadata (static_cast <const unsigned char*> (msg [6].data ()),
285 msg [6].
size (),
true);
288 for (
int i = 0; i < 7; i++) {
289 const int rc2 = msg [i].close ();
297 int zmq::gssapi_server_t::encode (msg_t *msg_)
302 return encode_message (msg_);
307 int zmq::gssapi_server_t::decode (msg_t *msg_)
312 return decode_message (msg_);
317 int zmq::gssapi_server_t::zap_msg_available ()
319 if (state != expect_zap_reply) {
323 const int rc = receive_and_process_zap_reply ();
334 int zmq::gssapi_server_t::produce_next_token (msg_t *msg_)
336 if (send_tok.length != 0) {
337 if (produce_initiate(msg_, send_tok.value, send_tok.length) < 0)
339 gss_release_buffer(&min_stat, &send_tok);
342 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
343 gss_release_name(&min_stat, &target_name);
344 if (context != GSS_C_NO_CONTEXT)
345 gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
352 int zmq::gssapi_server_t::process_next_token (msg_t *msg_)
354 if (maj_stat == GSS_S_CONTINUE_NEEDED) {
355 if (process_initiate(msg_, &recv_tok.value, recv_tok.length) < 0) {
356 if (target_name != GSS_C_NO_NAME)
357 gss_release_name(&min_stat, &target_name);
365 void zmq::gssapi_server_t::accept_context ()
367 maj_stat = gss_accept_sec_context(&init_sec_min_stat, &context, cred,
368 &recv_tok, GSS_C_NO_CHANNEL_BINDINGS,
369 &target_name, &doid, &send_tok,
370 &ret_flags, NULL, NULL);
372 if (recv_tok.value) {
373 free (recv_tok.value);
374 recv_tok.value = NULL;
unsigned char identity[256]
unsigned char identity_size