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 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 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 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 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 */ 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 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 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 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