lmjm@doc.imperial.ac.uk (01/13/91)
Since we're in the process of switching over to kerberos here (well bones anyhow) I've had to add kerberos style checking on incoming ftam requests. Here are the various bits I've added. Hope these are of some use - please let me know of any problems. I'd also like to have this code, or a relative, available in the next release if possible? The patches presume you want the style of passwd file where if the user has been kerberised (by being given a principle) their password entry is '*krb*'. If the password field is not '*krb*' then normal crypt based checking is done. To do this three files were patched. Firstly CONFIG.make file to add the options to turn on kerberos checks and the paths to the include directories and libraries for both kerberos and des. The second file is the Makefile in the ftam2 directory so that when xftam and xftamd are built they link with the kerberos and des libraries. Lastly there are the patches to the ftam_start() routine in ftam2/ftamsystem.c to call the new routine I've added to the bottom of that file: krb_pwcheck(). This new routine is based on one I added to the unix-niftp system yesterday. It is based on code I borrowed off Steve Lacey here at DoC, that he had added to the xnlock program. It has been in used in xnlock here for some time. I should point out that I've not done a full system rebuild since adding these changes and the patches have only been in place for a few hours. But heck! they seem to work and look ok! Seriously I've tested incoming ftam's on both kerberised and non-kerberised accounts and both correct and incorrect passwords and all seems to work correctly.e} *** config/CONFIG.make.ORIG Sun Jan 13 00:19:28 1991 --- config/CONFIG.make Sun Jan 13 00:38:06 1991 *************** *** 30,36 **** # Options ############################################################################### ! OPTIONS = -I. -I$(TOPDIR)h HDIR = $(TOPDIR)h/ UTILDIR = $(TOPDIR)util/ --- 30,41 ---- # Options ############################################################################### ! # For kerberos. ! # Define these as null if not available. ! KRBOPT = -DKRB_PASSWD -I/usr/local/athena/include ! KRBLIB = /usr/local/athena/lib/libkrb.a /usr/local/athena/lib/libdes.a ! ! OPTIONS = -I. -I$(TOPDIR)h $(KRBOPT) HDIR = $(TOPDIR)h/ UTILDIR = $(TOPDIR)util/ *** ftam2/Makefile.ORIG Sun Jan 13 00:31:13 1991 --- ftam2/Makefile Sun Jan 13 00:32:32 1991 *************** *** 32,38 **** .py.c:; $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) $< ! LIBES = $(TOPDIR)libftam.a $(TOPDIR)libisode.a LLIBS = $(TOPDIR)llib-lftam $(TOPDIR)llib-lisode CFILES = ftamd.c ftamsystem.c ftamd-manage.c ftamd-select.c \ ftamd-trans.c \ --- 32,38 ---- .py.c:; $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) $< ! LIBES = $(TOPDIR)libftam.a $(TOPDIR)libisode.a $(KRBLIB) LLIBS = $(TOPDIR)llib-lftam $(TOPDIR)llib-lisode CFILES = ftamd.c ftamsystem.c ftamd-manage.c ftamd-select.c \ ftamd-trans.c \ *** ftam2/ftamsystem.c.ORIG Sun Jan 13 01:09:46 1991 --- ftam2/ftamsystem.c Sun Jan 13 00:50:58 1991 *************** *** 309,319 **** --- 309,326 ---- pw = baduser ("ftamusers", initiator) ? NULL : getpwnam (initiator); if (pw == NULL) seterr (FS_ACS_USER, EREF_RFSU, EREF_IFSU, ""); + #ifdef KRB_PASSWD if ((!guest && fts -> fts_password == NULL) || *pw -> pw_passwd == NULL + || (!guest && !krb_pwcheck (initiator, pw -> pw_passwd, fts -> fts_password))) + seterr (FS_ACS_PASSWORD, EREF_RFSU, EREF_IFSU, ""); + #else + if ((!guest && fts -> fts_password == NULL) + || *pw -> pw_passwd == NULL || (!guest && strcmp (crypt (fts -> fts_password, pw -> pw_passwd), pw -> pw_passwd))) seterr (FS_ACS_PASSWORD, EREF_RFSU, EREF_IFSU, ""); + #endif if (account = fts -> fts_account) { register struct group *gr = getgrnam (account); *************** *** 607,609 **** --- 614,665 ---- exit (1); } + + #ifdef KRB_PASSWD + #include <krb.h> + + /* L.McLoughlin added kerberos passwd checking - based on original + * code from xnlock by S. Lacey. + * Takes the username, the password from the password file, and the passwd + * the user is trying to use. + * Returns 1 if the passwd matches otherwise 0. + */ + krb_pwcheck( usrname, pwpass, usrpass ) + char *usrname; + char *pwpass; + char *usrpass; + { + char realm[REALM_SZ]; + int krbval; + int ret; + + /* + * check to see if the passwd is `*krb*' + * if it is, use kerberos + */ + + if (strcmp(pwpass, "*krb*") == 0) { + /* + * use kerberos, first of all find the realm + */ + if (krb_get_lrealm(realm, 1) != KSUCCESS) { + (void) strncpy(realm, KRB_REALM, sizeof(realm)); + } + + /* + * now check the passwd + */ + krbval = krb_get_pw_in_tkt(usrname, "", + realm, "krbtgt", + realm, + DEFAULT_TKT_LIFE, usrpass); + ret = (krbval == INTK_OK); + return ret; + } + /* + * use passwd file password + */ + ret = (strcmp(crypt(usrpass, pwpass), pwpass) == 0); + return ret; + } + #endif
jon@athena.mit.edu (Jon A. Rochlis) (01/16/91)
While it's nice to see people adapting Kerberos for their needs, I must point out two problems with this use of Kerberos: 1) You're not getting any increase in security because you are still sending the user's password in the clear. The only thing you're gaining is not having to maintain a password file(s). 2) Just getting an initial ticket is not sufficent to prove your identity. You've violated the basic assumption of client/server *each* sharing a secret with the KDC. Where there's only one secret the user can spoof the KDC and fool the server in question. Take a look at MIT's ksu.c for a way around this (which requires the server to have a secret).