/*
- * $Id: uams_randnum.c,v 1.10 2002-01-04 04:45:48 sibaz Exp $
+ * $Id: uams_randnum.c,v 1.12.6.4.2.2 2008-11-25 15:16:33 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
#include <crack.h>
#endif /* USE_CRACKLIB */
-#ifndef __inline__
-#define __inline__
-#endif /* __inline__ */
-
#define PASSWDLEN 8
static C_Block seskey;
/* 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 ) {
- LOG(log_error, logtype_default, "Failed to open %s", path);
+ LOG(log_error, logtype_uams, "Failed to open %s", path);
return AFPERR_ACCESS;
}
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 )) ) {
- LOG(log_info, logtype_default, "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) {
- LOG(log_error, logtype_default, "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) {
- LOG(log_error, logtype_default, "Failed to read from %s", path );
+ LOG(log_error, logtype_uams, "Failed to read from %s", path );
goto 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) {
- LOG(log_error, logtype_default, "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);
}
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) {
- LOG(log_info, logtype_default, "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;
}
/* 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) {
* 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();
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_, int ibuflen _U_,
+ char *rbuf, int *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;
+ int len, err;
+
+ if (( randpwd = uam_getname(obj, username, ulen)) == NULL )
return AFPERR_PARAM; /* unknown user */
- LOG(log_info, logtype_default, "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;
/* 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, int ibuflen _U_,
+ char *rbuf _U_, int *rbuflen)
{
u_int16_t sessid;
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) )) { /* != */
* and sends it back as part of the reply.
*/
static int rand2num_logincont(void *obj, struct passwd **uam_pwd,
- char *ibuf, int ibuflen,
+ char *ibuf, int ibuflen _U_,
char *rbuf, int *rbuflen)
{
u_int16_t sessid;
- int i;
+ unsigned int i;
*rbuflen = 0;
/* 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);
/* 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;
* 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)
+ int ibuflen _U_, char *rbuf _U_, int *rbuflen _U_)
{
char *passwdfile;
int err, len;
err = randpass(pwd, passwdfile, 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 */
return( AFP_OK );
}
+/* randnum login */
+static int randnum_login(void *obj, struct passwd **uam_pwd,
+ char *ibuf, int ibuflen,
+ char *rbuf, int *rbuflen)
+{
+ char *username;
+ int len, ulen;
+
+ *rbuflen = 0;
+
+ if (uam_afpserver_option(obj, UAM_OPTION_USERNAME,
+ (void *) &username, &ulen) < 0)
+ return AFPERR_MISC;
+
+ if (ibuflen <= 1) {
+ 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, int ibuflen,
+ char *rbuf, int *rbuflen)
+{
+ char *username;
+ int 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");