1 /*
2 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
3 *
4 * $Id$
5 *
6 */
7
8 #include "autoconf.h"
9 #include <stdio.h>
10 #include <string.h>
11 #include <netdb.h>
12 #include <sys/socket.h>
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16 #include <gssrpc/rpc.h>
17 #include <gssapi/gssapi.h>
18 #include <gssapi/gssapi_krb5.h>
19 #include <gssrpc/rpc.h>
20 #include <gssrpc/auth_gssapi.h>
21 #include "rpc_test.h"
22
23 #define BIG_BUF 4096
24 /* copied from auth_gssapi.c for hackery */
25 struct auth_gssapi_data {
26 bool_t established;
27 CLIENT *clnt;
28 gss_ctx_id_t context;
29 gss_buffer_desc client_handle;
30 OM_uint32 seq_num;
31 int def_cred;
32
33 /* pre-serialized ah_cred */
34 u_char cred_buf[MAX_AUTH_BYTES];
35 int32_t cred_len;
36 };
37 #define AUTH_PRIVATE(auth) ((struct auth_gssapi_data *)auth->ah_private)
38
39 extern int auth_debug_gssapi;
40 char *whoami;
41
42 #ifdef __GNUC__
43 __attribute__((noreturn))
44 #endif
usage()45 static void usage()
46 {
47 fprintf(stderr, "usage: %s {-t|-u} [-a] [-s num] [-m num] host service [count]\n",
48 whoami);
49 exit(1);
50 }
51
52 int
main(argc,argv)53 main(argc, argv)
54 int argc;
55 char **argv;
56 {
57 char *host, *port, *target, *echo_arg, **echo_resp, buf[BIG_BUF];
58 CLIENT *clnt;
59 AUTH *tmp_auth;
60 struct rpc_err e;
61 int auth_once, sock, use_tcp;
62 unsigned int count, i;
63 extern int optind;
64 extern char *optarg;
65 extern int svc_debug_gssapi, misc_debug_gssapi, auth_debug_gssapi;
66 int c;
67 struct sockaddr_in sin;
68 struct hostent *h;
69 struct timeval tv;
70
71 extern int krb5_gss_dbg_client_expcreds;
72 krb5_gss_dbg_client_expcreds = 1;
73
74 whoami = argv[0];
75 count = 1026;
76 auth_once = 0;
77 use_tcp = -1;
78
79 while ((c = getopt(argc, argv, "a:m:os:tu")) != -1) {
80 switch (c) {
81 case 'a':
82 auth_debug_gssapi = atoi(optarg);
83 break;
84 case 'm':
85 misc_debug_gssapi = atoi(optarg);
86 break;
87 case 'o':
88 auth_once++;
89 break;
90 case 's':
91 svc_debug_gssapi = atoi(optarg);
92 break;
93 case 't':
94 use_tcp = 1;
95 break;
96 case 'u':
97 use_tcp = 0;
98 break;
99 case '?':
100 usage();
101 break;
102 }
103 }
104 if (use_tcp == -1)
105 usage();
106
107 argv += optind;
108 argc -= optind;
109
110 switch (argc) {
111 case 4:
112 count = atoi(argv[3]);
113 if (count > BIG_BUF-1) {
114 fprintf(stderr, "Test count cannot exceed %d.\n", BIG_BUF-1);
115 usage();
116 }
117 case 3:
118 host = argv[0];
119 port = argv[1];
120 target = argv[2];
121 break;
122 default:
123 usage();
124 }
125
126 /* get server address */
127 h = gethostbyname(host);
128 if (h == NULL) {
129 fprintf(stderr, "Can't resolve hostname %s\n", host);
130 exit(1);
131 }
132 memset(&sin, 0, sizeof(sin));
133 sin.sin_family = h->h_addrtype;
134 sin.sin_port = ntohs(atoi(port));
135 memmove(&sin.sin_addr, h->h_addr, sizeof(sin.sin_addr));
136
137 /* client handle to rstat */
138 sock = RPC_ANYSOCK;
139 if (use_tcp) {
140 clnt = clnttcp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, &sock, 0,
141 0);
142 } else {
143 tv.tv_sec = 5;
144 tv.tv_usec = 0;
145 clnt = clntudp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, tv,
146 &sock);
147 }
148 if (clnt == NULL) {
149 clnt_pcreateerror(whoami);
150 exit(1);
151 }
152
153 clnt->cl_auth = auth_gssapi_create_default(clnt, target);
154 if (clnt->cl_auth == NULL) {
155 clnt_pcreateerror(whoami);
156 exit(2);
157 }
158
159 /*
160 * Call the echo service multiple times.
161 */
162 echo_arg = buf;
163 for (i = 0; i < 3; i++) {
164 snprintf(buf, sizeof(buf), "testing %d\n", i);
165
166 echo_resp = rpc_test_echo_1(&echo_arg, clnt);
167 if (echo_resp == NULL) {
168 fprintf(stderr, "RPC_TEST_ECHO call %d%s", i,
169 clnt_sperror(clnt, ""));
170 }
171 if (strncmp(*echo_resp, "Echo: ", 6) &&
172 strcmp(echo_arg, (*echo_resp) + 6) != 0)
173 fprintf(stderr, "RPC_TEST_ECHO call %d response wrong: "
174 "arg = %s, resp = %s\n", i, echo_arg, *echo_resp);
175 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
176 }
177
178 /*
179 * Make a call with an invalid verifier and check for error;
180 * server should log error message. It is important to
181 *increment* seq_num here, since a decrement would be fixed (see
182 * below). Note that seq_num will be incremented (by
183 * authg_gssapi_refresh) twice, so we need to decrement by three
184 * to reset.
185 */
186 AUTH_PRIVATE(clnt->cl_auth)->seq_num++;
187
188 echo_arg = "testing with bad verf";
189
190 echo_resp = rpc_test_echo_1(&echo_arg, clnt);
191 if (echo_resp == NULL) {
192 CLNT_GETERR(clnt, &e);
193 if (e.re_status != RPC_AUTHERROR || e.re_why != AUTH_REJECTEDVERF)
194 clnt_perror(clnt, whoami);
195 } else {
196 fprintf(stderr, "bad seq didn't cause failure\n");
197 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
198 }
199
200 AUTH_PRIVATE(clnt->cl_auth)->seq_num -= 3;
201
202 /*
203 * Make sure we're resyncronized.
204 */
205 echo_arg = "testing for reset";
206 echo_resp = rpc_test_echo_1(&echo_arg, clnt);
207 if (echo_resp == NULL)
208 clnt_perror(clnt, "Sequence number improperly reset");
209 else
210 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
211
212 /*
213 * Now simulate a lost server response, and see if
214 * auth_gssapi_refresh recovers.
215 */
216 AUTH_PRIVATE(clnt->cl_auth)->seq_num--;
217 echo_arg = "forcing auto-resynchronization";
218 echo_resp = rpc_test_echo_1(&echo_arg, clnt);
219 if (echo_resp == NULL)
220 clnt_perror(clnt, "Auto-resynchronization failed");
221 else
222 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
223
224 /*
225 * Now make sure auto-resyncrhonization actually worked
226 */
227 echo_arg = "testing for resynchronization";
228 echo_resp = rpc_test_echo_1(&echo_arg, clnt);
229 if (echo_resp == NULL)
230 clnt_perror(clnt, "Auto-resynchronization did not work");
231 else
232 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
233
234 if (! auth_once) {
235 tmp_auth = clnt->cl_auth;
236 clnt->cl_auth = auth_gssapi_create_default(clnt, target);
237 if (clnt->cl_auth == NULL) {
238 clnt_pcreateerror(whoami);
239 exit(2);
240 }
241 AUTH_DESTROY(clnt->cl_auth);
242 clnt->cl_auth = tmp_auth;
243 }
244
245 /*
246 * Try RPC calls with argument/result lengths [0, 1025]. Do
247 * this last, since it takes a while..
248 */
249 echo_arg = buf;
250 memset(buf, 0, count+1);
251 for (i = 0; i < count; i++) {
252 echo_resp = rpc_test_echo_1(&echo_arg, clnt);
253 if (echo_resp == NULL) {
254 fprintf(stderr, "RPC_TEST_LENGTHS call %d%s", i,
255 clnt_sperror(clnt, ""));
256 break;
257 } else {
258 if (strncmp(*echo_resp, "Echo: ", 6) &&
259 strcmp(echo_arg, (*echo_resp) + 6) != 0)
260 fprintf(stderr,
261 "RPC_TEST_LENGTHS call %d response wrong\n", i);
262 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
263 }
264
265 /* cycle from 1 to 255 */
266 buf[i] = (i % 255) + 1;
267
268 if (i % 100 == 0) {
269 fputc('.', stdout);
270 fflush(stdout);
271 }
272 }
273 fputc('\n', stdout);
274
275 AUTH_DESTROY(clnt->cl_auth);
276 CLNT_DESTROY(clnt);
277 exit(0);
278 }
279