Path: blob/main/crypto/krb5/src/lib/rpc/auth_gssapi_misc.c
39536 views
/*1* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.2*3*/45#include <gssrpc/rpc.h>6#include <stdio.h>78#include <gssapi/gssapi.h>9#include <gssrpc/auth_gssapi.h>1011#include "gssrpcint.h"1213#ifdef __CODECENTER__14#define DEBUG_GSSAPI 115#endif1617#ifdef DEBUG_GSSAPI18int misc_debug_gssapi = DEBUG_GSSAPI;19extern void gssrpcint_printf(const char *, ...);20#define L_PRINTF(l,args) if (misc_debug_gssapi >= l) gssrpcint_printf args21#define PRINTF(args) L_PRINTF(99, args)22#define AUTH_GSSAPI_DISPLAY_STATUS(args) \23if (misc_debug_gssapi) auth_gssapi_display_status args24#else25#define PRINTF(args)26#define L_PRINTF(l, args)27#define AUTH_GSSAPI_DISPLAY_STATUS(args)28#endif2930static void auth_gssapi_display_status_131(char *, OM_uint32, int, int);3233bool_t xdr_gss_buf(34XDR *xdrs,35gss_buffer_t buf)36{37/*38* On decode, xdr_bytes will only allocate buf->value if the39* length read in is < maxsize (last arg). This is dumb, because40* the whole point of allocating memory is so that I don't *have*41* to know the maximum length. -1 effectively disables this42* braindamage.43*/44bool_t result;45/* Fix type mismatches between APIs. */46unsigned int length = buf->length;47char *cp = buf->value;48result = xdr_bytes(xdrs, &cp, &length,49(xdrs->x_op == XDR_DECODE && buf->value == NULL)50? (unsigned int) -1 : (unsigned int) buf->length);51buf->value = cp;52buf->length = length;53return result;54}5556bool_t xdr_authgssapi_creds(57XDR *xdrs,58auth_gssapi_creds *creds)59{60if (! xdr_u_int32(xdrs, &creds->version) ||61! xdr_bool(xdrs, &creds->auth_msg) ||62! xdr_gss_buf(xdrs, &creds->client_handle))63return FALSE;64return TRUE;65}6667bool_t xdr_authgssapi_init_arg(68XDR *xdrs,69auth_gssapi_init_arg *init_arg)70{71if (! xdr_u_int32(xdrs, &init_arg->version) ||72! xdr_gss_buf(xdrs, &init_arg->token))73return FALSE;74return TRUE;75}7677bool_t xdr_authgssapi_init_res(78XDR *xdrs,79auth_gssapi_init_res *init_res)80{81if (! xdr_u_int32(xdrs, &init_res->version) ||82! xdr_gss_buf(xdrs, &init_res->client_handle) ||83! xdr_u_int32(xdrs, &init_res->gss_major) ||84! xdr_u_int32(xdrs, &init_res->gss_minor) ||85! xdr_gss_buf(xdrs, &init_res->token) ||86! xdr_gss_buf(xdrs, &init_res->signed_isn))87return FALSE;88return TRUE;89}9091bool_t auth_gssapi_seal_seq(92gss_ctx_id_t context,93uint32_t seq_num,94gss_buffer_t out_buf)95{96gss_buffer_desc in_buf;97OM_uint32 gssstat, minor_stat;98uint32_t nl_seq_num;99100nl_seq_num = htonl(seq_num);101102in_buf.length = sizeof(uint32_t);103in_buf.value = (char *) &nl_seq_num;104gssstat = gss_seal(&minor_stat, context, 0, GSS_C_QOP_DEFAULT,105&in_buf, NULL, out_buf);106if (gssstat != GSS_S_COMPLETE) {107PRINTF(("gssapi_seal_seq: failed\n"));108AUTH_GSSAPI_DISPLAY_STATUS(("sealing sequence number",109gssstat, minor_stat));110return FALSE;111}112return TRUE;113}114115bool_t auth_gssapi_unseal_seq(116gss_ctx_id_t context,117gss_buffer_t in_buf,118uint32_t *seq_num)119{120gss_buffer_desc out_buf;121OM_uint32 gssstat, minor_stat;122uint32_t nl_seq_num;123124gssstat = gss_unseal(&minor_stat, context, in_buf, &out_buf,125NULL, NULL);126if (gssstat != GSS_S_COMPLETE) {127PRINTF(("gssapi_unseal_seq: failed\n"));128AUTH_GSSAPI_DISPLAY_STATUS(("unsealing sequence number",129gssstat, minor_stat));130return FALSE;131} else if (out_buf.length != sizeof(uint32_t)) {132PRINTF(("gssapi_unseal_seq: unseal gave %d bytes\n",133(int) out_buf.length));134gss_release_buffer(&minor_stat, &out_buf);135return FALSE;136}137138nl_seq_num = *((uint32_t *) out_buf.value);139*seq_num = (uint32_t) ntohl(nl_seq_num);140gss_release_buffer(&minor_stat, &out_buf);141142return TRUE;143}144145void auth_gssapi_display_status(146char *msg,147OM_uint32 major,148OM_uint32 minor)149{150auth_gssapi_display_status_1(msg, major, GSS_C_GSS_CODE, 0);151auth_gssapi_display_status_1(msg, minor, GSS_C_MECH_CODE, 0);152}153154static void auth_gssapi_display_status_1(155char *m,156OM_uint32 code,157int type,158int rec)159{160OM_uint32 gssstat, minor_stat;161gss_buffer_desc msg;162OM_uint32 msg_ctx;163164msg_ctx = 0;165while (1) {166gssstat = gss_display_status(&minor_stat, code,167type, GSS_C_NULL_OID,168&msg_ctx, &msg);169if (gssstat != GSS_S_COMPLETE) {170if (!rec) {171auth_gssapi_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);172auth_gssapi_display_status_1(m, minor_stat,173GSS_C_MECH_CODE, 1);174} else {175fputs ("GSS-API authentication error ", stderr);176fwrite (msg.value, msg.length, 1, stderr);177fputs (": recursive failure!\n", stderr);178}179return;180}181182fprintf (stderr, "GSS-API authentication error %s: ", m);183fwrite (msg.value, msg.length, 1, stderr);184putc ('\n', stderr);185if (misc_debug_gssapi)186gssrpcint_printf("GSS-API authentication error %s: %*s\n",187m, (int)msg.length, (char *) msg.value);188(void) gss_release_buffer(&minor_stat, &msg);189190if (!msg_ctx)191break;192}193}194195bool_t auth_gssapi_wrap_data(196OM_uint32 *major,197OM_uint32 *minor,198gss_ctx_id_t context,199uint32_t seq_num,200XDR *out_xdrs,201xdrproc_t xdr_func,202caddr_t xdr_ptr)203{204gss_buffer_desc in_buf, out_buf;205XDR temp_xdrs;206int conf_state;207unsigned int length;208char *cp;209210PRINTF(("gssapi_wrap_data: starting\n"));211212*major = GSS_S_COMPLETE;213*minor = 0; /* assumption */214215xdralloc_create(&temp_xdrs, XDR_ENCODE);216217/* serialize the sequence number into local memory */218PRINTF(("gssapi_wrap_data: encoding seq_num %d\n", seq_num));219if (! xdr_u_int32(&temp_xdrs, &seq_num)) {220PRINTF(("gssapi_wrap_data: serializing seq_num failed\n"));221XDR_DESTROY(&temp_xdrs);222return FALSE;223}224225/* serialize the arguments into local memory */226if (!(*xdr_func)(&temp_xdrs, xdr_ptr)) {227PRINTF(("gssapi_wrap_data: serializing arguments failed\n"));228XDR_DESTROY(&temp_xdrs);229return FALSE;230}231232in_buf.length = xdr_getpos(&temp_xdrs);233in_buf.value = xdralloc_getdata(&temp_xdrs);234235*major = gss_seal(minor, context, 1,236GSS_C_QOP_DEFAULT, &in_buf, &conf_state,237&out_buf);238if (*major != GSS_S_COMPLETE) {239XDR_DESTROY(&temp_xdrs);240return FALSE;241}242243PRINTF(("gssapi_wrap_data: %d bytes data, %d bytes sealed\n",244(int) in_buf.length, (int) out_buf.length));245246/* write the token */247length = out_buf.length;248cp = out_buf.value;249if (! xdr_bytes(out_xdrs, &cp, &length, out_buf.length)) {250PRINTF(("gssapi_wrap_data: serializing encrypted data failed\n"));251XDR_DESTROY(&temp_xdrs);252return FALSE;253}254out_buf.value = cp;255256*major = gss_release_buffer(minor, &out_buf);257258PRINTF(("gssapi_wrap_data: succeeding\n\n"));259XDR_DESTROY(&temp_xdrs);260return TRUE;261}262263bool_t auth_gssapi_unwrap_data(264OM_uint32 *major,265OM_uint32 *minor,266gss_ctx_id_t context,267uint32_t seq_num,268XDR *in_xdrs,269xdrproc_t xdr_func,270caddr_t xdr_ptr)271{272gss_buffer_desc in_buf, out_buf;273XDR temp_xdrs;274uint32_t verf_seq_num;275int conf, qop;276unsigned int length;277char *cp;278279PRINTF(("gssapi_unwrap_data: starting\n"));280281*major = GSS_S_COMPLETE;282*minor = 0; /* assumption */283284in_buf.value = NULL;285out_buf.value = NULL;286cp = in_buf.value;287if (! xdr_bytes(in_xdrs, &cp, &length, (unsigned int) -1)) {288PRINTF(("gssapi_unwrap_data: deserializing encrypted data failed\n"));289temp_xdrs.x_op = XDR_FREE;290(void)xdr_bytes(&temp_xdrs, &cp, &length, (unsigned int) -1);291in_buf.value = NULL;292return FALSE;293}294in_buf.value = cp;295in_buf.length = length;296297*major = gss_unseal(minor, context, &in_buf, &out_buf, &conf,298&qop);299free(in_buf.value);300if (*major != GSS_S_COMPLETE)301return FALSE;302303PRINTF(("gssapi_unwrap_data: %llu bytes data, %llu bytes sealed\n",304(unsigned long long)out_buf.length,305(unsigned long long)in_buf.length));306307xdrmem_create(&temp_xdrs, out_buf.value, out_buf.length, XDR_DECODE);308309/* deserialize the sequence number */310if (! xdr_u_int32(&temp_xdrs, &verf_seq_num)) {311PRINTF(("gssapi_unwrap_data: deserializing verf_seq_num failed\n"));312gss_release_buffer(minor, &out_buf);313XDR_DESTROY(&temp_xdrs);314return FALSE;315}316if (verf_seq_num != seq_num) {317PRINTF(("gssapi_unwrap_data: seq %d specified, read %d\n",318seq_num, verf_seq_num));319gss_release_buffer(minor, &out_buf);320XDR_DESTROY(&temp_xdrs);321return FALSE;322}323PRINTF(("gssapi_unwrap_data: unwrap seq_num %d okay\n", verf_seq_num));324325/* deserialize the arguments into xdr_ptr */326if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) {327PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n"));328gss_release_buffer(minor, &out_buf);329XDR_DESTROY(&temp_xdrs);330return FALSE;331}332333PRINTF(("gssapi_unwrap_data: succeeding\n\n"));334335gss_release_buffer(minor, &out_buf);336XDR_DESTROY(&temp_xdrs);337return TRUE;338}339340341