authldap.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:5k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 1998 - 1999 Double Precision, Inc.  See COPYING for
  3. ** distribution information.
  4. */
  5. #if HAVE_CONFIG_H
  6. #include "config.h"
  7. #endif
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <string.h>
  12. #include <errno.h>
  13. #include "auth.h"
  14. #include "authmod.h"
  15. #include "authldap.h"
  16. static const char rcsid[]="$Id: authldap.c,v 1.10 2000/05/30 02:00:23 mrsam Exp $";
  17. struct callback_info {
  18. char *userret;
  19. int issession;
  20. void (*callback_func)(struct authinfo *, void *);
  21. void *callback_arg;
  22. };
  23. static int callback_ldap(struct authinfo *a, void *p)
  24. {
  25. struct callback_info *i=(struct callback_info *)p;
  26. char *pp;
  27. /* No need to check passwords, authldaplib did it already */
  28. if (i->callback_func == 0)
  29. {
  30. static char *env_buf=0;
  31. char *p;
  32. const char *d=a->maildir;
  33. if (!d) d="";
  34. p=malloc(sizeof("MAILDIR=")+strlen(d)+1);
  35. if (!p)
  36. {
  37. perror("malloc");
  38. authexit(1);
  39. }
  40. sprintf(p,"MAILDIR=%s", d);
  41. putenv(p);
  42. if (env_buf) free(env_buf);
  43. env_buf=p;
  44. }
  45. if (i->callback_func == 0)
  46. {
  47. static char *env_buf=0;
  48. char *p;
  49. const char *d=a->quota;
  50. if (!d) d="";
  51. p=malloc(sizeof("MAILDIRQUOTA=")+strlen(d)+1);
  52. if (!p)
  53. {
  54. perror("malloc");
  55. authexit(1);
  56. }
  57. sprintf(p,"MAILDIRQUOTA=%s", d);
  58. putenv(p);
  59. if (env_buf) free(env_buf);
  60. env_buf=p;
  61. }
  62.         if ((i->userret=pp=strdup(a->address)) == 0)
  63.         {
  64.                 perror("malloc");
  65.                 return (1);
  66.         }
  67. if (i->callback_func)
  68. {
  69. a->address=i->userret;
  70. (*i->callback_func)(a, i->callback_arg);
  71. }
  72. else
  73. authsuccess(a->homedir, 0, a->sysuserid, &a->sysgroupid,
  74. a->address, a->fullname);
  75.         return (0);
  76. }
  77. static char *auth_ldap_login(const char *service, char *authdata, int issession,
  78. void (*callback_func)(struct authinfo *, void *), void *callback_arg)
  79. {
  80. const char *user, *pass;
  81. struct callback_info ci;
  82. int rc;
  83. if ((user=strtok(authdata, "n")) == 0 ||
  84. (pass=strtok(0, "n")) == 0)
  85. {
  86. errno=EPERM;
  87. return (0);
  88. }
  89. ci.issession=issession;
  90. ci.callback_func=callback_func;
  91. ci.callback_arg=callback_arg;
  92. rc=authldapcommon(user, pass, &callback_ldap, &ci);
  93. if (callback_func == 0)
  94. authldapclose();
  95. if (rc)
  96. {
  97. errno=EPERM;
  98. return (0);
  99. }
  100. return (ci.userret);
  101. }
  102. #if HAVE_HMACLIB
  103. #include "../libhmac/hmac.h"
  104. #include "cramlib.h"
  105. struct cram_callback_info {
  106. struct hmac_hashinfo *h;
  107. char *user;
  108. char *challenge;
  109. char *response;
  110. char *userret;
  111. int issession;
  112. void (*callback_func)(struct authinfo *, void *);
  113. void *callback_arg;
  114. };
  115. static int callback_cram(struct authinfo *a, void *vp)
  116. {
  117. struct cram_callback_info *cci=(struct cram_callback_info *)vp;
  118. unsigned char *hashbuf;
  119. unsigned char *p;
  120. unsigned i;
  121. static const char hex[]="0123456789abcdef";
  122. int rc;
  123. struct callback_info ci;
  124. if (!a->clearpasswd)
  125. return (-1);
  126. /*
  127. hmac->hh_L*2 will be the size of the binary hash.
  128. hmac->hh_L*4+1 will therefore be size of the binary hash,
  129. as a hexadecimal string.
  130. */
  131. if ((hashbuf=malloc(cci->h->hh_L*6+1)) == 0)
  132. return (1);
  133. hmac_hashkey(cci->h, a->clearpasswd, strlen(a->clearpasswd),
  134. hashbuf, hashbuf+cci->h->hh_L);
  135. p=hashbuf+cci->h->hh_L*2;
  136. for (i=0; i<cci->h->hh_L*2; i++)
  137. {
  138. char c;
  139. c = hex[ (hashbuf[i] >> 4) & 0x0F];
  140. *p++=c;
  141. c = hex[ hashbuf[i] & 0x0F];
  142. *p++=c;
  143. *p=0;
  144. }
  145. rc=auth_verify_cram(cci->h, cci->challenge, cci->response,
  146. (const char *)hashbuf+cci->h->hh_L*2);
  147. free(hashbuf);
  148. if (rc) return (rc);
  149. ci.issession=cci->issession;
  150. ci.callback_func=cci->callback_func;
  151. ci.callback_arg=cci->callback_arg;
  152. if ((cci->userret=strdup(a->address)) == 0)
  153. {
  154. perror("malloc");
  155. return (-1);
  156. }
  157. rc=callback_ldap(a, &ci);
  158. if (rc == 0)
  159. free(ci.userret);
  160. return (rc);
  161. }
  162. static char *auth_ldap_cram(const char *service,
  163. const char *authtype, char *authdata, int issession,
  164. void (*callback_func)(struct authinfo *, void *), void *callback_arg)
  165. {
  166. struct cram_callback_info cci;
  167. int rc;
  168. if (auth_get_cram(authtype, authdata,
  169. &cci.h, &cci.user, &cci.challenge, &cci.response))
  170. return (0);
  171. cci.issession=issession;
  172. cci.callback_func=callback_func;
  173. cci.callback_arg=callback_arg;
  174. rc=authldapcommon(cci.user, 0, &callback_cram, &cci);
  175. if (callback_func == 0)
  176. authldapclose();
  177. if (rc < 0)
  178. {
  179. errno=EPERM;
  180. return (0);
  181. }
  182. if (rc > 0)
  183. {
  184. errno=EACCES;
  185. return (0);
  186. }
  187. return (cci.userret);
  188. }
  189. #endif
  190. char *auth_ldap(const char *service, const char *authtype, char *authdata,
  191. int issession,
  192. void (*callback_func)(struct authinfo *, void *), void *callback_arg)
  193. {
  194. if (strcmp(authtype, AUTHTYPE_LOGIN) == 0)
  195. return (auth_ldap_login(service, authdata, issession,
  196. callback_func, callback_arg));
  197. #if HAVE_HMACLIB
  198. return (auth_ldap_cram(service, authtype, authdata, issession,
  199. callback_func, callback_arg));
  200. #else
  201. errno=EPERM;
  202. return (0);
  203. #endif
  204. }