Path: blob/main/crypto/krb5/src/lib/rpc/unit-test/client.c
39565 views
/*1* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.2*3* $Id$4*5*/67#include "autoconf.h"8#include <stdio.h>9#include <string.h>10#include <netdb.h>11#include <sys/socket.h>12#ifdef HAVE_UNISTD_H13#include <unistd.h>14#endif15#include <gssrpc/rpc.h>16#include <gssapi/gssapi.h>17#include <gssapi/gssapi_krb5.h>18#include <gssrpc/rpc.h>19#include <gssrpc/auth_gssapi.h>20#include "rpc_test.h"2122#define BIG_BUF 409623/* copied from auth_gssapi.c for hackery */24struct auth_gssapi_data {25bool_t established;26CLIENT *clnt;27gss_ctx_id_t context;28gss_buffer_desc client_handle;29OM_uint32 seq_num;30int def_cred;3132/* pre-serialized ah_cred */33u_char cred_buf[MAX_AUTH_BYTES];34int32_t cred_len;35};36#define AUTH_PRIVATE(auth) ((struct auth_gssapi_data *)auth->ah_private)3738extern int auth_debug_gssapi;39char *whoami;4041#ifdef __GNUC__42__attribute__((noreturn))43#endif44static void usage(void)45{46fprintf(stderr, "usage: %s {-t|-u} [-a] [-s num] [-m num] host service [count]\n",47whoami);48exit(1);49}5051int52main(int argc, char **argv)53{54char *host, *port, *target, *echo_arg, **echo_resp, buf[BIG_BUF];55CLIENT *clnt;56AUTH *tmp_auth;57struct rpc_err e;58int auth_once, sock, use_tcp;59unsigned int count, i;60extern int optind;61extern char *optarg;62extern int svc_debug_gssapi, misc_debug_gssapi, auth_debug_gssapi;63int c;64struct sockaddr_in sin;65struct hostent *h;66struct timeval tv;6768extern int krb5_gss_dbg_client_expcreds;69krb5_gss_dbg_client_expcreds = 1;7071whoami = argv[0];72count = 1026;73auth_once = 0;74use_tcp = -1;7576while ((c = getopt(argc, argv, "a:m:os:tu")) != -1) {77switch (c) {78case 'a':79auth_debug_gssapi = atoi(optarg);80break;81case 'm':82misc_debug_gssapi = atoi(optarg);83break;84case 'o':85auth_once++;86break;87case 's':88svc_debug_gssapi = atoi(optarg);89break;90case 't':91use_tcp = 1;92break;93case 'u':94use_tcp = 0;95break;96case '?':97usage();98break;99}100}101if (use_tcp == -1)102usage();103104argv += optind;105argc -= optind;106107switch (argc) {108case 4:109count = atoi(argv[3]);110if (count > BIG_BUF-1) {111fprintf(stderr, "Test count cannot exceed %d.\n", BIG_BUF-1);112usage();113}114case 3:115host = argv[0];116port = argv[1];117target = argv[2];118break;119default:120usage();121}122123/* get server address */124h = gethostbyname(host);125if (h == NULL) {126fprintf(stderr, "Can't resolve hostname %s\n", host);127exit(1);128}129memset(&sin, 0, sizeof(sin));130sin.sin_family = h->h_addrtype;131sin.sin_port = ntohs(atoi(port));132memmove(&sin.sin_addr, h->h_addr, sizeof(sin.sin_addr));133134/* client handle to rstat */135sock = RPC_ANYSOCK;136if (use_tcp) {137clnt = clnttcp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, &sock, 0,1380);139} else {140tv.tv_sec = 5;141tv.tv_usec = 0;142clnt = clntudp_create(&sin, RPC_TEST_PROG, RPC_TEST_VERS_1, tv,143&sock);144}145if (clnt == NULL) {146clnt_pcreateerror(whoami);147exit(1);148}149150clnt->cl_auth = auth_gssapi_create_default(clnt, target);151if (clnt->cl_auth == NULL) {152clnt_pcreateerror(whoami);153exit(2);154}155156/*157* Call the echo service multiple times.158*/159echo_arg = buf;160for (i = 0; i < 3; i++) {161snprintf(buf, sizeof(buf), "testing %d\n", i);162163echo_resp = rpc_test_echo_1(&echo_arg, clnt);164if (echo_resp == NULL) {165fprintf(stderr, "RPC_TEST_ECHO call %d%s", i,166clnt_sperror(clnt, ""));167break;168}169if (strncmp(*echo_resp, "Echo: ", 6) &&170strcmp(echo_arg, (*echo_resp) + 6) != 0)171fprintf(stderr, "RPC_TEST_ECHO call %d response wrong: "172"arg = %s, resp = %s\n", i, echo_arg, *echo_resp);173gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);174}175176/*177* Make a call with an invalid verifier and check for error;178* server should log error message. It is important to179*increment* seq_num here, since a decrement would be fixed (see180* below). Note that seq_num will be incremented (by181* authg_gssapi_refresh) twice, so we need to decrement by three182* to reset.183*/184AUTH_PRIVATE(clnt->cl_auth)->seq_num++;185186echo_arg = "testing with bad verf";187188echo_resp = rpc_test_echo_1(&echo_arg, clnt);189if (echo_resp == NULL) {190CLNT_GETERR(clnt, &e);191if (e.re_status != RPC_AUTHERROR || e.re_why != AUTH_REJECTEDVERF)192clnt_perror(clnt, whoami);193} else {194fprintf(stderr, "bad seq didn't cause failure\n");195gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);196}197198AUTH_PRIVATE(clnt->cl_auth)->seq_num -= 3;199200/*201* Make sure we're resyncronized.202*/203echo_arg = "testing for reset";204echo_resp = rpc_test_echo_1(&echo_arg, clnt);205if (echo_resp == NULL)206clnt_perror(clnt, "Sequence number improperly reset");207else208gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);209210/*211* Now simulate a lost server response, and see if212* auth_gssapi_refresh recovers.213*/214AUTH_PRIVATE(clnt->cl_auth)->seq_num--;215echo_arg = "forcing auto-resynchronization";216echo_resp = rpc_test_echo_1(&echo_arg, clnt);217if (echo_resp == NULL)218clnt_perror(clnt, "Auto-resynchronization failed");219else220gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);221222/*223* Now make sure auto-resyncrhonization actually worked224*/225echo_arg = "testing for resynchronization";226echo_resp = rpc_test_echo_1(&echo_arg, clnt);227if (echo_resp == NULL)228clnt_perror(clnt, "Auto-resynchronization did not work");229else230gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);231232if (! auth_once) {233tmp_auth = clnt->cl_auth;234clnt->cl_auth = auth_gssapi_create_default(clnt, target);235if (clnt->cl_auth == NULL) {236clnt_pcreateerror(whoami);237exit(2);238}239AUTH_DESTROY(clnt->cl_auth);240clnt->cl_auth = tmp_auth;241}242243/*244* Try RPC calls with argument/result lengths [0, 1025]. Do245* this last, since it takes a while..246*/247echo_arg = buf;248memset(buf, 0, count+1);249for (i = 0; i < count; i++) {250echo_resp = rpc_test_echo_1(&echo_arg, clnt);251if (echo_resp == NULL) {252fprintf(stderr, "RPC_TEST_LENGTHS call %d%s", i,253clnt_sperror(clnt, ""));254break;255} else {256if (strncmp(*echo_resp, "Echo: ", 6) &&257strcmp(echo_arg, (*echo_resp) + 6) != 0)258fprintf(stderr,259"RPC_TEST_LENGTHS call %d response wrong\n", i);260gssrpc_xdr_free((xdrproc_t)xdr_wrapstring, echo_resp);261}262263/* cycle from 1 to 255 */264buf[i] = (i % 255) + 1;265266if (i % 100 == 0) {267fputc('.', stdout);268fflush(stdout);269}270}271fputc('\n', stdout);272273AUTH_DESTROY(clnt->cl_auth);274CLNT_DESTROY(clnt);275exit(0);276}277278279