예제 #1
0
파일: context.c 프로젝트: dezelin/maily
/* 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;
}
예제 #2
0
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;
}