import cyrus-sasl-2.1.23
[cyrus-sasl.git] / mac / CommonKClient / mac_kclient / KClient.c
1 /*
2         KClient.c -- Application library for KClient
3
4         © Copyright 1994,1995 by Cornell University
5         
6         Initial coding 8/94 by Peter Bosanko.
7 */
8
9 #ifndef _KrbDriver_
10 #include "krbdriver.h"
11 #endif
12
13 #ifndef _DEVICES_
14 #include        <Devices.h>
15 #endif
16
17 #include "kcglue_des.h"
18
19 #define KC_SESSION ((KClientRec *)session)
20 #define KC_PB (&(((KClientRec *)session)->hiParm))
21 #define OLD_KC_PB ((krbHiParmBlock *)session)
22 #define PICK_PARM (kcRec ? (void*) kcRec : (void*) pb)
23 #define KCLIENTDRIVER "\p.Kerberos"
24
25 /* Forward Declarations */
26
27 OSErr KClientSendMessage(short msg, void *parm);
28 OSErr KClientSetPassword(  KClientSessionInfo *session, char *password  );
29 krbHiParmBlock *KClientSessionKind(  KClientSessionInfo *session, KClientRec **kcRec );
30 OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString );
31
32 /*
33  * call into des ecb_encrypt
34  */
35 /* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
36 int KClient_des_ecb_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,int do_encrypt)
37 {
38         KClientKey sessionKey;
39         Key_schedule schedule;
40         
41         int rc=KClientGetSessionKey(session,&sessionKey);
42         if(rc!=0)
43                 return rc;
44         rc=kcglue_des_key_sched(&sessionKey,schedule);
45         if(rc!=0)
46                 return rc;
47         kcglue_des_ecb_encrypt(v1,v2,schedule,do_encrypt);
48         return rc;
49 }
50
51 /*
52  * call into des pcbc_encrypt
53  */
54 /* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
55 int KClient_des_pcbc_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,long len,int do_encrypt)
56 {
57         KClientKey sessionKey;
58         Key_schedule schedule;
59         
60         int rc=KClientGetSessionKey(session,&sessionKey);
61         if(rc!=0)
62                 return rc;
63         rc=kcglue_des_key_sched(&sessionKey,schedule);
64         if(rc!=0)
65                 return rc;
66         kcglue_des_pcbc_encrypt(v1,v2,len,schedule,&sessionKey,do_encrypt);
67         return rc;
68 }
69
70 /*---------------------------------------------------------------------------------------------------*/
71 OSErr KClientSendMessage(short msg, void *parm)
72 {
73         ParamBlockRec aPBR;
74         short refNum = 0;
75         
76 /************************************************** 
77         OK to "open" driver everytime because driver
78         just returns if it's already open.
79         This saves us from having to pass around refNum
80         or store it in a global.                     
81 ***************************************************/
82         
83         OSErr err = OpenDriver(KCLIENTDRIVER,&refNum);
84         if (err) return err;
85
86         aPBR.cntrlParam.ioCompletion = nil;
87         aPBR.cntrlParam.ioVRefNum = 0;
88         aPBR.cntrlParam.ioCRefNum = refNum;
89         aPBR.cntrlParam.csCode = msg;
90         BlockMove(&parm,aPBR.cntrlParam.csParam,sizeof(parm));
91                 
92         (void) PBControlImmed( &aPBR );
93
94         err = aPBR.cntrlParam.ioResult;
95         return err;
96 }
97
98 /*---------------------------------------------------------------------------------------------------*/
99 krbHiParmBlock *KClientSessionKind(  KClientSessionInfo *session, KClientRec **kcRec )
100 {
101         if (KC_SESSION->tag==NEW_KCLIENT_TAG) {
102                 /* Newer driver, use newer session record */
103                 if (kcRec)
104                         *kcRec          = KC_SESSION;
105                 return KC_PB;
106         }
107         else {
108                 if (kcRec)
109                         *kcRec          = NULL;
110                 return OLD_KC_PB;
111         }
112 }
113
114 /*---------------------------------------------------------------------------------------------------*/
115 OSErr KClientSetPassword(  KClientSessionInfo *session, char *password  )
116 {
117         KClientRec *kcRec;
118         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
119         
120         pb->user = password;
121         return KClientSendMessage(cKrbSetPassword,PICK_PARM);
122 }
123
124 /*---------------------------------------------------------------------------------------------------*/
125 OSErr KClientNewSession(KClientSessionInfo *session, unsigned long lAddr,unsigned short lPort,unsigned long fAddr,unsigned short fPort)
126 {
127         OSErr err;
128
129         err = KClientSendMessage(cKrbNewClientSession,KC_SESSION);
130         
131         if (err==cKrbBadSelector) {
132                 /* old driver, so initialize by hand */
133                 short i,e = sizeof(KClientSessionInfo) / sizeof(long);
134                 long *s = (long *) session;
135                 for (i=0;i<e;i++) *s++ = 0;
136                 err = noErr;
137         }
138
139         KC_SESSION->libVersion          = 2;
140         KC_PB->lAddr                            = lAddr;
141         KC_PB->lPort                            = lPort;
142         KC_PB->fAddr                            = fAddr;
143         KC_PB->fPort                            = fPort;
144                 
145         return err;
146 }
147
148 /*---------------------------------------------------------------------------------------------------*/
149 OSErr KClientDisposeSession(KClientSessionInfo *session)
150 {
151         KClientRec *kcRec;
152         (void) KClientSessionKind(session,&kcRec);
153         
154         if (kcRec)
155                 return KClientSendMessage(cKrbDisposeSession,session);
156
157         return noErr;
158 }
159
160 /*---------------------------------------------------------------------------------------------------*/
161 /*
162  * modified by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
163  */
164 OSErr KClientGetTicketForService(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen)
165 {
166         return KClientGetTicketForServiceFull(session,service,buf,buflen,0);
167 }
168
169 #include <stdio.h>
170 #include <string.h>
171
172 /*
173  * store the passed long in network byte order
174  */
175 static char *put_long(char *dst,long aval)
176 {
177         *dst++=aval>>24;
178         *dst++=aval>>16;
179         *dst++=aval>>8;
180         *dst++=aval;
181         return dst;
182 }
183
184 /*
185  * - int = 1 byte
186  * - long = 4 bytes
187  * long length of all the following [kclientism]
188  * ticket format, from reading mk_req.c
189  * int KRB_PROT_VERSION      
190  * int AUTH_MSG_APPL_REQUEST
191  * int key version numbner
192  * string realm
193  * int ticket length
194  * int authenticator length
195  * ticket
196  * authenticator [
197  *   string name
198  *   string instance
199  *   string realm
200  *   long checksum
201  *   byte GMT microseconds/5
202  *   int GMT time
203  * ] encrypted in session key
204  */
205
206 /*---------------------------------------------------------------------------------------------------*/
207 /*
208  * created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
209  */
210 OSErr KClientGetTicketForServiceFull(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long cks)
211 {
212         char *p=(char *)buf;
213         long tkt_len;
214         long auth_len;
215         char wbuf[1500];
216
217         OSErr err;      
218         KClientRec *kcRec;
219         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
220
221         pb->service = service;
222         pb->buf = (char *) buf;
223         pb->buflen = *buflen;
224         pb->checksum = cks;
225         err = KClientSendMessage(cKrbGetTicketForService,PICK_PARM);
226         *buflen = pb->buflen;
227         if(err!=0)
228                 return err;
229         /*
230          * if checksum is zero, buth kclientman and kclient will correctly get the ticket
231          * if checksum is non zero, then kclientman will have incorrectly encoded 0 in the checksum
232          * field of the authenticator, kclient will have encoded the correct checksum...
233          * rather than check the underlying authentication package (kclient vs kclientman)
234          * we will go ahead and decrypt the authenticator and fix the checksum.  this is unessary but
235          * harmless for kclient.
236      */
237         if(cks==0)
238                 return 0;
239         p+=4+3+strlen(p+7)+1; /*4 byte kclient len, vers,req, kvno*/
240         tkt_len= (*p++)&0x0ff;
241         auth_len= (*p++)&0x0ff;
242         p+=tkt_len;
243         err=KClient_des_pcbc_encrypt(session,(unsigned char *)p,(unsigned char *)wbuf,auth_len,0);
244         if(err!=0)
245                 return err;
246         {
247                 char *w=wbuf;
248                 /* printf("name='%s'\n",w); */
249                 w+=strlen(w)+1; /*skip name */
250                 /* printf("instance='%s'\n",w); */
251                 w+=strlen(w)+1; /*skip instance */
252                 /* printf("realm='%s'\n",w); */
253                 w+=strlen(w)+1; /*realm*/
254                 w=put_long(w,cks);
255         }
256         err=KClient_des_pcbc_encrypt(session,(unsigned char *)wbuf,(unsigned char *)wbuf,auth_len,1);
257         memcpy(p,wbuf,auth_len);
258         return err;
259 }
260
261 /*---------------------------------------------------------------------------------------------------*/
262 OSErr KClientLogin(  KClientSessionInfo *session, KClientKey *privateKey )
263 {       
264         OSErr err;
265         KClientRec *kcRec;
266         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
267         
268         pb->service = (char *) privateKey; /* pointer to private key in first 4 bytes */
269         err = KClientSendMessage(cKrbLogin,PICK_PARM);
270         return err;
271 }
272
273 /*---------------------------------------------------------------------------------------------------*/
274 OSErr KClientSetPrompt(  KClientSessionInfo *session, char *prompt )
275 {       
276         KClientRec *kcRec;
277         (void) KClientSessionKind(session,&kcRec);
278
279         if (kcRec)
280                 kcRec->prompt = prompt;
281         else return cKrbBadSelector;
282         
283         return noErr;
284 }
285
286 /*---------------------------------------------------------------------------------------------------*/
287 OSErr KClientPasswordLogin(  KClientSessionInfo *session, char *password, KClientKey *privateKey )
288 {
289         OSErr err;
290         
291         if ( ( err = KClientSetPassword(session,password) ) != noErr )
292                  return err;
293         
294         return KClientLogin(session,privateKey);
295 }
296
297 /*---------------------------------------------------------------------------------------------------*/
298 OSErr KClientPasswordToKey( char *password, KClientKey *privateKey )
299 {
300         ParamBlockRec aPBR;
301         short refNum;
302         OSErr err;
303         
304         if ( (err = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
305                 return err;
306
307         aPBR.cntrlParam.ioCompletion = nil;
308         aPBR.cntrlParam.ioVRefNum = 0;
309         aPBR.cntrlParam.ioCRefNum = refNum;
310         aPBR.cntrlParam.csCode = cKrbPasswordToKey;
311         ((long *)aPBR.cntrlParam.csParam)[0] = (long)password;
312         ((long *)aPBR.cntrlParam.csParam)[1] = (long)privateKey;
313                 
314         (void) PBControl( &aPBR, false );
315         return aPBR.cntrlParam.ioResult;
316 }
317
318 /*---------------------------------------------------------------------------------------------------*/
319 OSErr KClientKeyLogin( KClientSessionInfo *session, KClientKey *privateKey )
320 {
321         OSErr err;
322
323         err = KClientSendMessage(cKrbSetKey,privateKey);
324         if (err) return err;
325         
326         return KClientLogin(session,privateKey);
327 }
328
329 /*---------------------------------------------------------------------------------------------------*/
330 OSErr KClientLogout( )
331 {
332         krbHiParmBlock  cpb;
333
334         return KClientSendMessage(cKrbDeleteAllSessions, &cpb);
335 }
336                 
337 /*---------------------------------------------------------------------------------------------------*/
338 short KClientStatus( )
339 {
340         char user[40];
341         
342         user[0] = '\0';
343         (void) KClientGetUserName(user);
344         if (*user != 0)
345                 return KClientLoggedIn;
346         return KClientNotLoggedIn;
347 }
348
349 /*---------------------------------------------------------------------------------------------------*/
350 OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString )
351 {
352         ParamBlockRec aPBR;
353         short refNum;
354         OSErr err;
355         
356         if ( (err = OpenDriver(driver,&refNum)) != noErr)
357                 return err;
358
359         aPBR.cntrlParam.ioCompletion = nil;
360         aPBR.cntrlParam.ioVRefNum = 0;
361         aPBR.cntrlParam.ioCRefNum = refNum;
362         aPBR.cntrlParam.csCode = cKrbDriverVersion;
363         ((long *)aPBR.cntrlParam.csParam)[1] = (long)versionString;
364                 
365         (void) PBControl( &aPBR, false );
366         err = aPBR.cntrlParam.ioResult;
367         
368         /* For pre-2.0, do some detective work */
369         if (err==cKrbBadSelector) {
370                 *majorVersion = 1;
371                 aPBR.cntrlParam.csCode = cKrbGetDesPointers;
372                 ((long *)aPBR.cntrlParam.csParam)[1] = 11; /* so it doesn't return anything */
373                 (void) PBControl( &aPBR, false );
374                 if (aPBR.cntrlParam.ioResult==cKrbOldDriver) {
375                         *minorVersion = 1;
376                         if (versionString)
377                                 *((long *)versionString) = '1.1\0';
378                 }
379                 else {
380                         *minorVersion = 0;
381                         if (versionString)
382                                 *((long *)versionString) = '1.0\0';
383                 }
384                 err = 0;
385         }
386         else {
387                 *majorVersion = aPBR.cntrlParam.csParam[0];
388                 *minorVersion = aPBR.cntrlParam.csParam[1];
389         }
390         
391         return err;
392 }
393
394 /*---------------------------------------------------------------------------------------------------*/
395 OSErr KClientVersion( short *majorVersion, short *minorVersion, char *versionString )
396 {
397         return _KClientVersion(KCLIENTDRIVER,majorVersion,minorVersion,versionString);
398 }
399
400 /*---------------------------------------------------------------------------------------------------*/
401 OSErr KClientGetUserName(char *user)
402 {
403         OSErr err;
404         KClientSessionInfo s,*session = &s;
405         
406         KC_SESSION->tag = 0;
407         OLD_KC_PB->user = user;
408         err = KClientSendMessage(cKrbGetUserName,session);
409         return err;
410 }
411
412 /*---------------------------------------------------------------------------------------------------*/
413 OSErr KClientGetSessionUserName(KClientSessionInfo *session, char *user, short nameType )
414 {
415         OSErr err;
416         KClientRec *kcRec;
417         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
418
419         pb->user = user;
420         kcRec->nameType = nameType;
421         err = KClientSendMessage(cKrbGetSessionUserName,PICK_PARM);
422         return err;
423 }
424
425 /*---------------------------------------------------------------------------------------------------*/
426 OSErr KClientSetUserName(char *user)
427 {
428         OSErr err;
429         KClientSessionInfo s,*session = &s;
430         
431         KC_SESSION->tag = 0;
432         OLD_KC_PB->user = user;
433         err = KClientSendMessage(cKrbSetUserName,session);
434         return err;
435 }
436
437 /*---------------------------------------------------------------------------------------------------*/
438 OSErr KClientCacheInitialTicket(KClientSessionInfo *session, char *service)
439 {
440         OSErr err;      
441         KClientRec *kcRec;
442         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
443                 
444         pb->service = service;
445         err = KClientSendMessage(cKrbCacheInitialTicket,PICK_PARM);
446         return err;
447 }
448
449 /*---------------------------------------------------------------------------------------------------*/
450 OSErr KClientGetSessionKey(KClientSessionInfo *session, KClientKey *sessionKey)
451 {       
452         KClientRec *kcRec;
453         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
454
455         /* Not logged in and no server context */
456         if ((!kcRec || !kcRec->serverContext) && KClientStatus()==KClientNotLoggedIn)
457                 return cKrbNotLoggedIn;
458         
459         BlockMove(&(pb->sessionKey),sessionKey,sizeof(KClientKey));
460         return 0;
461 }
462
463 /*---------------------------------------------------------------------------------------------------*/
464 OSErr KClientMakeSendAuth(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long checksum, char *applicationVersion)
465 {
466         OSErr err;
467         KClientRec *kcRec;
468         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
469                 
470         pb->service = service;
471         pb->buf = (char *) buf;
472         pb->buflen = *buflen;
473         pb->checksum = checksum;
474         pb->applicationVersion = applicationVersion;
475         err = KClientSendMessage(cKrbGetAuthForService,PICK_PARM);
476         *buflen = pb->buflen;
477         return err;
478 }                               
479 /*---------------------------------------------------------------------------------------------------*/
480 OSErr KClientVerifyReplyTicket(KClientSessionInfo *session, void *buf,unsigned long *buflen )
481 {
482         OSErr err;
483         KClientRec *kcRec;
484         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
485         
486         pb->buf = (char *) buf;
487         pb->buflen = *buflen;
488         err = KClientSendMessage(cKrbCheckServiceResponse,PICK_PARM);
489         *buflen = pb->buflen;
490         return err;
491 }
492                 
493 /*---------------------------------------------------------------------------------------------------*/
494 OSErr KClientEncrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,void *encryptBuf,unsigned long *encryptLength)
495 {
496         OSErr err;
497         KClientRec *kcRec;
498         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
499
500         pb->buf = (char *) buf;
501         pb->buflen = buflen;
502         pb->encryptBuf = (char *) encryptBuf;
503         err = KClientSendMessage(cKrbEncrypt,PICK_PARM);
504         *encryptLength = pb->encryptLength;
505         return err;
506 }
507                 
508 /*---------------------------------------------------------------------------------------------------*/
509 OSErr KClientDecrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,
510                                         unsigned long *decryptOffset,unsigned long *decryptLength)
511 {
512         OSErr err;
513         KClientRec *kcRec;
514         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
515
516         pb->buf = (char *) buf;
517         pb->buflen = buflen;
518         err = KClientSendMessage(cKrbDecrypt,PICK_PARM);
519         *decryptOffset = pb->decryptOffset;
520         *decryptLength = pb->decryptLength;
521         return err;
522 }
523
524 /*---------------------------------------------------------------------------------------------------*/
525 void KClientErrorText(OSErr err, char *text)
526 {
527         ParamBlockRec aPBR;
528         short refNum;
529         OSErr oerr;
530         
531         if ( (oerr = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
532                 return;
533
534         aPBR.cntrlParam.ioCompletion = nil;
535         aPBR.cntrlParam.ioVRefNum = 0;
536         aPBR.cntrlParam.ioCRefNum = refNum;
537         aPBR.cntrlParam.csCode = cKrbGetErrorText;
538         ((long *)aPBR.cntrlParam.csParam)[0] = (long)err;
539         ((long *)aPBR.cntrlParam.csParam)[1] = (long)text;
540                 
541         (void) PBControl( &aPBR, false );
542         
543         /* In case driver is old, at least return something */
544         if (aPBR.cntrlParam.ioResult==cKrbBadSelector) {
545                 BlockMove("Kerberos error",text,15);            
546         }
547 }
548
549 /*---------------------------------------------------------------------------------------------------*/
550 /* Kerberized Server routines                                                                        */
551 /*---------------------------------------------------------------------------------------------------*/
552 OSErr KServerNewSession( KClientSessionInfo *session, char *service,unsigned long lAddr, 
553                                                 unsigned short lPort,unsigned long fAddr,unsigned short fPort)
554 {
555         OSErr err;
556
557         KC_PB->service                          = service;
558
559         err = KClientSendMessage(cKrbNewServerSession,KC_SESSION);
560         
561         if (err)
562                 return err;
563
564         KC_SESSION->libVersion          = 2;
565         KC_PB->lAddr                            = lAddr;
566         KC_PB->lPort                            = lPort;
567         KC_PB->fAddr                            = fAddr;
568         KC_PB->fPort                            = fPort;
569                 
570         return err;
571 }
572
573 /*---------------------------------------------------------------------------------------------------*/
574 OSErr KServerVerifyTicket( KClientSessionInfo *session, void *buf, char *filename )
575 {
576         OSErr err;
577         KC_PB->buf = (char *) buf;
578         KC_SESSION->filename = filename;
579
580         err = KClientSendMessage(cKrbServerVerifyTicket,KC_SESSION);
581         return err;
582 }
583
584 /*---------------------------------------------------------------------------------------------------*/
585 OSErr KServerGetReplyTicket( KClientSessionInfo *session, void *buf, unsigned long *buflen )
586 {
587         OSErr err;
588         KClientRec *kcRec;
589         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
590         
591         pb->buf                 = (char *) buf;
592         pb->buflen      = *buflen;
593
594         err = KClientSendMessage(cKrbServerGetReplyTkt,PICK_PARM);
595         if (err) return err;
596         
597         *buflen = pb->buflen;
598         return noErr;
599 }
600
601 /*---------------------------------------------------------------------------------------------------*/
602 OSErr KServerAddKey( KClientSessionInfo *session, KClientKey *privateKey, char *service, long version, char *filename )
603 {
604         OSErr err;
605         KClientKey key;
606         char srv[128];
607         char tkt[1250];
608         unsigned long len;
609         KClientRec *kcRec;
610         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
611
612         if (!kcRec)
613                 return cKrbBadSelector; /* old driver */
614         
615         KC_SESSION->filename    = filename;
616         KC_PB->service                  = service;
617
618         if (!service) {
619                 /* No service, build from scratch, prompt the user */
620  
621                 /* Get the user to log in, using service principle and password */
622                 KClientLogout();
623                 err = KClientLogin( session, &key );
624                 if (err) return err;
625                 
626                 err = KClientGetUserName(srv);
627                 if (err) return err;
628
629                 /* Get a service ticket for the service so that we can obtain key version number */
630                 err = KClientGetTicketForService(session, srv,tkt,&len);
631                 if (err) return err;
632                                 
633                 KC_PB->service = srv;
634                 BlockMove(&key,KC_SESSION->serverKey,8);
635                 KC_SESSION->keyVersion  = tkt[6];               /* tkt contains private key's version in the seventh byte */
636         }
637         else {
638                 KC_SESSION->keyVersion  = version;
639                 BlockMove(privateKey,KC_SESSION->serverKey,8);
640                 KC_PB->service          = service;
641         }
642         
643         return KClientSendMessage(cKrbAddServiceKey,session);
644
645 }
646
647 /*---------------------------------------------------------------------------------------------------*/
648 OSErr KServerGetKey( KClientSessionInfo *session, KClientKey *privateKey,char *service, long version, char *filename )
649 {
650         OSErr err;
651         KClientRec *kcRec;
652         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
653                 
654         if (!kcRec)
655                 return cKrbBadSelector; /* old driver */
656
657         KC_SESSION->keyVersion  = version;
658         KC_SESSION->filename    = filename;
659         KC_PB->service                  = service;
660
661         err = KClientSendMessage(cKrbGetServiceKey,KC_SESSION);
662         if (err) return err;
663
664         BlockMove(KC_SESSION->serverKey,privateKey,8);
665         return noErr;
666 }
667
668 /*---------------------------------------------------------------------------------------------------*/
669 OSErr KServerGetSessionTimeRemaining( KClientSessionInfo *session, long *seconds )
670 {
671         OSErr err;
672         KClientRec *kcRec;
673         krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
674
675         err = KClientSendMessage(cKrbGetSessionTimeRemaining,PICK_PARM);
676         *seconds = pb->checksum;
677         return err;
678 }
679
680 /*---------------------------------------------------------------------------------------------------*/
681 /* Configuration routines                                                                            */
682 /*---------------------------------------------------------------------------------------------------*/
683 OSErr KClientGetLocalRealm( char *realm )
684 {
685         krbParmBlock pb;
686         pb.uRealm = realm;
687         return KClientSendMessage(cKrbGetLocalRealm,&pb);
688 }
689
690 /*---------------------------------------------------------------------------------------------------*/
691 OSErr KClientSetLocalRealm( char *realm )
692 {
693         krbParmBlock pb;
694         pb.uRealm = realm;
695         return KClientSendMessage(cKrbSetLocalRealm,&pb);
696 }
697
698 /*---------------------------------------------------------------------------------------------------*/
699 OSErr KClientGetRealm( char *host, char *realm )
700 {
701         krbParmBlock pb;
702         pb.uRealm = realm;
703         pb.host = host;
704         return KClientSendMessage(cKrbGetRealm,&pb);
705 }
706
707 /*---------------------------------------------------------------------------------------------------*/
708 OSErr KClientAddRealmMap( char *host, char *realm )
709 {
710         krbParmBlock pb;
711         pb.uRealm = realm;
712         pb.host = host;
713         return KClientSendMessage(cKrbAddRealmMap,&pb);
714 }
715
716 /*---------------------------------------------------------------------------------------------------*/
717 OSErr KClientDeleteRealmMap( char *host )
718 {
719         krbParmBlock pb;
720         pb.host = host;
721         return KClientSendMessage(cKrbDeleteRealmMap,&pb);
722 }
723
724 /*---------------------------------------------------------------------------------------------------*/
725 OSErr KClientGetNthRealmMap( long n, char *host, char *realm )
726 {
727         krbParmBlock pb;        
728         pb.host = host;
729         pb.uRealm = realm;
730         pb.itemNumber = &n;
731         return KClientSendMessage(cKrbGetNthRealmMap,&pb);
732 }
733
734 /*---------------------------------------------------------------------------------------------------*/
735 OSErr KClientGetNthServer( long n, char *host, char *realm, Boolean admin )
736 {
737         krbParmBlock pb;
738         
739         pb.host = host;
740         pb.uRealm = realm;
741         pb.itemNumber = &n;
742         pb.admin = (long) admin;
743         return KClientSendMessage(cKrbGetNthServer,&pb);
744 }
745
746 /*---------------------------------------------------------------------------------------------------*/
747 OSErr KClientAddServerMap( char *host, char *realm, Boolean admin )
748 {
749         krbParmBlock pb;
750         pb.uRealm = realm;
751         pb.host = host;
752         pb.admin = admin ? 1 : 0;
753         return KClientSendMessage(cKrbAddServerMap,&pb);
754 }
755
756 /*---------------------------------------------------------------------------------------------------*/
757 OSErr KClientDeleteServerMap( char *host, char *realm )
758 {
759         krbParmBlock pb;
760         pb.uRealm = realm;
761         pb.host = host;
762         return KClientSendMessage(cKrbDeleteServerMap,&pb);
763 }
764
765 /*---------------------------------------------------------------------------------------------------*/
766 OSErr KClientGetNthServerMap( long n, char *host, char *realm, Boolean *admin )
767 {
768         OSErr err;
769         long ladmin;
770         krbParmBlock pb;
771         
772         pb.uRealm = realm;
773         pb.host = host;
774         pb.adminReturn = &ladmin;
775         pb.itemNumber = &n;
776         err = KClientSendMessage(cKrbGetNthServerMap,&pb);
777         *admin = (ladmin==1);
778         return err;
779 }
780
781 /*---------------------------------------------------------------------------------------------------*/
782 OSErr KClientGetNthServerPort( long n, short *port )
783 {
784         OSErr err;
785         krbParmBlock pb;
786         pb.itemNumber = &n;
787         err = KClientSendMessage(cKrbGetNthServerPort,&pb);
788         *port = pb.port;
789         return err;
790 }
791
792 /*---------------------------------------------------------------------------------------------------*/
793 OSErr KClientSetNthServerPort( long n, short port )
794 {
795         krbParmBlock pb;
796         pb.itemNumber = &n;
797         pb.port = port;
798         return KClientSendMessage(cKrbSetNthServerPort,&pb);
799 }
800
801 /*---------------------------------------------------------------------------------------------------*/
802 OSErr KClientGetNumSessions( long *n )
803 {
804         krbParmBlock pb;
805         pb.itemNumber = n;
806         return KClientSendMessage(cKrbGetNumSessions,&pb);
807 }
808
809 /*---------------------------------------------------------------------------------------------------*/
810 OSErr KClientGetNthSession( long n, char *name, char *instance, char *realm )
811 {
812         krbParmBlock pb;
813         pb.itemNumber = &n;
814         pb.uName = name;
815         pb.uInstance = instance;
816         pb.uRealm = realm;
817         return KClientSendMessage(cKrbGetNthSession,&pb);
818 }
819
820 /*---------------------------------------------------------------------------------------------------*/
821 OSErr KClientDeleteSession( char *name, char *instance, char *realm )
822 {
823         krbParmBlock pb;
824         pb.uName = name;
825         pb.uInstance = instance;
826         pb.uRealm = realm;
827         return KClientSendMessage(cKrbDeleteSession,&pb);
828 }
829
830 /*---------------------------------------------------------------------------------------------------*/
831 OSErr KClientGetCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
832 {
833         krbParmBlock pb;
834         pb.uName = name;
835         pb.uInstance = instance;
836         pb.uRealm = realm;
837         pb.cred = cred;
838         return KClientSendMessage(cKrbGetCredentials,&pb);
839 }
840
841 /*---------------------------------------------------------------------------------------------------*/
842 OSErr KClientAddCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
843 {
844         krbParmBlock pb;
845         pb.uName = name;
846         pb.uInstance = instance;
847         pb.uRealm = realm;
848         pb.cred = cred;
849         return KClientSendMessage(cKrbAddCredentials,&pb);
850 }
851
852 /*---------------------------------------------------------------------------------------------------*/
853 OSErr KClientDeleteCredentials( char *name, char *instance, char *realm, 
854                                                                 char *sname, char *sinstance, char *srealm )
855 {
856         krbParmBlock pb;
857         pb.uName = name;
858         pb.uInstance = instance;
859         pb.uRealm = realm;
860         pb.sName = sname;
861         pb.sInstance = sinstance;
862         pb.sRealm = srealm;
863         return KClientSendMessage(cKrbDeleteCredentials,&pb);
864 }
865
866 /*---------------------------------------------------------------------------------------------------*/
867 OSErr KClientGetNumCredentials( long *n, char *name, char *instance, char *realm )
868 {
869         krbParmBlock pb;
870         pb.uName = name;
871         pb.uInstance = instance;
872         pb.uRealm = realm;
873         pb.itemNumber = n;
874         return KClientSendMessage(cKrbGetNumCredentials,&pb);
875 }
876
877 /*---------------------------------------------------------------------------------------------------*/
878 OSErr KClientGetNthCredential( long n, char *name, char *instance, char *realm,
879                                                                 char *sname, char *sinstance, char *srealm )
880 {
881         krbParmBlock pb;
882         pb.uName = name;
883         pb.uInstance = instance;
884         pb.uRealm = realm;
885         pb.sName = sname;
886         pb.sInstance = sinstance;
887         pb.sRealm = srealm;
888         pb.itemNumber = &n;
889         return KClientSendMessage(cKrbGetNthCredentials,&pb);
890 }
891
892 /*---------------------------------------------------------------------------------------------------*/
893 OSErr KClientAddSpecial( char *service, char *name )
894 {
895         krbParmBlock pb;
896         pb.uName = name;
897         pb.sName = service;
898         return KClientSendMessage(cKrbAddSpecial,&pb);
899 }
900
901 /*---------------------------------------------------------------------------------------------------*/
902 OSErr KClientDeleteSpecial( char *service )
903 {
904         krbParmBlock pb;
905         pb.sName = service;
906         return KClientSendMessage(cKrbDeleteSpecial,&pb);
907 }
908
909 /*---------------------------------------------------------------------------------------------------*/
910 OSErr KClientGetNumSpecials( long *n )
911 {
912         krbParmBlock pb;
913         pb.itemNumber = n;
914         return KClientSendMessage(cKrbGetNumSpecials,&pb);
915 }
916
917 /*---------------------------------------------------------------------------------------------------*/
918 OSErr KClientGetNthSpecial( long n, char *name, char *service )
919 {
920         krbParmBlock pb;
921         pb.uName = name;
922         pb.sName = service;
923         pb.itemNumber = &n;
924         return KClientSendMessage(cKrbGetNthSpecial,&pb);
925 }
926
927 /*---------------------------------------------------------------------------------------------------*/
928 OSErr KClientSetOption( short option, void *value )
929 {
930         krbParmBlock pb;
931         pb.uName = (char *) value;
932         pb.port = option;
933         return KClientSendMessage(cKrbSetOption,&pb);
934 }
935
936 /*---------------------------------------------------------------------------------------------------*/
937 OSErr KClientGetOption( short option, void *value )
938 {
939         krbParmBlock pb;
940         pb.uName = (char *) value;
941         pb.port = option;
942         return KClientSendMessage(cKrbGetOption,&pb);
943 }
944