ruserpass.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:7k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  * This product includes software developed by the University of
  16.  * California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. #include "ftp_var.h"
  34. #ifdef HAVE_SYS_TYPES_H
  35. #include <sys/types.h>
  36. #endif
  37. #ifdef HAVE_SYS_STAT_H
  38. #include <sys/stat.h>
  39. #endif
  40. #ifdef HAVE_UNISTD_H
  41. #include <unistd.h>
  42. #endif
  43. #include <stdio.h>
  44. #include <utmp.h>
  45. #include <ctype.h>
  46. #include <errno.h>
  47. #ifndef MAXHOSTNAMELEN
  48. #define MAXHOSTNAMELEN 64
  49. #endif
  50. char *renvlook(), *getpass(), *getlogin();
  51. struct utmp *getutmp();
  52. static FILE *cfile;
  53. #define DEFAULT 1
  54. #define LOGIN 2
  55. #define PASSWD 3
  56. #define ACCOUNT 4
  57. #define MACDEF  5
  58. #define ID 10
  59. #define MACH 11
  60. static char tokval[100];
  61. static struct toktab {
  62. char *tokstr;
  63. int tval;
  64. } toktab[]= {
  65.     { "default", DEFAULT },
  66.     { "login",   LOGIN   },
  67.     { "password", PASSWD  },
  68.     { "passwd",         PASSWD  }, 
  69.     { "account", ACCOUNT },
  70.     { "machine", MACH    }, 
  71.     { "macdef",     MACDEF  },
  72.     { NULL,       0       }
  73. };
  74. static int token() {
  75. char *cp;
  76. int c;
  77. struct toktab *t;
  78. if (feof(cfile))
  79. return (0);
  80. while ((c = getc(cfile)) != EOF &&
  81.     (c == 'n' || c == 't' || c == ' ' || c == ','))
  82. continue;
  83. if (c == EOF)
  84. return (0);
  85. cp = tokval;
  86. if (c == '"') {
  87. while ((c = getc(cfile)) != EOF && c != '"') {
  88. if (c == '\')
  89. c = getc(cfile);
  90. *cp++ = c;
  91. }
  92. } else {
  93. *cp++ = c;
  94. while ((c = getc(cfile)) != EOF
  95.     && c != 'n' && c != 't' && c != ' ' && c != ',') {
  96. if (c == '\')
  97. c = getc(cfile);
  98. *cp++ = c;
  99. }
  100. }
  101. *cp = 0;
  102. if (tokval[0] == 0)
  103. return (0);
  104. for (t = toktab; t->tokstr; t++)
  105. if (!strcmp(t->tokstr, tokval))
  106. return (t->tval);
  107. return (ID);
  108. }
  109. int ruserpass(char *host, char **aname, char **apass, char **aacct) {
  110. char *hdir, buf[BUFSIZ], *tmp;
  111. char myname[MAXHOSTNAMELEN], *mydomain;
  112. int t, i, c, usedefault = 0;
  113. struct stat stb;
  114. hdir = getenv("HOME");
  115. if (hdir == NULL)
  116. hdir = ".";
  117. (void) sprintf(buf, "%s/.netrc", hdir);
  118. cfile = fopen(buf, "r");
  119. if (cfile == NULL) {
  120. if (errno != ENOENT)
  121. perror(buf);
  122. return(0);
  123. }
  124. if (gethostname(myname, sizeof(myname)) < 0)
  125. myname[0] = '';
  126. if ((mydomain = index(myname, '.')) == NULL)
  127. mydomain = "";
  128. next:
  129. while ((t = token())) switch(t) {
  130. case DEFAULT:
  131. usedefault = 1;
  132. /* FALL THROUGH */
  133. case MACH:
  134. if (!usedefault) {
  135. if (token() != ID)
  136. continue;
  137. /*
  138.  * Allow match either for user's input host name
  139.  * or official hostname.  Also allow match of 
  140.  * incompletely-specified host in local domain.
  141.  */
  142. if (strcasecmp(host, tokval) == 0)
  143. goto match;
  144. if (strcasecmp(hostname, tokval) == 0)
  145. goto match;
  146. if ((tmp = index(hostname, '.')) != NULL &&
  147.     strcasecmp(tmp, mydomain) == 0 &&
  148.     strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
  149.     tokval[tmp - hostname] == '')
  150. goto match;
  151. if ((tmp = index(host, '.')) != NULL &&
  152.     strcasecmp(tmp, mydomain) == 0 &&
  153.     strncasecmp(host, tokval, tmp - host) == 0 &&
  154.     tokval[tmp - host] == '')
  155. goto match;
  156. continue;
  157. }
  158. match:
  159. while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
  160. case LOGIN:
  161. if (token())
  162. if (*aname == 0) { 
  163. *aname = malloc((unsigned) strlen(tokval) + 1);
  164. (void) strcpy(*aname, tokval);
  165. } else {
  166. if (strcmp(*aname, tokval))
  167. goto next;
  168. }
  169. break;
  170. case PASSWD:
  171. if (strcmp(*aname, "anonymous") &&
  172.     fstat(fileno(cfile), &stb) >= 0 &&
  173.     (stb.st_mode & 077) != 0) {
  174. fprintf(stderr, "Error - .netrc file not correct mode.n");
  175. fprintf(stderr, "Remove password or correct mode.n");
  176. goto bad;
  177. }
  178. if (token() && *apass == 0) {
  179. *apass = malloc((unsigned) strlen(tokval) + 1);
  180. (void) strcpy(*apass, tokval);
  181. }
  182. break;
  183. case ACCOUNT:
  184. if (fstat(fileno(cfile), &stb) >= 0
  185.     && (stb.st_mode & 077) != 0) {
  186. fprintf(stderr, "Error - .netrc file not correct mode.n");
  187. fprintf(stderr, "Remove account or correct mode.n");
  188. goto bad;
  189. }
  190. if (token() && *aacct == 0) {
  191. *aacct = malloc((unsigned) strlen(tokval) + 1);
  192. (void) strcpy(*aacct, tokval);
  193. }
  194. break;
  195. case MACDEF:
  196. if (proxy) {
  197. (void) fclose(cfile);
  198. return(0);
  199. }
  200. while ((c = getc(cfile)) != EOF && (c == ' ' || c == 't'));
  201. if (c == EOF || c == 'n') {
  202. printf("Missing macdef name argument.n");
  203. goto bad;
  204. }
  205. if (macnum == 16) {
  206. printf("Limit of 16 macros have already been definedn");
  207. goto bad;
  208. }
  209. tmp = macros[macnum].mac_name;
  210. *tmp++ = c;
  211. for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
  212.     !isspace(c); ++i) {
  213. *tmp++ = c;
  214. }
  215. if (c == EOF) {
  216. printf("Macro definition missing null line terminator.n");
  217. goto bad;
  218. }
  219. *tmp = '';
  220. if (c != 'n') {
  221. while ((c=getc(cfile)) != EOF && c != 'n');
  222. }
  223. if (c == EOF) {
  224. printf("Macro definition missing null line terminator.n");
  225. goto bad;
  226. }
  227. if (macnum == 0) {
  228. macros[macnum].mac_start = macbuf;
  229. }
  230. else {
  231. macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
  232. }
  233. tmp = macros[macnum].mac_start;
  234. while (tmp != macbuf + 4096) {
  235. if ((c=getc(cfile)) == EOF) {
  236. printf("Macro definition missing null line terminator.n");
  237. goto bad;
  238. }
  239. *tmp = c;
  240. if (*tmp == 'n') {
  241. if (*(tmp-1) == '') {
  242.    macros[macnum++].mac_end = tmp - 1;
  243.    break;
  244. }
  245. *tmp = '';
  246. }
  247. tmp++;
  248. }
  249. if (tmp == macbuf + 4096) {
  250. printf("4K macro buffer exceededn");
  251. goto bad;
  252. }
  253. break;
  254. default:
  255. fprintf(stderr, "Unknown .netrc keyword %sn", tokval);
  256. break;
  257. }
  258. goto done;
  259. }
  260. done:
  261. (void) fclose(cfile);
  262. return(0);
  263. bad:
  264. (void) fclose(cfile);
  265. return(-1);
  266. }