xref: /freebsd/crypto/krb5/src/lib/rpc/unit-test/server.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /*
2*7f2fe78bSCy Schubert  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
3*7f2fe78bSCy Schubert  *
4*7f2fe78bSCy Schubert  * $Id$
5*7f2fe78bSCy Schubert  * $Source$
6*7f2fe78bSCy Schubert  */
7*7f2fe78bSCy Schubert 
8*7f2fe78bSCy Schubert #include "k5-platform.h"
9*7f2fe78bSCy Schubert 
10*7f2fe78bSCy Schubert #include <stdio.h>
11*7f2fe78bSCy Schubert #include <stdlib.h>
12*7f2fe78bSCy Schubert #include "autoconf.h"
13*7f2fe78bSCy Schubert #ifdef HAVE_UNISTD_H
14*7f2fe78bSCy Schubert #include <unistd.h>
15*7f2fe78bSCy Schubert #endif
16*7f2fe78bSCy Schubert #include <string.h>
17*7f2fe78bSCy Schubert #include <signal.h>
18*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
19*7f2fe78bSCy Schubert #include <gssrpc/pmap_clnt.h>
20*7f2fe78bSCy Schubert #include <arpa/inet.h>  /* inet_ntoa */
21*7f2fe78bSCy Schubert #include <gssapi/gssapi.h>
22*7f2fe78bSCy Schubert #include <gssapi/gssapi_generic.h>
23*7f2fe78bSCy Schubert #include <gssrpc/auth_gssapi.h>
24*7f2fe78bSCy Schubert #include <sys/param.h>	/* MAXHOSTNAMELEN */
25*7f2fe78bSCy Schubert #include "rpc_test.h"
26*7f2fe78bSCy Schubert 
27*7f2fe78bSCy Schubert extern int svc_debug_gssapi, misc_debug_gssapi;
28*7f2fe78bSCy Schubert 
29*7f2fe78bSCy Schubert void rpc_test_badauth(OM_uint32 major, OM_uint32 minor,
30*7f2fe78bSCy Schubert 		 struct sockaddr_in *addr, caddr_t data);
31*7f2fe78bSCy Schubert void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg, char
32*7f2fe78bSCy Schubert 		 *error, char *data);
33*7f2fe78bSCy Schubert void log_badauth_display_status(OM_uint32 major, OM_uint32 minor);
34*7f2fe78bSCy Schubert void log_badauth_display_status_1(OM_uint32 code, int type, int rec);
35*7f2fe78bSCy Schubert static void rpc_test_badverf(gss_name_t client, gss_name_t server,
36*7f2fe78bSCy Schubert 			     struct svc_req *rqst, struct rpc_msg *msg,
37*7f2fe78bSCy Schubert 			     caddr_t data);
38*7f2fe78bSCy Schubert 
39*7f2fe78bSCy Schubert #ifndef SERVICE_NAME
40*7f2fe78bSCy Schubert #define SERVICE_NAME "host"
41*7f2fe78bSCy Schubert #endif
42*7f2fe78bSCy Schubert 
usage()43*7f2fe78bSCy Schubert static void usage()
44*7f2fe78bSCy Schubert {
45*7f2fe78bSCy Schubert      fprintf(stderr, "Usage: server {-t|-u} [svc-debug] [misc-debug]\n");
46*7f2fe78bSCy Schubert      exit(1);
47*7f2fe78bSCy Schubert }
48*7f2fe78bSCy Schubert 
49*7f2fe78bSCy Schubert #ifdef POSIX_SIGNALS
handlesig(int dummy)50*7f2fe78bSCy Schubert static void handlesig(int dummy)
51*7f2fe78bSCy Schubert #else
52*7f2fe78bSCy Schubert static void handlesig(void)
53*7f2fe78bSCy Schubert #endif
54*7f2fe78bSCy Schubert {
55*7f2fe78bSCy Schubert     exit(0);
56*7f2fe78bSCy Schubert }
57*7f2fe78bSCy Schubert 
58*7f2fe78bSCy Schubert int
main(int argc,char ** argv)59*7f2fe78bSCy Schubert main(int argc, char **argv)
60*7f2fe78bSCy Schubert {
61*7f2fe78bSCy Schubert      int c, prot;
62*7f2fe78bSCy Schubert      auth_gssapi_name names[2];
63*7f2fe78bSCy Schubert      SVCXPRT *transp;
64*7f2fe78bSCy Schubert      extern int optind;
65*7f2fe78bSCy Schubert #ifdef POSIX_SIGNALS
66*7f2fe78bSCy Schubert      struct sigaction sa;
67*7f2fe78bSCy Schubert #endif
68*7f2fe78bSCy Schubert 
69*7f2fe78bSCy Schubert      names[0].name = SERVICE_NAME;
70*7f2fe78bSCy Schubert      names[0].type = (gss_OID) gss_nt_service_name;
71*7f2fe78bSCy Schubert      names[1].name = 0;
72*7f2fe78bSCy Schubert      names[1].type = 0;
73*7f2fe78bSCy Schubert 
74*7f2fe78bSCy Schubert      prot = 0;
75*7f2fe78bSCy Schubert      while ((c = getopt(argc, argv, "tu")) != -1) {
76*7f2fe78bSCy Schubert 	  switch (c) {
77*7f2fe78bSCy Schubert 	  case 't':
78*7f2fe78bSCy Schubert 	       prot = IPPROTO_TCP;
79*7f2fe78bSCy Schubert 	       break;
80*7f2fe78bSCy Schubert 	  case 'u':
81*7f2fe78bSCy Schubert 	       prot = IPPROTO_UDP;
82*7f2fe78bSCy Schubert 	       break;
83*7f2fe78bSCy Schubert 	  case '?':
84*7f2fe78bSCy Schubert 	       usage();
85*7f2fe78bSCy Schubert 	       break;
86*7f2fe78bSCy Schubert 	  }
87*7f2fe78bSCy Schubert      }
88*7f2fe78bSCy Schubert      if (prot == 0)
89*7f2fe78bSCy Schubert 	  usage();
90*7f2fe78bSCy Schubert 
91*7f2fe78bSCy Schubert      argv += optind;
92*7f2fe78bSCy Schubert      argc -= optind;
93*7f2fe78bSCy Schubert 
94*7f2fe78bSCy Schubert      switch (argc) {
95*7f2fe78bSCy Schubert      case 2:
96*7f2fe78bSCy Schubert 	  misc_debug_gssapi = atoi(argv[1]);
97*7f2fe78bSCy Schubert      case 1:
98*7f2fe78bSCy Schubert 	  svc_debug_gssapi = atoi(argv[0]);
99*7f2fe78bSCy Schubert      case 0:
100*7f2fe78bSCy Schubert 	  break;
101*7f2fe78bSCy Schubert      default:
102*7f2fe78bSCy Schubert 	  usage();
103*7f2fe78bSCy Schubert 	  exit(1);
104*7f2fe78bSCy Schubert      }
105*7f2fe78bSCy Schubert 
106*7f2fe78bSCy Schubert      (void) pmap_unset(RPC_TEST_PROG, RPC_TEST_VERS_1);
107*7f2fe78bSCy Schubert 
108*7f2fe78bSCy Schubert      if (prot == IPPROTO_TCP)
109*7f2fe78bSCy Schubert 	  transp = svctcp_create(RPC_ANYSOCK, 0, 0);
110*7f2fe78bSCy Schubert      else
111*7f2fe78bSCy Schubert 	  transp = svcudp_create(RPC_ANYSOCK);
112*7f2fe78bSCy Schubert      if (transp == NULL) {
113*7f2fe78bSCy Schubert 	  fprintf(stderr, "cannot create tcp service.");
114*7f2fe78bSCy Schubert 	  exit(1);
115*7f2fe78bSCy Schubert      }
116*7f2fe78bSCy Schubert      if (!svc_register(transp, RPC_TEST_PROG, RPC_TEST_VERS_1,
117*7f2fe78bSCy Schubert 		       rpc_test_prog_1_svc, 0)) {
118*7f2fe78bSCy Schubert 	  fprintf(stderr,
119*7f2fe78bSCy Schubert 		  "unable to register (RPC_TEST_PROG, RPC_TEST_VERS_1, %s).",
120*7f2fe78bSCy Schubert 		  prot == IPPROTO_TCP ? "tcp" : "udp");
121*7f2fe78bSCy Schubert 	  exit(1);
122*7f2fe78bSCy Schubert      }
123*7f2fe78bSCy Schubert 
124*7f2fe78bSCy Schubert      if (svcauth_gssapi_set_names(names, 0) == FALSE) {
125*7f2fe78bSCy Schubert 	  fprintf(stderr, "unable to set gssapi names\n");
126*7f2fe78bSCy Schubert 	  exit(1);
127*7f2fe78bSCy Schubert      }
128*7f2fe78bSCy Schubert 
129*7f2fe78bSCy Schubert      svcauth_gssapi_set_log_badauth_func(rpc_test_badauth, NULL);
130*7f2fe78bSCy Schubert      svcauth_gssapi_set_log_badverf_func(rpc_test_badverf, NULL);
131*7f2fe78bSCy Schubert      svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);
132*7f2fe78bSCy Schubert 
133*7f2fe78bSCy Schubert #ifdef POSIX_SIGNALS
134*7f2fe78bSCy Schubert      (void) sigemptyset(&sa.sa_mask);
135*7f2fe78bSCy Schubert      sa.sa_flags = 0;
136*7f2fe78bSCy Schubert      sa.sa_handler = handlesig;
137*7f2fe78bSCy Schubert      (void) sigaction(SIGHUP, &sa, NULL);
138*7f2fe78bSCy Schubert      (void) sigaction(SIGINT, &sa, NULL);
139*7f2fe78bSCy Schubert      (void) sigaction(SIGTERM, &sa, NULL);
140*7f2fe78bSCy Schubert #else
141*7f2fe78bSCy Schubert      signal(SIGHUP, handlesig);
142*7f2fe78bSCy Schubert      signal(SIGINT, handlesig);
143*7f2fe78bSCy Schubert      signal(SIGTERM, handlesig);
144*7f2fe78bSCy Schubert #endif
145*7f2fe78bSCy Schubert      printf("running\n");
146*7f2fe78bSCy Schubert      printf("port: %d\n", (int)transp->xp_port);
147*7f2fe78bSCy Schubert      fflush(stdout);
148*7f2fe78bSCy Schubert 
149*7f2fe78bSCy Schubert      svc_run();
150*7f2fe78bSCy Schubert      fprintf(stderr, "svc_run returned");
151*7f2fe78bSCy Schubert      exit(1);
152*7f2fe78bSCy Schubert      /* NOTREACHED */
153*7f2fe78bSCy Schubert }
154*7f2fe78bSCy Schubert 
rpc_test_echo_1_svc(char ** arg,struct svc_req * h)155*7f2fe78bSCy Schubert char **rpc_test_echo_1_svc(char **arg, struct svc_req *h)
156*7f2fe78bSCy Schubert {
157*7f2fe78bSCy Schubert      static char *res = NULL;
158*7f2fe78bSCy Schubert 
159*7f2fe78bSCy Schubert      if (res)
160*7f2fe78bSCy Schubert 	  free(res);
161*7f2fe78bSCy Schubert      asprintf(&res, "Echo: %s", *arg);
162*7f2fe78bSCy Schubert      return &res;
163*7f2fe78bSCy Schubert }
164*7f2fe78bSCy Schubert 
rpc_test_badverf(gss_name_t client,gss_name_t server,struct svc_req * rqst,struct rpc_msg * msg,caddr_t data)165*7f2fe78bSCy Schubert static void rpc_test_badverf(gss_name_t client, gss_name_t server,
166*7f2fe78bSCy Schubert 			     struct svc_req *rqst, struct rpc_msg *msg,
167*7f2fe78bSCy Schubert 			     caddr_t data)
168*7f2fe78bSCy Schubert {
169*7f2fe78bSCy Schubert      OM_uint32 minor_stat;
170*7f2fe78bSCy Schubert      gss_OID type;
171*7f2fe78bSCy Schubert      gss_buffer_desc client_name, server_name;
172*7f2fe78bSCy Schubert 
173*7f2fe78bSCy Schubert      (void) gss_display_name(&minor_stat, client, &client_name, &type);
174*7f2fe78bSCy Schubert      (void) gss_display_name(&minor_stat, server, &server_name, &type);
175*7f2fe78bSCy Schubert 
176*7f2fe78bSCy Schubert      printf("rpc_test server: bad verifier from %.*s at %s:%d for %.*s\n",
177*7f2fe78bSCy Schubert 	    (int) client_name.length, (char *) client_name.value,
178*7f2fe78bSCy Schubert 	    inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr),
179*7f2fe78bSCy Schubert 	    ntohs(rqst->rq_xprt->xp_raddr.sin_port),
180*7f2fe78bSCy Schubert 	    (int) server_name.length, (char *) server_name.value);
181*7f2fe78bSCy Schubert      fflush(stdout);
182*7f2fe78bSCy Schubert 
183*7f2fe78bSCy Schubert      (void) gss_release_buffer(&minor_stat, &client_name);
184*7f2fe78bSCy Schubert      (void) gss_release_buffer(&minor_stat, &server_name);
185*7f2fe78bSCy Schubert }
186*7f2fe78bSCy Schubert 
187*7f2fe78bSCy Schubert /*
188*7f2fe78bSCy Schubert  * Function: log_badauth
189*7f2fe78bSCy Schubert  *
190*7f2fe78bSCy Schubert  * Purpose: Callback from GSS-API Sun RPC for authentication
191*7f2fe78bSCy Schubert  * failures/errors.
192*7f2fe78bSCy Schubert  *
193*7f2fe78bSCy Schubert  * Arguments:
194*7f2fe78bSCy Schubert  * 	major 		(r) GSS-API major status
195*7f2fe78bSCy Schubert  * 	minor		(r) GSS-API minor status
196*7f2fe78bSCy Schubert  * 	addr		(r) originating address
197*7f2fe78bSCy Schubert  * 	data		(r) arbitrary data (NULL), not used
198*7f2fe78bSCy Schubert  *
199*7f2fe78bSCy Schubert  * Effects:
200*7f2fe78bSCy Schubert  *
201*7f2fe78bSCy Schubert  * Logs the GSS-API error to stdout.
202*7f2fe78bSCy Schubert  */
rpc_test_badauth(OM_uint32 major,OM_uint32 minor,struct sockaddr_in * addr,caddr_t data)203*7f2fe78bSCy Schubert void rpc_test_badauth(OM_uint32 major, OM_uint32 minor,
204*7f2fe78bSCy Schubert 		 struct sockaddr_in *addr, caddr_t data)
205*7f2fe78bSCy Schubert {
206*7f2fe78bSCy Schubert      char *a;
207*7f2fe78bSCy Schubert 
208*7f2fe78bSCy Schubert      /* Authentication attempt failed: <IP address>, <GSS-API error */
209*7f2fe78bSCy Schubert      /* strings> */
210*7f2fe78bSCy Schubert 
211*7f2fe78bSCy Schubert      a = inet_ntoa(addr->sin_addr);
212*7f2fe78bSCy Schubert 
213*7f2fe78bSCy Schubert      printf("rpc_test server: Authentication attempt failed: %s", a);
214*7f2fe78bSCy Schubert      log_badauth_display_status(major, minor);
215*7f2fe78bSCy Schubert      printf("\n");
216*7f2fe78bSCy Schubert      fflush(stdout);
217*7f2fe78bSCy Schubert }
218*7f2fe78bSCy Schubert 
log_miscerr(struct svc_req * rqst,struct rpc_msg * msg,char * error,char * data)219*7f2fe78bSCy Schubert void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
220*7f2fe78bSCy Schubert 		 char *error, char *data)
221*7f2fe78bSCy Schubert {
222*7f2fe78bSCy Schubert      char *a;
223*7f2fe78bSCy Schubert 
224*7f2fe78bSCy Schubert      a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
225*7f2fe78bSCy Schubert      printf("Miscellaneous RPC error: %s, %s\n", a, error);
226*7f2fe78bSCy Schubert      fflush(stdout);
227*7f2fe78bSCy Schubert }
228*7f2fe78bSCy Schubert 
log_badauth_display_status(OM_uint32 major,OM_uint32 minor)229*7f2fe78bSCy Schubert void log_badauth_display_status(OM_uint32 major, OM_uint32 minor)
230*7f2fe78bSCy Schubert {
231*7f2fe78bSCy Schubert      log_badauth_display_status_1(major, GSS_C_GSS_CODE, 0);
232*7f2fe78bSCy Schubert      log_badauth_display_status_1(minor, GSS_C_MECH_CODE, 0);
233*7f2fe78bSCy Schubert }
234*7f2fe78bSCy Schubert 
log_badauth_display_status_1(OM_uint32 code,int type,int rec)235*7f2fe78bSCy Schubert void log_badauth_display_status_1(OM_uint32 code, int type, int rec)
236*7f2fe78bSCy Schubert {
237*7f2fe78bSCy Schubert      OM_uint32 gssstat, minor_stat, msg_ctx;
238*7f2fe78bSCy Schubert      gss_buffer_desc msg;
239*7f2fe78bSCy Schubert 
240*7f2fe78bSCy Schubert      msg_ctx = 0;
241*7f2fe78bSCy Schubert      while (1) {
242*7f2fe78bSCy Schubert 	  gssstat = gss_display_status(&minor_stat, code,
243*7f2fe78bSCy Schubert 				       type, GSS_C_NULL_OID,
244*7f2fe78bSCy Schubert 				       &msg_ctx, &msg);
245*7f2fe78bSCy Schubert 	  if (gssstat != GSS_S_COMPLETE) {
246*7f2fe78bSCy Schubert  	       if (!rec) {
247*7f2fe78bSCy Schubert 		    log_badauth_display_status_1(gssstat,GSS_C_GSS_CODE,1);
248*7f2fe78bSCy Schubert 		    log_badauth_display_status_1(minor_stat,
249*7f2fe78bSCy Schubert 						 GSS_C_MECH_CODE, 1);
250*7f2fe78bSCy Schubert 	       } else {
251*7f2fe78bSCy Schubert 		    printf("GSS-API authentication error %.*s: "
252*7f2fe78bSCy Schubert 			   "recursive failure!\n", (int) msg.length,
253*7f2fe78bSCy Schubert 			   (char *)msg.value);
254*7f2fe78bSCy Schubert 	       }
255*7f2fe78bSCy Schubert 	       fflush(stdout);
256*7f2fe78bSCy Schubert 	       return;
257*7f2fe78bSCy Schubert 	  }
258*7f2fe78bSCy Schubert 
259*7f2fe78bSCy Schubert 	  printf(", %.*s", (int) msg.length, (char *)msg.value);
260*7f2fe78bSCy Schubert 	  (void) gss_release_buffer(&minor_stat, &msg);
261*7f2fe78bSCy Schubert 
262*7f2fe78bSCy Schubert 	  if (!msg_ctx)
263*7f2fe78bSCy Schubert 	       break;
264*7f2fe78bSCy Schubert      }
265*7f2fe78bSCy Schubert      fflush(stdout);
266*7f2fe78bSCy Schubert }
267