A near complete re-write of the gss sample client on windows. Supports the
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 31 Jan 2004 00:00:51 +0000 (00:00 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 31 Jan 2004 00:00:51 +0000 (00:00 +0000)
current protocol implemented in the Unix gss sample applications as well as
a new User Interface making this one neat testing tool.

There are still many little kinks to get out in a future version.  The sliders
for the Call Count and the Message Count do not have text strings indicating
their current value.  They slide from 1 to 20.  And the known Mechanism
strings should be accessible in the drop down list.

A documentation file on how to use the tool would be a good addition.

ticket: 2144
tags: pullup

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

src/windows/gss/ChangeLog
src/windows/gss/Makefile.in
src/windows/gss/gss-client.c
src/windows/gss/gss-misc.c
src/windows/gss/gss.c
src/windows/gss/gss.h
src/windows/gss/gss.rc
src/windows/gss/resource.h [new file with mode: 0644]

index b426555a37ccad52f7b40dfc753d5bef60aa30c6..e989480f25da1a7275784c909b5ce697986077fa 100644 (file)
@@ -1,3 +1,14 @@
+2004-01-30  Jeffrey Altman <jaltman@mit.edu>
+
+    * resource.h: new file containing new ui component id values
+    
+    * gss.rc: new user interface definition
+
+    * gss.h, gss-misc.c, gss-client.c: Updates to support new UI and 
+      corrections to add compatibility with the Unix gss-server
+
+    * Makefile: add linkage to comctl32.lib
+
 2002-06-13  Ken Raeburn  <raeburn@mit.edu>
 
        * Makefile.in (SYSLIBS): Use ws2_32.lib instead of wsock32.lib.
index b545599aeb45db83e5d3d532a7253cbf909e2459..c88452667a863d8c789afc6e855b85049a8ec50a 100644 (file)
@@ -17,7 +17,7 @@ RCFLAGS       = $(RFLAGS) -D_WIN32 -DGSS_APP
 ##### Linker
 LINK   = link
 LIBS   = $(GLIB) $(CLIB) $(WLIB)
-SYSLIBS        = kernel32.lib ws2_32.lib user32.lib gdi32.lib comdlg32.lib
+SYSLIBS        = kernel32.lib ws2_32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib
 LFLAGS = /nologo $(LOPTS)
 
 all:: Makefile $(OUTPRE)gss.exe
index d5e8972b311072fbfc6510b1a38bc308a997c42b..848f226cded9ba2a8f4c44f9546f7f86350343f6 100644 (file)
@@ -9,7 +9,7 @@
  * in advertising or publicity pertaining to distribution of the software
  * without specific, written prior permission. OpenVision makes no
  * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
+ * purpose.  It is provided "as is" without express or implied warranty.
  * 
  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include "gss.h"
-
-static const gss_OID_desc oids[] = {
-   {10, "\052\206\110\206\367\022\001\002\001\004"},
-};
-
-const gss_OID_desc * nt_service_name = oids+0;
-
-int
-gss (char *host, char *name, char *oid, char *msg, int port)
-{
-       if (port == 0 || port == -1)
-        port = 4444;
-
-    if (call_server(host, port, name, oid, msg) < 0)
-        return 1;
-
-    return 0;
-}
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+#include <winsock.h>
 
-/*+
- * Function: call_server
- *
- * Purpose: Call the "sign" service.
- *
- * Arguments:
- *
- *             host                    (r) the host providing the service
- *             port                    (r) the port to connect to on host
- *             service_name    (r) the GSS-API service name to authenticate to 
- *             msg                             (r) the message to have "signed"
- *
- * Returns: 0 on success, -1 on failure
- *
- * Effects:
- * 
- * call_server opens a TCP connection to <host:port> and establishes a
- * GSS-API context with service_name over the connection.  It then
- * seals msg in a GSS-API token with gss_seal, sends it to the server,
- * reads back a GSS-API signature block for msg from the server, and
- * verifies it with gss_verify.         -1 is returned if any step fails,
- * otherwise 0 is returned.
- */
-int
-call_server (char *host, u_short port, char *service_name, char *oid, char *msg)
-{
-    gss_ctx_id_t context;
-    gss_buffer_desc in_buf, out_buf;
-    int s, state;
-    OM_uint32 maj_stat, min_stat;
-
-    /* Open connection */
-    if ((s = connect_to_server(host, port)) < 0)
-        return -1;
-
-    /* Establish context */
-    if (client_establish_context(s, service_name, oid, &context) < 0)
-        return -1;
-
-    /* Seal the message */
-    in_buf.value = msg;
-    in_buf.length = strlen(msg) + 1;
-    maj_stat = gss_seal(&min_stat, context, 1, GSS_C_QOP_DEFAULT,
-        &in_buf, &state, &out_buf);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("sealing message", maj_stat, min_stat);
-        return -1;
-    } else if (! state) {
-        OkMsgBox ("Warning!  Message not encrypted.\n");
-    }
-
-    /* Send to server */
-    if (send_token(s, &out_buf) < 0)
-        return -1;
-    (void) gss_release_buffer(&min_stat, &out_buf);
-
-    /* Read signature block into out_buf */
-    if (recv_token(s, &out_buf) < 0)
-        return -1;
-
-    /* Verify signature block */
-    maj_stat = gss_verify(&min_stat, context, &in_buf, &out_buf, &state);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("verifying signature", maj_stat, min_stat);
-        return -1;
-    }
-    (void) gss_release_buffer(&min_stat, &out_buf);
-
-    OkMsgBox ("Signature verified.");
-
-    /* Delete context */
-    maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("deleting context", maj_stat, min_stat);
-        return -1;
-    }
-    (void) gss_release_buffer(&min_stat, &out_buf);
+#include <gssapi/gssapi_generic.h>
+#include "gss.h"
+#include "gss-misc.h"
 
-    closesocket(s);
-        
-    return 0;
-}
+static int verbose = 1;
 
-/*+
+/*
  * Function: connect_to_server
  *
  * Purpose: Opens a TCP connection to the name host and port.
  *
  * Arguments:
  *
- *             host                    (r) the target host name
- *             port                    (r) the target port, in host byte order
+ *     host            (r) the target host name
+ *     port            (r) the target port, in host byte order
  *
  * Returns: the established socket file desciptor, or -1 on failure
  *
@@ -141,34 +50,36 @@ call_server (char *host, u_short port, char *service_name, char *oid, char *msg)
  * opened and connected.  If an error occurs, an error message is
  * displayed and -1 is returned.
  */
-int
-connect_to_server (char *host, u_short port)
+static int connect_to_server(host, port)
+     char *host;
+     u_short port;
 {
-    struct sockaddr_in saddr;
-    struct hostent *hp;
-    int s;
-        
-    if ((hp = gethostbyname(host)) == NULL) {
-        OkMsgBox ("Unknown host: %s\n", host);
-        return -1;
-    }
-        
-    saddr.sin_family = hp->h_addrtype;
-    memcpy((char *)&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr));
-    saddr.sin_port = htons(port);
+     struct sockaddr_in saddr;
+     struct hostent *hp;
+     int s;
+     
+     if ((hp = gethostbyname(host)) == NULL) {
+         printf("Unknown host: %s\r\n", host);
+         return -1;
+     }
+     
+     saddr.sin_family = hp->h_addrtype;
+     memcpy((char *)&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr));
+     saddr.sin_port = htons(port);
 
-    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        my_perror("creating socket");
-        return -1;
-    }
-    if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
-        my_perror("connecting to server");
-        return -1;
-    }
-    return s;
+     if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+         perror("creating socket");
+         return -1;
+     }
+     if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
+         perror("connecting to server");
+         (void) closesocket(s);
+         return -1;
+     }
+     return s;
 }
 
-/*+
+/*
  * Function: client_establish_context
  *
  * Purpose: establishes a GSS-API context with a specified service and
@@ -176,15 +87,19 @@ connect_to_server (char *host, u_short port)
  *
  * Arguments:
  *
- *             s                               (r) an established TCP connection to the service
- *             sname           (r) the ASCII service name of the service
- *             context                 (w) the established GSS-API context
+ *     s               (r) an established TCP connection to the service
+ *     service_name    (r) the ASCII service name of the service
+ *     deleg_flag      (r) GSS-API delegation flag (if any)
+ *     auth_flag       (r) whether to actually do authentication
+ *     oid             (r) OID of the mechanism to use
+ *     context         (w) the established GSS-API context
+ *     ret_flags       (w) the returned flags from init_sec_context
  *
  * Returns: 0 on success, -1 on failure
  *
  * Effects:
  * 
- * sname is imported as a GSS-API name and a GSS-API context is
+ * service_name is imported as a GSS-API name and a GSS-API context is
  * established with the corresponding service; the service should be
  * listening on the TCP connection s.  The default GSS-API mechanism
  * is used, and mutual authentication and replay detection are
@@ -194,100 +109,467 @@ connect_to_server (char *host, u_short port)
  * unsuccessful, the GSS-API error messages are displayed on stderr
  * and -1 is returned.
  */
-int
-client_establish_context (int s, char *sname, char *oid_name,
-                         gss_ctx_id_t *gss_context)
+int client_establish_context( int s, 
+                              char *service_name,
+                              OM_uint32 deleg_flag, 
+                              int auth_flag,
+                              int v1_format, 
+                              gss_OID oid, 
+                              gss_ctx_id_t *gss_context, 
+                              OM_uint32 *ret_flags)
 {
-    gss_buffer_desc send_tok, recv_tok, *token_ptr;
-    gss_name_t target_name;
-    OM_uint32 maj_stat, min_stat;
-    gss_OID oid = GSS_C_NULL_OID;
+    if (auth_flag) {
+        gss_buffer_desc send_tok, recv_tok, *token_ptr;
+        gss_name_t target_name;
+        OM_uint32 maj_stat, min_stat, init_sec_min_stat;
+        int token_flags;
 
-    if (oid_name && oid_name[0]) {
-           send_tok.value = oid_name;
-           send_tok.length = strlen(oid_name);
-           maj_stat = gss_str_to_oid(&min_stat, &send_tok, &oid);
-           if (maj_stat != GSS_S_COMPLETE) {
-                   display_status("str_to_oid", maj_stat, min_stat);
-                   return -1;
-           }
-    }
-
-    /*
-     * Import the name into target_name.  Use send_tok to save
-     * local variable space.
-     */
-    send_tok.value = sname;
-    send_tok.length = strlen(sname) + 1;
-    maj_stat = gss_import_name(&min_stat, &send_tok,
-        (gss_OID) nt_service_name, &target_name);
-    if (maj_stat != GSS_S_COMPLETE) {
-        display_status("parsing name", maj_stat, min_stat);
-        return -1;
-    }
-        
-       /*
-        * Perform the context-establishement loop.
-        *
-        * On each pass through the loop, token_ptr points to the token
-        * to send to the server (or GSS_C_NO_BUFFER on the first pass).
-        * Every generated token is stored in send_tok which is then
-        * transmitted to the server; every received token is stored in
-        * recv_tok, which token_ptr is then set to, to be processed by
-        * the next call to gss_init_sec_context.
-        * 
-        * GSS-API guarantees that send_tok's length will be non-zero
-        * if and only if the server is expecting another token from us,
-        * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if
-        * and only if the server has another token to send us.
-        */
-        
-    token_ptr = GSS_C_NO_BUFFER;
-    *gss_context = GSS_C_NO_CONTEXT;
-
-    do {
-        maj_stat =
-            gss_init_sec_context(&min_stat,
-                                            GSS_C_NO_CREDENTIAL,
-                                                                gss_context,
-                                                                target_name,
-                                                                oid,
-                                                                GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
-                                                                0,
-                                                                NULL,          /* no channel bindings */
-                                                                token_ptr,
-                                                                NULL,          /* ignore mech type */
-                                                                &send_tok,
-                                                                NULL,          /* ignore ret_flags */
-                                                                NULL);         /* ignore time_rec */
-
-        if (token_ptr != GSS_C_NO_BUFFER)
-            (void) gss_release_buffer(&min_stat, &recv_tok);
-
-        if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {
-            display_status("initializing context", maj_stat, min_stat);
-            (void) gss_release_name(&min_stat, &target_name);
+       /*
+        * Import the name into target_name.  Use send_tok to save
+        * local variable space.
+        */
+        send_tok.value = service_name;
+        send_tok.length = strlen(service_name) ;
+        maj_stat = gss_import_name(&min_stat, &send_tok,
+                                    (gss_OID) gss_nt_service_name, &target_name);
+        if (maj_stat != GSS_S_COMPLETE) {
+            display_status("parsing name", maj_stat, min_stat);
             return -1;
         }
-
-        if (send_tok.length != 0) {
-            if (send_token(s, &send_tok) < 0) {
-                (void) gss_release_buffer(&min_stat, &send_tok);
+     
+        if (!v1_format) {
+            if (send_token(s, TOKEN_NOOP|TOKEN_CONTEXT_NEXT, empty_token) < 0) {
                 (void) gss_release_name(&min_stat, &target_name);
                 return -1;
             }
         }
-        (void) gss_release_buffer(&min_stat, &send_tok);
-                 
-        if (maj_stat == GSS_S_CONTINUE_NEEDED) {
-            if (recv_token(s, &recv_tok) < 0) {
+
+       /*
+        * Perform the context-establishement loop.
+        *
+        * On each pass through the loop, token_ptr points to the token
+        * to send to the server (or GSS_C_NO_BUFFER on the first pass).
+        * Every generated token is stored in send_tok which is then
+        * transmitted to the server; every received token is stored in
+        * recv_tok, which token_ptr is then set to, to be processed by
+        * the next call to gss_init_sec_context.
+        * 
+        * GSS-API guarantees that send_tok's length will be non-zero
+        * if and only if the server is expecting another token from us,
+        * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if
+        * and only if the server has another token to send us.
+        */
+
+        token_ptr = GSS_C_NO_BUFFER;
+        *gss_context = GSS_C_NO_CONTEXT;
+
+        do {
+            maj_stat =
+                gss_init_sec_context(&init_sec_min_stat,
+                                      GSS_C_NO_CREDENTIAL,
+                                      gss_context,
+                                      target_name,
+                                      oid,
+                                      GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+                                      deleg_flag,
+                                      0,
+                                      NULL,    /* no channel bindings */
+                                      token_ptr,
+                                      NULL,    /* ignore mech type */
+                                      &send_tok,
+                                      ret_flags,
+                                      NULL);   /* ignore time_rec */
+
+            if (token_ptr != GSS_C_NO_BUFFER)
+                free (recv_tok.value);
+
+            if (send_tok.length != 0) {
+                if (verbose)
+                    printf("Sending init_sec_context token (size=%d)...",
+                            (int) send_tok.length);
+                if (send_token(s, v1_format?0:TOKEN_CONTEXT, &send_tok) < 0) {
+                    (void) gss_release_buffer(&min_stat, &send_tok);
+                    (void) gss_release_name(&min_stat, &target_name);
+                    return -1;
+                }
+            }
+            (void) gss_release_buffer(&min_stat, &send_tok);
+
+            if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {
+                display_status("initializing context", maj_stat,
+                                init_sec_min_stat);
                 (void) gss_release_name(&min_stat, &target_name);
+                if (*gss_context != GSS_C_NO_CONTEXT)
+                    gss_delete_sec_context(&min_stat, gss_context,
+                                            GSS_C_NO_BUFFER);
                 return -1;
             }
-            token_ptr = &recv_tok;
-        }
-    } while (maj_stat == GSS_S_CONTINUE_NEEDED);
 
-    (void) gss_release_name(&min_stat, &target_name);
+            if (maj_stat == GSS_S_CONTINUE_NEEDED) {
+                if (verbose)
+                    printf("continue needed...");
+                if (recv_token(s, &token_flags, &recv_tok) < 0) {
+                    (void) gss_release_name(&min_stat, &target_name);
+                    return -1;
+                }
+                token_ptr = &recv_tok;
+            }
+            if (verbose)
+                printf("\r\n");
+        } while (maj_stat == GSS_S_CONTINUE_NEEDED);
+
+        (void) gss_release_name(&min_stat, &target_name);
+    }
+    else {
+        if (send_token(s, TOKEN_NOOP, empty_token) < 0)
+            return -1;
+    }
+
     return 0;
 }
+
+static void read_file(file_name, in_buf)
+    char               *file_name;
+    gss_buffer_t       in_buf;
+{
+    int fd, count;
+    struct stat stat_buf;
+    
+    if ((fd = open(file_name, O_RDONLY, 0)) < 0) {
+       perror("open");
+       printf("Couldn't open file %s\r\n", file_name);
+       exit(1);
+    }
+    if (fstat(fd, &stat_buf) < 0) {
+       perror("fstat");
+       exit(1);
+    }
+    in_buf->length = stat_buf.st_size;
+
+    if (in_buf->length == 0) {
+       in_buf->value = NULL;
+       return;
+    }
+
+    if ((in_buf->value = malloc(in_buf->length)) == 0) {
+       printf("Couldn't allocate %d byte buffer for reading file\r\n",
+               (int) in_buf->length);
+       exit(1);
+    }
+
+    /* this code used to check for incomplete reads, but you can't get
+       an incomplete read on any file for which fstat() is meaningful */
+
+    count = read(fd, in_buf->value, in_buf->length);
+    if (count < 0) {
+       perror("read");
+       exit(1);
+    }
+    if (count < in_buf->length)
+       printf("Warning, only read in %d bytes, expected %d\r\n",
+               count, (int) in_buf->length);
+}
+
+/*
+ * Function: call_server
+ *
+ * Purpose: Call the "sign" service.
+ *
+ * Arguments:
+ *
+ *     host            (r) the host providing the service
+ *     port            (r) the port to connect to on host
+ *     service_name    (r) the GSS-API service name to authenticate to
+ *     deleg_flag      (r) GSS-API delegation flag (if any)
+ *     auth_flag       (r) whether to do authentication
+ *     wrap_flag       (r) whether to do message wrapping at all
+ *     encrypt_flag    (r) whether to do encryption while wrapping
+ *     mic_flag        (r) whether to request a MIC from the server
+ *     msg             (r) the message to have "signed"
+ *     use_file        (r) whether to treat msg as an input file name
+ *     mcount          (r) the number of times to send the message
+ *
+ * Returns: 0 on success, -1 on failure
+ *
+ * Effects:
+ * 
+ * call_server opens a TCP connection to <host:port> and establishes a
+ * GSS-API context with service_name over the connection.  It then
+ * seals msg in a GSS-API token with gss_wrap, sends it to the server,
+ * reads back a GSS-API signature block for msg from the server, and
+ * verifies it with gss_verify.  -1 is returned if any step fails,
+ * otherwise 0 is returned.  */
+int call_server(char *host, u_short port, gss_OID oid, char *service_name, 
+                OM_uint32 deleg_flag, int auth_flag,
+                       int wrap_flag, int encrypt_flag, int mic_flag, int v1_format, 
+                char *msg, int use_file, int mcount)
+{
+     gss_ctx_id_t context;
+     gss_buffer_desc in_buf, out_buf;
+     int s, state;
+     OM_uint32 ret_flags;
+     OM_uint32 maj_stat, min_stat;
+     gss_name_t                src_name, targ_name;
+     gss_buffer_desc   sname, tname;
+     OM_uint32         lifetime;
+     gss_OID           mechanism, name_type;
+     int               is_local;
+     OM_uint32         context_flags;
+     int               is_open;
+     gss_qop_t         qop_state;
+     gss_OID_set       mech_names;
+     gss_buffer_desc   oid_name;
+     size_t    i;
+     int token_flags;
+
+     /* Open connection */
+     if ((s = connect_to_server(host, port)) < 0)
+         return -1;
+
+     /* Establish context */
+     if (client_establish_context(s, service_name, deleg_flag, auth_flag,
+                                 v1_format, oid, &context,
+                                 &ret_flags) < 0) {
+         (void) closesocket(s);
+         return -1;
+     }
+
+     if (auth_flag) {
+         if (verbose) {
+             /* display the flags */
+             /* display_ctx_flags(ret_flags); */
+
+             /* Get context information */
+             maj_stat = gss_inquire_context(&min_stat, context,
+                                       &src_name, &targ_name, &lifetime,
+                                       &mechanism, &context_flags,
+                                       &is_local,
+                                       &is_open);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("inquiring context", maj_stat, min_stat);
+                 return -1;
+             }
+
+             maj_stat = gss_display_name(&min_stat, src_name, &sname,
+                                          &name_type);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("displaying source name", maj_stat, min_stat);
+                 return -1;
+             }
+             maj_stat = gss_display_name(&min_stat, targ_name, &tname,
+                                          (gss_OID *) NULL);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("displaying target name", maj_stat, min_stat);
+                 return -1;
+             }
+             printf("\"%.*s\" to \"%.*s\", lifetime %d, flags %x, %s, %s\r\n",
+                     (int) sname.length, (char *) sname.value,
+                     (int) tname.length, (char *) tname.value, lifetime,
+                     context_flags,
+                     (is_local) ? "locally initiated" : "remotely initiated",
+                     (is_open) ? "open" : "closed");
+
+             (void) gss_release_name(&min_stat, &src_name);
+             (void) gss_release_name(&min_stat, &targ_name);
+             (void) gss_release_buffer(&min_stat, &sname);
+             (void) gss_release_buffer(&min_stat, &tname);
+
+             maj_stat = gss_oid_to_str(&min_stat,
+                                        name_type,
+                                        &oid_name);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("converting oid->string", maj_stat, min_stat);
+                 return -1;
+             }
+             printf("Name type of source name is %.*s.\r\n",
+                     (int) oid_name.length, (char *) oid_name.value);
+             (void) gss_release_buffer(&min_stat, &oid_name);
+
+             /* Now get the names supported by the mechanism */
+             maj_stat = gss_inquire_names_for_mech(&min_stat,
+                                                    mechanism,
+                                                    &mech_names);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("inquiring mech names", maj_stat, min_stat);
+                 return -1;
+             }
+
+             maj_stat = gss_oid_to_str(&min_stat,
+                                        mechanism,
+                                        &oid_name);
+             if (maj_stat != GSS_S_COMPLETE) {
+                 display_status("converting oid->string", maj_stat, min_stat);
+                 return -1;
+             }
+             printf("Mechanism %.*s supports %d names\r\n",
+                     (int) oid_name.length, (char *) oid_name.value,
+                     (int) mech_names->count);
+             (void) gss_release_buffer(&min_stat, &oid_name);
+
+             for (i=0; i<mech_names->count; i++) {
+                 maj_stat = gss_oid_to_str(&min_stat,
+                                            &mech_names->elements[i],
+                                            &oid_name);
+                 if (maj_stat != GSS_S_COMPLETE) {
+                     display_status("converting oid->string", maj_stat, min_stat);
+                     return -1;
+                 }
+                 printf("  %d: %.*s\r\n", (int) i,
+                         (int) oid_name.length, (char *) oid_name.value);
+
+                 (void) gss_release_buffer(&min_stat, &oid_name);
+             }
+             (void) gss_release_oid_set(&min_stat, &mech_names);
+         }
+     }
+     
+     if (use_file) {
+         read_file(msg, &in_buf);
+     } else {
+        /* Seal the message */
+        in_buf.value = msg;
+        in_buf.length = strlen(msg);
+     }
+
+     for (i = 0; i < mcount; i++) {
+       if (wrap_flag) {
+        maj_stat = gss_wrap(&min_stat, context, encrypt_flag, GSS_C_QOP_DEFAULT,
+                            &in_buf, &state, &out_buf);
+        if (maj_stat != GSS_S_COMPLETE) {
+          display_status("wrapping message", maj_stat, min_stat);
+          (void) closesocket(s);
+          (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+          return -1;
+        } else if (encrypt_flag && ! state) {
+          fprintf(stderr, "Warning!  Message not encrypted.\r\n");
+        }
+       }
+       else {
+        out_buf = in_buf;
+       }
+
+       /* Send to server */
+       if (send_token(s, (v1_format?0
+                         :(TOKEN_DATA |
+                         (wrap_flag ? TOKEN_WRAPPED : 0) |
+                         (encrypt_flag ? TOKEN_ENCRYPTED : 0) |
+                         (mic_flag ? TOKEN_SEND_MIC : 0))), &out_buf) < 0) {
+        (void) closesocket(s);
+        (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+        return -1;
+       }
+       if (out_buf.value != in_buf.value)
+        (void) gss_release_buffer(&min_stat, &out_buf);
+
+       /* Read signature block into out_buf */
+       if (recv_token(s, &token_flags, &out_buf) < 0) {
+        (void) closesocket(s);
+        (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+        return -1;
+       }
+
+       if (mic_flag) {
+        /* Verify signature block */
+        maj_stat = gss_verify_mic(&min_stat, context, &in_buf,
+                                  &out_buf, &qop_state);
+        if (maj_stat != GSS_S_COMPLETE) {
+          display_status("verifying signature", maj_stat, min_stat);
+          (void) closesocket(s);
+          (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+          return -1;
+        }
+
+        if (verbose)
+          printf("Signature verified.\r\n");
+       }
+       else {
+        if (verbose)
+          printf("Response received.\r\n");
+       }
+
+       free (out_buf.value);
+     }
+
+     if (use_file)
+       free(in_buf.value);
+
+     /* Send NOOP */
+     if (!v1_format)
+     (void) send_token(s, TOKEN_NOOP, empty_token);
+
+     if (auth_flag) {
+       /* Delete context */
+       maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf);
+       if (maj_stat != GSS_S_COMPLETE) {
+        display_status("deleting context", maj_stat, min_stat);
+        (void) closesocket(s);
+        (void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
+        return -1;
+       }
+
+       (void) gss_release_buffer(&min_stat, &out_buf);
+     }
+
+     (void) closesocket(s);
+     return 0;
+}
+
+static void parse_oid(char *mechanism, gss_OID *oid)
+{
+    char       *mechstr = 0, *cp;
+    gss_buffer_desc tok;
+    OM_uint32 maj_stat, min_stat;
+    
+    if (isdigit((int) mechanism[0])) {
+       mechstr = malloc(strlen(mechanism)+5);
+       if (!mechstr) {
+           printf("Couldn't allocate mechanism scratch!\r\n");
+           return;
+       }
+       sprintf(mechstr, "{ %s }", mechanism);
+       for (cp = mechstr; *cp; cp++)
+           if (*cp == '.')
+               *cp = ' ';
+       tok.value = mechstr;
+    } else
+       tok.value = mechanism;
+    tok.length = strlen(tok.value);
+    maj_stat = gss_str_to_oid(&min_stat, &tok, oid);
+    if (maj_stat != GSS_S_COMPLETE) {
+       display_status("str_to_oid", maj_stat, min_stat);
+       return;
+    }
+    if (mechstr)
+       free(mechstr);
+}
+
+int
+gss (char *server_host, char *service_name, char *mechanism, char *msg, int port,
+     int verbose, int delegate, int v1_format, int auth_flag, int wrap_flag,
+     int encrypt_flag, int mic_flag, int ccount, int mcount)
+{
+    int use_file = 0;
+    OM_uint32 deleg_flag = (delegate ? GSS_C_DELEG_FLAG : 0), min_stat;
+    gss_OID oid = GSS_C_NULL_OID;
+    int i;
+    int rc = 0;
+
+        if (ccount <= 0)  ccount = 1;
+        if (mcount <= 0)  mcount = 1;
+
+     if (mechanism && mechanism[0])
+         parse_oid(mechanism, &oid);
+
+     for (i = 0; i < ccount; i++) {
+         if (call_server(server_host, port, oid, service_name,
+                         deleg_flag, auth_flag, wrap_flag, encrypt_flag, mic_flag,
+                         v1_format, msg, use_file, mcount) < 0)
+             rc = -1;
+             break;
+     }
+
+    if (oid != GSS_C_NULL_OID)
+        (void) gss_release_oid(&min_stat, &oid);
+        
+    return rc;
+}
index cb84e9327946f1cfa6a969ccc324eaa544a2e415..9ed8109dc2bd571979d06454eef781617020e23d 100644 (file)
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <sys\timeb.h>
+#include <time.h>
 
-/*+
+FILE *display_file;
+DWORD ws_err;
+
+gss_buffer_desc empty_token_buf = { 0, (void *) "" };
+gss_buffer_t empty_token = &empty_token_buf;
+
+static void display_status_1
+       (char *m, OM_uint32 code, int type);
+
+static int write_all(int fildes, char *buf, unsigned int nbyte)
+{
+    int ret;
+    char *ptr;
+
+    for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
+        ret = send(fildes, ptr, nbyte, 0);
+        if (ret < 0) {
+            ws_err = WSAGetLastError();
+            errno = ws_err;
+            return(ret);
+        } else if (ret == 0) {
+            return(ptr-buf);
+        }
+    }
+
+    return(ptr-buf);
+}
+
+static int read_all(int s, char *buf, unsigned int nbyte)
+{
+    int ret;
+    char *ptr;
+    fd_set rfds;
+    struct timeval tv;
+
+    FD_ZERO(&rfds);
+    FD_SET(s, &rfds);
+    tv.tv_sec = 10;
+    tv.tv_usec = 0;
+
+    for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
+        if ( select(FD_SETSIZE, &rfds, NULL, NULL, &tv) <= 0 || !FD_ISSET(s, &rfds) )
+            return(ptr-buf);
+        ret = recv(s, ptr, nbyte, 0);
+        if (ret < 0) {
+            ws_err = WSAGetLastError();
+            errno = ws_err;
+            return(ret);
+        } else if (ret == 0) {
+            return(ptr-buf);
+        }
+    }
+
+    return(ptr-buf);
+}
+
+/*
  * Function: send_token
  *
  * Purpose: Writes a token to a file descriptor.
  *
  * Arguments:
  *
- *     s               (r) an open file descriptor
- *     tok             (r) the token to write
+ *     s               (r) an open file descriptor
+ *     flags           (r) the flags to write
+ *     tok             (r) the token to write
  *
  * Returns: 0 on success, -1 on failure
  *
  * Effects:
  *
- * send_token writes the token length (as a network long) and then the
- * token data to the file descriptor s.         It returns 0 on success, and
- * -1 if an error occurs or if it could not write all the data.
+ * If the flags are non-null, send_token writes the token flags (a
+ * single byte, even though they're passed in in an integer). Next,
+ * the token length (as a network long) and then the token data are
+ * written to the file descriptor s.  It returns 0 on success, and -1
+ * if an error occurs or if it could not write all the data.
  */
-int send_token(int s, gss_buffer_t tok) {
-    long len;
-    size_t ret;
-    size_t ws_err;
+int send_token(int s, int flags, gss_buffer_t tok)
+{
+     int len, ret;
+     unsigned char char_flags = (unsigned char) flags;
+     unsigned char lenbuf[4];
 
-    len = htonl(tok->length);
+     if (char_flags) {
+         ret = write_all(s, (char *)&char_flags, 1);
+         if (ret != 1) {
+             my_perror("sending token flags");
+             OkMsgBox ("Winsock error  %d \n", ws_err);
+             return -1;
+         }
+     }
+    if (tok->length > 0xffffffffUL)
+        abort();
+    lenbuf[0] = (tok->length >> 24) & 0xff;
+    lenbuf[1] = (tok->length >> 16) & 0xff;
+    lenbuf[2] = (tok->length >> 8) & 0xff;
+    lenbuf[3] = tok->length & 0xff;
 
-    ret = send (s, (char *) &len, 4, 0);        // Send length over the socket
+    ret = write_all(s, lenbuf, 4);
     if (ret < 0) {
-               ws_err = WSAGetLastError();
-               errno = ws_err;
-               my_perror("sending token length");
+        my_perror("sending token length");
                OkMsgBox ("Winsock error  %d \n", ws_err);
-               return -1;
+        return -1;
     } else if (ret != 4) {
-           ws_err = WSAGetLastError();
-           OkMsgBox("sending token length: %d of %d bytes written\nWinsock error = %d\n",
-                    ret, 4, ws_err);
-           return -1;
+        if (verbose)
+            printf("sending token length: %d of %d bytes written\r\n", 
+                     ret, 4);
+        return -1;
     }
 
-    ret = send (s, tok->value, tok->length, 0); // Send the data
+    ret = write_all(s, tok->value, tok->length);
     if (ret < 0) {
-           ws_err = WSAGetLastError();
-           errno = ws_err;
-           my_perror("sending token data");
-           OkMsgBox ("Winsock error  %d \n", ws_err);
-           return -1;
+        my_perror("sending token data");
+               OkMsgBox ("Winsock error  %d \n", ws_err);
+        return -1;
     } else if (ret != tok->length) {
-           ws_err = WSAGetLastError();
-           OkMsgBox ("sending token data: %d of %d bytes written\nWinsock error = %d\n",
-                     ret, tok->length, ws_err);
-           return -1;
+        if (verbose)
+            printf("sending token data: %d of %d bytes written\r\n", 
+                     ret, (int) tok->length);
+        return -1;
     }
 
     return 0;
 }
 
-/*+
+/*
  * Function: recv_token
  *
  * Purpose: Reads a token from a file descriptor.
  *
  * Arguments:
  *
- *     s               (r) an open file descriptor
- *     tok             (w) the read token
+ *     s               (r) an open file descriptor
+ *     flags           (w) the read flags
+ *     tok             (w) the read token
  *
  * Returns: 0 on success, -1 on failure
  *
  * Effects:
  * 
- * recv_token reads the token length (as a network long), allocates
- * memory to hold the data, and then reads the token data from the
- * file descriptor s.  It blocks to read the length and data, if
- * necessary.  On a successful return, the token should be freed with
- * gss_release_buffer. It returns 0 on success, and -1 if an error
- * occurs or if it could not read all the data.
+ * recv_token reads the token flags (a single byte, even though
+ * they're stored into an integer, then reads the token length (as a
+ * network long), allocates memory to hold the data, and then reads
+ * the token data from the file descriptor s.  It blocks to read the
+ * length and data, if necessary.  On a successful return, the token
+ * should be freed with gss_release_buffer.  It returns 0 on success,
+ * and -1 if an error occurs or if it could not read all the data.
  */
-int
-recv_token (int s, gss_buffer_t tok) {
+int recv_token(int s, int * flags, gss_buffer_t tok)
+{
     int ret;
-    unsigned long len;
-       size_t ws_err;
+    unsigned char char_flags;
+    unsigned char lenbuf[4];
 
-    ret = recv (s, (char *) &len, 4, 0);
+    ret = read_all(s, (char *) &char_flags, 1);
     if (ret < 0) {
-           ws_err = WSAGetLastError();
-           errno = ws_err;
-           my_perror("reading token length");
-           OkMsgBox ("Winsock error  %d \n", ws_err);
+        my_perror("reading token flags");
+               OkMsgBox ("Winsock error  %d \n", ws_err);
         return -1;
-    } else if (ret != 4) {
-           ws_err = WSAGetLastError();
-           OkMsgBox ("reading token length: %d of %d bytes written\nWinsock error = %d\n",
-                     ret, 4, ws_err);
-           return -1;
+    } else if (! ret) {
+        if (display_file)
+            printf("reading token flags: 0 bytes read\r\n", display_file);
+        return -1;
+    } else {
+        *flags = (int) char_flags;
     }
-         
-    len = ntohl(len);
-    tok->length = (size_t) len;
-    tok->value = (char *) malloc(tok->length);
-    if (tok->value == NULL) {
-        OkMsgBox ("Out of memory allocating token data\n");
+
+    if (char_flags == 0 ) {
+        lenbuf[0] = 0;
+        ret = read_all(s, &lenbuf[1], 3);
+        if (ret < 0) {
+            my_perror("reading token length");
+            OkMsgBox ("Winsock error  %d \n", ws_err);
+            return -1;
+        } else if (ret != 3) {
+            if (verbose)
+                printf("reading token length: %d of %d bytes read\r\n", 
+                         ret, 3);
+            return -1;
+        }
+    }
+    else {
+        ret = read_all(s, lenbuf, 4);
+        if (ret < 0) {
+            my_perror("reading token length");
+            OkMsgBox ("Winsock error  %d \n", ws_err);
+            return -1;
+        } else if (ret != 4) {
+            if (verbose)
+                printf("reading token length: %d of %d bytes read\r\n", 
+                         ret, 4);
+            return -1;
+        }
+    }
+
+    tok->length = ((lenbuf[0] << 24)
+                    | (lenbuf[1] << 16)
+                    | (lenbuf[2] << 8)
+                    | lenbuf[3]);
+    tok->value = (char *) malloc(tok->length ? tok->length : 1);
+    if (tok->length && tok->value == NULL) {
+        if (verbose)
+            printf("Out of memory allocating token data\r\n");
         return -1;
     }
 
-    ret = recv (s, (char *) tok->value, tok->length, 0);
+    ret = read_all(s, (char *) tok->value, tok->length);
     if (ret < 0) {
-           ws_err = WSAGetLastError();
-           errno = ws_err;
-           my_perror("reading token data");
-           OkMsgBox ("Winsock error  %d \n", ws_err);
-           free(tok->value);
-           return -1;
-    } else if ((size_t) ret != tok->length) {
-           ws_err = WSAGetLastError();
-           OkMsgBox ("reading token data: %d of %d bytes written\nWinsock error = %d\n",
-                     ret, tok->length, ws_err);
-           free(tok->value);
-           return -1;
+        my_perror("reading token data");
+               OkMsgBox ("Winsock error  %d \n", ws_err);
+        free(tok->value);
+        return -1;
+    } else if (ret != tok->length) {
+        printf("sending token data: %d of %d bytes written\r\n", 
+                 ret, (int) tok->length);
+        free(tok->value);
+        return -1;
     }
 
     return 0;
 }
 
+void 
+free_token(gss_buffer_t tok)
+{
+    if (tok->length <= 0 || tok->value == NULL)
+        return;
+
+    free(tok->value);
+    tok->value = NULL;
+    tok->length = 0;
+}
+
 /*+
  * Function: display_status
  *
@@ -183,6 +294,9 @@ display_status_1(char *m, OM_uint32 code, int type) {
         maj_stat = gss_display_status(&min_stat, code,
                                       type, GSS_C_NULL_OID,
                                       &msg_ctx, &msg);
+        if (verbose)
+            printf("GSS-API error %s: %s\r\n", m,
+                     (char *)msg.value); 
         OkMsgBox ("GSS-API error %s: %s\n", m,
             (char *)msg.value);
         (void) gss_release_buffer(&min_stat, &msg);
@@ -191,6 +305,70 @@ display_status_1(char *m, OM_uint32 code, int type) {
             break;
     }
 }
+
+/*
+ * Function: display_ctx_flags
+ *
+ * Purpose: displays the flags returned by context initation in
+ *         a human-readable form
+ *
+ * Arguments:
+ *
+ *     int             ret_flags
+ *
+ * Effects:
+ *
+ * Strings corresponding to the context flags are printed on
+ * stdout, preceded by "context flag: " and followed by a newline
+ */
+
+void display_ctx_flags(flags)
+     OM_uint32 flags;
+{
+     if (flags & GSS_C_DELEG_FLAG)
+         printf("context flag: GSS_C_DELEG_FLAG\r\n");
+     if (flags & GSS_C_MUTUAL_FLAG)
+         printf("context flag: GSS_C_MUTUAL_FLAG\r\n");
+     if (flags & GSS_C_REPLAY_FLAG)
+         printf("context flag: GSS_C_REPLAY_FLAG\r\n");
+     if (flags & GSS_C_SEQUENCE_FLAG)
+         printf("context flag: GSS_C_SEQUENCE_FLAG\r\n");
+     if (flags & GSS_C_CONF_FLAG )
+         printf("context flag: GSS_C_CONF_FLAG \r\n");
+     if (flags & GSS_C_INTEG_FLAG )
+         printf("context flag: GSS_C_INTEG_FLAG \r\n");
+}
+
+void print_token(tok)
+     gss_buffer_t tok;
+{
+    int i;
+    unsigned char *p = tok->value;
+
+    if (!verbose)
+       return;
+    for (i=0; i < tok->length; i++, p++) {
+       printf("%02x ", *p);
+       if ((i % 16) == 15) {
+           printf("\r\n");
+       }
+    }
+    printf("\r\n");
+}
+
+
+int gettimeofday (struct timeval *tv, void *ignore_tz)
+{
+    struct _timeb tb;
+    _tzset();
+    _ftime(&tb);
+    if (tv) {
+       tv->tv_sec = tb.time;
+       tv->tv_usec = tb.millitm * 1000;
+    }
+    return 0;
+}
+
 /*+*************************************************************************
 ** 
 ** OkMsgBox
index 2a9b93dcf6fcf273f7ca4b990774799ca1d3390c..4254211a63c7b6abcd0d5a76ce5b3703b530d64b 100644 (file)
@@ -9,28 +9,63 @@
 #include <windows.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <commctrl.h>
 #include "gss.h"
 
-#define GSS_CONNECT_NAME            102
-#define GSS_OK                      100
-#define GSS_CANCEL                  101
+#include "resource.h"
 
-#define GSSAPI_INI     "kerberos.ini"                          // Which INI file
+#define GSSAPI_INI     "gsstest.ini"                           // Which INI file
 #define INI_HOSTS      "GSSAPI Hosts"                          // INI file section
 #define INI_HOST       "Host"                                          // INI file line label
+#define INI_SVCS       "GSSAPI Services"                       // INI file section
+#define INI_SVC            "Service"                                   // INI file line label
+#define INI_MSGS       "GSSAPI Messages"                       // INI file section
+#define INI_MSG            "Message"                                   // INI file line label
+#define INI_MECHS      "GSSAPI Mechanisms"                     // INI file section
+#define INI_MECH       "Mech"                                          // INI file line label
+#define INI_LAST    "GSSAPI Most Recent" 
+#define INI_LAST_HOST "Host"
+#define INI_LAST_PORT "Port"
+#define INI_LAST_SVC  "Service"
+#define INI_LAST_MECH "Mechanism"
+#define INI_LAST_MSG  "Message"
+#define INI_LAST_DELEGATE  "Delegation"
+#define INI_LAST_VERBOSE   "Verbose"
+#define INI_LAST_CCOUNT    "Call Count"
+#define INI_LAST_MCOUNT    "Message Count"
+#define INI_LAST_VER1      "Version One"
+#define INI_LAST_NOAUTH    "No Auth"
+#define INI_LAST_NOWRAP    "No Wrap"
+#define INI_LAST_NOCRYPT   "No Encrypt"
+#define INI_LAST_NOMIC     "No Mic"
 
-#define MAX_HOSTS 9
-char hosts[MAX_HOSTS][256];
+#define MAX_SAVED 9
+char hosts[MAX_SAVED][256];
+char svcs[MAX_SAVED][256];
+char msgs[MAX_SAVED][256];
+char mechs[MAX_SAVED][256];
 char szHost[256];                      // GSSAPI Host to connect to
-char szServiceName[256];               // Service to do
-char szOID[256];                       // OID to use   
+char szService[256];           // Service to do
+char szMessage[256];        // Message to send
+char szMech[256];                      // OID to use
 int port = 0;                          // Which port to use
+int delegate = 0;           // Delegate?
+int verbose = 1;            // Verbose?
+int ccount = 1;             // Call Count
+int mcount = 1;             // Message Count
+int gssv1 = 0;              // Version 1?
+int noauth = 0;             // No Auth?
+int nowrap = 0;             // No Wrap?
+int nocrypt = 0;            // No Crypt?
+int nomic = 0;              // No Mic?
 
-static void do_gssapi_test (char *name);
+HWND hDialog = 0;
+
+static void do_gssapi_test (void);
 static void parse_name (char *name);
-static int read_hosts(void);
-static void write_hosts (void);
-static void    update_hosts (char *name);
+static void read_saved(void);
+static void write_saved (void);
+static void    update_saved (void);
 static void fill_combo (HWND hDlg);
 
 /*+*************************************************************************
@@ -40,17 +75,15 @@ static void fill_combo (HWND hDlg);
 ** Sets up the Dialog that drives our program
 **
 ***************************************************************************/
-int PASCAL
-WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
-HANDLE hInstance, hPrevInstance;
-LPSTR lpszCmdLine;
-int nCmdShow;
+int __stdcall
+WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
 {
-       FARPROC lpfnDlgProc;
        WSADATA wsadata;
        WORD versionrequested;
        int rc;
 
+       InitCommonControls();
+
        versionrequested = 0x0101;              /* Version 1.1 */
        rc = WSAStartup(versionrequested, &wsadata);
        if (rc) {
@@ -65,9 +98,8 @@ int nCmdShow;
            return FALSE;
        }
        
-       lpfnDlgProc = MakeProcInstance(OpenGssapiDlg, hInstance);
-       DialogBox (hInstance, "OPENGSSAPIDLG", NULL, lpfnDlgProc);
-       FreeProcInstance(lpfnDlgProc);
+       rc = DialogBoxParam (hInstance, "GSSAPIDLG", HWND_DESKTOP, OpenGssapiDlg, 0L);
+       rc = GetLastError();
 
        WSACleanup();
        return 0;
@@ -80,14 +112,13 @@ int nCmdShow;
 **
 ***************************************************************************/
 void
-do_gssapi_test (char *name) {
+do_gssapi_test (void) {
        int n;                                                                          // Return value
        HCURSOR hcursor;                                                        // For the hourglass cursor
 
-       parse_name(name);                                                       // Get host, service and port
-
        hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
-       n = gss (szHost, szServiceName, szOID, "Test Gssapi Message", port);
+       n = gss (szHost, szService, szMech, szMessage[0] ? szMessage : "Test Gssapi Message", port,
+             verbose, delegate, gssv1, !noauth, !nowrap, !nocrypt, !nomic, ccount, mcount);
        SetCursor(hcursor);
 
        if (n)
@@ -105,19 +136,21 @@ do_gssapi_test (char *name) {
 **     WM_COMMAND    - Input received
 **
 ***************************************************************************/
-BOOL PASCAL
+INT_PTR CALLBACK
 OpenGssapiDlg(
        HWND hDlg,
-       WORD message,
-       WORD wParam,
-       LONG lParam)
+       UINT message,
+       WPARAM wParam,
+       LPARAM lParam)
 {
        HDC hDC;                                                                        // For getting graphic info
        DWORD Ext;                                                                      // Size of dialog
        int xExt, yExt;                                                         // Size broken apart
-       char hostname[256];                                                     // What the user typed
+    char buff[32];
+
        switch (message) {
        case WM_INITDIALOG:
+        hDialog = hDlg;
                /*
                ** First center the dialog
                */
@@ -131,10 +164,11 @@ OpenGssapiDlg(
                        0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
                ReleaseDC(hDlg, hDC);
 
-               read_hosts ();                                                  // Get the host list
+        SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_LIMITTEXT, sizeof(szHost), 0);
+               read_saved ();                                                  // Get the host list
                fill_combo (hDlg);                                              // Put into combo box
 
-               SendMessage(hDlg, WM_SETFOCUS, NULL, NULL);
+               SendMessage(hDlg, WM_SETFOCUS, 0, 0);
                return (TRUE);
 
        case WM_COMMAND:
@@ -145,22 +179,71 @@ OpenGssapiDlg(
                        break;
 
                case GSS_OK:
-                       GetDlgItemText(hDlg, GSS_CONNECT_NAME, hostname, 256);
-                       SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_SHOWDROPDOWN,
-                               FALSE, NULL);
+                       GetDlgItemText(hDlg, GSS_HOST_NAME, szHost, 256);
+                       SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_SHOWDROPDOWN, FALSE, 0);
+
+                       if (!*szHost) {
+                               MessageBox(hDlg, "You must enter a host name", NULL, MB_OK);
+                               break;
+                       }
+
+                       GetDlgItemText(hDlg, GSS_SERVICE_NAME, szService, 256);
+                       SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_SHOWDROPDOWN, FALSE, 0);
 
-                       if (! *hostname) {
-                               MessageBox(hDlg, "You must enter a host name",
-                                       NULL, MB_OK);
+                       if (!*szService) {
+                               MessageBox(hDlg, "You must enter a service name", NULL, MB_OK);
                                break;
                        }
-                       do_gssapi_test (hostname);                      // Test GSSAPI
-                       update_hosts (hostname);                        // Add it to the host list
+
+            GetDlgItemText(hDlg, GSS_MECHANISM, szMech, 256);
+            GetDlgItemText(hDlg, GSS_MESSAGE, szMessage, 256);
+            GetDlgItemText(hDlg, GSS_PORT, buff, 32);
+            if (!*buff) {
+                               MessageBox(hDlg, "You must enter a valid port number", NULL, MB_OK);
+                               break;
+            }
+            port = atoi(buff);
+            if (port == 0 || port == -1)
+                port = 4444;
+
+            ccount = SendDlgItemMessage( hDlg, GSS_CALL_COUNT, TBM_GETPOS, 0, 0);
+            mcount = SendDlgItemMessage( hDlg, GSS_MESSAGE_COUNT, TBM_GETPOS, 0, 0);
+
+            verbose = IsDlgButtonChecked(hDlg, GSS_VERBOSE);
+            delegate = IsDlgButtonChecked(hDlg, GSS_DELEGATION);
+            gssv1 = IsDlgButtonChecked(hDlg, GSS_VERSION_ONE);
+
+            noauth = IsDlgButtonChecked(hDlg, GSS_NO_AUTH);
+            if ( noauth ) {
+                nowrap = nocrypt = nomic = 0;
+            } else {
+                nowrap = IsDlgButtonChecked(hDlg, GSS_NO_WRAP);
+                nocrypt = IsDlgButtonChecked(hDlg, GSS_NO_ENCRYPT);
+                nomic = IsDlgButtonChecked(hDlg, GSS_NO_MIC);
+            }
+
+                       update_saved ();                                // Add it to the host list
                        fill_combo (hDlg);                                      // Update the combo box
+            SetDlgItemText(hDlg, GSS_OUTPUT, "", 0);
+            do_gssapi_test ();                         // Test GSSAPI
 
                        //EndDialog(hDlg, TRUE);
                        break;
-               }
+               
+        case GSS_NO_AUTH:
+            if ( IsDlgButtonChecked(hDlg, GSS_NO_AUTH) ) {
+                // disable the other no_xxx options
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), FALSE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), FALSE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), FALSE);
+            } else {
+                // enable the other no_xxx options
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), TRUE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), TRUE);
+                EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), TRUE);
+            }
+            break;
+        }
                return FALSE;
        }
        return FALSE;
@@ -199,84 +282,204 @@ parse_name (char *name) {
            ptr = strtok( NULL, seps);
        }
        if( ptr ){
-           strcpy( szServiceName, ptr );
+           strcpy( szService, ptr );
        }else{
-           wsprintf (szServiceName, "sample@%s", szHost); // Make the service name
+           wsprintf (szService, "sample@%s", szHost); // Make the service name
        }
        if( ptr ){
            ptr = strtok( NULL, seps);
        }
        if( ptr ){
-           wsprintf (szOID, "{ %s }", ptr); // Put in the OID
-           for (ptr = szOID; *ptr; ptr++)
+           wsprintf (szMech, "{ %s }", ptr); // Put in the OID
+           for (ptr = szMech; *ptr; ptr++)
                    if (*ptr == '.')
                            *ptr = ' ';
     } else {
-          szOID[0] = 0;
+          szMech[0] = 0;
        }
 
 }
 /*+*************************************************************************
 **
-** Read_hosts
+** read_saved
 **
 ** Reads all the hosts listed in the INI file.
 **
 ***************************************************************************/
-static int
-read_hosts (void) {
+static void
+read_saved (void) {
        int i;                                  /* Index */
-       char buff[10];
+       char buff[32];
        
-       for (i = 0; MAX_HOSTS; ++i) {           /* Read this many entries */
+       for (i = 0; MAX_SAVED; ++i) {           /* Read this many entries */
                wsprintf (buff, INI_HOST "%d", i);
                GetPrivateProfileString(INI_HOSTS, buff, "", hosts[i], 256, GSSAPI_INI);
                if (*hosts[i] == '\0')          /* No more entries??? */
                        break;
        }
-
-       return i;
+       for (i = 0; MAX_SAVED; ++i) {           /* Read this many entries */
+               wsprintf (buff, INI_SVC "%d", i);
+               GetPrivateProfileString(INI_SVCS, buff, "", svcs[i], 256, GSSAPI_INI);
+               if (*svcs[i] == '\0')           /* No more entries??? */
+                       break;
+       }
+       for (i = 0; MAX_SAVED; ++i) {           /* Read this many entries */
+               wsprintf (buff, INI_MSG "%d", i);
+               GetPrivateProfileString(INI_MSGS, buff, "", msgs[i], 256, GSSAPI_INI);
+               if (*msgs[i] == '\0')           /* No more entries??? */
+                       break;
+       }
+       for (i = 0; MAX_SAVED; ++i) {           /* Read this many entries */
+               wsprintf (buff, INI_MECH "%d", i);
+               GetPrivateProfileString(INI_MECHS, buff, "", mechs[i], 256, GSSAPI_INI);
+               if (*mechs[i] == '\0')          /* No more entries??? */
+                       break;
+       }
+    GetPrivateProfileString(INI_LAST, INI_LAST_HOST, "", szHost, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_PORT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        port = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_SVC, "", szService, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_MSG, "", szMessage, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_MECH, "", szMech, 256, GSSAPI_INI);
+    GetPrivateProfileString(INI_LAST, INI_LAST_DELEGATE, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        delegate = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_VERBOSE, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        verbose = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_CCOUNT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        ccount = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_MCOUNT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        mcount = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_VER1, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        gssv1 = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOAUTH, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        noauth = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOWRAP, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        nowrap = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOCRYPT, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        nocrypt = atoi(buff);
+    GetPrivateProfileString(INI_LAST, INI_LAST_NOMIC, "", buff, 32, GSSAPI_INI);
+    if ( buff[0] )  
+        nomic = atoi(buff);
 }
+
 /*+*************************************************************************
 **
-** Write_hosts
+** write_saved
 **
 ** Writes the hosts list back to the ini file.
 **
 ***************************************************************************/
 static void
-write_hosts () {
+write_saved () {
        int i;                                                                          // Index
-       char buff[10];
+       char buff[32];
 
-       for (i = 0; i < MAX_HOSTS; ++i) {
+       for (i = 0; i < MAX_SAVED; ++i) {
                if (*hosts[i] == '\0')                                  // End of the list?
                        break;
                wsprintf (buff, INI_HOST "%d", i);
                WritePrivateProfileString(INI_HOSTS, buff, hosts[i], GSSAPI_INI);
        }
+       for (i = 0; i < MAX_SAVED; ++i) {
+               if (*svcs[i] == '\0')                                   // End of the list?
+                       break;
+               wsprintf (buff, INI_SVC "%d", i);
+               WritePrivateProfileString(INI_SVCS, buff, svcs[i], GSSAPI_INI);
+       }
+       for (i = 0; i < MAX_SAVED; ++i) {
+               if (*msgs[i] == '\0')                                   // End of the list?
+                       break;
+               wsprintf (buff, INI_MSG "%d", i);
+               WritePrivateProfileString(INI_MSGS, buff, msgs[i], GSSAPI_INI);
+       }
+       for (i = 0; i < MAX_SAVED; ++i) {
+               if (*mechs[i] == '\0')                                  // End of the list?
+                       break;
+               wsprintf (buff, INI_MECH "%d", i);
+               WritePrivateProfileString(INI_MECHS, buff, mechs[i], GSSAPI_INI);
+       }
+    WritePrivateProfileString(INI_LAST, INI_LAST_HOST, szHost, GSSAPI_INI);
+    wsprintf(buff, "%d", port);
+    WritePrivateProfileString(INI_LAST, INI_LAST_PORT, buff, GSSAPI_INI);
+    WritePrivateProfileString(INI_LAST, INI_LAST_SVC, szService, GSSAPI_INI);
+    WritePrivateProfileString(INI_LAST, INI_LAST_MECH, szMech, GSSAPI_INI);
+    WritePrivateProfileString(INI_LAST, INI_LAST_MSG, szMessage, GSSAPI_INI);
+    wsprintf(buff, "%d", delegate);
+    WritePrivateProfileString(INI_LAST, INI_LAST_DELEGATE, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", verbose);
+    WritePrivateProfileString(INI_LAST, INI_LAST_VERBOSE, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", ccount);
+    WritePrivateProfileString(INI_LAST, INI_LAST_CCOUNT, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", mcount);
+    WritePrivateProfileString(INI_LAST, INI_LAST_MCOUNT, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", gssv1);
+    WritePrivateProfileString(INI_LAST, INI_LAST_VER1, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", noauth);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOAUTH, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", nowrap);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOWRAP, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", nocrypt);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOCRYPT, buff, GSSAPI_INI);
+    wsprintf(buff, "%d", nomic);
+    WritePrivateProfileString(INI_LAST, INI_LAST_NOMIC, buff, GSSAPI_INI);
 }
 /*+*************************************************************************
 **
-** Update_hosts
+** Update_saved
 **
 ** Updates the host list with the new NAME the user typed.
 **
 ***************************************************************************/
 static void
-update_hosts (char *name) {
+update_saved (void) {
        int i;                                                                          // Index
 
-       for (i = 0; i < MAX_HOSTS-1; ++i) {                     // Find it in the list
-               if (! _stricmp (name, hosts[i]))                // A match
+       for (i = 0; i < MAX_SAVED-1; ++i) {                     // Find it in the list
+               if (! _stricmp (szHost, hosts[i]))              // A match
                        break;
                if (*hosts[i] == '\0')                                  // End of the list
                        break;
        }
        memmove (hosts[1], hosts[0], i * sizeof(hosts[0])); // Move the data down
-       strcpy (hosts[0], name);                                        // Insert this item
+       strcpy (hosts[0], szHost);                                      // Insert this item
 
-       write_hosts ();
+    for (i = 0; i < MAX_SAVED-1; ++i) {                        // Find it in the list
+               if (! _stricmp (szService, svcs[i]))            // A match
+                       break;
+               if (*svcs[i] == '\0')                                   // End of the list
+                       break;
+       }
+       memmove (svcs[1], svcs[0], i * sizeof(svcs[0])); // Move the data down
+       strcpy (svcs[0], szService);                                    // Insert this item
+
+       for (i = 0; i < MAX_SAVED-1; ++i) {                     // Find it in the list
+               if (! _stricmp (szMessage, msgs[i]))            // A match
+                       break;
+               if (*msgs[i] == '\0')                                   // End of the list
+                       break;
+       }
+       memmove (msgs[1], msgs[0], i * sizeof(msgs[0])); // Move the data down
+       strcpy (msgs[0], szMessage);                                    // Insert this item
+
+       for (i = 0; i < MAX_SAVED-1; ++i) {                     // Find it in the list
+               if (! _stricmp (szMech, mechs[i]))              // A match
+                       break;
+               if (*mechs[i] == '\0')                                  // End of the list
+                       break;
+       }
+       memmove (mechs[1], mechs[0], i * sizeof(hosts[0])); // Move the data down
+       strcpy (mechs[0], szMech);                                      // Insert this item
+
+       write_saved ();
 }
 /*+*************************************************************************
 **
@@ -289,16 +492,88 @@ update_hosts (char *name) {
 static void
 fill_combo (HWND hDlg) {
        int i;                                                                          // Index
+    char buff[32];
 
-       SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_RESETCONTENT, NULL, NULL);
+       SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_RESETCONTENT, 0, 0);
+       SetDlgItemText(hDlg, GSS_HOST_NAME, szHost);
+       SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_SETEDITSEL, 0, 0);
+       for (i = 1; i < MAX_SAVED; ++i) {                       // Fill in the list box
+               if (*hosts[i] == '\0')
+                       break;
+               SendDlgItemMessage(hDlg, GSS_HOST_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) hosts[i]));
+       }
+
+       SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_RESETCONTENT, 0, 0);
+       SetDlgItemText(hDlg, GSS_SERVICE_NAME, szService);
+       SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_SETEDITSEL, 0, 0);
+       for (i = 1; i < MAX_SAVED; ++i) {                       // Fill in the list box
+               if (*svcs[i] == '\0')
+                       break;
+               SendDlgItemMessage(hDlg, GSS_SERVICE_NAME, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) svcs[i]));
+       }
 
-       SetDlgItemText(hDlg, GSS_CONNECT_NAME, hosts[0]);
-       SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_SETEDITSEL, NULL, NULL);
+       SendDlgItemMessage(hDlg, GSS_MECHANISM, CB_RESETCONTENT, 0, 0);
+       SetDlgItemText(hDlg, GSS_MECHANISM, szMech);
+       SendDlgItemMessage(hDlg, GSS_MECHANISM, CB_SETEDITSEL, 0, 0);
+       for (i = 1; i < MAX_SAVED; ++i) {                       // Fill in the list box
+               if (*mechs[i] == '\0')
+                       break;
+               SendDlgItemMessage(hDlg, GSS_MECHANISM, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) mechs[i]));
+       }
 
-       for (i = 1; i < MAX_HOSTS; ++i) {                       // Fill in the list box
-               if (*hosts[i] == '\0')
+       SendDlgItemMessage(hDlg, GSS_MESSAGE, CB_RESETCONTENT, 0, 0);
+       SetDlgItemText(hDlg, GSS_MESSAGE, szMessage);
+       SendDlgItemMessage(hDlg, GSS_MESSAGE, CB_SETEDITSEL, 0, 0);
+       for (i = 1; i < MAX_SAVED; ++i) {                       // Fill in the list box
+               if (*msgs[i] == '\0')
                        break;
-               SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_ADDSTRING, 0,
-                       (LPARAM) ((LPSTR) hosts[i]));
+               SendDlgItemMessage(hDlg, GSS_MESSAGE, CB_ADDSTRING, 0, (LPARAM) ((LPSTR) msgs[i]));
        }
+
+    wsprintf(buff, "%d", port);
+    SetDlgItemText(hDlg, GSS_PORT, buff);
+
+    CheckDlgButton(hDlg, GSS_VERBOSE, verbose);
+    CheckDlgButton(hDlg, GSS_DELEGATION, delegate);
+    CheckDlgButton(hDlg, GSS_VERSION_ONE, gssv1);
+    CheckDlgButton(hDlg, GSS_NO_AUTH, noauth);
+    CheckDlgButton(hDlg, GSS_NO_WRAP, nowrap);
+    CheckDlgButton(hDlg, GSS_NO_ENCRYPT, nocrypt);
+    CheckDlgButton(hDlg, GSS_NO_MIC, nomic);
+
+    if ( noauth ) {
+        // disable the other no_xxx options
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), FALSE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), FALSE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), FALSE);
+    } else {
+        // enable the other no_xxx options
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_WRAP), TRUE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_ENCRYPT), TRUE);
+        EnableWindow(GetDlgItem(hDlg, GSS_NO_MIC), TRUE);
+    }
+
+    SendDlgItemMessage(hDlg, GSS_CALL_COUNT, TBM_SETRANGEMIN, (WPARAM) FALSE, (LPARAM) 0);
+    SendDlgItemMessage(hDlg, GSS_CALL_COUNT, TBM_SETRANGEMAX, (WPARAM) FALSE, (LPARAM) 20);
+    SendDlgItemMessage(hDlg, GSS_CALL_COUNT, TBM_SETPOS, (WPARAM) FALSE, (LPARAM) ccount);
+
+    SendDlgItemMessage(hDlg, GSS_MESSAGE_COUNT, TBM_SETRANGEMIN, (WPARAM) FALSE, (LPARAM) 0);
+    SendDlgItemMessage(hDlg, GSS_MESSAGE_COUNT, TBM_SETRANGEMAX, (WPARAM) FALSE, (LPARAM) 20);
+    SendDlgItemMessage(hDlg, GSS_MESSAGE_COUNT, TBM_SETPOS, (WPARAM) FALSE, (LPARAM) mcount);
+
+}
+
+int
+gss_printf (const char *format, ...) {
+    static char myprtfstr[4096];
+    int i, len, rc=0;
+    char *cp;
+    va_list ap;
+
+    va_start(ap, format);
+    rc = _vsnprintf(myprtfstr, sizeof(myprtfstr)-1, format, ap);
+    va_end(ap);
+
+    SendDlgItemMessage(hDialog, GSS_OUTPUT, EM_REPLACESEL, FALSE, (LPARAM) myprtfstr);
+    return rc;
 }
index e9b43c507097fa2f4c7889941c900c9ef9e8ea25..8dcf4fcd0d6d320343854e8fd96ab75a4b28efac 100644 (file)
 #include <gssapi/gssapi_generic.h>
 
 // gss.c
-BOOL PASCAL OpenGssapiDlg(HWND hDlg, WORD message, WORD wParam, LONG lParam);
+INT_PTR CALLBACK OpenGssapiDlg(        HWND hDlg,      UINT message,   WPARAM wParam,  LPARAM lParam);
 
 // gss-misc.c
-int send_token(int s, gss_buffer_t tok);
-int recv_token(int s, gss_buffer_t tok);
+int send_token(int s, int flags, gss_buffer_t tok);
+int recv_token(int s, int *flags, gss_buffer_t tok);
+void free_token(gss_buffer_t tok);
 void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat);
 static void display_status_1(char *m, OM_uint32 code, int type);
 void OkMsgBox (char *format, ...);
 void my_perror (char *msg);
 
 // gss-client.c
-int gss (char *host, char *name, char *msg, char *oid, int port);
-int call_server(char *host, u_short port, char *service_name, char *oid, char *msg);
+int
+gss (char *server_host, char *service_name, char *mechanism, char *msg, int port,
+     int verbose, int delegate, int v1_format, int auth_flag, int wrap_flag,
+     int encrypt_flag, int mic_flag, int ccount, int mcount);
+int call_server(char *host, u_short port, gss_OID oid, char *service_name, 
+                OM_uint32 deleg_flag, int auth_flag,
+                       int wrap_flag, int encrypt_flag, int mic_flag, int v1_format, 
+                char *msg, int use_file, int mcount);
 int connect_to_server(char *host, u_short port);
-int client_establish_context(int s, char *service_name, char *oid, gss_ctx_id_t *gss_context);
+int client_establish_context(int s, char *service_name, OM_uint32 deleg_flag,
+                             int auth_flag, int v1_format, gss_OID oid, 
+                             gss_ctx_id_t *gss_context, OM_uint32 *ret_flags);
+
+
+extern int verbose;
+#define printf  gss_printf
index 95458df6f12b577fca8cbe368448ddd1cb07717e..bc4a622df86b4eb2aaa0938d8681196ecf52b6b8 100644 (file)
-/*+*************************************************************************
-**
-**     Gss
-**     
-**     Tests the gssapi dll.
-**
-***************************************************************************/
-
-#include <windows.h>
-#include <winver.h>
+//Microsoft Developer Studio generated resource script.
+//
+
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
 
-#define GSS_CONNECT_NAME            102
-#define GSS_OK                      100
-#define GSS_CANCEL                  101
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+GSS                     ICON    DISCARDABLE     "gss.ico"
 
-gss ICON gss.ico
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
 
-OPENGSSAPIDLG DIALOG 63, 65, 330, 71
-STYLE DS_ABSALIGN | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Open GSSAPI Connection"
+GSSAPIDLG DIALOG DISCARDABLE 63, 65, 330, 311
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Test GSSAPI Connection"
 FONT 8, "MS Sans Serif"
 BEGIN
-       CONTROL "Host Port Service:", -1, "STATIC", NOT WS_GROUP, 5, 10, 60, 10
-       CONTROL "Example: foo 34000 sample@foo.bar.com", -1, "STATIC", NOT WS_GROUP, 70, 25, 256, 10
-       CONTROL "", GSS_CONNECT_NAME, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP, 70, 9, 256, 60
-       CONTROL "Test", GSS_OK, "BUTTON", WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON, 70, 50, 51, 14
-       CONTROL "Exit", GSS_CANCEL, "BUTTON", WS_TABSTOP, 150, 50, 51, 14
+    RTEXT           "Hostname:",IDC_STATIC_PORT,5,12,60,10,NOT WS_GROUP
+    COMBOBOX        GSS_HOST_NAME,70,9,246,60,CBS_DROPDOWN | CBS_AUTOHSCROLL | 
+                    WS_VSCROLL | WS_GROUP | WS_TABSTOP
+    DEFPUSHBUTTON   "Test",GSS_OK,80,290,51,14,WS_GROUP
+    PUSHBUTTON      "Exit",GSS_CANCEL,185,290,51,14
+    RTEXT           "Port:",IDC_STATIC_PORT,16,27,50,8
+    EDITTEXT        GSS_PORT,70,25,40,14,ES_RIGHT | ES_AUTOHSCROLL | 
+                    ES_NUMBER
+    COMBOBOX        GSS_SERVICE_NAME,69,41,246,30,CBS_DROPDOWN | CBS_SORT | 
+                    WS_VSCROLL | WS_TABSTOP
+    RTEXT           "GSS Service Name:",IDC_STATIC_SERVICE,1,44,64,8
+    COMBOBOX        GSS_MECHANISM,70,110,245,30,CBS_DROPDOWN | 
+                    CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    RTEXT           "Mechanism (OID):",IDC_STATIC_MECH,0,115,65,8
+    RTEXT           "Test Message:",IDC_STATIC_MSG,0,55,65,8
+    COMBOBOX        GSS_MESSAGE,70,55,245,30,CBS_DROPDOWN | CBS_AUTOHSCROLL | 
+                    CBS_SORT | WS_VSCROLL | WS_TABSTOP
+    LTEXT           "The following items are optional and should only be altered by those who understand their implications.",
+                    IDC_STATIC_OPTIONS,10,85,305,20
+    CONTROL         "Verbose Output",GSS_VERBOSE,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,70,135,65,10
+    CONTROL         "Delegation",GSS_DELEGATION,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,170,135,50,10
+    CONTROL         "Version 1",GSS_VERSION_ONE,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,270,135,45,10
+    CONTROL         "No Auth",GSS_NO_AUTH,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,70,155,42,10
+    CONTROL         "No Wrap",GSS_NO_WRAP,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,135,155,45,10
+    CONTROL         "No Encrypt",GSS_NO_ENCRYPT,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,205,155,51,10
+    CONTROL         "No Mic",GSS_NO_MIC,"Button",BS_AUTOCHECKBOX | 
+                    WS_TABSTOP,275,155,39,10
+    CONTROL         "Slider1",GSS_CALL_COUNT,"msctls_trackbar32",TBS_BOTH | 
+                    WS_TABSTOP,70,170,100,15
+    CONTROL         "Slider2",GSS_MESSAGE_COUNT,"msctls_trackbar32",TBS_BOTH | 
+                    WS_TABSTOP,205,170,100,15
+    CTEXT           "Call Count",IDC_STATIC_CCOUNT,75,185,90,8
+    CTEXT           "Message Count",IDC_STATIC_MSG_COUNT,210,185,90,8
+    GROUPBOX        "Output",IDC_GROUP_OUTPUT,0,210,325,75
+    GROUPBOX        "Configuration Options",IDC_GROUP_OPTIONS,0,0,325,205
+    EDITTEXT        GSS_OUTPUT,0,220,320,60,ES_MULTILINE | ES_AUTOVSCROLL | 
+                    ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resrc1.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""resource.h""\r\n"
+    "\0"
 END
 
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
+#include <winver.h>
 #include "..\version.rc"
 
 TestTrackerMOTD TEXT ver_serv.txt
diff --git a/src/windows/gss/resource.h b/src/windows/gss/resource.h
new file mode 100644 (file)
index 0000000..39abfe6
--- /dev/null
@@ -0,0 +1,44 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by gss.rc
+//
+#define GSS_HOST_NAME                   1000
+#define GSS_PORT                        1001
+#define GSS_SERVICE_NAME                1003
+#define IDC_STATIC_SERVICE              1004
+#define GSS_MECHANISM                   1005
+#define IDC_STATIC_MECH                 1006
+#define IDC_STATIC_MSG                  1007
+#define GSS_MESSAGE                     1008
+#define IDC_STATIC_OPTIONS              1009
+#define GSS_VERBOSE                     1010
+#define GSS_DELEGATION                  1011
+#define GSS_VERSION_ONE                 1012
+#define GSS_NO_AUTH                     1013
+#define GSS_NO_WRAP                     1014
+#define GSS_NO_ENCRYPT                  1015
+#define GSS_NO_MIC                      1016
+#define GSS_CALL_COUNT                  1017
+#define GSS_MESSAGE_COUNT               1018
+#define IDC_STATIC_CCOUNT               1019
+#define IDC_STATIC_MSG_COUNT            1020
+#define IDC_GROUP_OUTPUT                1021
+#define IDC_GROUP_OPTIONS               1022
+#define GSS_OUTPUT                      1023
+#define GSS_OK                          1024
+#define GSS_CANCEL                      1025
+#define IDC_STATIC_PORT                 1026
+
+#define IDD_GSSAPIDLG                   101
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        102
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1027
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif