Home | History | Annotate | Download | only in snoop
      1    0  stevel /*
      2    0  stevel  * CDDL HEADER START
      3    0  stevel  *
      4    0  stevel  * The contents of this file are subject to the terms of the
      5    0  stevel  * Common Development and Distribution License, Version 1.0 only
      6    0  stevel  * (the "License").  You may not use this file except in compliance
      7    0  stevel  * with the License.
      8    0  stevel  *
      9    0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10    0  stevel  * or http://www.opensolaris.org/os/licensing.
     11    0  stevel  * See the License for the specific language governing permissions
     12    0  stevel  * and limitations under the License.
     13    0  stevel  *
     14    0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     15    0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16    0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     17    0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     18    0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     19    0  stevel  *
     20    0  stevel  * CDDL HEADER END
     21    0  stevel  */
     22    0  stevel /*
     23  410  kcpoon  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     24  410  kcpoon  * Use is subject to license terms.
     25    0  stevel  */
     26    0  stevel 
     27    0  stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28    0  stevel 
     29    0  stevel #include <sys/types.h>
     30    0  stevel #include <sys/errno.h>
     31    0  stevel #include <sys/tiuser.h>
     32    0  stevel #include <setjmp.h>
     33    0  stevel 
     34    0  stevel #include <rpc/types.h>
     35    0  stevel #include <rpc/xdr.h>
     36    0  stevel #include <rpc/auth.h>
     37    0  stevel #include <rpc/clnt.h>
     38    0  stevel #include <rpc/rpc_msg.h>
     39    0  stevel #include <rpc/rpcsec_gss.h>
     40    0  stevel #include <string.h>
     41    0  stevel #include "snoop.h"
     42    0  stevel 
     43    0  stevel extern jmp_buf xdr_err;
     44    0  stevel 
     45    0  stevel struct cache_struct *find_xid();
     46    0  stevel char *nameof_prog(int prog);
     47  410  kcpoon static void print_rpc_gss_init_arg(int, struct cache_struct *);
     48  410  kcpoon static void print_rpc_gss_init_res(int);
     49    0  stevel 
     50    0  stevel char *
     51    0  stevel rpcsec_gss_proc_to_string(unsigned int proc)
     52    0  stevel {
     53    0  stevel 	switch (proc) {
     54    0  stevel 	case RPCSEC_GSS_DATA:	return "RPCSEC_GSS_DATA"; break;
     55    0  stevel 	case RPCSEC_GSS_INIT:	return "RPCSEC_GSS_INIT"; break;
     56    0  stevel 	case RPCSEC_GSS_CONTINUE_INIT:
     57    0  stevel 				return ("RPCSEC_GSS_CONTINUE_INIT");
     58    0  stevel 	case RPCSEC_GSS_DESTROY:
     59    0  stevel 				return ("RPCSEC_GSS_DESTROY");
     60    0  stevel 	default:		return ("unknown");
     61    0  stevel 
     62    0  stevel 	}
     63    0  stevel }
     64    0  stevel 
     65    0  stevel 
     66    0  stevel char *
     67    0  stevel rpcsec_gss_service_to_string(rpc_gss_service_t service)
     68    0  stevel {
     69    0  stevel 	switch (service) {
     70    0  stevel 	case rpc_gss_svc_none:	return "none"; break;
     71    0  stevel 	case rpc_gss_svc_integrity: return "integrity"; break;
     72    0  stevel 	case rpc_gss_svc_privacy: return "privacy"; break;
     73    0  stevel 	default:		return "unknown";	  break;
     74    0  stevel 
     75    0  stevel 	}
     76    0  stevel }
     77    0  stevel 
     78    0  stevel /*
     79    0  stevel  *  Print detailed RPCSEC_GSS cred data.
     80    0  stevel  */
     81    0  stevel void
     82    0  stevel print_rpcsec_gss_cred(int xid, int authlen)
     83    0  stevel {
     84    0  stevel 	unsigned int seq_num;
     85    0  stevel 	unsigned int handle_len;
     86    0  stevel 	unsigned int rpcsec_gss_ver;
     87    0  stevel 	rpc_gss_service_t rpcsec_gss_service;
     88    0  stevel 	unsigned int rpcsec_gss_proc;
     89    0  stevel 	char *handle, *line;
     90    0  stevel 	struct cache_struct *x;
     91    0  stevel 	int pos;
     92    0  stevel 
     93    0  stevel 	pos = getxdr_pos();
     94    0  stevel 	rpcsec_gss_ver = getxdr_u_long();
     95    0  stevel 
     96    0  stevel 	/* see if we know this version or not */
     97    0  stevel 
     98    0  stevel 	if (rpcsec_gss_ver != 1) {
     99    0  stevel 		(void) showxdr_hex(authlen, "[%s]");
    100    0  stevel 		return;
    101    0  stevel 	}
    102    0  stevel 
    103    0  stevel 	rpcsec_gss_proc   = getxdr_u_long();
    104    0  stevel 	seq_num    = getxdr_u_long();
    105    0  stevel 	rpcsec_gss_service    = getxdr_enum();
    106    0  stevel 
    107    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    108    0  stevel 		"   version = %u",  rpcsec_gss_ver);
    109    0  stevel 
    110    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    111    0  stevel 		"   gss control procedure = %u (%s)",
    112    0  stevel 		rpcsec_gss_proc,
    113    0  stevel 		rpcsec_gss_proc_to_string(rpcsec_gss_proc));
    114    0  stevel 
    115    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    116    0  stevel 		"   sequence num = %u", seq_num);
    117    0  stevel 
    118    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    119    0  stevel 	    "   service = %d (%s)", rpcsec_gss_service,
    120    0  stevel 	    rpcsec_gss_service_to_string(rpcsec_gss_service));
    121    0  stevel 	pos = getxdr_pos();
    122    0  stevel 	handle_len = getxdr_u_long();
    123    0  stevel 	handle = getxdr_hex(handle_len);
    124    0  stevel 	line = get_line(pos, getxdr_pos());
    125    0  stevel 	sprintf(line, "   handle: length = %d, data = [%s]",
    126    0  stevel 			handle_len, handle);
    127    0  stevel 	x = find_xid(xid);
    128    0  stevel 	if (x) {
    129    0  stevel 		x->xid_gss_proc    = rpcsec_gss_proc;
    130    0  stevel 		x->xid_gss_service = rpcsec_gss_service;
    131    0  stevel 	}
    132    0  stevel }
    133    0  stevel 
    134    0  stevel /*
    135    0  stevel  *  Based on different RPCSEC_GSS services supported, maybe a
    136    0  stevel  *  special handling is needed before printing the arguments.
    137    0  stevel  *
    138    0  stevel  *  For integrity service : print the sequence number.
    139    0  stevel  *  For privacy service : do not print the arguments.
    140    0  stevel  */
    141    0  stevel int
    142    0  stevel rpcsec_gss_pre_proto(int type, int flags, int xid,
    143    0  stevel 					int prog, int vers, int proc)
    144    0  stevel {
    145    0  stevel 	int seq;
    146    0  stevel 	struct cache_struct *x;
    147    0  stevel 
    148    0  stevel 	if (! (x = find_xid(xid)))
    149    0  stevel 		return (0);
    150    0  stevel 
    151    0  stevel 	switch (x->xid_gss_service) {
    152    0  stevel 	case rpc_gss_svc_default:
    153    0  stevel 	case rpc_gss_svc_none:
    154    0  stevel 		break; /* standard call args */
    155    0  stevel 	case rpc_gss_svc_integrity:
    156    0  stevel 		/* length of rpc_gss_data_t encoded in the databody_integ */
    157    0  stevel 		getxdr_u_long();
    158    0  stevel 		/* read the seq number */
    159    0  stevel 		seq = getxdr_u_long();
    160    0  stevel 		if (flags & F_ALLSUM) {
    161    0  stevel 			(void) sprintf(get_sum_line(), "%s %c seq_num = %u",
    162    0  stevel 				"RPC RPCSEC_GSS", type == CALL ? 'C' : 'R',
    163    0  stevel 				seq);
    164    0  stevel 		} else if (flags & F_DTAIL) {
    165    0  stevel 			sprintf(get_line(0, 0),
    166    0  stevel 				"RPCSEC_GSS data seq_num = %u", seq);
    167    0  stevel 			show_space();
    168    0  stevel 		}
    169    0  stevel 		/* call args follow */
    170    0  stevel 		break;
    171    0  stevel 	case rpc_gss_svc_privacy: {
    172    0  stevel 		char *progname = nameof_prog(prog);
    173    0  stevel 		char prognum[32];
    174    0  stevel 
    175    0  stevel 		if (*progname == '?') {
    176    0  stevel 			sprintf(prognum, "%d", prog);
    177    0  stevel 			progname = prognum;
    178    0  stevel 		}
    179    0  stevel 
    180    0  stevel 		if (flags & F_SUM || flags & F_ALLSUM) {
    181    0  stevel 		    (void) sprintf(get_sum_line(),
    182    0  stevel 			"%s %c %s ver(%d) proc(%d) (data encrypted) ",
    183    0  stevel 			"RPC RPCSEC_GSS", type == CALL ? 'C' : 'R',
    184    0  stevel 			progname, vers, proc);
    185    0  stevel 		} else if (flags & F_DTAIL) {
    186    0  stevel 		    unsigned int args_len;
    187    0  stevel 
    188    0  stevel 		    args_len = getxdr_u_long();
    189    0  stevel 		    sprintf(get_line(0, 0),
    190    0  stevel 			"RPCSEC_GSS %s ver(%d) proc(%d)",
    191    0  stevel 			progname, vers, proc);
    192    0  stevel 		    sprintf(get_line(0, 0),
    193    0  stevel 			"(%s args encrypted, len = %d bytes)",
    194    0  stevel 			type == CALL ? "CALL" : "REPLY", args_len);
    195    0  stevel 		    show_space();
    196    0  stevel 		}
    197    0  stevel 		}
    198    0  stevel 		return (1);
    199    0  stevel 
    200    0  stevel 	default:
    201    0  stevel 		break;
    202    0  stevel 	}
    203    0  stevel 	return (0);
    204    0  stevel }
    205    0  stevel 
    206    0  stevel /*
    207    0  stevel  *  Based on different RPCSEC_GSS services supported, maybe a
    208    0  stevel  *  special handling is needed after printing the arguments.
    209    0  stevel  *
    210    0  stevel  *  For integrity service : print the checksum.
    211    0  stevel  */
    212    0  stevel void
    213    0  stevel rpcsec_gss_post_proto(int flags, int xid)
    214    0  stevel {
    215    0  stevel 	char *line;
    216    0  stevel 
    217    0  stevel 	struct cache_struct *x;
    218    0  stevel 
    219    0  stevel 	if (! (x = find_xid(xid)))
    220    0  stevel 		return;
    221    0  stevel 
    222    0  stevel 	switch (x->xid_gss_service) {
    223    0  stevel 	case rpc_gss_svc_default:
    224    0  stevel 	case rpc_gss_svc_none:
    225    0  stevel 	case rpc_gss_svc_privacy:
    226    0  stevel 		/* nothing left */
    227    0  stevel 		break;
    228    0  stevel 	case rpc_gss_svc_integrity:
    229    0  stevel 		if (flags & F_ALLSUM) {
    230    0  stevel 			line = get_sum_line();
    231    0  stevel 			sprintf(line, "RPC RPCSEC_GSS C (checksum)");
    232    0  stevel 		} else if (flags & F_DTAIL) {
    233    0  stevel 			unsigned int checksum_len;
    234    0  stevel 			char *checksum;
    235    0  stevel 
    236    0  stevel 			show_header("RPC:  ", "RPCSEC_GSS", 0);
    237    0  stevel 			show_space();
    238    0  stevel 			checksum_len = getxdr_u_long();
    239    0  stevel 			checksum = getxdr_hex(checksum_len);
    240    0  stevel 			sprintf(get_line(0, 0),
    241    0  stevel 				"checksum: len = %d", checksum_len);
    242    0  stevel 			sprintf(get_line(0, 0), "[%s]", checksum);
    243    0  stevel 			show_trailer();
    244    0  stevel 		}
    245    0  stevel 		break;
    246    0  stevel 	default:
    247    0  stevel 		break;
    248    0  stevel 	}
    249    0  stevel }
    250    0  stevel 
    251    0  stevel /*
    252    0  stevel  *  Print RPCSEC_GSS control procedures protocol data,
    253    0  stevel  *  No-op for RPCSEC_GSS_DATA.
    254    0  stevel  */
    255    0  stevel int
    256    0  stevel rpcsec_gss_control_proc(int type, int flags, int xid)
    257    0  stevel {
    258    0  stevel 	int seq;
    259    0  stevel 
    260    0  stevel 	struct cache_struct *x;
    261    0  stevel 
    262    0  stevel 	if (! (x = find_xid(xid)))
    263    0  stevel 		return (0);
    264    0  stevel 
    265    0  stevel 	if (x->xid_gss_proc != RPCSEC_GSS_DATA) {
    266    0  stevel 		if (flags & F_SUM) {
    267    0  stevel 			if (type == CALL) {
    268    0  stevel 				(void) sprintf(get_sum_line(), "%s %c %u (%s)",
    269    0  stevel 				"RPC RPCSEC_GSS",
    270    0  stevel 				type == CALL ? 'C' : 'R',
    271    0  stevel 				x->xid_gss_proc,
    272    0  stevel 				rpcsec_gss_proc_to_string(x->xid_gss_proc));
    273    0  stevel 			}
    274    0  stevel 		} else if (flags & F_DTAIL) {
    275    0  stevel 			if (x->xid_gss_proc == RPCSEC_GSS_INIT ||
    276    0  stevel 			    x->xid_gss_proc == RPCSEC_GSS_CONTINUE_INIT) {
    277    0  stevel 				if (type == CALL) {
    278    0  stevel 					print_rpc_gss_init_arg(flags, x);
    279    0  stevel 				} else {
    280    0  stevel 					print_rpc_gss_init_res(flags);
    281    0  stevel 				}
    282    0  stevel 			}
    283    0  stevel 		}
    284    0  stevel 		return (1);
    285    0  stevel 	}
    286    0  stevel 
    287    0  stevel 	return (0);
    288    0  stevel }
    289    0  stevel 
    290    0  stevel /*
    291    0  stevel  *  Skip the header RPCSEC_GSS cred data and
    292    0  stevel  *  put service and control type in the xid cache.
    293    0  stevel  */
    294  410  kcpoon void
    295    0  stevel extract_rpcsec_gss_cred_info(int xid)
    296    0  stevel {
    297    0  stevel 	unsigned int seq_num;
    298    0  stevel 	unsigned int handle_len;
    299    0  stevel 	unsigned int flavor_len;
    300    0  stevel 	unsigned int rpcsec_gss_ver;
    301    0  stevel 	rpc_gss_service_t rpcsec_gss_service;
    302    0  stevel 	unsigned int rpcsec_gss_proc;
    303    0  stevel 	struct cache_struct *x;
    304    0  stevel 
    305    0  stevel 	flavor_len = getxdr_u_long();
    306    0  stevel 	rpcsec_gss_ver = getxdr_u_long();
    307    0  stevel 	/* see if we know this version or not */
    308    0  stevel 	if (rpcsec_gss_ver != 1) {
    309    0  stevel 		longjmp(xdr_err, 1);
    310    0  stevel 	}
    311    0  stevel 	rpcsec_gss_proc   = getxdr_u_long();
    312    0  stevel 	seq_num    = getxdr_u_long();
    313    0  stevel 	rpcsec_gss_service    = getxdr_enum();
    314    0  stevel 	/* skip the handle */
    315    0  stevel 	xdr_skip(RNDUP(getxdr_u_long()));
    316    0  stevel 
    317    0  stevel 	if (x = find_xid(xid)) {
    318    0  stevel 		x->xid_gss_service = rpcsec_gss_service;
    319    0  stevel 		x->xid_gss_proc = rpcsec_gss_proc;
    320    0  stevel 	}
    321    0  stevel 
    322    0  stevel }
    323    0  stevel 
    324    0  stevel /*
    325    0  stevel  *  Print the argument data for the RPCSEC_GSS_INIT control procedure.
    326    0  stevel  */
    327  410  kcpoon static void
    328  410  kcpoon print_rpc_gss_init_arg(int flags, struct cache_struct *x)
    329    0  stevel {
    330    0  stevel 
    331    0  stevel 	char *token, *line;
    332    0  stevel 	unsigned int token_len;
    333    0  stevel 	int pos;
    334    0  stevel 
    335    0  stevel 	/*
    336    0  stevel 	 *  see if we need to print out the rpc_gss_init_arg structure
    337    0  stevel 	 *  or not.
    338    0  stevel 	 */
    339    0  stevel 
    340    0  stevel 	if (x->xid_gss_proc != RPCSEC_GSS_INIT &&
    341    0  stevel 		x->xid_gss_proc != RPCSEC_GSS_CONTINUE_INIT) {
    342    0  stevel 		return;
    343    0  stevel 	}
    344    0  stevel 
    345    0  stevel 	/* print it */
    346    0  stevel 
    347    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    348    0  stevel 		"RPCSEC_GSS_INIT args:");
    349    0  stevel 
    350    0  stevel 	pos = getxdr_pos();
    351    0  stevel 	token_len = getxdr_u_long();
    352    0  stevel 	token = getxdr_hex(token_len);
    353    0  stevel 	line = get_line(pos, getxdr_pos());
    354    0  stevel 		sprintf(line, "   gss token: length = %d, data = [%d bytes]",
    355    0  stevel 			token_len, token_len);
    356    0  stevel 
    357    0  stevel 	show_trailer();
    358    0  stevel }
    359    0  stevel 
    360    0  stevel /*
    361    0  stevel  *  Print the results data for the RPCSEC_GSS_INIT control procedure.
    362    0  stevel  */
    363  410  kcpoon void
    364    0  stevel print_rpc_gss_init_res(int flags)
    365    0  stevel {
    366    0  stevel 
    367    0  stevel 	char *handle, *token, *line;
    368    0  stevel 	unsigned int token_len, handle_len;
    369    0  stevel 	unsigned int major, minor, seq_window;
    370    0  stevel 
    371    0  stevel 	int pos;
    372    0  stevel 	struct cache_struct *x;
    373    0  stevel 
    374    0  stevel 	/* print it */
    375    0  stevel 
    376    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()), "RPCSEC_GSS_INIT result:");
    377    0  stevel 
    378    0  stevel 	pos = getxdr_pos();
    379    0  stevel 	handle_len = getxdr_u_long();
    380    0  stevel 	handle = getxdr_hex(handle_len);
    381    0  stevel 	line = get_line(pos, getxdr_pos());
    382    0  stevel 	sprintf(line, "   handle: length = %d, data = [%s]",
    383    0  stevel 		handle_len, handle);
    384    0  stevel 	pos = getxdr_pos();
    385    0  stevel 	major = getxdr_u_long();
    386    0  stevel 	minor = getxdr_u_long();
    387    0  stevel 	seq_window = getxdr_u_long();
    388    0  stevel 
    389    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    390    0  stevel 				"   gss_major status = %u", major);
    391    0  stevel 
    392    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    393    0  stevel 				"   gss_minor status = %u", minor);
    394    0  stevel 
    395    0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
    396    0  stevel 				"   sequence window  = %u", seq_window);
    397    0  stevel 	pos = getxdr_pos();
    398    0  stevel 	token_len = getxdr_u_long();
    399    0  stevel 	token = getxdr_hex(token_len);
    400    0  stevel 	line = get_line(pos, getxdr_pos());
    401    0  stevel 	sprintf(line, "   gss token: length = %d, data = [%d bytes]",
    402    0  stevel 		token_len, token_len);
    403    0  stevel 	show_trailer();
    404    0  stevel }
    405