示例#1
0
OM_uint32
_gssiakerb_accept_sec_context(OM_uint32 * minor_status,
			      gss_ctx_id_t * context_handle,
			      const gss_cred_id_t acceptor_cred_handle,
			      const gss_buffer_t input_token_buffer,
			      const gss_channel_bindings_t input_chan_bindings,
			      gss_name_t * src_name,
			      gss_OID * mech_type,
			      gss_buffer_t output_token,
			      OM_uint32 * ret_flags,
			      OM_uint32 * time_rec,
			      gss_cred_id_t * delegated_cred_handle)
{
    return accept_sec_context(minor_status,
			      context_handle,
			      acceptor_cred_handle,
			      input_token_buffer,
			      input_chan_bindings,
			      src_name,
			      mech_type,
			      output_token,
			      ret_flags,
			      time_rec,
			      delegated_cred_handle,
			      GSS_IAKERB_MECHANISM,
			      iakerb_acceptor_start);
}
示例#2
0
static int do_gss_auth(void *obj,
                       char *ibuf, size_t ibuflen,
                       char *rbuf, int *rbuflen,
                       char *username, size_t ulen,
                       struct session_info *sinfo )
{
    OM_uint32 status = 0;
    gss_name_t client_name;
    gss_ctx_id_t context = GSS_C_NO_CONTEXT;
    gss_buffer_desc ticket_buffer, authenticator_buff;
    int ret = 0;

    /*
     * 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 = ibuflen;
    ticket_buffer.value = ibuf;

    if ((ret = accept_sec_context(&context,
                                  &ticket_buffer,
                                  &client_name,
                                  &authenticator_buff)))
        return ret;
    log_service_name(context);

    /* We succesfully acquired the secondary context, now get the
       username for afpd and gss_wrap the sessionkey */
    if ((ret = get_client_username(username, ulen, &client_name)))
        goto cleanup_client_name;

    if ((ret = wrap_sessionkey(context, sinfo)))
        goto cleanup_client_name;

    /* Authenticated, construct the reply using:
     * authenticator length (uint16_t)
     * authenticator
     */
    /* copy the authenticator length into the reply buffer */
    uint16_t auth_len = htons(authenticator_buff.length);
    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;

cleanup_client_name:
    gss_release_name(&status, &client_name);

cleanup_context:
    gss_release_buffer(&status, &authenticator_buff);
    gss_delete_sec_context(&status, &context, NULL);

    return ret;
}
示例#3
0
static int
build_context(struct client *ipeer, struct client *apeer,
	      int32_t flags, int32_t hCred,
	      int32_t *iContext, int32_t *aContext, int32_t *hDelegCred)
{
    int32_t val = GSMERR_ERROR, ic = 0, ac = 0, deleg = 0;
    krb5_data itoken, otoken;
    int iDone = 0, aDone = 0;
    int step = 0;
    int first_call = 0x80;

    if (apeer->target_name == NULL)
	errx(1, "apeer %s have no target name", apeer->name);

    krb5_data_zero(&itoken);

    while (!iDone || !aDone) {

	if (iDone) {
	    warnx("iPeer already done, aPeer want extra rtt");
	    val = GSMERR_ERROR;
	    goto out;
	}

	val = init_sec_context(ipeer, &ic, &hCred, flags|first_call,
			       apeer->target_name, &itoken, &otoken);
	step++;
	switch(val) {
	case GSMERR_OK:
	    iDone = 1;
	    if (aDone)
		continue;
	    break;
	case GSMERR_CONTINUE_NEEDED:
	    break;
	default:
	    warnx("iPeer %s failed with %d (step %d)",
		  ipeer->name, (int)val, step);
	    goto out;
	}

	if (aDone) {
	    warnx("aPeer already done, iPeer want extra rtt");
	    val = GSMERR_ERROR;
	    goto out;
	}

	val = accept_sec_context(apeer, &ac, flags|first_call,
				 &otoken, &itoken, &deleg);
	step++;
	switch(val) {
	case GSMERR_OK:
	    aDone = 1;
	    if (iDone)
		continue;
	    break;
	case GSMERR_CONTINUE_NEEDED:
	    break;
	default:
	    warnx("aPeer %s failed with %d (step %d)",
		 apeer->name, (int)val, step);
	    val = GSMERR_ERROR;
	    goto out;
	}
	first_call = 0;
	val = GSMERR_OK;
    }

    if (iContext == NULL || val != GSMERR_OK) {
	if (ic)
	    toast_resource(ipeer, ic);
	if (iContext)
	    *iContext = 0;
    } else
	*iContext = ic;

    if (aContext == NULL || val != GSMERR_OK) {
	if (ac)
	    toast_resource(apeer, ac);
	if (aContext)
	    *aContext = 0;
    } else
	*aContext = ac;

    if (hDelegCred == NULL || val != GSMERR_OK) {
	if (deleg)
	    toast_resource(apeer, deleg);
	if (hDelegCred)
	    *hDelegCred = 0;
    } else
	*hDelegCred = deleg;

out:
    return val;
}
示例#4
0
/* 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;
}