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