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
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]
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>
33 #include <rpc/types.h>
37 #include <rpc/rpc_msg.h>
38 #include <rpc/rpcsec_gss.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);
50 rpcsec_gss_proc_to_string(unsigned int 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");
66 rpcsec_gss_service_to_string(rpc_gss_service_t 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.
81 print_rpcsec_gss_cred(int xid
, int authlen
)
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
;
89 struct cache_struct
*x
;
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]");
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)",
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
));
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]",
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
)
145 struct cache_struct
*x
;
147 if (! (x
= find_xid(xid
)))
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 */
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',
163 } else if (flags
& F_DTAIL
) {
164 sprintf(get_line(0, 0),
165 "RPCSEC_GSS data seq_num = %u", seq
);
168 /* call args follow */
170 case rpc_gss_svc_privacy
: {
171 char *progname
= nameof_prog(prog
);
174 if (*progname
== '?') {
175 sprintf(prognum
, "%d", prog
);
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
);
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.
212 rpcsec_gss_post_proto(int flags
, int xid
)
216 struct cache_struct
*x
;
218 if (! (x
= find_xid(xid
)))
221 switch (x
->xid_gss_service
) {
222 case rpc_gss_svc_default
:
223 case rpc_gss_svc_none
:
224 case rpc_gss_svc_privacy
:
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
;
235 show_header("RPC: ", "RPCSEC_GSS", 0);
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
);
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
)
259 struct cache_struct
*x
;
261 if (! (x
= find_xid(xid
)))
264 if (x
->xid_gss_proc
!= RPCSEC_GSS_DATA
) {
267 (void) sprintf(get_sum_line(), "%s %c %u (%s)",
269 type
== CALL
? 'C' : 'R',
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
) {
277 print_rpc_gss_init_arg(flags
, x
);
279 print_rpc_gss_init_res(flags
);
290 * Skip the header RPCSEC_GSS cred data and
291 * put service and control type in the xid cache.
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) {
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.
327 print_rpc_gss_init_arg(int flags
, struct cache_struct
*x
)
331 unsigned int token_len
;
335 * see if we need to print out the rpc_gss_init_arg structure
339 if (x
->xid_gss_proc
!= RPCSEC_GSS_INIT
&&
340 x
->xid_gss_proc
!= RPCSEC_GSS_CONTINUE_INIT
) {
346 (void) sprintf(get_line(pos
, getxdr_pos()),
347 "RPCSEC_GSS_INIT args:");
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
);
360 * Print the results data for the RPCSEC_GSS_INIT control procedure.
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
;
371 struct cache_struct
*x
;
375 (void) sprintf(get_line(pos
, getxdr_pos()), "RPCSEC_GSS_INIT result:");
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]",
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
);
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
);