diff options
-rw-r--r-- | src/appl/gss-sample/ChangeLog | 15 | ||||
-rw-r--r-- | src/appl/gss-sample/gss-client.c | 88 | ||||
-rw-r--r-- | src/appl/gss-sample/gss-misc.c | 40 | ||||
-rw-r--r-- | src/appl/gss-sample/gss-server.c | 114 |
4 files changed, 219 insertions, 38 deletions
diff --git a/src/appl/gss-sample/ChangeLog b/src/appl/gss-sample/ChangeLog index 20c8b64..109d1aa 100644 --- a/src/appl/gss-sample/ChangeLog +++ b/src/appl/gss-sample/ChangeLog @@ -1,3 +1,18 @@ +Sat Mar 2 03:03:27 1996 Theodore Y. Ts'o <tytso@dcl> + + * gss-server.c (sign_server): Do better import/export security + checking. If the received message to be signed is not + printable (at least the first two characters are not), + display the message in hex. Print the hex values of the + incoming and outcoming packets, for your information. + + * gss-misc.c (print_token, display_buffer): Two new tokens for + displaying GSSAPI buffers, either has hex or as a + printable string. + + * gss-client.c (call_server): Add option to support reading in the + message to be signed from a file. + Wed Feb 28 11:42:26 1996 Theodore Y. Ts'o <tytso@dcl> * gss-client.c (call_server): Get the nametype OID from diff --git a/src/appl/gss-sample/gss-client.c b/src/appl/gss-sample/gss-client.c index 986a796..2f58d1e 100644 --- a/src/appl/gss-sample/gss-client.c +++ b/src/appl/gss-sample/gss-client.c @@ -21,10 +21,15 @@ */ #include <stdio.h> +#include <unistd.h> +#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> +#include <errno.h> +#include <sys/stat.h> +#include <fcntl.h> #include <gssapi/gssapi.h> #include <gssapi/gssapi_generic.h> @@ -38,29 +43,33 @@ int establish_context(); int connect_to_server(); int call_server(); +int client_establish_context(); int send_token(); int recv_token(); +void read_file(); int deleg_flag; void display_status(); extern FILE *display_file; -usage() + +void usage() { fprintf(stderr, "Usage: gss-client [-port port] [-d] [-v2] host service \ msg\n"); exit(1); } -main(argc, argv) +int main(argc, argv) int argc; char **argv; { char *service_name, *server_host, *msg; u_short port = 4444; int v2 = 0; + int use_file = 0; display_file = stdout; deleg_flag = 0; @@ -76,6 +85,8 @@ main(argc, argv) v2 = 1; } else if (strcmp(*argv, "-d") == 0) { deleg_flag = GSS_C_DELEG_FLAG; + } else if (strcmp(*argv, "-f") == 0) { + use_file = 1; } else break; argc--; argv++; @@ -87,7 +98,7 @@ main(argc, argv) service_name = *argv++; msg = *argv++; - if (call_server(server_host, port, v2, service_name, msg) < 0) + if (call_server(server_host, port, v2, service_name, msg, use_file) < 0) exit(1); return 0; @@ -116,12 +127,13 @@ main(argc, argv) * verifies it with gss_verify. -1 is returned if any step fails, * otherwise 0 is returned. */ -int call_server(host, port, dov2, service_name, msg) +int call_server(host, port, dov2, service_name, msg, use_file) char *host; u_short port; int dov2; char *service_name; char *msg; + int use_file; { gss_ctx_id_t context; gss_buffer_desc in_buf, out_buf, context_token; @@ -141,7 +153,6 @@ int call_server(host, port, dov2, service_name, msg) #else /* GSSAPI_V2 */ int context_flags; #endif /* GSSAPI_V2 */ - /* Open connection */ if ((s = connect_to_server(host, port)) < 0) @@ -201,7 +212,8 @@ int call_server(host, port, dov2, service_name, msg) return -1; } fprintf(stderr, "\"%s\" to \"%s\", lifetime %d, flags %x, %s", - sname.value, tname.value, lifetime, context_flags, + (char *) sname.value, (char *) tname.value, lifetime, + context_flags, (is_local) ? "locally initiated" : "remotely initiated"); #ifdef GSSAPI_V2 fprintf(stderr, " %s", (is_open) ? "open" : "closed"); @@ -225,7 +237,7 @@ int call_server(host, port, dov2, service_name, msg) return -1; } fprintf(stderr, "Name type of source name is %s.\n", - oid_name.value); + (char *) oid_name.value); (void) gss_release_buffer(&min_stat, &oid_name); (void) gss_release_oid(&min_stat, &name_type); @@ -246,7 +258,7 @@ int call_server(host, port, dov2, service_name, msg) return -1; } fprintf(stderr, "Mechanism %s supports %d names\n", - oid_name.value, mech_names->count); + (char *) oid_name.value, mech_names->count); (void) gss_release_buffer(&min_stat, &oid_name); for (i=0; i<mech_names->count; i++) { gss_OID tmpoid; @@ -259,7 +271,7 @@ int call_server(host, port, dov2, service_name, msg) display_status("converting oid->string", maj_stat, min_stat); return -1; } - fprintf(stderr, "%d: %s\n", i, oid_name.value); + fprintf(stderr, "%d: %s\n", i, (char *) oid_name.value); maj_stat = gss_str_to_oid(&min_stat, &oid_name, @@ -279,7 +291,7 @@ int call_server(host, port, dov2, service_name, msg) } if (!is_present) { fprintf(stderr, "%s is not present in list?\n", - oid_name.value); + (char *) oid_name.value); } (void) gss_release_oid(&min_stat, &tmpoid); (void) gss_release_buffer(&min_stat, &oid_name); @@ -290,9 +302,13 @@ int call_server(host, port, dov2, service_name, msg) } #endif /* GSSAPI_V2 */ - /* Seal the message */ - in_buf.value = msg; - in_buf.length = strlen(msg) + 1; + if (use_file) { + read_file(msg, &in_buf); + } else { + /* Seal the message */ + in_buf.value = msg; + in_buf.length = strlen(msg) + 1; + } #ifdef GSSAPI_V2 if (dov2) maj_stat = gss_wrap(&min_stat, context, 1, GSS_C_QOP_DEFAULT, @@ -307,6 +323,8 @@ int call_server(host, port, dov2, service_name, msg) } else if (! state) { fprintf(stderr, "Warning! Message not encrypted.\n"); } + if (use_file) + free(in_buf.value); /* Send to server */ if (send_token(s, &out_buf) < 0) @@ -484,6 +502,8 @@ int client_establish_context(s, service_name, gss_context) } if (send_tok.length != 0) { + printf("Sending init_sec_context token (size=%d)...", + send_tok.length); if (send_token(s, &send_tok) < 0) { (void) gss_release_buffer(&min_stat, &send_tok); (void) gss_release_name(&min_stat, &target_name); @@ -493,14 +513,56 @@ int client_establish_context(s, service_name, gss_context) (void) gss_release_buffer(&min_stat, &send_tok); if (maj_stat == GSS_S_CONTINUE_NEEDED) { + printf("continue needed..."); if (recv_token(s, &recv_tok) < 0) { (void) gss_release_name(&min_stat, &target_name); return -1; } token_ptr = &recv_tok; } + printf("\n"); } while (maj_stat == GSS_S_CONTINUE_NEEDED); (void) gss_release_name(&min_stat, &target_name); return 0; } + + +void read_file(file_name, in_buf) + char *file_name; + gss_buffer_t in_buf; +{ + int fd, bytes_in, count; + struct stat stat_buf; + + if ((fd = open(file_name, O_RDONLY, 0)) < 0) { + perror("open"); + fprintf(stderr, "Couldn't open file %s\n", file_name); + exit(1); + } + if (fstat(fd, &stat_buf) < 0) { + perror("fstat"); + exit(1); + } + in_buf->length = stat_buf.st_size; + in_buf->value = malloc(in_buf->length); + if (in_buf->value == 0) { + fprintf(stderr, "Couldn't allocate %d byte buffer for reading file\n", + in_buf->length); + exit(1); + } + memset(in_buf->value, 0, in_buf->length); + for (bytes_in = 0; bytes_in < in_buf->length; bytes_in += count) { + count = read(fd, in_buf->value, in_buf->length); + if (count < 0) { + perror("read"); + exit(1); + } + if (count == 0) + break; + } + if (bytes_in != count) + fprintf(stderr, "Warning, only read in %d bytes, expected %d\n", + bytes_in, count); +} + diff --git a/src/appl/gss-sample/gss-misc.c b/src/appl/gss-sample/gss-misc.c index 2801212..446aa30 100644 --- a/src/appl/gss-sample/gss-misc.c +++ b/src/appl/gss-sample/gss-misc.c @@ -26,6 +26,7 @@ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#include <string.h> #include <gssapi/gssapi.h> #include <gssapi/gssapi_generic.h> @@ -209,3 +210,42 @@ static void display_status_1(m, code, type) break; } } + +void print_token(tok) + gss_buffer_t tok; +{ + int i; + unsigned char *p = tok->value; + + if (!display_file) + return; + for (i=0; i < tok->length; i++, p++) { + fprintf(display_file, "%02x ", *p); + if ((i % 16) == 15) { + fprintf(display_file, "\n"); + } + } + fprintf(display_file, "\n"); + fflush(display_file); +} + +void display_buffer(buffer) + gss_buffer_desc buffer; +{ + char *namebuf; + + if (!display_file) + return; + namebuf = malloc(buffer.length+1); + if (!namebuf) { + fprintf(stderr, "display_buffer: couldn't allocate buffer!\n"); + exit(1); + } + strncpy(namebuf, buffer.value, buffer.length); + namebuf[buffer.length] = '\0'; + fprintf(display_file, "%s", namebuf); + free(namebuf); +} + + + diff --git a/src/appl/gss-sample/gss-server.c b/src/appl/gss-sample/gss-server.c index 4d0a03c..8e7bc92 100644 --- a/src/appl/gss-sample/gss-server.c +++ b/src/appl/gss-sample/gss-server.c @@ -27,6 +27,8 @@ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#include <stdlib.h> +#include <ctype.h> #include <sys/time.h> #include <time.h> @@ -44,10 +46,17 @@ int create_socket(); int send_token(); int recv_token(); void display_status(); +int test_import_export_context(); +void print_token(); + +int server_acquire_creds(); +int server_establish_context(); +int sign_server(); extern FILE *display_file; FILE *log; +int verbose = 0; void usage() @@ -79,6 +88,8 @@ main(argc, argv) } else if (strcmp(*argv, "-inetd") == 0) { do_inetd = 1; display_file = 0; + } else if (strcmp(*argv, "-verbose") == 0) { + verbose = 1; } else if (strcmp(*argv, "-v2") == 0) { dov2 = 1; } else if (strcmp(*argv, "-once") == 0) { @@ -200,11 +211,12 @@ int sign_server(s, service_name, dov2, once) int once; { gss_cred_id_t server_creds; - gss_buffer_desc client_name, xmit_buf, msg_buf, context_token; + gss_buffer_desc client_name, xmit_buf, msg_buf; gss_ctx_id_t context; OM_uint32 maj_stat, min_stat; - int s2; + int i,s2; time_t now; + char *cp; if (server_acquire_creds(service_name, &server_creds) < 0) return -1; @@ -230,30 +242,21 @@ int sign_server(s, service_name, dov2, once) (void) gss_release_buffer(&min_stat, &client_name); if (dov2) { - /* - * Attempt to save and then restore the context. - */ - maj_stat = gss_export_sec_context(&min_stat, - &context, - &context_token); - if (maj_stat != GSS_S_COMPLETE) { - display_status("exporting context", maj_stat, min_stat); - break; - } - fprintf(log, "Exported context: %d bytes\n", context_token.length); - maj_stat = gss_import_sec_context(&min_stat, - &context_token, - &context); - if (maj_stat != GSS_S_COMPLETE) { - display_status("importing context", maj_stat, min_stat); - break; - } - (void) gss_release_buffer(&min_stat, &context_token); + for (i=0; i < 3; i++) + if (test_import_export_context(&context)) + break; + if (i < 3) + break; } /* Receive the sealed message token */ if (recv_token(s2, &xmit_buf) < 0) break; + + if (verbose && log) { + fprintf(log, "Sealed message token:\n"); + print_token(xmit_buf); + } #ifdef GSSAPI_V2 if (dov2) @@ -271,8 +274,15 @@ int sign_server(s, service_name, dov2, once) (void) gss_release_buffer(&min_stat, &xmit_buf); - fprintf(log, "Received message: \"%s\"\n", (char *) msg_buf.value); - + fprintf(log, "Received message: "); + cp = msg_buf.value; + if (isprint(cp[0]) && isprint(cp[1])) + fprintf(log, "\"%s\"\n", cp); + else { + printf("\n"); + print_token(msg_buf); + } + /* Produce a signature block for the message */ #ifdef GSSAPI_V2 if (dov2) @@ -408,6 +418,11 @@ int server_establish_context(s, server_creds, context, client_name) if (recv_token(s, &recv_tok) < 0) return -1; + if (verbose && log) { + fprintf(log, "Received token: \n"); + print_token(&recv_tok); + } + maj_stat = gss_accept_sec_context(&min_stat, context, @@ -428,8 +443,13 @@ int server_establish_context(s, server_creds, context, client_name) } (void) gss_release_buffer(&min_stat, &recv_tok); - if (send_tok.length != 0) { + if (verbose && log) { + fprintf(log, + "Sending accept_sec_context token (size=%d)...", + send_tok.length); + print_token(&send_tok); + } if (send_token(s, &send_tok) < 0) { fprintf(log, "failure sending token\n"); return -1; @@ -437,6 +457,13 @@ int server_establish_context(s, server_creds, context, client_name) (void) gss_release_buffer(&min_stat, &send_tok); } + if (maj_stat == GSS_S_CONTINUE_NEEDED) + if (log) + fprintf(log, "continue needed..."); + if (log) { + fprintf(log, "\n"); + fflush(log); + } } while (maj_stat == GSS_S_CONTINUE_NEEDED); maj_stat = gss_display_name(&min_stat, client, client_name, &doid); @@ -452,5 +479,42 @@ int server_establish_context(s, server_creds, context, client_name) return 0; } - +static float timeval_subtract(struct timeval *tv1, + struct timeval *tv2) +{ + return ((tv1->tv_sec - tv2->tv_sec) + + ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000); +} +int test_import_export_context(context) + gss_ctx_id_t *context; +{ + OM_uint32 min_stat, maj_stat; + gss_buffer_desc context_token; + struct timeval tm1, tm2; + + /* + * Attempt to save and then restore the context. + */ + gettimeofday(&tm1); + maj_stat = gss_export_sec_context(&min_stat, context, &context_token); + if (maj_stat != GSS_S_COMPLETE) { + display_status("exporting context", maj_stat, min_stat); + return 1; + } + gettimeofday(&tm2); + if (verbose && log) + fprintf(log, "Exported context: %d bytes, %7.4f seconds\n", + context_token.length, timeval_subtract(&tm2, &tm1)); + maj_stat = gss_import_sec_context(&min_stat, &context_token, context); + if (maj_stat != GSS_S_COMPLETE) { + display_status("importing context", maj_stat, min_stat); + return 1; + } + gettimeofday(&tm1); + if (verbose && log) + fprintf(log, "Importing context: %7.4f seconds\n", + timeval_subtract(&tm1, &tm2)); + (void) gss_release_buffer(&min_stat, &context_token); + return 0; +} |