gss-server.c (sign_server): Do better import/export security checking.
authorTheodore Tso <tytso@mit.edu>
Sat, 2 Mar 1996 08:08:14 +0000 (08:08 +0000)
committerTheodore Tso <tytso@mit.edu>
Sat, 2 Mar 1996 08:08:14 +0000 (08:08 +0000)
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.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7583 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/gss-sample/ChangeLog
src/appl/gss-sample/gss-client.c
src/appl/gss-sample/gss-misc.c
src/appl/gss-sample/gss-server.c

index 20c8b64d1893e7c693b7e79d9e916d6cd86cf6c7..109d1aa39c70cda54da2412a957f3049dab0341e 100644 (file)
@@ -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
index 986a7968cd308c90ef6890147aa12657ae478487..2f58d1e8f958f1386c6d363c80872f89ac1d9429 100644 (file)
  */
 
 #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>
 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);
+}
+
index 2801212cf5a2595b966b326f6e671e50a2714908..446aa3087c461a00c5f6b710ead40abbcb439f2e 100644 (file)
@@ -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);
+}
+
+    
+    
index 4d0a03c854a4afd10781be24aa6c518450c6ff72..8e7bc928694cb64f4aef6ff3770e95ea3a309d61 100644 (file)
@@ -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;
+}