/* Initiates the establishment of a krb5 security context between the application and a remote peer. Assumes that context_handle and output_token are valid and cleared. */ OM_uint32 gss_krb5_init_sec_context (OM_uint32 * minor_status, const gss_cred_id_t initiator_cred_handle, gss_ctx_id_t * context_handle, const gss_name_t target_name, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID * actual_mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec) { gss_ctx_id_t ctx = *context_handle; _gss_krb5_ctx_t k5 = ctx->krb5; OM_uint32 maj_stat; int rc; if (minor_status) *minor_status = 0; if (initiator_cred_handle) { /* We only support the default initiator. See k5internal.h for adding a Shishi_tkt to the credential structure. I'm not sure what the use would be -- user-to-user authentication perhaps? Later: if you have tickets for foo@BAR and bar@FOO, it may be useful to call gss_acquire_cred first to chose which one to initiate the context with. Not many applications need this. */ return GSS_S_NO_CRED; } if (k5 == NULL) { k5 = ctx->krb5 = calloc (sizeof (*k5), 1); if (!k5) { if (minor_status) *minor_status = ENOMEM; return GSS_S_FAILURE; } rc = shishi_init (&k5->sh); if (rc != SHISHI_OK) return GSS_S_FAILURE; } if (!k5->reqdone) { maj_stat = init_request (minor_status, initiator_cred_handle, context_handle, target_name, mech_type, req_flags, time_req, input_chan_bindings, input_token, actual_mech_type, output_token, ret_flags, time_rec); if (GSS_ERROR (maj_stat)) return maj_stat; k5->flags = req_flags & ( /* GSS_C_DELEG_FLAG | */ GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG); /* PROT_READY is not mentioned in 1964/gssapi-cfx but we support it anyway. */ k5->flags |= GSS_C_PROT_READY_FLAG; if (ret_flags) *ret_flags = k5->flags; k5->key = shishi_ap_key (k5->ap); k5->reqdone = 1; } else if (k5->reqdone && k5->flags & GSS_C_MUTUAL_FLAG && !k5->repdone) { maj_stat = init_reply (minor_status, initiator_cred_handle, context_handle, target_name, mech_type, req_flags, time_req, input_chan_bindings, input_token, actual_mech_type, output_token, ret_flags, time_rec); if (GSS_ERROR (maj_stat)) return maj_stat; if (ret_flags) *ret_flags = k5->flags; k5->repdone = 1; } else maj_stat = GSS_S_FAILURE; if (time_rec) *time_rec = gss_krb5_tktlifetime (k5->tkt); return maj_stat; }
int main(int argc, char **argv) { pingtun_t handle; handle.ret = -1; memset(&handle, 0, sizeof(handle)); DBG("parsing options"); parse_opts(&handle, argc, argv); if (handle.flags.is_server) { if (0 != set_ignore_echo(&handle)) { goto exit; } } DBG("initializing event base"); if (0 != init_base_ev(&handle)) { goto exit; } DBG("initializing ping socket"); if (handle.flags.is_server) { if (0 != init_sping(&handle)) { goto exit; } } if (handle.flags.is_client) { if (0 != init_cping(&handle)) { goto exit; } } if (handle.flags.is_server && !handle.flags.ignore_pings) { if (0 != init_reply(&handle)) { goto exit; } } DBG("initializing tun device"); if (0 != init_tun(&handle)) { goto exit; } if (0 != init_signals(&handle)) { goto exit; } switch (event_base_dispatch(handle.base_ev)) { case 0: break; case -1: ERR("dispatch event loop failed"); goto exit; case 1: ERR("no more active/pending events"); goto exit; } exit: if (handle.flags.is_server) { reset_ignore_echo(&handle); } //TODO: de-allocate all the shit. Do I really care? return handle.ret; }