upwd.c
资源名称:socks5.zip [点击查看]
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:8k
源码类别:
代理服务器
开发平台:
Unix_Linux
- /* Copyright (c) 1995,1996,1997 NEC Corporation. All rights reserved. */
- /* */
- /* The redistribution, use and modification in source or binary forms of */
- /* this software is subject to the conditions set forth in the copyright */
- /* document ("Copyright") included with this distribution. */
- /*
- * $Id: upwd.c,v 1.38.4.3 1998/10/09 16:14:14 steve Exp $
- */
- #include "socks5p.h"
- #include "buffer.h"
- #include "threads.h"
- #include "confutil.h"
- #include "addr.h"
- #include "msg.h"
- #include "log.h"
- #ifdef USE_PASSWD
- #ifdef HAVE_CRYPT_H
- #include <crypt.h>
- #endif
- #endif
- #ifdef USE_SHADOW_PASSWD
- #include <shadow.h>
- #ifdef HAVE_CRYPT_H
- #include <crypt.h>
- #endif
- #endif
- #define RESP_OFFSET 1
- #define ULEN_OFFSET(x) 1
- #define USER_OFFSET(x) 2
- #define PLEN_OFFSET(x) USER_OFFSET((x))+(x)[ULEN_OFFSET((x))]
- #define PSWD_OFFSET(x) PLEN_OFFSET((x))+1
- #define SETVERS(x, y) ((x)[0] = (y))
- #define SETULEN(x, y) ((x)[ULEN_OFFSET(x)] = ((y)?(u_char)strlen((y)):0))
- #define SETPLEN(x, y) ((x)[PLEN_OFFSET(x)] = ((y)?(u_char)strlen((y)):0))
- #define SETUSER(x, y) if ((y)) strcpy((x)+USER_OFFSET((x)), (y));
- #define SETPSWD(x, y) if ((y)) strcpy((x)+PSWD_OFFSET((x)), (y));
- #define GETRESP(x) ((u_char)(x[RESP_OFFSET]))
- #define PASSWDHDRSIZE(x) PSWD_OFFSET((x))+(x)[PLEN_OFFSET((x))]
- #define PASSWDRSPSIZE 2
- #ifndef UPWD_TIMEOUT
- #define UPWD_TIMEOUT 15
- #endif
- #define UPWD_IOFLAGS S5_IOFLAGS_RESTART|S5_IOFLAGS_TIMED|S5_IOFLAGS_NBYTES
- char *lsUpwdDefaultFilename = SRVPWD_FILE;
- char *lsUpwdDefaultEnvname = "SOCKS5_PWDFILE";
- IFTHREADED(extern MUTEX_T env_mutex;)
- static int GetString(S5IOHandle fd, char *buf, double *timerm) {
- u_char len;
- buf[0] = ' ';
- if (S5IORecv(fd, NULL, (char *)&len, 1, 0, UPWD_IOFLAGS, timerm) != 1) return -1;
- if (len == 0) return 0;
- if (S5IORecv(fd, NULL, buf, len, 0, UPWD_IOFLAGS, timerm) != len) return -1;
- buf[len] = ' ';
- return len;
- }
- int lsPasswdCliAuth(S5IOHandle fd, S5AuthInfo *ainfo, char *user) {
- double timerm = (double)UPWD_TIMEOUT;
- char buf[2*255+3], *pwd;
- char *tmp;
- MUTEX_LOCK(env_mutex);
- if ((tmp = getenv("SOCKS5_USER"))) user = tmp;
- pwd = getenv("SOCKS5_PASSWD");
- MUTEX_UNLOCK(env_mutex);
- SETVERS(buf, 1);
- SETULEN(buf, user);
- SETUSER(buf, user);
- SETPLEN(buf, pwd);
- SETPSWD(buf, pwd);
- if (S5IOSend(fd, NULL, buf, PASSWDHDRSIZE(buf), 0, UPWD_IOFLAGS, &timerm) != PASSWDHDRSIZE(buf)) return AUTH_FAIL;
- if (S5IORecv(fd, NULL, buf, PASSWDRSPSIZE, 0, UPWD_IOFLAGS, &timerm) != PASSWDRSPSIZE) return AUTH_FAIL;
- return (GETRESP(buf) == 0x00)?AUTH_OK:AUTH_FAIL;
- }
- int lsPasswdSrvAuth(S5IOHandle sd, S5AuthInfo *ainfo, char *name) {
- char resp[] = { 0x01, (char)0xff }, ver, passwd[256];
- double timerm = UPWD_TIMEOUT;
- int rval = AUTH_FAIL;
- IFTHREADED(static MUTEX_T upwd_mutex = MUTEX_INITIALIZER;)
- MUTEX_LOCK(upwd_mutex);
- if (S5IORecv(sd, NULL, &ver, 1, 0, UPWD_IOFLAGS, &timerm) != 1) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Failed to receive version number");
- goto done;
- }
- if ((u_char)ver != 0x01) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Incorrect version number: %d", ver);
- goto done;
- }
- if (GetString(sd, name, &timerm) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Failed to get valid username");
- goto done;
- }
- if (GetString(sd, passwd, &timerm) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Failed to get valid password");
- goto done;
- }
- #ifdef USE_PASSWD
- {
- struct passwd *pw = getpwnam(name);
- if (pw == NULL || pw->pw_uid == 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: No Password entry for user: %s", name);
- goto done;
- }
- if (pw->pw_passwd && strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Password incorrect for user: %s", name);
- goto done;
- }
- }
- #else
- #ifdef USE_SHADOW_PASSWD
- {
- struct spwd *pw = getspnam(name);
- if (pw == NULL) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: No Shadow Password entry for user: %s", name);
- goto done;
- }
- if (pw->sp_pwdp && strcmp(crypt(passwd, pw->sp_pwdp),pw->sp_pwdp)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Shadow Password incorrect for user: %s", name);
- goto done;
- }
- }
- #else
- {
- char c, *myfile, *tmp, *tmpname, *tmppasswd;
- static char *buf = NULL;
- struct stat sb;
- S5IOHandle fd;
- if (buf) goto findname;
- MUTEX_LOCK(env_mutex);
- myfile = getenv(lsUpwdDefaultEnvname);
- myfile = myfile?myfile:lsUpwdDefaultFilename;
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Password file is %s", myfile);
- fd = open(myfile, O_RDONLY);
- MUTEX_UNLOCK(env_mutex);
- /* No passwd file probably means you don't car about having passwds */
- if (fd == S5InvalidIOHandle) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Error opening password file: %m");
- goto done;
- }
- /* Fstat to see how big a buffer we should allocated...what would */
- /* cause this to fail? Either way, if it does, bail. */
- if (fstat(fd, &sb) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Error stating open password file: %m");
- REAL(close)(fd);
- goto done;
- }
- /* If we can't allocate a buffer as big as the password file itself, */
- /* bail... */
- if ((buf = (char *)malloc((sb.st_size+1)*sizeof(char))) == NULL) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Malloc failed for password file");
- REAL(close)(fd);
- goto done;
- }
- /* Read in the contents of the file... */
- if (READFILE(fd, buf, sb.st_size) < 0) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Error reading open password file: %m");
- free(buf); buf = NULL;
- REAL(close)(fd);
- goto done;
- }
- buf[sb.st_size] = ' ';
- REAL(close)(fd);
- findname:
- for (tmp = buf ; tmp; tmp = strchr(tmp, 'n'), tmp = tmp?tmp+1:NULL) {
- tmpname = tmp;
- while ((*tmpname != 'n') && isspace(*tmpname)) tmpname++;
- if (*tmpname == 'n') continue;
- tmppasswd = tmpname;
- while ((*tmppasswd != 'n') && !isspace(*tmppasswd)) tmppasswd++;
- if (*tmppasswd == 'n') continue;
- c = *tmppasswd;
- *tmppasswd = ' ';
- if (strcmp(tmpname, name) != 0) {
- *tmppasswd = c;
- continue;
- }
- *tmppasswd = c;
- while ((*tmppasswd != 'n') && isspace(*tmppasswd)) tmppasswd++;
- if (*tmppasswd == 'n') continue;
- tmpname = tmppasswd;
- while (!isspace(*tmpname)) tmpname++;
- c = *tmpname;
- *tmpname = ' ';
- if (strcmp(tmppasswd, passwd) != 0) {
- *tmpname = c;
- continue;
- }
- *tmpname = c;
- break;
- }
- if (!tmp) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: User: %s no match in password file", name);
- goto done;
- }
- }
- #endif /* USE_SHADOW_PASSWD */
- #endif /* USE_PASSWD */
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: successful: user is %s", name);
- rval = AUTH_OK;
- done:
- MUTEX_UNLOCK(upwd_mutex);
- if (rval == AUTH_OK) resp[1] = 0x00;
- memset(passwd, 0, sizeof(passwd));
- if (S5IOSend(sd, NULL, resp, sizeof(resp), 0, UPWD_IOFLAGS, &timerm) != sizeof(resp)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "UPWD: Failed to send response to client");
- return AUTH_FAIL;
- }
- return rval;
- }