Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/rpc/unit-test/client.c
39565 views
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
45
static void usage(void)
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
53
main(int argc, char **argv)
54
{
55
char *host, *port, *target, *echo_arg, **echo_resp, buf[BIG_BUF];
56
CLIENT *clnt;
57
AUTH *tmp_auth;
58
struct rpc_err e;
59
int auth_once, sock, use_tcp;
60
unsigned int count, i;
61
extern int optind;
62
extern char *optarg;
63
extern int svc_debug_gssapi, misc_debug_gssapi, auth_debug_gssapi;
64
int c;
65
struct sockaddr_in sin;
66
struct hostent *h;
67
struct timeval tv;
68
69
extern int krb5_gss_dbg_client_expcreds;
70
krb5_gss_dbg_client_expcreds = 1;
71
72
whoami = argv[0];
73
count = 1026;
74
auth_once = 0;
75
use_tcp = -1;
76
77
while ((c = getopt(argc, argv, "a:m:os:tu")) != -1) {
78
switch (c) {
79
case 'a':
80
auth_debug_gssapi = atoi(optarg);
81
break;
82
case 'm':
83
misc_debug_gssapi = atoi(optarg);
84
break;
85
case 'o':
86
auth_once++;
87
break;
88
case 's':
89
svc_debug_gssapi = atoi(optarg);
90
break;
91
case 't':
92
use_tcp = 1;
93
break;
94
case 'u':
95
use_tcp = 0;
96
break;
97
case '?':
98
usage();
99
break;
100
}
101
}
102
if (use_tcp == -1)
103
usage();
104
105
argv += optind;
106
argc -= optind;
107
108
switch (argc) {
109
case 4:
110
count = atoi(argv[3]);
111
if (count > BIG_BUF-1) {
112
fprintf(stderr, "Test count cannot exceed %d.\n", BIG_BUF-1);
113
usage();
114
}
115
case 3:
116
host = argv[0];
117
port = argv[1];
118
target = argv[2];
119
break;
120
default:
121
usage();
122
}
123
124
/* get server address */
125
h = gethostbyname(host);
126
if (h == NULL) {
127
fprintf(stderr, "Can't resolve hostname %s\n", host);
128
exit(1);
129
}
130
memset(&sin, 0, sizeof(sin));
131
sin.sin_family = h->h_addrtype;
132
sin.sin_port = ntohs(atoi(port));
133
memmove(&sin.sin_addr, h->h_addr, sizeof(sin.sin_addr));
134
135
/* client handle to rstat */
136
sock = RPC_ANYSOCK;
137
if (use_tcp) {
138
clnt = clnttcp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, &sock, 0,
139
0);
140
} else {
141
tv.tv_sec = 5;
142
tv.tv_usec = 0;
143
clnt = clntudp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, tv,
144
&sock);
145
}
146
if (clnt == NULL) {
147
clnt_pcreateerror(whoami);
148
exit(1);
149
}
150
151
clnt->cl_auth = auth_gssapi_create_default(clnt, target);
152
if (clnt->cl_auth == NULL) {
153
clnt_pcreateerror(whoami);
154
exit(2);
155
}
156
157
/*
158
* Call the echo service multiple times.
159
*/
160
echo_arg = buf;
161
for (i = 0; i < 3; i++) {
162
snprintf(buf, sizeof(buf), "testing %d\n", i);
163
164
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
165
if (echo_resp == NULL) {
166
fprintf(stderr, "RPC_TEST_ECHO call %d%s", i,
167
clnt_sperror(clnt, ""));
168
break;
169
}
170
if (strncmp(*echo_resp, "Echo: ", 6) &&
171
strcmp(echo_arg, (*echo_resp) + 6) != 0)
172
fprintf(stderr, "RPC_TEST_ECHO call %d response wrong: "
173
"arg = %s, resp = %s\n", i, echo_arg, *echo_resp);
174
gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);
175
}
176
177
/*
178
* Make a call with an invalid verifier and check for error;
179
* server should log error message. It is important to
180
*increment* seq_num here, since a decrement would be fixed (see
181
* below). Note that seq_num will be incremented (by
182
* authg_gssapi_refresh) twice, so we need to decrement by three
183
* to reset.
184
*/
185
AUTH_PRIVATE(clnt->cl_auth)->seq_num++;
186
187
echo_arg = "testing with bad verf";
188
189
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
190
if (echo_resp == NULL) {
191
CLNT_GETERR(clnt, &e);
192
if (e.re_status != RPC_AUTHERROR || e.re_why != AUTH_REJECTEDVERF)
193
clnt_perror(clnt, whoami);
194
} else {
195
fprintf(stderr, "bad seq didn't cause failure\n");
196
gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);
197
}
198
199
AUTH_PRIVATE(clnt->cl_auth)->seq_num -= 3;
200
201
/*
202
* Make sure we're resyncronized.
203
*/
204
echo_arg = "testing for reset";
205
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
206
if (echo_resp == NULL)
207
clnt_perror(clnt, "Sequence number improperly reset");
208
else
209
gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);
210
211
/*
212
* Now simulate a lost server response, and see if
213
* auth_gssapi_refresh recovers.
214
*/
215
AUTH_PRIVATE(clnt->cl_auth)->seq_num--;
216
echo_arg = "forcing auto-resynchronization";
217
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
218
if (echo_resp == NULL)
219
clnt_perror(clnt, "Auto-resynchronization failed");
220
else
221
gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);
222
223
/*
224
* Now make sure auto-resyncrhonization actually worked
225
*/
226
echo_arg = "testing for resynchronization";
227
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
228
if (echo_resp == NULL)
229
clnt_perror(clnt, "Auto-resynchronization did not work");
230
else
231
gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);
232
233
if (! auth_once) {
234
tmp_auth = clnt->cl_auth;
235
clnt->cl_auth = auth_gssapi_create_default(clnt, target);
236
if (clnt->cl_auth == NULL) {
237
clnt_pcreateerror(whoami);
238
exit(2);
239
}
240
AUTH_DESTROY(clnt->cl_auth);
241
clnt->cl_auth = tmp_auth;
242
}
243
244
/*
245
* Try RPC calls with argument/result lengths [0, 1025]. Do
246
* this last, since it takes a while..
247
*/
248
echo_arg = buf;
249
memset(buf, 0, count+1);
250
for (i = 0; i < count; i++) {
251
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
252
if (echo_resp == NULL) {
253
fprintf(stderr, "RPC_TEST_LENGTHS call %d%s", i,
254
clnt_sperror(clnt, ""));
255
break;
256
} else {
257
if (strncmp(*echo_resp, "Echo: ", 6) &&
258
strcmp(echo_arg, (*echo_resp) + 6) != 0)
259
fprintf(stderr,
260
"RPC_TEST_LENGTHS call %d response wrong\n", i);
261
gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);
262
}
263
264
/* cycle from 1 to 255 */
265
buf[i] = (i % 255) + 1;
266
267
if (i % 100 == 0) {
268
fputc('.', stdout);
269
fflush(stdout);
270
}
271
}
272
fputc('\n', stdout);
273
274
AUTH_DESTROY(clnt->cl_auth);
275
CLNT_DESTROY(clnt);
276
exit(0);
277
}
278
279