X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fuams%2Fuams_randnum.c;h=686cc088e09abe99a838518d580a83d8a287fb44;hb=5f5367aa2eedd7e8538566a83d163cc549c9d68f;hp=3d84bf711c1d621207dfbe1af5398284dcafc73b;hpb=34ce7aa317ac91a87df04c84f8132e20c98a819d;p=netatalk.git diff --git a/etc/uams/uams_randnum.c b/etc/uams/uams_randnum.c index 3d84bf71..686cc088 100644 --- a/etc/uams/uams_randnum.c +++ b/etc/uams/uams_randnum.c @@ -1,5 +1,5 @@ /* - * $Id: uams_randnum.c,v 1.7 2001-10-24 14:34:33 srittau Exp $ + * $Id: uams_randnum.c,v 1.20 2009-10-22 13:40:11 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) @@ -39,7 +39,7 @@ char *strchr (), *strrchr (); #include #include -#include +#include #include @@ -47,17 +47,12 @@ char *strchr (), *strrchr (); #include -#ifdef UAM_RNDNUM #include #ifdef USE_CRACKLIB #include #endif /* USE_CRACKLIB */ -#ifndef __inline__ -#define __inline__ -#endif /* __inline__ */ - #define PASSWDLEN 8 static C_Block seskey; @@ -72,16 +67,16 @@ static u_int8_t randbuf[8]; /* handle ~/.passwd. courtesy of shirsch@ibm.net. */ -static __inline__ int home_passwd(const struct passwd *pwd, - const char *path, const int pathlen, - char *passwd, const int len, +static int home_passwd(const struct passwd *pwd, + const char *path, const int pathlen _U_, + unsigned char *passwd, const int len, const int set) { struct stat st; int fd, i; if ( (fd = open(path, (set) ? O_WRONLY : O_RDONLY)) < 0 ) { - syslog( LOG_ERR, "Failed to open %s", path); + LOG(log_error, logtype_uams, "Failed to open %s", path); return AFPERR_ACCESS; } @@ -96,19 +91,19 @@ static __inline__ int home_passwd(const struct passwd *pwd, if (!S_ISREG(st.st_mode) || (pwd->pw_uid != st.st_uid) || (pwd->pw_gid != st.st_gid) || (st.st_mode & ( S_IRWXG | S_IRWXO )) ) { - syslog( LOG_INFO, "Insecure permissions found for %s.", path); + LOG(log_info, logtype_uams, "Insecure permissions found for %s.", path); goto home_passwd_fail; } /* get the password */ if (set) { if (write(fd, passwd, len) < 0) { - syslog( LOG_ERR, "Failed to write to %s", path ); + LOG(log_error, logtype_uams, "Failed to write to %s", path ); goto home_passwd_fail; } } else { if (read(fd, passwd, len) < 0) { - syslog( LOG_ERR, "Failed to read from %s", path ); + LOG(log_error, logtype_uams, "Failed to read from %s", path ); goto home_passwd_fail; } @@ -146,24 +141,25 @@ home_passwd_fail: #define unhex(x) (isdigit(x) ? (x) - '0' : toupper(x) + 10 - 'A') static int afppasswd(const struct passwd *pwd, const char *path, const int pathlen, - char *passwd, int len, + unsigned char *passwd, int len, const int set) { u_int8_t key[DES_KEY_SZ*2]; char buf[MAXPATHLEN + 1], *p; Key_schedule schedule; FILE *fp; - int i, j, keyfd = -1, err = 0; + unsigned int i, j; + int keyfd = -1, err = 0; off_t pos; if ((fp = fopen(path, (set) ? "r+" : "r")) == NULL) { - syslog( LOG_ERR, "Failed to open %s", path); + LOG(log_error, logtype_uams, "Failed to open %s", path); return AFPERR_ACCESS; } /* open the key file if it exists */ strcpy(buf, path); - if (pathlen < sizeof(buf) - 5) { + if (pathlen < (int) sizeof(buf) - 5) { strcat(buf, ".key"); keyfd = open(buf, O_RDONLY); } @@ -172,10 +168,11 @@ static int afppasswd(const struct passwd *pwd, memset(buf, 0, sizeof(buf)); while (fgets(buf, sizeof(buf), fp)) { if ((p = strchr(buf, ':'))) { - if (strncmp(buf, pwd->pw_name, p - buf) == 0) { + if ( strlen(pwd->pw_name) == (p - buf) && + strncmp(buf, pwd->pw_name, p - buf) == 0) { p++; if (*p == PASSWD_ILLEGAL) { - syslog(LOG_INFO, "invalid password entry for %s", pwd->pw_name); + LOG(log_info, logtype_uams, "invalid password entry for %s", pwd->pw_name); err = AFPERR_ACCESS; goto afppasswd_done; } @@ -202,7 +199,7 @@ afppasswd_found: read(keyfd, key, sizeof(key)); /* convert to binary key */ - for (i = j = 0; i < strlen(key); i += 2, j++) + for (i = j = 0; i < strlen((char *) key); i += 2, j++) key[j] = (unhex(key[i]) << 4) | unhex(key[i + 1]); if (j <= DES_KEY_SZ) memset(key + j, 0, sizeof(key) - j); @@ -218,7 +215,7 @@ afppasswd_found: /* decrypt the password */ ecb_encrypt((C_Block *) p, (C_Block *) p, schedule, DES_DECRYPT); } - memset(schedule, 0, sizeof(schedule)); + memset(&schedule, 0, sizeof(schedule)); } if (set) { @@ -263,7 +260,7 @@ afppasswd_done: * depending upon whether or not the password is in ~/.passwd * or in a global location */ static int randpass(const struct passwd *pwd, const char *file, - char *passwd, const int len, const int set) + unsigned char *passwd, const int len, const int set) { int i; uid_t uid = geteuid(); @@ -300,45 +297,30 @@ static int randpass(const struct passwd *pwd, const char *file, return i; } - /* randnum sends an 8-byte number and uses the user's password to * check against the encrypted reply. */ -static int randnum_login(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) +static int rand_login(void *obj, char *username, int ulen, struct passwd **uam_pwd _U_, + char *ibuf _U_, size_t ibuflen _U_, + char *rbuf, size_t *rbuflen) { - char *username, *passwdfile; - u_int16_t sessid; - int len, ulen, err; - - *rbuflen = 0; - - if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, - (void *) &username, &ulen) < 0) - return AFPERR_PARAM; - len = UAM_PASSWD_FILENAME; - if (uam_afpserver_option(obj, UAM_OPTION_PASSWDOPT, - (void *) &passwdfile, &len) < 0) - return AFPERR_PARAM; - - len = (unsigned char) *ibuf++; - if ( len > ulen ) { - return AFPERR_PARAM; - } - memcpy(username, ibuf, len ); - ibuf += len; - username[ len ] = '\0'; - if ((unsigned long) ibuf & 1) /* padding */ - ++ibuf; - - if (( randpwd = uam_getname(username, ulen)) == NULL ) + char *passwdfile; + u_int16_t sessid; + size_t len; + int err; + + if (( randpwd = uam_getname(obj, username, ulen)) == NULL ) return AFPERR_PARAM; /* unknown user */ - syslog( LOG_INFO, "randnum/rand2num login: %s", username); + LOG(log_info, logtype_uams, "randnum/rand2num login: %s", username); if (uam_checkuser(randpwd) < 0) return AFPERR_NOTAUTH; + len = UAM_PASSWD_FILENAME; + if (uam_afpserver_option(obj, UAM_OPTION_PASSWDOPT, + (void *) &passwdfile, &len) < 0) + return AFPERR_PARAM; + if ((err = randpass(randpwd, passwdfile, seskey, sizeof(seskey), 0)) != AFP_OK) return err; @@ -365,8 +347,8 @@ static int randnum_login(void *obj, struct passwd **uam_pwd, /* check encrypted reply. we actually setup the encryption stuff * here as the first part of randnum and rand2num are identical. */ static int randnum_logincont(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + char *ibuf, size_t ibuflen _U_, + char *rbuf _U_, size_t *rbuflen) { u_int16_t sessid; @@ -384,7 +366,7 @@ static int randnum_logincont(void *obj, struct passwd **uam_pwd, memset(seskey, 0, sizeof(seskey)); ecb_encrypt((C_Block *) randbuf, (C_Block *) randbuf, seskeysched, DES_ENCRYPT); - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); /* test against what the client sent */ if (memcmp( randbuf, ibuf, sizeof(randbuf) )) { /* != */ @@ -404,11 +386,11 @@ static int randnum_logincont(void *obj, struct passwd **uam_pwd, * and sends it back as part of the reply. */ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, - char *ibuf, int ibuflen, - char *rbuf, int *rbuflen) + char *ibuf, size_t ibuflen _U_, + char *rbuf, size_t *rbuflen) { u_int16_t sessid; - int i; + unsigned int i; *rbuflen = 0; @@ -432,7 +414,7 @@ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, /* test against client's reply */ if (memcmp(randbuf, ibuf, sizeof(randbuf))) { /* != */ memset(randbuf, 0, sizeof(randbuf)); - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); return AFPERR_NOTAUTH; } ibuf += sizeof(randbuf); @@ -441,7 +423,7 @@ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, /* encrypt client's challenge and send back */ ecb_encrypt( (C_Block *) ibuf, (C_Block *) rbuf, seskeysched, DES_ENCRYPT); - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); *rbuflen = sizeof(randbuf); *uam_pwd = randpwd; @@ -452,12 +434,13 @@ static int rand2num_logincont(void *obj, struct passwd **uam_pwd, * NOTE: an FPLogin must already have completed successfully for this * to work. */ -static int randnum_changepw(void *obj, const char *username, +static int randnum_changepw(void *obj, const char *username _U_, struct passwd *pwd, char *ibuf, - int ibuflen, char *rbuf, int *rbuflen) + size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen _U_) { char *passwdfile; - int err, len; + int err; + size_t len; if (uam_checkuser(pwd) < 0) return AFPERR_ACCESS; @@ -493,10 +476,10 @@ static int randnum_changepw(void *obj, const char *username, #endif /* USE_CRACKLIB */ if (!err) - err = randpass(pwd, passwdfile, ibuf + PASSWDLEN, sizeof(seskey), 1); + err = randpass(pwd, passwdfile, (unsigned char *)ibuf + PASSWDLEN, sizeof(seskey), 1); /* zero out some fields */ - memset(seskeysched, 0, sizeof(seskeysched)); + memset(&seskeysched, 0, sizeof(seskeysched)); memset(seskey, 0, sizeof(seskey)); memset(ibuf, 0, sizeof(seskey)); /* old passwd */ memset(ibuf + PASSWDLEN, 0, sizeof(seskey)); /* new passwd */ @@ -507,17 +490,81 @@ static int randnum_changepw(void *obj, const char *username, return( AFP_OK ); } +/* randnum login */ +static int randnum_login(void *obj, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + char *username; + size_t len, ulen; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (ibuflen < 2) { + return( AFPERR_PARAM ); + } + + len = (unsigned char) *ibuf++; + ibuflen--; + if (!len || len > ibuflen || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, ibuf, len ); + ibuf += len; + ibuflen -=len; + username[ len ] = '\0'; + + if ((unsigned long) ibuf & 1) { /* pad character */ + ++ibuf; + ibuflen--; + } + return (rand_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + +/* randnum login ext */ +static int randnum_login_ext(void *obj, char *uname, struct passwd **uam_pwd, + char *ibuf, size_t ibuflen, + char *rbuf, size_t *rbuflen) +{ + char *username; + size_t len, ulen; + u_int16_t temp16; + + *rbuflen = 0; + + if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, + (void *) &username, &ulen) < 0) + return AFPERR_MISC; + + if (*uname != 3) + return AFPERR_PARAM; + uname++; + memcpy(&temp16, uname, sizeof(temp16)); + len = ntohs(temp16); + if (!len || len > ulen ) { + return( AFPERR_PARAM ); + } + memcpy(username, uname +2, len ); + username[ len ] = '\0'; + return (rand_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen)); +} + static int uam_setup(const char *path) { - if (uam_register(UAM_SERVER_LOGIN, path, "Randnum exchange", - randnum_login, randnum_logincont, NULL) < 0) + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Randnum exchange", + randnum_login, randnum_logincont, NULL, randnum_login_ext) < 0) return -1; - if (uam_register(UAM_SERVER_LOGIN, path, "2-Way Randnum exchange", - randnum_login, rand2num_logincont, NULL) < 0) { + + if (uam_register(UAM_SERVER_LOGIN_EXT, path, "2-Way Randnum exchange", + randnum_login, rand2num_logincont, NULL, randnum_login_ext) < 0) { uam_unregister(UAM_SERVER_LOGIN, "Randnum exchange"); return -1; } - + if (uam_register(UAM_SERVER_CHANGEPW, path, "Randnum Exchange", randnum_changepw) < 0) { uam_unregister(UAM_SERVER_LOGIN, "Randnum exchange"); @@ -543,5 +590,3 @@ UAM_MODULE_EXPORT struct uam_export uams_randnum = { UAM_MODULE_VERSION, uam_setup, uam_cleanup }; - -#endif /* UAM_RNDNUM */