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_svc_t svc, uint32_t seq) { XDR tmpxdrs; gss_buffer_desc databuf, wrapbuf; OM_uint32 maj_stat, min_stat; int conf_state; bool_t xdr_stat; xdralloc_create(&tmpxdrs, XDR_ENCODE); xdr_stat = FALSE; /* Marshal rpc_gss_data_t (sequence number + arguments). */ if (!xdr_u_int32(&tmpxdrs, &seq) || !(*xdr_func)(&tmpxdrs, xdr_ptr)) goto errout; /* Set databuf to marshalled rpc_gss_data_t. */ databuf.length = xdr_getpos(&tmpxdrs); databuf.value = xdralloc_getdata(&tmpxdrs); if (svc == RPCSEC_GSS_SVC_INTEGRITY) { if (!xdr_rpc_gss_buf(xdrs, &databuf, (unsigned int)-1)) goto errout; /* 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"); goto errout; } /* Marshal checksum. */ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1); gss_release_buffer(&min_stat, &wrapbuf); } else if (svc == RPCSEC_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", maj_stat, min_stat); goto errout; } /* Marshal databody_priv. */ xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1); gss_release_buffer(&min_stat, &wrapbuf); } errout: xdr_destroy(&tmpxdrs); return (xdr_stat); }
bool_t xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p) { bool_t xdr_stat; xdr_stat = (xdr_rpc_gss_buf(xdrs, &p->gr_ctx, MAX_NETOBJ_SZ) && xdr_u_int32(xdrs, &p->gr_major) && xdr_u_int32(xdrs, &p->gr_minor) && xdr_u_int32(xdrs, &p->gr_win) && xdr_rpc_gss_buf(xdrs, &p->gr_token, MAX_NETOBJ_SZ)); log_debug("xdr_rpc_gss_init_res %s %s " "(ctx %p:%d, maj %d, min %d, win %d, token %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->gr_ctx.value, p->gr_ctx.length, p->gr_major, p->gr_minor, p->gr_win, p->gr_token.value, p->gr_token.length); return (xdr_stat); }
bool_t xdr_rpc_gss_init_args(XDR *xdrs, gss_buffer_desc *p) { bool_t xdr_stat; xdr_stat = xdr_rpc_gss_buf(xdrs, p, MAX_NETOBJ_SZ); log_debug("xdr_rpc_gss_init_args: %s %s (token %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->value, p->length); return (xdr_stat); }
bool_t xdr_rpc_gss_init_args(XDR *xdrs, gss_buffer_desc *p) { bool_t xdr_stat; u_int maxlen = (u_int)(p->length + RPC_SLACK_SPACE); xdr_stat = xdr_rpc_gss_buf(xdrs, p, maxlen); log_debug("xdr_rpc_gss_init_args: %s %s (token %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->value, p->length); return (xdr_stat); }
bool_t xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p) { bool_t xdr_stat; u_int ctx_maxlen = (u_int)(p->gr_ctx.length + RPC_SLACK_SPACE); u_int tok_maxlen = (u_int)(p->gr_token.length + RPC_SLACK_SPACE); xdr_stat = (xdr_rpc_gss_buf(xdrs, &p->gr_ctx, ctx_maxlen) && xdr_u_int(xdrs, &p->gr_major) && xdr_u_int(xdrs, &p->gr_minor) && xdr_u_int(xdrs, &p->gr_win) && xdr_rpc_gss_buf(xdrs, &p->gr_token, tok_maxlen)); log_debug("xdr_rpc_gss_init_res %s %s " "(ctx %p:%d, maj %d, min %d, win %d, token %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->gr_ctx.value, p->gr_ctx.length, p->gr_major, p->gr_minor, p->gr_win, p->gr_token.value, p->gr_token.length); return (xdr_stat); }
bool_t xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p) { bool_t xdr_stat; xdr_stat = (xdr_u_int(xdrs, &p->gc_v) && xdr_enum(xdrs, (enum_t *)&p->gc_proc) && xdr_u_int(xdrs, &p->gc_seq) && xdr_enum(xdrs, (enum_t *)&p->gc_svc) && xdr_rpc_gss_buf(xdrs, &p->gc_ctx, MAX_AUTH_BYTES)); log_debug("xdr_rpc_gss_cred: %s %s " "(v %d, proc %d, seq %d, svc %d, ctx %p:%d)", (xdrs->x_op == XDR_ENCODE) ? "encode" : "decode", (xdr_stat == TRUE) ? "success" : "failure", p->gc_v, p->gc_proc, p->gc_seq, p->gc_svc, p->gc_ctx.value, p->gc_ctx.length); return (xdr_stat); }
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_svc_t svc, u_int seq) { XDR tmpxdrs; gss_buffer_desc databuf, wrapbuf; OM_uint32 maj_stat, min_stat; u_int seq_num, qop_state; int conf_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 == RPCSEC_GSS_SVC_INTEGRITY) { /* Decode databody_integ. */ if (!xdr_rpc_gss_buf(xdrs, &databuf, (u_int)-1)) { log_debug("xdr decode databody_integ failed"); return (FALSE); } /* Decode checksum. */ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) { gss_release_buffer(&min_stat, &databuf); log_debug("xdr decode checksum failed"); return (FALSE); } /* Verify checksum and QOP. */ maj_stat = gss_verify_mic(&min_stat, ctx, &databuf, &wrapbuf, &qop_state); gss_release_buffer(&min_stat, &wrapbuf); if (maj_stat != GSS_S_COMPLETE || qop_state != qop) { gss_release_buffer(&min_stat, &databuf); log_status("gss_verify_mic", maj_stat, min_stat); return (FALSE); } } else if (svc == RPCSEC_GSS_SVC_PRIVACY) { /* Decode databody_priv. */ if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) { log_debug("xdr decode databody_priv failed"); return (FALSE); } /* Decrypt databody. */ maj_stat = gss_unwrap(&min_stat, ctx, &wrapbuf, &databuf, &conf_state, &qop_state); gss_release_buffer(&min_stat, &wrapbuf); /* 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", 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); 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_svc_t svc, u_int seq) { gss_buffer_desc databuf, wrapbuf; OM_uint32 maj_stat, min_stat; int start, end, conf_state; bool_t xdr_stat; u_int databuflen, maxwrapsz; /* Skip databody length. */ start = XDR_GETPOS(xdrs); XDR_SETPOS(xdrs, start + 4); memset(&databuf, 0, sizeof(databuf)); memset(&wrapbuf, 0, sizeof(wrapbuf)); /* 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. */ databuflen = end - start - 4; XDR_SETPOS(xdrs, start + 4); databuf.value = XDR_INLINE(xdrs, databuflen); xdr_stat = FALSE; if (svc == RPCSEC_GSS_SVC_INTEGRITY) { /* Marshal databody_integ length. */ XDR_SETPOS(xdrs, start); if (!xdr_u_int(xdrs, (u_int *)&databuflen)) return (FALSE); databuf.length = databuflen; /* 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); maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE); xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz); gss_release_buffer(&min_stat, &wrapbuf); } else if (svc == RPCSEC_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", maj_stat, min_stat); return (FALSE); } /* Marshal databody_priv. */ XDR_SETPOS(xdrs, start); maxwrapsz = (u_int)(wrapbuf.length + RPC_SLACK_SPACE); xdr_stat = xdr_rpc_gss_buf(xdrs, &wrapbuf, maxwrapsz); gss_release_buffer(&min_stat, &wrapbuf); } return (xdr_stat); }