mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
Fix utils directory breakage.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393675 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
168
main/utils.c
168
main/utils.c
@@ -37,9 +37,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#if defined(HAVE_CRYPT_R)
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#include <mach/mach.h>
|
||||
#elif defined(HAVE_SYS_THR_H)
|
||||
@@ -2367,171 +2364,6 @@ int ast_get_tid(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Max length of a salt string.
|
||||
*
|
||||
* $[1,5,6]$[a–zA–Z0–9./]{1,16}$, plus null terminator
|
||||
*/
|
||||
#define MAX_SALT_LEN 21
|
||||
|
||||
static char salt_chars[] =
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"0123456789"
|
||||
"./";
|
||||
|
||||
/*! Randomly select a character for a salt string */
|
||||
static char gen_salt_char(void)
|
||||
{
|
||||
int which = ast_random_double() * 64;
|
||||
return salt_chars[which];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Generates a salt to try with crypt.
|
||||
*
|
||||
* If given an empty string, will generate a salt for the most secure algorithm
|
||||
* to try with crypt(). If given a previously generated salt, the algorithm will
|
||||
* be lowered by one level of security.
|
||||
*
|
||||
* \param[out] current_salt Output string in which to generate the salt.
|
||||
* This can be an empty string, or the results of a
|
||||
* prior gen_salt call.
|
||||
* \param max_len Length of \a current_salt.
|
||||
* \return 0 on success.
|
||||
* \return Non-zero on error.
|
||||
*/
|
||||
static int gen_salt(char *current_salt, size_t maxlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (maxlen < MAX_SALT_LEN || current_salt == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (current_salt[0]) {
|
||||
case '\0':
|
||||
/* Initial generation; $6$ = SHA-512 */
|
||||
*current_salt++ = '$';
|
||||
*current_salt++ = '6';
|
||||
*current_salt++ = '$';
|
||||
for (i = 0; i < 16; ++i) {
|
||||
*current_salt++ = gen_salt_char();
|
||||
}
|
||||
*current_salt++ = '$';
|
||||
*current_salt++ = '\0';
|
||||
return 0;
|
||||
case '$':
|
||||
switch (current_salt[1]) {
|
||||
case '6':
|
||||
/* Downgrade to SHA-256 */
|
||||
current_salt[1] = '5';
|
||||
return 0;
|
||||
case '5':
|
||||
/* Downgrade to MD5 */
|
||||
current_salt[1] = '1';
|
||||
return 0;
|
||||
case '1':
|
||||
/* Downgrade to traditional crypt */
|
||||
*current_salt++ = gen_salt_char();
|
||||
*current_salt++ = gen_salt_char();
|
||||
*current_salt++ = '\0';
|
||||
return 0;
|
||||
default:
|
||||
/* Unrecognized algorithm */
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
/* Was already as insecure as it gets */
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(HAVE_CRYPT_R)
|
||||
|
||||
char *ast_crypt(const char *key, const char *salt)
|
||||
{
|
||||
struct crypt_data data = {};
|
||||
const char *crypted = crypt_r(key, salt, &data);
|
||||
|
||||
/* Crypt may return success even if it doesn't recognize the salt. But
|
||||
* in those cases it always mangles the salt in some way.
|
||||
*/
|
||||
if (!crypted || !ast_begins_with(crypted, salt)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ast_strdup(crypted);
|
||||
}
|
||||
|
||||
int ast_crypt_validate(const char *key, const char *expected)
|
||||
{
|
||||
struct crypt_data data = {};
|
||||
return strcmp(expected, crypt_r(key, expected, &data)) == 0;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_CRYPT)
|
||||
|
||||
/* crypt is not reentrant. A global mutex is neither ideal nor perfect, but good
|
||||
* enough if crypt_r support is unavailable
|
||||
*/
|
||||
AST_MUTEX_DEFINE_STATIC(crypt_mutex);
|
||||
|
||||
char *ast_crypt(const char *key, const char *salt)
|
||||
{
|
||||
const char *crypted;
|
||||
SCOPED_MUTEX(lock, &crypt_mutex);
|
||||
|
||||
crypted = crypt(key, salt);
|
||||
|
||||
/* Crypt may return success even if it doesn't recognize the salt. But
|
||||
* in those cases it always mangles the salt in some way.
|
||||
*/
|
||||
if (!crypted || !ast_begins_with(crypted, salt)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ast_strdup(crypted);
|
||||
}
|
||||
|
||||
int ast_crypt_validate(const char *key, const char *expected)
|
||||
{
|
||||
SCOPED_MUTEX(lock, &crypt_mutex);
|
||||
return strcmp(expected, crypt(key, expected)) == 0;
|
||||
}
|
||||
|
||||
#else /* No crypt support */
|
||||
|
||||
char *ast_crypt(const char *key, const char *salt)
|
||||
{
|
||||
ast_log(LOG_WARNING,
|
||||
"crypt() support not available; cannot encrypt password\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ast_crypt_validate(const char *key, const char *expected)
|
||||
{
|
||||
ast_log(LOG_WARNING,
|
||||
"crypt() support not available; cannot validate password\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* No crypt support */
|
||||
|
||||
char *ast_crypt_encrypt(const char *key)
|
||||
{
|
||||
char salt[MAX_SALT_LEN] = {};
|
||||
while (gen_salt(salt, sizeof(salt)) == 0) {
|
||||
char *crypted = ast_crypt(key, salt);
|
||||
if (crypted) {
|
||||
return crypted;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
|
||||
{
|
||||
const char *envPATH = getenv("PATH");
|
||||
|
Reference in New Issue
Block a user