From c3f88158d5a194b7e3fe1c655d45799521895847 Mon Sep 17 00:00:00 2001 From: Keith Vetter Date: Wed, 22 Mar 1995 20:17:41 +0000 Subject: [PATCH] Added files to the windows/cns directory git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5189 dc483132-0cff-0310-8789-dd5450dbe970 --- src/windows/cns/clock00.ico | Bin 0 -> 1086 bytes src/windows/cns/clock05.ico | Bin 0 -> 1086 bytes src/windows/cns/clock10.ico | Bin 0 -> 1086 bytes src/windows/cns/clock15.ico | Bin 0 -> 1086 bytes src/windows/cns/clock20.ico | Bin 0 -> 1086 bytes src/windows/cns/clock25.ico | Bin 0 -> 1086 bytes src/windows/cns/clock30.ico | Bin 0 -> 1086 bytes src/windows/cns/clock35.ico | Bin 0 -> 1086 bytes src/windows/cns/clock40.ico | Bin 0 -> 1086 bytes src/windows/cns/clock45.ico | Bin 0 -> 1086 bytes src/windows/cns/clock50.ico | Bin 0 -> 1086 bytes src/windows/cns/clock55.ico | Bin 0 -> 1086 bytes src/windows/cns/clock60.ico | Bin 0 -> 1086 bytes src/windows/cns/clockexp.ico | Bin 0 -> 1086 bytes src/windows/cns/clocktkt.ico | Bin 0 -> 1086 bytes src/windows/cns/cns.c | 2878 ++++++++++++++++++++++++++++++++++ src/windows/cns/cns.def | 9 + src/windows/cns/cns.h | 136 ++ src/windows/cns/cns.ico | Bin 0 -> 1086 bytes src/windows/cns/cns.rc | 105 ++ src/windows/cns/krbini.h | 23 + src/windows/cns/makefile | 79 + src/windows/cns/tktlist.c | 427 +++++ src/windows/cns/tktlist.h | 35 + 24 files changed, 3692 insertions(+) create mode 100644 src/windows/cns/clock00.ico create mode 100644 src/windows/cns/clock05.ico create mode 100644 src/windows/cns/clock10.ico create mode 100644 src/windows/cns/clock15.ico create mode 100644 src/windows/cns/clock20.ico create mode 100644 src/windows/cns/clock25.ico create mode 100644 src/windows/cns/clock30.ico create mode 100644 src/windows/cns/clock35.ico create mode 100644 src/windows/cns/clock40.ico create mode 100644 src/windows/cns/clock45.ico create mode 100644 src/windows/cns/clock50.ico create mode 100644 src/windows/cns/clock55.ico create mode 100644 src/windows/cns/clock60.ico create mode 100644 src/windows/cns/clockexp.ico create mode 100644 src/windows/cns/clocktkt.ico create mode 100644 src/windows/cns/cns.c create mode 100644 src/windows/cns/cns.def create mode 100644 src/windows/cns/cns.h create mode 100644 src/windows/cns/cns.ico create mode 100644 src/windows/cns/cns.rc create mode 100644 src/windows/cns/krbini.h create mode 100644 src/windows/cns/makefile create mode 100644 src/windows/cns/tktlist.c create mode 100644 src/windows/cns/tktlist.h diff --git a/src/windows/cns/clock00.ico b/src/windows/cns/clock00.ico new file mode 100644 index 0000000000000000000000000000000000000000..1c2e424c83feaba846167809f124ed859e27099b GIT binary patch literal 1086 zcmd5)%MHRX41Fm`+z=z=ggCMRY{jXn*XT6OCS2Ko6PV|wrA=u;NEPBG{yZmf;>dtQ z2Jbg8Tryxw>pdM}?|}6J*jbEnq&O_80f}2`KUEdLiK>c*nl3^J5D_kDJ)vqIg~LLo z{s3iz_9-uXbuyIC^%*!*B>BGO!}ko&U;Fvv!@K)F)Z5ni3(FoD2T-!nad5}675Y`S(rPO@Z9u6N?@uGZlCRE zCr%t0P>7)Q93r;}SkP)shq6+@YyvDLMr;X%DK%i+lG^uG4)8~wJ3~zuMNz;Q!-TDW zSSudEPeP*pK(a>KtGw|z5y`sz2%IIndKmCH_VYuY4D+SGzI?6cF5aKV22Yo4z|S3T z`}~FF41@(pAHZe|aLUr~A=dhH&fynnj3d2fjh=)&YYm6mpilYhu^nPAjp> Z?XgGhKbTPIHuk9x>2Zv=k{aLM>j_+x5QYE% literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock10.ico b/src/windows/cns/clock10.ico new file mode 100644 index 0000000000000000000000000000000000000000..15e00b24af94ea279af062fb5c16dc81b395919d GIT binary patch literal 1086 zcmd5)%MpSw5PhICxjB}=$?<3djy7O9PHvJmumfp=R3cY9;H2>_A0ZlU==jLn-M0xF zmRTS|j3ik?aEpNzeUdOBHW9Fx0c**TdoseD7BJ0`I`&NgaG@v~N6Qe_S{P%v;pzqF zBqI4pO3WW1YtenmhgMpUz4j;2c&n%2*H>D3_bFXny!(~Thgwy>uJk}R2mAAE@SNwP zx~uyO&lv~6D()}(;jK!(3Aid%CdE|3}LN>F@_tiS#VAw zl8>as`~h;0?kXQzX+i$lpFji0pq|oMF|4n&dee2FwbFrBb*O7S&~4%VJR7_e#i;J? z@e9uxhy%zTzb>!3_K?Vv;}^Gr=nwi&_2mi1aye?4SUD~{0ZwN?N;Om-l85Yxh`GX$P|>; zkvxf{MS(zu9f~4{$aM!i(-s9C$}s~Dd*DU(h&Lj`6E)ys$lz<$0bJ<1XsGGJdk^Ov z55lkzf_MZ!*%I{+q)swkqF3D5a>lC}*ZIckd~2+Z?=|o3 zFCH&8#k0YtZCCl&$0ICfU|E3b2E48#-#F8GoU&^9Cn4xL=kSXp6Un4mV^6G*^1qIuW#563hDp= literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock25.ico b/src/windows/cns/clock25.ico new file mode 100644 index 0000000000000000000000000000000000000000..fc163fa23d4967135acb93dc84874f5076de5890 GIT binary patch literal 1086 zcmd5)I}(C05PhIC=^T$h<`aZ!TI(0 zzOJw#KMQ1ev$}tWUod-M+JLM9_MZT|ESo;WTEEZP{9+wBF?i+}#8hNoY-*xh0Tpjv kJvzRT@5G5X6UUBaUUb7fWNRFza(82Mbx4iO^7Z$61JPd!1ONa4 literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock30.ico b/src/windows/cns/clock30.ico new file mode 100644 index 0000000000000000000000000000000000000000..3dfd8458d2804c5ffd5d0308e5555abab1339773 GIT binary patch literal 1086 zcmd5)I}XAy41Fy~*$_v_gc!L29EpiY3^dn(BlHsON$AQAx-~pEtx7@*3m}~M^I|)( zBLfLiXuX8cEd^H8TGJqH5@0a{)^bMPkrT`*0qa9rI}`=LjiT_1k|xTsgte9q*KRl` z7MV+qMEn7rNtZm&`%<2;GKPEb6VxiirVg<(Du`F6j_^LhS%hEbv!F0OdcS_G*EcrA zzv;LChhJ#Uz&HU}18hIRoU&~E5$D1==kN=4%7a1jjsc8W&T^>9C7l&3uTJDE`Ow+N ZPWM=R64UscKA-7RG}VXn$XmYtUw0}w2KfL0 literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock35.ico b/src/windows/cns/clock35.ico new file mode 100644 index 0000000000000000000000000000000000000000..b508e881d648eaf8094e965adf35afc1e6dc4697 GIT binary patch literal 1086 zcmd5)OAdlC5Phf#JL3^p8JFHbkK{@c7t(9gBX|k8h~Ux_*q!wa1z`y8)HrlLZ$9k| z86d(0NwR>@Z2~N*lY|Co9Rc$xuo546OO7z31WZV&Z7p(u2YDV8B~27X0b>jUzCQ3? zEHXcFiTDGu_FPljinS+=<22xoPg{BY(BxCn}f->Hq)$ literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock40.ico b/src/windows/cns/clock40.ico new file mode 100644 index 0000000000000000000000000000000000000000..d7e64a398494b2f9fd6bfda0ce5f8b19ea02e8eb GIT binary patch literal 1086 zcmd5)I}XAy41EQpY=|4s2{Cd5I1&?)7-+7MN?d?Tw0B@dbmateBRn@PZTNIT2si#b z+i~p5K!gF}cmkoz0GLt7F%8lp0>(pNEcBa%$o#}5;t%LhQ`5=|R$B8Mns}-f5f?P&$;|Uwep~q ztkHr#Ys#*tJ79kX3fjjjaH1}@WcrIuttBp)v77~+@!V7U(;PA*t1Q34egEqYV}k{Q literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock45.ico b/src/windows/cns/clock45.ico new file mode 100644 index 0000000000000000000000000000000000000000..e35b2008dfb46e3ec83fc7051b684677430a7f89 GIT binary patch literal 1086 zcmc(eO-{ow5QSe#rLZeU$O?7Ijuk4W;2f;5#De4+<_Nt+auT}j3GlAwvz^q5NGc>G znAm=PwF@H|gO6 zWPkseaQiA9&>voU@&}Gj7af@EF-U6fScD zmFD@(?Iy&pGmrVQzl}Wm2adzkew06)yHUM16`t*_weMVVxDRx~2mN2*();6OEWh(L Q@BfN<{j>id#9GSp1(5Foj{pDw literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock50.ico b/src/windows/cns/clock50.ico new file mode 100644 index 0000000000000000000000000000000000000000..b1eaa1c82952b060a1823219067081c461c56392 GIT binary patch literal 1086 zcmd5)OK!qI41J-MyrY#^bcM*O>asVWH|Z5vVTlEqYos?Qmq<=hww!?3b^4qkOu{EC zgzAhx&-Qri$Uue>^86V_yAkk8o#!-2?-?+D0N%_;{vc;~qy$_{Y3#nJ03K9TRFpJP z*EO7T420$&1hdHe%w^&q(B?pGD`!|#c{azmsCemNufB_!t7#F}%$wE=HVW*cq2%W*bTJ9kGiT`d$_BOmQ8tNW~Hf zb|UHb4Duv#<0PxkYH7cr@tEK2Hd_vPny1-hc=SI)a|bRHP#=NSEtp$YUoPT(zUN$i zr9lM{CEtkPn$>r`20r#-g5^)pi*IWB-@h0e&Fuh3s}=!|^j?*Ho-GMoLK literal 0 HcmV?d00001 diff --git a/src/windows/cns/clock60.ico b/src/windows/cns/clock60.ico new file mode 100644 index 0000000000000000000000000000000000000000..0e9d6ebd14d4696ef4fcc7220127e16f899af2c2 GIT binary patch literal 1086 zcmd5)I}XAy41EQpY`_sZAvV~U5FCk#NDQ>+;0RozJqa@>ARFO1fhH}bLINS&`15Sn zjw1sJdPvhTgw8!+LY<~GNb>|3_JOJR$ZK+f0VR<86ld2(0q~$GyrQIuvMiD3IRn-m zSSuEppSVQ)0Uhu3xXKe&TJs#MxYEj~8aCR*nAuuI`G(j845_yXcqBLrSg}Fle-;1l z!f`)sRINX|#rO3W5A`|Vfn3egzz_c~G=o#PAvIv(yKXSMppUwy}I5?dfxzVT>t|B literal 0 HcmV?d00001 diff --git a/src/windows/cns/clockexp.ico b/src/windows/cns/clockexp.ico new file mode 100644 index 0000000000000000000000000000000000000000..6a22b90b94bc5b1569fb5d467a99ab7bcb29d4ea GIT binary patch literal 1086 zcmc&yy-LJD5dLxsAsnc0kW^yn3&`5tgWL0;7VfDTWWw)TA=VLTYuNo z06)~VKWOQqX&Mwo!Ha(Tq3^|`@+ToNegc_Gr?n1W`^%EJ}^3Gg*4ZhFThJCu;7G4rn1F^TS?IEgoO<`OgPm#B8L%| z>>ZMW@%1A%V=*)GiAX?)IVT+ElUmYZm)W+5C_91E-}X{{R30 literal 0 HcmV?d00001 diff --git a/src/windows/cns/clocktkt.ico b/src/windows/cns/clocktkt.ico new file mode 100644 index 0000000000000000000000000000000000000000..dc4d246f4af8b968c21d4a4e646ee8b278971f02 GIT binary patch literal 1086 zcmd5)Jqp4w7=5i`AxQNInZ(gWT)l=4;t{$DF7_yya{{;a7RAlc(Xm^6U+PZ_S`h?& z$@}uXd@pGe0t5)5^$>zn2#h#t&4ic)K->YwGDptI09{5Ptt>uoh74dwmQ@2IQ{;J$ zG)-A>zQZ}mNH&?0@NbB04F>pJ8>@^`q_JF&Ew!?+icJn1-83yX?fnK`(@!W*v0HGt z5p89^&;Q4-tb%-CQ$s@iTks9ML. + */ + +#if !defined(KRB5) && !defined(KRB4) + #define KRB5 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef KRB4 + #define DEFINE_SOCKADDR + #include "mit-copyright.h" + #include "krb.h" + #include "kadm.h" + #include "org.h" +#endif + +#ifdef KRB5 + #define NEED_SOCKETS + #include "krb5.h" + #include "krbini.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) + #define ORGANIZATION "Cygnus Support" + + #define CREDENTIALS char +#endif + +#include "cns.h" +#include "tktlist.h" + +/* + * Constants + */ +#define BLOCK_MAX_SEC 30 /* Blocking timeout duration */ +#define KWIN_UPDATE_PERIOD 30000 /* Every 30 seconds update the screen */ +#define TIME_BUFFER 300 /* Pop-up time buffer in seconds */ +#define WM_KWIN_SETNAME (WM_USER+100) /* Sets the name fields in the dialog */ + +enum { /* Actions after login */ + LOGIN_AND_EXIT, + LOGIN_AND_MINIMIZE, + LOGIN_AND_RUN, +}; + +/* + * Globals + */ +static HICON kwin_icons[MAX_ICONS]; /* Icons depicting time */ +static HFONT hfontdialog = NULL; /* Font in which the dialog is drawn. */ +static HFONT hfonticon = NULL; /* Font for icon label */ +static HINSTANCE hinstance; +static int dlgncmdshow; /* ncmdshow from WinMain */ +static char confname[FILENAME_MAX]; /* current krb.conf location */ +static char realmsname[FILENAME_MAX]; /* current krb.realms location */ +static UINT wm_kerberos_changed; /* Registered message for cache changing */ +static int action; /* After login actions */ +static UINT kwin_timer_id; /* Timer being used for update */ +static BOOL alert; /* Actions on ticket expiration */ +static BOOL beep; +static BOOL alerted; /* TRUE when user already alerted */ +static BOOL isblocking = FALSE; /* TRUE when blocked in WinSock */ +static DWORD blocking_end_time; /* Ending tick count for blocking timeout */ +static FARPROC hook_instance; /* Intance handle for blocking hook function */ + +#ifdef KRB5 + krb5_context k5_context; + krb5_ccache k5_ccache; +#endif + +/*+ + * Function: Called during blocking operations. Implement a timeout + * if nothing occurs within the specified time, cancel the blocking + * operation. Also permit the user to press escape in order to + * cancel the blocking operation. + * + * Returns: TRUE if we got and dispatched a message, FALSE otherwise. + */ +BOOL __export CALLBACK +blocking_hook_proc (void) +{ + MSG msg; + BOOL rc; + + if (GetTickCount() > blocking_end_time) { + WSACancelBlockingCall(); + return FALSE; + } + + rc = (BOOL) PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + if (!rc) + return FALSE; + + if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) { + WSACancelBlockingCall(); + blocking_end_time = msg.time - 1; + return FALSE; + } + + TranslateMessage(&msg); + DispatchMessage(&msg); + + return TRUE; + +} /* blocking_hook_proc */ + + +/*+ + * Function: Set up a blocking hook function. + * + * Parameters: + * timeout - # of seconds to block for before cancelling. + */ +static void +start_blocking_hook ( + int timeout) +{ + FARPROC proc; + + if (isblocking) + return; + + isblocking = TRUE; + blocking_end_time = GetTickCount() + (1000 * timeout); + hook_instance = MakeProcInstance(blocking_hook_proc, hinstance); + proc = WSASetBlockingHook(hook_instance); + assert(proc != NULL); + +} /* start_blocking_hook */ + + +/*+ + * Function: End the blocking hook fuction set up above. + */ +static void +end_blocking_hook (void) +{ + + FreeProcInstance(hook_instance); + WSAUnhookBlockingHook(); + isblocking = FALSE; + +} /* end_blocking_hook */ + + +/*+ + * Function: Centers the specified window on the screen. + * + * Parameters: + * hwnd - the window to center on the screen. + */ +static void +center_dialog ( + HWND hwnd) +{ + int scrwidth, scrheight; + int dlgwidth, dlgheight; + RECT r; + HDC hdc; + + if (hwnd == NULL) + return; + + GetWindowRect(hwnd, &r); + dlgwidth = r.right - r.left; + dlgheight = r.bottom - r.top ; + hdc = GetDC(NULL); + scrwidth = GetDeviceCaps(hdc, HORZRES); + scrheight = GetDeviceCaps(hdc, VERTRES); + ReleaseDC(NULL, hdc); + r.left = (scrwidth - dlgwidth) / 2; + r.top = (scrheight - dlgheight) / 2; + MoveWindow(hwnd, r.left, r.top, dlgwidth, dlgheight, TRUE); + +} /* center_dialog */ + + +/*+ + * Function: Positions the kwin dialog either to the saved location + * or the center of the screen if no saved location. + * + * Parameters: + * hwnd - the window to center on the screen. + */ +static void +position_dialog ( + HWND hwnd) +{ + int n; + int scrwidth, scrheight; + HDC hdc; + char position[256]; + int x, y, cx, cy; + + if (hwnd == NULL) + return; + + hdc = GetDC(NULL); + scrwidth = GetDeviceCaps(hdc, HORZRES); + scrheight = GetDeviceCaps(hdc, VERTRES); + ReleaseDC(NULL, hdc); + GetPrivateProfileString(INI_DEFAULTS, INI_POSITION, "", + position, sizeof(position), KERBEROS_INI); + + n = sscanf(position, " [%d , %d , %d , %d", &x, &y, &cx, &cy); + if (n != 4 || + x > scrwidth || + y > scrheight || + x + cx < 0 || + y + cy < 0) + center_dialog(hwnd); + else + MoveWindow(hwnd, x, y, cx, cy, TRUE); + +} /* position_dialog */ + + +/*+ + * Function: Set font of all dialog items. + * + * Parameters: + * hwnd - the dialog to set the font of + */ +static void +set_dialog_font ( + HWND hwnd, + HFONT hfont) +{ + hwnd = GetWindow(hwnd, GW_CHILD); + + while (hwnd != NULL) { + SendMessage(hwnd, WM_SETFONT, (WPARAM) hfont, 0); + hwnd = GetWindow(hwnd, GW_HWNDNEXT); + } + +} /* set_dialog_font */ + + +/*+ + * Function: Trim leading and trailing white space from a string. + * + * Parameters: + * s - the string to trim. + */ +void +trim ( + char *s) +{ + int l; + int i; + + for (i = 0; s[i]; i++) + if (s[i] != ' ' && s[i] != '\t') + break; + + l = strlen(&s[i]); + memmove(s, &s[i], l + 1); + + for (l--; l >= 0; l--) { + if (s[l] != ' ' && s[l] != '\t') + break; + } + s[l + 1] = 0; + +} /* trim */ + + +/*+ + * Function: This routine figures out the current time epoch and + * returns the conversion factor. It exists because Microloss + * screwed the pooch on the time() and _ftime() calls in its release + * 7.0 libraries. They changed the epoch to Dec 31, 1899! + */ +time_t +kwin_get_epoch (void) +{ + static struct tm jan_1_70 = {0, 0, 0, 1, 0, 70}; + time_t epoch = 0; + + epoch = -mktime(&jan_1_70); /* Seconds til 1970 localtime */ + epoch += _timezone; /* Seconds til 1970 GMT */ + + return epoch; + +} /* kwin_get_epoch */ + + +/*+ + * Function: Save the credentials for later restoration. + * + * Parameters: + * c - Returned pointer to saved credential cache. + * + * pname - Returned as principal name of session. + * + * pinstance - Returned as principal instance of session. + * + * ncred - Returned number of credentials saved. + */ +static void +push_credentials ( + CREDENTIALS **cp, + char *pname, + char *pinstance, + int *ncred) +{ +#ifdef KRB4 + int i; + char service[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + CREDENTIALS *c; + + if (krb_get_tf_fullname ((char *) 0, pname, pinstance, (char *) 0) != KSUCCESS) { + pname[0] = 0; + + pinstance[0] = 0; + } + + *ncred = krb_get_num_cred(); + if (*ncred <= 0) + return; + + c= malloc(*ncred * sizeof(CREDENTIALS)); + assert(c != NULL); + if (c == NULL) { + *ncred = 0; + + return; + } + + for (i = 0; i < *ncred; i++) { + krb_get_nth_cred(service, instance, realm, i + 1); + krb_get_cred(service, instance, realm, &c[i]); + } + + *cp = c; +#endif + +#ifdef KRB5 /* FIXME */ + return; +#endif + +} /* push_credentials */ + + +/*+ + * Function: Restore the saved credentials. + * + * c - Pointer to saved credential cache. + * + * pname - Principal name of session. + * + * pinstance - Principal instance of session. + * + * ncred - Number of credentials saved. + */ +static void +pop_credentials ( + CREDENTIALS *c, + char *pname, + char *pinstance, + int ncred) +{ +#ifdef KRB4 + int i; + + if (pname[0]) + in_tkt(pname, pinstance); + else + dest_tkt(); + + if (ncred <= 0) + return; + + for (i = 0; i < ncred; i++) { + krb_save_credentials(c[i].service, c[i].instance, c[i].realm, + c[i].session, c[i].lifetime, c[i].kvno, &(c[i].ticket_st), + c[i].issue_date); + } + + free(c); +#endif +#ifdef KRB5 /* FIXME */ + return; +#endif + +} /* pop_credentials */ + + +/*+ + * Function: Changes the password. + * + * Parameters: + * hwnd - the current window from which command was invoked. + * + * name - name of user to change password for + * + * instance - instance of user to change password for + * + * realm - realm in which to change password + * + * oldpw - the old password + * + * newpw - the new password to change to + * + * Returns: TRUE if change took place, FALSE otherwise. + */ +static BOOL +change_password ( + HWND hwnd, + char *name, + char *instance, + char *realm, + char *oldpw, + char *newpw) +{ +#ifdef KRB4 + des_cblock new_key; + char *ret_st; + int krc; + char *p; + CREDENTIALS *c; + int ncred; + char pname[ANAME_SZ]; + char pinstance[INST_SZ]; + + push_credentials(&c, pname, pinstance, &ncred); + krc = krb_get_pw_in_tkt( + name, instance, realm, PWSERV_NAME, KADM_SINST, 1, oldpw); + + if (krc != KSUCCESS) { + if (krc == INTK_BADPW) + p = "Old password is incorrect"; + else + p = krb_get_err_text(krc); + pop_credentials(c, pname, pinstance, ncred); + MessageBox(hwnd, p, "", MB_OK | MB_ICONEXCLAMATION); + + return FALSE; + } + + krc = kadm_init_link(PWSERV_NAME, KRB_MASTER, realm); + + if (krc != KSUCCESS) { + pop_credentials(c, pname, pinstance, ncred); + MessageBox(hwnd, kadm_get_err_text(krc), "", MB_OK | MB_ICONEXCLAMATION); + + return FALSE; + } + + des_string_to_key(newpw, new_key); + krc = kadm_change_pw2(new_key, newpw, &ret_st); + pop_credentials(c, pname, pinstance, ncred); + + if (ret_st != NULL) + free(ret_st); + + if (krc != KSUCCESS) { + MessageBox(hwnd, kadm_get_err_text(krc), "", MB_OK | MB_ICONEXCLAMATION); + + return FALSE; + } + + return TRUE; +#endif + +#ifdef KRB5 /* FIXME */ + MessageBox (NULL, "Changing passwords is not yet implemented", "", MB_ICONEXCLAMATION); + return TRUE; +#endif + +} /* change_password */ + +/*+ + * Function: Process WM_COMMAND messages for the password dialog. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - id of the command item + * + * lparam - LOWORD=hwnd of control, HIWORD=notification message. + * + * Returns: TRUE if initialized sucessfully, false otherwise. + */ +static LONG +password_command ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + char name[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + char oldpw[MAX_KPW_LEN]; + char newpw1[MAX_KPW_LEN]; + char newpw2[MAX_KPW_LEN]; + HCURSOR hcursor; + BOOL b; + int id; + + if (HIWORD(lparam) != BN_CLICKED) { + GetDlgItemText(hwnd, IDD_PASSWORD_NAME, name, sizeof(name)); + trim(name); + GetDlgItemText(hwnd, IDD_PASSWORD_REALM, realm, sizeof(realm)); + trim(realm); + GetDlgItemText(hwnd, IDD_OLD_PASSWORD, oldpw, sizeof(oldpw)); + GetDlgItemText(hwnd, IDD_NEW_PASSWORD1, newpw1, sizeof(newpw1)); + GetDlgItemText(hwnd, IDD_NEW_PASSWORD2, newpw2, sizeof(newpw2)); + b = strlen(name) && strlen(realm) && strlen(oldpw) && + strlen(newpw1) && strlen(newpw2); + EnableWindow(GetDlgItem(hwnd, IDOK), b); + id = (b) ? IDOK : IDD_PASSWORD_CR; + SendMessage(hwnd, DM_SETDEFID, id, 0); + + return FALSE; + } + + switch (wparam) { + case IDOK: + if (isblocking) + return TRUE; + + GetDlgItemText(hwnd, IDD_PASSWORD_NAME, name, sizeof(name)); + trim(name); + GetDlgItemText(hwnd, IDD_PASSWORD_INSTANCE, instance, sizeof(instance)); + trim(instance); + GetDlgItemText(hwnd, IDD_PASSWORD_REALM, realm, sizeof(realm)); + trim(realm); + GetDlgItemText(hwnd, IDD_OLD_PASSWORD, oldpw, sizeof(oldpw)); + GetDlgItemText(hwnd, IDD_NEW_PASSWORD1, newpw1, sizeof(newpw1)); + GetDlgItemText(hwnd, IDD_NEW_PASSWORD2, newpw2, sizeof(newpw2)); + + if (strcmp(newpw1, newpw2) != 0) { + MessageBox(hwnd, "The two passwords you entered don't match!", "", + MB_OK | MB_ICONEXCLAMATION); + SetDlgItemText(hwnd, IDD_NEW_PASSWORD1, ""); + SetDlgItemText(hwnd, IDD_NEW_PASSWORD2, ""); + PostMessage(hwnd, WM_NEXTDLGCTL, + GetDlgItem(hwnd, IDD_NEW_PASSWORD1), MAKELONG(1, 0)); + + return TRUE; + } + + hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); + start_blocking_hook(BLOCK_MAX_SEC); + + if (change_password(hwnd, name, instance, realm, oldpw, newpw1)) + EndDialog(hwnd, IDOK); + else + PostMessage(hwnd, WM_NEXTDLGCTL, + GetDlgItem(hwnd, IDD_OLD_PASSWORD), MAKELONG(1, 0)); + + end_blocking_hook(); + SetCursor(hcursor); + + return TRUE; + + case IDCANCEL: + if (isblocking) + WSACancelBlockingCall(); + EndDialog(hwnd, IDCANCEL); + + return TRUE; + + case IDD_PASSWORD_CR: + id = GetDlgCtrlID(GetFocus()); + assert(id != 0); + + if (id == IDD_NEW_PASSWORD2) + PostMessage(hwnd, WM_NEXTDLGCTL, + GetDlgItem(hwnd, IDD_PASSWORD_NAME), MAKELONG(1, 0)); + else + PostMessage(hwnd, WM_NEXTDLGCTL, 0, 0); + + return TRUE; + + } + + return FALSE; + +} /* password_command */ + + +/*+ + * Function: Process WM_INITDIALOG messages for the password dialog. + * Set up all initial dialog values from the parent dialog. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - handle of the control for focus. + * + * lparam - lparam from dialog box call. + * + * Returns: TRUE if we didn't set the focus here, + * FALSE if we did. + */ +static BOOL +password_initdialog ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + char name[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + HWND hwndparent; + int id; + + center_dialog(hwnd); + set_dialog_font(hwnd, hfontdialog); + + hwndparent = GetParent(hwnd); + assert(hwndparent != NULL); + + GetDlgItemText(hwndparent, IDD_LOGIN_NAME, name, sizeof(name)); + trim(name); + SetDlgItemText(hwnd, IDD_PASSWORD_NAME, name); + + GetDlgItemText(hwndparent, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); + trim(instance); + SetDlgItemText(hwnd, IDD_PASSWORD_INSTANCE, instance); + + GetDlgItemText(hwndparent, IDD_LOGIN_REALM, realm, sizeof(realm)); + trim(realm); + SetDlgItemText(hwnd, IDD_PASSWORD_REALM, realm); + + if (strlen(name) == 0) + id = IDD_PASSWORD_NAME; + else if (strlen(realm) == 0) + id = IDD_PASSWORD_REALM; + else + id = IDD_OLD_PASSWORD; + + SetFocus(GetDlgItem(hwnd, id)); + + return FALSE; + +} /* password_initdialog */ + + +/*+ + * Function: Process dialog specific messages for the password dialog. + * + * Parameters: + * hwnd - the dialog receiving the message. + * + * message - the message to process. + * + * wparam - wparam of the message. + * + * lparam - lparam of the message. + * + * Returns: TRUE if message handled locally, FALSE otherwise. + */ +static BOOL CALLBACK +password_dlg_proc ( + HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + LRESULT rc; + + switch (message) { + + case WM_INITDIALOG: + return password_initdialog(hwnd, wparam, lparam); + + case WM_COMMAND: + password_command(hwnd, wparam, lparam); + return (BOOL) rc; + + case WM_SETCURSOR: + if (isblocking) { + SetCursor(LoadCursor(NULL, IDC_WAIT)); + SetWindowLong(hwnd, DWL_MSGRESULT, TRUE); + + return TRUE; + } + break; + } + + return FALSE; + +} /* password_dlg_proc */ + + +/*+ + * Function: Display and process the password dialog. + * + * Parameters: + * hwnd - the parent window for the dialog + * + * Returns: TRUE if the dialog completed successfully, FALSE otherwise. + */ +static BOOL +password_dialog ( + HWND hwnd) +{ + DLGPROC dlgproc; + int rc; + + dlgproc = (FARPROC) MakeProcInstance(password_dlg_proc, hinstance); + assert(dlgproc != NULL); + + if (dlgproc == NULL) + return FALSE; + + rc = DialogBox(hinstance, MAKEINTRESOURCE(ID_PASSWORD), hwnd, dlgproc); + assert(rc != -1); + + FreeProcInstance((FARPROC) dlgproc); + + return rc == IDOK; + +} /* password_dialog */ + + +/*+ + * Function: Process WM_INITDIALOG messages for the options dialog. + * Set up all initial dialog values from the KERBEROS_INI file. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - handle of the control for focus. + * + * lparam - lparam from dialog box call. + * + * Returns: TRUE if we didn't set the focus here, + * FALSE if we did. + */ +static LONG +opts_initdialog ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + char defname[FILENAME_MAX]; + UINT rc; + int lifetime; + + center_dialog(hwnd); + set_dialog_font(hwnd, hfontdialog); + + /* krb.conf file */ + rc = GetWindowsDirectory(defname, sizeof(defname)); + assert(rc > 0); + + strcat(defname, "\\"); + strcat(defname, DEF_KRB_CONF); + GetPrivateProfileString(INI_FILES, INI_KRB_CONF, defname, + confname, sizeof(confname), KERBEROS_INI); + _strupr(confname); + SetDlgItemText(hwnd, IDD_CONF, confname); + + /* krb.realms file */ + rc = GetWindowsDirectory(defname, sizeof(defname)); + assert(rc > 0); + + strcat(defname, "\\"); + strcat(defname, DEF_KRB_REALMS); + GetPrivateProfileString(INI_FILES, INI_KRB_REALMS, defname, + realmsname, sizeof(realmsname), KERBEROS_INI); + _strupr(realmsname); + SetDlgItemText(hwnd, IDD_REALMS, realmsname); + + /* Ticket duration */ + lifetime = GetPrivateProfileInt(INI_OPTIONS, INI_DURATION, + DEFAULT_TKT_LIFE * 5, KERBEROS_INI); + SetDlgItemInt(hwnd, IDD_LIFETIME, lifetime, FALSE); + + /* Expiration action */ + GetPrivateProfileString(INI_EXPIRATION, INI_ALERT, "No", + defname, sizeof(defname), KERBEROS_INI); + alert = _stricmp(defname, "Yes") == 0; + SendDlgItemMessage(hwnd, IDD_ALERT, BM_SETCHECK, alert, 0); + GetPrivateProfileString(INI_EXPIRATION, INI_BEEP, "No", + defname, sizeof(defname), KERBEROS_INI); + beep = _stricmp(defname, "Yes") == 0; + SendDlgItemMessage(hwnd, IDD_BEEP, BM_SETCHECK, beep, 0); + + return TRUE; + +} /* opts_initdialog */ + + +/*+ + * Function: Process WM_COMMAND messages for the options dialog. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - id of the command item + * + * lparam - LOWORD=hwnd of control, HIWORD=notification message. + * + * Returns: TRUE if initialized sucessfully, false otherwise. + */ +static LONG +opts_command ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + char defname[FILENAME_MAX]; + char *p; + BOOL b; + int lifetime; + int rc; + + switch (wparam) { + + case IDOK: + /* Ticket duration */ + lifetime = GetDlgItemInt(hwnd, IDD_LIFETIME, &b, FALSE); + + if (!b) { + MessageBox(hwnd, "Lifetime must be a number!", "", MB_OK | MB_ICONEXCLAMATION); + + return TRUE; + } + + _itoa(lifetime, defname, 10); + b = WritePrivateProfileString(INI_OPTIONS, INI_DURATION, defname, KERBEROS_INI); + assert(b); + + /* krb.conf file */ + GetDlgItemText(hwnd, IDD_CONF, confname, sizeof(confname)); + trim(confname); + rc = GetWindowsDirectory(defname, sizeof(defname)); + assert(rc > 0); + + strcat(defname, "\\"); + strcat(defname, DEF_KRB_CONF); + if (_stricmp(confname, defname) == 0 || !defname[0]) + p = NULL; + else + p = confname; + b = WritePrivateProfileString(INI_FILES, INI_KRB_CONF, p, KERBEROS_INI); + assert(b); + + /* krb.realms file */ + GetDlgItemText(hwnd, IDD_REALMS, realmsname, sizeof(realmsname)); + trim(realmsname); + rc = GetWindowsDirectory(defname, sizeof(defname)); + assert(rc > 0); + + strcat(defname, "\\"); + strcat(defname, DEF_KRB_REALMS); + if (_stricmp(realmsname, defname) == 0 || !defname[0]) + p = NULL; + else + p = defname; + b = WritePrivateProfileString(INI_FILES, INI_KRB_REALMS, p, KERBEROS_INI); + assert(b); + + /* 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); + + EndDialog(hwnd, IDOK); + + return TRUE; + + case IDCANCEL: + EndDialog(hwnd, IDCANCEL); + + return TRUE; + } + + return FALSE; + +} /* opts_command */ + + +/*+ + * Function: Process dialog specific messages for the opts dialog. + * + * Parameters: + * hwnd - the dialog receiving the message. + * + * message - the message to process. + * + * wparam - wparam of the message. + * + * lparam - lparam of the message. + * + * Returns: TRUE if message handled locally, FALSE otherwise. + */ +static BOOL CALLBACK +opts_dlg_proc ( + HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + LRESULT rc; + + switch (message) { + + case WM_INITDIALOG: + rc = opts_initdialog(hwnd, wparam, lparam); + + return (BOOL) rc; + + case WM_COMMAND: + rc = opts_command(hwnd, wparam, lparam); + + return (BOOL) rc; + } + + return FALSE; + +} /* opts_dlg_proc */ + + +/*+ + * Function: Display and process the options dialog. + * + * Parameters: + * hwnd - the parent window for the dialog + * + * Returns: TRUE if the dialog completed successfully, FALSE otherwise. + */ +static BOOL +opts_dialog ( + HWND hwnd) +{ + DLGPROC dlgproc; + int rc; + + dlgproc = (FARPROC) MakeProcInstance(opts_dlg_proc, hinstance); + assert(dlgproc != NULL); + + if (dlgproc == NULL) + return FALSE; + + rc = DialogBox(hinstance, MAKEINTRESOURCE(ID_OPTS), hwnd, dlgproc); + assert(rc != -1); + + FreeProcInstance((FARPROC) dlgproc); + + return rc == IDOK; + +} /* opts_dialog */ + + +/*+ + * Function: Save most recent login triplets for placement on the + * bottom of the file menu. + * + * Parameters: + * hwnd - the handle of the window containing the menu to edit. + * + * name - A login name to save in the recent login list + * + * instance - An instance to save in the recent login list + * + * realm - A realm to save in the recent login list + */ +static void +kwin_push_login ( + HWND hwnd, + char *name, + char *instance, + char *realm) +{ + HMENU hmenu; + int i; + int id; + int ctitems; + char fullname[MAX_K_NAME_SZ + 3]; + 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); + + hmenu = GetMenu(hwnd); + assert(hmenu != NULL); + + hmenu = GetSubMenu(hmenu, 0); + assert(hmenu != NULL); + + ctitems = GetMenuItemCount(hmenu); + assert(ctitems >= FILE_MENU_ITEMS); + + if (ctitems == FILE_MENU_ITEMS) { + rc = AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); + assert(rc); + + ctitems++; + } + + for (i = FILE_MENU_ITEMS + 1; i < ctitems; i++) { + GetMenuString(hmenu, i, menuitem, sizeof(menuitem), MF_BYPOSITION); + + if (strcmp(&fullname[3], &menuitem[3]) == 0) { + rc = RemoveMenu(hmenu, i, MF_BYPOSITION); + assert(rc); + + ctitems--; + + break; + } + } + + rc = InsertMenu(hmenu, FILE_MENU_ITEMS + 1, MF_BYPOSITION, 1, fullname); + assert(rc); + + ctitems++; + if (ctitems - FILE_MENU_ITEMS - 1 > FILE_MENU_MAX_LOGINS) { + RemoveMenu(hmenu, ctitems - 1, MF_BYPOSITION); + + ctitems--; + } + + id = 0; + for (i = FILE_MENU_ITEMS + 1; i < ctitems; i++) { + GetMenuString(hmenu, i, menuitem, sizeof(menuitem), MF_BYPOSITION); + + rc = RemoveMenu(hmenu, i, MF_BYPOSITION); + assert(rc); + + menuitem[1] = '1' + id; + rc = InsertMenu(hmenu, i, MF_BYPOSITION, IDM_FIRST_LOGIN + id, menuitem); + assert(rc); + + id++; + } + +} /* kwin_push_login */ + + +/*+ + * Function: Initialize the logins on the file menu form the KERBEROS.INI + * file. + * + * Parameters: + * hwnd - handle of the dialog containing the file menu. + */ +static void +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; + + hmenu = GetMenu(hwnd); + assert(hmenu != NULL); + + 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); + if (!menuitem[3]) + continue; + + menuitem[0] = '&'; + menuitem[1] = '1' + id; + menuitem[2] = ' '; + + if (id == 0) { + rc = AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); + assert(rc); + } + AppendMenu(hmenu, MF_STRING, IDM_FIRST_LOGIN + id, menuitem); + + id++; + } + +} /* kwin_init_file_menu */ + + +/*+ + * Function: Save the items on the file menu in the KERBEROS.INI file. + * + * Parameters: + * hwnd - handle of the dialog containing the file menu. + */ +static void +kwin_save_file_menu ( + HWND hwnd) +{ + HMENU hmenu; + int i; + 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); + + 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); + + id++; + } + +} /* kwin_save_file_menu */ + + + +/*+ + * Function: Given an expiration time, choose an appropriate + * icon to display. + * + * Parameters: + * expiration time of expiration in time() compatible units + * + * Returns: Handle of icon to display + */ +HICON +kwin_get_icon ( + time_t expiration) +{ + int ixicon; + time_t dt; + + dt = expiration - time(NULL); + dt = dt / 60; /* convert to minutes */ + if (dt <= 0) + ixicon = IDI_EXPIRED - IDI_FIRST_CLOCK; + else if (dt > 60) + ixicon = IDI_TICKET - IDI_FIRST_CLOCK; + else + ixicon = (int) (dt / 5); + + return kwin_icons[ixicon]; + +} /* kwin_get_icon */ + + +/*+ + * Function: Intialize name fields in the Kerberos dialog. + * + * Parameters: + * hwnd - the window recieving the message. + * + * fullname - the full kerberos name to initialize with + */ +static void +kwin_init_name ( + HWND hwnd, + char *fullname) +{ + char name[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + int krc; + + if (fullname == NULL || fullname[0] == 0) { + #ifdef KRB4 + strcpy(name, krb_get_default_user()); + GetPrivateProfileString(INI_DEFAULTS, INI_INSTANCE, "", + instance, sizeof(instance), KERBEROS_INI); + krc = krb_get_lrealm(realm, 1); + if (krc != KSUCCESS) + realm[0] = 0; + #endif + + + #ifdef KRB5 + { + krb5_error_code code; + char *ptr; + + GetPrivateProfileString (INI_DEFAULTS, INI_USER, "", + name, sizeof(name), KERBEROS_INI); + //GetPrivateProfileString(INI_DEFAULTS, INI_INSTANCE, "", + // instance, sizeof(instance), KERBEROS_INI); + *instance = '\0'; + + *realm = '\0'; + code = krb5_get_default_realm (k5_context, &ptr); + if (! code) { + strcpy (realm, ptr); + free (ptr); + } + } + #endif + + GetPrivateProfileString(INI_DEFAULTS, INI_REALM, realm, + realm, sizeof(realm), KERBEROS_INI); + } else { + #ifdef KRB4 + kname_parse(name, instance, realm, fullname); + #endif + + #ifdef KRB5 + krc = k5_kname_parse(name, realm, fullname); + *instance = '\0'; + #endif + } + + SetDlgItemText(hwnd, IDD_LOGIN_NAME, name); + name[0] = 0; + GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); + SetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance); + SetDlgItemText(hwnd, IDD_LOGIN_REALM, realm); + +} /* kwin_init_name */ + + +/*+ + * Function: Set the focus to the name control if no name + * exists, the realm control if no realm exists or the + * password control. Uses PostMessage not SetFocus. + * + * Parameters: + * hwnd - the Window handle of the parent. + */ +void +kwin_set_default_focus ( + HWND hwnd) +{ + char name[ANAME_SZ]; + char realm[REALM_SZ]; + HWND hwnditem; + + GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); + + trim(name); + if (strlen(name) <= 0) + hwnditem = GetDlgItem(hwnd, IDD_LOGIN_NAME); + else { + GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); + trim(realm); + + if (strlen(realm) <= 0) + hwnditem = GetDlgItem(hwnd, IDD_LOGIN_REALM); + else + hwnditem = GetDlgItem(hwnd, IDD_LOGIN_PASSWORD); + } + + PostMessage(hwnd, WM_NEXTDLGCTL, hwnditem, MAKELONG(1, 0)); + +} /* kwin_set_default_focus */ + + +/*+ + * Function: Save the values which live in the KERBEROS.INI file. + * + * Parameters: + * hwnd - the window handle of the dialog containing fields to + * be saved + */ +static void +kwin_save_name ( + HWND hwnd) +{ + char name[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + + GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); + trim(name); + + #ifdef KRB4 + krb_set_default_user(name); + GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); + trim(instance); + WritePrivateProfileString(INI_DEFAULTS, INI_INSTANCE, instance, KERBEROS_INI); + #endif + + #ifdef KRB5 + WritePrivateProfileString(INI_DEFAULTS, INI_USER, name, KERBEROS_INI); + *instance = '\0'; + #endif + + GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); + trim(realm); + WritePrivateProfileString(INI_DEFAULTS, INI_REALM, realm, KERBEROS_INI); + + kwin_push_login(hwnd, name, instance, realm); + +} /* kwin_save_name */ + + +/*+ + * Function: Process WM_INITDIALOG messages. Set the fonts + * for all items on the dialog and populate the ticket list. + * Also set the default values for user, instance and realm. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - handle of the control for focus. + * + * lparam - lparam from dialog box call. + * + * Returns: TRUE if we didn't set the focus here, + * FALSE if we did. + */ +static BOOL +kwin_initdialog ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + LOGFONT lf; + HDC hdc; + char name[ANAME_SZ]; + + position_dialog(hwnd); + ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); + kwin_init_file_menu(hwnd); + kwin_init_name(hwnd, (char *) lparam); + hdc = GetDC(NULL); + assert(hdc != NULL); + + memset(&lf, 0, sizeof(lf)); + lf.lfHeight = -MulDiv(9, GetDeviceCaps(hdc, LOGPIXELSY), 72); + strcpy(lf.lfFaceName, "Arial"); + hfontdialog = CreateFontIndirect(&lf); + assert(hfontdialog != NULL); + + if (hfontdialog == NULL) { + ReleaseDC(NULL, hdc); + + return TRUE; + } + + lf.lfHeight = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72); + hfonticon = CreateFontIndirect(&lf); + assert(hfonticon != NULL); + + if (hfonticon == NULL) { + ReleaseDC(NULL, hdc); + + return TRUE; + } + + ReleaseDC(NULL, hdc); + + set_dialog_font(hwnd, hfontdialog); + GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); + trim(name); + + if (strlen(name) > 0) + SetFocus(GetDlgItem(hwnd, IDD_LOGIN_PASSWORD)); + else + SetFocus(GetDlgItem(hwnd, IDD_LOGIN_NAME)); + + ShowWindow(hwnd, dlgncmdshow); + kwin_timer_id = SetTimer(hwnd, 1, KWIN_UPDATE_PERIOD, NULL); + assert(kwin_timer_id != 0); + + return FALSE; + +} /* kwin_initdialog */ + + +/*+ + * Function: Process WM_DESTROY messages. Delete the font + * created for use by the controls. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - none + * + * lparam - none + * + * Returns: 0 + */ +static LONG +kwin_destroy ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + char position[256]; + RECT r; + BOOL b; + + ticket_destroy(GetDlgItem(hwnd, IDD_TICKET_LIST)); + + if (hfontdialog != NULL) + DeleteObject(hfontdialog); + + if (hfonticon != NULL) + DeleteObject(hfonticon); + + 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); + + KillTimer(hwnd, kwin_timer_id); + + return 0; + +} /* kwin_destroy */ + + +/*+ + * Function: Retrievs item WindowRect in hwnd client + * coordiate system. + * + * Parameters: + * hwnditem - the item to retrieve + * + * item - dialog in which into which to translate + * + * r - rectangle returned + */ +static void +windowrect ( + HWND hwnditem, + HWND hwnd, + RECT *r) +{ + GetWindowRect(hwnditem, r); + ScreenToClient(hwnd, (LPPOINT) &(r->left)); + ScreenToClient(hwnd, (LPPOINT) &(r->right)); + +} /* windowrect */ + + +/*+ + * Function: Process WM_SIZE messages. Resize the + * list and position the buttons attractively. + * + * Parameters: + * hwnd - the window receiving the message. + * + * wparam - type of resize occuring + * + * lparam - LOWORD=width of client area, + * HIWORD=height of client area. + * + * Returns: 0 + */ +static LONG +kwin_size ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + #define listgap 8 + RECT r; + RECT rdlg; + int hmargin, vmargin; + HWND hwnditem; + int cx, cy; + int cxdlg, cydlg; + int i; + int titlebottom; + int editbottom; + int listbottom; + int gap; + int left; + int titleleft[IDD_MAX_TITLE - IDD_MIN_TITLE + 1]; + + if (wparam == SIZE_MINIMIZED) + return 0; + + GetClientRect(hwnd, &rdlg); + cxdlg = LOWORD(lparam); + cydlg = HIWORD(lparam); + + /* + * The ticket list title + */ + hwnditem = GetDlgItem(hwnd, IDD_TICKET_LIST_TITLE); + + if (hwnditem == NULL) + return 0; + + windowrect(hwnditem, hwnd, &r); + hmargin = r.left; + vmargin = r.top; + cx = cxdlg - 2 * hmargin; + cy = r.bottom - r.top; + MoveWindow(hwnditem, r.left, r.top, cx, cy, TRUE); + + /* + * The buttons + */ + cx = 0; + + for (i = IDD_MIN_BUTTON; i <= IDD_MAX_BUTTON; i++) { + hwnditem = GetDlgItem(hwnd, i); + windowrect(hwnditem, hwnd, &r); + if (i == IDD_MIN_BUTTON) + hmargin = r.left; + + cx += r.right - r.left; + } + + gap = (cxdlg - 2 * hmargin - cx) / (IDD_MAX_BUTTON - IDD_MIN_BUTTON); + left = hmargin; + for (i = IDD_MIN_BUTTON; i <= IDD_MAX_BUTTON; i++) { + hwnditem = GetDlgItem(hwnd, i); + windowrect(hwnditem, hwnd, &r); + editbottom = -r.top; + cx = r.right - r.left; + cy = r.bottom - r.top; + r.top = rdlg.bottom - vmargin - cy; + MoveWindow(hwnditem, left, r.top, cx, cy, TRUE); + + left += cx + gap; + } + + /* + * Edit fields + */ + editbottom += r.top; + + cx = 0; + for (i = IDD_MIN_EDIT; i <= IDD_MAX_EDIT; i++) { + hwnditem = GetDlgItem(hwnd, i); + windowrect(hwnditem, hwnd, &r); + + if (i == IDD_MIN_EDIT) { + gap = r.right; + hmargin = r.left; + editbottom += r.bottom; + titlebottom = -r.top; + } + if (i == IDD_MIN_EDIT + 1) + gap = r.left - gap; + + cx += r.right - r.left; + } + + cx = cxdlg - 2 * hmargin - (IDD_MAX_EDIT - IDD_MIN_EDIT) * gap; + cx = cx / (IDD_MAX_EDIT - IDD_MIN_EDIT + 1); + left = hmargin; + + for (i = IDD_MIN_EDIT; i <= IDD_MAX_EDIT; i++) { + hwnditem = GetDlgItem(hwnd, i); + windowrect(hwnditem, hwnd, &r); + cy = r.bottom - r.top; + r.top = editbottom - cy; + MoveWindow(hwnditem, left, r.top, cx, cy, TRUE); + titleleft[i-IDD_MIN_EDIT] = left; + + left += cx + gap; + } + + /* + * Edit field titles + */ + titlebottom += r.top; + windowrect(GetDlgItem(hwnd, IDD_MIN_TITLE), hwnd, &r); + titlebottom += r.bottom; + listbottom = -r.top; + + for (i = IDD_MIN_TITLE; i <= IDD_MAX_TITLE; i++) { + hwnditem = GetDlgItem(hwnd, i); + windowrect(hwnditem, hwnd, &r); + cx = r.right - r.left; + cy = r.bottom - r.top; + r.top = titlebottom - cy; + MoveWindow(hwnditem, titleleft[i-IDD_MIN_TITLE], r.top, cx, cy, TRUE); + } + + /* + * The list + */ + listbottom = r.top - listgap; + hwnditem = GetDlgItem(hwnd, IDD_TICKET_LIST); + windowrect(hwnditem, hwnd, &r); + hmargin = r.left; + cx = cxdlg - 2 * hmargin; + cy = listbottom - r.top; + MoveWindow(hwnditem, r.left, r.top, cx, cy, TRUE); + + return 0; + +} /* kwin_size */ + + +/*+ + * Function: Process WM_GETMINMAXINFO messages + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - none. + * + * lparam - LPMINMAXINFO + * + * Returns: 0 + */ +static LONG +kwin_getminmaxinfo ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + MINMAXINFO *lpmmi; + + lpmmi = (MINMAXINFO *) lparam; + lpmmi->ptMinTrackSize.x = (KWIN_MIN_WIDTH * LOWORD(GetDialogBaseUnits())) / 4; + lpmmi->ptMinTrackSize.y = (KWIN_MIN_HEIGHT * HIWORD(GetDialogBaseUnits())) / 8; + + return 0; + +} /* kwin_getminmaxinfo */ + + +/*+ + * Function: Process WM_TIMER messages + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - the timer id. + * + * lparam - timer callback proceedure + * + * Returns: 0 + */ +static LONG +kwin_timer ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + HWND hwndfocus; + time_t t; + time_t expiration; + BOOL expired; + #ifdef KRB4 + CREDENTIALS c; + int ncred; + int i; + char service[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + #endif + #ifdef KRB5 + krb5_error_code code; + krb5_cc_cursor cursor; + krb5_creds cred; + int n; + char *s; + #endif + + if (wparam != 1) + return DefDlgProc(hwnd, WM_TIMER, wparam, lparam); + + expired = FALSE; + ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); + + if (alerted) { + if (IsIconic(hwnd)) + InvalidateRect(hwnd, NULL, TRUE); + + return 0; + } + + #ifdef KRB4 + ncred = krb_get_num_cred(); + for (i = 1; i <= ncred; i++) { + krb_get_nth_cred(service, instance, realm, i); + + if (_stricmp(service, "krbtgt") == 0) { + /* Warn if ticket will expire w/i TIME_BUFFER seconds */ + krb_get_cred(service, instance, realm, &c); + expiration = c.issue_date + (long) c.lifetime * 5L * 60L; + t = TIME_BUFFER + time(NULL); + + if (t >= expiration) { + expired = TRUE; + /* Don't alert because of stale tickets */ + if (t >= expiration + KWIN_UPDATE_PERIOD / 1000) { + alerted = TRUE; + + if (IsIconic(hwnd)) + InvalidateRect(hwnd, NULL, TRUE); + return 0; + } + break; + } + } + } + #endif + + #ifdef KRB5 + code = krb5_cc_start_seq_get (k5_context, k5_ccache, &cursor); + + while (code == 0) { + code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &cred); + if (code) + break; + n = krb5_princ_component(k5_context, cred.server, 0)->length; + s = krb5_princ_component(k5_context, cred.server, 0)->data; + if (n != KRB5_TGS_NAME_SIZE) + continue; + if (memcmp (KRB5_TGS_NAME, s, KRB5_TGS_NAME_SIZE)) + continue; + + /* Warn if ticket will expire w/i TIME_BUFFER seconds */ + expiration = cred.times.endtime; + t = TIME_BUFFER + time(NULL); + + if (t >= expiration) { + expired = TRUE; + /* Don't alert because of stale tickets */ + if (t >= expiration + KWIN_UPDATE_PERIOD / 1000) { + alerted = TRUE; + + if (IsIconic(hwnd)) + InvalidateRect(hwnd, NULL, TRUE); + return 0; + } + break; + } + } + krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); + + #endif + + if (!expired) { + if (IsIconic(hwnd)) + InvalidateRect(hwnd, NULL, TRUE); + + return 0; + } + + alerted = TRUE; + + if (beep) + MessageBeep(MB_ICONEXCLAMATION); + + if (alert) { + if (IsIconic(hwnd)) { + hwndfocus = GetFocus(); + ShowWindow(hwnd, SW_RESTORE); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); + SetFocus(hwndfocus); + } + + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); + + return 0; + } + + if (IsIconic(hwnd)) + InvalidateRect(hwnd, NULL, TRUE); + + return 0; + +} /* kwin_timer */ + + +/*+ + * Function: Process WM_COMMAND messages + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - id of the command item + * + * lparam - LOWORD=hwnd of control, HIWORD=notification message. + * + * Returns: TRUE if initialized sucessfully, false otherwise. + */ +static LONG +kwin_command ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + char name[ANAME_SZ]; + char instance[INST_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]; + #ifdef KRB4 + int lifetime; + int krc; + #endif + #ifdef KRB5 + long lifetime; + krb5_error_code code; + krb5_principal principal; + krb5_creds creds; + krb5_principal server; + krb5_timestamp now; + #endif + + #ifdef KRB4 + EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), krb_get_num_cred() > 0); + #endif + + #ifdef KRB5 + EnableWindow(GetDlgItem(hwnd, IDD_TICKET_DELETE), k5_get_num_cred() > 0); + #endif + + GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); + trim(name); + blogin = strlen(name) > 0; + + if (blogin) { + GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); + trim(realm); + blogin = strlen(realm) > 0; + } + + if (blogin) { + GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password)); + blogin = strlen(password) > 0; + } + + EnableWindow(GetDlgItem(hwnd, IDD_LOGIN), blogin); + + if (HIWORD(lparam) != BN_CLICKED && HIWORD(lparam) != 0 && HIWORD(lparam) != 1) + return FALSE; + + if (wparam >= IDM_FIRST_LOGIN && wparam < IDM_FIRST_LOGIN + FILE_MENU_MAX_LOGINS) { + hmenu = GetMenu(hwnd); + assert(hmenu != NULL); + + hmenu = GetSubMenu(hmenu, 0); + assert(hmenu != NULL); + + if (!GetMenuString(hmenu, wparam, menuitem, sizeof(menuitem), MF_BYCOMMAND)) + return TRUE; + + if (menuitem[0]) + kwin_init_name(hwnd, &menuitem[3]); + + return TRUE; + } + + switch (wparam) { + case IDM_EXIT: + if (isblocking) + WSACancelBlockingCall(); + WinHelp(hwnd, KERBEROS_HLP, HELP_QUIT, 0); + PostQuitMessage(0); + + return TRUE; + + case IDD_LOGIN: + if (isblocking) + return TRUE; + + GetDlgItemText(hwnd, IDD_LOGIN_NAME, name, sizeof(name)); + trim(name); + GetDlgItemText(hwnd, IDD_LOGIN_INSTANCE, instance, sizeof(instance)); + trim(instance); + GetDlgItemText(hwnd, IDD_LOGIN_REALM, realm, sizeof(realm)); + trim(realm); + GetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, password, sizeof(password)); + trim(password); + + hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); + lifetime = GetPrivateProfileInt(INI_OPTIONS, INI_DURATION, + DEFAULT_TKT_LIFE * 5, KERBEROS_INI); + start_blocking_hook(BLOCK_MAX_SEC); + + #ifdef KRB4 + lifetime = (lifetime + 4) / 5; + krc = krb_get_pw_in_tkt(name, instance, realm, "krbtgt", realm, + lifetime, password); + #endif + + #ifdef KRB5 + code = krb5_parse_name(k5_context, name, &principal); + code = krb5_cc_initialize(k5_context, k5_ccache, principal); + memset(&creds, 0, sizeof(creds)); + creds.client = principal; + + 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); + + creds.server = server; + + //code = krb5_os_localaddr(&address); + code = krb5_timeofday(k5_context, &now); + + creds.times.starttime = 0; + creds.times.endtime = now + 60L * lifetime; + creds.times.renew_till = 0; + + code = krb5_get_in_tkt_with_password(k5_context, 0, NULL, NULL, + NULL, password, k5_ccache, &creds, 0); + + krb5_free_principal(k5_context, server); + //krb5_free_addresses(k5_context, address); + + #endif + + 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) { + com_err (NULL, code, "while logging in"); + return TRUE; + } + // ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); + + #endif + + SetDlgItemText(hwnd, IDD_LOGIN_PASSWORD, ""); + kwin_save_name(hwnd); + alerted = FALSE; + + switch (action) { + case LOGIN_AND_EXIT: + SendMessage(hwnd, WM_COMMAND, IDM_EXIT, 0); + break; + + case LOGIN_AND_MINIMIZE: + ShowWindow(hwnd, SW_MINIMIZE); + break; + } + + return TRUE; + + case IDD_TICKET_DELETE: + if (isblocking) + return TRUE; + + #ifdef KRB4 + krc = dest_tkt(); + if (krc != KSUCCESS) + MessageBox(hwnd, krb_get_err_text(krc), "", + MB_OK | MB_ICONEXCLAMATION); + #endif + + #ifdef KRB5 + code = k5_dest_tkt (); + // ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); + #endif + + kwin_set_default_focus(hwnd); + alerted = FALSE; + + return TRUE; + + case IDD_CHANGE_PASSWORD: + if (isblocking) + return TRUE; + password_dialog(hwnd); + kwin_set_default_focus(hwnd); + + return TRUE; + + case IDM_OPTIONS: + if (isblocking) + return TRUE; + opts_dialog(hwnd); + + return TRUE; + + case IDM_HELP_INDEX: + WinHelp(hwnd, KERBEROS_HLP, HELP_INDEX, 0); + + return TRUE; + + case 1234: + ticket_init_list(GetDlgItem(hwnd, IDD_TICKET_LIST)); + + return TRUE; + + case IDM_ABOUT: + if (isblocking) + return TRUE; + + strcpy(copyright, " Kerberos for Windows\n"); + strcat(copyright, "\n Version 1.00\n\n"); + strcat(copyright, " For support, contact:\n"); + strcat(copyright, ORGANIZATION); + strcat(copyright, " - (415) 903-1400"); + MessageBox(hwnd, copyright, "Kerberos", MB_OK); + + return TRUE; + } + + return FALSE; + +} /* kwin_command */ + + +/*+ + * Function: Process WM_SYSCOMMAND messages by setting + * the focus to the password or name on restore. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - the syscommand option. + * + * lparam - + * + * Returns: 0 + */ +static LONG +kwin_syscommand ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + if ((wparam & 0xFFF0) == SC_RESTORE) + kwin_set_default_focus(hwnd); + + if ((wparam & 0xFFF0) == SC_CLOSE) { + SendMessage(hwnd, WM_COMMAND, IDM_EXIT, 0); + + return 0; + } + + return DefDlgProc(hwnd, WM_SYSCOMMAND, wparam, lparam); + +} /* kwin_syscommand */ + + +/*+ + * Function: Process WM_PAINT messages by displaying an + * informative icon when we are iconic. + * + * Parameters: + * hwnd - the window recieving the message. + * + * wparam - none + * + * lparam - none + * + * Returns: 0 + */ +static LONG +kwin_paint ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + HDC hdc; + PAINTSTRUCT ps; + HICON hicon; + time_t expiration = 0; + time_t dt; + char buf[20]; + RECT r; + #ifdef KRB4 + int i; + int ncred; + char service[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + CREDENTIALS c; + #endif + #ifdef KRB5 + krb5_error_code code; + krb5_cc_cursor cursor; + krb5_creds c; + int n; + char *service; + #endif + + if (!IsIconic(hwnd)) + return DefDlgProc(hwnd, WM_PAINT, wparam, lparam); + + #ifdef KRB4 + ncred = krb_get_num_cred(); + + for (i = 1; i <= ncred; i++) { + krb_get_nth_cred(service, instance, realm, i); + krb_get_cred(service, instance, realm, &c); + if (_stricmp(c.service, "krbtgt") == 0) { + expiration = c.issue_date - kwin_get_epoch() + (long) c.lifetime * 5L * 60L; + break; + } + } + #endif + + #ifdef KRB5 + code = krb5_cc_start_seq_get (k5_context, k5_ccache, &cursor); + + while (code == 0) { + code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); + if (code) + break; + n = krb5_princ_component(k5_context, c.server, 0)->length; + service = krb5_princ_component(k5_context, c.server, 0)->data; + if (n != KRB5_TGS_NAME_SIZE) + continue; + if (memcmp (KRB5_TGS_NAME, service, KRB5_TGS_NAME_SIZE)) + continue; + expiration = c.times.endtime; + break; + + } + krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); + #endif + + hdc = BeginPaint(hwnd, &ps); + GetClientRect(hwnd, &r); + DefWindowProc(hwnd, WM_ICONERASEBKGND, hdc, 0); + + if (expiration == 0) { + strcpy(buf, KWIN_DIALOG_NAME); + hicon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_KWIN)); + } + else { + hicon = kwin_get_icon(expiration); + dt = (expiration - time(NULL)) / 60; + + if (dt <= 0) + sprintf(buf, "%s - %s", KWIN_DIALOG_NAME, "Expired"); + else if (dt < 60) { + dt %= 60; + sprintf(buf, "%s - %ld min", KWIN_DIALOG_NAME, dt); + } + else { + dt /= 60; + sprintf(buf, "%s - %ld hr", KWIN_DIALOG_NAME, dt); + } + + if (dt > 1) + strcat(buf, "s"); + } + + DrawIcon(hdc, r.left, r.top, hicon); + EndPaint(hwnd, &ps); + SetWindowText(hwnd, buf); + + return 0; + +} /* kwin_paint */ + + +/*+ + * Function: Window proceedure for the Kerberos control panel dialog. + * + * Parameters: + * hwnd - the window receiving the message. + * + * message - the message to process. + * + * wparam - wparam of the message. + * + * lparam - lparam of the message. + * + * Returns: message dependent value. + */ +LRESULT __export CALLBACK +kwin_wnd_proc ( + HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + LRESULT rc; + int n; + + 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; + } + + switch (message) { + case WM_GETMINMAXINFO: + rc = kwin_getminmaxinfo(hwnd, wparam, lparam); + return rc; + + case WM_DESTROY: + rc = kwin_destroy(hwnd, wparam, lparam); + return rc; + + case WM_MEASUREITEM: + if (wparam == IDD_TICKET_LIST) { + rc = ticket_measureitem(hwnd, wparam, lparam); + return rc; + } + break; + + case WM_DRAWITEM: + if (wparam == IDD_TICKET_LIST) { + rc = ticket_drawitem(hwnd, wparam, lparam); + return rc; + } + break; + + case WM_SETCURSOR: + if (isblocking) { + SetCursor(LoadCursor(NULL, IDC_WAIT)); + return TRUE; + } + break; + + case WM_SIZE: + rc = kwin_size(hwnd, wparam, lparam); + return rc; + + case WM_SYSCOMMAND: + rc = kwin_syscommand(hwnd, wparam, lparam); + return rc; + + case WM_TIMER: + rc = kwin_timer(hwnd, wparam, lparam); + return 0; + + case WM_PAINT: + rc = kwin_paint(hwnd, wparam, lparam); + return rc; + + case WM_ERASEBKGND: + if (!IsIconic(hwnd)) + break; + return 0; + + case WM_KWIN_SETNAME: + kwin_init_name(hwnd, (char *) lparam); + } + + return DefDlgProc(hwnd, message, wparam, lparam); + +} /* kwin_wnd_proc */ + + +/*+ + * Function: Dialog procedure called by the dialog manager + * to process dialog specific messages. + * + * Parameters: + * hwnd - the dialog receiving the message. + * + * message - the message to process. + * + * wparam - wparam of the message. + * + * lparam - lparam of the message. + * + * Returns: TRUE if message handled locally, FALSE otherwise. + */ +static BOOL CALLBACK +kwin_dlg_proc ( + HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) +{ + LRESULT rc; + + switch (message) { + case WM_INITDIALOG: + return kwin_initdialog(hwnd, wparam, lparam); + + case WM_COMMAND: + rc = kwin_command(hwnd, wparam, lparam); + return TRUE; + } + + return FALSE; + +} /* kwin_dlg_proc */ + + +/*+ + * Function: Initialize the kwin dialog class. + * + * Parameters: + * hinstance - the instance to initialize + * + * Returns: TRUE if dialog class registration is sucessfully, false otherwise. + */ +static BOOL +kwin_init ( + HINSTANCE hinstance) +{ + WNDCLASS class; + ATOM rc; + + class.style = CS_HREDRAW | CS_VREDRAW; + class.lpfnWndProc = (WNDPROC) kwin_wnd_proc; + class.cbClsExtra = 0; + class.cbWndExtra = DLGWINDOWEXTRA; + class.hInstance = hinstance; + class.hIcon = NULL; +// LoadIcon(hinstance, MAKEINTRESOURCE(IDI_KWIN)); + class.hCursor = NULL; + class.hbrBackground = NULL; + class.lpszMenuName = NULL; + class.lpszClassName = KWIN_DIALOG_CLASS; + + rc = RegisterClass (&class); + assert(rc); + + return rc; + +} /* kwin_init */ + + +/*+ + * Function: Initialize the KWIN application. This routine should + * only be called if no previous instance of the application + * exists. Currently it only registers a class for the kwin + * dialog type. + * + * Parameters: + * hinstance - the instance to initialize + * + * Returns: TRUE if initialized sucessfully, false otherwise. + */ +static BOOL +init_application ( + HINSTANCE hinstance) +{ + BOOL rc; + + #ifdef KRB4 + wm_kerberos_changed = krb_get_notification_message(); + #endif + + #ifdef KRB5 + wm_kerberos_changed = krb5_get_notification_message(); + #endif + + rc = kwin_init(hinstance); + + return rc; + +} /* init_application */ + + +/*+ + * Function: Quits the KWIN application. This routine should + * be called when the last application instance exits. + * + * Parameters: + * hinstance - the instance which is quitting. + * + * Returns: TRUE if initialized sucessfully, false otherwise. + */ +static BOOL +quit_application ( + HINSTANCE hinstance) +{ + return TRUE; +} /* quit_application */ + + +/*+ + * Function: Initialize the current instance of the KWIN application. + * + * Parameters: + * hinstance - the instance to initialize + * + * ncmdshow - show flag to indicate wheather to come up minimized + * or not. + * + * Returns: TRUE if initialized sucessfully, false otherwise. + */ +static BOOL +init_instance ( + HINSTANCE hinstance, + int ncmdshow) +{ + WORD versionrequested; + WSADATA wsadata; + int rc; + char buf[20]; + int i; + + versionrequested = 0x0101; /* We need version 1.1 */ + rc = WSAStartup(versionrequested, &wsadata); + if (rc != 0) { + MessageBox(NULL, "Couldn't initialize Winsock library", "", MB_OK | MB_ICONSTOP); + + return FALSE; + } + + if (versionrequested != wsadata.wVersion) { + WSACleanup(); + MessageBox(NULL, "Winsock version 1.1 not available", "", MB_OK | MB_ICONSTOP); + + return FALSE; + } + + /* + * 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; + + /* + * Load clock icons + */ + for (i = IDI_FIRST_CLOCK; i <= IDI_LAST_CLOCK; i++) + kwin_icons[i - IDI_FIRST_CLOCK] = LoadIcon(hinstance, MAKEINTRESOURCE(i)); + + #ifdef KRB4 + krb_start_session(NULL); + #endif + + #ifdef KRB5 + krb5_init_context(&k5_context); + krb5_init_ets(k5_context); + krb5_cc_default(k5_context, &k5_ccache); + #endif + + return TRUE; + +} /* init_instance */ + + +/*+ + * Function: Quits the current instance of the KWIN application. + * + * Parameters: + * hinstance - the instance to quit. + * + * Returns: TRUE if termination was sucessfully, false otherwise. + */ +static BOOL +quit_instance ( + HINSTANCE hinstance) +{ + int i; + + #ifdef KRB4 + krb_end_session((char *) NULL); + #endif + + #ifdef KRB5 /* FIXME */ + krb5_cc_close (k5_context, k5_ccache); + #endif + + WSACleanup(); + + /* + * Unload clock icons + */ + for (i = IDI_FIRST_CLOCK; i <= IDI_LAST_CLOCK; i++) + DestroyIcon(kwin_icons[i - IDI_FIRST_CLOCK]); + + return TRUE; + +} /* quit_instance */ + + +/*+ + * Function: Main routine called on program invocation. + * + * Parameters: + * hinstance - the current instance + * + * hprevinstance - previous instance if one exists or NULL. + * + * cmdline - the command line string passed by Windows. + * + * ncmdshow - show flag to indicate wheather to come up minimized + * or not. + * + * Returns: TRUE if initialized sucessfully, false otherwise. + */ +int PASCAL +WinMain ( + HINSTANCE hinst, + HINSTANCE hprevinstance, + LPSTR cmdline, + int ncmdshow) +{ + DLGPROC dlgproc; + HWND hwnd; + HACCEL haccel; + MSG msg; + char *p; + char buf[MAX_K_NAME_SZ + 9]; + char name[MAX_K_NAME_SZ]; + + strcpy(buf, cmdline); + action = LOGIN_AND_RUN; + name[0] = 0; + p = strtok(buf, " ,"); + + while (p != NULL) { + if (_stricmp(p, "/exit") == 0) + action = LOGIN_AND_EXIT; + else if (_stricmp(p, "/minimize") == 0) + action = LOGIN_AND_MINIMIZE; + else + strcpy(name, p); + + p = strtok(NULL, " ,"); + } + + dlgncmdshow = ncmdshow; + hinstance = hinst; + + /* + * If a previous instance of this application exits, bring it + * to the front and exit. + */ + if (hprevinstance != NULL) { + hwnd = FindWindow(KWIN_DIALOG_CLASS, NULL); + + if (IsWindow(hwnd) && IsWindowVisible(hwnd)) { + if (GetWindowWord(hwnd, GWW_HINSTANCE) == hprevinstance) { + if (name[0]) + SendMessage(hwnd, WM_KWIN_SETNAME, 0, (LONG) name); + + ShowWindow(hwnd, ncmdshow); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, + SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); + + return FALSE; + } + } + } + + if (hprevinstance == NULL) + if (!init_application(hinstance)) + return FALSE; + + if (!init_instance(hinstance, ncmdshow)) + return FALSE; + + dlgproc = (FARPROC) MakeProcInstance(kwin_dlg_proc, hinstance); + assert(dlgproc != NULL); + + if (dlgproc == NULL) + return 1; + + hwnd = CreateDialogParam(hinstance, MAKEINTRESOURCE (ID_KWIN), + HWND_DESKTOP, dlgproc, (LONG) name); + assert(hwnd != NULL); + + if (hwnd == NULL) + return 1; + haccel = LoadAccelerators(hinstance, MAKEINTRESOURCE(IDA_KWIN)); + assert(hwnd != NULL); + + while (GetMessage(&msg, NULL, 0, 0)) { + if (!TranslateAccelerator(hwnd, haccel, &msg) && + !IsDialogMessage(hwnd, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + DestroyWindow(hwnd); + FreeProcInstance((FARPROC) dlgproc); + + return 0; + +} /* WinMain */ + + +#if 0 + + #define WM_ASYNC_COMPLETED (WM_USER + 1) + #define GETHOSTBYNAME_CLASS "krb_gethostbyname" + static HTASK htaskasync; /* Asynchronos call in progress */ + static BOOL iscompleted; /* True when async call is completed */ + + /* + * This routine is called to cancel a blocking hook call within + * the Kerberos library. The need for this routine arises due + * to bugs which exist in existing WINSOCK implementations. We + * blocking gethostbyname with WSAASyncGetHostByName. In order + * to cancel such an operation, this routine must be called. + * Applications may call this routine in addition to calls to + * WSACancelBlockingCall to get any sucy Async calls canceled. + * Return values are as they would be for WSACancelAsyncRequest. + */ + int + krb_cancel_blocking_call(void) + { + if (htaskasync == NULL) + return 0; + iscompleted = TRUE; + + return WSACancelAsyncRequest(htask); + + } /* krb_cancel_blocking_call */ + + + /* + * Window proceedure for temporary Windows created in + * krb_gethostbyname. Fields completion messages. + */ + LRESULT __export CALLBACK krb_gethostbyname_wnd_proc( + HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) + { + if (message == WM_ASYNC_COMPLETED) { + iscompleted = TRUE; + return 0; + } + + return DefWindowProc(hwnd, message, wparam, lparam); + + } /* krb_gethostbyname_wnd_proc */ + + + /* + * The WINSOCK routine gethostbyname has a bug in both FTP and NetManage + * implementations which causes the blocking hook, if any, not to be + * called. This routine attempts to work around the problem by using + * the async routines to emulate the functionality of the synchronous + * routines + */ + struct hostent FAR *PASCAL FAR + krb_gethostbyname( + const char FAR *name) + { + HWND hwnd; + char buf[MAXGETHOSTSTRUCT]; + BOOL FARPROC blockinghook; + WNDCLASS wc; + static BOOL isregistered; + + blockinghook = WSASetBlockingHook(NULL); + WSASetBlockingHook(blockinghook); + + if (blockinghook == NULL) + return gethostbyname(name); + + if (RegisterWndClass() == NULL) + return gethostbyname(name); + + if (!isregistered) { + wc.style = 0; + wc.lpfnWndProc = gethostbyname_wnd_proc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hlibinstance; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = GETHOSTBYNAME_CLASS; + + if (!RegisterClass(&wc)) + return gethostbyname(name); + + isregistered = TRUE; + } + + hwnd = CreateWindow(GETHOSTBYNAME_CLASS, "", WS_OVERLAPPED, + -100, -100, 0, 0, HWND_DESKTOP, NULL, hlibinstance, NULL); + if (hwnd == NULL) + return gethostbyname(name); + + htaskasync = + WSAAsyncGetHostByName(hwnd, WM_ASYNC_COMPLETED, name, buf, sizeof(buf)); + b = blockinghook(NULL); + + } /* krb_gethostbyname */ + +#endif + +#ifdef KRB5 + +void +debugbox () { + MessageBox (NULL, "foobar", "FOOBAR", IDOK | MB_ICONINFORMATION); +} + +/*+ + * Function: destroys all tickets in a k5 ccache + * + * Parameters: + * none + * + * Returns: K5 error code (0 == success) + */ +static krb5_error_code +k5_dest_tkt (void) { + krb5_error_code code; + krb5_principal princ; + char *defname; /* Name of cache */ + + if (code = krb5_cc_get_principal(k5_context, k5_ccache, &princ)) { + com_err (NULL, code, "while retrieving principal name"); + return code; + } + if (code = krb5_unparse_name(k5_context, princ, &defname)) { + com_err (NULL, code, "while unparsing principal name"); + return code; + } + + code = krb5_cc_initialize (k5_context, k5_ccache, princ); + if (code != 0) { + com_err (NULL, code, "when re-initializing cache"); + return code; + } + + return code; +} + +/*+ + * + * k5_get_num_cred + * + * Returns: number of creds in the credential cache + * + */ +static int +k5_get_num_cred () { + krb5_error_code code; + krb5_cc_cursor cursor; + krb5_creds c; + int ncreds = 0; + + if (code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor)) { + if (code != KRB5_FCC_NOFILE) + com_err (NULL, code, "while starting to retrieve tickets"); + return 0; + } + + while (1) { + code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); + if (code) + break; + ++ncreds; + } + + if (code == KRB5_CC_END) { /* End of ccache */ + if (code = krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor)) + com_err (NULL, code, "while finishing ticket retrieval"); + } else { + com_err (NULL, code, "while retrieving a ticket"); + return 0; + } + + return ncreds; +} + +static int +k5_get_num_cred2 () { + krb5_error_code code; + krb5_cc_cursor cursor; + krb5_creds c; + int ncreds = 0; + + code = krb5_cc_start_seq_get (k5_context, k5_ccache, &cursor); + if (code == KRB5_FCC_NOFILE) + return 0; + + while (1) { + code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); + if (code) + break; + ++ncreds; + } + krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor); + + return ncreds; +} + +/*+ + * Function: Parses fullname into name, instance and realm + * + * Parameters: + * name - buffer filled with name of user + * + * realm - buffer filled with realm of user + * + * fullname - string in form name.instance@realm + * + * Returns: 0 + */ +static int +k5_kname_parse (char *name, char *realm, char *fullname) { + char *ptr; /* For parsing */ + + ptr = strchr (fullname, '@'); /* Name, realm separator */ + + if (ptr != NULL) { /* Get the name */ + strncpy (name, fullname, ptr - fullname); + name[ptr - fullname] = '\0'; + } else + strcpy (name, fullname); + + if (ptr != NULL) /* Get realm */ + strcpy (realm, ptr + 1); + else + *realm = '\0'; + + return 0; +} +#endif /* KRB5 */ diff --git a/src/windows/cns/cns.def b/src/windows/cns/cns.def new file mode 100644 index 000000000..d0f2032c7 --- /dev/null +++ b/src/windows/cns/cns.def @@ -0,0 +1,9 @@ +NAME KWIN +DESCRIPTION 'KWIN' +EXETYPE WINDOWS +STUB 'WINSTUB.EXE' +SEGMENTS _TEXT CLASS 'CODE' PRELOAD +CODE DISCARDABLE +DATA PRELOAD MULTIPLE MOVEABLE +HEAPSIZE 20480 +STACKSIZE 20480 diff --git a/src/windows/cns/cns.h b/src/windows/cns/cns.h new file mode 100644 index 000000000..006804d12 --- /dev/null +++ b/src/windows/cns/cns.h @@ -0,0 +1,136 @@ +/* + * cns.h + * + * Public Domain -- written by Cygnus Support. + */ + +/* Only one time, please */ +#ifndef KWIN_DEFS +#define KWIN_DEFS + +/* + * Menu items + */ +#define FILE_MENU_ITEMS 3 +#define FILE_MENU_MAX_LOGINS 5 +#define IDM_KWIN 1000 + #define IDM_OPTIONS 1001 + #define IDM_EXIT 1002 + #define IDM_FIRST_LOGIN 1003 + + #define IDM_HELP_INDEX 1020 + #define IDM_ABOUT 1021 + +/* + * Accelerator + */ +#define IDA_KWIN 2000 + +/* + * Dialog and dialog item ids + */ +#define KWIN_DIALOG_CLASS "KERBEROS" /* class for kerberos dialog */ +#define KWIN_DIALOG_NAME "Kerberos" /* name for kerberos dialog */ + +#define ID_KWIN 100 /* the main kerberos dialog */ + #define IDD_KWIN_FIRST 101 + #define IDD_TICKET_LIST_TITLE 101 + #define IDD_TICKET_LIST 102 + + #define IDD_MIN_TITLE 103 + #define IDD_LOGIN_NAME_TITLE 103 + #define IDD_LOGIN_INSTANCE_TITLE 104 + #define IDD_LOGIN_REALM_TITLE 105 + #define IDD_LOGIN_PASSWORD_TITLE 106 + #define IDD_MAX_TITLE 106 + + #define IDD_MIN_EDIT 107 + #define IDD_LOGIN_NAME 107 + #define IDD_LOGIN_INSTANCE 108 + #define IDD_LOGIN_REALM 109 + #define IDD_LOGIN_PASSWORD 110 + #define IDD_MAX_EDIT 110 + + #define IDD_MIN_BUTTON 111 + #define IDD_CHANGE_PASSWORD 111 + #define IDD_TICKET_DELETE 112 + #define IDD_LOGIN 113 + #define IDD_MAX_BUTTON 113 + + #define IDD_KWIN_LAST 113 + + +#define ID_PASSWORD 200 + #define IDD_PASSWORD_NAME 204 + #define IDD_PASSWORD_INSTANCE 205 + #define IDD_PASSWORD_REALM 206 + #define IDD_OLD_PASSWORD 207 + #define IDD_NEW_PASSWORD1 208 + #define IDD_NEW_PASSWORD2 209 + #define IDD_PASSWORD_CR 210 + + +#define ID_OPTS 300 + #define IDD_CONF 301 + #define IDD_REALMS 302 + #define IDD_LIFETIME 303 + #define IDD_BEEP 304 + #define IDD_ALERT 305 + +/* + * Dialog dimensions + */ +#define KWIN_MIN_WIDTH 180 +#define KWIN_MIN_HEIGHT 110 + +/* + * Icons + */ +#define IDI_KWIN 1 /* The program icon */ + +#define ICON_WIDTH 30 /* Width used with icons */ +#define ICON_HEIGHT 20 /* Height used with icons */ + +#define IDI_FIRST_CLOCK 2 +#define IDI_0_MIN 2 /* < 5 minutes left */ +#define IDI_5_MIN 3 +#define IDI_10_MIN 4 +#define IDI_15_MIN 5 +#define IDI_20_MIN 6 +#define IDI_25_MIN 7 +#define IDI_30_MIN 8 +#define IDI_35_MIN 9 +#define IDI_40_MIN 10 +#define IDI_45_MIN 11 +#define IDI_50_MIN 12 +#define IDI_55_MIN 13 +#define IDI_60_MIN 14 +#define IDI_EXPIRED 15 +#define IDI_TICKET 16 +#define IDI_LAST_CLOCK 16 +#define MAX_ICONS (IDI_LAST_CLOCK - IDI_FIRST_CLOCK + 1) + +#ifndef RC_INVOKED + +#ifdef KRB5 + extern krb5_context k5_context; + extern krb5_ccache k5_ccache; +#endif + +/* + * Prototypes + */ + +time_t kwin_get_epoch(void); +#ifdef KRB5 + static krb5_error_code k5_dest_tkt (void); + static int k5_get_num_cred (void); + static int k5_kname_parse (char *name, char *realm, char *fullname); + static int k5_get_lrealm (char *realm); +#endif + +HICON kwin_get_icon(time_t expiration); + +#endif /* RC_INVOKED */ + +#endif diff --git a/src/windows/cns/cns.ico b/src/windows/cns/cns.ico new file mode 100644 index 0000000000000000000000000000000000000000..645efa5ba049b95732ee60341a4603a7bd1df9cb GIT binary patch literal 1086 zcmc&yv5wO~6da#XY$@VQj}Wd-lvmM)ub@P(Tp^Us?z|F(x7&gb;1{l-J0#puLQfGY zL`AmCN-=rN?%Kl930=uc=DnTq+qdgUfCLvP%M19pPJk=cvV0WyPs%T;J@Xpzf=KxB zp+df!MC7hGD`^EhRKW9(z&Ea6v-h1vB73B6r`Ctf*T+Zs@Z`6=c{QwddnBI@D(#Md zj7U!-l7JQ%J+?r5O_aPk!EX%SA;j37Hb;@&VKeSe6ierF{i|AOzC5emyZ{?JF^di}3;){qO-cQHMxnB?Bv}o}>c~Mm~Q>oyo&s-7; z!!WRq9(hZ7>rj}z#XO7Rz0uGkA6XMi$RULXTST2DJ8ziwdC_DGLYmvqIwex2rzw;q zw`UE7H8AqG!RDm2a|-?-45jtN4GDBEE*@Et7mhom_xD>>TEvDeR#UjFbKl^F^-Z%~ zUDj0`l-b*?Z|dqtJ2{b-uHc7SHB|7;B?#8_1uom=w2;&?wsB(cwvlI tt9crSIOnkB#u)NA-RIoVwFNJX0xJJx3hzlZ6IQiY|6>`9VESMG^FQ(KGx`7k literal 0 HcmV?d00001 diff --git a/src/windows/cns/cns.rc b/src/windows/cns/cns.rc new file mode 100644 index 000000000..f7d6d2c4c --- /dev/null +++ b/src/windows/cns/cns.rc @@ -0,0 +1,105 @@ +#include +#include "cns.h" + +IDI_KWIN ICON PRELOAD cns.ico +IDI_0_MIN ICON PRELOAD clock00.ico +IDI_5_MIN ICON PRELOAD clock05.ico +IDI_10_MIN ICON PRELOAD clock10.ico +IDI_15_MIN ICON PRELOAD clock15.ico +IDI_20_MIN ICON PRELOAD clock20.ico +IDI_25_MIN ICON PRELOAD clock25.ico +IDI_30_MIN ICON PRELOAD clock30.ico +IDI_35_MIN ICON PRELOAD clock35.ico +IDI_40_MIN ICON PRELOAD clock40.ico +IDI_45_MIN ICON PRELOAD clock45.ico +IDI_50_MIN ICON PRELOAD clock50.ico +IDI_55_MIN ICON PRELOAD clock55.ico +IDI_60_MIN ICON PRELOAD clock60.ico +IDI_EXPIRED ICON PRELOAD clockexp.ico +IDI_TICKET ICON PRELOAD clocktkt.ico + +IDM_KWIN MENU PRELOAD +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Options...", IDM_OPTIONS + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_EXIT + END + + POPUP "&Help" + BEGIN + MENUITEM "&Index\tF1", IDM_HELP_INDEX + MENUITEM "&Debug", 1234 + MENUITEM SEPARATOR + MENUITEM "&About Kerberos...", IDM_ABOUT + END +END + +IDA_KWIN ACCELERATORS PRELOAD +BEGIN + VK_F1, IDM_HELP_INDEX, VIRTKEY +END + +ID_KWIN DIALOG PRELOAD MOVEABLE DISCARDABLE 0, 0, 276, 114 +STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX +CLASS KWIN_DIALOG_CLASS +CAPTION KWIN_DIALOG_NAME +MENU IDM_KWIN +FONT 8, "Arial" +BEGIN + CONTROL " Start Time End Time Ticket", IDD_TICKET_LIST_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 16, 7, 240, 8 + CONTROL "", IDD_TICKET_LIST, "LISTBOX", LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 8, 18, 261, 52 + CONTROL "&Name", IDD_LOGIN_NAME_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 69, 27, 8 + CONTROL "&Instance", IDD_LOGIN_INSTANCE_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 73, 69, 36, 8 + CONTROL "&Realm", IDD_LOGIN_REALM_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 140, 69, 26, 8 + CONTROL "&Password", IDD_LOGIN_PASSWORD_TITLE, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 207, 69, 36, 8 + CONTROL "", IDD_LOGIN_NAME, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 6, 79, 62, 12 + CONTROL "", IDD_LOGIN_INSTANCE, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 73, 79, 62, 12 + CONTROL "", IDD_LOGIN_REALM, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_UPPERCASE | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 140, 79, 62, 12 + CONTROL "", IDD_LOGIN_PASSWORD, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 207, 79, 62, 12 + CONTROL "&Change Password...", IDD_CHANGE_PASSWORD, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 6, 96, 74, 14 + CONTROL "&Delete", IDD_TICKET_DELETE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 122, 96, 52, 14 + CONTROL "&Login", IDD_LOGIN, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 216, 96, 52, 14 +END + +ID_PASSWORD DIALOG 96, 50, 143, 129 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Change Password" +FONT 8, "Arial" +BEGIN + CONTROL "&Name:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 9, 53, 8 + CONTROL "", IDD_PASSWORD_NAME, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_GROUP | WS_TABSTOP, 61, 6, 76, 12 + CONTROL "&Instance:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 26, 53, 8 + CONTROL "", IDD_PASSWORD_INSTANCE, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 23, 76, 12 + CONTROL "&Realm:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 43, 53, 8 + CONTROL "", IDD_PASSWORD_REALM, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 40, 76, 12 + CONTROL "&Old Password:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 60, 53, 8 + CONTROL "", IDD_OLD_PASSWORD, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 57, 76, 12 + CONTROL "&New Password:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 77, 53, 8 + CONTROL "", IDD_NEW_PASSWORD1, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 74, 76, 12 + CONTROL "&New Password:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 94, 53, 8 + CONTROL "", IDD_NEW_PASSWORD2, "EDIT", ES_LEFT | ES_AUTOHSCROLL | ES_PASSWORD | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 61, 91, 76, 12 + CONTROL "", IDD_PASSWORD_CR, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 5000, 5000, 0, 0 + CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 13, 110, 52, 14 + CONTROL "Cancel", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 77, 110, 52, 14 +END + +ID_OPTS DIALOG 97, 52, 148, 107 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Kerberos Options" +FONT 8, "Arial" +BEGIN + CONTROL "&conf file:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 9, 40, 8 + CONTROL "", IDD_CONF, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 6, 82, 12 + CONTROL "&realms file:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 26, 40, 8 + CONTROL "", IDD_REALMS, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 23, 82, 12 + CONTROL "&Ticket lifetime:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 43, 53, 8 + CONTROL "", IDD_LIFETIME, "EDIT", ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 40, 20, 12 + CONTROL "minutes", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 85, 43, 46, 8 + CONTROL "Action when login expires", 209, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP, 5, 56, 138, 23 + CONTROL "&Alert ", IDD_ALERT, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 31, 65, 28, 12 + CONTROL "&Beep", IDD_BEEP, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 80, 65, 39, 12 + CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 17, 87, 52, 14 + CONTROL "Cancel", IDCANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 81, 87, 52, 14 +END diff --git a/src/windows/cns/krbini.h b/src/windows/cns/krbini.h new file mode 100644 index 000000000..da5aa88b4 --- /dev/null +++ b/src/windows/cns/krbini.h @@ -0,0 +1,23 @@ +/* Kerberos changed window message */ +#define WM_KERBEROS_CHANGED "Kerberos Changed" + +/* Kerberos Windows initialization file */ +#define KERBEROS_INI "kerberos.ini" +#define KERBEROS_HLP "kerberos.hlp" +#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" +#define INI_KRB_CONF "krb.conf" /* Location of krb.conf file */ +#define DEF_KRB_CONF "krb.con" /* Default name for krb.conf file */ +#define INI_KRB_REALMS "krb.realms" /* Location of krb.realms file */ +#define DEF_KRB_REALMS "krb.rea" /* Default name for krb.realms file */ +#define INI_RECENT_LOGINS "Recent Logins" +#define INI_LOGIN "Login" diff --git a/src/windows/cns/makefile b/src/windows/cns/makefile new file mode 100644 index 000000000..8dc8e5436 --- /dev/null +++ b/src/windows/cns/makefile @@ -0,0 +1,79 @@ +# makefile: Constructs the Kerberos for Windows ticket manager +# Works for both k4 and k5 releases. +# +NAME = cns +OBJS = cns.obj tktlist.obj + +##### Options +DEBUG = 1 +!IF ! defined(KVERSION) +KVERSION = 5 +!endif +KRB = KRB$(KVERSION) + +!if $(KVERSION) == 4 +BUILDTOP = .. +LIBDIR = $(BUILDTOP)\lib\krb +KLIB = $(LIBDIR)\kerberos.lib +WLIB = $(LIBDIR)\winsock.lib +INCLUDES = /I$(BUILDTOP)\include +!endif + +!if $(KVERSION) == 5 +BUILDTOP =..\.. +LIBDIR = $(BUILDTOP)\lib +KLIB = $(LIBDIR)\libkrb5.lib +WLIB = $(LIBDIR)\winsock.lib +INCLUDES = /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 + +RM = $(BUILDTOP)\config\rm.bat +WHAT = windows +OBJEXT = obj +!endif + +##### C Compiler +CC = cl +CFLAGS_RELEASE = /f- /nologo /W3 /AL /Gw /Gy /Zp /O2 /DNDEBUG=1 +CFLAGS_DEBUG = /f /nologo /W3 /AL /Gw /Gy /Zp /O2 /Od /Zi +!if $(DEBUG) +CFLAGS = $(CFLAGS_DEBUG) $(INCLUDES) /D$(KRB)=1 +!else +CFLAGS = $(CFLAGS_RELEASE) $(INCLUDES) /D$(KRB)=1 +!endif + +##### RC Compiler +RC = rc +RFLAGS = /nologo $(INCLUDES) + +##### Linker +LINK = link +LIBS = $(KLIB) $(WLIB) +SYSLIBS = libw llibcew +!if $(DEBUG) +LFLAGS = /co /nologo /nod /nopackcode /map:full +!else +LFLAGS = /nologo /nod /nopackcode +!endif + +all:: makefile $(NAME).exe + +$(NAME).exe: $*.def $*.res $(OBJS) $(LIBS) + $(LINK) $(LFLAGS) $(OBJS), $@, $*.map, $(LIBS) $(SYSLIBS), $*.def + $(RC) $(RFLAGS) /k $*.res $@ + +$(OBJS) cns.res: cns.h tktlist.h + +install: + copy cns.exe ..\floppy + +clean:: tidy + if exist *.exe del *.exe + if exist ..\floppy\cns.exe del ..\floppy\cns.exe + +tidy:: + if exist *.obj del *.obj + if exist *.res del *.res + if exist *.map del *.map + if exist *.pdb del *.pdb + if exist *.err del *.err + diff --git a/src/windows/cns/tktlist.c b/src/windows/cns/tktlist.c new file mode 100644 index 000000000..8eb94a52f --- /dev/null +++ b/src/windows/cns/tktlist.c @@ -0,0 +1,427 @@ +/* + * tktlist.c + * + * Handle all actions of the Kerberos ticket list. + * + * Copyright 1994 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + */ + +#if !defined(KRB5) && !defined(KRB4) + #define KRB5 1 +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef KRB4 + #include "mit-copyright.h" + #include "kerberos.h" +#endif + +#ifdef KRB5 + #define NEED_SOCKETS + #include "krb5.h" + #include "krbini.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) + #define ORGANIZATION "Cygnus Support" +#endif + +#include "cns.h" +#include "tktlist.h" + +/* + * Ticket information for a list line + */ +typedef struct { + BOOL ticket; /* TRUE if this is a real ticket */ + time_t issue_time; /* time_t of issue */ + long lifetime; /* Lifetime for ticket in 5 minute intervals */ + char buf[0]; /* String to display */ +} TICKETINFO, *LPTICKETINFO; + +/*+ + * Function: Returns a standard ctime date with day of week and year + * removed. + * + * Parameters: + * t - time_t date to convert + * + * Returns: A pointer to the adjusted time value. + */ +static char * +short_date (long t) { + static char buf[26 - 4]; + char *p; + + p = ctime(&t); + assert(p != NULL); + + strcpy (buf, p + 4); + buf[12] = '\0'; + + return buf; + +} /* short_date */ + + +/*++ + * Function: Initializes and populates the ticket list with all existing + * Kerberos tickets. + * + * Parameters: + * hwnd - the window handle of the ticket window. + * + * Returns: Number of elements in the list or -1 on error + */ +int +ticket_init_list ( + HWND hwnd) +{ + int ncred; + LRESULT rc; + int l; + LPTICKETINFO lpinfo; + char buf[26+2 + 26+2 + ANAME_SZ+1 + INST_SZ+1 + REALM_SZ + 22]; + #ifdef KRB4 + int i; + time_t expiration; + char service[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; + CREDENTIALS c; + #endif + #ifdef KRB5 + krb5_cc_cursor cursor; + krb5_error_code code; + krb5_creds c; + krb5_flags flags; + char *sname; /* Name of the service */ + #endif + + SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + + rc = SendMessage(hwnd, LB_GETCOUNT, 0, 0); + assert(rc != LB_ERR); + + if (rc > 0) + ticket_destroy(hwnd); + + while (--rc >= 0) + SendMessage(hwnd, LB_DELETESTRING, (WPARAM) rc, 0); + + #ifdef KRB4 + + ncred = krb_get_num_cred(); + for (i = 1; i <= ncred; i++) { + 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())); + expiration = c.issue_date - kwin_get_epoch() + (long) c.lifetime * 5L * 60L; + strcat(buf, " "); + strcat(buf, short_date(expiration)); + l = strlen(buf); + sprintf(&buf[l], " %s%s%s%s%s (%d)", + c.service, (c.instance[0] ? "." : ""), c.instance, + (c.realm[0] ? "@" : ""), c.realm, c.kvno); + l = strlen(buf); + + lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + l + 1); + assert(lpinfo != NULL); + + if (lpinfo == NULL) + return -1; + + lpinfo->ticket = TRUE; + lpinfo->issue_time = c.issue_date - kwin_get_epoch(); /* back to system time */ + lpinfo->lifetime = (long) c.lifetime * 5L * 60L; + strcpy(lpinfo->buf, buf); + + rc = SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM) lpinfo); + assert(rc >= 0); + + if (rc < 0) + return -1; + } + + #endif + + #ifdef KRB5 + + ncred = 0; + flags = 0; + if (code = krb5_cc_set_flags(k5_context, k5_ccache, flags)) { + if (code != KRB5_FCC_NOFILE) { + com_err (NULL, code, + "while setting cache flags (ticket cache %s)", + krb5_cc_get_name(k5_context, k5_ccache)); + return -1; + } + } else { + if (code = krb5_cc_start_seq_get(k5_context, k5_ccache, &cursor)) { + com_err (NULL, code, "while starting to retrieve tickets"); + return -1; + } + + while (1) { + code = krb5_cc_next_cred(k5_context, k5_ccache, &cursor, &c); + if (code != 0) + break; + + 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, " "); + + code = krb5_unparse_name (k5_context, c.server, &sname); + if (code) { + com_err (NULL, code, "while unparsing server name"); + break; + } + strcat (buf, sname); + free (sname); + + l = strlen(buf); + lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + l + 1); + assert(lpinfo != NULL); + + if (lpinfo == NULL) + return -1; + + lpinfo->ticket = TRUE; + lpinfo->issue_time = c.times.starttime - kwin_get_epoch(); + lpinfo->lifetime = c.times.endtime - c.times.starttime; + strcpy(lpinfo->buf, buf); + + rc = SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM) lpinfo); + assert(rc >= 0); + + if (rc < 0) + return -1; + } + + if (code == KRB5_CC_END) { /* End of ccache */ + if (code = krb5_cc_end_seq_get(k5_context, k5_ccache, &cursor)) { + com_err(NULL, code, "while finishing ticket retrieval"); + return -1; + } + flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */ + if (code = krb5_cc_set_flags(k5_context, k5_ccache, flags)) { + com_err(NULL, code, "while closing ccache"); + return -1; + } + } else { + com_err(NULL, code, "while retrieving a ticket"); + return -1; + } + } + #endif + + if (ncred <= 0) { + strcpy(buf, " No Tickets"); + lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + strlen(buf) + 1); + assert(lpinfo != NULL); + + if (lpinfo == NULL) + return -1; + + lpinfo->ticket = FALSE; + strcpy (lpinfo->buf, buf); + rc = SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM) lpinfo); + assert(rc >= 0); + } + + SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); + + return ncred; + +} /* ticket_init_list */ + + +/*+ + * Function: Destroy the ticket list. Make sure to delete all + * ticket entries created during ticket initialization. + * + * Parameters: + * hwnd - the window handle of the ticket window. + */ +void +ticket_destroy ( + HWND hwnd) +{ + int i; + int n; + LRESULT rc; + + n = (int) SendMessage(hwnd, LB_GETCOUNT, 0, 0); + + for (i = 0; i < n; i++) { + rc = SendMessage(hwnd, LB_GETITEMDATA, i, 0); + assert(rc != LB_ERR); + + if (rc != LB_ERR) + free ((void *) rc); + } + +} /* ticket_destroy */ + + +/*+ + * Function: Respond to the WM_MEASUREITEM message for the ticket list + * by setting each list item up at 1/4" hight. + * + * Parameters: + * hwnd - the window handle of the ticket window. + * + * wparam - control id of the ticket list. + * + * lparam - pointer to the MEASUREITEMSTRUCT. + * + * Returns: TRUE if message process, FALSE otherwise. + */ +LONG +ticket_measureitem ( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + int logpixelsy; + LPMEASUREITEMSTRUCT lpmi; + HDC hdc; + + lpmi = (LPMEASUREITEMSTRUCT) lparam; + hdc = GetDC(HWND_DESKTOP); + logpixelsy = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(HWND_DESKTOP, hdc); + lpmi->itemHeight = logpixelsy / 4; /* 1/4 inch */ + + return TRUE; + +} /* ticket_measureitem */ + + +/*+ + * Function: Respond to the WM_DRAWITEM message for the ticket list + * by displaying a single list item. + * + * Parameters: + * hwnd - the window handle of the ticket window. + * + * wparam - control id of the ticket list. + * + * lparam - pointer to the DRAWITEMSTRUCT. + * + * Returns: TRUE if message process, FALSE otherwise. + */ +LONG ticket_drawitem( + HWND hwnd, + WPARAM wparam, + LPARAM lparam) +{ + LPDRAWITEMSTRUCT lpdi; + BOOL rc; + COLORREF bkcolor; + HBRUSH hbrush; + UINT textheight; + UINT alignment; + int left, top; + BOOL b; + LPTICKETINFO lpinfo; + HICON hicon; + #if 0 + COLORREF textcolor; + COLORREF orgbkcolor; + COLORREF orgtextcolor; + #endif + + lpdi = (LPDRAWITEMSTRUCT) lparam; + lpinfo = (LPTICKETINFO) lpdi->itemData; + + if (lpdi->itemAction == ODA_FOCUS) + return TRUE; + + #if 0 + if (lpdi->itemState & ODS_SELECTED) { + textcolor = GetSysColor(COLOR_HIGHLIGHTTEXT); + bkcolor = GetSysColor(COLOR_HIGHLIGHT); + + orgtextcolor = SetTextColor(lpdi->hDC, textcolor); + assert(textcolor != 0x80000000); + + orgbkcolor = SetBkColor(lpdi->hDC, bkcolor); + assert(bkcolor != 0x80000000); + } + else + #endif + + bkcolor = GetBkColor(lpdi->hDC); + hbrush = CreateSolidBrush(bkcolor); + assert(hbrush != NULL); + + FillRect(lpdi->hDC, &(lpdi->rcItem), hbrush); + DeleteObject(hbrush); + + /* + * Display the appropriate icon + */ + if (lpinfo->ticket) { + hicon = kwin_get_icon(lpinfo->issue_time + lpinfo->lifetime); + left = lpdi->rcItem.left - (32 - ICON_WIDTH) / 2; + top = lpdi->rcItem.top; + top += (lpdi->rcItem.bottom - lpdi->rcItem.top - 32) / 2; + + b = DrawIcon(lpdi->hDC, left, top, hicon); + assert(b); + } + + /* + * Display centered string + */ + textheight = HIWORD(GetTextExtent(lpdi->hDC, "X", 1)); + alignment = SetTextAlign(lpdi->hDC, TA_TOP | TA_LEFT); + + if (lpinfo->ticket) + left = lpdi->rcItem.left + ICON_WIDTH; + else + left = lpdi->rcItem.left; + + top = lpdi->rcItem.top; + top += (lpdi->rcItem.bottom - lpdi->rcItem.top - textheight) / 2; + rc = TextOut(lpdi->hDC, left, top, (LPSTR) lpinfo->buf, + strlen((LPSTR) lpinfo->buf)); + assert(rc); + + alignment = SetTextAlign(lpdi->hDC, alignment); + + #if 0 + if (lpdi->itemState & ODS_SELECTED) { + textcolor = SetTextColor(lpdi->hDC, orgtextcolor); + assert(textcolor != 0x80000000); + + bkcolor = SetBkColor(lpdi->hDC, orgbkcolor); + assert(bkcolor != 0x80000000); + } + + #endif + + return TRUE; + +} /* ticket_drawitem */ diff --git a/src/windows/cns/tktlist.h b/src/windows/cns/tktlist.h new file mode 100644 index 000000000..1ebd146a7 --- /dev/null +++ b/src/windows/cns/tktlist.h @@ -0,0 +1,35 @@ +/* + * tktlist.h + * + * Handle all actions of the Kerberos ticket list. + * + * Copyright 1994 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + */ + +/* Only one time, please */ +#ifndef TKTLIST_DEFS +#define TKTLIST_DEFS + +/* + * Prototypes + */ +BOOL ticket_init_list( + HWND hwnd); + +void ticket_destroy( + HWND hwnd); + +LONG ticket_measureitem( + HWND hwnd, + WPARAM wparam, + LPARAM lparam); + +LONG ticket_drawitem( + HWND hwnd, + WPARAM wparam, + LPARAM lparam); + +#endif -- 2.26.2