diff options
Diffstat (limited to 'src/windows')
-rw-r--r-- | src/windows/ChangeLog | 83 | ||||
-rw-r--r-- | src/windows/Makefile.in | 6 | ||||
-rw-r--r-- | src/windows/README | 48 | ||||
-rw-r--r-- | src/windows/cns/ChangeLog | 14 | ||||
-rw-r--r-- | src/windows/cns/cns.c | 34 | ||||
-rw-r--r-- | src/windows/cns/cns_reg.c | 8 | ||||
-rw-r--r-- | src/windows/cns/tktlist.c | 23 | ||||
-rw-r--r-- | src/windows/lib/ChangeLog | 4 | ||||
-rw-r--r-- | src/windows/lib/cacheapi.h | 455 | ||||
-rw-r--r-- | src/windows/ms2mit/ChangeLog | 8 | ||||
-rw-r--r-- | src/windows/ms2mit/Makefile.in | 22 | ||||
-rw-r--r-- | src/windows/ms2mit/ms2mit.c | 560 | ||||
-rw-r--r-- | src/windows/version.rc | 18 | ||||
-rw-r--r-- | src/windows/wintel/ChangeLog | 6 | ||||
-rw-r--r-- | src/windows/wintel/auth.c | 17 | ||||
-rw-r--r-- | src/windows/wintel/encrypt.c | 5 |
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); |