|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* $Id$
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#include "autoconf.h"
|
|
Packit |
fd8b60 |
#include <stdio.h>
|
|
Packit |
fd8b60 |
#include <string.h>
|
|
Packit |
fd8b60 |
#include <netdb.h>
|
|
Packit |
fd8b60 |
#include <sys/socket.h>
|
|
Packit |
fd8b60 |
#ifdef HAVE_UNISTD_H
|
|
Packit |
fd8b60 |
#include <unistd.h>
|
|
Packit |
fd8b60 |
#endif
|
|
Packit |
fd8b60 |
#include <gssrpc/rpc.h>
|
|
Packit |
fd8b60 |
#include <gssapi/gssapi.h>
|
|
Packit |
fd8b60 |
#include <gssapi/gssapi_krb5.h>
|
|
Packit |
fd8b60 |
#include <gssrpc/rpc.h>
|
|
Packit |
fd8b60 |
#include <gssrpc/auth_gssapi.h>
|
|
Packit |
fd8b60 |
#include "rpc_test.h"
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#define BIG_BUF 4096
|
|
Packit |
fd8b60 |
/* copied from auth_gssapi.c for hackery */
|
|
Packit |
fd8b60 |
struct auth_gssapi_data {
|
|
Packit |
fd8b60 |
bool_t established;
|
|
Packit |
fd8b60 |
CLIENT *clnt;
|
|
Packit |
fd8b60 |
gss_ctx_id_t context;
|
|
Packit |
fd8b60 |
gss_buffer_desc client_handle;
|
|
Packit |
fd8b60 |
OM_uint32 seq_num;
|
|
Packit |
fd8b60 |
int def_cred;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* pre-serialized ah_cred */
|
|
Packit |
fd8b60 |
u_char cred_buf[MAX_AUTH_BYTES];
|
|
Packit |
fd8b60 |
int32_t cred_len;
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
#define AUTH_PRIVATE(auth) ((struct auth_gssapi_data *)auth->ah_private)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
extern int auth_debug_gssapi;
|
|
Packit |
fd8b60 |
char *whoami;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
#ifdef __GNUC__
|
|
Packit |
fd8b60 |
__attribute__((noreturn))
|
|
Packit |
fd8b60 |
#endif
|
|
Packit |
fd8b60 |
static void usage()
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
fprintf(stderr, "usage: %s {-t|-u} [-a] [-s num] [-m num] host service [count]\n",
|
|
Packit |
fd8b60 |
whoami);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
int
|
|
Packit |
fd8b60 |
main(argc, argv)
|
|
Packit |
fd8b60 |
int argc;
|
|
Packit |
fd8b60 |
char **argv;
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
char *host, *port, *target, *echo_arg, **echo_resp, buf[BIG_BUF];
|
|
Packit |
fd8b60 |
CLIENT *clnt;
|
|
Packit |
fd8b60 |
AUTH *tmp_auth;
|
|
Packit |
fd8b60 |
struct rpc_err e;
|
|
Packit |
fd8b60 |
int auth_once, sock, use_tcp;
|
|
Packit |
fd8b60 |
unsigned int count, i;
|
|
Packit |
fd8b60 |
extern int optind;
|
|
Packit |
fd8b60 |
extern char *optarg;
|
|
Packit |
fd8b60 |
extern int svc_debug_gssapi, misc_debug_gssapi, auth_debug_gssapi;
|
|
Packit |
fd8b60 |
int c;
|
|
Packit |
fd8b60 |
struct sockaddr_in sin;
|
|
Packit |
fd8b60 |
struct hostent *h;
|
|
Packit |
fd8b60 |
struct timeval tv;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
extern int krb5_gss_dbg_client_expcreds;
|
|
Packit |
fd8b60 |
krb5_gss_dbg_client_expcreds = 1;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
whoami = argv[0];
|
|
Packit |
fd8b60 |
count = 1026;
|
|
Packit |
fd8b60 |
auth_once = 0;
|
|
Packit |
fd8b60 |
use_tcp = -1;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
while ((c = getopt(argc, argv, "a:m:os:tu")) != -1) {
|
|
Packit |
fd8b60 |
switch (c) {
|
|
Packit |
fd8b60 |
case 'a':
|
|
Packit |
fd8b60 |
auth_debug_gssapi = atoi(optarg);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case 'm':
|
|
Packit |
fd8b60 |
misc_debug_gssapi = atoi(optarg);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case 'o':
|
|
Packit |
fd8b60 |
auth_once++;
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case 's':
|
|
Packit |
fd8b60 |
svc_debug_gssapi = atoi(optarg);
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case 't':
|
|
Packit |
fd8b60 |
use_tcp = 1;
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case 'u':
|
|
Packit |
fd8b60 |
use_tcp = 0;
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
case '?':
|
|
Packit |
fd8b60 |
usage();
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (use_tcp == -1)
|
|
Packit |
fd8b60 |
usage();
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
argv += optind;
|
|
Packit |
fd8b60 |
argc -= optind;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
switch (argc) {
|
|
Packit |
fd8b60 |
case 4:
|
|
Packit |
fd8b60 |
count = atoi(argv[3]);
|
|
Packit |
fd8b60 |
if (count > BIG_BUF-1) {
|
|
Packit |
fd8b60 |
fprintf(stderr, "Test count cannot exceed %d.\n", BIG_BUF-1);
|
|
Packit |
fd8b60 |
usage();
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
case 3:
|
|
Packit |
fd8b60 |
host = argv[0];
|
|
Packit |
fd8b60 |
port = argv[1];
|
|
Packit |
fd8b60 |
target = argv[2];
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
default:
|
|
Packit |
fd8b60 |
usage();
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* get server address */
|
|
Packit |
fd8b60 |
h = gethostbyname(host);
|
|
Packit |
fd8b60 |
if (h == NULL) {
|
|
Packit |
fd8b60 |
fprintf(stderr, "Can't resolve hostname %s\n", host);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
memset(&sin, 0, sizeof(sin));
|
|
Packit |
fd8b60 |
sin.sin_family = h->h_addrtype;
|
|
Packit |
fd8b60 |
sin.sin_port = ntohs(atoi(port));
|
|
Packit |
fd8b60 |
memmove(&sin.sin_addr, h->h_addr, sizeof(sin.sin_addr));
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* client handle to rstat */
|
|
Packit |
fd8b60 |
sock = RPC_ANYSOCK;
|
|
Packit |
fd8b60 |
if (use_tcp) {
|
|
Packit |
fd8b60 |
clnt = clnttcp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, &sock, 0,
|
|
Packit |
fd8b60 |
0);
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
tv.tv_sec = 5;
|
|
Packit |
fd8b60 |
tv.tv_usec = 0;
|
|
Packit |
fd8b60 |
clnt = clntudp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, tv,
|
|
Packit |
fd8b60 |
&sock);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (clnt == NULL) {
|
|
Packit |
fd8b60 |
clnt_pcreateerror(whoami);
|
|
Packit |
fd8b60 |
exit(1);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
clnt->cl_auth = auth_gssapi_create_default(clnt, target);
|
|
Packit |
fd8b60 |
if (clnt->cl_auth == NULL) {
|
|
Packit |
fd8b60 |
clnt_pcreateerror(whoami);
|
|
Packit |
fd8b60 |
exit(2);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Call the echo service multiple times.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
echo_arg = buf;
|
|
Packit |
fd8b60 |
for (i = 0; i < 3; i++) {
|
|
Packit |
fd8b60 |
snprintf(buf, sizeof(buf), "testing %d\n", i);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
|
|
Packit |
fd8b60 |
if (echo_resp == NULL) {
|
|
Packit |
fd8b60 |
fprintf(stderr, "RPC_TEST_ECHO call %d%s", i,
|
|
Packit |
fd8b60 |
clnt_sperror(clnt, ""));
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
if (strncmp(*echo_resp, "Echo: ", 6) &&
|
|
Packit |
fd8b60 |
strcmp(echo_arg, (*echo_resp) + 6) != 0)
|
|
Packit |
fd8b60 |
fprintf(stderr, "RPC_TEST_ECHO call %d response wrong: "
|
|
Packit |
fd8b60 |
"arg = %s, resp = %s\n", i, echo_arg, *echo_resp);
|
|
Packit |
fd8b60 |
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Make a call with an invalid verifier and check for error;
|
|
Packit |
fd8b60 |
* server should log error message. It is important to
|
|
Packit |
fd8b60 |
*increment* seq_num here, since a decrement would be fixed (see
|
|
Packit |
fd8b60 |
* below). Note that seq_num will be incremented (by
|
|
Packit |
fd8b60 |
* authg_gssapi_refresh) twice, so we need to decrement by three
|
|
Packit |
fd8b60 |
* to reset.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
AUTH_PRIVATE(clnt->cl_auth)->seq_num++;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
echo_arg = "testing with bad verf";
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
|
|
Packit |
fd8b60 |
if (echo_resp == NULL) {
|
|
Packit |
fd8b60 |
CLNT_GETERR(clnt, &e);
|
|
Packit |
fd8b60 |
if (e.re_status != RPC_AUTHERROR || e.re_why != AUTH_REJECTEDVERF)
|
|
Packit |
fd8b60 |
clnt_perror(clnt, whoami);
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
fprintf(stderr, "bad seq didn't cause failure\n");
|
|
Packit |
fd8b60 |
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
AUTH_PRIVATE(clnt->cl_auth)->seq_num -= 3;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Make sure we're resyncronized.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
echo_arg = "testing for reset";
|
|
Packit |
fd8b60 |
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
|
|
Packit |
fd8b60 |
if (echo_resp == NULL)
|
|
Packit |
fd8b60 |
clnt_perror(clnt, "Sequence number improperly reset");
|
|
Packit |
fd8b60 |
else
|
|
Packit |
fd8b60 |
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Now simulate a lost server response, and see if
|
|
Packit |
fd8b60 |
* auth_gssapi_refresh recovers.
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
AUTH_PRIVATE(clnt->cl_auth)->seq_num--;
|
|
Packit |
fd8b60 |
echo_arg = "forcing auto-resynchronization";
|
|
Packit |
fd8b60 |
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
|
|
Packit |
fd8b60 |
if (echo_resp == NULL)
|
|
Packit |
fd8b60 |
clnt_perror(clnt, "Auto-resynchronization failed");
|
|
Packit |
fd8b60 |
else
|
|
Packit |
fd8b60 |
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Now make sure auto-resyncrhonization actually worked
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
echo_arg = "testing for resynchronization";
|
|
Packit |
fd8b60 |
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
|
|
Packit |
fd8b60 |
if (echo_resp == NULL)
|
|
Packit |
fd8b60 |
clnt_perror(clnt, "Auto-resynchronization did not work");
|
|
Packit |
fd8b60 |
else
|
|
Packit |
fd8b60 |
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Test fix for secure-rpc/586, part 1: btree keys must be
|
|
Packit |
fd8b60 |
* unique. Create another context from the same credentials; it
|
|
Packit |
fd8b60 |
* should have the same expiration time and will cause the server
|
|
Packit |
fd8b60 |
* to abort if the clients are not differentiated.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* Test fix for secure-rpc/586, part 2: btree keys cannot be
|
|
Packit |
fd8b60 |
* mutated in place. To test this: a second client, *with a
|
|
Packit |
fd8b60 |
* later expiration time*, must be run. The second client should
|
|
Packit |
fd8b60 |
* destroy itself *after* the first one; if the key-mutating bug
|
|
Packit |
fd8b60 |
* is not fixed, the second client_data will be in the btree
|
|
Packit |
fd8b60 |
* before the first, but its key will be larger; thus, when the
|
|
Packit |
fd8b60 |
* first client calls AUTH_DESTROY, the server won't find it in
|
|
Packit |
fd8b60 |
* the btree and call abort.
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* For unknown reasons, running just a second client didn't
|
|
Packit |
fd8b60 |
* tickle the bug; the btree code seemed to guess which node to
|
|
Packit |
fd8b60 |
* look at first. Running a total of three clients does ticket
|
|
Packit |
fd8b60 |
* the bug. Thus, the full test sequence looks like this:
|
|
Packit |
fd8b60 |
*
|
|
Packit |
fd8b60 |
* kinit -l 20m user && client server test@ddn 200
|
|
Packit |
fd8b60 |
* sleep 1
|
|
Packit |
fd8b60 |
* kini -l 30m user && client server test@ddn 300
|
|
Packit |
fd8b60 |
* sleep 1
|
|
Packit |
fd8b60 |
* kinit -l 40m user && client server test@ddn 400
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
if (! auth_once) {
|
|
Packit |
fd8b60 |
tmp_auth = clnt->cl_auth;
|
|
Packit |
fd8b60 |
clnt->cl_auth = auth_gssapi_create_default(clnt, target);
|
|
Packit |
fd8b60 |
if (clnt->cl_auth == NULL) {
|
|
Packit |
fd8b60 |
clnt_pcreateerror(whoami);
|
|
Packit |
fd8b60 |
exit(2);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
AUTH_DESTROY(clnt->cl_auth);
|
|
Packit |
fd8b60 |
clnt->cl_auth = tmp_auth;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* Try RPC calls with argument/result lengths [0, 1025]. Do
|
|
Packit |
fd8b60 |
* this last, since it takes a while..
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
echo_arg = buf;
|
|
Packit |
fd8b60 |
memset(buf, 0, count+1);
|
|
Packit |
fd8b60 |
for (i = 0; i < count; i++) {
|
|
Packit |
fd8b60 |
echo_resp = rpc_test_echo_1(&echo_arg, clnt);
|
|
Packit |
fd8b60 |
if (echo_resp == NULL) {
|
|
Packit |
fd8b60 |
fprintf(stderr, "RPC_TEST_LENGTHS call %d%s", i,
|
|
Packit |
fd8b60 |
clnt_sperror(clnt, ""));
|
|
Packit |
fd8b60 |
break;
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
if (strncmp(*echo_resp, "Echo: ", 6) &&
|
|
Packit |
fd8b60 |
strcmp(echo_arg, (*echo_resp) + 6) != 0)
|
|
Packit |
fd8b60 |
fprintf(stderr,
|
|
Packit |
fd8b60 |
"RPC_TEST_LENGTHS call %d response wrong\n", i);
|
|
Packit |
fd8b60 |
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/* cycle from 1 to 255 */
|
|
Packit |
fd8b60 |
buf[i] = (i % 255) + 1;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (i % 100 == 0) {
|
|
Packit |
fd8b60 |
fputc('.', stdout);
|
|
Packit |
fd8b60 |
fflush(stdout);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
fputc('\n', stdout);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
AUTH_DESTROY(clnt->cl_auth);
|
|
Packit |
fd8b60 |
CLNT_DESTROY(clnt);
|
|
Packit |
fd8b60 |
exit(0);
|
|
Packit |
fd8b60 |
}
|