2 * Copyright (c) 1990,1993 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
7 #if defined( KRB ) || defined( UAM_AFSKRB )
10 #include <sys/types.h>
13 #include <sys/socket.h>
19 #include <netinet/in.h>
24 #include <netatalk/endian.h>
25 #include <atalk/afp.h>
26 #include <atalk/compat.h>
27 #include <atalk/util.h>
29 static C_Block seskey;
30 static Key_schedule seskeysched;
32 static char realm[ REALM_SZ ];
35 static int validseskey = 0;
36 static int logged = 0;
38 static char instance[ INST_SZ ], name[ ANAME_SZ ];
45 #include <afs/venus.h>
46 #include <afs/afsint.h>
54 int32_t BeginTimestamp;
62 static __inline__ void lcase( p )
73 static __inline__ void ucase( p )
84 #define KRB4CMD_HELO 1
85 #define KRB4RPL_REALM 2
86 #define KRB4WRT_SESS 3
87 #define KRB4RPL_DONE 4
88 #define KRB4RPL_PRINC 5
89 #define KRB4WRT_TOKEN 6
90 #define KRB4WRT_SKIP 7
91 #define KRB4RPL_DONEMUT 8
94 static int krb4_login(void *obj, struct passwd **uam_pwd,
95 char *ibuf, int ibuflen,
96 char *rbuf, int *rbuflen )
102 if ( *ibuf != KRB4CMD_HELO ) {
103 syslog( LOG_INFO, "krb4_login: bad command %d", *ibuf );
104 return( AFPERR_NOTAUTH );
108 if ( krb_get_lrealm( realm, 1 ) != KSUCCESS ) {
109 syslog( LOG_ERR, "krb4_login: can't get local realm!" );
110 return( AFPERR_NOTAUTH );
113 *p++ = KRB4RPL_REALM;
115 len = strlen( realm );
121 if ( setpag() < 0 ) {
122 syslog( LOG_ERR, "krb_login: setpag: %m" );
123 return( AFPERR_BADUAM );
128 return( AFPERR_AUTHCONT );
131 static int krb4_logincont(void *obj, struct passwd **uam_pwd,
132 char *ibuf, int ibuflen,
133 char *rbuf, int *rbuflen)
135 static struct passwd *pwd;
144 struct ClearToken ct;
149 if (uam_afp_read(obj, rbuf, rbuflen) < 0) /* read in the rest. */
153 if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, &username) < 0)
156 if (uam_afpserver_option(obj, UAM_OPTION_USERNAMELEN, &ulen) < 0)
161 switch ( rc = *p++ ) {
163 memcpy( &len, p, sizeof( len ));
164 tkt.length = ntohs( len );
165 p += sizeof( short );
167 if ( tkt.length <= 0 || tkt.length > MAX_KTXT_LEN ) {
168 return( AFPERR_BADUAM );
170 memcpy( tkt.dat, p, tkt.length );
173 if (( rc = krb_rd_req( &tkt, "afpserver", obj->Obj, 0, &ad, "" ))
175 syslog( LOG_ERR, "krb4_logincont: krb_rd_req: %s",
177 return( AFPERR_BADUAM );
180 syslog( LOG_INFO, "krb4_login: %s.%s@%s", ad.pname, ad.pinst,
182 memcpy(realm, ad.prealm, sizeof(realm));
183 memcpy(seskey, ad.session, sizeof( C_Block ));
184 key_sched((C_Block *) seskey, seskeysched );
186 strncpy(username, ad.pname, ulen);
190 *p = KRB4RPL_DONE; /* XXX */
193 if (( pwd = uam_getname( ad.pname, strlen(ad.pname) )) == NULL ) {
194 return( AFPERR_PARAM );
200 *p++ = KRB4RPL_PRINC;
201 len = strlen( realm );
207 return( AFPERR_AUTHCONT );
210 memcpy( &len, p, sizeof( len ));
213 memcpy( &cr, p, len );
215 pcbc_encrypt((C_Block *)&cr, (C_Block *)&cr, len, seskeysched,
216 seskey, DES_DECRYPT );
219 cr.ticket_st.length = ntohl( cr.ticket_st.length );
220 memcpy( p, &cr.ticket_st.length, sizeof( int ));
222 memcpy( p, cr.ticket_st.dat, cr.ticket_st.length );
223 p += cr.ticket_st.length;
225 ct.AuthHandle = ntohl( cr.kvno );
226 memcpy( ct.HandShakeKey, cr.session, sizeof( cr.session ));
228 ct.BeginTimestamp = ntohl( cr.issue_date );
229 ct.EndTimestamp = krb_life_to_time( ntohl( cr.issue_date ),
230 ntohl( cr.lifetime ));
232 aint = sizeof( struct ClearToken );
233 memcpy( p, &aint, sizeof( int ));
235 memcpy( p, &ct, sizeof( struct ClearToken ));
236 p += sizeof( struct ClearToken );
239 memcpy( p, &aint, sizeof( int ));
244 p += strlen( realm ) + 1;
247 vi.in_size = p - buf;
249 vi.out_size = sizeof( buf );
250 if ( pioctl( 0, VIOCSETTOK, &vi, 0 ) < 0 ) {
251 syslog( LOG_ERR, "krb4_logincont: pioctl: %m" );
252 return( AFPERR_BADUAM );
258 *p = KRB4RPL_DONE; /* XXX */
261 if (( pwd = uam_getname( ad.pname, strlen(ad.pname) )) == NULL ) {
262 return( AFPERR_PARAM );
269 syslog( LOG_INFO, "krb4_logincont: bad command %d", rc );
270 return( AFPERR_NOTAUTH );
279 #include <rx/rxkad.h>
280 #include <afs/afsint.h>
282 char *ka_LocalCell();
285 addrealm(realm,cells)
294 for(;*ptr != 0 ;ptr++)
295 if(!strcmp(realm,*ptr))
299 *cells=(char**)realloc(*cells,((2+temp)*sizeof(char*)));
302 *ptr=(char*)malloc(strlen(realm)+1);
303 strcpy(*ptr++,realm);
308 static int kcheckuser(pwd,passwd)
314 char realm[MAXKTCREALMLEN];
315 char lorealm[MAXKTCREALMLEN];
317 Date lifetime=MAXKTCTICKETLIFETIME;
319 char **cells=(char **)malloc(sizeof(char*));
322 struct ktc_principal serviceName;
330 temp=(char*)malloc(strlen(pwd->pw_dir)+1);
331 strcpy(temp,pwd->pw_dir);
333 temp=strtok(temp,"/");
334 temp=strtok('\0',"/");
335 ka_CellToRealm(temp,realm,0);
336 addrealm(realm,&cells);
341 authenticate(cells,pwd->pw_name,passwd);
343 rc=ktc_ListTokens(cellNum,&cellNum,&serviceName);
353 static void authenticate(cells,name,passwd)
362 ka_UserAuthenticate(name,/*instance*/"",/*cell*/*ptr++,
363 passwd,/*setpag*/0,&errorstring);
368 #if defined( UAM_AFSKRB ) && defined( AFS )
369 static int afskrb_login(void *obj, struct passwd *uam_pwd,
370 char *ibuf, int ibuflen,
371 char *rbuf, int *rbuflen )
373 KTEXT_ST authent, rpkt;
375 char *p, *q, *username;
376 int len, rc, whoserealm, ulen;
380 if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, &username) < 0)
383 if (uam_afpserver_option(obj, UAM_OPTION_USERNAMELEN, &ulen) < 0)
386 len = (unsigned char) *ibuf++;
388 if (( p = strchr( ibuf, '@' )) != NULL ) {
394 if ( krb_get_lrealm( realm, 1 ) != KSUCCESS ) {
395 return AFPERR_BADUAM;
399 if (( p = strchr( ibuf, '.' )) != NULL ) {
401 strcpy( instance, p );
405 strcpy( name, ibuf );
407 * We don't have the session key, yet. Get one.
410 if ( validseskey == 0 ) {
411 if ( setpag() < 0 ) {
412 syslog( LOG_ERR, "krb_login: setpag: %m" );
413 return AFPERR_BADUAM;
415 krb_set_tkt_string(( tktfile = mktemp( _PATH_AFPTKT )));
416 if (( rc = krb_get_svc_in_tkt( "afpserver", Obj, realm,
417 TICKET_GRANTING_TICKET, realm, 255, KEYFILE )) != INTK_OK ) {
418 syslog( LOG_ERR, "krb_login: can't get ticket-granting-ticket" );
419 return (( whoserealm ) ? AFPERR_BADUAM : AFPERR_PARAM );
421 if ( krb_mk_req( &authent, name, instance, realm, 0 ) != KSUCCESS ) {
422 return ( AFPERR_PARAM );
424 if ( krb_get_cred( name, instance, realm, &cr ) != KSUCCESS ) {
425 return ( AFPERR_BADUAM );
428 if ( unlink( tktfile ) < 0 ) {
429 syslog( LOG_ERR, "krb_login: unlink %s: %m", tktfile );
430 return ( AFPERR_BADUAM );
433 memcpy( seskey, cr.session, sizeof( C_Block ));
434 key_sched((C_Block *) seskey, seskeysched );
436 strncpy(username, name, ulen);
438 memcpy( p, authent.dat, authent.length );
442 if ( kuam_get_in_tkt( name, instance, realm, TICKET_GRANTING_TICKET,
443 realm, 255, &rpkt ) != INTK_OK ) {
444 return ( AFPERR_PARAM );
448 q = (char *)rpkt.dat;
459 len = strlen( realm );
462 memcpy( &slen, q, sizeof( short ));
463 memcpy( p, &slen, sizeof( short ));
464 p += sizeof( short );
465 q += sizeof( short );
466 memcpy( p, q, slen );
470 return( AFPERR_AUTHCONT );
473 static int afskrb_logincont(void *obj, struct passwd *uam_pwd,
474 char *ibuf, int ibuflen,
475 char *rbuf, int *rbuflen )
479 struct ClearToken ct;
481 char buf[ 1024 ], *p;
486 if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, &username) < 0)
490 memcpy( &clen, ibuf, sizeof( short ));
491 clen = ntohs( clen );
492 ibuf += sizeof( short );
494 pcbc_encrypt((C_Block *)ibuf, (C_Block *)ibuf,
495 clen, seskeysched, seskey, DES_DECRYPT );
496 if ( kuam_set_in_tkt( name, instance, realm, TICKET_GRANTING_TICKET,
497 realm, ibuf ) != INTK_OK ) {
498 return ( AFPERR_PARAM );
501 if ( get_ad_tkt( "afs", "", realm, 255 ) != KSUCCESS ) {
502 return ( AFPERR_PARAM );
504 if ( krb_get_cred( "afs", "", realm, &cr ) != KSUCCESS ) {
505 return ( AFPERR_PARAM );
509 memcpy( p, &cr.ticket_st.length, sizeof( int ));
511 memcpy( p, cr.ticket_st.dat, cr.ticket_st.length );
512 p += cr.ticket_st.length;
514 ct.AuthHandle = cr.kvno;
515 memcpy( ct.HandShakeKey, cr.session, sizeof( cr.session ));
517 ct.BeginTimestamp = cr.issue_date;
518 /* ct.EndTimestamp = cr.issue_date + ( cr.lifetime * 5 * 60 ); */
519 ct.EndTimestamp = krb_life_to_time( cr.issue_date, cr.lifetime );
521 aint = sizeof( struct ClearToken );
522 memcpy( p, &aint, sizeof( int ));
524 memcpy( p, &ct, sizeof( struct ClearToken ));
525 p += sizeof( struct ClearToken );
528 memcpy( p, &aint, sizeof( int ));
533 p += strlen( realm ) + 1;
536 vi.in_size = p - buf;
538 vi.out_size = sizeof( buf );
539 if ( pioctl( 0, VIOCSETTOK, &vi, 0 ) < 0 ) {
540 syslog( LOG_ERR, "krb_logincont: pioctl: %m" );
541 return ( AFPERR_BADUAM );
544 if ( unlink( tktfile ) < 0 ) {
545 syslog( LOG_ERR, "krb_logincont: %s: %m", tktfile );
546 return ( AFPERR_BADUAM );
549 if (( pwd = uam_getname( username )) == NULL ) {
550 return ( AFPERR_PARAM );
555 syslog( LOG_INFO, "authenticated %s.%s@%s", name, instance, realm );
559 syslog( LOG_INFO, "re-authenticated %s.%s@%s", name, instance, realm );
562 #endif /* UAM_AFSKRB AFS */
567 uam_register(UAM_SERVER_LOGIN, "Kerberos IV", krb4_login,
568 krb4_logincont, NULL);
569 /* uam_afpserver_action(); */
572 uam_register(UAM_SERVER_LOGIN, "AFS Kerberos", afskrb_login,
573 afskrb_logincont, NULL);
574 /* uam_afpserver_action(); */
581 /* uam_afpserver_action(); */
582 uam_unregister(UAM_SERVER_LOGIN, "Kerberos IV");
585 /* uam_afpserver_action(); */
586 uam_unregister(UAM_SERVER_LOGIN, "AFS Kerberos");
590 #endif /* KRB or UAM_AFSKRB */