From 03dcc375ba4fdfc5b72b9c6fe6aa7c564e90d8f6 Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Wed, 26 Oct 2005 22:07:33 +0000 Subject: [PATCH] pull up r17445 from trunk ticket: 3214 version_fixed: 1.4.3 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-4@17454 dc483132-0cff-0310-8789-dd5450dbe970 --- src/appl/gss-sample/ChangeLog | 33 +++++++ src/appl/gss-sample/gss-client.c | 147 +++++++++++++++++++++++---- src/appl/gss-sample/gss-misc.c | 2 +- src/appl/gss-sample/gss-server.c | 165 ++++++++++++++++++++++++++++--- 4 files changed, 315 insertions(+), 32 deletions(-) diff --git a/src/appl/gss-sample/ChangeLog b/src/appl/gss-sample/ChangeLog index b641880db..25c4c3fb8 100644 --- a/src/appl/gss-sample/ChangeLog +++ b/src/appl/gss-sample/ChangeLog @@ -1,3 +1,36 @@ +2005-10-20 Ken Raeburn + Jeffrey Altman + + * gss-server.c [!_WIN32]: Include port-sockets.h instead of the + various network-related UNIX header files. + (worker_bee): New function. + (main): Use it. + (max_threads): New variable. + (thread_count, hMutex, hEvent) [_WIN32]: New variables. + (InitHandles, CleanupHandles, WaitAndIncrementThreadCounter, + DecrementAndSignalThreadCounter) [_WIN32]: New functions. + (main) [_WIN32]: Accept new option -threads, and keep that many + threads going. + (usage) [_WIN32]: Document new option. + + * gss-client.c [!_WIN32]: Include assert.h. + (max_threads): New variable. + (service_name, server_host, msg, mechanism, port, use_file, + gss_flags, min_stat, oid, mcount, ccount, auth_flag, wrap_flag, + encrypt_flag, mic_flag, v1_format): Moved variables to top level + from inside main. + (worker_bee): New function, with call_server call moved from + main. + (main): Call it. + (thread_count, hMutex, hEvent) [_WIN32]: New variables. + (InitHandles, CleanupHandles, WaitAndIncrementThreadCounter, + DecrementAndSignalThreadCounter) [_WIN32]: New functions. + (main) [_WIN32]: Accept new option -threads, and keep that many + threads going. + (usage) [_WIN32]: Document new option. + + * gss-misc.c (send_token): Delete unused variable "len". + 2004-03-08 Ken Raeburn * Makefile.in (MY_SUBDIRS): Deleted. diff --git a/src/appl/gss-sample/gss-client.c b/src/appl/gss-sample/gss-client.c index f7b578a19..d05ab41d5 100644 --- a/src/appl/gss-sample/gss-client.c +++ b/src/appl/gss-sample/gss-client.c @@ -20,7 +20,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ /* - * Copyright (C) 2003, 2004 by the Massachusetts Institute of Technology. + * Copyright (C) 2003, 2004, 2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may @@ -50,6 +50,7 @@ #include #include #else +#include #include #include #include @@ -69,7 +70,11 @@ static int verbose = 1; static void usage() { fprintf(stderr, "Usage: gss-client [-port port] [-mech mechanism] [-d]\n"); - fprintf(stderr, " [-seq] [-noreplay] [-nomutual]\n"); + fprintf(stderr, " [-seq] [-noreplay] [-nomutual]"); +#ifdef _WIN32 + fprintf(stderr, " [-threads num]"); +#endif + fprintf(stderr, "\n"); fprintf(stderr, " [-f] [-q] [-ccount count] [-mcount count]\n"); fprintf(stderr, " [-v1] [-na] [-nw] [-nx] [-nm] host service msg\n"); exit(1); @@ -595,20 +600,94 @@ static void parse_oid(char *mechanism, gss_OID *oid) free(mechstr); } +static int max_threads = 1; + +#ifdef _WIN32 +static thread_count = 0; +static HANDLE hMutex = NULL; +static HANDLE hEvent = NULL; + +void +InitHandles(void) +{ + hMutex = CreateMutex(NULL, FALSE, NULL); + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); +} + +void +CleanupHandles(void) +{ + CloseHandle(hMutex); + CloseHandle(hEvent); +} + +BOOL +WaitAndIncrementThreadCounter(void) +{ + for (;;) { + if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { + if ( thread_count < max_threads ) { + thread_count++; + ReleaseMutex(hMutex); + return TRUE; + } else { + ReleaseMutex(hMutex); + + if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) { + continue; + } else { + return FALSE; + } + } + } else { + return FALSE; + } + } +} + +BOOL +DecrementAndSignalThreadCounter(void) +{ + if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { + if ( thread_count == max_threads ) + ResetEvent(hEvent); + thread_count--; + ReleaseMutex(hMutex); + return TRUE; + } else { + return FALSE; + } +} +#endif + +static char *service_name, *server_host, *msg; +static char *mechanism = 0; +static u_short port = 4444; +static int use_file = 0; +static OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; +static OM_uint32 min_stat; +static gss_OID oid = GSS_C_NULL_OID; +static int mcount = 1, ccount = 1; +static int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format; + +void worker_bee(void * unused) +{ + if (call_server(server_host, port, oid, service_name, + gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag, + v1_format, msg, use_file, mcount) < 0) + exit(1); + +#ifdef _WIN32 + if ( max_threads > 1 ) + DecrementAndSignalThreadCounter(); +#endif +} + int main(argc, argv) int argc; char **argv; { - char *service_name, *server_host, *msg; - char *mechanism = 0; - u_short port = 4444; - int use_file = 0; - OM_uint32 gss_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; - OM_uint32 min_stat; - gss_OID oid = GSS_C_NULL_OID; - int mcount = 1, ccount = 1; int i; - int auth_flag, wrap_flag, encrypt_flag, mic_flag, v1_format; display_file = stdout; auth_flag = wrap_flag = encrypt_flag = mic_flag = 1; @@ -625,7 +704,15 @@ int main(argc, argv) argc--; argv++; if (!argc) usage(); mechanism = *argv; - } else if (strcmp(*argv, "-d") == 0) { + } +#ifdef _WIN32 + else if (strcmp(*argv, "-threads") == 0) { + argc--; argv++; + if (!argc) usage(); + max_threads = atoi(*argv); + } +#endif + else if (strcmp(*argv, "-d") == 0) { gss_flags |= GSS_C_DELEG_FLAG; } else if (strcmp(*argv, "-seq") == 0) { gss_flags |= GSS_C_SEQUENCE_FLAG; @@ -664,6 +751,13 @@ int main(argc, argv) if (argc != 3) usage(); +#ifdef _WIN32 + if (max_threads < 1) { + fprintf(stderr, "warning: there must be at least one thread\n"); + max_threads = 1; + } +#endif + server_host = *argv++; service_name = *argv++; msg = *argv++; @@ -671,15 +765,34 @@ int main(argc, argv) if (mechanism) parse_oid(mechanism, &oid); - for (i = 0; i < ccount; i++) { - if (call_server(server_host, port, oid, service_name, - gss_flags, auth_flag, wrap_flag, encrypt_flag, mic_flag, - v1_format, msg, use_file, mcount) < 0) - exit(1); + if (max_threads == 1) { + for (i = 0; i < ccount; i++) { + worker_bee(0); + } + } else { +#ifdef _WIN32 + for (i = 0; i < ccount; i++) { + if ( WaitAndIncrementThreadCounter() ) { + uintptr_t handle = _beginthread(worker_bee, 0, (void *)0); + if (handle == (uintptr_t)-1) { + exit(1); + } + } else { + exit(1); + } + } +#else + /* boom */ + assert(max_threads == 1); +#endif } if (oid != GSS_C_NULL_OID) (void) gss_release_oid(&min_stat, &oid); +#ifdef _WIN32 + CleanupHandles(); +#endif + return 0; } diff --git a/src/appl/gss-sample/gss-misc.c b/src/appl/gss-sample/gss-misc.c index 1347a547b..c912792e0 100644 --- a/src/appl/gss-sample/gss-misc.c +++ b/src/appl/gss-sample/gss-misc.c @@ -160,7 +160,7 @@ int send_token(s, flags, tok) int flags; gss_buffer_t tok; { - int len, ret; + int ret; unsigned char char_flags = (unsigned char) flags; unsigned char lenbuf[4]; diff --git a/src/appl/gss-sample/gss-server.c b/src/appl/gss-sample/gss-server.c index e5adc618b..dae67afa2 100644 --- a/src/appl/gss-sample/gss-server.c +++ b/src/appl/gss-sample/gss-server.c @@ -20,7 +20,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ /* - * Copyright (C) 2004 by the Massachusetts Institute of Technology. + * Copyright (C) 2004,2005 by the Massachusetts Institute of Technology. * All rights reserved. * * Export of this software from the United States of America may @@ -48,10 +48,7 @@ #include #include #else -#include -#include -#include -#include +#include "port-sockets.h" #endif #ifdef HAVE_UNISTD_H #include @@ -70,7 +67,11 @@ static void usage() { - fprintf(stderr, "Usage: gss-server [-port port] [-verbose] [-once]\n"); + fprintf(stderr, "Usage: gss-server [-port port] [-verbose] [-once]"); +#ifdef _WIN32 + fprintf(stderr, " [-threads num]"); +#endif + fprintf(stderr, "\n"); fprintf(stderr, " [-inetd] [-export] [-logfile file] service_name\n"); exit(1); } @@ -554,6 +555,90 @@ static int sign_server(s, server_creds, export) return(0); } +static int max_threads = 1; + +#ifdef _WIN32 +static thread_count = 0; +static HANDLE hMutex = NULL; +static HANDLE hEvent = NULL; + +void +InitHandles(void) +{ + hMutex = CreateMutex(NULL, FALSE, NULL); + hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); +} + +void +CleanupHandles(void) +{ + CloseHandle(hMutex); + CloseHandle(hEvent); +} + +BOOL +WaitAndIncrementThreadCounter(void) +{ + for (;;) { + if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { + if ( thread_count < max_threads ) { + thread_count++; + ReleaseMutex(hMutex); + return TRUE; + } else { + ReleaseMutex(hMutex); + + if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0) { + continue; + } else { + return FALSE; + } + } + } else { + return FALSE; + } + } +} + +BOOL +DecrementAndSignalThreadCounter(void) +{ + if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { + if ( thread_count == max_threads ) + ResetEvent(hEvent); + thread_count--; + ReleaseMutex(hMutex); + return TRUE; + } else { + return FALSE; + } +} +#endif + +struct _work_plan { + int s; + gss_cred_id_t server_creds; + int export; +}; + +void +worker_bee(void * param) +{ + struct _work_plan *work = (struct _work_plan *) param; + + /* this return value is not checked, because there's + * not really anything to do if it fails + */ + sign_server(work->s, work->server_creds, work->export); + closesocket(work->s); + free(work); + +#ifdef _WIN32 + if ( max_threads > 1 ) + DecrementAndSignalThreadCounter(); +#endif +} + int main(argc, argv) int argc; @@ -563,7 +648,6 @@ main(argc, argv) gss_cred_id_t server_creds; OM_uint32 min_stat; u_short port = 4444; - int s; int once = 0; int do_inetd = 0; int export = 0; @@ -576,7 +660,15 @@ main(argc, argv) argc--; argv++; if (!argc) usage(); port = atoi(*argv); - } else if (strcmp(*argv, "-verbose") == 0) { + } +#ifdef _WIN32 + else if (strcmp(*argv, "-threads") == 0) { + argc--; argv++; + if (!argc) usage(); + max_threads = atoi(*argv); + } +#endif + else if (strcmp(*argv, "-verbose") == 0) { verbose = 1; } else if (strcmp(*argv, "-once") == 0) { once = 1; @@ -612,6 +704,18 @@ main(argc, argv) if ((*argv)[0] == '-') usage(); +#ifdef _WIN32 + if (max_threads < 1) { + fprintf(stderr, "warning: there must be at least one thread\n"); + max_threads = 1; + } + + if (max_threads > 1 && do_inetd) + fprintf(stderr, "warning: one thread may be used in conjunction with inetd\n"); + + InitHandles(); +#endif + service_name = *argv; if (server_acquire_creds(service_name, &server_creds) < 0) @@ -627,23 +731,56 @@ main(argc, argv) int stmp; if ((stmp = create_socket(port)) >= 0) { + if (listen(stmp, max_threads == 1 ? 0 : max_threads) < 0) + perror("listening on socket"); + do { + struct _work_plan * work = malloc(sizeof(struct _work_plan)); + + if ( work == NULL ) { + fprintf(stderr, "fatal error: out of memory"); + break; + } + /* Accept a TCP connection */ - if ((s = accept(stmp, NULL, 0)) < 0) { + if ((work->s = accept(stmp, NULL, 0)) < 0) { perror("accepting connection"); continue; } - /* this return value is not checked, because there's - not really anything to do if it fails */ - sign_server(s, server_creds, export); - close(s); + + work->server_creds = server_creds; + work->export = export; + + if (max_threads == 1) { + worker_bee((void *)work); + } +#ifdef _WIN32 + else { + if ( WaitAndIncrementThreadCounter() ) { + uintptr_t handle = _beginthread(worker_bee, 0, (void *)work); + if (handle == (uintptr_t)-1) { + closesocket(work->s); + free(work); + } + } else { + fprintf(stderr, "fatal error incrementing thread counter"); + closesocket(work->s); + free(work); + break; + } + } +#endif } while (!once); - close(stmp); + closesocket(stmp); } } (void) gss_release_cred(&min_stat, &server_creds); +#ifdef _WIN32 + CleanupHandles(); +#endif + return 0; } -- 2.26.2