dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.sbin / snoop / snoop_rpcsec.c
blobe3579dc4f4ce111c07c26350821fefc02c50956b
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
28 #include <sys/types.h>
29 #include <sys/errno.h>
30 #include <sys/tiuser.h>
31 #include <setjmp.h>
33 #include <rpc/types.h>
34 #include <rpc/xdr.h>
35 #include <rpc/auth.h>
36 #include <rpc/clnt.h>
37 #include <rpc/rpc_msg.h>
38 #include <rpc/rpcsec_gss.h>
39 #include <string.h>
40 #include "snoop.h"
42 extern jmp_buf xdr_err;
44 struct cache_struct *find_xid();
45 char *nameof_prog(int prog);
46 static void print_rpc_gss_init_arg(int, struct cache_struct *);
47 static void print_rpc_gss_init_res(int);
49 char *
50 rpcsec_gss_proc_to_string(unsigned int proc)
52 switch (proc) {
53 case RPCSEC_GSS_DATA: return "RPCSEC_GSS_DATA"; break;
54 case RPCSEC_GSS_INIT: return "RPCSEC_GSS_INIT"; break;
55 case RPCSEC_GSS_CONTINUE_INIT:
56 return ("RPCSEC_GSS_CONTINUE_INIT");
57 case RPCSEC_GSS_DESTROY:
58 return ("RPCSEC_GSS_DESTROY");
59 default: return ("unknown");
65 char *
66 rpcsec_gss_service_to_string(rpc_gss_service_t service)
68 switch (service) {
69 case rpc_gss_svc_none: return "none"; break;
70 case rpc_gss_svc_integrity: return "integrity"; break;
71 case rpc_gss_svc_privacy: return "privacy"; break;
72 default: return "unknown"; break;
78 * Print detailed RPCSEC_GSS cred data.
80 void
81 print_rpcsec_gss_cred(int xid, int authlen)
83 unsigned int seq_num;
84 unsigned int handle_len;
85 unsigned int rpcsec_gss_ver;
86 rpc_gss_service_t rpcsec_gss_service;
87 unsigned int rpcsec_gss_proc;
88 char *handle, *line;
89 struct cache_struct *x;
90 int pos;
92 pos = getxdr_pos();
93 rpcsec_gss_ver = getxdr_u_long();
95 /* see if we know this version or not */
97 if (rpcsec_gss_ver != 1) {
98 (void) showxdr_hex(authlen, "[%s]");
99 return;
102 rpcsec_gss_proc = getxdr_u_long();
103 seq_num = getxdr_u_long();
104 rpcsec_gss_service = getxdr_enum();
106 (void) sprintf(get_line(pos, getxdr_pos()),
107 " version = %u", rpcsec_gss_ver);
109 (void) sprintf(get_line(pos, getxdr_pos()),
110 " gss control procedure = %u (%s)",
111 rpcsec_gss_proc,
112 rpcsec_gss_proc_to_string(rpcsec_gss_proc));
114 (void) sprintf(get_line(pos, getxdr_pos()),
115 " sequence num = %u", seq_num);
117 (void) sprintf(get_line(pos, getxdr_pos()),
118 " service = %d (%s)", rpcsec_gss_service,
119 rpcsec_gss_service_to_string(rpcsec_gss_service));
120 pos = getxdr_pos();
121 handle_len = getxdr_u_long();
122 handle = getxdr_hex(handle_len);
123 line = get_line(pos, getxdr_pos());
124 sprintf(line, " handle: length = %d, data = [%s]",
125 handle_len, handle);
126 x = find_xid(xid);
127 if (x) {
128 x->xid_gss_proc = rpcsec_gss_proc;
129 x->xid_gss_service = rpcsec_gss_service;
134 * Based on different RPCSEC_GSS services supported, maybe a
135 * special handling is needed before printing the arguments.
137 * For integrity service : print the sequence number.
138 * For privacy service : do not print the arguments.
141 rpcsec_gss_pre_proto(int type, int flags, int xid,
142 int prog, int vers, int proc)
144 int seq;
145 struct cache_struct *x;
147 if (! (x = find_xid(xid)))
148 return (0);
150 switch (x->xid_gss_service) {
151 case rpc_gss_svc_default:
152 case rpc_gss_svc_none:
153 break; /* standard call args */
154 case rpc_gss_svc_integrity:
155 /* length of rpc_gss_data_t encoded in the databody_integ */
156 getxdr_u_long();
157 /* read the seq number */
158 seq = getxdr_u_long();
159 if (flags & F_ALLSUM) {
160 (void) sprintf(get_sum_line(), "%s %c seq_num = %u",
161 "RPC RPCSEC_GSS", type == CALL ? 'C' : 'R',
162 seq);
163 } else if (flags & F_DTAIL) {
164 sprintf(get_line(0, 0),
165 "RPCSEC_GSS data seq_num = %u", seq);
166 show_space();
168 /* call args follow */
169 break;
170 case rpc_gss_svc_privacy: {
171 char *progname = nameof_prog(prog);
172 char prognum[32];
174 if (*progname == '?') {
175 sprintf(prognum, "%d", prog);
176 progname = prognum;
179 if (flags & F_SUM || flags & F_ALLSUM) {
180 (void) sprintf(get_sum_line(),
181 "%s %c %s ver(%d) proc(%d) (data encrypted) ",
182 "RPC RPCSEC_GSS", type == CALL ? 'C' : 'R',
183 progname, vers, proc);
184 } else if (flags & F_DTAIL) {
185 unsigned int args_len;
187 args_len = getxdr_u_long();
188 sprintf(get_line(0, 0),
189 "RPCSEC_GSS %s ver(%d) proc(%d)",
190 progname, vers, proc);
191 sprintf(get_line(0, 0),
192 "(%s args encrypted, len = %d bytes)",
193 type == CALL ? "CALL" : "REPLY", args_len);
194 show_space();
197 return (1);
199 default:
200 break;
202 return (0);
206 * Based on different RPCSEC_GSS services supported, maybe a
207 * special handling is needed after printing the arguments.
209 * For integrity service : print the checksum.
211 void
212 rpcsec_gss_post_proto(int flags, int xid)
214 char *line;
216 struct cache_struct *x;
218 if (! (x = find_xid(xid)))
219 return;
221 switch (x->xid_gss_service) {
222 case rpc_gss_svc_default:
223 case rpc_gss_svc_none:
224 case rpc_gss_svc_privacy:
225 /* nothing left */
226 break;
227 case rpc_gss_svc_integrity:
228 if (flags & F_ALLSUM) {
229 line = get_sum_line();
230 sprintf(line, "RPC RPCSEC_GSS C (checksum)");
231 } else if (flags & F_DTAIL) {
232 unsigned int checksum_len;
233 char *checksum;
235 show_header("RPC: ", "RPCSEC_GSS", 0);
236 show_space();
237 checksum_len = getxdr_u_long();
238 checksum = getxdr_hex(checksum_len);
239 sprintf(get_line(0, 0),
240 "checksum: len = %d", checksum_len);
241 sprintf(get_line(0, 0), "[%s]", checksum);
242 show_trailer();
244 break;
245 default:
246 break;
251 * Print RPCSEC_GSS control procedures protocol data,
252 * No-op for RPCSEC_GSS_DATA.
255 rpcsec_gss_control_proc(int type, int flags, int xid)
257 int seq;
259 struct cache_struct *x;
261 if (! (x = find_xid(xid)))
262 return (0);
264 if (x->xid_gss_proc != RPCSEC_GSS_DATA) {
265 if (flags & F_SUM) {
266 if (type == CALL) {
267 (void) sprintf(get_sum_line(), "%s %c %u (%s)",
268 "RPC RPCSEC_GSS",
269 type == CALL ? 'C' : 'R',
270 x->xid_gss_proc,
271 rpcsec_gss_proc_to_string(x->xid_gss_proc));
273 } else if (flags & F_DTAIL) {
274 if (x->xid_gss_proc == RPCSEC_GSS_INIT ||
275 x->xid_gss_proc == RPCSEC_GSS_CONTINUE_INIT) {
276 if (type == CALL) {
277 print_rpc_gss_init_arg(flags, x);
278 } else {
279 print_rpc_gss_init_res(flags);
283 return (1);
286 return (0);
290 * Skip the header RPCSEC_GSS cred data and
291 * put service and control type in the xid cache.
293 void
294 extract_rpcsec_gss_cred_info(int xid)
296 unsigned int seq_num;
297 unsigned int handle_len;
298 unsigned int flavor_len;
299 unsigned int rpcsec_gss_ver;
300 rpc_gss_service_t rpcsec_gss_service;
301 unsigned int rpcsec_gss_proc;
302 struct cache_struct *x;
304 flavor_len = getxdr_u_long();
305 rpcsec_gss_ver = getxdr_u_long();
306 /* see if we know this version or not */
307 if (rpcsec_gss_ver != 1) {
308 longjmp(xdr_err, 1);
310 rpcsec_gss_proc = getxdr_u_long();
311 seq_num = getxdr_u_long();
312 rpcsec_gss_service = getxdr_enum();
313 /* skip the handle */
314 xdr_skip(RNDUP(getxdr_u_long()));
316 if (x = find_xid(xid)) {
317 x->xid_gss_service = rpcsec_gss_service;
318 x->xid_gss_proc = rpcsec_gss_proc;
324 * Print the argument data for the RPCSEC_GSS_INIT control procedure.
326 static void
327 print_rpc_gss_init_arg(int flags, struct cache_struct *x)
330 char *token, *line;
331 unsigned int token_len;
332 int pos = 0;
335 * see if we need to print out the rpc_gss_init_arg structure
336 * or not.
339 if (x->xid_gss_proc != RPCSEC_GSS_INIT &&
340 x->xid_gss_proc != RPCSEC_GSS_CONTINUE_INIT) {
341 return;
344 /* print it */
346 (void) sprintf(get_line(pos, getxdr_pos()),
347 "RPCSEC_GSS_INIT args:");
349 pos = getxdr_pos();
350 token_len = getxdr_u_long();
351 token = getxdr_hex(token_len);
352 line = get_line(pos, getxdr_pos());
353 sprintf(line, " gss token: length = %d, data = [%d bytes]",
354 token_len, token_len);
356 show_trailer();
360 * Print the results data for the RPCSEC_GSS_INIT control procedure.
362 void
363 print_rpc_gss_init_res(int flags)
366 char *handle, *token, *line;
367 unsigned int token_len, handle_len;
368 unsigned int major, minor, seq_window;
370 int pos = 0;
371 struct cache_struct *x;
373 /* print it */
375 (void) sprintf(get_line(pos, getxdr_pos()), "RPCSEC_GSS_INIT result:");
377 pos = getxdr_pos();
378 handle_len = getxdr_u_long();
379 handle = getxdr_hex(handle_len);
380 line = get_line(pos, getxdr_pos());
381 sprintf(line, " handle: length = %d, data = [%s]",
382 handle_len, handle);
383 pos = getxdr_pos();
384 major = getxdr_u_long();
385 minor = getxdr_u_long();
386 seq_window = getxdr_u_long();
388 (void) sprintf(get_line(pos, getxdr_pos()),
389 " gss_major status = %u", major);
391 (void) sprintf(get_line(pos, getxdr_pos()),
392 " gss_minor status = %u", minor);
394 (void) sprintf(get_line(pos, getxdr_pos()),
395 " sequence window = %u", seq_window);
396 pos = getxdr_pos();
397 token_len = getxdr_u_long();
398 token = getxdr_hex(token_len);
399 line = get_line(pos, getxdr_pos());
400 sprintf(line, " gss token: length = %d, data = [%d bytes]",
401 token_len, token_len);
402 show_trailer();