auth_file.c
上传用户:ladybrid91
上传日期:2007-01-04
资源大小:287k
文件大小:6k
源码类别:

Web服务器

开发平台:

Unix_Linux

  1. /*
  2. ** auth_file.c
  3. **
  4. ** Copyright (c) 1994-1996 Peter Eriksson <pen@signum.se>
  5. **
  6. ** This program is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2 of the License, or
  9. ** (at your option) any later version.
  10. **
  11. ** This program is distributed in the hope that it will be useful,
  12. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ** GNU General Public License for more details.
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <crypt.h>
  22. #include "phttpd.h"
  23. static hashtable_t *auth_files_table = NULL;
  24. static struct options authfile_cfg_table[] =
  25. {
  26.     { "auth-files", T_HTABLE, &auth_files_table,  NULL },
  27.     { NULL,             -1,       NULL, NULL }
  28. };
  29. static char *mystrcopy(line)
  30. char *line;
  31. {
  32.     char *p;
  33.     int x;
  34.     
  35.     p=line;
  36.     x=0;
  37.     while (x == 0 )
  38.     {
  39. if ( *p != 0x20 && *p != 0x09 && *p != 0x00 )
  40.     p++;
  41. else
  42.     x=1; 
  43.     }
  44.     if ( *p == 0x00 )
  45. return NULL;
  46.     while ( ( *p == 0x20 ||  *p == 0x09) &&  *p !=0x00 )
  47.     {
  48. p++;
  49.     }
  50.     if ( *p == 0x00 )
  51. return NULL;
  52.     if ( p[strlen(p)-1] == 0x0a )
  53. p[strlen(p)-1]=0x00;
  54.     
  55.     return p;
  56. }
  57. int pm_init(const char **argv)
  58. {
  59.     char *cfg_path, *cp;
  60.     const char *name = argv[0];
  61.     int clen;
  62.     
  63.     if (debug > 1)
  64. fprintf(stderr, "*** auth_file/pm_init("%s") called ***n", name);
  65.     clen = strlen(name)+6;
  66.     cfg_path = s_malloc(clen);
  67.     s_strcpy(cfg_path, clen, name);
  68.     
  69.     cp = strrchr(cfg_path, '.');
  70.     if (cp && strcmp(cp, ".so") == 0)
  71. *cp = '';
  72.     
  73.     s_strcat(cfg_path, clen, ".conf");
  74.     if (config_parse_file(cfg_path, authfile_cfg_table, 0) < 0)
  75. return -1;
  76.     
  77.     if (config_parse_argv(argv+1, authfile_cfg_table) < 0)
  78. return -1;
  79.     
  80.     return 0;
  81. }
  82. void pm_exit(void)
  83. {
  84.     if (debug > 1)
  85. fprintf(stderr, "*** auth_file/pm_exit() called ***n");
  86.     
  87.     ht_destroy(auth_files_table);
  88.     s_free(auth_files_table);
  89. }
  90. static int check_file(const char *typepath,
  91.       struct authinfo *aip,
  92.       struct connectioninfo *cip)
  93. {
  94.     int fd;
  95.     char buf[1024], *up, *pp, *lp;
  96.     const char *path;
  97.     int usecrypt=1;
  98.     int use_gecos_as_host=0, i_use,ip_ok=0;
  99.     char *username, *password;
  100.     char *address,*hostname;
  101.     char *hostacl,**hav;
  102.    
  103.     if (aip == NULL ||
  104. aip->type == NULL ||
  105. strcasecmp(aip->type, "basic") != 0 ||
  106. aip->u.basic.username == NULL ||
  107. aip->u.basic.password == NULL)
  108.     {
  109. /* Unknown/bad authentication */
  110. return -1;
  111.     }
  112.     username = aip->u.basic.username;
  113.     password = aip->u.basic.password;
  114.     
  115.     /* RK * should be dynamic */
  116.     if ( strncmp(typepath,"plain",5) == 0 || typepath[0]=='/' )
  117. usecrypt=0;
  118.     else
  119. if (strncasecmp(typepath,"extended",8)==0)
  120. use_gecos_as_host=1;
  121. else
  122. if (strncasecmp(typepath,"crypt",5)!=0 &&
  123. strncasecmp(typepath,"passwd",6)!=0 )
  124. fprintf(stderr, "auth_file: unknown keyword in %sn",typepath);
  125.     /* Now drop KEYWORD */
  126.     if (  typepath[0]!='/' )
  127. path=mystrcopy(typepath);
  128.     else
  129. path=typepath;
  130.     if ( path == NULL )
  131. path=typepath;
  132.     
  133.     /* Select a MODE, default is name:pw:... (passwd-format) */
  134.     /* key: passwd  OR crypt */
  135.     /* Altername is plain :    name plain text keyn */
  136.     
  137.     if (debug > 2)
  138. fprintf(stderr, "auth_file: check_file: %sn",
  139. path);
  140.     
  141.     fd = fd_open(path, O_RDONLY);
  142.     if (fd < 0)
  143. return 0;
  144.     while (fd_gets(buf, sizeof(buf), fd))
  145.     {
  146. up = strtok_r(buf, " tnr:", &lp);
  147. if (up == NULL || up[0] == '#')
  148.     continue;
  149. if (strcmp(up, username) == 0)
  150. {
  151.     if (debug > 2)
  152. fprintf(stderr, "auth_file: check_file: Found usern");
  153.     while (lp && *lp && (*lp == ' ' || *lp == 't'))
  154. ++*lp;
  155.     if (usecrypt)
  156. pp = strtok_r(NULL, "nr:", &lp);
  157.     else
  158. pp = strtok_r(NULL, "nr", &lp);
  159.     if (pp == NULL)
  160.     {
  161. if (password == NULL || *password == '')
  162.     goto OK;
  163.     }
  164.     else
  165.     {
  166.   if (usecrypt==0 &&
  167.     password != NULL && strcmp(password, pp) == 0)
  168.     goto OK;
  169. /* Will use crypt ! Crypt should return 13 character !!  RK */
  170. if (usecrypt==1 &&
  171.     password != NULL &&
  172.     strncmp(crypt(password,pp),pp,13) == 0)
  173.     goto OK;
  174.     }
  175.     
  176.     break;
  177. }
  178.     }
  179.     fd_close(fd);
  180.     return 0;
  181.   OK:
  182.     fd_close(fd);
  183.     aip->validated_username = s_strdup(aip->u.basic.username);
  184.     
  185.     /* Now check for PUT access if "usecrypt" is enabled */
  186.     if (usecrypt && pp != NULL)
  187.     {
  188. pp = strtok_r(NULL, "nr:", &lp); /* This is UID */
  189. if (pp != NULL)
  190.     pp = strtok_r(NULL, "nr:", &lp); /* This is GID */
  191. if (pp != NULL)
  192.     pp = strtok_r(NULL, "nr:", &lp); /* This is GECOS */
  193. /* we do use this for: use_gecos_as_host == 1 */
  194.         if ( pp != NULL && use_gecos_as_host == 1 )
  195.         {
  196. if ( ! cip ) return 0;
  197. ip_ok=0;
  198. hostacl=s_strdup(pp);
  199. hav=strsplit(hostacl,'|',0);
  200.      dns_get(cip->client, NULL, &hostname, &address, NULL);
  201. if ( debug > 6 ) fprintf(stderr,"use_gecos_as_host: From: %s n",address);
  202.                 for (i_use = 0; hav[i_use]; i_use++)
  203. { fprintf(stderr,"                 vs %s %dn",hav[i_use],strmatch( address,hav[i_use] ));
  204. if ( strmatch( address,hav[i_use] )!=0 ) { ip_ok=1; break; }
  205. }
  206. s_free(hav);
  207. if ( ip_ok == 0 ) return 0;
  208.         }
  209. if (pp != NULL)
  210.     pp = strtok_r(NULL, "nr:", &lp); /* This is HOME/PUTDIR */
  211. if (pp != NULL && strlen(pp) > 0)
  212. {
  213.     aip->xtype = AUTH_XTYPE_FILE;
  214.     aip->xfree = s_free;
  215.     aip->xinfo = s_strdup(pp);
  216. }    
  217.     }
  218.     
  219.     return 1;
  220. }
  221. int pm_auth(struct authinfo *aip, struct connectioninfo *cip,
  222.     const char *domain)
  223. {
  224.     hashentry_t *hep;
  225.     int status;
  226.     
  227.     
  228.     if (debug > 1)
  229. fprintf(stderr, "*** auth_file/pm_auth(%s)n",
  230. domain);
  231.     hep = ht_lookup(auth_files_table, domain, strlen(domain));
  232.     if (hep == NULL)
  233. return 0;
  234.     status = check_file(hep->data, aip, cip);
  235.     ht_release(hep);
  236.     
  237.     return status;
  238. }