From 7029886dba72c0504dfc528893dc7d6e98d51e07 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Wed, 27 May 1998 19:51:25 +0000 Subject: Folded in enhancements from Cygnus's Kerbnet-1.2 (plus our changes made since Cygnus's last snapshot). See ChangeLog from Cygnus (included in the ChangeLog file) for more details. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10598 dc483132-0cff-0310-8789-dd5450dbe970 --- src/windows/cns/ChangeLog | 75 ++++------ src/windows/cns/Makefile.in | 78 ++++++++--- src/windows/cns/cns.c | 335 +++++++++++++++++++------------------------- src/windows/cns/cns.h | 33 +++-- src/windows/cns/cns_reg.c | 217 ++++++++++++++++++++++++++++ src/windows/cns/cns_reg.h | 32 +++++ src/windows/cns/cnsres5.rc | 10 +- src/windows/cns/debug.c | 1 - src/windows/cns/kpasswd.c | 266 ++++++++++------------------------- src/windows/cns/krbini.h | 37 +++++ src/windows/cns/options.c | 171 +++++++--------------- src/windows/cns/password.c | 21 ++- src/windows/cns/tktlist.c | 9 -- 13 files changed, 678 insertions(+), 607 deletions(-) create mode 100644 src/windows/cns/cns_reg.c create mode 100644 src/windows/cns/cns_reg.h create mode 100644 src/windows/cns/krbini.h (limited to 'src') diff --git a/src/windows/cns/ChangeLog b/src/windows/cns/ChangeLog index d6c555f2e8..1a835147f5 100644 --- a/src/windows/cns/ChangeLog +++ b/src/windows/cns/ChangeLog @@ -1,48 +1,39 @@ -Tue Aug 5 18:44:45 1997 Theodore Y. Ts'o +1998-05-27 Theodore Ts'o - * Makefile.in, cnsres5.rc: Add a version resource to the - executable. + * Folded in enhancements from Cygnus's Kerbnet-1.2 (plus our + changes made since Cygnus's last snapshot). See + ChangeLog from Cygnus (included below) for more details. -Mon Jul 28 23:33:11 1997 Theodore Y. Ts'o +---------------------- Begin of ChangeLog from Cygnus - * Makefile.in: Take out the /nod option, and remove libc.lib from - the list of libraries to be linked. +Fri Mar 28 15:12:28 1997 Michael Graff -Mon Feb 17 13:58:06 1997 Richard Basch + * Makefile.in, cns.c, options.c: use the registry now, not an ini file. - * Makefile.in: Winsock library is still required for win16 - * cns.h: Don't include krb5ini.h (obsolete file) + * cns_reg.c, cns_reg.h: registry functions. -Sat Feb 15 12:21:51 1997 Richard Basch +Wed Mar 12 17:32:59 1997 Michael Graff - * Makefile.in: Link in ComErr library $(CLIB) - * cns.c: Winsock initialization/teardown is handled by krb5 lib + * cns.h, passwd.c, kpasswd.c: use krb5_change_password() rather + than rolling our own. -Mon Feb 10 23:19:26 1997 Richard Basch + * cnsres5.rc: remove forced uppercase realm name - * Makefile.in: Use WLIB definition in config/windows.in +Wed Mar 5 19:13:31 1997 Michael Graff -Fri Feb 7 08:08:39 1997 Richard Basch + * cns.c: Start to use init creds stuff. - * cns.c (blocking_hook_proc): Additional logic is required to - prevent instantaneous timeouts when GetTickCount() - wraps every 49.7 days. Declared function with old - __export convention so that it works properly in Win16. +Mon Nov 4 21:46:52 1996 Michael Graff -Sun Feb 2 11:22:57 1997 Richard Basch + * cns.c: update name from Kerb*Net to KerbNet - * cns.c (k5_name_from_ccache): - Declare variable as (char FAR *) to match - krb5_unparse_name prototype + * cns.h: add length to extern character array to give the compiler + more of a hint. - * Makefile.in: Build using CCOPTS2, not COPTS (win16) + * kpasswd.c: remove two unused variables. -Fri Dec 20 10:28:59 1996 Theodore Y. Ts'o - - * krb5.def: New file, modelled after krbnet.def - - * cns.h, cns.c, krbini.h, cnsres5.c, Makefile: remove - Cygnus/KerbNet(tm) name from MIT distribution + * tktlist.c: Pull definition of MAX_K_NAME_SZ from cns.h rather + than having a local definition. Fri Aug 9 03:41:52 1996 Michael Graff @@ -50,7 +41,7 @@ Fri Aug 9 03:41:52 1996 Michael Graff * cns.def: rename to kerbnet.def -Wed Aug 7 14:25:34 1996 Michael Graff +Wed Aug 7 14:25:34 1996 Michael Graff * Makefile.in: Build kerbnet, not cns.exe @@ -71,7 +62,7 @@ Sat Aug 3 13:58:20 1996 Jeff Bigler * Makefile.in: added line to install section to install help file. -Thu Jul 25 13:52:04 1996 +Thu Jul 25 13:52:04 1996 * options.c (opts_command): Display a warning message when changing the location of the krb.conf file, since the KRB5 libraries @@ -84,7 +75,7 @@ Wed Aug 7 18:03:16 1996 Jeff Bigler * kerbnet.doc: help file (Microsoft Word document) * kerbnet.hlp: new help file (Windows help file) -Wed Jul 24 06:12:24 1996 Michael Graff +Wed Jul 24 06:12:24 1996 Michael Graff * Makefile.in: Build cnsres[45].rc into executable, depending on if we're compiling for V4 or V5. @@ -99,7 +90,7 @@ Wed Jul 24 06:12:24 1996 Michael Graff * cnsres5.rc: * krbini.h: Add forwardable option to options menu -Tue Jul 16 12:42:48 1996 Michael Graff +Tue Jul 16 12:42:48 1996 Michael Graff * options.c: * password.c: Split parts of cns.c into these files. Each deals @@ -108,7 +99,7 @@ Tue Jul 16 12:42:48 1996 Michael Graff * debug.c: * heap.c: Added to aid in debugging. -Wed Jul 10 18:01:03 1996 Michael Graff +Wed Jul 10 18:01:03 1996 Michael Graff * cns.c: Remove the quick hacks mentioned below. @@ -119,7 +110,7 @@ Thu Jul 25 13:52:04 1996 will have opened it and tucked it away in krb5_context->profile, which we as a client don't have access to. -Fri Jun 28 19:29:14 1996 Michael Graff +Fri Jun 28 19:29:14 1996 Michael Graff * cns.c: Really quick hacks to disable some features that just plain don't work correctly. The "cns" client has some flavor of @@ -128,7 +119,7 @@ Fri Jun 28 19:29:14 1996 Michael Graff * cnsres5.rc: reload this using a dialog editor. Add clickbox for "ticket options" of "forwardable" -Wed Jun 26 14:58:23 1996 Michael Graff +Wed Jun 26 14:58:23 1996 Michael Graff * cns.h kpasswd.c: formatting change, including changing // to /* */ @@ -141,19 +132,13 @@ Wed Jun 26 14:58:23 1996 Michael Graff of the details of 16- vs 32-bit hidden to the code. (Disgusting magic happens in ) -Tue Jun 25 13:57:59 1996 Michael Graff +Tue Jun 25 13:57:59 1996 Michael Graff * Makefile.in: Fix to work for WIN32 native compiles. Many changes; some should be put into common files (win-post.in or windows.in?) -Wed Jun 12 00:20:08 1996 Theodore Ts'o - - * makefile: Renamed to Makefile.in, so that we can do WIN16/WIN32 - specializations. Remove /nologo option for Win32 RFLAGS, - since RC apparently doesn't support it. - - * changelo: Renamed to ChangeLog, to make life easier. +---------------------- End of ChangeLog from Cygnus Wed Jan 10 23:16:41 1996 Theodore Y. Ts'o diff --git a/src/windows/cns/Makefile.in b/src/windows/cns/Makefile.in index 8d4a6f26b7..2c4eef30dd 100644 --- a/src/windows/cns/Makefile.in +++ b/src/windows/cns/Makefile.in @@ -1,59 +1,91 @@ -# makefile: Constructs the Kerberos for Windows ticket manager +# Makefile for the Kerberos for Windows ticket manager # Works for both k4 and k5 releases. # NAME = krb5 OBJS = cns.obj tktlist.obj password.obj options.obj ##### Options +DEBUG=yes !IF ! defined(KVERSION) KVERSION = 5 !endif KRB = KRB$(KVERSION) +!if $(KVERSION) == 4 +BUILDTOP = .. +LIBDIR = $(BUILDTOP)\lib\krb +KLIB = $(LIBDIR)\kerberos.lib +##WIN16##WLIB = $(LIBDIR)\winsock.lib +INCLUDES = /I$(BUILDTOP)\include +##WIN16##XOBJS = +##WIN32##XOBJS = cnsres4.obj +!endif + +!if $(KVERSION) == 5 BUILDTOP =..\.. +LIBDIR = $(BUILDTOP)\lib INCLUDES = /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 +##WIN16##XOBJS = kpasswd.obj +##WIN32##XOBJS = cnsres5.obj kpasswd.obj cns_reg.obj +!endif -##DOS##XOBJS = kpasswd.obj - -CFLAGS = $(CCOPTS2) $(INCLUDES) /D$(KRB)=1 +##### C Compiler +#CC = cl +!if defined(DEBUG) +CFLAGS = $(CCOPTS2) $(INCLUDES) /D$(KRB)=1 /Zi /Yd /DDEBUG +!else +CFLAGS = $(CCOPTS2) $(INCLUDES) /D$(KRB)=1 +!endif +##### RC Compiler +RC = rc ##WIN16##RFLAGS = /nologo /D$(KRB)=1 $(INCLUDES) ##WIN32##RFLAGS = /D$(KRB)=1 $(INCLUDES) +##### CVSRES -- .res -> .obj converter +CVTRES = cvtres + ##### Linker LINK = link -LIBS = $(KLIB) $(CLIB) $(WLIB) +LIBS = $(KLIB) $(CLIB) $(WLIB) ../lib/libwin.lib ##WIN16##SYSLIBS = libw llibcew -##WIN16##LFLAGS = /nologo /nod /nopackcode -##WIN32##LFLAGS = /nologo -##WIN32##SYSLIBS = kernel32.lib wsock32.lib user32.lib gdi32.lib +!if defined(DEBUG) +##WIN16##LFLAGS = /co /nologo /nod /nopackcode /map:full +##WIN32##LFLAGS = /nologo /debug +##WIN32##SYSLIBS = kernel32.lib wsock32.lib user32.lib gdi32.lib advapi32.lib +!else +##WIN16##LFLAGS = /nologo /nod /nopackcode +##WIN32##LFLAGS = /nologo +##WIN32##SYSLIBS = kernel32.lib wsock32.lib user32.lib gdi32.lib advapi32.lib +!endif all:: makefile $(NAME).exe $(NAME).exe: $*.def $(OBJS) $(XOBJS) $(LIBS) ##WIN16## $(LINK) $(LFLAGS) $(OBJS) $(XOBJS), $@, $*.map, \ ##WIN16## $(LIBS) $(SYSLIBS), $*.def -##WIN16## $(RC) $(RFLAGS) /k -DKRB5_APP cnsres5.rc $@ -##WIN32## $(RC) $(RFLAGS) /r -D_WIN32 -DKRB5_APP cnsres5.rc +##WIN16## $(RC) $(RFLAGS) -DKRB5_APP /k cnsres4.res $@ ##WIN32## $(LINK) $(LFLAGS) /map:$*.map /out:$@ $(OBJS) $(XOBJS) \ -##WIN32## $(LIBS) $(SYSLIBS) cnsres5.res +##WIN32## $(LIBS) $(SYSLIBS) + +##WIN32##.rc.obj: +##WIN32## $(RC) $(RFLAGS) -DKRB5_APP /r $*.rc +##WIN32## $(CVTRES) /nologo /out:$*.obj $*.res install:: $(CP) $(NAME).exe $(DESTDIR) - $(CP) $(NAME).hlp $(DESTDIR) + $(CP) krb5.hlp $(DESTDIR) clean:: - if exist *.obj del *.obj - if exist *.exe del *.exe - if exist *.res del *.res - if exist *.map del *.map - if exist *.pdb del *.pdb - if exist *.err del *.err + $(RM) *.exe + $(RM) *.res + $(RM) *.map $(OBJS): cns.h tktlist.h -cns.res: cns.h \ - clock00.ico clock05.ico clock10.ico clock15.ico clock20.ico \ - clock25.ico clock30.ico clock35.ico clock40.ico clock45.ico \ - clock50.ico clock55.ico clock60.ico clockexp.ico clocktkt.ico \ - cns.ico +cns.res: cns.h + +cns.res: clock00.ico clock05.ico clock10.ico clock15.ico clock20.ico \ + clock25.ico clock30.ico clock35.ico clock40.ico clock45.ico \ + clock50.ico clock55.ico clock60.ico clockexp.ico clocktkt.ico \ + cns.ico diff --git a/src/windows/cns/cns.c b/src/windows/cns/cns.c index 205f933252..8999d9f98c 100644 --- a/src/windows/cns/cns.c +++ b/src/windows/cns/cns.c @@ -10,10 +10,6 @@ * . */ -#if !defined(KRB5) && !defined(KRB4) -#error "Must define either KRB4 or KRB5" -#endif - #include #include @@ -27,6 +23,9 @@ #include "cns.h" #include "tktlist.h" +#include "cns_reg.h" + +#include "../lib/gic.h" enum { /* Actions after login */ LOGIN_AND_EXIT, @@ -34,12 +33,6 @@ enum { /* Actions after login */ LOGIN_AND_RUN, }; -#ifndef _WIN32 -typedef MINMAXINFO *LPMINMAXINFO; -#define GET_WM_COMMAND_MPS(id, hwnd, cmd) \ - (WPARAM)MAKELONG(id, cmd), (LONG)(hwnd) -#endif - /* * Globals */ @@ -55,7 +48,6 @@ BOOL alert; /* Actions on ticket expiration */ BOOL beep; static BOOL alerted; /* TRUE when user already alerted */ BOOL isblocking = FALSE; /* TRUE when blocked in WinSock */ -static DWORD blocking_timeout; /* Blocking timeout */ static DWORD blocking_end_time; /* Ending count for blocking timeout */ static FARPROC hook_instance; /* handle for blocking hook function */ @@ -76,21 +68,13 @@ krb5_ccache k5_ccache; * * Returns: TRUE if we got and dispatched a message, FALSE otherwise. */ -BOOL __export CALLBACK +BOOL CALLBACK blocking_hook_proc(void) { MSG msg; BOOL rc; - DWORD now; - /* - * The additional timeout logic is required because GetTickCount will - * wrap approximately every 49.7 days. - */ - now = GetTickCount(); - if (now >= blocking_end_time && - (blocking_end_time >= blocking_end_time - blocking_timeout || - now < blocking_end_time - blocking_timeout)) { + if (GetTickCount() > blocking_end_time) { WSACancelBlockingCall(); return FALSE; } @@ -127,8 +111,7 @@ start_blocking_hook(int timeout) return; isblocking = TRUE; - blocking_timeout = 1000 * timeout; - blocking_end_time = GetTickCount() + blocking_timeout; + blocking_end_time = GetTickCount() + (1000 * timeout); #ifdef _WIN32 proc = WSASetBlockingHook(blocking_hook_proc); #else @@ -193,10 +176,8 @@ center_dialog(HWND hwnd) static void position_dialog(HWND hwnd) { - int n; int scrwidth, scrheight; HDC hdc; - char position[256]; int x, y, cx, cy; if (hwnd == NULL) @@ -206,12 +187,12 @@ position_dialog(HWND hwnd) scrwidth = GetDeviceCaps(hdc, HORZRES); scrheight = GetDeviceCaps(hdc, VERTRES); ReleaseDC(NULL, hdc); - GetPrivateProfileString(INI_DEFAULTS, INI_POSITION, "", - position, sizeof(position), KERBEROS_INI); + x = cns_res.x; + y = cns_res.y; + cx = cns_res.cx; + cy = cns_res.cy; - n = sscanf(position, " [%d , %d , %d , %d", &x, &y, &cx, &cy); - if (n != 4 || - x > scrwidth || + if (x > scrwidth || y > scrheight || x + cx < 0 || y + cy < 0) @@ -477,7 +458,6 @@ kwin_init_file_menu(HWND hwnd) { HMENU hmenu; int i; - char login[sizeof(INI_LOGIN)+1]; char menuitem[MAX_K_NAME_SZ + 3]; int id; BOOL rc; @@ -488,13 +468,10 @@ kwin_init_file_menu(HWND hwnd) hmenu = GetSubMenu(hmenu, 0); assert(hmenu != NULL); - strcpy(login, INI_LOGIN); id = 0; for (i = 0; i < FILE_MENU_MAX_LOGINS; i++) { - login[sizeof(INI_LOGIN) - 1] = '1' + i; - login[sizeof(INI_LOGIN)] = 0; - GetPrivateProfileString(INI_RECENT_LOGINS, login, "", - &menuitem[3], sizeof(menuitem) - 3, KERBEROS_INI); + strcpy(menuitem + 3, cns_res.logins[i]); + if (!menuitem[3]) continue; @@ -527,8 +504,6 @@ kwin_save_file_menu(HWND hwnd) int id; int ctitems; char menuitem[MAX_K_NAME_SZ + 3]; - char login[sizeof(INI_LOGIN)+1]; - BOOL rc; hmenu = GetMenu(hwnd); assert(hmenu != NULL); @@ -536,19 +511,14 @@ kwin_save_file_menu(HWND hwnd) hmenu = GetSubMenu(hmenu, 0); assert(hmenu != NULL); - strcpy(login, INI_LOGIN); ctitems = GetMenuItemCount(hmenu); assert(ctitems >= FILE_MENU_ITEMS); id = 0; for (i = FILE_MENU_ITEMS + 1; i < ctitems; i++) { GetMenuString(hmenu, i, menuitem, sizeof(menuitem), MF_BYPOSITION); - login[sizeof(INI_LOGIN) - 1] = '1' + id; - login[sizeof(INI_LOGIN)] = 0; - rc = WritePrivateProfileString(INI_RECENT_LOGINS, login, - &menuitem[3], KERBEROS_INI); - assert(rc); + strcpy(cns_res.logins[id], menuitem + 3); id++; } @@ -607,18 +577,15 @@ kwin_init_name(HWND hwnd, char *fullname) if (fullname == NULL || fullname[0] == 0) { #ifdef KRB4 strcpy(name, krb_get_default_user()); - GetPrivateProfileString(INI_DEFAULTS, INI_INSTANCE, "", - instance, sizeof(instance), KERBEROS_INI); + strcpy(instance, cns_res.instance); krc = krb_get_lrealm(realm, 1); if (krc != KSUCCESS) realm[0] = 0; - GetPrivateProfileString(INI_DEFAULTS, INI_REALM, realm, - realm, sizeof(realm), KERBEROS_INI); + strcpy(realm, cns_res.realm); #endif /* KRB4 */ #ifdef KRB5 - GetPrivateProfileString(INI_DEFAULTS, INI_USER, "", - name, sizeof(name), KERBEROS_INI); + strcpy(name, cns_res.name); *realm = '\0'; code = krb5_get_default_realm(k5_context, &ptr); @@ -626,8 +593,7 @@ kwin_init_name(HWND hwnd, char *fullname) strcpy(realm, ptr); /* free(ptr); XXX */ } - GetPrivateProfileString(INI_DEFAULTS, INI_REALM, realm, - realm, sizeof(realm), KERBEROS_INI); + strcpy(realm, cns_res.realm); #endif /* KRB5 */ } else { @@ -702,18 +668,17 @@ kwin_save_name(HWND hwnd) krb_set_default_user(name); GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); trim(instance); - WritePrivateProfileString(INI_DEFAULTS, INI_INSTANCE, - instance, KERBEROS_INI); + strcpy(cns_res.instance, instance); #endif #ifdef KRB5 - WritePrivateProfileString(INI_DEFAULTS, INI_USER, name, KERBEROS_INI); + strcpy(cns_res.name, name); *instance = '\0'; #endif GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); trim(realm); - WritePrivateProfileString(INI_DEFAULTS, INI_REALM, realm, KERBEROS_INI); + strcpy(cns_res.realm, realm); kwin_push_login(hwnd, name, instance, realm); } @@ -790,9 +755,7 @@ kwin_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) static void kwin_destroy(HWND hwnd) { - char position[256]; RECT r; - BOOL b; ticket_destroy(GetDlgItem(hwnd, IDD_TICKET_LIST)); @@ -804,11 +767,10 @@ kwin_destroy(HWND hwnd) kwin_save_file_menu(hwnd); GetWindowRect(hwnd, &r); - sprintf(position, "[%d,%d,%d,%d]", r.left, r.top, - r.right - r.left, r.bottom - r.top); - b = WritePrivateProfileString(INI_DEFAULTS, INI_POSITION, - position, KERBEROS_INI); - assert(b); + cns_res.x = r.left; + cns_res.y = r.top; + cns_res.cx = r.right - r.left; + cns_res.cy = r.bottom - r.top; KillTimer(hwnd, kwin_timer_id); } @@ -1120,27 +1082,27 @@ kwin_timer(HWND hwnd, UINT timer_id) static void kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) { - char name[ANAME_SZ]; - char realm[REALM_SZ]; - char password[MAX_KPW_LEN]; - HCURSOR hcursor; - BOOL blogin; - HMENU hmenu; - char menuitem[MAX_K_NAME_SZ + 3]; - char copyright[128]; - int id; + char name[ANAME_SZ]; + char realm[REALM_SZ]; + char password[MAX_KPW_LEN]; + HCURSOR hcursor; + BOOL blogin; + HMENU hmenu; + char menuitem[MAX_K_NAME_SZ + 3]; + char copyright[128]; + int id; #ifdef KRB4 - char instance[INST_SZ]; - int lifetime; - int krc; + char instance[INST_SZ]; + int lifetime; + int krc; #endif #ifdef KRB5 - long lifetime; - krb5_error_code code; - krb5_principal principal; - krb5_creds creds; - krb5_principal server; - krb5_int32 sec, usec; + long lifetime; + krb5_error_code code; + krb5_principal principal; + krb5_creds creds; + krb5_get_init_creds_opt opts; + gic_data gd; #endif #ifdef KRB4 @@ -1223,15 +1185,16 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); trim(realm); GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password)); + SetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, ""); /* nuke the password */ trim(password); + #ifdef KRB4 GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); trim(instance); #endif hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); - lifetime = GetPrivateProfileInt(INI_OPTIONS, INI_DURATION, - DEFAULT_TKT_LIFE * 5, KERBEROS_INI); + lifetime = cns_res.lifetime; start_blocking_hook(BLOCK_MAX_SEC); #ifdef KRB4 @@ -1241,83 +1204,74 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) #endif #ifdef KRB5 - do { - principal = server = NULL; - memset(&creds, 0, sizeof(creds)); - - sprintf(menuitem, "%s@%s", name, realm); - code = krb5_parse_name(k5_context, menuitem, &principal); - if (code) - break; - - code = krb5_cc_initialize(k5_context, k5_ccache, principal); - if (code) - break; - - code = krb5_build_principal_ext(k5_context, &server, - krb5_princ_realm(k5_context, principal)->length, - krb5_princ_realm(k5_context, principal)->data, - KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, - krb5_princ_realm(k5_context, principal)->length, - krb5_princ_realm(k5_context, principal)->data, 0); - if (code) - break; - - creds.client = principal; - creds.server = server; - - code = krb5_us_timeofday(k5_context, &sec, &usec); - if (code) - break; - creds.times.starttime = 0; - creds.times.endtime = sec + 60L * lifetime; - creds.times.renew_till = 0; - - /* - * XXX whether or not the credentials should be - * forwardable should be a configurable option in the - * UI. - */ - code = krb5_get_in_tkt_with_password(k5_context, - (forwardable ? KDC_OPT_FORWARDABLE : 0), - NULL, NULL, - NULL, password, k5_ccache, - &creds, 0); - } while (0); - + principal = NULL; + + /* + * convert the name + realm into a krb5 principal string and parse it into a principal + */ + sprintf(menuitem, "%s@%s", name, realm); + code = krb5_parse_name(k5_context, menuitem, &principal); + if (code) + goto errorpoint; + + /* + * set the various ticket options. First, initialize the structure, then set the ticket + * to be forwardable if desired, and set the lifetime. + */ + krb5_get_init_creds_opt_init(&opts); + krb5_get_init_creds_opt_set_forwardable(&opts, forwardable); + krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime * 60); + + /* + * get the initial creds using the password and the options we set above + */ + gd.hinstance = hinstance; + gd.hwnd = hwnd; + gd.id = ID_VARDLG; + code = krb5_get_init_creds_password(k5_context, &creds, principal, password, + gic_prompter, &gd, 0, NULL, &opts); + if (code) + goto errorpoint; + + /* + * initialize the credential cache + */ + code = krb5_cc_initialize(k5_context, k5_ccache, principal); + if (code) + goto errorpoint; + + /* + * insert the principal into the cache + */ + code = krb5_cc_store_cred(k5_context, k5_ccache, &creds); + + errorpoint: + if (principal) krb5_free_principal(k5_context, principal); - if (server) - krb5_free_principal(k5_context, server); - -#endif /* KRB5 */ - end_blocking_hook(); SetCursor(hcursor); kwin_set_default_focus(hwnd); - -#ifdef KRB4 - if (krc != KSUCCESS) { - MessageBox(hwnd, krb_get_err_text(krc), "", - MB_OK | MB_ICONEXCLAMATION); - - return; /* TRUE */ - } -#endif - -#ifdef KRB5 + if (code) { if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) MessageBox(hwnd, "Password incorrect", NULL, MB_OK | MB_ICONEXCLAMATION); else com_err(NULL, code, "while logging in"); + } +#endif /* KRB5 */ + +#ifdef KRB4 + if (krc != KSUCCESS) { + MessageBox(hwnd, krb_get_err_text(krc), "", + MB_OK | MB_ICONEXCLAMATION); + return; /* TRUE */ } #endif - SetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, ""); kwin_save_name(hwnd); alerted = FALSE; @@ -1378,25 +1332,22 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) if (isblocking) return; /* TRUE */ -#ifdef CYGNUS - strcpy(copyright, " KerbNet for Windows "); +#ifdef KRB4 + strcpy(copyright, " Kerberos 4 for Windows "); +#endif +#ifdef KRB5 + strcpy(copyright, " Kerberos V5 for Windows "); +#endif #ifdef _WIN32 strcat(copyright, "32-bit\n"); #else strcat(copyright, "16-bit\n"); #endif - strcat(copyright, "\n Version 1.11\n\n"); - strcat(copyright, " For support, contact:\n"); + strcat(copyright, "\n Version 1.12\n\n"); +#ifdef ORGANIZATION + strcat(copyright, " For information, contact:\n"); strcat(copyright, ORGANIZATION); -#else /* Cygnus */ - strcpy(copyright, " Kerberos V5 for Windows "); -#ifdef _WIN32 - strcat(copyright, "32-bit\n"); -#else - strcat(copyright, "16-bit\n"); #endif - strcat(copyright, "\n Version 1.11\n\n"); -#endif /* Cygnus */ MessageBox(hwnd, copyright, KWIN_DIALOG_NAME, MB_OK); return; /* TRUE */ @@ -1544,10 +1495,12 @@ kwin_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } switch (message) { - HANDLE_MSG(hwnd, WM_GETMINMAXINFO, kwin_getminmaxinfo); + HANDLE_MSG(hwnd, WM_DESTROY, kwin_destroy); + HANDLE_MSG(hwnd, WM_MEASUREITEM, ticket_measureitem); + HANDLE_MSG(hwnd, WM_DRAWITEM, ticket_drawitem); case WM_SETCURSOR: @@ -1558,8 +1511,11 @@ kwin_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; HANDLE_MSG(hwnd, WM_SIZE, kwin_size); + HANDLE_MSG(hwnd, WM_SYSCOMMAND, kwin_syscommand); + HANDLE_MSG(hwnd, WM_TIMER, kwin_timer); + HANDLE_MSG(hwnd, WM_PAINT, kwin_paint); case WM_ERASEBKGND: @@ -1584,6 +1540,7 @@ kwin_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { HANDLE_MSG(hwnd, WM_INITDIALOG, kwin_initdialog); + HANDLE_MSG(hwnd, WM_COMMAND, kwin_command); } @@ -1643,6 +1600,7 @@ init_application(HINSTANCE hinstance) #ifdef KRB4 wm_kerberos_changed = krb_get_notification_message(); #endif + #ifdef KRB5 wm_kerberos_changed = krb5_get_notification_message(); #endif @@ -1683,11 +1641,10 @@ quit_application(HINSTANCE hinstance) static BOOL init_instance(HINSTANCE hinstance, int ncmdshow) { - char buf[20]; - int i; - int rc; WORD versionrequested; WSADATA wsadata; + int rc; + int i; versionrequested = 0x0101; /* We need version 1.1 */ rc = WSAStartup(versionrequested, &wsadata); @@ -1706,22 +1663,37 @@ init_instance(HINSTANCE hinstance, int ncmdshow) return FALSE; } +#ifdef KRB5 + { + krb5_error_code code; + + code = krb5_init_context(&k5_context); + if (!code) { +#if 0 /* Not needed under windows */ + krb5_init_ets(k5_context); +#endif + code = k5_init_ccache(&k5_ccache); + } + if (code) { + com_err(NULL, code, "while initializing program"); + return FALSE; + } + k5_name_from_ccache(k5_ccache); + } +#endif + + cns_load_registry(); + /* * Set up expiration action */ - GetPrivateProfileString(INI_EXPIRATION, INI_ALERT, "No", - buf, sizeof(buf), KERBEROS_INI); - alert = _stricmp(buf, "Yes") == 0; - GetPrivateProfileString(INI_EXPIRATION, INI_BEEP, "No", - buf, sizeof(buf), KERBEROS_INI); - beep = _stricmp(buf, "Yes") == 0; + alert = cns_res.alert; + beep = cns_res.beep; /* * ticket options */ - GetPrivateProfileString(INI_TICKETOPTS, INI_FORWARDABLE, "No", - buf, sizeof(buf), KERBEROS_INI); - forwardable = _stricmp(buf, "Yes") == 0; + forwardable = cns_res.forwardable; /* * Load clock icons @@ -1733,22 +1705,6 @@ init_instance(HINSTANCE hinstance, int ncmdshow) krb_start_session(NULL); #endif -#ifdef KRB5 - { - krb5_error_code code; - - code = krb5_init_context(&k5_context); - if (!code) - code = k5_init_ccache(&k5_ccache); - if (code) { - com_err(NULL, code, "while initializing program"); - return FALSE; - } - k5_name_from_ccache(k5_ccache); - } - -#endif - return TRUE; } @@ -1858,6 +1814,7 @@ WinMain(HINSTANCE hinst, HINSTANCE hprevinstance, LPSTR cmdline, int ncmdshow) if (hprevinstance == NULL) #endif /* _WIN32 */ + if (!init_application(hinstance)) return FALSE; @@ -1897,6 +1854,8 @@ WinMain(HINSTANCE hinst, HINSTANCE hprevinstance, LPSTR cmdline, int ncmdshow) FreeProcInstance((FARPROC)dlgproc); #endif + cns_save_registry(); + return 0; } @@ -2216,7 +2175,7 @@ k5_name_from_ccache(krb5_ccache k5_ccache) krb5_principal princ; char name[ANAME_SZ]; char realm[REALM_SZ]; - char FAR *defname; + char *defname; if (code = krb5_cc_get_principal(k5_context, k5_ccache, &princ)) return FALSE; @@ -2227,8 +2186,8 @@ k5_name_from_ccache(krb5_ccache k5_ccache) } k5_kname_parse(name, realm, defname); /* Extract the components */ - WritePrivateProfileString(INI_DEFAULTS, INI_USER, name, KERBEROS_INI); - WritePrivateProfileString(INI_DEFAULTS, INI_REALM, realm, KERBEROS_INI); + strcpy(cns_res.name, name); + strcpy(cns_res.realm, realm); return TRUE; } diff --git a/src/windows/cns/cns.h b/src/windows/cns/cns.h index 0d38da2f7b..6ed5c7beb9 100644 --- a/src/windows/cns/cns.h +++ b/src/windows/cns/cns.h @@ -8,6 +8,10 @@ #ifndef KWIN_DEFS #define KWIN_DEFS +#if !defined(KRB4) && !defined(KRB5) +#define KRB5 +#endif + #ifndef RC_INVOKED #ifdef KRB4 @@ -21,6 +25,7 @@ #ifdef KRB5 #include "winsock.h" #include "krb5.h" +#include "krbini.h" #include "com_err.h" #define DEFAULT_TKT_LIFE 120 /* In 5 minute units */ @@ -32,7 +37,7 @@ /* include space for '.' and '@' */ #define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2) #ifdef CYGNUS -#define ORGANIZATION "Cygnus Support - (415) 903-1400" +#define ORGANIZATION "Cygnus Solutions\n(800)CYGNUS-1\nhttp://www.cygnus.com\ninfo@cygnus.com" #endif #define CREDENTIALS char #endif @@ -69,12 +74,8 @@ * Dialog and dialog item ids */ #define KWIN_DIALOG_CLASS "KERBEROS" /* class for kerberos dialog */ -#ifdef CYGNUS -#define KWIN_DIALOG_NAME "KerbNet" /* name for kerberos dialog */ -#else #define KWIN_DIALOG_NAME "Krb5" /* name for kerberos dialog */ -#endif - + #define ID_KWIN 100 /* the main kerberos dialog */ #define IDD_KWIN_FIRST 101 #define IDD_TICKET_LIST_TITLE 101 @@ -145,6 +146,12 @@ #define IDD_TKOPT 320 #define IDD_FORWARDABLE 321 +/* + * the entire range (400 through 499) is reserved for the blasted variable + * dialog box thingie. + */ +#define ID_VARDLG 400 + /* * Dialog dimensions */ @@ -186,12 +193,12 @@ extern HINSTANCE hinstance; extern BOOL alert; extern BOOL beep; -extern char confname[]; +extern char confname[FILENAME_MAX]; #ifdef KRB5 extern krb5_context k5_context; extern krb5_ccache k5_ccache; -extern char ccname[]; +extern char ccname[FILENAME_MAX]; extern BOOL forwardable; #endif @@ -224,11 +231,17 @@ int k5_get_num_cred(int); int k5_kname_parse(char *, char *, char *); krb5_error_code k5_init_ccache(krb5_ccache *); int k5_name_from_ccache(krb5_ccache); -krb5_error_code k5_change_password(krb5_context, char *, char *, char *, +krb5_error_code k5_change_password(HWND, krb5_context, char *, char *, char *, char *, char **); -#endif + +#endif /* KRB5 */ HICON kwin_get_icon(time_t); +void trim(char *); +void start_blocking_hook(int); +void end_blocking_hook(void); +void center_dialog(HWND); +void set_dialog_font(HWND, HFONT); #endif /* RC_INVOKED */ diff --git a/src/windows/cns/cns_reg.c b/src/windows/cns/cns_reg.c new file mode 100644 index 0000000000..95a5a5f87f --- /dev/null +++ b/src/windows/cns/cns_reg.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 1997 Cygnus Solutions + * + * Author: Michael Graff + */ + +#include +#include +#include +#include + +#include "cns.h" +#include "cns_reg.h" + +#include "../lib/registry.h" + +cns_reg_t cns_res; /* yes, a global. Sue me. */ + +/* + * function to load all the data we will want from the registry. If the + * registry data cannot be found this function will initialize a default + * environment. + */ +void +cns_load_registry(void) +{ + char tmp[1024]; + DWORD tdw; + char *ts; + HKEY key; + int i; + + /* + * Set up reasonable default values. These will all be overwritten if + * the registry is successfully opened. + */ + cns_res.name[0] = '\0'; + cns_res.realm[0] = '\0'; + cns_res.x = 0; + cns_res.y = 0; + cns_res.cx = 0; + cns_res.cy = 0; + + cns_res.alert = 0; + cns_res.beep = 0; + cns_res.lifetime = DEFAULT_TKT_LIFE * 5; + cns_res.forwardable = 1; + + + for (i = 1 ; i < FILE_MENU_MAX_LOGINS ; i++) + cns_res.logins[i][0] = '\0'; + + /* + * by default, allow the user to override the config file location and NOT the + * cred cache name. + */ + cns_res.conf_override = 1; + cns_res.cc_override = 0; + + { + char *s; + s = krb5_cc_default_name(k5_context); + + strcpy(cns_res.def_ccname, s); + } + + cns_res.def_confname[0] = '\0'; + + /* + * If the system has these keys in the registry, do not allow the user to + * override the config file and ccache locations. + */ + key = registry_open(HKEY_LOCAL_MACHINE, KERBNET_BASE, KEY_READ); + 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"); + free(ts); + } + + if (registry_string_get(key, "ccname", &ts) == 0) { + cns_res.cc_override = 0; + strcpy(cns_res.def_ccname, ts); + free(ts); + } + } + + /* + * Try to open the registry. If we succeed, read the last used values from there. If we + * do not get the registry open simply return. + */ + key = registry_open(HKEY_CURRENT_USER, KERBNET_CNS_BASE, KEY_ALL_ACCESS); + + if (key == INVALID_HANDLE_VALUE) + return; + + if (registry_dword_get(key, "x", &tdw) == 0) + cns_res.x = tdw; + + if (registry_dword_get(key, "y", &tdw) == 0) + cns_res.y = tdw; + + if (registry_dword_get(key, "cx", &tdw) == 0) + cns_res.cx = tdw; + + if (registry_dword_get(key, "cy", &tdw) == 0) + cns_res.cy = tdw; + + if (registry_dword_get(key, "lifetime", &tdw) == 0) + cns_res.lifetime = tdw; + + if (registry_dword_get(key, "forwardable", &tdw) == 0) + cns_res.forwardable = tdw; + + if (registry_dword_get(key, "alert", &tdw) == 0) + cns_res.alert = tdw; + + if (registry_dword_get(key, "beep", &tdw) == 0) + cns_res.beep = tdw; + + if (registry_string_get(key, "name", &ts) == 0) { + strcpy(cns_res.name, ts); + free(ts); + } + + if (registry_string_get(key, "realm", &ts) == 0) { + strcpy(cns_res.realm, ts); + free(ts); + } + + if (cns_res.conf_override && (registry_string_get(key, "confname", &ts) == 0)) { + strcpy(cns_res.confname, ts); + free(ts); + } else + strcpy(cns_res.confname, cns_res.def_confname); + + if (registry_string_get(key, "ccname", &ts) == 0) { + strcpy(cns_res.ccname, ts); + free(ts); + } else + strcpy(cns_res.ccname, cns_res.def_ccname); + + for (i = 0 ; i < FILE_MENU_MAX_LOGINS ; i++) { + sprintf(tmp, "login_%02d", i); + if (registry_string_get(key, tmp, &ts) == 0) { + strcpy(cns_res.logins[i], ts); + free(ts); + } + } + + registry_close(key); +} + +/* + * save all the registry data, creating the keys if needed. + */ +void +cns_save_registry(void) +{ + char tmp[1024]; + HKEY key; + int i; + + /* + * First, create the heirachy... This is gross, but functional + */ + key = registry_key_create(HKEY_CURRENT_USER, CYGNUS_SOLUTIONS, KEY_WRITE); + if (key == INVALID_HANDLE_VALUE) + return; + + key = registry_key_create(HKEY_CURRENT_USER, KERBNET_SANS_VERSION, KEY_WRITE); + if (key == INVALID_HANDLE_VALUE) + return; + registry_close(key); + + key = registry_key_create(HKEY_CURRENT_USER, KERBNET_BASE, KEY_WRITE); + if (key == INVALID_HANDLE_VALUE) + return; + registry_close(key); + + key = registry_key_create(HKEY_CURRENT_USER, KERBNET_CNS_BASE, KEY_WRITE); + if (key == INVALID_HANDLE_VALUE) + return; + + registry_dword_set(key, "x", cns_res.x); + registry_dword_set(key, "y", cns_res.y); + registry_dword_set(key, "cx", cns_res.cx); + registry_dword_set(key, "cy", cns_res.cy); + + registry_dword_set(key, "alert", cns_res.alert); + registry_dword_set(key, "beep", cns_res.beep); + registry_dword_set(key, "lifetime", cns_res.lifetime); + registry_dword_set(key, "forwardable", cns_res.forwardable); + + registry_string_set(key, "name", cns_res.name); + registry_string_set(key, "realm", cns_res.realm); + + if (cns_res.conf_override) + if (strcmp(cns_res.confname, cns_res.def_confname)) + registry_string_set(key, "confname", cns_res.confname); + else + registry_value_delete(key, "confname"); + + if (strcmp(cns_res.ccname, cns_res.def_ccname)) + registry_string_set(key, "ccname", cns_res.ccname); + else + registry_value_delete(key, "ccname"); + + for (i = 0 ; i < FILE_MENU_MAX_LOGINS ; i++) + if (cns_res.logins[i][0] != '\0') { + sprintf(tmp, "login_%02d", i); + registry_string_set(key, tmp, cns_res.logins[i]); + } + + registry_close(key); +} diff --git a/src/windows/cns/cns_reg.h b/src/windows/cns/cns_reg.h new file mode 100644 index 0000000000..7ec7263569 --- /dev/null +++ b/src/windows/cns/cns_reg.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1997 Cygnus Solutions + * + * Author: Michael Graff + */ + +#include + +typedef struct cns_reg { + DWORD x; /* default dialog size */ + DWORD y; + DWORD cx; + DWORD cy; + DWORD lifetime; /* ticket lifetime */ + DWORD beep; /* beep on expire/warning? */ + DWORD alert; /* alert (deiconify) when tix expired? */ + DWORD forwardable; /* get forwardable tickets? */ + DWORD conf_override; /* allow changing of confname */ + DWORD cc_override; /* allow changing of ccname */ + char name[MAX_K_NAME_SZ]; /* last user used */ + char realm[MAX_K_NAME_SZ]; /* last realm used */ + char confname[FILENAME_MAX]; + char ccname[FILENAME_MAX]; + char def_confname[FILENAME_MAX]; + char def_ccname[FILENAME_MAX]; + char logins[FILE_MENU_MAX_LOGINS][MAX_K_NAME_SZ]; +} cns_reg_t; + +extern cns_reg_t cns_res; + +void cns_load_registry(void); +void cns_save_registry(void); diff --git a/src/windows/cns/cnsres5.rc b/src/windows/cns/cnsres5.rc index e29ab5ac5b..e56375334b 100644 --- a/src/windows/cns/cnsres5.rc +++ b/src/windows/cns/cnsres5.rc @@ -1,6 +1,5 @@ //Microsoft Developer Studio generated resource script. // -// XXX Since modified by hand! #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -89,7 +88,7 @@ END ID_KWIN DIALOG PRELOAD DISCARDABLE 0, 0, 336, 115 STYLE WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME #ifdef CYGNUS -CAPTION "Kerb*Net" +CAPTION "KerbNet" #else CAPTION "Kerberos" #endif @@ -106,10 +105,11 @@ BEGIN LTEXT "&Password",IDD_LOGIN_PASSWORD_TITLE,125,69,42,8 LTEXT "&Realm",IDD_LOGIN_REALM_TITLE,239,69,26,8 EDITTEXT IDD_LOGIN_NAME,6,79,84,12,ES_AUTOHSCROLL - EDITTEXT IDD_LOGIN_PASSWORD,126,78,84,12,ES_PASSWORD|ES_AUTOHSCROLL + EDITTEXT IDD_LOGIN_PASSWORD,126,78,84,12,ES_PASSWORD | + ES_AUTOHSCROLL EDITTEXT IDD_LOGIN_REALM,239,79,84,12,ES_AUTOHSCROLL PUSHBUTTON "&Change Password...",IDD_CHANGE_PASSWORD,6,96,84,14 - PUSHBUTTON "&Destroy Credentials",IDD_TICKET_DELETE,126,96,84,14 + PUSHBUTTON "&Delete",IDD_TICKET_DELETE,141,96,52,14 DEFPUSHBUTTON "&Login",IDD_LOGIN,271,96,52,14 PUSHBUTTON "",IDD_PASSWORD_CR2,5000,5000,6,6,NOT WS_TABSTOP END @@ -140,7 +140,7 @@ END ID_OPTS DIALOG DISCARDABLE 97, 52, 169, 138 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU #ifdef CYGNUS -CAPTION "Kerb*Net Options" +CAPTION "KerbNet Options" #else CAPTION "Kerberos Options" #endif diff --git a/src/windows/cns/debug.c b/src/windows/cns/debug.c index 101fe30b59..d35e64ed56 100644 --- a/src/windows/cns/debug.c +++ b/src/windows/cns/debug.c @@ -1,5 +1,4 @@ #ifdef DEBUG -#define _DEBUG #include #include diff --git a/src/windows/cns/kpasswd.c b/src/windows/cns/kpasswd.c index 2f1327126c..8d867f02d8 100644 --- a/src/windows/cns/kpasswd.c +++ b/src/windows/cns/kpasswd.c @@ -1,213 +1,89 @@ /* - * - * k5passwd - * - * Changes your password in the Kerberos V5. This should have been - * part of the kadm stuff but we're forced to build a nicer API on top - * of the calls they provide. - * + * Copyright (c) 1997 Cygnus Solutions. + * + * Author: Michael Graff */ -#ifdef KRB5 - #include #include #include + #include "krb5.h" #include "com_err.h" -#include "adm.h" -#include "adm_proto.h" -static const char *kadm_replies[] = { - "Operation successful", /* KRB5_ADM_SUCCESS */ - "Command not recognized", /* KRB5_ADM_CMD_UNKNOWN */ - "Password unacceptable to server", /* KRB5_ADM_PW_UNACCEPT */ - "Old password incorrect", /* KRB5_ADM_BAD_PW */ - "Invalid ticket (TKT_FLAG_INITIAL not set)",/* KRB5_ADM_NOT_IN_TKT */ - "Server refused password change", /* KRB5_ADM_CANT_CHANGE */ - "Language not supported", /* KRB5_ADM_LANG_NOT_SUPPORTED */ -}; - -static const char *kadm_replies_unknown = "UNKNOWN ERROR"; -static char errbuf[1024]; /* For response from kadm */ - -/* - * get_admin_response - * - * Builds into a static buffer the replies sent back by the admin server. - */ -static char * -get_admin_response(krb5_int32 status, /* Type of error */ - krb5_int32 nreplies, /* Size of reply */ - krb5_data *reply) /* Buffer of messages */ -{ - char *ptr; /* For building the response */ - char *end = errbuf + sizeof (errbuf); /* So we don't overflow */ - int i; /* Index */ - int n; /* Length */ - - if (status <= KRB5_ADM_LANG_NOT_SUPPORTED) /* Is it of a known type??? */ - strcpy (errbuf, kadm_replies[status]); - else - strcpy (errbuf, kadm_replies_unknown); /* Unknown error type */ - ptr = errbuf + strlen (errbuf); /* Point at the end */ - - if (nreplies > 0) { /* Are there more message? */ - *ptr++ = ':'; - *ptr = '\0'; - } - - for (i = 0; i < nreplies; ++i) { /* Append additional messages */ - *ptr++ = '\n'; - - n = reply[i].length; /* Easier to work with */ - if (ptr + n + 2 >= errbuf) /* Check for overflow */ - break; - memcpy (ptr, reply[i].data, n); /* Add the message */ - ptr += n; /* Point to the end */ - *ptr = '\0'; - } - - return errbuf; -} - -/* - * keyadmin_send_recieve - * - * Sends a command to the key admin and reads the reply. - */ -static krb5_error_code -keyadmin_send_receive(krb5_context k5context, - int *conn_socket, - krb5_auth_context auth_context, - krb5_int32 nargs, - krb5_data *arglist, - krb5_int32 *cmd_stat, - krb5_int32 *nreplies, - krb5_data **reply) -{ - krb5_error_code kret; - char foo[1024]; - int i; - - kret = krb5_send_adm_cmd (k5context, conn_socket, auth_context, - nargs, arglist); - - if (! kret) - kret = krb5_read_adm_reply (k5context, conn_socket, auth_context, - cmd_stat, nreplies, reply); - - return kret; -} +#include "cns.h" +#include "../lib/gic.h" /* * k5_change_password * - * Bundles all the crud needed to change the password into one file. + * Use the new functions to change the password. */ krb5_error_code -k5_change_password (krb5_context k5context, char *user, char *realm, - char *opasswd, char *npasswd, char **text) +k5_change_password(HWND hwnd, krb5_context context, char *user, char *realm, + char *opasswd, char *npasswd, char **text) { - krb5_error_code kret, kret2; - krb5_auth_context auth_context; - krb5_ccache ccache; - int conn_socket; /* Socket for talking over */ - krb5_int32 nreplies; - krb5_data data[3]; - krb5_data *reply; - krb5_int32 status; - char *name; - - *text = NULL; /* Be safe */ - name = malloc(strlen(user) + strlen(realm) + 2); - if (name == NULL) - return ENOMEM; - sprintf(name, "%s@%s", user, realm); - ccache = (krb5_ccache)NULL; - - /* - * Establish the connection. - */ - kret = krb5_adm_connect(k5context, name, NULL, opasswd, &conn_socket, - &auth_context, &ccache, "kadm.tk", 0); - if (kret) - goto done; - - /* - * Check to see if it's an acceptable password - */ - data[0].data = KRB5_ADM_CHECKPW_CMD; - data[0].length = strlen (data[0].data); - data[1].data = npasswd; - data[1].length = strlen (npasswd); - - kret = keyadmin_send_receive (k5context, &conn_socket, auth_context, - 2, data, &status, &nreplies, &reply); - if (kret) /* Some external error */ - goto cleanup; - - if (status != KRB5_ADM_SUCCESS) { /* Some problem??? */ - kret = status; - *text = get_admin_response (status, nreplies, reply); - krb5_free_adm_data (k5context, nreplies, reply); - - goto quit; - } - krb5_free_adm_data (k5context, nreplies, reply); - - /* - * The new password is ok, so now actually change the password - */ - data[0].data = KRB5_ADM_CHANGEPW_CMD; - data[0].length = strlen (data[0].data); - data[1].data = opasswd; - data[1].length = strlen (opasswd); - data[2].data = npasswd; - data[2].length = strlen (npasswd); - - kret = keyadmin_send_receive (k5context, &conn_socket, auth_context, - 3, data, &status, &nreplies, &reply); - if (kret) - goto cleanup; - - if (status != KRB5_ADM_SUCCESS) { - kret = status; - *text = get_admin_response (status, nreplies, reply); - krb5_free_adm_data (k5context, nreplies, reply); - - goto quit; - } - - krb5_free_adm_data (k5context, nreplies, reply); - /* - * Need to send quit command. - */ -quit: - data[0].data = KRB5_ADM_QUIT_CMD; - data[0].length = strlen (data[0].data); - - kret2 = keyadmin_send_receive (k5context, &conn_socket, auth_context, - 1, data, &status, &nreplies, &reply); - if (kret2) { - if (! kret) - kret = kret2; - } else if (status != KRB5_ADM_SUCCESS) { - if (! kret) - kret = status; - if (*text == NULL) - *text = get_admin_response (status, nreplies, reply); - } - krb5_free_adm_data (k5context, nreplies, reply); - -cleanup: - krb5_adm_disconnect (k5context, &conn_socket, auth_context, ccache); - -done: - free (name); - - return kret; + krb5_error_code ret; + krb5_data result_string; + krb5_data result_code_string; + int result_code; + krb5_get_init_creds_opt opts; + krb5_creds creds; + krb5_principal princ; + char *name; + gic_data gd; + + *text = NULL; + + name = malloc(strlen(user) + strlen(realm) + 2); + if (name == NULL) { + *text = "Failed to allocate memory while changing password"; + return 1; + } + sprintf(name, "%s@%s", user, realm); + + ret = krb5_parse_name(context, name, &princ); + free(name); + if (ret) { + *text = "while parsing name"; + return ret; + } + + krb5_get_init_creds_opt_init(&opts); + krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); + krb5_get_init_creds_opt_set_renew_life(&opts, 0); + krb5_get_init_creds_opt_set_forwardable(&opts, 0); + krb5_get_init_creds_opt_set_proxiable(&opts, 0); + + gd.hinstance = hinstance; + gd.hwnd = hwnd; + gd.id = ID_VARDLG; + + ret = krb5_get_init_creds_password(context, &creds, princ, opasswd, gic_prompter, + &gd, 0, "kadmin/changepw", &opts); + if (ret) { + *text = "while getting creds"; + return ret; + } + + ret = krb5_change_password(context, &creds, npasswd, &result_code, &result_code_string, + &result_string); + if (ret) { + *text = "while changing password"; + return ret; + } + + if (result_code) { + *text = malloc(result_code_string.length + result_string.length + 3); + if (*text == NULL) + return -1; + + sprintf(*text, "%.*s%s%.*s", + result_code_string.length, result_code_string.data, + (result_string.length ? ": " : ""), + result_string.length, result_string.data); + } + + return 0; } - -#endif /* KRB5 */ diff --git a/src/windows/cns/krbini.h b/src/windows/cns/krbini.h new file mode 100644 index 0000000000..8daf93b730 --- /dev/null +++ b/src/windows/cns/krbini.h @@ -0,0 +1,37 @@ +/* Kerberos changed window message */ +#define WM_KERBEROS_CHANGED "Kerberos Changed" + +/* Kerberos Windows initialization file */ +#define KERBEROS_INI "kerberos.ini" +#ifdef CYGNUS +#define KERBEROS_HLP "kerbnet.hlp" +#else +#define KERBEROS_HLP "krb5.hlp" +#endif +#define INI_DEFAULTS "Defaults" +#define INI_USER "User" /* Default user */ +#define INI_INSTANCE "Instance" /* Default instance */ +#define INI_REALM "Realm" /* Default realm */ +#define INI_POSITION "Position" +#define INI_OPTIONS "Options" +#define INI_DURATION "Duration" /* Ticket duration in minutes */ +#define INI_EXPIRATION "Expiration" /* Action on expiration (alert or beep) */ +#define INI_ALERT "Alert" +#define INI_BEEP "Beep" +#define INI_FILES "Files" +#ifdef KRB4 +#define INI_KRB_CONF "krb.conf" /* Location of krb.conf file */ +#define DEF_KRB_CONF "krb.conf" /* Default name for krb.conf file */ +#endif /* KRB4 */ +#ifdef KRB5 +#define INI_KRB5_CONF "krb5.ini" /* From k5-config.h */ +#define INI_KRB_CONF INI_KRB5_CONF /* Location of krb.conf file */ +#define DEF_KRB_CONF INI_KRB5_CONF /* Default name for krb.conf file */ +#define INI_TICKETOPTS "TicketOptions" /* Ticket options */ +#define INI_FORWARDABLE "Forwardable" /* get forwardable tickets */ +#define INI_KRB_CCACHE "krb5cc" /* From k5-config.h */ +#endif /* KRB5 */ +#define INI_KRB_REALMS "krb.realms" /* Location of krb.realms file */ +#define DEF_KRB_REALMS "krb.realms" /* Default name for krb.realms file */ +#define INI_RECENT_LOGINS "Recent Logins" +#define INI_LOGIN "Login" diff --git a/src/windows/cns/options.c b/src/windows/cns/options.c index 8a3b77bf16..f133145754 100644 --- a/src/windows/cns/options.c +++ b/src/windows/cns/options.c @@ -21,9 +21,8 @@ #include #include "cns.h" - -char confname[FILENAME_MAX]; -char ccname[FILENAME_MAX]; +#include "tktlist.h" +#include "cns_reg.h" /* * Function: Process WM_INITDIALOG messages for the options dialog. @@ -35,74 +34,45 @@ char ccname[FILENAME_MAX]; BOOL opts_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { - char wdir[FILENAME_MAX]; - char defname[FILENAME_MAX]; - char newname[FILENAME_MAX]; - UINT rc; - int lifetime; - center_dialog(hwnd); set_dialog_font(hwnd, hfontdialog); - rc = GetWindowsDirectory(wdir, sizeof(wdir)); - assert(rc > 0); - strcat(wdir, "\\"); /* krb.conf file */ - strcpy(defname, wdir); - strcat(defname, DEF_KRB_CONF); - GetPrivateProfileString(INI_FILES, INI_KRB_CONF, defname, - confname, sizeof(confname), KERBEROS_INI); + strcpy(confname, cns_res.confname); #ifndef _WIN32 _strupr(confname); #endif SetDlgItemText(hwnd, IDD_CONF, confname); - -#ifdef KRB4 - /* krb.realms file */ - strcpy(defname, wdir); - strcat(defname, DEF_KRB_REALMS); - GetPrivateProfileString(INI_FILES, INI_KRB_REALMS, defname, - newname, sizeof(newname), KERBEROS_INI); -#ifndef _WIN32 - _strupr(newname); -#endif - SetDlgItemText(hwnd, IDD_REALMS, newname); -#endif /* KRB4 */ -#ifdef KRB5 + if (cns_res.conf_override == 0) + EnableWindow(GetDlgItem(hwnd, IDD_CONF), 0); + else + EnableWindow(GetDlgItem(hwnd, IDD_CONF), 1); + /* Credential cache file */ - strcpy(defname, wdir); - strcat(defname, INI_KRB_CCACHE); - GetPrivateProfileString(INI_FILES, INI_KRB_CCACHE, defname, - ccname, sizeof(ccname), KERBEROS_INI); + strcpy(ccname, cns_res.ccname); #ifndef _WIN32 _strupr(ccname); #endif SetDlgItemText(hwnd, IDD_CCACHE, ccname); -#endif /* KRB5 */ + + if (cns_res.cc_override == 0) + EnableWindow(GetDlgItem(hwnd, IDD_CCACHE), 0); + else + EnableWindow(GetDlgItem(hwnd, IDD_CCACHE), 1); /* Ticket duration */ - lifetime = GetPrivateProfileInt(INI_OPTIONS, INI_DURATION, - DEFAULT_TKT_LIFE * 5, KERBEROS_INI); - SetDlgItemInt(hwnd, IDD_LIFETIME, lifetime, FALSE); + SetDlgItemInt(hwnd, IDD_LIFETIME, cns_res.lifetime, FALSE); /* Expiration action */ - GetPrivateProfileString(INI_EXPIRATION, INI_ALERT, "No", - defname, sizeof(defname), KERBEROS_INI); - alert = _stricmp(defname, "Yes") == 0; + alert = cns_res.alert; SendDlgItemMessage(hwnd, IDD_ALERT, BM_SETCHECK, alert, 0); - GetPrivateProfileString(INI_EXPIRATION, INI_BEEP, "No", - defname, sizeof(defname), KERBEROS_INI); - beep = _stricmp(defname, "Yes") == 0; + beep = cns_res.beep; SendDlgItemMessage(hwnd, IDD_BEEP, BM_SETCHECK, beep, 0); -#ifdef KRB5 - GetPrivateProfileString(INI_TICKETOPTS, INI_FORWARDABLE, "No", - defname, sizeof(defname), KERBEROS_INI); - forwardable = _stricmp(defname, "Yes") == 0; + forwardable = cns_res.forwardable; SendDlgItemMessage(hwnd, IDD_FORWARDABLE, BM_SETCHECK, forwardable, 0); -#endif return TRUE; } @@ -114,19 +84,12 @@ opts_initdialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) void opts_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) { - char wdir[FILENAME_MAX]; - char defname[FILENAME_MAX]; char newname[FILENAME_MAX]; - char *p; BOOL b; int lifetime; - int rc; switch (cid) { case IDOK: - rc = GetWindowsDirectory(wdir, sizeof(wdir)); - assert(rc > 0); - strcat(wdir, "\\"); /* Ticket duration */ lifetime = GetDlgItemInt(hwnd, IDD_LIFETIME, &b, FALSE); @@ -137,51 +100,31 @@ opts_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) return; /* TRUE */ } - _itoa(lifetime, defname, 10); - b = WritePrivateProfileString(INI_OPTIONS, INI_DURATION, - defname, KERBEROS_INI); - assert(b); - - /* krb.conf file */ - GetDlgItemText(hwnd, IDD_CONF, newname, sizeof(newname)); - trim(newname); - if (_stricmp(newname, confname)) { /* file name changed */ - MessageBox(NULL, - "Change to configuration file location requires a restart" - "of KerbNet.\n" - "Please exit this application and restart this application", - "", MB_OK | MB_ICONEXCLAMATION); + cns_res.lifetime = lifetime; + + if (cns_res.conf_override) { + /* krb.conf file */ + GetDlgItemText(hwnd, IDD_CONF, newname, sizeof(newname)); + trim(newname); + if (newname[0] == '\0') + strcpy(newname, cns_res.def_confname); + if (_stricmp(newname, confname)) { /* file name changed */ + MessageBox(NULL, + "Change to configuration file location requires a restart" + "of KerbNet.\n" + "Please exit this application and restart it for the change to take" + "effect", + "", MB_OK | MB_ICONEXCLAMATION); + } + strcpy(confname, newname); } - strcpy(defname, wdir); - strcat(defname, DEF_KRB_CONF); - p = (*newname && _stricmp(newname, defname)) ? newname : NULL; - if (p) - strcpy(confname, p); - b = WritePrivateProfileString(INI_FILES, INI_KRB_CONF, p, KERBEROS_INI); - assert(b); - - /* krb.realms file */ -#ifdef KRB4 - GetDlgItemText(hwnd, IDD_REALMS, newname, sizeof(newname)); - trim(newname); - strcpy(defname, wdir); - strcat(defname, DEF_KRB_REALMS); - p = (*newname && _stricmp(newname, defname)) ? newname : NULL; - b = WritePrivateProfileString(INI_FILES, INI_KRB_REALMS, p, KERBEROS_INI); - assert(b); -#endif /* KRB4 */ /* Credential cache file */ -#ifdef KRB5 GetDlgItemText(hwnd, IDD_CCACHE, newname, sizeof(newname)); trim(newname); - strcpy(defname, wdir); - strcat(defname, "krb5cc"); - if (*newname == '\0') /* For detecting name change */ - strcpy(newname, defname); - p = (*newname && _stricmp(newname, defname)) ? newname : NULL; - b = WritePrivateProfileString(INI_FILES, INI_KRB_CCACHE, p, KERBEROS_INI); - assert(b); + + if (newname[0] == '\0') + strcpy(newname, cns_res.def_ccname); if (_stricmp(ccname, newname)) { /* Did we change ccache file? */ krb5_error_code code; @@ -191,9 +134,10 @@ opts_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) if (code) { /* Problem opening new one? */ com_err(NULL, code, "while changing ccache.\r\nRestoring old ccache."); - b = WritePrivateProfileString(INI_FILES, INI_KRB_CCACHE, - ccname, KERBEROS_INI); } else { + strcpy(ccname, newname); + strcpy(cns_res.ccname, newname); + code = krb5_cc_close(k5_context, k5_ccache); k5_ccache = cctemp; /* Copy new into old */ if (k5_name_from_ccache(k5_ccache)) { @@ -204,27 +148,18 @@ opts_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) IDD_TICKET_LIST)); } } -#endif /* KRB5 */ - - /* Expiration action */ - alert = (BOOL)SendDlgItemMessage(hwnd, IDD_ALERT, BM_GETCHECK, 0, 0); - p = (alert) ? "Yes" : "No"; - b = WritePrivateProfileString(INI_EXPIRATION, INI_ALERT, p, KERBEROS_INI); - assert(b); - - beep = (BOOL)SendDlgItemMessage(hwnd, IDD_BEEP, BM_GETCHECK, 0, 0); - p = (beep) ? "Yes" : "No"; - b = WritePrivateProfileString(INI_EXPIRATION, INI_BEEP, p, KERBEROS_INI); - assert(b); - -#ifdef KRB5 - forwardable = (BOOL)SendDlgItemMessage(hwnd, IDD_FORWARDABLE, - BM_GETCHECK, 0, 0); - p = (forwardable) ? "Yes" : "No"; - b = WritePrivateProfileString(INI_TICKETOPTS, INI_FORWARDABLE, - p, KERBEROS_INI); - assert(b); -#endif + + /* + * get values for the clickboxes + */ + alert = SendDlgItemMessage(hwnd, IDD_ALERT, BM_GETCHECK, 0, 0); + cns_res.alert = alert; + + beep = SendDlgItemMessage(hwnd, IDD_BEEP, BM_GETCHECK, 0, 0); + cns_res.beep = beep; + + forwardable = SendDlgItemMessage(hwnd, IDD_FORWARDABLE, BM_GETCHECK, 0, 0); + cns_res.forwardable = forwardable; EndDialog(hwnd, IDOK); diff --git a/src/windows/cns/password.c b/src/windows/cns/password.c index c9aaa6574e..ad02201f14 100644 --- a/src/windows/cns/password.c +++ b/src/windows/cns/password.c @@ -97,22 +97,17 @@ change_password(HWND hwnd, char *name, char *instance, char *realm, #ifdef KRB5 char *msg; /* Message string */ krb5_error_code code; /* Return value */ - code = k5_change_password(k5_context, name, realm, oldpw, newpw, &msg); + code = k5_change_password(hwnd, k5_context, name, realm, oldpw, newpw, &msg); - if (msg != NULL) { - MessageBox(NULL, msg, NULL, MB_ICONEXCLAMATION); - } else if (code) { - if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) + if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) MessageBox(NULL, "Password incorrect", NULL, MB_ICONEXCLAMATION); - else if (code == ENOENT) - MessageBox(NULL, "Cannot connect to admin server", NULL, + else if (code == -1) + MessageBox(NULL, (msg ? msg : "Cannot change password"), NULL, MB_ICONEXCLAMATION); - else - com_err(NULL, code, "while changing password."); - } - - if (code == 0) - MessageBox(NULL, "Password changed.", "Kerberos", MB_OK | MB_APPLMODAL); + else if (code != 0) + com_err(NULL, code, (msg ? msg : "while changing password.")); + else + MessageBox(NULL, (msg ? msg : "Password changed"), "Kerberos", MB_OK | MB_APPLMODAL); return (code == 0); diff --git a/src/windows/cns/tktlist.c b/src/windows/cns/tktlist.c index 79d9483de6..62b6eb8d6c 100644 --- a/src/windows/cns/tktlist.c +++ b/src/windows/cns/tktlist.c @@ -31,15 +31,6 @@ #include "winsock.h" #include "krb5.h" #include "com_err.h" - -#define DEFAULT_TKT_LIFE 120 -#define ANAME_SZ 40 -#define REALM_SZ 40 -#define SNAME_SZ 40 -#define INST_SZ 40 -#define MAX_KPW_LEN 128 -/* include space for '.' and '@' */ -#define MAX_K_NAME_SZ (ANAME_SZ + INST_SZ + REALM_SZ + 2) #endif #include "cns.h" -- cgit