summaryrefslogtreecommitdiffstats
path: root/src/windows
diff options
context:
space:
mode:
authorJeffrey Altman <jaltman@secure-endpoints.com>2004-01-31 00:00:51 +0000
committerJeffrey Altman <jaltman@secure-endpoints.com>2004-01-31 00:00:51 +0000
commit47d5889c35038d022cf31dc1ac68260789d9c011 (patch)
tree5c17c7e55fffc3d8f5a037e15d38585d9cc7f584 /src/windows
parent8f962a4f65b4fb609b58f91b667f8de16e958efd (diff)
downloadkrb5-47d5889c35038d022cf31dc1ac68260789d9c011.tar.gz
krb5-47d5889c35038d022cf31dc1ac68260789d9c011.tar.xz
krb5-47d5889c35038d022cf31dc1ac68260789d9c011.zip
A near complete re-write of the gss sample client on windows. Supports the
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
Diffstat (limited to 'src/windows')
-rw-r--r--src/windows/gss/ChangeLog11
-rw-r--r--src/windows/gss/Makefile.in2
-rw-r--r--src/windows/gss/gss-client.c712
-rw-r--r--src/windows/gss/gss-misc.c322
-rw-r--r--src/windows/gss/gss.c415
-rw-r--r--src/windows/gss/gss.h25
-rw-r--r--src/windows/gss/gss.rc150
-rw-r--r--src/windows/gss/resource.h44
8 files changed, 1295 insertions, 386 deletions
diff --git a/src/windows/gss/ChangeLog b/src/windows/gss/ChangeLog
index b426555a37..e989480f25 100644
--- a/src/windows/gss/ChangeLog
+++ b/src/windows/gss/ChangeLog
@@ -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.
diff --git a/src/windows/gss/Makefile.in b/src/windows/gss/Makefile.in
index b545599aeb..c88452667a 100644
--- a/src/windows/gss/Makefile.in
+++ b/src/windows/gss/Makefile.in
@@ -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
diff --git a/src/windows/gss/gss-client.c b/src/windows/gss/gss-client.c
index d5e8972b31..848f226cde 100644
--- a/src/windows/gss/gss-client.c
+++ b/src/windows/gss/gss-client.c
@@ -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
@@ -20,118 +20,27 @@
* 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;
+}
diff --git a/src/windows/gss/gss-misc.c b/src/windows/gss/gss-misc.c
index cb84e93279..9ed8109dc2 100644
--- a/src/windows/gss/gss-misc.c
+++ b/src/windows/gss/gss-misc.c
@@ -24,131 +24,242 @@
#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
diff --git a/src/windows/gss/gss.c b/src/windows/gss/gss.c
index 2a9b93dcf6..4254211a63 100644
--- a/src/windows/gss/gss.c
+++ b/src/windows/gss/gss.c
@@ -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;
}
diff --git a/src/windows/gss/gss.h b/src/windows/gss/gss.h
index e9b43c5070..8dcf4fcd0d 100644
--- a/src/windows/gss/gss.h
+++ b/src/windows/gss/gss.h
@@ -12,18 +12,31 @@
#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
diff --git a/src/windows/gss/gss.rc b/src/windows/gss/gss.rc
index 95458df6f1..bc4a622df8 100644
--- a/src/windows/gss/gss.rc
+++ b/src/windows/gss/gss.rc
@@ -1,32 +1,138 @@
-/*+*************************************************************************
-**
-** 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
index 0000000000..39abfe6363
--- /dev/null
+++ b/src/windows/gss/resource.h
@@ -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