/* * 3. Validate */ static bool authdes_validate(AUTH *auth, struct opaque_auth *rverf) { /* LINTED pointer alignment */ struct ad_private *ad = AUTH_PRIVATE(auth); struct authdes_verf verf; int status; uint32_t *ixdr; des_block buf; if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) return (false); /* LINTED pointer alignment */ ixdr = (uint32_t *) rverf->oa_base; buf.key.high = (uint32_t) *ixdr++; buf.key.low = (uint32_t) *ixdr++; verf.adv_int_u = (uint32_t) *ixdr++; /* * Decrypt the timestamp */ status = ecb_crypt((char *)&auth->ah_key, (char *)&buf, (u_int) sizeof(des_block), DES_DECRYPT | DES_HW); if (DES_FAILED(status)) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "authdes_validate: DES decryption failure"); return (false); } /* * xdr the decrypted timestamp */ /* LINTED pointer alignment */ ixdr = (uint32_t *) buf.c; verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1; verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr); /* * validate */ if (bcmp ((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, sizeof(struct timeval)) != 0) { __warnx(TIRPC_DEBUG_FLAG_AUTH, "authdes_validate: verifier mismatch"); return (false); } /* * We have a nickname now, let's use it */ ad->ad_nickname = verf.adv_nickname; ad->ad_cred.adc_namekind = ADN_NICKNAME; return (true); }
static void authunix_destroy(AUTH *auth) { struct audata *au = AUTH_PRIVATE(auth); assert(auth != NULL); mem_free(au, sizeof(*au)); }
/* * Function: auth_gssapi_marhsall * * Purpose: Marshall RPC credentials and verifier onto xdr stream. * * Arguments: * * auth (r/w) AUTH structure for client * xdrs (r/w) XDR stream to marshall to * * Returns: boolean indicating success/failure * * Effects: * * The pre-serialized credentials in cred_buf are serialized. If the * context is established, the sealed sequence number is serialized as * the verifier. If the context is not established, an empty verifier * is serialized. The sequence number is *not* incremented, because * this function is called multiple times if retransmission is required. * * If this took all the header fields as arguments, it could sign * them. */ static bool_t auth_gssapi_marshall( AUTH *auth, XDR *xdrs) { OM_uint32 minor_stat; gss_buffer_desc out_buf; uint32_t seq_num; if (AUTH_PRIVATE(auth)->established == TRUE) { PRINTF(("gssapi_marshall: starting\n")); seq_num = AUTH_PRIVATE(auth)->seq_num + 1; PRINTF(("gssapi_marshall: sending seq_num %d\n", seq_num)); if (auth_gssapi_seal_seq(AUTH_PRIVATE(auth)->context, seq_num, &out_buf) == FALSE) { PRINTF(("gssapi_marhshall: seal failed\n")); } auth->ah_verf.oa_base = out_buf.value; auth->ah_verf.oa_length = out_buf.length; if (! xdr_opaque_auth(xdrs, &auth->ah_cred) || ! xdr_opaque_auth(xdrs, &auth->ah_verf)) { (void) gss_release_buffer(&minor_stat, &out_buf); return FALSE; } (void) gss_release_buffer(&minor_stat, &out_buf); } else { PRINTF(("gssapi_marshall: not established, sending null verf\n")); auth->ah_verf.oa_base = NULL; auth->ah_verf.oa_length = 0; if (! xdr_opaque_auth(xdrs, &auth->ah_cred) || ! xdr_opaque_auth(xdrs, &auth->ah_verf)) { return FALSE; } } return TRUE; }
static bool authunix_marshal(AUTH *auth, XDR *xdrs) { struct audata *au = AUTH_PRIVATE(auth); assert(auth != NULL); assert(xdrs != NULL); return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); }
/* * 5. Destroy */ static void authdes_destroy (AUTH *auth) { struct ad_private *ad = AUTH_PRIVATE (auth); FREE (ad->ad_fullname, ad->ad_fullnamelen + 1); FREE (ad->ad_servername, ad->ad_servernamelen + 1); FREE (ad, sizeof (struct ad_private)); FREE (auth, sizeof (AUTH)); }
/* * Function: marshall_new_creds * * Purpose: (pre-)serialize auth_msg and client_handle fields of * auth_gssapi_creds into auth->cred_buf * * Arguments: * * auth (r/w) the AUTH structure to modify * auth_msg (r) the auth_msg field to serialize * client_handle (r) the client_handle field to serialize, or * NULL * * Returns: TRUE if successful, FALSE if not * * Requires: auth must point to a valid GSS-API auth structure, auth_msg * must be TRUE or FALSE, client_handle must be a gss_buffer_t with a valid * value and length field or NULL. * * Effects: auth->ah_cred is set to the serialized auth_gssapi_creds * version 2 structure (stored in the cred_buf field of private data) * containing version, auth_msg and client_handle. * auth->ah_cred.oa_flavor is set to AUTH_GSSAPI. If cliend_handle is * NULL, it is treated as if it had a length of 0 and a value of NULL. * * Modifies: auth */ static bool_t marshall_new_creds( AUTH *auth, bool_t auth_msg, gss_buffer_t client_handle) { auth_gssapi_creds creds; XDR xdrs; PRINTF(("marshall_new_creds: starting\n")); creds.version = 2; creds.auth_msg = auth_msg; if (client_handle) GSS_COPY_BUFFER(creds.client_handle, *client_handle) else { creds.client_handle.length = 0; creds.client_handle.value = NULL; } xdrmem_create(&xdrs, (caddr_t) AUTH_PRIVATE(auth)->cred_buf, MAX_AUTH_BYTES, XDR_ENCODE); if (! xdr_authgssapi_creds(&xdrs, &creds)) { PRINTF(("marshall_new_creds: failed encoding auth_gssapi_creds\n")); XDR_DESTROY(&xdrs); return FALSE; } AUTH_PRIVATE(auth)->cred_len = xdr_getpos(&xdrs); XDR_DESTROY(&xdrs); PRINTF(("marshall_new_creds: auth_gssapi_creds is %d bytes\n", AUTH_PRIVATE(auth)->cred_len)); auth->ah_cred.oa_flavor = AUTH_GSSAPI; auth->ah_cred.oa_base = (char *) AUTH_PRIVATE(auth)->cred_buf; auth->ah_cred.oa_length = AUTH_PRIVATE(auth)->cred_len; PRINTF(("marshall_new_creds: succeeding\n")); return TRUE; }
static bool_t authgss_validate(AUTH *auth, struct opaque_auth *verf) { struct rpc_gss_data *gd; u_int num, qop_state; gss_buffer_desc signbuf, checksum; OM_uint32 maj_stat, min_stat; log_debug("in authgss_validate()"); gd = AUTH_PRIVATE(auth); if (gd->established == FALSE) { /* would like to do this only on NULL rpc -- * gc->established is good enough. * save the on the wire verifier to validate last * INIT phase packet after decode if the major * status is GSS_S_COMPLETE */ if ((gd->gc_wire_verf.value = mem_alloc(verf->oa_length)) == NULL) { fprintf(stderr, "gss_validate: out of memory\n"); return (FALSE); } memcpy(gd->gc_wire_verf.value, verf->oa_base, verf->oa_length); gd->gc_wire_verf.length = verf->oa_length; return (TRUE); } if (gd->gc.gc_proc == RPCSEC_GSS_INIT || gd->gc.gc_proc == RPCSEC_GSS_CONTINUE_INIT) { num = htonl(gd->win); } else num = htonl(gd->gc.gc_seq); signbuf.value = # signbuf.length = sizeof(num); checksum.value = verf->oa_base; checksum.length = verf->oa_length; maj_stat = gss_verify_mic(&min_stat, gd->ctx, &signbuf, &checksum, &qop_state); if (maj_stat != GSS_S_COMPLETE || qop_state != gd->sec.qop) { log_status("gss_verify_mic", maj_stat, min_stat); if (maj_stat == GSS_S_CONTEXT_EXPIRED) { gd->established = FALSE; authgss_destroy_context(auth); } return (FALSE); } return (TRUE); }
/* * 3. Validate */ static bool_t authdes_validate (AUTH *auth, struct opaque_auth *rverf) { struct ad_private *ad = AUTH_PRIVATE (auth); struct authdes_verf verf; int status; register uint32_t *ixdr; if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) return FALSE; ixdr = (uint32_t *) rverf->oa_base; verf.adv_xtimestamp.key.high = *ixdr++; verf.adv_xtimestamp.key.low = *ixdr++; verf.adv_int_u = *ixdr++; /* nickname not XDR'd ! */ /* * Decrypt the timestamp */ status = ecb_crypt ((char *) &auth->ah_key, (char *) &verf.adv_xtimestamp, sizeof (des_block), DES_DECRYPT | DES_HW); if (DES_FAILED (status)) { debug ("authdes_validate: DES decryption failure"); return FALSE; } /* * xdr the decrypted timestamp */ ixdr = (uint32_t *) verf.adv_xtimestamp.c; verf.adv_timestamp.tv_sec = IXDR_GET_U_INT32 (ixdr) + 1; verf.adv_timestamp.tv_usec = IXDR_GET_U_INT32 (ixdr); /* * validate */ if (memcmp ((char *) &ad->ad_timestamp, (char *) &verf.adv_timestamp, sizeof (struct rpc_timeval)) != 0) { debug ("authdes_validate: verifier mismatch\n"); return FALSE; } /* * We have a nickname now, let's use it */ ad->ad_nickname = verf.adv_nickname; ad->ad_cred.adc_namekind = ADN_NICKNAME; return TRUE; }
static bool_t rpc_gss_validate(AUTH *auth, struct opaque_auth *verf) { struct rpc_gss_data *gd; gss_qop_t qop_state; uint32_t num; gss_buffer_desc signbuf, checksum; OM_uint32 maj_stat, min_stat; log_debug("in rpc_gss_validate()"); gd = AUTH_PRIVATE(auth); if (gd->gd_state == RPCSEC_GSS_CONTEXT) { /* * Save the on the wire verifier to validate last INIT * phase packet after decode if the major status is * GSS_S_COMPLETE. */ if (gd->gd_verf.value) xdr_free((xdrproc_t) xdr_gss_buffer_desc, (char *) &gd->gd_verf); gd->gd_verf.value = mem_alloc(verf->oa_length); if (gd->gd_verf.value == NULL) { fprintf(stderr, "gss_validate: out of memory\n"); _rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM); return (FALSE); } memcpy(gd->gd_verf.value, verf->oa_base, verf->oa_length); gd->gd_verf.length = verf->oa_length; return (TRUE); } num = htonl(gd->gd_cred.gc_seq); signbuf.value = # signbuf.length = sizeof(num); checksum.value = verf->oa_base; checksum.length = verf->oa_length; maj_stat = gss_verify_mic(&min_stat, gd->gd_ctx, &signbuf, &checksum, &qop_state); if (maj_stat != GSS_S_COMPLETE || qop_state != gd->gd_qop) { log_status("gss_verify_mic", gd->gd_mech, maj_stat, min_stat); if (maj_stat == GSS_S_CONTEXT_EXPIRED) { rpc_gss_destroy_context(auth, TRUE); } _rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, EPERM); return (FALSE); } return (TRUE); }
/* * Function: auth_gssapi_unwrap * * Purpose: read encrypted arguments from xdrs, decrypt, and * deserialize with xdr_func into xdr_ptr. * * Effects: See design doc, section XXX. */ static bool_t auth_gssapi_unwrap( AUTH *auth, XDR *in_xdrs, bool_t (*xdr_func)(), caddr_t xdr_ptr) { OM_uint32 gssstat, minor_stat; if (! AUTH_PRIVATE(auth)->established) { PRINTF(("gssapi_unwrap: context not established, noop\n")); return (*xdr_func)(in_xdrs, xdr_ptr); } else if (! auth_gssapi_unwrap_data(&gssstat, &minor_stat, AUTH_PRIVATE(auth)->context, AUTH_PRIVATE(auth)->seq_num, in_xdrs, xdr_func, xdr_ptr)) { if (gssstat != GSS_S_COMPLETE) AUTH_GSSAPI_DISPLAY_STATUS(("decrypting function arguments", gssstat, minor_stat)); return FALSE; } else return TRUE; }
/* * Function: auth_gssapi_refresh * * Purpose: Attempts to resyncrhonize the sequence number. * * Effects: * * When the server receives a properly authenticated RPC call, it * increments the sequence number it is expecting from the client. * But if the server's response is lost for any reason, the client * can't know whether the server ever received it, assumes it didn't, * and does *not* increment its sequence number. Thus, the client's * next call will fail with AUTH_REJECTEDCRED because the server will * think it is a replay attack. * * When an AUTH_REJECTEDCRED error arrives, this function attempts to * resyncrhonize by incrementing the client's sequence number and * returning TRUE. If any other error arrives, it returns FALSE. */ static bool_t auth_gssapi_refresh( AUTH *auth, struct rpc_msg *msg) { if (msg->rm_reply.rp_rjct.rj_stat == AUTH_ERROR && msg->rm_reply.rp_rjct.rj_why == AUTH_REJECTEDVERF) { PRINTF(("gssapi_refresh: rejected verifier, incrementing\n")); AUTH_PRIVATE(auth)->seq_num++; return TRUE; } else { PRINTF(("gssapi_refresh: failing\n")); return FALSE; } }
/* * Function: auth_gssapi_validate * * Purpose: Validate RPC response verifier from server. * * Effects: See design document, section XXX. */ static bool_t auth_gssapi_validate( AUTH *auth, struct opaque_auth *verf) { gss_buffer_desc in_buf; uint32_t seq_num; if (AUTH_PRIVATE(auth)->established == FALSE) { PRINTF(("gssapi_validate: not established, noop\n")); return TRUE; } PRINTF(("gssapi_validate: starting\n")); in_buf.length = verf->oa_length; in_buf.value = verf->oa_base; if (auth_gssapi_unseal_seq(AUTH_PRIVATE(auth)->context, &in_buf, &seq_num) == FALSE) { PRINTF(("gssapi_validate: failed unsealing verifier\n")); return FALSE; } /* we sent seq_num+1, so we should get back seq_num+2 */ if (AUTH_PRIVATE(auth)->seq_num+2 != seq_num) { PRINTF(("gssapi_validate: expecting seq_num %d, got %d (%#x)\n", AUTH_PRIVATE(auth)->seq_num + 2, seq_num, seq_num)); return FALSE; } PRINTF(("gssapi_validate: seq_num %d okay\n", seq_num)); /* +1 for successful transmission, +1 for successful validation */ AUTH_PRIVATE(auth)->seq_num += 2; PRINTF(("gssapi_validate: succeeding\n")); return TRUE; }
/* * Marshals (pre-serializes) an auth struct. * sets private data, au_marshed and au_mpos */ static void marshal_new_auth(AUTH *auth) { XDR xdr_stream; XDR *xdrs = &xdr_stream; struct audata *au = AUTH_PRIVATE(auth); xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { perror("auth_none.c - Fatal marshalling problem"); } else { au->au_mpos = XDR_GETPOS(xdrs); } XDR_DESTROY(xdrs); }
bool_t authgss_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr) { struct rpc_gss_data *gd; log_debug("in authgss_unwrap()"); gd = AUTH_PRIVATE(auth); if (!gd->established || gd->sec.svc == RPCSEC_GSS_SVC_NONE) { return ((*xdr_func)(xdrs, xdr_ptr)); } return (xdr_rpc_gss_data(xdrs, xdr_func, xdr_ptr, gd->ctx, gd->sec.qop, gd->sec.svc, gd->gc.gc_seq)); }
bool_t authgss_service(AUTH *auth, int svc) { struct rpc_gss_data *gd; log_debug("in authgss_service()"); if (!auth) return(FALSE); gd = AUTH_PRIVATE(auth); if (!gd || !gd->established) return (FALSE); gd->sec.svc = svc; gd->gc.gc_svc = svc; return (TRUE); }
/* * Marshals (pre-serializes) an auth struct. * sets private data, au_marshed and au_mpos */ static void marshal_new_auth(AUTH *auth) { XDR xdr_stream; XDR *xdrs = &xdr_stream; struct audata *au = AUTH_PRIVATE(auth); xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { /* XXX nothing we can do */ } else { au->au_mpos = XDR_GETPOS(xdrs); } XDR_DESTROY(xdrs); }
static void authunix_destroy(AUTH *auth) { struct audata *au = AUTH_PRIVATE(auth); mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); if (au->au_shcred.oa_base != NULL) mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); mem_free(auth->ah_private, sizeof(struct audata)); if (auth->ah_verf.oa_base != NULL) mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); mem_free((caddr_t)auth, sizeof(*auth)); }
/* * 5. Destroy */ static void authdes_destroy(AUTH *auth) { /* LINTED pointer alignment */ struct ad_private *ad = AUTH_PRIVATE(auth); FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); FREE(ad->ad_servername, ad->ad_servernamelen + 1); if (ad->ad_timehost) FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); if (ad->ad_netid) FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); if (ad->ad_uaddr) FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); FREE(ad, sizeof(struct ad_private)); FREE(auth, sizeof(AUTH)); }
bool_t __rpc_gss_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, void *xdr_ptr) { struct rpc_gss_data *gd; log_debug("in rpc_gss_unwrap()"); gd = AUTH_PRIVATE(auth); if (gd->gd_state != RPCSEC_GSS_ESTABLISHED || gd->gd_cred.gc_svc == rpc_gss_svc_none) { return (xdr_func(xdrs, xdr_ptr)); } return (xdr_rpc_gss_unwrap_data(xdrs, xdr_func, xdr_ptr, gd->gd_ctx, gd->gd_qop, gd->gd_cred.gc_svc, gd->gd_cred.gc_seq)); }
/* * Marshals (pre-serializes) an auth struct. * sets private data, au_marshed and au_mpos */ static void marshal_new_auth(AUTH *auth) { XDR xdrs[1]; struct audata *au = AUTH_PRIVATE(auth); assert(auth != NULL); xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); if ((!xdr_opaque_auth_encode(xdrs, &(auth->ah_cred))) || (!xdr_opaque_auth_encode(xdrs, &(auth->ah_verf)))) __warnx(TIRPC_DEBUG_FLAG_AUTH, "auth_none.c - Fatal marshalling " "problem"); else au->au_mpos = XDR_GETPOS(xdrs); XDR_DESTROY(xdrs); }
/* * Marshals (pre-serializes) an auth struct. * sets private data, au_marshed and au_mpos */ static void marshal_new_auth(AUTH *auth) { XDR xdr_stream; XDR *xdrs = &xdr_stream; struct audata *au; _DIAGASSERT(auth != NULL); au = AUTH_PRIVATE(auth); xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) warnx("%s: Fatal marshalling problem", __func__); else au->au_mpos = XDR_GETPOS(xdrs); XDR_DESTROY(xdrs); }
static void authgss_destroy(AUTH *auth) { struct rpc_gss_data *gd; OM_uint32 min_stat; log_debug("in authgss_destroy()"); gd = AUTH_PRIVATE(auth); authgss_destroy_context(auth); if (gd->name != GSS_C_NO_NAME) gss_release_name(&min_stat, &gd->name); free(gd); free(auth); }
static bool authunix_refresh(AUTH *auth, void *dummy) { struct audata *au = AUTH_PRIVATE(auth); struct authunix_parms aup; struct timespec now; XDR xdrs; int stat; assert(auth != NULL); if (memcmp(&auth->ah_cred, &au->au_origcred, sizeof(struct opaque_auth)) == 0) { /* there is no hope. Punt */ return (false); } au->au_shfaults++; /* first deserialize the creds back into a struct authunix_parms */ aup.aup_machname = NULL; aup.aup_gids = NULL; xdrmem_create(&xdrs, au->au_origcred.oa_body, au->au_origcred.oa_length, XDR_DECODE); stat = xdr_authunix_parms(&xdrs, &aup); if (!stat) goto done; /* update the time and serialize in place */ (void)clock_gettime(CLOCK_MONOTONIC_FAST, &now); aup.aup_time = now.tv_sec; xdrs.x_op = XDR_ENCODE; XDR_SETPOS(&xdrs, 0); stat = xdr_authunix_parms(&xdrs, &aup); if (!stat) goto done; auth->ah_cred = au->au_origcred; marshal_new_auth(auth); done: /* free the struct authunix_parms created by deserializing */ xdrs.x_op = XDR_FREE; (void)xdr_authunix_parms(&xdrs, &aup); XDR_DESTROY(&xdrs); return (stat); }
int rpc_gss_max_data_length(AUTH *auth, int max_tp_unit_len) { struct rpc_gss_data *gd; int want_conf; OM_uint32 max; OM_uint32 maj_stat, min_stat; int result; gd = AUTH_PRIVATE(auth); switch (gd->gd_cred.gc_svc) { case rpc_gss_svc_none: return (max_tp_unit_len); break; case rpc_gss_svc_default: case rpc_gss_svc_integrity: want_conf = FALSE; break; case rpc_gss_svc_privacy: want_conf = TRUE; break; default: return (0); } maj_stat = gss_wrap_size_limit(&min_stat, gd->gd_ctx, want_conf, gd->gd_qop, max_tp_unit_len, &max); if (maj_stat == GSS_S_COMPLETE) { result = (int) max; if (result < 0) result = 0; return (result); } else { log_status("gss_wrap_size_limit", gd->gd_mech, maj_stat, min_stat); return (0); } }
static bool_t authunix_refresh(AUTH *auth) { struct audata *au = AUTH_PRIVATE(auth); struct authunix_parms aup; struct timeval now; XDR xdrs; int stat; _DIAGASSERT(auth != NULL); if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { /* there is no hope. Punt */ return (FALSE); } au->au_shfaults++; /* first deserialize the creds back into a struct authunix_parms */ aup.aup_machname = NULL; aup.aup_gids = NULL; xdrmem_create(&xdrs, au->au_origcred.oa_base, au->au_origcred.oa_length, XDR_DECODE); stat = xdr_authunix_parms(&xdrs, &aup); if (! stat) goto done; /* update the time and serialize in place */ (void)gettimeofday(&now, NULL); aup.aup_time = (u_long)now.tv_sec; /* XXX: truncate on 32 bit */ xdrs.x_op = XDR_ENCODE; XDR_SETPOS(&xdrs, 0); stat = xdr_authunix_parms(&xdrs, &aup); if (! stat) goto done; auth->ah_cred = au->au_origcred; marshal_new_auth(auth); done: /* free the struct authunix_parms created by deserializing */ xdrs.x_op = XDR_FREE; (void)xdr_authunix_parms(&xdrs, &aup); XDR_DESTROY(&xdrs); return (stat); }
static void authgss_destroy_context(AUTH *auth) { struct rpc_gss_data *gd; OM_uint32 min_stat; log_debug("in authgss_destroy_context()"); gd = AUTH_PRIVATE(auth); if (gd->gc.gc_ctx.length != 0) { if (gd->established) { AUTH *save_auth = NULL; /* Make sure we use the right auth_ops */ if (gd->clnt->cl_auth != auth) { save_auth = gd->clnt->cl_auth; gd->clnt->cl_auth = auth; } gd->gc.gc_proc = RPCSEC_GSS_DESTROY; clnt_call(gd->clnt, NULLPROC, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, NULL, AUTH_TIMEOUT); if (save_auth != NULL) gd->clnt->cl_auth = save_auth; } gss_release_buffer(&min_stat, &gd->gc.gc_ctx); /* XXX ANDROS check size of context - should be 8 */ memset(&gd->gc.gc_ctx, 0, sizeof(gd->gc.gc_ctx)); } if (gd->ctx != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&min_stat, &gd->ctx, NULL); gd->ctx = GSS_C_NO_CONTEXT; } /* free saved wire verifier (if any) */ mem_free(gd->gc_wire_verf.value, gd->gc_wire_verf.length); gd->gc_wire_verf.value = NULL; gd->gc_wire_verf.length = 0; gd->established = FALSE; }
static void authgss_destroy(AUTH *auth) { struct rpc_gss_data *gd; OM_uint32 min_stat; log_debug("in authgss_destroy()"); gd = AUTH_PRIVATE(auth); authgss_destroy_context(auth); #ifdef DEBUG fprintf(stderr, "authgss_destroy: freeing name %p\n", gd->name); #endif if (gd->name != GSS_C_NO_NAME) gss_release_name(&min_stat, &gd->name); free(gd); free(auth); }
static void rpc_gss_destroy(AUTH *auth) { struct rpc_gss_data *gd; OM_uint32 min_stat; log_debug("in rpc_gss_destroy()"); gd = AUTH_PRIVATE(auth); rpc_gss_destroy_context(auth, TRUE); if (gd->gd_name != GSS_C_NO_NAME) gss_release_name(&min_stat, &gd->gd_name); if (gd->gd_verf.value) xdr_free((xdrproc_t) xdr_gss_buffer_desc, (char *) &gd->gd_verf); mem_free(gd, sizeof(*gd)); mem_free(auth, sizeof(*auth)); }
bool_t authgss_get_private_data(AUTH *auth, struct authgss_private_data *pd) { struct rpc_gss_data *gd; log_debug("in authgss_get_private_data()"); if (!auth || !pd) return (FALSE); gd = AUTH_PRIVATE(auth); if (!gd || !gd->established) return (FALSE); pd->pd_ctx = gd->ctx; pd->pd_ctx_hndl = gd->gc.gc_ctx; pd->pd_seq_win = gd->win; return (TRUE); }
static bool authunix_validate(AUTH *auth, struct opaque_auth *verf) { struct audata *au = AUTH_PRIVATE(auth); XDR xdrs; assert(auth != NULL); assert(verf != NULL); if (verf->oa_flavor == AUTH_SHORT) { xdrmem_create(&xdrs, verf->oa_body, verf->oa_length, XDR_DECODE); if (xdr_opaque_auth_decode(&xdrs, &au->au_shcred, NULL)) { auth->ah_cred = au->au_shcred; } else { auth->ah_cred = au->au_origcred; } marshal_new_auth(auth); } return (true); }