crypt.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2012 - 2013, Digium, Inc.
  5. *
  6. * David M. Lee, II <dlee@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief Asterisk wrapper for crypt(3)
  21. * \author David M. Lee, II <dlee@digium.com>
  22. */
  23. /*** MODULEINFO
  24. <support_level>core</support_level>
  25. ***/
  26. #include "asterisk.h"
  27. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  28. #include <unistd.h>
  29. #if defined(HAVE_CRYPT_R) && !defined(__FreeBSD__)
  30. #include <crypt.h>
  31. #endif
  32. #include "asterisk/utils.h"
  33. /*!
  34. * \brief Max length of a salt string.
  35. *
  36. * $[1,5,6]$[a–zA–Z0–9./]{1,16}$, plus null terminator
  37. */
  38. #define MAX_SALT_LEN 21
  39. static char salt_chars[] =
  40. "abcdefghijklmnopqrstuvwxyz"
  41. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  42. "0123456789"
  43. "./";
  44. /*! Randomly select a character for a salt string */
  45. static char gen_salt_char(void)
  46. {
  47. int which = ast_random_double() * 64;
  48. return salt_chars[which];
  49. }
  50. /*!
  51. * \brief Generates a salt to try with crypt.
  52. *
  53. * If given an empty string, will generate a salt for the most secure algorithm
  54. * to try with crypt(). If given a previously generated salt, the algorithm will
  55. * be lowered by one level of security.
  56. *
  57. * \param[out] current_salt Output string in which to generate the salt.
  58. * This can be an empty string, or the results of a
  59. * prior gen_salt call.
  60. * \param max_len Length of \a current_salt.
  61. * \return 0 on success.
  62. * \return Non-zero on error.
  63. */
  64. static int gen_salt(char *current_salt, size_t maxlen)
  65. {
  66. int i;
  67. if (maxlen < MAX_SALT_LEN || current_salt == NULL) {
  68. return -1;
  69. }
  70. switch (current_salt[0]) {
  71. case '\0':
  72. /* Initial generation; $6$ = SHA-512 */
  73. *current_salt++ = '$';
  74. *current_salt++ = '6';
  75. *current_salt++ = '$';
  76. for (i = 0; i < 16; ++i) {
  77. *current_salt++ = gen_salt_char();
  78. }
  79. *current_salt++ = '$';
  80. *current_salt++ = '\0';
  81. return 0;
  82. case '$':
  83. switch (current_salt[1]) {
  84. case '6':
  85. /* Downgrade to SHA-256 */
  86. current_salt[1] = '5';
  87. return 0;
  88. case '5':
  89. /* Downgrade to MD5 */
  90. current_salt[1] = '1';
  91. return 0;
  92. case '1':
  93. /* Downgrade to traditional crypt */
  94. *current_salt++ = gen_salt_char();
  95. *current_salt++ = gen_salt_char();
  96. *current_salt++ = '\0';
  97. return 0;
  98. default:
  99. /* Unrecognized algorithm */
  100. return -1;
  101. }
  102. default:
  103. /* Was already as insecure as it gets */
  104. return -1;
  105. }
  106. }
  107. #if defined(HAVE_CRYPT_R)
  108. char *ast_crypt(const char *key, const char *salt)
  109. {
  110. struct crypt_data data = {};
  111. const char *crypted = crypt_r(key, salt, &data);
  112. /* Crypt may return success even if it doesn't recognize the salt. But
  113. * in those cases it always mangles the salt in some way.
  114. */
  115. if (!crypted || !ast_begins_with(crypted, salt)) {
  116. return NULL;
  117. }
  118. return ast_strdup(crypted);
  119. }
  120. int ast_crypt_validate(const char *key, const char *expected)
  121. {
  122. struct crypt_data data = {};
  123. return strcmp(expected, crypt_r(key, expected, &data)) == 0;
  124. }
  125. #elif defined(HAVE_CRYPT)
  126. /* crypt is not reentrant. A global mutex is neither ideal nor perfect, but good
  127. * enough if crypt_r support is unavailable
  128. */
  129. AST_MUTEX_DEFINE_STATIC(crypt_mutex);
  130. char *ast_crypt(const char *key, const char *salt)
  131. {
  132. const char *crypted;
  133. SCOPED_MUTEX(lock, &crypt_mutex);
  134. crypted = crypt(key, salt);
  135. /* Crypt may return success even if it doesn't recognize the salt. But
  136. * in those cases it always mangles the salt in some way.
  137. */
  138. if (!crypted || !ast_begins_with(crypted, salt)) {
  139. return NULL;
  140. }
  141. return ast_strdup(crypted);
  142. }
  143. int ast_crypt_validate(const char *key, const char *expected)
  144. {
  145. SCOPED_MUTEX(lock, &crypt_mutex);
  146. return strcmp(expected, crypt(key, expected)) == 0;
  147. }
  148. #else /* No crypt support */
  149. char *ast_crypt(const char *key, const char *salt)
  150. {
  151. ast_log(LOG_WARNING,
  152. "crypt() support not available; cannot encrypt password\n");
  153. return NULL;
  154. }
  155. int ast_crypt_validate(const char *key, const char *expected)
  156. {
  157. ast_log(LOG_WARNING,
  158. "crypt() support not available; cannot validate password\n");
  159. return 0;
  160. }
  161. #endif /* No crypt support */
  162. char *ast_crypt_encrypt(const char *key)
  163. {
  164. char salt[MAX_SALT_LEN] = {};
  165. while (gen_salt(salt, sizeof(salt)) == 0) {
  166. char *crypted = ast_crypt(key, salt);
  167. if (crypted) {
  168. return crypted;
  169. }
  170. }
  171. return NULL;
  172. }