1*7f2fe78bSCy Schubert // Module name: krb5routines.c
2*7f2fe78bSCy Schubert
3*7f2fe78bSCy Schubert #include <windows.h>
4*7f2fe78bSCy Schubert #define SECURITY_WIN32
5*7f2fe78bSCy Schubert #include <security.h>
6*7f2fe78bSCy Schubert
7*7f2fe78bSCy Schubert /* _WIN32_WINNT must be 0x0501 or greater to pull in definition of
8*7f2fe78bSCy Schubert * all required LSA data types when the Vista SDK NtSecAPI.h is used.
9*7f2fe78bSCy Schubert */
10*7f2fe78bSCy Schubert #ifndef _WIN32_WINNT
11*7f2fe78bSCy Schubert #define _WIN32_WINNT 0x0501
12*7f2fe78bSCy Schubert #else
13*7f2fe78bSCy Schubert #if _WIN32_WINNT < 0x0501
14*7f2fe78bSCy Schubert #undef _WIN32_WINNT
15*7f2fe78bSCy Schubert #define _WIN32_WINNT 0x0501
16*7f2fe78bSCy Schubert #endif
17*7f2fe78bSCy Schubert #endif
18*7f2fe78bSCy Schubert #include <ntsecapi.h>
19*7f2fe78bSCy Schubert #include <stdio.h>
20*7f2fe78bSCy Schubert #include <string.h>
21*7f2fe78bSCy Schubert #include <time.h>
22*7f2fe78bSCy Schubert #include <assert.h>
23*7f2fe78bSCy Schubert
24*7f2fe78bSCy Schubert #include <winsock2.h>
25*7f2fe78bSCy Schubert
26*7f2fe78bSCy Schubert /* Private Include files */
27*7f2fe78bSCy Schubert #include "leashdll.h"
28*7f2fe78bSCy Schubert #include <leashwin.h>
29*7f2fe78bSCy Schubert #include "leash-int.h"
30*7f2fe78bSCy Schubert
31*7f2fe78bSCy Schubert #define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
32*7f2fe78bSCy Schubert
GetTicketFlag(krb5_creds * cred)33*7f2fe78bSCy Schubert char *GetTicketFlag(krb5_creds *cred)
34*7f2fe78bSCy Schubert {
35*7f2fe78bSCy Schubert static char buf[32];
36*7f2fe78bSCy Schubert int i = 0;
37*7f2fe78bSCy Schubert
38*7f2fe78bSCy Schubert buf[i++] = ' ';
39*7f2fe78bSCy Schubert buf[i++] = '(';
40*7f2fe78bSCy Schubert
41*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_FORWARDABLE)
42*7f2fe78bSCy Schubert buf[i++] = 'F';
43*7f2fe78bSCy Schubert
44*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_FORWARDED)
45*7f2fe78bSCy Schubert buf[i++] = 'f';
46*7f2fe78bSCy Schubert
47*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_PROXIABLE)
48*7f2fe78bSCy Schubert buf[i++] = 'P';
49*7f2fe78bSCy Schubert
50*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_PROXY)
51*7f2fe78bSCy Schubert buf[i++] = 'p';
52*7f2fe78bSCy Schubert
53*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE)
54*7f2fe78bSCy Schubert buf[i++] = 'D';
55*7f2fe78bSCy Schubert
56*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_POSTDATED)
57*7f2fe78bSCy Schubert buf[i++] = 'd';
58*7f2fe78bSCy Schubert
59*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_INVALID)
60*7f2fe78bSCy Schubert buf[i++] = 'i';
61*7f2fe78bSCy Schubert
62*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_RENEWABLE)
63*7f2fe78bSCy Schubert buf[i++] = 'R';
64*7f2fe78bSCy Schubert
65*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_INITIAL)
66*7f2fe78bSCy Schubert buf[i++] = 'I';
67*7f2fe78bSCy Schubert
68*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_HW_AUTH)
69*7f2fe78bSCy Schubert buf[i++] = 'H';
70*7f2fe78bSCy Schubert
71*7f2fe78bSCy Schubert if (cred->ticket_flags & TKT_FLG_PRE_AUTH)
72*7f2fe78bSCy Schubert buf[i++] = 'A';
73*7f2fe78bSCy Schubert
74*7f2fe78bSCy Schubert buf[i++] = ')';
75*7f2fe78bSCy Schubert buf[i] = '\0';
76*7f2fe78bSCy Schubert
77*7f2fe78bSCy Schubert if (i <= 3)
78*7f2fe78bSCy Schubert buf[0] = '\0';
79*7f2fe78bSCy Schubert
80*7f2fe78bSCy Schubert return buf;
81*7f2fe78bSCy Schubert }
82*7f2fe78bSCy Schubert
83*7f2fe78bSCy Schubert int
LeashKRB5_renew(void)84*7f2fe78bSCy Schubert LeashKRB5_renew(void)
85*7f2fe78bSCy Schubert {
86*7f2fe78bSCy Schubert krb5_error_code code = 0;
87*7f2fe78bSCy Schubert krb5_context ctx = 0;
88*7f2fe78bSCy Schubert krb5_ccache cc = 0;
89*7f2fe78bSCy Schubert krb5_principal me = 0;
90*7f2fe78bSCy Schubert krb5_principal server = 0;
91*7f2fe78bSCy Schubert krb5_creds my_creds;
92*7f2fe78bSCy Schubert krb5_data *realm = 0;
93*7f2fe78bSCy Schubert
94*7f2fe78bSCy Schubert if ( !pkrb5_init_context )
95*7f2fe78bSCy Schubert goto cleanup;
96*7f2fe78bSCy Schubert
97*7f2fe78bSCy Schubert memset(&my_creds, 0, sizeof(krb5_creds));
98*7f2fe78bSCy Schubert
99*7f2fe78bSCy Schubert code = pkrb5_init_context(&ctx);
100*7f2fe78bSCy Schubert if (code) goto cleanup;
101*7f2fe78bSCy Schubert
102*7f2fe78bSCy Schubert code = pkrb5_cc_default(ctx, &cc);
103*7f2fe78bSCy Schubert if (code) goto cleanup;
104*7f2fe78bSCy Schubert
105*7f2fe78bSCy Schubert code = pkrb5_cc_get_principal(ctx, cc, &me);
106*7f2fe78bSCy Schubert if (code) goto cleanup;
107*7f2fe78bSCy Schubert
108*7f2fe78bSCy Schubert realm = krb5_princ_realm(ctx, me);
109*7f2fe78bSCy Schubert
110*7f2fe78bSCy Schubert code = pkrb5_build_principal_ext(ctx, &server,
111*7f2fe78bSCy Schubert realm->length,realm->data,
112*7f2fe78bSCy Schubert KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
113*7f2fe78bSCy Schubert realm->length,realm->data,
114*7f2fe78bSCy Schubert 0);
115*7f2fe78bSCy Schubert if ( code ) goto cleanup;
116*7f2fe78bSCy Schubert
117*7f2fe78bSCy Schubert my_creds.client = me;
118*7f2fe78bSCy Schubert my_creds.server = server;
119*7f2fe78bSCy Schubert
120*7f2fe78bSCy Schubert pkrb5_cc_set_flags(ctx, cc, 0);
121*7f2fe78bSCy Schubert code = pkrb5_get_renewed_creds(ctx, &my_creds, me, cc, NULL);
122*7f2fe78bSCy Schubert pkrb5_cc_set_flags(ctx, cc, KRB5_TC_NOTICKET);
123*7f2fe78bSCy Schubert if (code) {
124*7f2fe78bSCy Schubert if (code != KRB5KDC_ERR_ETYPE_NOSUPP && code != KRB5_KDC_UNREACH &&
125*7f2fe78bSCy Schubert code != KRB5_CC_NOTFOUND)
126*7f2fe78bSCy Schubert Leash_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx, &cc);
127*7f2fe78bSCy Schubert goto cleanup;
128*7f2fe78bSCy Schubert }
129*7f2fe78bSCy Schubert
130*7f2fe78bSCy Schubert code = pkrb5_cc_initialize(ctx, cc, me);
131*7f2fe78bSCy Schubert if (code) goto cleanup;
132*7f2fe78bSCy Schubert
133*7f2fe78bSCy Schubert code = pkrb5_cc_store_cred(ctx, cc, &my_creds);
134*7f2fe78bSCy Schubert if (code) goto cleanup;
135*7f2fe78bSCy Schubert
136*7f2fe78bSCy Schubert cleanup:
137*7f2fe78bSCy Schubert if (my_creds.client == me)
138*7f2fe78bSCy Schubert my_creds.client = 0;
139*7f2fe78bSCy Schubert if (my_creds.server == server)
140*7f2fe78bSCy Schubert my_creds.server = 0;
141*7f2fe78bSCy Schubert pkrb5_free_cred_contents(ctx, &my_creds);
142*7f2fe78bSCy Schubert if (me)
143*7f2fe78bSCy Schubert pkrb5_free_principal(ctx, me);
144*7f2fe78bSCy Schubert if (server)
145*7f2fe78bSCy Schubert pkrb5_free_principal(ctx, server);
146*7f2fe78bSCy Schubert if (cc)
147*7f2fe78bSCy Schubert pkrb5_cc_close(ctx, cc);
148*7f2fe78bSCy Schubert if (ctx)
149*7f2fe78bSCy Schubert pkrb5_free_context(ctx);
150*7f2fe78bSCy Schubert return(code);
151*7f2fe78bSCy Schubert }
152*7f2fe78bSCy Schubert
153*7f2fe78bSCy Schubert static krb5_error_code KRB5_CALLCONV
154*7f2fe78bSCy Schubert leash_krb5_prompter( krb5_context context,
155*7f2fe78bSCy Schubert void *data,
156*7f2fe78bSCy Schubert const char *name,
157*7f2fe78bSCy Schubert const char *banner,
158*7f2fe78bSCy Schubert int num_prompts,
159*7f2fe78bSCy Schubert krb5_prompt prompts[]);
160*7f2fe78bSCy Schubert
161*7f2fe78bSCy Schubert int
Leash_krb5_kinit(krb5_context alt_ctx,HWND hParent,char * principal_name,char * password,krb5_deltat lifetime,DWORD forwardable,DWORD proxiable,krb5_deltat renew_life,DWORD addressless,DWORD publicIP)162*7f2fe78bSCy Schubert Leash_krb5_kinit(
163*7f2fe78bSCy Schubert krb5_context alt_ctx,
164*7f2fe78bSCy Schubert HWND hParent,
165*7f2fe78bSCy Schubert char *principal_name,
166*7f2fe78bSCy Schubert char *password,
167*7f2fe78bSCy Schubert krb5_deltat lifetime,
168*7f2fe78bSCy Schubert DWORD forwardable,
169*7f2fe78bSCy Schubert DWORD proxiable,
170*7f2fe78bSCy Schubert krb5_deltat renew_life,
171*7f2fe78bSCy Schubert DWORD addressless,
172*7f2fe78bSCy Schubert DWORD publicIP
173*7f2fe78bSCy Schubert )
174*7f2fe78bSCy Schubert {
175*7f2fe78bSCy Schubert krb5_error_code code = 0;
176*7f2fe78bSCy Schubert krb5_context ctx = 0;
177*7f2fe78bSCy Schubert krb5_ccache cc = 0, defcache = 0;
178*7f2fe78bSCy Schubert krb5_principal me = 0;
179*7f2fe78bSCy Schubert char* name = 0;
180*7f2fe78bSCy Schubert krb5_creds my_creds;
181*7f2fe78bSCy Schubert krb5_get_init_creds_opt * options = NULL;
182*7f2fe78bSCy Schubert krb5_address ** addrs = NULL;
183*7f2fe78bSCy Schubert int i = 0, addr_count = 0;
184*7f2fe78bSCy Schubert int cc_new = 0;
185*7f2fe78bSCy Schubert const char * deftype = NULL;
186*7f2fe78bSCy Schubert
187*7f2fe78bSCy Schubert if (!pkrb5_init_context)
188*7f2fe78bSCy Schubert return 0;
189*7f2fe78bSCy Schubert
190*7f2fe78bSCy Schubert memset(&my_creds, 0, sizeof(my_creds));
191*7f2fe78bSCy Schubert
192*7f2fe78bSCy Schubert if (alt_ctx)
193*7f2fe78bSCy Schubert {
194*7f2fe78bSCy Schubert ctx = alt_ctx;
195*7f2fe78bSCy Schubert }
196*7f2fe78bSCy Schubert else
197*7f2fe78bSCy Schubert {
198*7f2fe78bSCy Schubert code = pkrb5_init_context(&ctx);
199*7f2fe78bSCy Schubert if (code) goto cleanup;
200*7f2fe78bSCy Schubert }
201*7f2fe78bSCy Schubert
202*7f2fe78bSCy Schubert code = pkrb5_get_init_creds_opt_alloc(ctx, &options);
203*7f2fe78bSCy Schubert if (code) goto cleanup;
204*7f2fe78bSCy Schubert
205*7f2fe78bSCy Schubert code = pkrb5_cc_default(ctx, &defcache);
206*7f2fe78bSCy Schubert if (code) goto cleanup;
207*7f2fe78bSCy Schubert
208*7f2fe78bSCy Schubert code = pkrb5_parse_name(ctx, principal_name, &me);
209*7f2fe78bSCy Schubert if (code) goto cleanup;
210*7f2fe78bSCy Schubert
211*7f2fe78bSCy Schubert deftype = pkrb5_cc_get_type(ctx, defcache);
212*7f2fe78bSCy Schubert if (me != NULL && pkrb5_cc_support_switch(ctx, deftype)) {
213*7f2fe78bSCy Schubert /* Use an existing cache for the specified principal if we can. */
214*7f2fe78bSCy Schubert code = pkrb5_cc_cache_match(ctx, me, &cc);
215*7f2fe78bSCy Schubert if (code != 0 && code != KRB5_CC_NOTFOUND)
216*7f2fe78bSCy Schubert goto cleanup;
217*7f2fe78bSCy Schubert if (code == KRB5_CC_NOTFOUND) {
218*7f2fe78bSCy Schubert code = pkrb5_cc_new_unique(ctx, deftype, NULL, &cc);
219*7f2fe78bSCy Schubert if (code)
220*7f2fe78bSCy Schubert goto cleanup;
221*7f2fe78bSCy Schubert cc_new = 1;
222*7f2fe78bSCy Schubert }
223*7f2fe78bSCy Schubert pkrb5_cc_close(ctx, defcache);
224*7f2fe78bSCy Schubert } else {
225*7f2fe78bSCy Schubert cc = defcache;
226*7f2fe78bSCy Schubert }
227*7f2fe78bSCy Schubert
228*7f2fe78bSCy Schubert code = pkrb5_unparse_name(ctx, me, &name);
229*7f2fe78bSCy Schubert if (code) goto cleanup;
230*7f2fe78bSCy Schubert
231*7f2fe78bSCy Schubert if (lifetime == 0)
232*7f2fe78bSCy Schubert lifetime = Leash_get_default_lifetime();
233*7f2fe78bSCy Schubert else
234*7f2fe78bSCy Schubert lifetime *= 5*60;
235*7f2fe78bSCy Schubert
236*7f2fe78bSCy Schubert if (renew_life > 0)
237*7f2fe78bSCy Schubert renew_life *= 5*60;
238*7f2fe78bSCy Schubert
239*7f2fe78bSCy Schubert if (lifetime)
240*7f2fe78bSCy Schubert pkrb5_get_init_creds_opt_set_tkt_life(options, lifetime);
241*7f2fe78bSCy Schubert pkrb5_get_init_creds_opt_set_forwardable(options,
242*7f2fe78bSCy Schubert forwardable ? 1 : 0);
243*7f2fe78bSCy Schubert pkrb5_get_init_creds_opt_set_proxiable(options,
244*7f2fe78bSCy Schubert proxiable ? 1 : 0);
245*7f2fe78bSCy Schubert pkrb5_get_init_creds_opt_set_renew_life(options,
246*7f2fe78bSCy Schubert renew_life);
247*7f2fe78bSCy Schubert if (addressless)
248*7f2fe78bSCy Schubert pkrb5_get_init_creds_opt_set_address_list(options,NULL);
249*7f2fe78bSCy Schubert else {
250*7f2fe78bSCy Schubert if (publicIP)
251*7f2fe78bSCy Schubert {
252*7f2fe78bSCy Schubert // we are going to add the public IP address specified by the user
253*7f2fe78bSCy Schubert // to the list provided by the operating system
254*7f2fe78bSCy Schubert krb5_address ** local_addrs=NULL;
255*7f2fe78bSCy Schubert DWORD netIPAddr;
256*7f2fe78bSCy Schubert
257*7f2fe78bSCy Schubert pkrb5_os_localaddr(ctx, &local_addrs);
258*7f2fe78bSCy Schubert while ( local_addrs[i++] );
259*7f2fe78bSCy Schubert addr_count = i + 1;
260*7f2fe78bSCy Schubert
261*7f2fe78bSCy Schubert addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *));
262*7f2fe78bSCy Schubert if ( !addrs ) {
263*7f2fe78bSCy Schubert pkrb5_free_addresses(ctx, local_addrs);
264*7f2fe78bSCy Schubert assert(0);
265*7f2fe78bSCy Schubert }
266*7f2fe78bSCy Schubert memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1));
267*7f2fe78bSCy Schubert i = 0;
268*7f2fe78bSCy Schubert while ( local_addrs[i] ) {
269*7f2fe78bSCy Schubert addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
270*7f2fe78bSCy Schubert if (addrs[i] == NULL) {
271*7f2fe78bSCy Schubert pkrb5_free_addresses(ctx, local_addrs);
272*7f2fe78bSCy Schubert assert(0);
273*7f2fe78bSCy Schubert }
274*7f2fe78bSCy Schubert
275*7f2fe78bSCy Schubert addrs[i]->magic = local_addrs[i]->magic;
276*7f2fe78bSCy Schubert addrs[i]->addrtype = local_addrs[i]->addrtype;
277*7f2fe78bSCy Schubert addrs[i]->length = local_addrs[i]->length;
278*7f2fe78bSCy Schubert addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
279*7f2fe78bSCy Schubert if (!addrs[i]->contents) {
280*7f2fe78bSCy Schubert pkrb5_free_addresses(ctx, local_addrs);
281*7f2fe78bSCy Schubert assert(0);
282*7f2fe78bSCy Schubert }
283*7f2fe78bSCy Schubert
284*7f2fe78bSCy Schubert memcpy(addrs[i]->contents,local_addrs[i]->contents,
285*7f2fe78bSCy Schubert local_addrs[i]->length); /* safe */
286*7f2fe78bSCy Schubert i++;
287*7f2fe78bSCy Schubert }
288*7f2fe78bSCy Schubert pkrb5_free_addresses(ctx, local_addrs);
289*7f2fe78bSCy Schubert
290*7f2fe78bSCy Schubert addrs[i] = (krb5_address *)malloc(sizeof(krb5_address));
291*7f2fe78bSCy Schubert if (addrs[i] == NULL)
292*7f2fe78bSCy Schubert assert(0);
293*7f2fe78bSCy Schubert
294*7f2fe78bSCy Schubert addrs[i]->magic = KV5M_ADDRESS;
295*7f2fe78bSCy Schubert addrs[i]->addrtype = AF_INET;
296*7f2fe78bSCy Schubert addrs[i]->length = 4;
297*7f2fe78bSCy Schubert addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length);
298*7f2fe78bSCy Schubert if (!addrs[i]->contents)
299*7f2fe78bSCy Schubert assert(0);
300*7f2fe78bSCy Schubert
301*7f2fe78bSCy Schubert netIPAddr = htonl(publicIP);
302*7f2fe78bSCy Schubert memcpy(addrs[i]->contents,&netIPAddr,4);
303*7f2fe78bSCy Schubert
304*7f2fe78bSCy Schubert pkrb5_get_init_creds_opt_set_address_list(options,addrs);
305*7f2fe78bSCy Schubert
306*7f2fe78bSCy Schubert }
307*7f2fe78bSCy Schubert }
308*7f2fe78bSCy Schubert
309*7f2fe78bSCy Schubert code = pkrb5_get_init_creds_opt_set_out_ccache(ctx, options, cc);
310*7f2fe78bSCy Schubert if (code)
311*7f2fe78bSCy Schubert goto cleanup;
312*7f2fe78bSCy Schubert
313*7f2fe78bSCy Schubert code = pkrb5_get_init_creds_password(ctx,
314*7f2fe78bSCy Schubert &my_creds,
315*7f2fe78bSCy Schubert me,
316*7f2fe78bSCy Schubert password, // password
317*7f2fe78bSCy Schubert leash_krb5_prompter, // prompter
318*7f2fe78bSCy Schubert hParent, // prompter data
319*7f2fe78bSCy Schubert 0, // start time
320*7f2fe78bSCy Schubert 0, // service name
321*7f2fe78bSCy Schubert options);
322*7f2fe78bSCy Schubert // @TODO: make this an option
323*7f2fe78bSCy Schubert if ((!code) && (cc != defcache)) {
324*7f2fe78bSCy Schubert code = pkrb5_cc_switch(ctx, cc);
325*7f2fe78bSCy Schubert if (!code) {
326*7f2fe78bSCy Schubert const char *cctype = pkrb5_cc_get_type(ctx, cc);
327*7f2fe78bSCy Schubert if (cctype != NULL) {
328*7f2fe78bSCy Schubert char defname[20];
329*7f2fe78bSCy Schubert sprintf_s(defname, sizeof(defname), "%s:", cctype);
330*7f2fe78bSCy Schubert pkrb5int_cc_user_set_default_name(ctx, defname);
331*7f2fe78bSCy Schubert }
332*7f2fe78bSCy Schubert }
333*7f2fe78bSCy Schubert }
334*7f2fe78bSCy Schubert cleanup:
335*7f2fe78bSCy Schubert if (code && cc_new) {
336*7f2fe78bSCy Schubert // don't leave newly-generated empty ccache lying around on failure
337*7f2fe78bSCy Schubert pkrb5_cc_destroy(ctx, cc);
338*7f2fe78bSCy Schubert cc = NULL;
339*7f2fe78bSCy Schubert }
340*7f2fe78bSCy Schubert if ( addrs ) {
341*7f2fe78bSCy Schubert for ( i=0;i<addr_count;i++ ) {
342*7f2fe78bSCy Schubert if ( addrs[i] ) {
343*7f2fe78bSCy Schubert if ( addrs[i]->contents )
344*7f2fe78bSCy Schubert free(addrs[i]->contents);
345*7f2fe78bSCy Schubert free(addrs[i]);
346*7f2fe78bSCy Schubert }
347*7f2fe78bSCy Schubert }
348*7f2fe78bSCy Schubert }
349*7f2fe78bSCy Schubert if (my_creds.client == me)
350*7f2fe78bSCy Schubert my_creds.client = 0;
351*7f2fe78bSCy Schubert pkrb5_free_cred_contents(ctx, &my_creds);
352*7f2fe78bSCy Schubert if (name)
353*7f2fe78bSCy Schubert pkrb5_free_unparsed_name(ctx, name);
354*7f2fe78bSCy Schubert if (me)
355*7f2fe78bSCy Schubert pkrb5_free_principal(ctx, me);
356*7f2fe78bSCy Schubert if (cc)
357*7f2fe78bSCy Schubert pkrb5_cc_close(ctx, cc);
358*7f2fe78bSCy Schubert if (options)
359*7f2fe78bSCy Schubert pkrb5_get_init_creds_opt_free(ctx, options);
360*7f2fe78bSCy Schubert if (ctx && (ctx != alt_ctx))
361*7f2fe78bSCy Schubert pkrb5_free_context(ctx);
362*7f2fe78bSCy Schubert return(code);
363*7f2fe78bSCy Schubert }
364*7f2fe78bSCy Schubert
365*7f2fe78bSCy Schubert
366*7f2fe78bSCy Schubert /**************************************/
367*7f2fe78bSCy Schubert /* LeashKRB5destroyTicket(): */
368*7f2fe78bSCy Schubert /**************************************/
369*7f2fe78bSCy Schubert int
Leash_krb5_kdestroy(void)370*7f2fe78bSCy Schubert Leash_krb5_kdestroy(
371*7f2fe78bSCy Schubert void
372*7f2fe78bSCy Schubert )
373*7f2fe78bSCy Schubert {
374*7f2fe78bSCy Schubert krb5_context ctx;
375*7f2fe78bSCy Schubert krb5_ccache cache;
376*7f2fe78bSCy Schubert krb5_error_code rc;
377*7f2fe78bSCy Schubert
378*7f2fe78bSCy Schubert ctx = NULL;
379*7f2fe78bSCy Schubert cache = NULL;
380*7f2fe78bSCy Schubert rc = Leash_krb5_initialize(&ctx);
381*7f2fe78bSCy Schubert if (rc)
382*7f2fe78bSCy Schubert return(rc);
383*7f2fe78bSCy Schubert
384*7f2fe78bSCy Schubert if (rc = pkrb5_cc_default(ctx, &cache))
385*7f2fe78bSCy Schubert return(rc);
386*7f2fe78bSCy Schubert
387*7f2fe78bSCy Schubert rc = pkrb5_cc_destroy(ctx, cache);
388*7f2fe78bSCy Schubert
389*7f2fe78bSCy Schubert if (ctx != NULL)
390*7f2fe78bSCy Schubert pkrb5_free_context(ctx);
391*7f2fe78bSCy Schubert
392*7f2fe78bSCy Schubert return(rc);
393*7f2fe78bSCy Schubert
394*7f2fe78bSCy Schubert }
395*7f2fe78bSCy Schubert
396*7f2fe78bSCy Schubert krb5_error_code
Leash_krb5_cc_default(krb5_context * ctx,krb5_ccache * cache)397*7f2fe78bSCy Schubert Leash_krb5_cc_default(krb5_context *ctx, krb5_ccache *cache)
398*7f2fe78bSCy Schubert {
399*7f2fe78bSCy Schubert krb5_error_code rc;
400*7f2fe78bSCy Schubert krb5_flags flags;
401*7f2fe78bSCy Schubert
402*7f2fe78bSCy Schubert char *functionName = NULL;
403*7f2fe78bSCy Schubert if (*cache == 0) {
404*7f2fe78bSCy Schubert rc = pkrb5_cc_default(*ctx, cache);
405*7f2fe78bSCy Schubert if (rc) {
406*7f2fe78bSCy Schubert functionName = "krb5_cc_default()";
407*7f2fe78bSCy Schubert goto on_error;
408*7f2fe78bSCy Schubert }
409*7f2fe78bSCy Schubert }
410*7f2fe78bSCy Schubert flags = KRB5_TC_NOTICKET;
411*7f2fe78bSCy Schubert rc = pkrb5_cc_set_flags(*ctx, *cache, flags);
412*7f2fe78bSCy Schubert if (rc) {
413*7f2fe78bSCy Schubert if (rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) {
414*7f2fe78bSCy Schubert if (*cache != NULL && *ctx != NULL)
415*7f2fe78bSCy Schubert pkrb5_cc_close(*ctx, *cache);
416*7f2fe78bSCy Schubert } else {
417*7f2fe78bSCy Schubert functionName = "krb5_cc_set_flags()";
418*7f2fe78bSCy Schubert goto on_error;
419*7f2fe78bSCy Schubert }
420*7f2fe78bSCy Schubert }
421*7f2fe78bSCy Schubert on_error:
422*7f2fe78bSCy Schubert if (rc && functionName) {
423*7f2fe78bSCy Schubert Leash_krb5_error(rc, functionName, 0, ctx, cache);
424*7f2fe78bSCy Schubert }
425*7f2fe78bSCy Schubert return rc;
426*7f2fe78bSCy Schubert }
427*7f2fe78bSCy Schubert
428*7f2fe78bSCy Schubert /**************************************/
429*7f2fe78bSCy Schubert /* Leash_krb5_initialize(): */
430*7f2fe78bSCy Schubert /**************************************/
Leash_krb5_initialize(krb5_context * ctx)431*7f2fe78bSCy Schubert int Leash_krb5_initialize(krb5_context *ctx)
432*7f2fe78bSCy Schubert {
433*7f2fe78bSCy Schubert LPCSTR functionName = NULL;
434*7f2fe78bSCy Schubert krb5_error_code rc;
435*7f2fe78bSCy Schubert
436*7f2fe78bSCy Schubert if (pkrb5_init_context == NULL)
437*7f2fe78bSCy Schubert return 1;
438*7f2fe78bSCy Schubert
439*7f2fe78bSCy Schubert if (*ctx == 0) {
440*7f2fe78bSCy Schubert if (rc = (*pkrb5_init_context)(ctx)) {
441*7f2fe78bSCy Schubert functionName = "krb5_init_context()";
442*7f2fe78bSCy Schubert return Leash_krb5_error(rc, functionName, 0, ctx, NULL);
443*7f2fe78bSCy Schubert }
444*7f2fe78bSCy Schubert }
445*7f2fe78bSCy Schubert return 0;
446*7f2fe78bSCy Schubert }
447*7f2fe78bSCy Schubert
448*7f2fe78bSCy Schubert
449*7f2fe78bSCy Schubert /**************************************/
450*7f2fe78bSCy Schubert /* Leash_krb5_error(): */
451*7f2fe78bSCy Schubert /**************************************/
452*7f2fe78bSCy Schubert int
Leash_krb5_error(krb5_error_code rc,LPCSTR FailedFunctionName,int FreeContextFlag,krb5_context * ctx,krb5_ccache * cache)453*7f2fe78bSCy Schubert Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
454*7f2fe78bSCy Schubert int FreeContextFlag, krb5_context * ctx,
455*7f2fe78bSCy Schubert krb5_ccache * cache)
456*7f2fe78bSCy Schubert {
457*7f2fe78bSCy Schubert #ifdef USE_MESSAGE_BOX
458*7f2fe78bSCy Schubert char message[256];
459*7f2fe78bSCy Schubert const char *errText;
460*7f2fe78bSCy Schubert
461*7f2fe78bSCy Schubert errText = perror_message(rc);
462*7f2fe78bSCy Schubert _snprintf(message, sizeof(message),
463*7f2fe78bSCy Schubert "%s\n(Kerberos error %ld)\n\n%s failed",
464*7f2fe78bSCy Schubert errText,
465*7f2fe78bSCy Schubert rc,
466*7f2fe78bSCy Schubert FailedFunctionName);
467*7f2fe78bSCy Schubert message[sizeof(message)-1] = 0;
468*7f2fe78bSCy Schubert
469*7f2fe78bSCy Schubert MessageBox(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR |
470*7f2fe78bSCy Schubert MB_TASKMODAL |
471*7f2fe78bSCy Schubert MB_SETFOREGROUND);
472*7f2fe78bSCy Schubert #endif /* USE_MESSAGE_BOX */
473*7f2fe78bSCy Schubert
474*7f2fe78bSCy Schubert if (ctx != NULL && *ctx != NULL) {
475*7f2fe78bSCy Schubert if (cache != NULL && *cache != NULL) {
476*7f2fe78bSCy Schubert pkrb5_cc_close(*ctx, *cache);
477*7f2fe78bSCy Schubert *cache = NULL;
478*7f2fe78bSCy Schubert }
479*7f2fe78bSCy Schubert
480*7f2fe78bSCy Schubert if (FreeContextFlag) {
481*7f2fe78bSCy Schubert pkrb5_free_context(*ctx);
482*7f2fe78bSCy Schubert *ctx = NULL;
483*7f2fe78bSCy Schubert }
484*7f2fe78bSCy Schubert }
485*7f2fe78bSCy Schubert
486*7f2fe78bSCy Schubert return rc;
487*7f2fe78bSCy Schubert }
488*7f2fe78bSCy Schubert
489*7f2fe78bSCy Schubert
490*7f2fe78bSCy Schubert /* User Query data structures and functions */
491*7f2fe78bSCy Schubert
492*7f2fe78bSCy Schubert struct textField {
493*7f2fe78bSCy Schubert char * buf; /* Destination buffer address */
494*7f2fe78bSCy Schubert int len; /* Destination buffer length */
495*7f2fe78bSCy Schubert char * label; /* Label for this field */
496*7f2fe78bSCy Schubert char * def; /* Default response for this field */
497*7f2fe78bSCy Schubert int echo; /* 0 = no, 1 = yes, 2 = asterisks */
498*7f2fe78bSCy Schubert };
499*7f2fe78bSCy Schubert
500*7f2fe78bSCy Schubert static int mid_cnt = 0;
501*7f2fe78bSCy Schubert static struct textField * mid_tb = NULL;
502*7f2fe78bSCy Schubert
503*7f2fe78bSCy Schubert #define ID_TEXT 150
504*7f2fe78bSCy Schubert #define ID_MID_TEXT 300
505*7f2fe78bSCy Schubert
506*7f2fe78bSCy Schubert static BOOL CALLBACK
MultiInputDialogProc(HWND hDialog,UINT message,WPARAM wParam,LPARAM lParam)507*7f2fe78bSCy Schubert MultiInputDialogProc( HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam)
508*7f2fe78bSCy Schubert {
509*7f2fe78bSCy Schubert int i;
510*7f2fe78bSCy Schubert
511*7f2fe78bSCy Schubert switch ( message ) {
512*7f2fe78bSCy Schubert case WM_INITDIALOG:
513*7f2fe78bSCy Schubert if ( GetDlgCtrlID((HWND) wParam) != ID_MID_TEXT )
514*7f2fe78bSCy Schubert {
515*7f2fe78bSCy Schubert SetFocus(GetDlgItem( hDialog, ID_MID_TEXT));
516*7f2fe78bSCy Schubert return FALSE;
517*7f2fe78bSCy Schubert }
518*7f2fe78bSCy Schubert for ( i=0; i < mid_cnt ; i++ ) {
519*7f2fe78bSCy Schubert if (mid_tb[i].echo == 0)
520*7f2fe78bSCy Schubert SendDlgItemMessage(hDialog, ID_MID_TEXT+i, EM_SETPASSWORDCHAR, 32, 0);
521*7f2fe78bSCy Schubert else if (mid_tb[i].echo == 2)
522*7f2fe78bSCy Schubert SendDlgItemMessage(hDialog, ID_MID_TEXT+i, EM_SETPASSWORDCHAR, '*', 0);
523*7f2fe78bSCy Schubert }
524*7f2fe78bSCy Schubert return TRUE;
525*7f2fe78bSCy Schubert
526*7f2fe78bSCy Schubert case WM_COMMAND:
527*7f2fe78bSCy Schubert switch ( LOWORD(wParam) ) {
528*7f2fe78bSCy Schubert case IDOK:
529*7f2fe78bSCy Schubert for ( i=0; i < mid_cnt ; i++ ) {
530*7f2fe78bSCy Schubert if ( !GetDlgItemText(hDialog, ID_MID_TEXT+i, mid_tb[i].buf, mid_tb[i].len) )
531*7f2fe78bSCy Schubert *mid_tb[i].buf = '\0';
532*7f2fe78bSCy Schubert }
533*7f2fe78bSCy Schubert /* fallthrough */
534*7f2fe78bSCy Schubert case IDCANCEL:
535*7f2fe78bSCy Schubert EndDialog(hDialog, LOWORD(wParam));
536*7f2fe78bSCy Schubert return TRUE;
537*7f2fe78bSCy Schubert }
538*7f2fe78bSCy Schubert }
539*7f2fe78bSCy Schubert return FALSE;
540*7f2fe78bSCy Schubert }
541*7f2fe78bSCy Schubert
542*7f2fe78bSCy Schubert static LPWORD
lpwAlign(LPWORD lpIn)543*7f2fe78bSCy Schubert lpwAlign( LPWORD lpIn )
544*7f2fe78bSCy Schubert {
545*7f2fe78bSCy Schubert ULONG ul;
546*7f2fe78bSCy Schubert
547*7f2fe78bSCy Schubert ul = (ULONG) lpIn;
548*7f2fe78bSCy Schubert ul += 3;
549*7f2fe78bSCy Schubert ul >>=2;
550*7f2fe78bSCy Schubert ul <<=2;
551*7f2fe78bSCy Schubert return (LPWORD) ul;;
552*7f2fe78bSCy Schubert }
553*7f2fe78bSCy Schubert
554*7f2fe78bSCy Schubert /*
555*7f2fe78bSCy Schubert * dialog widths are measured in 1/4 character widths
556*7f2fe78bSCy Schubert * dialog height are measured in 1/8 character heights
557*7f2fe78bSCy Schubert */
558*7f2fe78bSCy Schubert
559*7f2fe78bSCy Schubert static LRESULT
MultiInputDialog(HINSTANCE hinst,HWND hwndOwner,char * ptext[],int numlines,int width,int tb_cnt,struct textField * tb)560*7f2fe78bSCy Schubert MultiInputDialog( HINSTANCE hinst, HWND hwndOwner,
561*7f2fe78bSCy Schubert char * ptext[], int numlines, int width,
562*7f2fe78bSCy Schubert int tb_cnt, struct textField * tb)
563*7f2fe78bSCy Schubert {
564*7f2fe78bSCy Schubert HGLOBAL hgbl;
565*7f2fe78bSCy Schubert LPDLGTEMPLATE lpdt;
566*7f2fe78bSCy Schubert LPDLGITEMTEMPLATE lpdit;
567*7f2fe78bSCy Schubert LPWORD lpw;
568*7f2fe78bSCy Schubert LPWSTR lpwsz;
569*7f2fe78bSCy Schubert LRESULT ret;
570*7f2fe78bSCy Schubert int nchar, i;
571*7f2fe78bSCy Schubert size_t pwid;
572*7f2fe78bSCy Schubert
573*7f2fe78bSCy Schubert hgbl = GlobalAlloc(GMEM_ZEROINIT, 4096);
574*7f2fe78bSCy Schubert if (!hgbl)
575*7f2fe78bSCy Schubert return -1;
576*7f2fe78bSCy Schubert
577*7f2fe78bSCy Schubert mid_cnt = tb_cnt;
578*7f2fe78bSCy Schubert mid_tb = tb;
579*7f2fe78bSCy Schubert
580*7f2fe78bSCy Schubert lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
581*7f2fe78bSCy Schubert
582*7f2fe78bSCy Schubert // Define a dialog box.
583*7f2fe78bSCy Schubert
584*7f2fe78bSCy Schubert lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU
585*7f2fe78bSCy Schubert | DS_MODALFRAME | WS_CAPTION | DS_CENTER
586*7f2fe78bSCy Schubert | DS_SETFOREGROUND | DS_3DLOOK
587*7f2fe78bSCy Schubert | DS_SHELLFONT | DS_NOFAILCREATE;
588*7f2fe78bSCy Schubert lpdt->cdit = numlines + (2 * tb_cnt) + 2; // number of controls
589*7f2fe78bSCy Schubert lpdt->x = 10;
590*7f2fe78bSCy Schubert lpdt->y = 10;
591*7f2fe78bSCy Schubert lpdt->cx = 20 + width * 4;
592*7f2fe78bSCy Schubert lpdt->cy = 20 + (numlines + tb_cnt + 4) * 14;
593*7f2fe78bSCy Schubert
594*7f2fe78bSCy Schubert lpw = (LPWORD) (lpdt + 1);
595*7f2fe78bSCy Schubert *lpw++ = 0; // no menu
596*7f2fe78bSCy Schubert *lpw++ = 0; // predefined dialog box class (by default)
597*7f2fe78bSCy Schubert
598*7f2fe78bSCy Schubert lpwsz = (LPWSTR) lpw;
599*7f2fe78bSCy Schubert nchar = MultiByteToWideChar (CP_ACP, 0, "", -1, lpwsz, 128);
600*7f2fe78bSCy Schubert lpw += nchar;
601*7f2fe78bSCy Schubert *lpw++ = 8; // font size (points)
602*7f2fe78bSCy Schubert lpwsz = (LPWSTR) lpw;
603*7f2fe78bSCy Schubert nchar = MultiByteToWideChar (CP_ACP, 0, "MS Shell Dlg",
604*7f2fe78bSCy Schubert -1, lpwsz, 128);
605*7f2fe78bSCy Schubert lpw += nchar;
606*7f2fe78bSCy Schubert
607*7f2fe78bSCy Schubert //-----------------------
608*7f2fe78bSCy Schubert // Define an OK button.
609*7f2fe78bSCy Schubert //-----------------------
610*7f2fe78bSCy Schubert lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
611*7f2fe78bSCy Schubert lpdit = (LPDLGITEMTEMPLATE) lpw;
612*7f2fe78bSCy Schubert lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_BORDER;
613*7f2fe78bSCy Schubert lpdit->dwExtendedStyle = 0;
614*7f2fe78bSCy Schubert lpdit->x = (lpdt->cx - 14)/4 - 20;
615*7f2fe78bSCy Schubert lpdit->y = 10 + (numlines + tb_cnt + 2) * 14;
616*7f2fe78bSCy Schubert lpdit->cx = 40;
617*7f2fe78bSCy Schubert lpdit->cy = 14;
618*7f2fe78bSCy Schubert lpdit->id = IDOK; // OK button identifier
619*7f2fe78bSCy Schubert
620*7f2fe78bSCy Schubert lpw = (LPWORD) (lpdit + 1);
621*7f2fe78bSCy Schubert *lpw++ = 0xFFFF;
622*7f2fe78bSCy Schubert *lpw++ = 0x0080; // button class
623*7f2fe78bSCy Schubert
624*7f2fe78bSCy Schubert lpwsz = (LPWSTR) lpw;
625*7f2fe78bSCy Schubert nchar = MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50);
626*7f2fe78bSCy Schubert lpw += nchar;
627*7f2fe78bSCy Schubert *lpw++ = 0; // no creation data
628*7f2fe78bSCy Schubert
629*7f2fe78bSCy Schubert //-----------------------
630*7f2fe78bSCy Schubert // Define an Cancel button.
631*7f2fe78bSCy Schubert //-----------------------
632*7f2fe78bSCy Schubert lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
633*7f2fe78bSCy Schubert lpdit = (LPDLGITEMTEMPLATE) lpw;
634*7f2fe78bSCy Schubert lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP | WS_BORDER;
635*7f2fe78bSCy Schubert lpdit->dwExtendedStyle = 0;
636*7f2fe78bSCy Schubert lpdit->x = (lpdt->cx - 14)*3/4 - 20;
637*7f2fe78bSCy Schubert lpdit->y = 10 + (numlines + tb_cnt + 2) * 14;
638*7f2fe78bSCy Schubert lpdit->cx = 40;
639*7f2fe78bSCy Schubert lpdit->cy = 14;
640*7f2fe78bSCy Schubert lpdit->id = IDCANCEL; // CANCEL button identifier
641*7f2fe78bSCy Schubert
642*7f2fe78bSCy Schubert lpw = (LPWORD) (lpdit + 1);
643*7f2fe78bSCy Schubert *lpw++ = 0xFFFF;
644*7f2fe78bSCy Schubert *lpw++ = 0x0080; // button class
645*7f2fe78bSCy Schubert
646*7f2fe78bSCy Schubert lpwsz = (LPWSTR) lpw;
647*7f2fe78bSCy Schubert nchar = MultiByteToWideChar (CP_ACP, 0, "Cancel", -1, lpwsz, 50);
648*7f2fe78bSCy Schubert lpw += nchar;
649*7f2fe78bSCy Schubert *lpw++ = 0; // no creation data
650*7f2fe78bSCy Schubert
651*7f2fe78bSCy Schubert /* Add controls for preface data */
652*7f2fe78bSCy Schubert for ( i=0; i<numlines; i++) {
653*7f2fe78bSCy Schubert /*-----------------------
654*7f2fe78bSCy Schubert * Define a static text control.
655*7f2fe78bSCy Schubert *-----------------------*/
656*7f2fe78bSCy Schubert lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
657*7f2fe78bSCy Schubert lpdit = (LPDLGITEMTEMPLATE) lpw;
658*7f2fe78bSCy Schubert lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
659*7f2fe78bSCy Schubert lpdit->dwExtendedStyle = 0;
660*7f2fe78bSCy Schubert lpdit->x = 10;
661*7f2fe78bSCy Schubert lpdit->y = 10 + i * 14;
662*7f2fe78bSCy Schubert lpdit->cx = strlen(ptext[i]) * 4 + 10;
663*7f2fe78bSCy Schubert lpdit->cy = 14;
664*7f2fe78bSCy Schubert lpdit->id = ID_TEXT + i; // text identifier
665*7f2fe78bSCy Schubert
666*7f2fe78bSCy Schubert lpw = (LPWORD) (lpdit + 1);
667*7f2fe78bSCy Schubert *lpw++ = 0xFFFF;
668*7f2fe78bSCy Schubert *lpw++ = 0x0082; // static class
669*7f2fe78bSCy Schubert
670*7f2fe78bSCy Schubert lpwsz = (LPWSTR) lpw;
671*7f2fe78bSCy Schubert nchar = MultiByteToWideChar (CP_ACP, 0, ptext[i],
672*7f2fe78bSCy Schubert -1, lpwsz, 2*width);
673*7f2fe78bSCy Schubert lpw += nchar;
674*7f2fe78bSCy Schubert *lpw++ = 0; // no creation data
675*7f2fe78bSCy Schubert }
676*7f2fe78bSCy Schubert
677*7f2fe78bSCy Schubert for ( i=0, pwid = 0; i<tb_cnt; i++) {
678*7f2fe78bSCy Schubert if ( pwid < strlen(tb[i].label) )
679*7f2fe78bSCy Schubert pwid = strlen(tb[i].label);
680*7f2fe78bSCy Schubert }
681*7f2fe78bSCy Schubert
682*7f2fe78bSCy Schubert for ( i=0; i<tb_cnt; i++) {
683*7f2fe78bSCy Schubert /* Prompt */
684*7f2fe78bSCy Schubert /*-----------------------
685*7f2fe78bSCy Schubert * Define a static text control.
686*7f2fe78bSCy Schubert *-----------------------*/
687*7f2fe78bSCy Schubert lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
688*7f2fe78bSCy Schubert lpdit = (LPDLGITEMTEMPLATE) lpw;
689*7f2fe78bSCy Schubert lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
690*7f2fe78bSCy Schubert lpdit->dwExtendedStyle = 0;
691*7f2fe78bSCy Schubert lpdit->x = 10;
692*7f2fe78bSCy Schubert lpdit->y = 10 + (numlines + i + 1) * 14;
693*7f2fe78bSCy Schubert lpdit->cx = pwid * 4;
694*7f2fe78bSCy Schubert lpdit->cy = 14;
695*7f2fe78bSCy Schubert lpdit->id = ID_TEXT + numlines + i; // text identifier
696*7f2fe78bSCy Schubert
697*7f2fe78bSCy Schubert lpw = (LPWORD) (lpdit + 1);
698*7f2fe78bSCy Schubert *lpw++ = 0xFFFF;
699*7f2fe78bSCy Schubert *lpw++ = 0x0082; // static class
700*7f2fe78bSCy Schubert
701*7f2fe78bSCy Schubert lpwsz = (LPWSTR) lpw;
702*7f2fe78bSCy Schubert nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].label ? tb[i].label : "",
703*7f2fe78bSCy Schubert -1, lpwsz, 128);
704*7f2fe78bSCy Schubert lpw += nchar;
705*7f2fe78bSCy Schubert *lpw++ = 0; // no creation data
706*7f2fe78bSCy Schubert
707*7f2fe78bSCy Schubert /*-----------------------
708*7f2fe78bSCy Schubert * Define an edit control.
709*7f2fe78bSCy Schubert *-----------------------*/
710*7f2fe78bSCy Schubert lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
711*7f2fe78bSCy Schubert lpdit = (LPDLGITEMTEMPLATE) lpw;
712*7f2fe78bSCy Schubert lpdit->style = WS_CHILD | WS_VISIBLE | ES_LEFT | WS_TABSTOP | WS_BORDER | (tb[i].echo == 1 ? 0L : ES_PASSWORD);
713*7f2fe78bSCy Schubert lpdit->dwExtendedStyle = 0;
714*7f2fe78bSCy Schubert lpdit->x = 10 + (pwid + 1) * 4;
715*7f2fe78bSCy Schubert lpdit->y = 10 + (numlines + i + 1) * 14;
716*7f2fe78bSCy Schubert lpdit->cx = (width - (pwid + 1)) * 4;
717*7f2fe78bSCy Schubert lpdit->cy = 14;
718*7f2fe78bSCy Schubert lpdit->id = ID_MID_TEXT + i; // identifier
719*7f2fe78bSCy Schubert
720*7f2fe78bSCy Schubert lpw = (LPWORD) (lpdit + 1);
721*7f2fe78bSCy Schubert *lpw++ = 0xFFFF;
722*7f2fe78bSCy Schubert *lpw++ = 0x0081; // edit class
723*7f2fe78bSCy Schubert
724*7f2fe78bSCy Schubert lpwsz = (LPWSTR) lpw;
725*7f2fe78bSCy Schubert nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].def ? tb[i].def : "",
726*7f2fe78bSCy Schubert -1, lpwsz, 128);
727*7f2fe78bSCy Schubert lpw += nchar;
728*7f2fe78bSCy Schubert *lpw++ = 0; // no creation data
729*7f2fe78bSCy Schubert }
730*7f2fe78bSCy Schubert
731*7f2fe78bSCy Schubert GlobalUnlock(hgbl);
732*7f2fe78bSCy Schubert ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl,
733*7f2fe78bSCy Schubert hwndOwner, (DLGPROC) MultiInputDialogProc);
734*7f2fe78bSCy Schubert GlobalFree(hgbl);
735*7f2fe78bSCy Schubert
736*7f2fe78bSCy Schubert switch ( ret ) {
737*7f2fe78bSCy Schubert case 0: /* Timeout */
738*7f2fe78bSCy Schubert return -1;
739*7f2fe78bSCy Schubert case IDOK:
740*7f2fe78bSCy Schubert return 1;
741*7f2fe78bSCy Schubert case IDCANCEL:
742*7f2fe78bSCy Schubert return 0;
743*7f2fe78bSCy Schubert default: {
744*7f2fe78bSCy Schubert char buf[256];
745*7f2fe78bSCy Schubert sprintf(buf,"DialogBoxIndirect() failed: %d",GetLastError());
746*7f2fe78bSCy Schubert MessageBox(hwndOwner,
747*7f2fe78bSCy Schubert buf,
748*7f2fe78bSCy Schubert "GetLastError()",
749*7f2fe78bSCy Schubert MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
750*7f2fe78bSCy Schubert return -1;
751*7f2fe78bSCy Schubert }
752*7f2fe78bSCy Schubert }
753*7f2fe78bSCy Schubert }
754*7f2fe78bSCy Schubert
755*7f2fe78bSCy Schubert static int
multi_field_dialog(HWND hParent,char * preface,int n,struct textField tb[])756*7f2fe78bSCy Schubert multi_field_dialog(HWND hParent, char * preface, int n, struct textField tb[])
757*7f2fe78bSCy Schubert {
758*7f2fe78bSCy Schubert extern HINSTANCE hLeashInst;
759*7f2fe78bSCy Schubert size_t maxwidth = 0;
760*7f2fe78bSCy Schubert int numlines = 0;
761*7f2fe78bSCy Schubert size_t len;
762*7f2fe78bSCy Schubert char * plines[16], *p = preface ? preface : "";
763*7f2fe78bSCy Schubert int i;
764*7f2fe78bSCy Schubert
765*7f2fe78bSCy Schubert for ( i=0; i<16; i++ )
766*7f2fe78bSCy Schubert plines[i] = NULL;
767*7f2fe78bSCy Schubert
768*7f2fe78bSCy Schubert while (*p && numlines < 16) {
769*7f2fe78bSCy Schubert plines[numlines++] = p;
770*7f2fe78bSCy Schubert for ( ;*p && *p != '\r' && *p != '\n'; p++ );
771*7f2fe78bSCy Schubert if ( *p == '\r' && *(p+1) == '\n' ) {
772*7f2fe78bSCy Schubert *p++ = '\0';
773*7f2fe78bSCy Schubert p++;
774*7f2fe78bSCy Schubert } else if ( *p == '\n' ) {
775*7f2fe78bSCy Schubert *p++ = '\0';
776*7f2fe78bSCy Schubert }
777*7f2fe78bSCy Schubert if ( strlen(plines[numlines-1]) > maxwidth )
778*7f2fe78bSCy Schubert maxwidth = strlen(plines[numlines-1]);
779*7f2fe78bSCy Schubert }
780*7f2fe78bSCy Schubert
781*7f2fe78bSCy Schubert for ( i=0;i<n;i++ ) {
782*7f2fe78bSCy Schubert len = strlen(tb[i].label) + 1 + (tb[i].len > 40 ? 40 : tb[i].len);
783*7f2fe78bSCy Schubert if ( maxwidth < len )
784*7f2fe78bSCy Schubert maxwidth = len;
785*7f2fe78bSCy Schubert }
786*7f2fe78bSCy Schubert
787*7f2fe78bSCy Schubert return(MultiInputDialog(hLeashInst, hParent, plines, numlines, maxwidth, n, tb));
788*7f2fe78bSCy Schubert }
789*7f2fe78bSCy Schubert
790*7f2fe78bSCy Schubert static krb5_error_code KRB5_CALLCONV
leash_krb5_prompter(krb5_context context,void * data,const char * name,const char * banner,int num_prompts,krb5_prompt prompts[])791*7f2fe78bSCy Schubert leash_krb5_prompter( krb5_context context,
792*7f2fe78bSCy Schubert void *data,
793*7f2fe78bSCy Schubert const char *name,
794*7f2fe78bSCy Schubert const char *banner,
795*7f2fe78bSCy Schubert int num_prompts,
796*7f2fe78bSCy Schubert krb5_prompt prompts[])
797*7f2fe78bSCy Schubert {
798*7f2fe78bSCy Schubert krb5_error_code errcode = 0;
799*7f2fe78bSCy Schubert int i;
800*7f2fe78bSCy Schubert struct textField * tb = NULL;
801*7f2fe78bSCy Schubert int len = 0, blen=0, nlen=0;
802*7f2fe78bSCy Schubert HWND hParent = (HWND)data;
803*7f2fe78bSCy Schubert
804*7f2fe78bSCy Schubert if (name)
805*7f2fe78bSCy Schubert nlen = strlen(name)+2;
806*7f2fe78bSCy Schubert
807*7f2fe78bSCy Schubert if (banner)
808*7f2fe78bSCy Schubert blen = strlen(banner)+2;
809*7f2fe78bSCy Schubert
810*7f2fe78bSCy Schubert tb = (struct textField *) malloc(sizeof(struct textField) * num_prompts);
811*7f2fe78bSCy Schubert if ( tb != NULL ) {
812*7f2fe78bSCy Schubert int ok;
813*7f2fe78bSCy Schubert memset(tb,0,sizeof(struct textField) * num_prompts);
814*7f2fe78bSCy Schubert for ( i=0; i < num_prompts; i++ ) {
815*7f2fe78bSCy Schubert tb[i].buf = prompts[i].reply->data;
816*7f2fe78bSCy Schubert tb[i].len = prompts[i].reply->length;
817*7f2fe78bSCy Schubert tb[i].label = prompts[i].prompt;
818*7f2fe78bSCy Schubert tb[i].def = NULL;
819*7f2fe78bSCy Schubert tb[i].echo = (prompts[i].hidden ? 2 : 1);
820*7f2fe78bSCy Schubert }
821*7f2fe78bSCy Schubert
822*7f2fe78bSCy Schubert ok = multi_field_dialog(hParent,(char *)banner,num_prompts,tb);
823*7f2fe78bSCy Schubert if ( ok ) {
824*7f2fe78bSCy Schubert for ( i=0; i < num_prompts; i++ )
825*7f2fe78bSCy Schubert prompts[i].reply->length = strlen(prompts[i].reply->data);
826*7f2fe78bSCy Schubert } else
827*7f2fe78bSCy Schubert errcode = -2;
828*7f2fe78bSCy Schubert }
829*7f2fe78bSCy Schubert
830*7f2fe78bSCy Schubert if ( tb )
831*7f2fe78bSCy Schubert free(tb);
832*7f2fe78bSCy Schubert if (errcode) {
833*7f2fe78bSCy Schubert for (i = 0; i < num_prompts; i++) {
834*7f2fe78bSCy Schubert memset(prompts[i].reply->data, 0, prompts[i].reply->length);
835*7f2fe78bSCy Schubert }
836*7f2fe78bSCy Schubert }
837*7f2fe78bSCy Schubert return errcode;
838*7f2fe78bSCy Schubert }
839