zmq::gssapi_client_t::gssapi_client_t (const options_t &options_) : gssapi_mechanism_base_t (options_), state (call_next_init), token_ptr (GSS_C_NO_BUFFER), mechs (), security_context_established (false) { const std::string::size_type service_size = options_.gss_service_principal.size(); service_name = static_cast <char *>(malloc(service_size+1)); assert(service_name); memcpy(service_name, options_.gss_service_principal.c_str(), service_size+1 ); maj_stat = GSS_S_COMPLETE; if(!options_.gss_principal.empty()) { const std::string::size_type principal_size = options_.gss_principal.size(); principal_name = static_cast <char *>(malloc(principal_size+1)); assert(principal_name); memcpy(principal_name, options_.gss_principal.c_str(), principal_size+1 ); if (acquire_credentials (principal_name, &cred) != 0) maj_stat = GSS_S_FAILURE; } mechs.elements = NULL; mechs.count = 0; }
zmq::gssapi_server_t::gssapi_server_t (session_base_t *session_, const std::string &peer_address_, const options_t &options_) : gssapi_mechanism_base_t (options_), session (session_), peer_address (peer_address_), state (recv_next_token), security_context_established (false) { maj_stat = GSS_S_CONTINUE_NEEDED; if(!options_.gss_principal.empty()) { const std::string::size_type principal_size = options_.gss_principal.size(); principal_name = static_cast <char *>(malloc(principal_size+1)); assert(principal_name); memcpy(principal_name, options_.gss_principal.c_str(), principal_size+1 ); gss_OID name_type = convert_nametype (options_.gss_principal_nt); if (acquire_credentials (principal_name, &cred, name_type) != 0) maj_stat = GSS_S_FAILURE; } }
/* return 0 on success */ static int do_gss_auth(void *obj, char *ibuf, int ticket_len, char *rbuf, int *rbuflen, char *username, int ulen, struct session_info *sinfo ) { OM_uint32 status = 0; gss_name_t server_name, client_name; gss_cred_id_t server_creds; gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT; gss_buffer_desc ticket_buffer, authenticator_buff; int ret = 0; /* import our principal name from afpd */ if (get_afpd_principal(obj, &server_name) != 0) { return 1; } log_principal(server_name); /* Now we have to acquire our credentials */ if ((ret = acquire_credentials (&server_name, &server_creds))) goto cleanup_vars; /* * Try to accept the secondary context, using the ticket/token the * client sent us. Ticket is stored at current ibuf position. * Don't try to release ticket_buffer later, it points into ibuf! */ ticket_buffer.length = ticket_len; ticket_buffer.value = ibuf; ret = accept_sec_context (&context_handle, server_creds, &ticket_buffer, &client_name, &authenticator_buff); if (!ret) { /* We succesfully acquired the secondary context, now get the username for afpd and gss_wrap the sessionkey */ if ( 0 == (ret = get_client_username(username, ulen, &client_name)) ) { ret = wrap_sessionkey(context_handle, sinfo); } if (!ret) { /* FIXME: Is copying the authenticator really necessary? Where is this documented? */ u_int16_t auth_len = htons( authenticator_buff.length ); /* copy the authenticator length into the reply buffer */ memcpy( rbuf, &auth_len, sizeof(auth_len) ); *rbuflen += sizeof(auth_len); rbuf += sizeof(auth_len); /* copy the authenticator value into the reply buffer */ memcpy( rbuf, authenticator_buff.value, authenticator_buff.length ); *rbuflen += authenticator_buff.length; } /* Clean up after ourselves */ gss_release_name( &status, &client_name ); if ( authenticator_buff.value) gss_release_buffer( &status, &authenticator_buff ); gss_delete_sec_context( &status, &context_handle, NULL ); } gss_release_cred( &status, &server_creds ); cleanup_vars: gss_release_name( &status, &server_name ); return ret; }