bool_t xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p) { return (xdr_gss_buffer_desc(xdrs, &p->gr_handle) && xdr_u_int(xdrs, &p->gr_major) && xdr_u_int(xdrs, &p->gr_minor) && xdr_u_int(xdrs, &p->gr_win) && xdr_gss_buffer_desc(xdrs, &p->gr_token)); }
bool_t xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p) { enum_t proc, svc; bool_t ret; proc = p->gc_proc; svc = p->gc_svc; ret = (xdr_u_int(xdrs, &p->gc_version) && xdr_enum(xdrs, &proc) && xdr_u_int(xdrs, &p->gc_seq) && xdr_enum(xdrs, &svc) && xdr_gss_buffer_desc(xdrs, &p->gc_handle)); p->gc_proc = proc; p->gc_svc = svc; return (ret); }
bool_t xdr_gss_channel_bindings_t(XDR *xdrs, gss_channel_bindings_t *chp) { gss_channel_bindings_t ch; bool_t is_null; switch (xdrs->x_op) { case XDR_ENCODE: ch = *chp; if (ch) { is_null = FALSE; if (!xdr_bool(xdrs, &is_null) || !xdr_uint32_t(xdrs, &ch->initiator_addrtype) || !xdr_gss_buffer_desc(xdrs, &ch->initiator_address) || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) || !xdr_gss_buffer_desc(xdrs, &ch->acceptor_address) || !xdr_gss_buffer_desc(xdrs, &ch->application_data)) return (FALSE); } else { is_null = TRUE; if (!xdr_bool(xdrs, &is_null)) return (FALSE); } break; case XDR_DECODE: if (!xdr_bool(xdrs, &is_null)) return (FALSE); if (is_null) { *chp = GSS_C_NO_CHANNEL_BINDINGS; } else { ch = mem_alloc(sizeof(*ch)); memset(ch, 0, sizeof(*ch)); if (!xdr_uint32_t(xdrs, &ch->initiator_addrtype) || !xdr_gss_buffer_desc(xdrs, &ch->initiator_address) || !xdr_uint32_t(xdrs, &ch->acceptor_addrtype) || !xdr_gss_buffer_desc(xdrs, &ch->acceptor_address) || !xdr_gss_buffer_desc(xdrs, &ch->application_data)) { mem_free(ch, sizeof(*ch)); return (FALSE); } *chp = ch; } break; case XDR_FREE: ch = *chp; if (ch) { xdr_gss_buffer_desc(xdrs, &ch->initiator_address); xdr_gss_buffer_desc(xdrs, &ch->acceptor_address); xdr_gss_buffer_desc(xdrs, &ch->application_data); mem_free(ch, sizeof(*ch)); } } return (TRUE); }
bool_t xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_service_t svc, u_int seq) { XDR tmpxdrs; gss_buffer_desc databuf, wrapbuf; OM_uint32 maj_stat, min_stat; u_int seq_num, conf_state, qop_state; bool_t xdr_stat; if (xdr_func == (xdrproc_t) xdr_void || xdr_ptr == NULL) return (TRUE); memset(&databuf, 0, sizeof(databuf)); memset(&wrapbuf, 0, sizeof(wrapbuf)); if (svc == rpc_gss_svc_integrity) { /* Decode databody_integ. */ if (!xdr_gss_buffer_desc(xdrs, &databuf)) { log_debug("xdr decode databody_integ failed"); return (FALSE); } /* Decode checksum. */ if (!xdr_gss_buffer_desc(xdrs, &wrapbuf)) { mem_free(databuf.value, databuf.length); log_debug("xdr decode checksum failed"); return (FALSE); } /* Verify checksum and QOP. */ maj_stat = gss_verify_mic(&min_stat, ctx, &databuf, &wrapbuf, &qop_state); mem_free(wrapbuf.value, wrapbuf.length); if (maj_stat != GSS_S_COMPLETE || qop_state != qop) { mem_free(databuf.value, databuf.length); log_status("gss_verify_mic", NULL, maj_stat, min_stat); return (FALSE); } } else if (svc == rpc_gss_svc_privacy) { /* Decode databody_priv. */ if (!xdr_gss_buffer_desc(xdrs, &wrapbuf)) { log_debug("xdr decode databody_priv failed"); return (FALSE); } /* Decrypt databody. */ maj_stat = gss_unwrap(&min_stat, ctx, &wrapbuf, &databuf, &conf_state, &qop_state); mem_free(wrapbuf.value, wrapbuf.length); /* Verify encryption and QOP. */ if (maj_stat != GSS_S_COMPLETE || qop_state != qop || conf_state != TRUE) { gss_release_buffer(&min_stat, &databuf); log_status("gss_unwrap", NULL, maj_stat, min_stat); return (FALSE); } } /* Decode rpc_gss_data_t (sequence number + arguments). */ xdrmem_create(&tmpxdrs, databuf.value, databuf.length, XDR_DECODE); xdr_stat = (xdr_u_int(&tmpxdrs, &seq_num) && xdr_func(&tmpxdrs, xdr_ptr)); XDR_DESTROY(&tmpxdrs); /* * Integrity service allocates databuf via XDR so free it the * same way. */ if (svc == rpc_gss_svc_integrity) { xdr_free((xdrproc_t) xdr_gss_buffer_desc, (char *) &databuf); } else { gss_release_buffer(&min_stat, &databuf); } /* Verify sequence number. */ if (xdr_stat == TRUE && seq_num != seq) { log_debug("wrong sequence number in databody"); return (FALSE); } return (xdr_stat); }
bool_t xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_service_t svc, u_int seq) { gss_buffer_desc databuf, wrapbuf; OM_uint32 maj_stat, min_stat; int start, end, conf_state; u_int len; bool_t xdr_stat; /* Skip databody length. */ start = XDR_GETPOS(xdrs); XDR_SETPOS(xdrs, start + 4); /* Marshal rpc_gss_data_t (sequence number + arguments). */ if (!xdr_u_int(xdrs, &seq) || !xdr_func(xdrs, xdr_ptr)) return (FALSE); end = XDR_GETPOS(xdrs); /* Set databuf to marshalled rpc_gss_data_t. */ databuf.length = end - start - 4; XDR_SETPOS(xdrs, start + 4); databuf.value = XDR_INLINE(xdrs, databuf.length); xdr_stat = FALSE; if (svc == rpc_gss_svc_integrity) { /* Marshal databody_integ length. */ XDR_SETPOS(xdrs, start); len = databuf.length; if (!xdr_u_int(xdrs, &len)) return (FALSE); /* Checksum rpc_gss_data_t. */ maj_stat = gss_get_mic(&min_stat, ctx, qop, &databuf, &wrapbuf); if (maj_stat != GSS_S_COMPLETE) { log_debug("gss_get_mic failed"); return (FALSE); } /* Marshal checksum. */ XDR_SETPOS(xdrs, end); xdr_stat = xdr_gss_buffer_desc(xdrs, &wrapbuf); gss_release_buffer(&min_stat, &wrapbuf); } else if (svc == rpc_gss_svc_privacy) { /* Encrypt rpc_gss_data_t. */ maj_stat = gss_wrap(&min_stat, ctx, TRUE, qop, &databuf, &conf_state, &wrapbuf); if (maj_stat != GSS_S_COMPLETE) { log_status("gss_wrap", NULL, maj_stat, min_stat); return (FALSE); } /* Marshal databody_priv. */ XDR_SETPOS(xdrs, start); xdr_stat = xdr_gss_buffer_desc(xdrs, &wrapbuf); gss_release_buffer(&min_stat, &wrapbuf); } return (xdr_stat); }