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