Imported Upstream version 1.15.1
[platform/upstream/krb5.git] / src / lib / rpc / unit-test / server.c
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 "server"
41 #endif
42
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
50 static void handlesig(int dummy)
51 #else
52 static void handlesig(void)
53 #endif
54 {
55     exit(0);
56 }
57
58 int
59 main(int argc, char **argv)
60 {
61      int c, prot;
62      auth_gssapi_name names[2];
63      register 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      printf("port: %d\n", (int)transp->xp_port);
124
125      if (svcauth_gssapi_set_names(names, 0) == FALSE) {
126           fprintf(stderr, "unable to set gssapi names\n");
127           exit(1);
128      }
129
130      svcauth_gssapi_set_log_badauth_func(rpc_test_badauth, NULL);
131      svcauth_gssapi_set_log_badverf_func(rpc_test_badverf, NULL);
132      svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);
133
134 #ifdef POSIX_SIGNALS
135      (void) sigemptyset(&sa.sa_mask);
136      sa.sa_flags = 0;
137      sa.sa_handler = handlesig;
138      (void) sigaction(SIGHUP, &sa, NULL);
139      (void) sigaction(SIGINT, &sa, NULL);
140      (void) sigaction(SIGTERM, &sa, NULL);
141 #else
142      signal(SIGHUP, handlesig);
143      signal(SIGINT, handlesig);
144      signal(SIGTERM, handlesig);
145 #endif
146      printf("running\n");
147
148      svc_run();
149      fprintf(stderr, "svc_run returned");
150      exit(1);
151      /* NOTREACHED */
152 }
153
154 char **rpc_test_echo_1_svc(char **arg, struct svc_req *h)
155 {
156      static char *res = NULL;
157
158      if (res)
159           free(res);
160      asprintf(&res, "Echo: %s", *arg);
161      return &res;
162 }
163
164 static void rpc_test_badverf(gss_name_t client, gss_name_t server,
165                              struct svc_req *rqst, struct rpc_msg *msg,
166                              caddr_t data)
167 {
168      OM_uint32 minor_stat;
169      gss_OID type;
170      gss_buffer_desc client_name, server_name;
171
172      (void) gss_display_name(&minor_stat, client, &client_name, &type);
173      (void) gss_display_name(&minor_stat, server, &server_name, &type);
174
175      printf("rpc_test server: bad verifier from %.*s at %s:%d for %.*s\n",
176             (int) client_name.length, (char *) client_name.value,
177             inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr),
178             ntohs(rqst->rq_xprt->xp_raddr.sin_port),
179             (int) server_name.length, (char *) server_name.value);
180
181      (void) gss_release_buffer(&minor_stat, &client_name);
182      (void) gss_release_buffer(&minor_stat, &server_name);
183 }
184
185 /*
186  * Function: log_badauth
187  *
188  * Purpose: Callback from GSS-API Sun RPC for authentication
189  * failures/errors.
190  *
191  * Arguments:
192  *      major           (r) GSS-API major status
193  *      minor           (r) GSS-API minor status
194  *      addr            (r) originating address
195  *      data            (r) arbitrary data (NULL), not used
196  *
197  * Effects:
198  *
199  * Logs the GSS-API error to stdout.
200  */
201 void rpc_test_badauth(OM_uint32 major, OM_uint32 minor,
202                  struct sockaddr_in *addr, caddr_t data)
203 {
204      char *a;
205
206      /* Authentication attempt failed: <IP address>, <GSS-API error */
207      /* strings> */
208
209      a = inet_ntoa(addr->sin_addr);
210
211      printf("rpc_test server: Authentication attempt failed: %s", a);
212      log_badauth_display_status(major, minor);
213      printf("\n");
214 }
215
216 void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
217                  char *error, char *data)
218 {
219      char *a;
220
221      a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
222      printf("Miscellaneous RPC error: %s, %s\n", a, error);
223 }
224
225 void log_badauth_display_status(OM_uint32 major, OM_uint32 minor)
226 {
227      log_badauth_display_status_1(major, GSS_C_GSS_CODE, 0);
228      log_badauth_display_status_1(minor, GSS_C_MECH_CODE, 0);
229 }
230
231 void log_badauth_display_status_1(OM_uint32 code, int type, int rec)
232 {
233      OM_uint32 gssstat, minor_stat, msg_ctx;
234      gss_buffer_desc msg;
235
236      msg_ctx = 0;
237      while (1) {
238           gssstat = gss_display_status(&minor_stat, code,
239                                        type, GSS_C_NULL_OID,
240                                        &msg_ctx, &msg);
241           if (gssstat != GSS_S_COMPLETE) {
242                if (!rec) {
243                     log_badauth_display_status_1(gssstat,GSS_C_GSS_CODE,1);
244                     log_badauth_display_status_1(minor_stat,
245                                                  GSS_C_MECH_CODE, 1);
246                } else
247                     printf("GSS-API authentication error %.*s: "
248                            "recursive failure!\n", (int) msg.length,
249                            (char *)msg.value);
250                return;
251           }
252
253           printf(", %.*s", (int) msg.length, (char *)msg.value);
254           (void) gss_release_buffer(&minor_stat, &msg);
255
256           if (!msg_ctx)
257                break;
258      }
259 }