5 #ifdef HAVE_LIBGSSAPI_KRB5
16 zmq::gssapi_client_t::gssapi_client_t (session_base_t *session_,
18 mechanism_base_t (session_,
options_),
19 gssapi_mechanism_base_t (session_,
options_),
20 state (call_next_init),
21 token_ptr (GSS_C_NO_BUFFER),
23 security_context_established (
false)
25 const std::string::size_type service_size =
26 options_.gss_service_principal.size ();
27 service_name =
static_cast<char *
> (malloc (service_size + 1));
28 assert (service_name);
29 memcpy (service_name,
options_.gss_service_principal.c_str (),
32 service_name_type = convert_nametype (
options_.gss_service_principal_nt);
33 maj_stat = GSS_S_COMPLETE;
34 if (!
options_.gss_principal.empty ()) {
35 const std::string::size_type principal_size =
37 principal_name =
static_cast<char *
> (malloc (principal_size + 1));
38 assert (principal_name);
39 memcpy (principal_name,
options_.gss_principal.c_str (),
42 gss_OID name_type = convert_nametype (
options_.gss_principal_nt);
43 if (acquire_credentials (principal_name, &cred, name_type) != 0)
44 maj_stat = GSS_S_FAILURE;
47 mechs.elements =
NULL;
51 zmq::gssapi_client_t::~gssapi_client_t ()
56 gss_release_cred (&min_stat, &cred);
59 int zmq::gssapi_client_t::next_handshake_command (msg_t *msg_)
61 if (state == send_ready) {
62 int rc = produce_ready (msg_);
69 if (state != call_next_init) {
74 if (initialize_context () < 0)
77 if (produce_next_token (msg_) < 0)
80 if (maj_stat != GSS_S_CONTINUE_NEEDED && maj_stat != GSS_S_COMPLETE)
83 if (maj_stat == GSS_S_COMPLETE) {
84 security_context_established =
true;
87 state = recv_next_token;
92 int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
94 if (state == recv_ready) {
95 int rc = process_ready (msg_);
102 if (state != recv_next_token) {
103 session->get_socket ()->event_handshake_failed_protocol (
109 if (process_next_token (msg_) < 0)
112 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
115 state = call_next_init;
123 int zmq::gssapi_client_t::encode (msg_t *msg_)
128 return encode_message (msg_);
133 int zmq::gssapi_client_t::decode (msg_t *msg_)
138 return decode_message (msg_);
145 return state == connected ? mechanism_t::ready : mechanism_t::handshaking;
148 int zmq::gssapi_client_t::initialize_context ()
151 if (principal_name !=
NULL && cred ==
NULL)
155 if (target_name == GSS_C_NO_NAME) {
156 send_tok.value = service_name;
157 send_tok.length = strlen (service_name) + 1;
158 OM_uint32 maj = gss_import_name (&min_stat, &send_tok,
159 service_name_type, &target_name);
161 if (maj != GSS_S_COMPLETE)
165 maj_stat = gss_init_sec_context (
166 &init_sec_min_stat, cred, &context, target_name, mechs.elements,
167 gss_flags, 0,
NULL, token_ptr,
NULL, &send_tok, &ret_flags,
NULL);
169 if (token_ptr != GSS_C_NO_BUFFER)
170 free (recv_tok.value);
175 int zmq::gssapi_client_t::produce_next_token (msg_t *msg_)
177 if (send_tok.length != 0) {
178 if (produce_initiate (msg_, send_tok.value, send_tok.length) < 0) {
179 gss_release_buffer (&min_stat, &send_tok);
180 gss_release_name (&min_stat, &target_name);
184 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_client_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 gss_release_name (&min_stat, &target_name);
203 token_ptr = &recv_tok;