aboutsummaryrefslogtreecommitdiff
path: root/src/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/windows')
-rw-r--r--src/windows/ChangeLog83
-rw-r--r--src/windows/Makefile.in6
-rw-r--r--src/windows/README48
-rw-r--r--src/windows/cns/ChangeLog14
-rw-r--r--src/windows/cns/cns.c34
-rw-r--r--src/windows/cns/cns_reg.c8
-rw-r--r--src/windows/cns/tktlist.c23
-rw-r--r--src/windows/lib/ChangeLog4
-rw-r--r--src/windows/lib/cacheapi.h455
-rw-r--r--src/windows/ms2mit/ChangeLog8
-rw-r--r--src/windows/ms2mit/Makefile.in22
-rw-r--r--src/windows/ms2mit/ms2mit.c560
-rw-r--r--src/windows/version.rc18
-rw-r--r--src/windows/wintel/ChangeLog6
-rw-r--r--src/windows/wintel/auth.c17
-rw-r--r--src/windows/wintel/encrypt.c5
16 files changed, 1037 insertions, 274 deletions
diff --git a/src/windows/ChangeLog b/src/windows/ChangeLog
index ce20631..d32a4e6 100644
--- a/src/windows/ChangeLog
+++ b/src/windows/ChangeLog
@@ -1,3 +1,86 @@
+2003-04-08 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.8 final.
+
+2002-11-15 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.7 final.
+
+2002-11-08 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.7-beta2.
+
+2002-11-04 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.7-beta1.
+
+2002-09-11 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.6 final.
+
+2002-08-30 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.6 beta2.
+
+2002-08-16 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.6 beta1.
+
+2002-04-16 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: 1.2.5 beta 2 (in anticipation).
+
+2002-04-04 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: 1.2.5 beta 1.
+
+2002-02-27 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: 1.2.4 (final)
+
+2002-02-21 Tom Yu <tlyu@mit.edu>
+
+ * version.rc: 1.2.4-beta2.
+
+2002-02-06 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: 1.2.4 beta 1.
+
+2002-01-09 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: 1.2.3 (final).
+
+2001-12-21 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: Beta 4.
+
+2001-11-28 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: Beta 3.
+
+2001-11-19 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: Beta 2.
+
+2001-11-06 Danilo Almeida <dalmeida@mit.edu>
+
+ * Makefile.in: Build ms2mit.
+ * version.rc: 1.2.3 beta 1 (pre-release)
+ * README: Note on building ms2mit.
+
+2000-07-07 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: No longer pre-release.
+
+2000-06-21 Danilo Almeida <dalmeida@mit.edu>
+
+ * README: Update documentation with DNS information. Fix up the
+ language a bit.
+
+2000-04-25 Danilo Almeida <dalmeida@mit.edu>
+
+ * version.rc: Bump version to 1.2 beta.
+
2000-02-06 Danilo Almeida <dalmeida@mit.edu>
* README: Add documentation about debug vs. release builds.
diff --git a/src/windows/Makefile.in b/src/windows/Makefile.in
index 0cd8e91..ebfc6e3 100644
--- a/src/windows/Makefile.in
+++ b/src/windows/Makefile.in
@@ -20,6 +20,9 @@ all-windows::
@echo Making in windows\gina
cd ..\gina
$(MAKE) -$(MFLAGS)
+ @echo Making in windows\ms2mit
+ cd ..\ms2mit
+ $(MAKE) -$(MFLAGS)
cd ..
clean-windows::
@@ -38,4 +41,7 @@ clean-windows::
@echo Making clean in windows\gina
cd ..\gina
$(MAKE) -$(MFLAGS) clean
+ @echo Making clean in windows\ms2mit
+ cd ..\ms2mit
+ $(MAKE) -$(MFLAGS) clean
cd ..
diff --git a/src/windows/README b/src/windows/README
index f30d029..eb221bc 100644
--- a/src/windows/README
+++ b/src/windows/README
@@ -1,29 +1,39 @@
Building & Running Kerberos 5 on Windows
----------------------------------------
-Kerberos 5 Windows support now only includes Win32 and no longer
-includes Win16.
+Kerberos 5 builds on Windows with MSVC++ 6.0. It may or may not build
+with other compilers or make utilities.
-We build Kerberos 5 on Windows just with MSVC++ 6.0. You should
-not need anything else. We do not know whether it currently
-builds with other compilers or make utilities.
-
-These build instructions assume that you got a standalong source
-distribution of Kerberos 5 rather than the MIT Kerberos for Win32
+These build instructions assume that you have the standalone source
+distribution of Kerberos 5 rather than the MIT Kerberos for Windows
distribution (which includes a working Kerberos 4).
There are two methods for building a Windows version of Kerberos 5.
The traditional method involves starting on a Unix machine and
creating a distribution that can be built on Windows. The second
method works from the sources that come from the Unix distribution if
-you have certain Unix-type utilities.
+you have certain Unix-type utilities (see below).
-IMPORTANT NOTE: By default, the sources are build with debug
+IMPORTANT NOTE: By default, the sources are built with debug
information and linked against the debug version of the Microsoft C
-Runtime library, which is not found on most Win32 systems unless they
-have development tools. To build a release version, you need to
+Runtime library, which is not found on most Windows systems unless
+they have development tools. To build a release version, you need to
define NODEBUG either in the environment or the nmake command-line.
+DNS Support: To support DNS lookups, you will need to define
+KRB5_DNS_LOOKUP, KRB5_DNS_LOOKUP_KDC, or KRB5_DNS_LOOKUP_REALMS. The
+DNS code will default to trying to use the wshelper library. If you
+would rather use a resolver library whose include files more closely
+match the Unix resolver library, define KRB5_NO_WSHELPER. You will
+also need to define DNS_INC to point to the include directory for the
+library and DNS_LIB to library itself. The default is not to support
+DNS because the build cannot know whether there is a DNS resolver
+library around for it to use.
+
+Building ms2mit requires that you have a reasonably recent Microsoft
+Platform SDK installed. Anything starting at the Windows 2000 edition
+should be fine.
+
Traditional Build Method:
------------------------
@@ -36,13 +46,13 @@ On the Unix side
On the PC side
-1) md \krb5 # Create where we'll put the tree
+1) md \krb5 # Create dir where we'll put the tree
2) cd \krb5
3) unzip kerbsrc.zip
- or -
pkunzip -d kerbsrc.zip
-4) nmake [NODEBUG=1] # Build the sources
-5) nmake install [NODEBUG=1] # Copy headers, libs, executables
+4) nmake [NODEBUG=1] [DNS-options] # Build the sources
+5) nmake install [NODEBUG=1] # Copy headers, libs, executables
All-Windows Build Method:
@@ -52,8 +62,8 @@ First, make sure you have sed, gawk, cat, and cp.
1) cd xxx/src # Go to where the source lives
2) nmake -f Makefile.in prep-windows # Create Makefile for Windows
-3) nmake [NODEBUG=1] # Build the sources
-4) nmake install [NODEBUG=1] # Copy headers, libs, executables
+3) nmake [NODEBUG=1] [DNS-options # Build the sources
+4) nmake install [NODEBUG=1] # Copy headers, libs, executables
Notes on the install Target:
@@ -82,7 +92,7 @@ able to run the applications that are built. Note that Kerberos 5
will not look for the krb5.ini file in your path.
-Krb5.ini File:
+krb5.ini File:
-------------
WARNING: Despite its name, this is not a Windows .ini file.
@@ -128,7 +138,7 @@ Othes Issues:
The krb4_32.dll that is built (but not installed) is not supported.
If you need Kerberos 4, you can use the krbv4w32.dll that MIT
-distributes as part of the MIT Kerberos for Win32 distribution.
+distributes as part of the MIT Kerberos for Windows distribution.
More Information:
diff --git a/src/windows/cns/ChangeLog b/src/windows/cns/ChangeLog
index f99c56a..dc32c85 100644
--- a/src/windows/cns/ChangeLog
+++ b/src/windows/cns/ChangeLog
@@ -1,3 +1,17 @@
+2002-04-16 Danilo Almeida <dalmeida@mit.edu>
+
+ * cns.c: Do not use krb_get_notification_message() or
+ krb5_get_notification_message().
+
+2000-05-08 Ken Raeburn <raeburn@mit.edu>
+ Nalin Dahyabhai <nalin@redhat.com>
+
+ * cns.c (kwin_push_login): Don't overflow buffer "fullname".
+ (kwin_command): Don't overflow buffer "copyright".
+ * cns_reg.c (cns_load_registry): Don't overflow buffer
+ "cns_res.def_confname".
+ * tktlist.c (ticket_init_list): Don't overflow buffer "buf".
+
1999-12-03 Danilo Almeida <dalmeida@mit.edu>
* Makefile.in: Windows fix for updated win-pre.in.
diff --git a/src/windows/cns/cns.c b/src/windows/cns/cns.c
index 7af81fc..d57c685 100644
--- a/src/windows/cns/cns.c
+++ b/src/windows/cns/cns.c
@@ -41,7 +41,9 @@ HFONT hfontdialog = NULL; /* Font in which the dialog is drawn. */
static HFONT hfonticon = NULL; /* Font for icon label */
HINSTANCE hinstance;
static int dlgncmdshow; /* ncmdshow from WinMain */
+#if 0
static UINT wm_kerberos_changed; /* message for cache changing */
+#endif
static int action; /* After login actions */
static UINT kwin_timer_id; /* Timer being used for update */
BOOL alert; /* Actions on ticket expiration */
@@ -384,12 +386,13 @@ kwin_push_login(HWND hwnd, char *name, char *instance, char *realm)
char menuitem[MAX_K_NAME_SZ + 3];
BOOL rc;
- strcpy(fullname, "&x ");
- strcat(fullname, name);
- strcat(fullname, ".");
- strcat(fullname, instance);
- strcat(fullname, "@");
- strcat(fullname, realm);
+ fullname[sizeof(fullname) - 1] = '\0';
+ strncpy(fullname, "&x ", sizeof(fullname) - 1);
+ strncat(fullname, name, sizeof(fullname) - 1 - strlen(fullname));
+ strncat(fullname, ".", sizeof(fullname) - 1 - strlen(fullname));
+ strncat(fullname, instance, sizeof(fullname) - 1 - strlen(fullname));
+ strncat(fullname, "@", sizeof(fullname) - 1 - strlen(fullname));
+ strncat(fullname, realm, sizeof(fullname) - 1 - strlen(fullname));
hmenu = GetMenu(hwnd);
assert(hmenu != NULL);
@@ -1339,14 +1342,16 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify)
strcpy(copyright, " Kerberos V5 for Windows ");
#endif
#ifdef _WIN32
- strcat(copyright, "32-bit\n");
+ strncat(copyright, "32-bit\n", sizeof(copyright) - 1 - strlen(copyright));
#else
- strcat(copyright, "16-bit\n");
+ strncat(copyright, "16-bit\n", sizeof(copyright) - 1 - strlen(copyright));
#endif
- strcat(copyright, "\n Version 1.12\n\n");
+ strncat(copyright, "\n Version 1.12\n\n",
+ sizeof(copyright) - 1 - strlen(copyright));
#ifdef ORGANIZATION
- strcat(copyright, " For information, contact:\n");
- strcat(copyright, ORGANIZATION);
+ strncat(copyright, " For information, contact:\n",
+ sizeof(copyright) - 1 - strlen(copyright));
+ strncat(copyright, ORGANIZATION, sizeof(copyright) - 1 - strlen(copyright));
#endif
MessageBox(hwnd, copyright, KWIN_DIALOG_NAME, MB_OK);
@@ -1469,8 +1474,9 @@ kwin_paint(HWND hwnd)
sprintf(buf, "%s - %ld hr", KWIN_DIALOG_NAME, dt);
}
+ buf[sizeof(buf) - 1] = '\0';
if (dt > 1)
- strcat(buf, "s");
+ strncat(buf, "s", sizeof(buf) - 1 - strlen(buf));
}
DrawIcon(hdc, r.left, r.top, hicon);
@@ -1487,12 +1493,14 @@ kwin_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int n;
+#if 0
if (message == wm_kerberos_changed) { /* Message from the ccache */
n = ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST));
EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), n > 0);
return 0;
}
+#endif
switch (message) {
HANDLE_MSG(hwnd, WM_GETMINMAXINFO, kwin_getminmaxinfo);
@@ -1597,6 +1605,7 @@ init_application(HINSTANCE hinstance)
{
BOOL rc;
+#if 0
#ifdef KRB4
wm_kerberos_changed = krb_get_notification_message();
#endif
@@ -1604,6 +1613,7 @@ init_application(HINSTANCE hinstance)
#ifdef KRB5
wm_kerberos_changed = krb5_get_notification_message();
#endif
+#endif
rc = kwin_init(hinstance);
diff --git a/src/windows/cns/cns_reg.c b/src/windows/cns/cns_reg.c
index 400d72d..160eb15 100644
--- a/src/windows/cns/cns_reg.c
+++ b/src/windows/cns/cns_reg.c
@@ -74,8 +74,12 @@ cns_load_registry(void)
if (key != INVALID_HANDLE_VALUE) {
if (registry_string_get(key, KERBNET_HOME, &ts) == 0) {
cns_res.conf_override = 0;
- strcpy(cns_res.def_confname, ts);
- strcat(cns_res.def_confname, "\\etc\\krb5.conf");
+ cns_res.def_confname[sizeof(cns_res.def_confname) - 1];
+ strncpy(cns_res.def_confname, ts,
+ sizeof(cns_res.def_confname) - 1);
+ strncat(cns_res.def_confname, "\\etc\\krb5.conf",
+ sizeof(cns_res.def_confname) - 1 -
+ strlen(cns_res.def_confname));
free(ts);
}
diff --git a/src/windows/cns/tktlist.c b/src/windows/cns/tktlist.c
index 62b6eb8..5e15201 100644
--- a/src/windows/cns/tktlist.c
+++ b/src/windows/cns/tktlist.c
@@ -122,11 +122,12 @@ ticket_init_list (HWND hwnd)
krb_get_nth_cred(service, instance, realm, i);
krb_get_cred(service, instance, realm, &c);
strcpy(buf, " ");
- strcat(buf, short_date(c.issue_date - kwin_get_epoch()));
+ strncat(buf, short_date(c.issue_date - kwin_get_epoch()),
+ sizeof(buf) - 1 - strlen(buf));
expiration = c.issue_date - kwin_get_epoch() + (long) c.lifetime * 5L * 60L;
- strcat (buf, " ");
- strcat(buf, short_date(expiration));
- strcat (buf, " ");
+ strncat(buf, " ", sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, short_date(expiration), sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, " ", sizeof(buf) - 1 - strlen(buf));
l = strlen(buf);
sprintf(&buf[l], "%s%s%s%s%s (%d)",
c.service, (c.instance[0] ? "." : ""), c.instance,
@@ -172,10 +173,12 @@ ticket_init_list (HWND hwnd)
ncred++;
strcpy (buf, " ");
- strcat (buf, short_date (c.times.starttime - kwin_get_epoch()));
- strcat (buf, " ");
- strcat (buf, short_date (c.times.endtime - kwin_get_epoch()));
- strcat (buf, " ");
+ strncat(buf, short_date (c.times.starttime - kwin_get_epoch()),
+ sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, " ", sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, short_date (c.times.endtime - kwin_get_epoch()),
+ sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, " ", sizeof(buf) - 1 - strlen(buf));
/* Add ticket service name and realm */
code = krb5_unparse_name (k5_context, c.server, &sname);
@@ -183,9 +186,9 @@ ticket_init_list (HWND hwnd)
com_err (NULL, code, "while unparsing server name");
break;
}
- strcat (buf, sname);
+ strncat (buf, sname, sizeof(buf) - 1 - strlen(buf));
- strcat (buf, flags_string (&c)); /* Add flag info */
+ strncat (buf, flags_string (&c), sizeof(buf) - 1 - strlen(buf)); /* Add flag info */
l = strlen(buf);
lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + l + 1);
diff --git a/src/windows/lib/ChangeLog b/src/windows/lib/ChangeLog
index 25f20f4..160a899 100644
--- a/src/windows/lib/ChangeLog
+++ b/src/windows/lib/ChangeLog
@@ -1,3 +1,7 @@
+2000-05-18 Danilo Almeida <dalmeida@mit.edu>
+
+ * cacheapi.h: Update to v2.
+
1999-12-03 Danilo Almeida <dalmeida@mit.edu>
* Makefile.in: Fix of build flags with updated win-pre.in.
diff --git a/src/windows/lib/cacheapi.h b/src/windows/lib/cacheapi.h
index d23b8d4..7661599 100644
--- a/src/windows/lib/cacheapi.h
+++ b/src/windows/lib/cacheapi.h
@@ -49,74 +49,64 @@
**
*/
-#include <krb5.h>
-
#ifndef Krb_CCacheAPI_h_
#define Krb_CCacheAPI_h_
#include <windows.h>
-#define CC_API_VER_1 1
+//typedef int cc_int32;
+#define cc_int32 long
+#define cc_uint32 unsigned long
-#define CCACHE_API __declspec(dllexport) cc_int32
-//#define CCACHE_API __declspec( dllexport ) cc_int32 __stdcall
+typedef cc_int32 cc_time_t;
-/*
-** Decisions I haven't nailed down yet
-*/
-// determines if cred_type precedes ptrs to creds in cred_union
-//#define CRED_TYPE_IN_UNION
-//
-// JENNYEXT - modifications Jenny made to cacheapi for MIT code
-// not blessed, but reproduced temporarily
-#ifndef JENNYEXT
-#define JENNYEXT
-#endif
+#define CC_API_VER_1 1
+#define CC_API_VER_2 2
+
+//enum {
+// CC_API_VER_1 = 1,
+// CC_API_VER_2 = 2
+//};
+
+#define CCACHE_API __declspec(dllexport) cc_int32
/*
** The Official Error Codes
*/
-#define CC_NOERROR 0
-#define CC_BADNAME 1
-#define CC_NOTFOUND 2
-#define CC_END 3
-#define CC_IO 4
-#define CC_WRITE 5
-#define CC_NOMEM 6
-#define CC_FORMAT 7
-#define CC_LOCKED 8
-#define CC_BAD_API_VERSION 9
-#define CC_NO_EXIST 10
-#define CC_NOT_SUPP 11
-#define CC_BAD_PARM 12
-#define CC_ERR_CACHE_ATTACH 13
-#define CC_ERR_CACHE_RELEASE 14
-#define CC_ERR_CACHE_FULL 15
-#define CC_ERR_CRED_VERSION 16
+#define CC_NOERROR 0
+#define CC_BADNAME 1
+#define CC_NOTFOUND 2
+#define CC_END 3
+#define CC_IO 4
+#define CC_WRITE 5
+#define CC_NOMEM 6
+#define CC_FORMAT 7
+#define CC_LOCKED 8
+#define CC_BAD_API_VERSION 9
+#define CC_NO_EXIST 10
+#define CC_NOT_SUPP 11
+#define CC_BAD_PARM 12
+#define CC_ERR_CACHE_ATTACH 13
+#define CC_ERR_CACHE_RELEASE 14
+#define CC_ERR_CACHE_FULL 15
+#define CC_ERR_CRED_VERSION 16
/*
** types, structs, & constants
*/
-typedef int cc_int32;
-typedef cc_int32 cc_time_t;
-
// Flag bits promised by Ted "RSN"
#define CC_FLAGS_RESERVED 0xFFFFFFFF
-typedef cc_int32 cc_nc_flags; // set via constants above
+typedef cc_uint32 cc_nc_flags; // set via constants above
-typedef struct opaque_ccache_pointer_type* ccache_p;
typedef struct opaque_dll_control_block_type* apiCB;
+typedef struct opaque_ccache_pointer_type* ccache_p;
typedef struct opaque_credential_iterator_type* ccache_cit;
-enum { KRB5_CLIENT_SZ = 256};
-enum { KRB5_SERVER_SZ = 256};
-enum { KRB5_DATA_SZ = 1024};
-enum { KRB5_DATA_CNT = 20};
-
+#if 0
enum _cc_data_type {
- type_ticket = 0, // 0 for ticket, second_ticket
+ type_ticket = 0, /* 0 for ticket, second_ticket */
/* Ted's draft spec says these are to be
"as defined in the Kerberos V5 protocol"
all I can find are typdefs,
@@ -125,22 +115,17 @@ enum _cc_data_type {
type_address, /* = <"as defined in the Kerberos V5 protocol"> */
type_authdata, /* = <"as defined in the Kerberos V5 protocol"> */
type_encryption, /* = <"as defined in the Kerberos V5 protocol"> */
- cc_data_type_max }; // for validation
+ cc_data_type_max /* for validation */
+};
+#endif
typedef struct _cc_data
{
- cc_int32 type; // should be one of _cc_data_type
- cc_int32 length;
- unsigned char* data; // the proverbial bag-o-bits
+ cc_uint32 type; // should be one of _cc_data_type
+ cc_uint32 length;
+ unsigned char* data; // the proverbial bag-o-bits
} cc_data;
-typedef struct _cc_data1
-{
- cc_int32 type; // should be one of _cc_data_type
- cc_int32 length;
- unsigned char data[KRB5_DATA_SZ]; // the proverbial bag-o-bits
-} cc_data1;
-
// V5 Credentials
typedef struct _cc_creds {
char* client;
@@ -150,75 +135,53 @@ typedef struct _cc_creds {
cc_time_t starttime;
cc_time_t endtime;
cc_time_t renew_till;
- cc_int32 is_skey;
- cc_int32 ticket_flags;
+ cc_uint32 is_skey;
+ cc_uint32 ticket_flags;
cc_data FAR ** addresses;
cc_data ticket;
cc_data second_ticket;
cc_data FAR ** authdata;
} cc_creds;
-typedef struct _cc_cache_creds {
- char client[KRB5_CLIENT_SZ];
- char server[KRB5_SERVER_SZ];
- cc_data1 keyblock;
- cc_time_t authtime;
- cc_time_t starttime;
- cc_time_t endtime;
- cc_time_t renew_till;
- cc_int32 is_skey;
- cc_int32 ticket_flags;
- cc_data1 addresses[KRB5_DATA_CNT];
- cc_data1 ticket;
- cc_data1 second_ticket;
- cc_data1 authdata[KRB5_DATA_CNT];
-} cc_cache_creds;
-
// begin V4 stuff
-
-enum { KRB_PRINCIPAL_SZ = 40 };
-enum { KRB_SERVICE_SZ = 40};
-enum { KRB_INSTANCE_SZ = 40};
-enum { KRB_REALM_SZ = 40};
-#ifndef ADDR_SZ
-enum { ADDR_SZ = 16};
-#endif
-
// use an enumerated type so all callers infer the same meaning
// these values are what krbv4win uses internally.
-enum StringToKey_Type { STK_AFS = 0, STK_DES = 1 };
+#define STK_AFS 0
+#define STK_DES 1
// K4 uses a MAX_KTXT_LEN of 1250 to hold a ticket
// K95 uses 256
// To be safe I'll use the larger number, but a factor of 5!!!
-enum { MAX_V4_CRED_LEN = 1250 };
+#define MAX_V4_CRED_LEN 1250
// V4 Credentials
+
+enum {
+ KRB_NAME_SZ = 40,
+ KRB_INSTANCE_SZ = 40,
+ KRB_REALM_SZ = 40
+};
+
typedef struct cc_V4credential {
- unsigned char kversion;
- char principal[KRB_PRINCIPAL_SZ];
- char principal_instance[KRB_INSTANCE_SZ];
- char service[KRB_SERVICE_SZ];
- char service_instance[KRB_INSTANCE_SZ];
- char realm[KRB_REALM_SZ];
- unsigned char session_key[8];
- cc_int32 kvno; // k95 used BYTE skvno
- enum StringToKey_Type
- str_to_key; // k4 infers dynamically, k95 stores
- long issue_date; // k95 called this issue_time
- cc_int32 lifetime; // k95 used LONG expiration_time
- char address[ADDR_SZ]; // IP Address of local host
- cc_int32 ticket_sz; // k95 used BYTE, k4 ktext uses int to hold up to 1250
- unsigned char ticket[MAX_V4_CRED_LEN];
- unsigned long oops; // zero to catch runaways
+ unsigned char kversion;
+ char principal[KRB_NAME_SZ + 1];
+ char principal_instance[KRB_INSTANCE_SZ + 1];
+ char service[KRB_NAME_SZ + 1];
+ char service_instance[KRB_INSTANCE_SZ + 1];
+ char realm[KRB_REALM_SZ + 1];
+ unsigned char session_key[8];
+ cc_int32 kvno; // k95 used BYTE skvno
+ cc_int32 str_to_key; // k4 infers dynamically, k95 stores
+ long issue_date; // k95 called this issue_time
+ cc_int32 lifetime; // k95 used LONG expiration_time
+ cc_uint32 address; // IP Address of local host
+ cc_int32 ticket_sz; // k95 used BYTE, k4 ktext uses int to hold up to 1250
+ unsigned char ticket[MAX_V4_CRED_LEN];
+ unsigned long oops; // zero to catch runaways
} V4Cred_type;
-#ifdef JENNYEXT
-typedef struct cc_V4credential CCV4CREDENTIALS; // JENNYEXT
-#endif
-
-enum cc_cred_vers {
+enum {
CC_CRED_VUNKNOWN = 0, // For validation
CC_CRED_V4 = 1,
CC_CRED_V5 = 2,
@@ -226,17 +189,21 @@ enum cc_cred_vers {
};
typedef union cred_ptr_union_type {
- V4Cred_type* pV4Cred;
- cc_creds* pV5Cred;
+ V4Cred_type* pV4Cred;
+ cc_creds* pV5Cred;
} cred_ptr_union;
typedef struct cred_union_type {
-//#ifdef CRED_TYPE_IN_UNION
- enum cc_cred_vers cred_type;
-//#endif
- cred_ptr_union cred;
+ cc_int32 cred_type;
+ cred_ptr_union cred;
} cred_union;
+typedef struct _infoNC {
+ char* name;
+ char* principal;
+ cc_int32 vers;
+} infoNC;
+
/*
** The official (externally visible) API
@@ -251,113 +218,147 @@ extern "C" /* this entire list of functions */
** Main cache routines : initialize, shutdown, get_cache_names, & get_change_time
*/
CCACHE_API
-cc_initialize(apiCB** cc_ctx, // < DLL's primary control structure.
- // returned here, passed everywhere else
- const cc_int32 api_version,// > ver supported by caller (use CC_API_VER_1)
- cc_int32* api_supported, // < if ~NULL, max ver supported by DLL
- const char** vendor); // < if ~NULL, vendor name in read only C string
+cc_initialize(
+ apiCB** cc_ctx, // < DLL's primary control structure.
+ // returned here, passed everywhere else
+ cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1)
+ cc_int32* api_supported, // < if ~NULL, max ver supported by DLL
+ const char** vendor // < if ~NULL, vendor name in read only C string
+ );
CCACHE_API
-cc_shutdown(apiCB** cc_ctx); // <> DLL's primary control structure. NULL after call.
+cc_shutdown(
+ apiCB** cc_ctx // <> DLL's primary control structure. NULL after call.
+ );
CCACHE_API
-cc_get_change_time(apiCB* cc_ctx, // > DLL's primary control structure
- cc_time_t* time); // < time of last change to main cache
+cc_get_change_time(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ cc_time_t* time // < time of last change to main cache
+ );
/*
** Named Cache (NC) routines
-** create, open, close, destroy, get_principal, get_cred_version, & lock_request
+** create, open, close, destroy, get_principal, get_cred_version, &
+** lock_request
**
-** Multiple NCs are allowed within the main cache. Each has a Name and kerberos
-** version # (V4 or V5). Caller gets "ccache_ptr"s for NCs.
+** Multiple NCs are allowed within the main cache. Each has a Name
+** and kerberos version # (V4 or V5). Caller gets "ccache_ptr"s for
+** NCs.
*/
CCACHE_API
-cc_create(apiCB* cc_ctx, // > DLL's primary control structure
- const char* name, // > name of cache to be [destroyed if exists, then] created
- const char* principal, // > name of principal associated with NC
- const enum cc_cred_vers vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5)
- const cc_int32 cc_flags, // > options
- ccache_p** ccache_ptr); // < NC control structure
+cc_create(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const char* name, // > name of cache to be [destroyed if exists, then] created
+ const char* principal,
+ cc_int32 vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5)
+ cc_uint32 cc_flags, // > options
+ ccache_p** ccache_ptr // < NC control structure
+ );
CCACHE_API
-cc_open(apiCB* cc_ctx, // > DLL's primary control structure
- const char* name, // > name of pre-created cache
- const enum cc_cred_vers vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5)
- const cc_int32 cc_flags, // > options
- ccache_p** ccache_ptr); // < NC control structure
+cc_open(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const char* name, // > name of pre-created cache
+ cc_int32 vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5)
+ cc_uint32 cc_flags, // > options
+ ccache_p** ccache_ptr // < NC control structure
+ );
CCACHE_API
-cc_close(apiCB* cc_ctx, // > DLL's primary control structure
- ccache_p** ccache_ptr); // <> NC control structure. NULL after call.
+cc_close(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ ccache_p** ccache_ptr // <> NC control structure. NULL after call.
+ );
CCACHE_API
-cc_destroy(apiCB* cc_ctx, // > DLL's primary control structure
- ccache_p** ccache_ptr); // <> NC control structure. NULL after call.
-
+cc_destroy(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ ccache_p** ccache_ptr // <> NC control structure. NULL after call.
+ );
/*
** Ways to get information about the NCs
*/
CCACHE_API
-cc_seq_fetch_NCs(apiCB* cc_ctx, // > DLL's primary control structure
- ccache_p** ccache_ptr, // < NC control structure (free via cc_close())
- ccache_cit** itNCs); // <> iterator used by DLL,
- // set to NULL before first call
- // returned NULL at CC_END
+cc_seq_fetch_NCs_begin(
+ apiCB* cc_ctx,
+ ccache_cit** itNCs
+ );
-typedef struct _infoNC {
- char* name;
- enum cc_cred_vers vers;
-} infoNC;
+CCACHE_API
+cc_seq_fetch_NCs_end(
+ apiCB* cc_ctx,
+ ccache_cit** itNCs
+ );
+
+CCACHE_API
+cc_seq_fetch_NCs_next(
+ apiCB* cc_ctx,
+ ccache_p** ccache_ptr,
+ ccache_cit* itNCs
+ );
CCACHE_API
-cc_get_NC_info(apiCB* cc_ctx, // > DLL's primary control structure
- struct _infoNC*** ppNCi); // < (NULL before call) null terminated,
- // list of a structs (free via cc_free_infoNC())
+cc_seq_fetch_NCs(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ ccache_p** ccache_ptr, // < NC control structure (free via cc_close())
+ ccache_cit** itNCs // <> iterator used by DLL,
+ // set to NULL before first call
+ // returned NULL at CC_END
+ );
CCACHE_API
-cc_free_NC_info(apiCB* cc_ctx,
- struct _infoNC*** ppNCi); // < free list of structs returned by cc_get_cache_names()
- // set to NULL on return
+cc_get_NC_info(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ struct _infoNC*** ppNCi // < (NULL before call) null terminated,
+ // list of a structs (free via cc_free_infoNC())
+ );
+
+CCACHE_API
+cc_free_NC_info(
+ apiCB* cc_ctx,
+ struct _infoNC*** ppNCi // < free list of structs returned by
+ // cc_get_cache_names(). set to NULL on return
+ );
/*
** Functions that provide distinguishing characteristics of NCs.
*/
CCACHE_API
-cc_get_name(apiCB* cc_ctx, // > DLL's primary control structure
- const ccache_p* ccache_ptr, // > NC control structure
- char** name); // < name of NC associated with ccache_ptr (free via cc_free_name())
+cc_get_name(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const ccache_p* ccache_ptr, // > NC control structure
+ char** name // < name of NC associated with ccache_ptr
+ // (free via cc_free_name())
+ );
CCACHE_API
-cc_set_principal(apiCB* cc_ctx, // > DLL's primary control structure
- const ccache_p* ccache_pointer,// < name of principal associated with NC
- const enum cc_cred_vers vers, // Free via cc_free_principal()
- const char* principal);
+cc_set_principal(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const ccache_p* ccache_pointer, // > NC control structure
+ const cc_int32 vers,
+ const char* principal // > name of principal associated with NC
+ // Free via cc_free_principal()
+ );
CCACHE_API
-cc_get_principal(apiCB* cc_ctx, // > DLL's primary control structure
- ccache_p* ccache_pointer, // < name of principal associated with NC
- char** principal); // Free via cc_free_principal()
+cc_get_principal(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const ccache_p* ccache_pointer, // > NC control structure
+ char** principal // < name of principal associated with NC
+ // Free via cc_free_principal()
+ );
-#ifdef JENNYEXT
-
-CCACHE_API
-cc_set_instance(apiCB* cc_ctx, // > DLL's primary control structure
- const char* instance); // < name of principal_instance associated with NC
- // Free via cc_free_instance()
CCACHE_API
-cc_get_instance(apiCB* cc_ctx, // > DLL's primary control structure
- char** instance); // < name of principal_instance associated with NC
- // Free via cc_free_instance()
-#endif /* JENNYEXT */
-
-CCACHE_API
-cc_get_cred_version(apiCB* cc_ctx, // > DLL's primary control structure
- const ccache_p* ccache_ptr,// > NC control structure
- enum cc_cred_vers* vers);// < ticket version associated with NC
+cc_get_cred_version(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const ccache_p* ccache_ptr, // > NC control structure
+ cc_int32* vers // < ticket version associated with NC
+ );
#define CC_LOCK_UNLOCK 1
#define CC_LOCK_READER 2
@@ -365,9 +366,12 @@ cc_get_cred_version(apiCB* cc_ctx, // > DLL's primary control structure
#define CC_LOCK_NOBLOCK 16
CCACHE_API
-cc_lock_request(apiCB* cc_ctx, // > DLL's primary control structure
- const ccache_p* ccache_ptr,// > NC control structure
- const cc_int32 lock_type);// > one (or combination) of above defined lock types
+cc_lock_request(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const ccache_p* ccache_ptr, // > NC control structure
+ const cc_int32 lock_type // > one (or combination) of above defined
+ // lock types
+ );
/*
@@ -375,23 +379,49 @@ cc_lock_request(apiCB* cc_ctx, // > DLL's primary control structure
** store, remove_cred, seq_fetch_creds
*/
CCACHE_API
-cc_store(apiCB* cc_ctx, // > DLL's primary control structure
- const ccache_p* ccache_ptr, // > NC control structure
- const cred_union creds); // > credentials to be copied into NC
+cc_store(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ ccache_p* ccache_ptr, // > NC control structure
+ const cred_union creds // > credentials to be copied into NC
+ );
CCACHE_API
-cc_remove_cred(apiCB* cc_ctx, // > DLL's primary control structure
- const ccache_p* ccache_ptr, // > NC control structure
- const cred_union cred); // > credentials to remove from NC
+cc_remove_cred(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ ccache_p* ccache_ptr, // > NC control structure
+ const cred_union cred // > credentials to remove from NC
+ );
CCACHE_API
-cc_seq_fetch_creds(apiCB* cc_ctx, // > DLL's primary control structure
- const ccache_p* ccache_ptr, // > NC control structure
- cred_union** creds, // < filled in by DLL, free via cc_free_creds()
- ccache_cit** itCreds); // <> iterator used by DLL, set to NULL before first call
- // Also NULL for final call if loop ends before CC_END
+cc_seq_fetch_creds(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ const ccache_p* ccache_ptr, // > NC control structure
+ cred_union** creds, // < filled in by DLL, free via cc_free_creds()
+ ccache_cit** itCreds // <> iterator used by DLL, set to NULL
+ // before first call -- Also NULL for final
+ // call if loop ends before CC_END
+ );
+
+CCACHE_API
+cc_seq_fetch_creds_begin(
+ apiCB* cc_ctx,
+ const ccache_p* ccache_ptr,
+ ccache_cit** itCreds
+ );
+
+CCACHE_API
+cc_seq_fetch_creds_end(
+ apiCB* cc_ctx,
+ ccache_cit** itCreds
+ );
+
+CCACHE_API
+cc_seq_fetch_creds_next(
+ apiCB* cc_ctx,
+ cred_union** cred,
+ ccache_cit* itCreds
+ );
-
/*
** methods of liberation,
** or freeing space via the free that goes with the malloc used to get it
@@ -401,37 +431,28 @@ cc_seq_fetch_creds(apiCB* cc_ctx, // > DLL's primary control structure
** freeing a NULL pointer is not treated as an error
*/
CCACHE_API
-cc_free_principal(apiCB* cc_ctx, // > DLL's primary control structure
- char** principal); // <> ptr to principal to be freed, returned as NULL
- // (from cc_get_principal())
-
-#ifdef JENNYEXT
-
-CCACHE_API
-cc_free_instance(apiCB* cc_ctx, // > DLL's primary control structure
- char** instance); // <> ptr to instance to be freed, returned as NULL
- // (from cc_get_instance())
-
-#endif
+cc_free_principal(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ char** principal // <> ptr to principal to be freed, returned as NULL
+ // (from cc_get_principal())
+ );
CCACHE_API
-cc_free_name(apiCB* cc_ctx, // > DLL's primary control structure
- char** name); // <> ptr to name to be freed, returned as NULL
- // (from cc_get_name())
+cc_free_name(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ char** name // <> ptr to name to be freed, returned as NULL
+ // (from cc_get_name())
+ );
CCACHE_API
-cc_free_name_list(apiCB* cc_ctx, // > DLL's primary control structure
- char*** name_list); // <> ptr to null terminated list of names to be freed
- // (from cc_get_cache_names()), returned as NULL
-
-CCACHE_API
-cc_free_creds(apiCB* cc_ctx, // > DLL's primary control structure
- cred_union** pCred); // <> cred (from cc_seq_fetch_creds()) to be freed
- // Returned as NULL.
+cc_free_creds(
+ apiCB* cc_ctx, // > DLL's primary control structure
+ cred_union** pCred // <> cred (from cc_seq_fetch_creds()) to be freed
+ // Returned as NULL.
+ );
#ifdef __cplusplus
} /* end extern "C" */
#endif /* __cplusplus */
#endif /* Krb_CCacheAPI_h_ */
-
diff --git a/src/windows/ms2mit/ChangeLog b/src/windows/ms2mit/ChangeLog
new file mode 100644
index 0000000..f2731ff
--- /dev/null
+++ b/src/windows/ms2mit/ChangeLog
@@ -0,0 +1,8 @@
+2001-11-28 Danilo Almeida <dalmeida@mit.edu>
+
+ * ms2mit.c: Make sure we get a des-cbc-crc session key instead of
+ potentially getting whatever happens to be in the cache. Remove
+ unnecessary static variables. Make function headers use a
+ consistent format. Rename ShowLastError() to ShowWinError() and
+ ShowNTError() to ShowLsaError().
+
diff --git a/src/windows/ms2mit/Makefile.in b/src/windows/ms2mit/Makefile.in
new file mode 100644
index 0000000..7a73d6c
--- /dev/null
+++ b/src/windows/ms2mit/Makefile.in
@@ -0,0 +1,22 @@
+# Makefile for the Microsoft to MIT cache converter.
+# Works for k5 release only.
+#
+
+thisconfigdir=./..
+myfulldir=windows/ms2mit
+mydir=.
+MY_SUBDIRS=.
+BUILDTOP=$(REL)$(U)$(S)$(U)
+DEFINES =
+PROG_LIBPATH=-L$(TOPLIBD) -L$(KRB5_LIBDIR)
+
+all-windows:: $(OUTPRE)ms2mit.exe
+
+$(OUTPRE)ms2mit.exe: $(OUTPRE)ms2mit.obj
+ link $(EXE_LINKOPTS) -out:$@ $(OUTPRE)ms2mit.obj user32.lib secur32.lib advapi32.lib $(KLIB) $(CLIB)
+
+install::
+ copy $(OUTPRE)ms2mit.exe $(DESTDIR)
+
+clean::
+ $(RM) $(OUTPRE)*.exe
diff --git a/src/windows/ms2mit/ms2mit.c b/src/windows/ms2mit/ms2mit.c
new file mode 100644
index 0000000..4ec6941
--- /dev/null
+++ b/src/windows/ms2mit/ms2mit.c
@@ -0,0 +1,560 @@
+/*
+ * ms2mit.c
+ *
+ */
+/***********************************************************
+ Copyright 2000 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Carnegie Mellon
+University not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+******************************************************************/
+
+
+#define UNICODE
+#define _UNICODE
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <conio.h>
+#include <time.h>
+#define SECURITY_WIN32
+#include <security.h>
+#include <ntsecapi.h>
+
+#include <krb5.h>
+#include <com_err.h>
+#include <assert.h>
+
+VOID
+ShowWinError(
+ LPSTR szAPI,
+ DWORD dwError
+ )
+{
+#define MAX_MSG_SIZE 256
+
+ // TODO - Write errors to event log so that scripts that don't
+ // check for errors will still get something in the event log
+
+ WCHAR szMsgBuf[MAX_MSG_SIZE];
+ DWORD dwRes;
+
+ printf("Error calling function %s: %lu\n", szAPI, dwError);
+
+ dwRes = FormatMessage (
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ dwError,
+ MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ szMsgBuf,
+ MAX_MSG_SIZE,
+ NULL);
+ if (0 == dwRes) {
+ printf("FormatMessage failed with %d\n", GetLastError());
+ ExitProcess(EXIT_FAILURE);
+ }
+
+ printf("%S",szMsgBuf);
+}
+
+VOID
+ShowLsaError(
+ LPSTR szAPI,
+ NTSTATUS Status
+ )
+{
+ //
+ // Convert the NTSTATUS to Winerror. Then call ShowWinError().
+ //
+ ShowWinError(szAPI, LsaNtStatusToWinError(Status));
+}
+
+
+
+BOOL
+WINAPI
+UnicodeToANSI(
+ LPTSTR lpInputString,
+ LPSTR lpszOutputString,
+ int nOutStringLen
+ )
+{
+#ifndef WIN32S
+ CPINFO CodePageInfo;
+
+ GetCPInfo(CP_ACP, &CodePageInfo);
+
+ if (CodePageInfo.MaxCharSize > 1)
+ // Only supporting non-Unicode strings
+ return FALSE;
+ else if (((LPBYTE) lpInputString)[1] == '\0')
+ {
+ // Looks like unicode, better translate it
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) lpInputString, -1,
+ lpszOutputString, nOutStringLen, NULL, NULL);
+ }
+ else
+ lstrcpyA(lpszOutputString, (LPSTR) lpInputString);
+#else
+ lstrcpy(lpszOutputString, (LPSTR) lpInputString);
+#endif
+ return TRUE;
+} // UnicodeToANSI
+
+VOID
+WINAPI
+ANSIToUnicode(
+ LPSTR lpInputString,
+ LPTSTR lpszOutputString,
+ int nOutStringLen
+ )
+{
+
+#ifndef WIN32S
+ CPINFO CodePageInfo;
+
+ lstrcpy(lpszOutputString, (LPTSTR) lpInputString);
+
+ GetCPInfo(CP_ACP, &CodePageInfo);
+
+ if (CodePageInfo.MaxCharSize > 1)
+ // It must already be a Unicode string
+ return;
+ else if (((LPBYTE) lpInputString)[1] != '\0')
+ {
+ // Looks like ANSI, better translate it
+ MultiByteToWideChar(CP_ACP, 0, (LPCSTR) lpInputString, -1,
+ (LPWSTR) lpszOutputString, nOutStringLen);
+ }
+ else
+ lstrcpy(lpszOutputString, (LPTSTR) lpInputString);
+#endif
+} // ANSIToUnicode
+
+
+void
+MSPrincToMITPrinc(
+ KERB_EXTERNAL_NAME *msprinc,
+ WCHAR *realm,
+ krb5_context context,
+ krb5_principal *principal
+ )
+{
+ WCHAR princbuf[512],tmpbuf[128];
+ char aname[512];
+ USHORT i;
+ princbuf[0]=0;
+ for (i=0;i<msprinc->NameCount;i++) {
+ wcsncpy(tmpbuf, msprinc->Names[i].Buffer,
+ msprinc->Names[i].Length/sizeof(WCHAR));
+ tmpbuf[msprinc->Names[i].Length/sizeof(WCHAR)]=0;
+ if (princbuf[0])
+ wcscat(princbuf, L"/");
+ wcscat(princbuf, tmpbuf);
+ }
+ wcscat(princbuf, L"@");
+ wcscat(princbuf, realm);
+ UnicodeToANSI(princbuf, aname, sizeof(aname));
+ krb5_parse_name(context, aname, principal);
+}
+
+
+time_t
+FileTimeToUnixTime(
+ LARGE_INTEGER *ltime
+ )
+{
+ FILETIME filetime, localfiletime;
+ SYSTEMTIME systime;
+ struct tm utime;
+ filetime.dwLowDateTime=ltime->LowPart;
+ filetime.dwHighDateTime=ltime->HighPart;
+ FileTimeToLocalFileTime(&filetime, &localfiletime);
+ FileTimeToSystemTime(&localfiletime, &systime);
+ utime.tm_sec=systime.wSecond;
+ utime.tm_min=systime.wMinute;
+ utime.tm_hour=systime.wHour;
+ utime.tm_mday=systime.wDay;
+ utime.tm_mon=systime.wMonth-1;
+ utime.tm_year=systime.wYear-1900;
+ utime.tm_isdst=-1;
+ return(mktime(&utime));
+}
+
+void
+MSSessionKeyToMITKeyblock(
+ KERB_CRYPTO_KEY *mskey,
+ krb5_context context,
+ krb5_keyblock *keyblock
+ )
+{
+ krb5_keyblock tmpblock;
+ tmpblock.magic=KV5M_KEYBLOCK;
+ tmpblock.enctype=mskey->KeyType;
+ tmpblock.length=mskey->Length;
+ tmpblock.contents=mskey->Value;
+ krb5_copy_keyblock_contents(context, &tmpblock, keyblock);
+}
+
+
+void
+MSFlagsToMITFlags(
+ ULONG msflags,
+ ULONG *mitflags
+ )
+{
+ *mitflags=msflags;
+}
+
+void
+MSTicketToMITTicket(
+ KERB_EXTERNAL_TICKET *msticket,
+ krb5_context context,
+ krb5_data *ticket
+ )
+{
+ krb5_data tmpdata, *newdata;
+ tmpdata.magic=KV5M_DATA;
+ tmpdata.length=msticket->EncodedTicketSize;
+ tmpdata.data=msticket->EncodedTicket;
+ // todo: fix this up a little. this is ugly and will break krb_free_data()
+ krb5_copy_data(context, &tmpdata, &newdata);
+ memcpy(ticket, newdata, sizeof(krb5_data));
+}
+
+void
+MSCredToMITCred(
+ KERB_EXTERNAL_TICKET *msticket,
+ krb5_context context,
+ krb5_creds *creds
+ )
+{
+ WCHAR wtmp[128];
+ ZeroMemory(creds, sizeof(krb5_creds));
+ creds->magic=KV5M_CREDS;
+ wcsncpy(wtmp, msticket->TargetDomainName.Buffer,
+ msticket->TargetDomainName.Length/sizeof(WCHAR));
+ wtmp[msticket->TargetDomainName.Length/sizeof(WCHAR)]=0;
+ MSPrincToMITPrinc(msticket->ClientName, wtmp, context, &creds->client);
+ wcsncpy(wtmp, msticket->DomainName.Buffer,
+ msticket->DomainName.Length/sizeof(WCHAR));
+ wtmp[msticket->DomainName.Length/sizeof(WCHAR)]=0;
+ MSPrincToMITPrinc(msticket->ServiceName, wtmp, context, &creds->server);
+ MSSessionKeyToMITKeyblock(&msticket->SessionKey, context,
+ &creds->keyblock);
+ MSFlagsToMITFlags(msticket->TicketFlags, &creds->ticket_flags);
+ creds->times.starttime=FileTimeToUnixTime(&msticket->StartTime);
+ creds->times.endtime=FileTimeToUnixTime(&msticket->EndTime);
+ creds->times.renew_till=FileTimeToUnixTime(&msticket->RenewUntil);
+
+ // krb5_cc_store_cred crashes downstream if creds->addresses is NULL.
+ // unfortunately, the MS interface doesn't seem to return a list of
+ // addresses as part of the credentials information. for now i'll just
+ // use krb5_os_localaddr to mock up the address list. is this sufficient?
+ krb5_os_localaddr(context, &creds->addresses);
+
+ MSTicketToMITTicket(msticket, context, &creds->ticket);
+}
+
+BOOL
+PackageConnectLookup(
+ HANDLE *pLogonHandle,
+ ULONG *pPackageId
+ )
+{
+ LSA_STRING Name;
+ NTSTATUS Status;
+
+ Status = LsaConnectUntrusted(
+ pLogonHandle
+ );
+
+ if (FAILED(Status))
+ {
+ ShowLsaError("LsaConnectUntrusted", Status);
+ return FALSE;
+ }
+
+ Name.Buffer = MICROSOFT_KERBEROS_NAME_A;
+ Name.Length = strlen(Name.Buffer);
+ Name.MaximumLength = Name.Length + 1;
+
+ Status = LsaLookupAuthenticationPackage(
+ *pLogonHandle,
+ &Name,
+ pPackageId
+ );
+
+ if (FAILED(Status))
+ {
+ ShowLsaError("LsaLookupAuthenticationPackage", Status);
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+
+DWORD
+ConcatenateUnicodeStrings(
+ UNICODE_STRING *pTarget,
+ UNICODE_STRING Source1,
+ UNICODE_STRING Source2
+ )
+{
+ //
+ // The buffers for Source1 and Source2 cannot overlap pTarget's
+ // buffer. Source1.Length + Source2.Length must be <= 0xFFFF,
+ // otherwise we overflow...
+ //
+
+ USHORT TotalSize = Source1.Length + Source2.Length;
+ PBYTE buffer = (PBYTE) pTarget->Buffer;
+
+ if (TotalSize > pTarget->MaximumLength)
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ pTarget->Length = TotalSize;
+ memcpy(buffer, Source1.Buffer, Source1.Length);
+ memcpy(buffer + Source1.Length, Source2.Buffer, Source2.Length);
+ return ERROR_SUCCESS;
+}
+
+BOOL
+GetMSTGT(
+ HANDLE LogonHandle,
+ ULONG PackageId,
+ KERB_EXTERNAL_TICKET **ticket
+ )
+{
+ //
+ // INVARIANTS:
+ //
+ // (FAILED(Status) || FAILED(SubStatus)) ==> error
+ // bIsLsaError ==> LsaCallAuthenticationPackage() error
+ //
+
+ //
+ // NOTE:
+ //
+ // The updated code leaks memory, but so does the old code. The
+ // whole program is full of leaks. Since it's short-lived
+ // process, it is ok.
+ //
+
+ BOOL bIsLsaError = FALSE;
+ NTSTATUS Status = 0;
+ NTSTATUS SubStatus = 0;
+
+ UNICODE_STRING TargetPrefix;
+
+ KERB_QUERY_TKT_CACHE_REQUEST CacheRequest;
+ PKERB_RETRIEVE_TKT_REQUEST pTicketRequest;
+ PKERB_RETRIEVE_TKT_RESPONSE pTicketResponse = NULL;
+ ULONG RequestSize;
+ ULONG ResponseSize;
+ USHORT TargetSize;
+
+ CacheRequest.MessageType = KerbRetrieveTicketMessage;
+ CacheRequest.LogonId.LowPart = 0;
+ CacheRequest.LogonId.HighPart = 0;
+
+ pTicketResponse = NULL;
+
+ Status = LsaCallAuthenticationPackage(
+ LogonHandle,
+ PackageId,
+ &CacheRequest,
+ sizeof(CacheRequest),
+ &pTicketResponse,
+ &ResponseSize,
+ &SubStatus
+ );
+
+ if (FAILED(Status) || FAILED(SubStatus))
+ {
+ bIsLsaError = TRUE;
+ goto cleanup;
+ }
+
+ if (pTicketResponse->Ticket.SessionKey.KeyType == KERB_ETYPE_DES_CBC_CRC)
+ {
+ // all done!
+ goto cleanup;
+ }
+
+ //
+ // Set up the "krbtgt/" target prefix into a UNICODE_STRING so we
+ // can easily concatenate it later.
+ //
+
+ TargetPrefix.Buffer = L"krbtgt/";
+ TargetPrefix.Length = wcslen(TargetPrefix.Buffer) * sizeof(WCHAR);
+ TargetPrefix.MaximumLength = TargetPrefix.Length;
+
+ //
+ // We will need to concatenate the "krbtgt/" prefix and the previous
+ // response's target domain into our request's target name.
+ //
+ // Therefore, first compute the necessary buffer size for that.
+ //
+ // Note that we might theoretically have integer overflow.
+ //
+
+ TargetSize = TargetPrefix.Length +
+ pTicketResponse->Ticket.TargetDomainName.Length;
+
+ //
+ // The ticket request buffer needs to be a single buffer. That buffer
+ // needs to include the buffer for the target name.
+ //
+
+ RequestSize = sizeof(*pTicketRequest) + TargetSize;
+
+ //
+ // Allocate the request buffer and make sure it's zero-filled.
+ //
+
+ pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
+ LocalAlloc(LMEM_ZEROINIT, RequestSize);
+ if (!pTicketRequest)
+ {
+ Status = GetLastError();
+ goto cleanup;
+ }
+
+ //
+ // Concatenate the target prefix with the previous reponse's
+ // target domain.
+ //
+
+ pTicketRequest->TargetName.Length = 0;
+ pTicketRequest->TargetName.MaximumLength = TargetSize;
+ pTicketRequest->TargetName.Buffer = (PWSTR) (pTicketRequest + 1);
+ Status = ConcatenateUnicodeStrings(&(pTicketRequest->TargetName),
+ TargetPrefix,
+ pTicketResponse->Ticket.TargetDomainName);
+ assert(SUCCEEDED(Status));
+
+ //
+ // Intialize the requst of the request.
+ //
+
+ pTicketRequest->MessageType = KerbRetrieveEncodedTicketMessage;
+ pTicketRequest->LogonId.LowPart = 0;
+ pTicketRequest->LogonId.HighPart = 0;
+ // Note: pTicketRequest->TargetName set up above
+ pTicketRequest->CacheOptions = KERB_RETRIEVE_TICKET_DONT_USE_CACHE;
+ pTicketRequest->TicketFlags = 0L;
+ pTicketRequest->EncryptionType = ENCTYPE_DES_CBC_CRC;
+
+ //
+ // Free the previous response buffer so we can get the new response.
+ //
+
+ LsaFreeReturnBuffer(pTicketResponse);
+ pTicketResponse = NULL;
+
+ Status = LsaCallAuthenticationPackage(
+ LogonHandle,
+ PackageId,
+ pTicketRequest,
+ RequestSize,
+ &pTicketResponse,
+ &ResponseSize,
+ &SubStatus
+ );
+
+ if (FAILED(Status) || FAILED(SubStatus))
+ {
+ bIsLsaError = TRUE;
+ goto cleanup;
+ }
+
+ cleanup:
+ if (FAILED(Status) || FAILED(SubStatus))
+ {
+ if (bIsLsaError)
+ {
+ // XXX - Will be fixed later
+ if (FAILED(Status))
+ ShowLsaError("LsaCallAuthenticationPackage", Status);
+ if (FAILED(SubStatus))
+ ShowLsaError("LsaCallAuthenticationPackage", SubStatus);
+ }
+ else
+ {
+ ShowWinError("GetMSTGT", Status);
+ }
+
+ if (pTicketResponse)
+ LsaFreeReturnBuffer(pTicketResponse);
+
+ return(FALSE);
+ }
+
+ *ticket = &(pTicketResponse->Ticket);
+ return(TRUE);
+}
+
+void
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ krb5_context kcontext;
+ krb5_error_code code;
+ krb5_creds creds;
+ krb5_ccache ccache=NULL;
+ krb5_get_init_creds_opt opts;
+ char *cache_name=NULL;
+ HANDLE LogonHandle=NULL;
+ ULONG PackageId;
+
+ KERB_EXTERNAL_TICKET *msticket;
+ if(!PackageConnectLookup(&LogonHandle, &PackageId))
+ exit(1);
+
+ if (GetMSTGT(LogonHandle, PackageId, &msticket)==FALSE)
+ exit(1);
+ if (code = krb5_init_context(&kcontext)) {
+ com_err(argv[0], code, "while initializing kerberos library");
+ exit(1);
+ }
+ krb5_get_init_creds_opt_init(&opts);
+ MSCredToMITCred(msticket, kcontext, &creds);
+ if (code = krb5_cc_default(kcontext, &ccache)) {
+ com_err(argv[0], code, "while getting default ccache");
+ exit(1);
+ }
+ if (code = krb5_cc_initialize(kcontext, ccache, creds.client)) {
+ com_err (argv[0], code, "when initializing cache %s",
+ cache_name?cache_name:"");
+ exit(1);
+ }
+ if (code = krb5_cc_store_cred(kcontext, ccache, &creds)) {
+ com_err (argv[0], code, "while storing credentials");
+ exit(1);
+ }
+ krb5_cc_close(kcontext, ccache);
+ krb5_free_context(kcontext);
+}
diff --git a/src/windows/version.rc b/src/windows/version.rc
index 67660fc..854db3a 100644
--- a/src/windows/version.rc
+++ b/src/windows/version.rc
@@ -5,6 +5,16 @@
* BEGIN COMMON VERSION INFO for GSS and Kerberos version resources
*/
+// #define PRE_RELEASE
+
+#ifdef PRE_RELEASE
+#define BETA_STR " beta 2"
+#define BETA_FLAG VS_FF_PRERELEASE
+#else
+#define BETA_STR ""
+#define BETA_FLAG 0
+#endif
+
#if !defined(_WIN32)
#define Targ_OS VOS__WINDOWS16
#else
@@ -13,10 +23,10 @@
/* we're going to stamp all the DLLs with the same version number */
-#define K5_PRODUCT_VERSION_STRING "1.1.1\0"
-#define K5_PRODUCT_VERSION 1, 1, 1, 0
+#define K5_PRODUCT_VERSION_STRING "1.2.8" BETA_STR "\0"
+#define K5_PRODUCT_VERSION 1, 2, 8, 0
-#define K5_COPYRIGHT "Copyright (C) 1997-1999 by the Massachusetts Institute of Technology\0"
+#define K5_COPYRIGHT "Copyright (C) 1997-2001 by the Massachusetts Institute of Technology\0"
#define K5_COMPANY_NAME "Massachusetts Institute of Technology.\0"
/*
@@ -134,7 +144,7 @@ VS_VERSION_INFO VERSIONINFO
FILEVERSION K5_PRODUCT_VERSION
PRODUCTVERSION K5_PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
-FILEFLAGS (VS_FF_DEBUG | VS_FF_PRIVATEBUILD)
+FILEFLAGS (VS_FF_DEBUG | VS_FF_PRIVATEBUILD | BETA_FLAG)
FILEOS Targ_OS
FILETYPE K5_FILETYPE
BEGIN
diff --git a/src/windows/wintel/ChangeLog b/src/windows/wintel/ChangeLog
index a9d6900..f8526d9 100644
--- a/src/windows/wintel/ChangeLog
+++ b/src/windows/wintel/ChangeLog
@@ -1,3 +1,9 @@
+2000-05-08 Nalin Dahyabhai <nalin@redhat.com>
+
+ * auth.c (auth_abort): Don't overflow buffer "strTmp".
+ (k4_auth_send): Don't overflow buffer "dbgbuf".
+ * encrypt.c (printsub): Don't overflow buffer "p".
+
1999-12-03 Danilo Almeida <dalmeida@mit.edu>
* Makefile.in: Windows fix for updated win-pre.in.
diff --git a/src/windows/wintel/auth.c b/src/windows/wintel/auth.c
index 5e9d1d2..28f515b 100644
--- a/src/windows/wintel/auth.c
+++ b/src/windows/wintel/auth.c
@@ -151,10 +151,11 @@ auth_abort(kstream ks, char *errmsg, long r)
TelnetSend(ks, (LPSTR)buf, 8, 0);
if (errmsg != NULL) {
- strcpy(strTmp, errmsg);
+ strTmp[sizeof(strTmp) - 1] = '\0';
+ strncpy(strTmp, errmsg, sizeof(strTmp) - 1);
if (r != KSUCCESS) {
- strcat(strTmp, "\n");
+ strncat(strTmp, "\n", sizeof(strTmp) - 1 - strlen(strTmp));
#ifdef KRB4
lstrcat(strTmp, krb_get_err_text((int)r));
#endif
@@ -423,8 +424,8 @@ k4_auth_send(kstream ks)
if (!realm) {
strcpy(buf, "Can't find realm for host \"");
- strcat(buf, szHostName);
- strcat(buf, "\"");
+ strncat(buf, szHostName, sizeof(buf) - 1 - strlen(buf));
+ strncat(buf, "\"", sizeof(buf) - 1 - strlen(buf));
auth_abort(ks, buf, 0);
return KFAILURE;
}
@@ -436,14 +437,14 @@ k4_auth_send(kstream ks)
if (r) {
strcpy(buf, "Can't get \"");
- strcat(buf, KRB_SERVICE_NAME);
+ strncat(buf, KRB_SERVICE_NAME, sizeof(buf) - 1 - strlen(buf));
if (instance[0] != 0) {
- strcat(buf, ".");
+ strncat(buf, ".", sizeof(buf) - 1 - strlen(buf));
lstrcat(buf, instance);
}
- strcat(buf, "@");
+ strncat(buf, "@", sizeof(buf) - 1 - strlen(buf));
lstrcat(buf, realm);
- strcat(buf, "\" ticket");
+ strncat(buf, "\" ticket", sizeof(buf) - 1 - strlen(buf));
auth_abort(ks, buf, r);
return r;
diff --git a/src/windows/wintel/encrypt.c b/src/windows/wintel/encrypt.c
index f1a1301..bbb5496 100644
--- a/src/windows/wintel/encrypt.c
+++ b/src/windows/wintel/encrypt.c
@@ -230,10 +230,11 @@ printsub(char c, unsigned char *s, size_t len)
*p++ = c;
- for (i = 0 ; i < len ; i++)
+ for (i = 0 ; (i < len) && (p - dbgbuf + 3 < sizeof(dbgbuf)) ; i++)
p += sprintf(p, "%02x ", s[i]);
+ dbgbuf[sizeof(dbgbuf) - 1] = '\0';
- strcat(p, "\n");
+ strncat(p, "\n", sizeof(dbgbuf) - 1 - (p - dbgbuf));
OutputDebugString(dbgbuf);