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

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 <string.h>
  11. #include <errno.h>
  12. #include "authsasl.h"
  13. #if HAVE_HMACLIB
  14. #include "../libhmac/hmac.h"
  15. #include "cramlib.h"
  16. static int nybble(int c)
  17. {
  18. if (c >= '0' && c <= '9') return (c-'0');
  19. if (c >= 'a' && c <= 'f') return (c-'a'+10);
  20. if (c >= 'A' && c <= 'F') return (c-'A'+10);
  21. return (-1);
  22. }
  23. int auth_verify_cram(struct hmac_hashinfo *hash,
  24. const char *challenge, const char *response,
  25. const char *hashsecret)
  26. {
  27. unsigned char *context;
  28. unsigned i;
  29. if (strlen(hashsecret) != hash->hh_L*4 ||
  30. strlen(response) != hash->hh_L*2)
  31. return (-1);
  32. if ((context=malloc(hash->hh_L*3)) == 0) return (-1);
  33. for (i=0; i<hash->hh_L*2; i++)
  34. {
  35. int a=nybble(hashsecret[i*2]), b=nybble(hashsecret[i*2+1]);
  36. if (a < 0 || b < 0)
  37. {
  38. free(context);
  39. return (-1);
  40. }
  41. context[i]= a*16 + b;
  42. }
  43. hmac_hashtext(hash, challenge, strlen(challenge),
  44. context, context+hash->hh_L,
  45. context+hash->hh_L*2);
  46. for (i=0; i<hash->hh_L; i++)
  47. {
  48. int a=nybble(response[i*2]), b=nybble(response[i*2+1]);
  49. if ( (unsigned char)(a*16+b) !=
  50. context[hash->hh_L*2+i])
  51. {
  52. free(context);
  53. return (-1);
  54. }
  55. }
  56. free(context);
  57. return (0);
  58. }
  59. int auth_get_cram(const char *authtype, char *authdata,
  60. struct hmac_hashinfo **hmacptr,
  61. char **user, char **challenge, char **response)
  62. {
  63. int i;
  64. int challenge_l;
  65. int response_l;
  66. if (strncmp(authtype, "cram-", 5) ||
  67. (*challenge=strtok(authdata, "n")) == 0 ||
  68. (*response=strtok(0, "n")) == 0)
  69. {
  70. errno=EPERM;
  71. return (-1);
  72. }
  73. for (i=0; hmac_list[i]; i++)
  74. if (strcmp(hmac_list[i]->hh_name, authtype+5) == 0)
  75. break;
  76. if (hmac_list[i] == 0
  77. || (challenge_l=authsasl_frombase64(*challenge)) < 0
  78. || (response_l=authsasl_frombase64(*response)) < 0)
  79. {
  80. errno=EACCES;
  81. return (-1);
  82. }
  83. *hmacptr=hmac_list[i];
  84. for (i=0; i<response_l; i++)
  85. if ((*response)[i] == ' ')
  86. break;
  87. if (i >= response_l)
  88. {
  89. errno=EACCES;
  90. return (-1);
  91. }
  92. (*response)[i++]=0;
  93. *user = *response;
  94. (*response) += i;
  95. response_l -= i;
  96. /* Since base64decoded data is always lesser in size (at least),
  97. ** we can do the following:
  98. */
  99. (*challenge)[challenge_l]=0;
  100. (*response)[response_l]=0;
  101. return (0);
  102. }
  103. #endif