2 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
12 #include <sys/socket.h>
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>
24 /* copied from auth_gssapi.c for hackery */
25 struct auth_gssapi_data {
29 gss_buffer_desc client_handle;
33 /* pre-serialized ah_cred */
34 u_char cred_buf[MAX_AUTH_BYTES];
37 #define AUTH_PRIVATE(auth) ((struct auth_gssapi_data *)auth->ah_private)
39 extern int auth_debug_gssapi;
43 __attribute__((noreturn))
47 fprintf(stderr, "usage: %s {-t|-u} [-a] [-s num] [-m num] host service [count]\n",
57 char *host, *port, *target, *echo_arg, **echo_resp, buf[BIG_BUF];
61 int auth_once, sock, use_tcp;
62 unsigned int count, i;
65 extern int svc_debug_gssapi, misc_debug_gssapi, auth_debug_gssapi;
67 struct sockaddr_in sin;
71 extern int krb5_gss_dbg_client_expcreds;
72 krb5_gss_dbg_client_expcreds = 1;
79 while ((c = getopt(argc, argv, "a:m:os:tu")) != -1) {
82 auth_debug_gssapi = atoi(optarg);
85 misc_debug_gssapi = atoi(optarg);
91 svc_debug_gssapi = atoi(optarg);
112 count = atoi(argv[3]);
113 if (count > BIG_BUF-1) {
114 fprintf(stderr, "Test count cannot exceed %d.\n", BIG_BUF-1);
126 /* get server address */
127 h = gethostbyname(host);
129 fprintf(stderr, "Can't resolve hostname %s\n", host);
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));
137 /* client handle to rstat */
140 clnt = clnttcp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, &sock, 0,
145 clnt = clntudp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, tv,
149 clnt_pcreateerror(whoami);
153 clnt->cl_auth = auth_gssapi_create_default(clnt, target);
154 if (clnt->cl_auth == NULL) {
155 clnt_pcreateerror(whoami);
160 * Call the echo service multiple times.
163 for (i = 0; i < 3; i++) {
164 snprintf(buf, sizeof(buf), "testing %d\n", i);
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, ""));
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);
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
186 AUTH_PRIVATE(clnt->cl_auth)->seq_num++;
188 echo_arg = "testing with bad verf";
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);
196 fprintf(stderr, "bad seq didn't cause failure\n");
197 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
200 AUTH_PRIVATE(clnt->cl_auth)->seq_num -= 3;
203 * Make sure we're resyncronized.
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");
210 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
213 * Now simulate a lost server response, and see if
214 * auth_gssapi_refresh recovers.
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");
222 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
225 * Now make sure auto-resyncrhonization actually worked
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");
232 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
235 * Test fix for secure-rpc/586, part 1: btree keys must be
236 * unique. Create another context from the same credentials; it
237 * should have the same expiration time and will cause the server
238 * to abort if the clients are not differentiated.
240 * Test fix for secure-rpc/586, part 2: btree keys cannot be
241 * mutated in place. To test this: a second client, *with a
242 * later expiration time*, must be run. The second client should
243 * destroy itself *after* the first one; if the key-mutating bug
244 * is not fixed, the second client_data will be in the btree
245 * before the first, but its key will be larger; thus, when the
246 * first client calls AUTH_DESTROY, the server won't find it in
247 * the btree and call abort.
249 * For unknown reasons, running just a second client didn't
250 * tickle the bug; the btree code seemed to guess which node to
251 * look at first. Running a total of three clients does ticket
252 * the bug. Thus, the full test sequence looks like this:
254 * kinit -l 20m user && client server test@ddn 200
256 * kini -l 30m user && client server test@ddn 300
258 * kinit -l 40m user && client server test@ddn 400
261 tmp_auth = clnt->cl_auth;
262 clnt->cl_auth = auth_gssapi_create_default(clnt, target);
263 if (clnt->cl_auth == NULL) {
264 clnt_pcreateerror(whoami);
267 AUTH_DESTROY(clnt->cl_auth);
268 clnt->cl_auth = tmp_auth;
272 * Try RPC calls with argument/result lengths [0, 1025]. Do
273 * this last, since it takes a while..
276 memset(buf, 0, count+1);
277 for (i = 0; i < count; i++) {
278 echo_resp = rpc_test_echo_1(&echo_arg, clnt);
279 if (echo_resp == NULL) {
280 fprintf(stderr, "RPC_TEST_LENGTHS call %d%s", i,
281 clnt_sperror(clnt, ""));
284 if (strncmp(*echo_resp, "Echo: ", 6) &&
285 strcmp(echo_arg, (*echo_resp) + 6) != 0)
287 "RPC_TEST_LENGTHS call %d response wrong\n", i);
288 gssrpc_xdr_free(xdr_wrapstring, echo_resp);
291 /* cycle from 1 to 255 */
292 buf[i] = (i % 255) + 1;
301 AUTH_DESTROY(clnt->cl_auth);