xref: /freebsd/crypto/krb5/src/lib/rpc/auth_gssapi_misc.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /*
2*7f2fe78bSCy Schubert  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
3*7f2fe78bSCy Schubert  *
4*7f2fe78bSCy Schubert  */
5*7f2fe78bSCy Schubert 
6*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
7*7f2fe78bSCy Schubert #include <stdio.h>
8*7f2fe78bSCy Schubert 
9*7f2fe78bSCy Schubert #include <gssapi/gssapi.h>
10*7f2fe78bSCy Schubert #include <gssrpc/auth_gssapi.h>
11*7f2fe78bSCy Schubert 
12*7f2fe78bSCy Schubert #include "gssrpcint.h"
13*7f2fe78bSCy Schubert 
14*7f2fe78bSCy Schubert #ifdef __CODECENTER__
15*7f2fe78bSCy Schubert #define DEBUG_GSSAPI 1
16*7f2fe78bSCy Schubert #endif
17*7f2fe78bSCy Schubert 
18*7f2fe78bSCy Schubert #ifdef DEBUG_GSSAPI
19*7f2fe78bSCy Schubert int misc_debug_gssapi = DEBUG_GSSAPI;
20*7f2fe78bSCy Schubert extern void gssrpcint_printf(const char *, ...);
21*7f2fe78bSCy Schubert #define L_PRINTF(l,args) if (misc_debug_gssapi >= l) gssrpcint_printf args
22*7f2fe78bSCy Schubert #define PRINTF(args) L_PRINTF(99, args)
23*7f2fe78bSCy Schubert #define AUTH_GSSAPI_DISPLAY_STATUS(args) \
24*7f2fe78bSCy Schubert 	if (misc_debug_gssapi) auth_gssapi_display_status args
25*7f2fe78bSCy Schubert #else
26*7f2fe78bSCy Schubert #define PRINTF(args)
27*7f2fe78bSCy Schubert #define L_PRINTF(l, args)
28*7f2fe78bSCy Schubert #define AUTH_GSSAPI_DISPLAY_STATUS(args)
29*7f2fe78bSCy Schubert #endif
30*7f2fe78bSCy Schubert 
31*7f2fe78bSCy Schubert static void auth_gssapi_display_status_1
32*7f2fe78bSCy Schubert 	(char *, OM_uint32, int, int);
33*7f2fe78bSCy Schubert 
xdr_gss_buf(XDR * xdrs,gss_buffer_t buf)34*7f2fe78bSCy Schubert bool_t xdr_gss_buf(
35*7f2fe78bSCy Schubert      XDR *xdrs,
36*7f2fe78bSCy Schubert      gss_buffer_t buf)
37*7f2fe78bSCy Schubert {
38*7f2fe78bSCy Schubert      /*
39*7f2fe78bSCy Schubert       * On decode, xdr_bytes will only allocate buf->value if the
40*7f2fe78bSCy Schubert       * length read in is < maxsize (last arg).  This is dumb, because
41*7f2fe78bSCy Schubert       * the whole point of allocating memory is so that I don't *have*
42*7f2fe78bSCy Schubert       * to know the maximum length.  -1 effectively disables this
43*7f2fe78bSCy Schubert       * braindamage.
44*7f2fe78bSCy Schubert       */
45*7f2fe78bSCy Schubert      bool_t result;
46*7f2fe78bSCy Schubert      /* Fix type mismatches between APIs.  */
47*7f2fe78bSCy Schubert      unsigned int length = buf->length;
48*7f2fe78bSCy Schubert      char *cp = buf->value;
49*7f2fe78bSCy Schubert      result = xdr_bytes(xdrs, &cp, &length,
50*7f2fe78bSCy Schubert 			(xdrs->x_op == XDR_DECODE && buf->value == NULL)
51*7f2fe78bSCy Schubert 			? (unsigned int) -1 : (unsigned int) buf->length);
52*7f2fe78bSCy Schubert      buf->value = cp;
53*7f2fe78bSCy Schubert      buf->length = length;
54*7f2fe78bSCy Schubert      return result;
55*7f2fe78bSCy Schubert }
56*7f2fe78bSCy Schubert 
xdr_authgssapi_creds(XDR * xdrs,auth_gssapi_creds * creds)57*7f2fe78bSCy Schubert bool_t xdr_authgssapi_creds(
58*7f2fe78bSCy Schubert      XDR *xdrs,
59*7f2fe78bSCy Schubert      auth_gssapi_creds *creds)
60*7f2fe78bSCy Schubert {
61*7f2fe78bSCy Schubert      if (! xdr_u_int32(xdrs, &creds->version) ||
62*7f2fe78bSCy Schubert 	 ! xdr_bool(xdrs, &creds->auth_msg) ||
63*7f2fe78bSCy Schubert 	 ! xdr_gss_buf(xdrs, &creds->client_handle))
64*7f2fe78bSCy Schubert        return FALSE;
65*7f2fe78bSCy Schubert      return TRUE;
66*7f2fe78bSCy Schubert }
67*7f2fe78bSCy Schubert 
xdr_authgssapi_init_arg(XDR * xdrs,auth_gssapi_init_arg * init_arg)68*7f2fe78bSCy Schubert bool_t xdr_authgssapi_init_arg(
69*7f2fe78bSCy Schubert      XDR *xdrs,
70*7f2fe78bSCy Schubert      auth_gssapi_init_arg *init_arg)
71*7f2fe78bSCy Schubert {
72*7f2fe78bSCy Schubert      if (! xdr_u_int32(xdrs, &init_arg->version) ||
73*7f2fe78bSCy Schubert 	 ! xdr_gss_buf(xdrs, &init_arg->token))
74*7f2fe78bSCy Schubert 	  return FALSE;
75*7f2fe78bSCy Schubert      return TRUE;
76*7f2fe78bSCy Schubert }
77*7f2fe78bSCy Schubert 
xdr_authgssapi_init_res(XDR * xdrs,auth_gssapi_init_res * init_res)78*7f2fe78bSCy Schubert bool_t xdr_authgssapi_init_res(
79*7f2fe78bSCy Schubert      XDR *xdrs,
80*7f2fe78bSCy Schubert      auth_gssapi_init_res *init_res)
81*7f2fe78bSCy Schubert {
82*7f2fe78bSCy Schubert      if (! xdr_u_int32(xdrs, &init_res->version) ||
83*7f2fe78bSCy Schubert 	 ! xdr_gss_buf(xdrs, &init_res->client_handle) ||
84*7f2fe78bSCy Schubert 	 ! xdr_u_int32(xdrs, &init_res->gss_major) ||
85*7f2fe78bSCy Schubert 	 ! xdr_u_int32(xdrs, &init_res->gss_minor) ||
86*7f2fe78bSCy Schubert 	 ! xdr_gss_buf(xdrs, &init_res->token) ||
87*7f2fe78bSCy Schubert 	 ! xdr_gss_buf(xdrs, &init_res->signed_isn))
88*7f2fe78bSCy Schubert 	  return FALSE;
89*7f2fe78bSCy Schubert      return TRUE;
90*7f2fe78bSCy Schubert }
91*7f2fe78bSCy Schubert 
auth_gssapi_seal_seq(gss_ctx_id_t context,uint32_t seq_num,gss_buffer_t out_buf)92*7f2fe78bSCy Schubert bool_t auth_gssapi_seal_seq(
93*7f2fe78bSCy Schubert      gss_ctx_id_t context,
94*7f2fe78bSCy Schubert      uint32_t seq_num,
95*7f2fe78bSCy Schubert      gss_buffer_t out_buf)
96*7f2fe78bSCy Schubert {
97*7f2fe78bSCy Schubert      gss_buffer_desc in_buf;
98*7f2fe78bSCy Schubert      OM_uint32 gssstat, minor_stat;
99*7f2fe78bSCy Schubert      uint32_t nl_seq_num;
100*7f2fe78bSCy Schubert 
101*7f2fe78bSCy Schubert      nl_seq_num = htonl(seq_num);
102*7f2fe78bSCy Schubert 
103*7f2fe78bSCy Schubert      in_buf.length = sizeof(uint32_t);
104*7f2fe78bSCy Schubert      in_buf.value = (char *) &nl_seq_num;
105*7f2fe78bSCy Schubert      gssstat = gss_seal(&minor_stat, context, 0, GSS_C_QOP_DEFAULT,
106*7f2fe78bSCy Schubert 			&in_buf, NULL, out_buf);
107*7f2fe78bSCy Schubert      if (gssstat != GSS_S_COMPLETE) {
108*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_seal_seq: failed\n"));
109*7f2fe78bSCy Schubert 	  AUTH_GSSAPI_DISPLAY_STATUS(("sealing sequence number",
110*7f2fe78bSCy Schubert 				      gssstat, minor_stat));
111*7f2fe78bSCy Schubert 	  return FALSE;
112*7f2fe78bSCy Schubert      }
113*7f2fe78bSCy Schubert      return TRUE;
114*7f2fe78bSCy Schubert }
115*7f2fe78bSCy Schubert 
auth_gssapi_unseal_seq(gss_ctx_id_t context,gss_buffer_t in_buf,uint32_t * seq_num)116*7f2fe78bSCy Schubert bool_t auth_gssapi_unseal_seq(
117*7f2fe78bSCy Schubert      gss_ctx_id_t context,
118*7f2fe78bSCy Schubert      gss_buffer_t in_buf,
119*7f2fe78bSCy Schubert      uint32_t *seq_num)
120*7f2fe78bSCy Schubert {
121*7f2fe78bSCy Schubert      gss_buffer_desc out_buf;
122*7f2fe78bSCy Schubert      OM_uint32 gssstat, minor_stat;
123*7f2fe78bSCy Schubert      uint32_t nl_seq_num;
124*7f2fe78bSCy Schubert 
125*7f2fe78bSCy Schubert      gssstat = gss_unseal(&minor_stat, context, in_buf, &out_buf,
126*7f2fe78bSCy Schubert 			  NULL, NULL);
127*7f2fe78bSCy Schubert      if (gssstat != GSS_S_COMPLETE) {
128*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_unseal_seq: failed\n"));
129*7f2fe78bSCy Schubert 	  AUTH_GSSAPI_DISPLAY_STATUS(("unsealing sequence number",
130*7f2fe78bSCy Schubert 				      gssstat, minor_stat));
131*7f2fe78bSCy Schubert 	  return FALSE;
132*7f2fe78bSCy Schubert      } else if (out_buf.length != sizeof(uint32_t)) {
133*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_unseal_seq: unseal gave %d bytes\n",
134*7f2fe78bSCy Schubert 		  (int) out_buf.length));
135*7f2fe78bSCy Schubert 	  gss_release_buffer(&minor_stat, &out_buf);
136*7f2fe78bSCy Schubert 	  return FALSE;
137*7f2fe78bSCy Schubert      }
138*7f2fe78bSCy Schubert 
139*7f2fe78bSCy Schubert      nl_seq_num = *((uint32_t *) out_buf.value);
140*7f2fe78bSCy Schubert      *seq_num = (uint32_t) ntohl(nl_seq_num);
141*7f2fe78bSCy Schubert      gss_release_buffer(&minor_stat, &out_buf);
142*7f2fe78bSCy Schubert 
143*7f2fe78bSCy Schubert      return TRUE;
144*7f2fe78bSCy Schubert }
145*7f2fe78bSCy Schubert 
auth_gssapi_display_status(char * msg,OM_uint32 major,OM_uint32 minor)146*7f2fe78bSCy Schubert void auth_gssapi_display_status(
147*7f2fe78bSCy Schubert      char *msg,
148*7f2fe78bSCy Schubert      OM_uint32 major,
149*7f2fe78bSCy Schubert      OM_uint32 minor)
150*7f2fe78bSCy Schubert {
151*7f2fe78bSCy Schubert      auth_gssapi_display_status_1(msg, major, GSS_C_GSS_CODE, 0);
152*7f2fe78bSCy Schubert      auth_gssapi_display_status_1(msg, minor, GSS_C_MECH_CODE, 0);
153*7f2fe78bSCy Schubert }
154*7f2fe78bSCy Schubert 
auth_gssapi_display_status_1(char * m,OM_uint32 code,int type,int rec)155*7f2fe78bSCy Schubert static void auth_gssapi_display_status_1(
156*7f2fe78bSCy Schubert      char *m,
157*7f2fe78bSCy Schubert      OM_uint32 code,
158*7f2fe78bSCy Schubert      int type,
159*7f2fe78bSCy Schubert      int rec)
160*7f2fe78bSCy Schubert {
161*7f2fe78bSCy Schubert      OM_uint32 gssstat, minor_stat;
162*7f2fe78bSCy Schubert      gss_buffer_desc msg;
163*7f2fe78bSCy Schubert      OM_uint32 msg_ctx;
164*7f2fe78bSCy Schubert 
165*7f2fe78bSCy Schubert      msg_ctx = 0;
166*7f2fe78bSCy Schubert      while (1) {
167*7f2fe78bSCy Schubert 	  gssstat = gss_display_status(&minor_stat, code,
168*7f2fe78bSCy Schubert 				       type, GSS_C_NULL_OID,
169*7f2fe78bSCy Schubert 				       &msg_ctx, &msg);
170*7f2fe78bSCy Schubert 	  if (gssstat != GSS_S_COMPLETE) {
171*7f2fe78bSCy Schubert  	       if (!rec) {
172*7f2fe78bSCy Schubert 		    auth_gssapi_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);
173*7f2fe78bSCy Schubert 		    auth_gssapi_display_status_1(m, minor_stat,
174*7f2fe78bSCy Schubert 						 GSS_C_MECH_CODE, 1);
175*7f2fe78bSCy Schubert 	       } else {
176*7f2fe78bSCy Schubert 		   fputs ("GSS-API authentication error ", stderr);
177*7f2fe78bSCy Schubert 		   fwrite (msg.value, msg.length, 1, stderr);
178*7f2fe78bSCy Schubert 		   fputs (": recursive failure!\n", stderr);
179*7f2fe78bSCy Schubert 	       }
180*7f2fe78bSCy Schubert 	       return;
181*7f2fe78bSCy Schubert 	  }
182*7f2fe78bSCy Schubert 
183*7f2fe78bSCy Schubert 	  fprintf (stderr, "GSS-API authentication error %s: ", m);
184*7f2fe78bSCy Schubert 	  fwrite (msg.value, msg.length, 1, stderr);
185*7f2fe78bSCy Schubert 	  putc ('\n', stderr);
186*7f2fe78bSCy Schubert 	  if (misc_debug_gssapi)
187*7f2fe78bSCy Schubert 	      gssrpcint_printf("GSS-API authentication error %s: %*s\n",
188*7f2fe78bSCy Schubert 			       m, (int)msg.length, (char *) msg.value);
189*7f2fe78bSCy Schubert 	  (void) gss_release_buffer(&minor_stat, &msg);
190*7f2fe78bSCy Schubert 
191*7f2fe78bSCy Schubert 	  if (!msg_ctx)
192*7f2fe78bSCy Schubert 	       break;
193*7f2fe78bSCy Schubert      }
194*7f2fe78bSCy Schubert }
195*7f2fe78bSCy Schubert 
auth_gssapi_wrap_data(OM_uint32 * major,OM_uint32 * minor,gss_ctx_id_t context,uint32_t seq_num,XDR * out_xdrs,bool_t (* xdr_func)(),caddr_t xdr_ptr)196*7f2fe78bSCy Schubert bool_t auth_gssapi_wrap_data(
197*7f2fe78bSCy Schubert      OM_uint32 *major,
198*7f2fe78bSCy Schubert      OM_uint32 *minor,
199*7f2fe78bSCy Schubert      gss_ctx_id_t context,
200*7f2fe78bSCy Schubert      uint32_t seq_num,
201*7f2fe78bSCy Schubert      XDR *out_xdrs,
202*7f2fe78bSCy Schubert      bool_t (*xdr_func)(),
203*7f2fe78bSCy Schubert      caddr_t xdr_ptr)
204*7f2fe78bSCy Schubert {
205*7f2fe78bSCy Schubert      gss_buffer_desc in_buf, out_buf;
206*7f2fe78bSCy Schubert      XDR temp_xdrs;
207*7f2fe78bSCy Schubert      int conf_state;
208*7f2fe78bSCy Schubert      unsigned int length;
209*7f2fe78bSCy Schubert      char *cp;
210*7f2fe78bSCy Schubert 
211*7f2fe78bSCy Schubert      PRINTF(("gssapi_wrap_data: starting\n"));
212*7f2fe78bSCy Schubert 
213*7f2fe78bSCy Schubert      *major = GSS_S_COMPLETE;
214*7f2fe78bSCy Schubert      *minor = 0; /* assumption */
215*7f2fe78bSCy Schubert 
216*7f2fe78bSCy Schubert      xdralloc_create(&temp_xdrs, XDR_ENCODE);
217*7f2fe78bSCy Schubert 
218*7f2fe78bSCy Schubert      /* serialize the sequence number into local memory */
219*7f2fe78bSCy Schubert      PRINTF(("gssapi_wrap_data: encoding seq_num %d\n", seq_num));
220*7f2fe78bSCy Schubert      if (! xdr_u_int32(&temp_xdrs, &seq_num)) {
221*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_wrap_data: serializing seq_num failed\n"));
222*7f2fe78bSCy Schubert 	  XDR_DESTROY(&temp_xdrs);
223*7f2fe78bSCy Schubert 	  return FALSE;
224*7f2fe78bSCy Schubert      }
225*7f2fe78bSCy Schubert 
226*7f2fe78bSCy Schubert      /* serialize the arguments into local memory */
227*7f2fe78bSCy Schubert      if (!(*xdr_func)(&temp_xdrs, xdr_ptr)) {
228*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_wrap_data: serializing arguments failed\n"));
229*7f2fe78bSCy Schubert 	  XDR_DESTROY(&temp_xdrs);
230*7f2fe78bSCy Schubert 	  return FALSE;
231*7f2fe78bSCy Schubert      }
232*7f2fe78bSCy Schubert 
233*7f2fe78bSCy Schubert      in_buf.length = xdr_getpos(&temp_xdrs);
234*7f2fe78bSCy Schubert      in_buf.value = xdralloc_getdata(&temp_xdrs);
235*7f2fe78bSCy Schubert 
236*7f2fe78bSCy Schubert      *major = gss_seal(minor, context, 1,
237*7f2fe78bSCy Schubert 		       GSS_C_QOP_DEFAULT, &in_buf, &conf_state,
238*7f2fe78bSCy Schubert 		       &out_buf);
239*7f2fe78bSCy Schubert      if (*major != GSS_S_COMPLETE) {
240*7f2fe78bSCy Schubert 	  XDR_DESTROY(&temp_xdrs);
241*7f2fe78bSCy Schubert 	  return FALSE;
242*7f2fe78bSCy Schubert      }
243*7f2fe78bSCy Schubert 
244*7f2fe78bSCy Schubert      PRINTF(("gssapi_wrap_data: %d bytes data, %d bytes sealed\n",
245*7f2fe78bSCy Schubert 	     (int) in_buf.length, (int) out_buf.length));
246*7f2fe78bSCy Schubert 
247*7f2fe78bSCy Schubert      /* write the token */
248*7f2fe78bSCy Schubert      length = out_buf.length;
249*7f2fe78bSCy Schubert      cp = out_buf.value;
250*7f2fe78bSCy Schubert      if (! xdr_bytes(out_xdrs, &cp, &length, out_buf.length)) {
251*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_wrap_data: serializing encrypted data failed\n"));
252*7f2fe78bSCy Schubert 	  XDR_DESTROY(&temp_xdrs);
253*7f2fe78bSCy Schubert 	  return FALSE;
254*7f2fe78bSCy Schubert      }
255*7f2fe78bSCy Schubert      out_buf.value = cp;
256*7f2fe78bSCy Schubert 
257*7f2fe78bSCy Schubert      *major = gss_release_buffer(minor, &out_buf);
258*7f2fe78bSCy Schubert 
259*7f2fe78bSCy Schubert      PRINTF(("gssapi_wrap_data: succeeding\n\n"));
260*7f2fe78bSCy Schubert      XDR_DESTROY(&temp_xdrs);
261*7f2fe78bSCy Schubert      return TRUE;
262*7f2fe78bSCy Schubert }
263*7f2fe78bSCy Schubert 
auth_gssapi_unwrap_data(OM_uint32 * major,OM_uint32 * minor,gss_ctx_id_t context,uint32_t seq_num,XDR * in_xdrs,bool_t (* xdr_func)(),caddr_t xdr_ptr)264*7f2fe78bSCy Schubert bool_t auth_gssapi_unwrap_data(
265*7f2fe78bSCy Schubert      OM_uint32 *major,
266*7f2fe78bSCy Schubert      OM_uint32 *minor,
267*7f2fe78bSCy Schubert      gss_ctx_id_t context,
268*7f2fe78bSCy Schubert      uint32_t seq_num,
269*7f2fe78bSCy Schubert      XDR *in_xdrs,
270*7f2fe78bSCy Schubert      bool_t (*xdr_func)(),
271*7f2fe78bSCy Schubert      caddr_t xdr_ptr)
272*7f2fe78bSCy Schubert {
273*7f2fe78bSCy Schubert      gss_buffer_desc in_buf, out_buf;
274*7f2fe78bSCy Schubert      XDR temp_xdrs;
275*7f2fe78bSCy Schubert      uint32_t verf_seq_num;
276*7f2fe78bSCy Schubert      int conf, qop;
277*7f2fe78bSCy Schubert      unsigned int length;
278*7f2fe78bSCy Schubert      char *cp;
279*7f2fe78bSCy Schubert 
280*7f2fe78bSCy Schubert      PRINTF(("gssapi_unwrap_data: starting\n"));
281*7f2fe78bSCy Schubert 
282*7f2fe78bSCy Schubert      *major = GSS_S_COMPLETE;
283*7f2fe78bSCy Schubert      *minor = 0; /* assumption */
284*7f2fe78bSCy Schubert 
285*7f2fe78bSCy Schubert      in_buf.value = NULL;
286*7f2fe78bSCy Schubert      out_buf.value = NULL;
287*7f2fe78bSCy Schubert      cp = in_buf.value;
288*7f2fe78bSCy Schubert      if (! xdr_bytes(in_xdrs, &cp, &length, (unsigned int) -1)) {
289*7f2fe78bSCy Schubert 	 PRINTF(("gssapi_unwrap_data: deserializing encrypted data failed\n"));
290*7f2fe78bSCy Schubert 	 temp_xdrs.x_op = XDR_FREE;
291*7f2fe78bSCy Schubert 	 (void)xdr_bytes(&temp_xdrs, &cp, &length, (unsigned int) -1);
292*7f2fe78bSCy Schubert 	 in_buf.value = NULL;
293*7f2fe78bSCy Schubert 	 return FALSE;
294*7f2fe78bSCy Schubert      }
295*7f2fe78bSCy Schubert      in_buf.value = cp;
296*7f2fe78bSCy Schubert      in_buf.length = length;
297*7f2fe78bSCy Schubert 
298*7f2fe78bSCy Schubert      *major = gss_unseal(minor, context, &in_buf, &out_buf, &conf,
299*7f2fe78bSCy Schubert 			 &qop);
300*7f2fe78bSCy Schubert      free(in_buf.value);
301*7f2fe78bSCy Schubert      if (*major != GSS_S_COMPLETE)
302*7f2fe78bSCy Schubert 	  return FALSE;
303*7f2fe78bSCy Schubert 
304*7f2fe78bSCy Schubert      PRINTF(("gssapi_unwrap_data: %llu bytes data, %llu bytes sealed\n",
305*7f2fe78bSCy Schubert 	     (unsigned long long)out_buf.length,
306*7f2fe78bSCy Schubert 	     (unsigned long long)in_buf.length));
307*7f2fe78bSCy Schubert 
308*7f2fe78bSCy Schubert      xdrmem_create(&temp_xdrs, out_buf.value, out_buf.length, XDR_DECODE);
309*7f2fe78bSCy Schubert 
310*7f2fe78bSCy Schubert      /* deserialize the sequence number */
311*7f2fe78bSCy Schubert      if (! xdr_u_int32(&temp_xdrs, &verf_seq_num)) {
312*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_unwrap_data: deserializing verf_seq_num failed\n"));
313*7f2fe78bSCy Schubert 	  gss_release_buffer(minor, &out_buf);
314*7f2fe78bSCy Schubert 	  XDR_DESTROY(&temp_xdrs);
315*7f2fe78bSCy Schubert 	  return FALSE;
316*7f2fe78bSCy Schubert      }
317*7f2fe78bSCy Schubert      if (verf_seq_num != seq_num) {
318*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_unwrap_data: seq %d specified, read %d\n",
319*7f2fe78bSCy Schubert 		  seq_num, verf_seq_num));
320*7f2fe78bSCy Schubert 	  gss_release_buffer(minor, &out_buf);
321*7f2fe78bSCy Schubert 	  XDR_DESTROY(&temp_xdrs);
322*7f2fe78bSCy Schubert 	  return FALSE;
323*7f2fe78bSCy Schubert      }
324*7f2fe78bSCy Schubert      PRINTF(("gssapi_unwrap_data: unwrap seq_num %d okay\n", verf_seq_num));
325*7f2fe78bSCy Schubert 
326*7f2fe78bSCy Schubert      /* deserialize the arguments into xdr_ptr */
327*7f2fe78bSCy Schubert      if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) {
328*7f2fe78bSCy Schubert 	  PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n"));
329*7f2fe78bSCy Schubert 	  gss_release_buffer(minor, &out_buf);
330*7f2fe78bSCy Schubert 	  XDR_DESTROY(&temp_xdrs);
331*7f2fe78bSCy Schubert 	  return FALSE;
332*7f2fe78bSCy Schubert      }
333*7f2fe78bSCy Schubert 
334*7f2fe78bSCy Schubert      PRINTF(("gssapi_unwrap_data: succeeding\n\n"));
335*7f2fe78bSCy Schubert 
336*7f2fe78bSCy Schubert      gss_release_buffer(minor, &out_buf);
337*7f2fe78bSCy Schubert      XDR_DESTROY(&temp_xdrs);
338*7f2fe78bSCy Schubert      return TRUE;
339*7f2fe78bSCy Schubert }
340