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

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 2000 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 <string.h>
  11. #include <errno.h>
  12. #include <pwd.h>
  13. #if HAVE_UNISTD_H
  14. #include <unistd.h>
  15. #endif
  16. #include "auth.h"
  17. #include "authmod.h"
  18. #include "authmysql.h"
  19. static const char rcsid[]="$Id: authmysql.c,v 1.7 2000/07/04 00:08:56 mrsam Exp $";
  20. static char *auth_mysql_login(const char *service, char *authdata,
  21. int issession,
  22. void (*callback_func)(struct authinfo *, void *), void *callback_arg)
  23. {
  24. char *user, *pass;
  25. struct authmysqluserinfo *authinfo;
  26. if ((user=strtok(authdata, "n")) == 0 ||
  27. (pass=strtok(0, "n")) == 0)
  28. {
  29. errno=EPERM;
  30. return (0);
  31. }
  32. authinfo=auth_mysql_getuserinfo(user);
  33. if (!callback_func)
  34. auth_mysql_cleanup();
  35. if (!authinfo) /* Fatal error - such as MySQL being down */
  36. {
  37. errno=EACCES;
  38. return (0);
  39. }
  40. if (authinfo->cryptpw)
  41. {
  42. if (authcheckpassword(pass,authinfo->cryptpw))
  43. {
  44. errno=EPERM;
  45. return (0); /* User/Password not found. */
  46. }
  47. }
  48. else if (authinfo->clearpw)
  49. {
  50. if (strcmp(pass, authinfo->clearpw))
  51. {
  52. errno=EPERM;
  53. return (0);
  54. }
  55. }
  56. else
  57. {
  58. errno=EPERM;
  59. return (0); /* Username not found */
  60. }
  61. if (callback_func == 0)
  62. {
  63. static char *maildir=0;
  64. authsuccess(authinfo->home, 0, &authinfo->uid,
  65. &authinfo->gid, authinfo->username, "");
  66. if (authinfo->maildir && authinfo->maildir[0])
  67. {
  68. if (maildir) free(maildir);
  69. maildir=malloc(sizeof("MAILDIR=")+
  70. strlen(authinfo->maildir));
  71. if (!maildir)
  72. {
  73. perror("malloc");
  74. exit(1);
  75. }
  76. strcat(strcpy(maildir, "MAILDIR="), authinfo->maildir);
  77. putenv(maildir);
  78. }
  79. else
  80. {
  81. putenv("MAILDIR=");
  82. }
  83. }
  84. else
  85. {
  86. struct authinfo aa;
  87. memset(&aa, 0, sizeof(aa));
  88. /*aa.sysusername=user;*/
  89. aa.sysuserid= &authinfo->uid;
  90. aa.sysgroupid= authinfo->gid;
  91. aa.homedir=authinfo->home;
  92. aa.maildir=authinfo->maildir && authinfo->maildir[0] ?
  93. authinfo->maildir:0;
  94. aa.address=authinfo->username;
  95. (*callback_func)(&aa, callback_arg);
  96. }
  97. return (strdup(authinfo->username));
  98. }
  99. #if HAVE_HMACLIB
  100. #include "../libhmac/hmac.h"
  101. #include "cramlib.h"
  102. struct cram_callback_info {
  103. struct hmac_hashinfo *h;
  104. char *user;
  105. char *challenge;
  106. char *response;
  107. char *userret;
  108. int issession;
  109. void (*callback_func)(struct authinfo *, void *);
  110. void *callback_arg;
  111. };
  112. static int callback_cram(struct authinfo *a, void *vp)
  113. {
  114. struct cram_callback_info *cci=(struct cram_callback_info *)vp;
  115. unsigned char *hashbuf;
  116. unsigned char *p;
  117. unsigned i;
  118. static const char hex[]="0123456789abcdef";
  119. int rc;
  120. if (!a->clearpasswd)
  121. return (-1);
  122. /*
  123. hmac->hh_L*2 will be the size of the binary hash.
  124. hmac->hh_L*4+1 will therefore be size of the binary hash,
  125. as a hexadecimal string.
  126. */
  127. if ((hashbuf=malloc(cci->h->hh_L*6+1)) == 0)
  128. return (1);
  129. hmac_hashkey(cci->h, a->clearpasswd, strlen(a->clearpasswd),
  130. hashbuf, hashbuf+cci->h->hh_L);
  131. p=hashbuf+cci->h->hh_L*2;
  132. for (i=0; i<cci->h->hh_L*2; i++)
  133. {
  134. char c;
  135. c = hex[ (hashbuf[i] >> 4) & 0x0F];
  136. *p++=c;
  137. c = hex[ hashbuf[i] & 0x0F];
  138. *p++=c;
  139. *p=0;
  140. }
  141. rc=auth_verify_cram(cci->h, cci->challenge, cci->response,
  142. (const char *)hashbuf+cci->h->hh_L*2);
  143. free(hashbuf);
  144. if (rc) return (rc);
  145. if ((cci->userret=strdup(a->address)) == 0)
  146. {
  147. perror("malloc");
  148. return (1);
  149. }
  150. if (cci->callback_func)
  151. (*cci->callback_func)(a, cci->callback_arg);
  152. else
  153. {
  154. authsuccess(a->homedir, a->sysusername, a->sysuserid,
  155. &a->sysgroupid,
  156. a->address,
  157. a->quota);
  158. if (a->maildir && a->maildir[0])
  159. {
  160. static char *maildir=0;
  161. if (maildir) free(maildir);
  162. maildir=malloc(sizeof("MAILDIR=")+strlen(a->maildir));
  163. if (!maildir)
  164. {
  165. perror("malloc");
  166. exit(1);
  167. }
  168. strcat(strcpy(maildir, "MAILDIR="), a->maildir);
  169. putenv(maildir);
  170. }
  171. else
  172. {
  173. putenv("MAILDIR=");
  174. }
  175. }
  176. return (0);
  177. }
  178. static char *auth_mysql_cram(const char *service,
  179. const char *authtype, char *authdata, int issession,
  180. void (*callback_func)(struct authinfo *, void *), void *callback_arg)
  181. {
  182. struct cram_callback_info cci;
  183. int rc;
  184. if (auth_get_cram(authtype, authdata,
  185. &cci.h, &cci.user, &cci.challenge, &cci.response))
  186. return (0);
  187. cci.issession=issession;
  188. cci.callback_func=callback_func;
  189. cci.callback_arg=callback_arg;
  190. rc=auth_mysql_pre(cci.user, service, &callback_cram, &cci);
  191. if (callback_func == 0)
  192. auth_mysql_cleanup();
  193. if (rc < 0)
  194. {
  195. errno=EPERM;
  196. return (0);
  197. }
  198. if (rc > 0)
  199. {
  200. errno=EACCES;
  201. return (0);
  202. }
  203. return (cci.userret);
  204. }
  205. #endif
  206. char *auth_mysql(const char *service, const char *authtype, char *authdata,
  207. int issession,
  208. void (*callback_func)(struct authinfo *, void *), void *callback_arg)
  209. {
  210. if (strcmp(authtype, AUTHTYPE_LOGIN) == 0)
  211. return (auth_mysql_login(service, authdata, issession,
  212. callback_func, callback_arg));
  213. #if HAVE_HMACLIB
  214. return (auth_mysql_cram(service, authtype, authdata, issession,
  215. callback_func, callback_arg));
  216. #else
  217. errno=EPERM;
  218. return (0);
  219. #endif
  220. }