5 #ifdef HAVE_LIBGSSAPI_KRB5
16 #include <gssapi/gssapi.h>
18 zmq::gssapi_server_t::gssapi_server_t (session_base_t *session_,
21 mechanism_base_t (session_,
options_),
22 gssapi_mechanism_base_t (session_,
options_),
23 zap_client_t (session_, peer_address_,
options_),
25 peer_address (peer_address_),
26 state (recv_next_token),
27 security_context_established (
false)
29 maj_stat = GSS_S_CONTINUE_NEEDED;
30 if (!
options_.gss_principal.empty ()) {
31 const std::string::size_type principal_size =
33 principal_name =
static_cast<char *
> (malloc (principal_size + 1));
34 assert (principal_name);
35 memcpy (principal_name,
options_.gss_principal.c_str (),
37 gss_OID name_type = convert_nametype (
options_.gss_principal_nt);
38 if (acquire_credentials (principal_name, &cred, name_type) != 0)
39 maj_stat = GSS_S_FAILURE;
43 zmq::gssapi_server_t::~gssapi_server_t ()
46 gss_release_cred (&min_stat, &cred);
49 gss_release_name (&min_stat, &target_name);
52 int zmq::gssapi_server_t::next_handshake_command (msg_t *msg_)
54 if (state == send_ready) {
55 int rc = produce_ready (msg_);
62 if (state != send_next_token) {
67 if (produce_next_token (msg_) < 0)
70 if (maj_stat != GSS_S_CONTINUE_NEEDED && maj_stat != GSS_S_COMPLETE)
73 if (maj_stat == GSS_S_COMPLETE) {
74 security_context_established =
true;
77 state = recv_next_token;
82 int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
84 if (state == recv_ready) {
85 int rc = process_ready (msg_);
92 if (state != recv_next_token) {
93 session->get_socket ()->event_handshake_failed_protocol (
99 if (security_context_established) {
103 bool expecting_zap_reply =
false;
104 int rc = session->zap_connect ();
107 rc = receive_and_process_zap_reply ();
111 expecting_zap_reply =
true;
114 state = expecting_zap_reply ? expect_zap_reply : send_ready;
118 if (process_next_token (msg_) < 0)
122 state = send_next_token;
130 void zmq::gssapi_server_t::send_zap_request ()
132 gss_buffer_desc principal;
133 gss_display_name (&min_stat, target_name, &principal,
NULL);
134 zap_client_t::send_zap_request (
135 "GSSAPI", 6,
reinterpret_cast<const uint8_t *
> (principal.value),
138 gss_release_buffer (&min_stat, &principal);
141 int zmq::gssapi_server_t::encode (msg_t *msg_)
146 return encode_message (msg_);
151 int zmq::gssapi_server_t::decode (msg_t *msg_)
156 return decode_message (msg_);
161 int zmq::gssapi_server_t::zap_msg_available ()
163 if (state != expect_zap_reply) {
167 const int rc = receive_and_process_zap_reply ();
170 return rc == -1 ? -1 : 0;
175 return state == connected ? mechanism_t::ready : mechanism_t::handshaking;
178 int zmq::gssapi_server_t::produce_next_token (msg_t *msg_)
180 if (send_tok.length != 0) {
181 if (produce_initiate (msg_, send_tok.value, send_tok.length) < 0)
183 gss_release_buffer (&min_stat, &send_tok);
186 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
187 gss_release_name (&min_stat, &target_name);
188 if (context != GSS_C_NO_CONTEXT)
189 gss_delete_sec_context (&min_stat, &context, GSS_C_NO_BUFFER);
196 int zmq::gssapi_server_t::process_next_token (msg_t *msg_)
198 if (maj_stat == GSS_S_CONTINUE_NEEDED) {
199 if (process_initiate (msg_, &recv_tok.value, recv_tok.length) < 0) {
200 if (target_name != GSS_C_NO_NAME)
201 gss_release_name (&min_stat, &target_name);
209 void zmq::gssapi_server_t::accept_context ()
211 maj_stat = gss_accept_sec_context (
212 &init_sec_min_stat, &context, cred, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS,
213 &target_name, &doid, &send_tok, &ret_flags,
NULL,
NULL);
215 if (recv_tok.value) {
216 free (recv_tok.value);
217 recv_tok.value =
NULL;