Whitespace and indentation changes.

Also changed line-endings from DOS CRLF to only LF.
In addition, made functions const correct.
This commit is contained in:
Johan Wikman
2015-11-09 13:55:59 +02:00
parent 14b8dbc4d8
commit 90a8646ac2
2 changed files with 437 additions and 425 deletions

View File

@ -32,20 +32,20 @@
static unsigned char static unsigned char
secrets_randomchar() secrets_randomchar()
{ {
return (char)((rand() % ('~' - ' ')) + ' '); return (char)((rand() % ('~' - ' ')) + ' ');
} }
static int static int
secrets_random_str(unsigned char *output, int len) secrets_random_str(unsigned char *output, int len)
{ {
int i; int i;
srand((unsigned long )time(0L) ^ (unsigned long )output); srand((unsigned long )time(0L) ^ (unsigned long )output);
for ( i = 0; i < len; ++i ) for (i = 0; i < len; ++i)
{ {
output[i] = secrets_randomchar(); output[i] = secrets_randomchar();
} }
return 0; return 0;
} }
/** /**
@ -53,166 +53,173 @@ int i;
* and the AES Init Vector. * and the AES Init Vector.
* If the path parameter is not null the custom path is interpreted as a folder * If the path parameter is not null the custom path is interpreted as a folder
* containing the .secrets file. Otherwise the default location is used. * containing the .secrets file. Otherwise the default location is used.
* @return The keys structure or NULL on error * @return The keys structure or NULL on error
*/ */
static MAXKEYS * static MAXKEYS *
secrets_readKeys(char* path) secrets_readKeys(const char* path)
{ {
char secret_file[PATH_MAX+1]; char secret_file[PATH_MAX+1];
char *home; char *home;
MAXKEYS *keys; MAXKEYS *keys;
struct stat secret_stats; struct stat secret_stats;
int fd; int fd;
int len; int len;
static int reported = 0; static int reported = 0;
if(path != NULL)
snprintf(secret_file, PATH_MAX, "%s/.secrets", path); if (path != NULL)
else {
snprintf(secret_file, PATH_MAX, "%s/.secrets", get_datadir()); snprintf(secret_file, PATH_MAX, "%s/.secrets", path);
/* Try to access secrets file */ }
if (access(secret_file, R_OK) == -1) else
{ {
int eno = errno; snprintf(secret_file, PATH_MAX, "%s/.secrets", get_datadir());
errno = 0; }
if (eno == ENOENT)
{ /* Try to access secrets file */
if (!reported) if (access(secret_file, R_OK) == -1)
{ {
char errbuf[STRERROR_BUFLEN]; int eno = errno;
LOGIF(LM, (skygw_log_write( errno = 0;
LOGFILE_MESSAGE, if (eno == ENOENT)
"Encrypted password file %s can't be accessed " {
"(%s). Password encryption is not used.", if (!reported)
secret_file, {
strerror_r(eno, errbuf, sizeof(errbuf))))); char errbuf[STRERROR_BUFLEN];
reported = 1; LOGIF(LM, (skygw_log_write(
} LOGFILE_MESSAGE,
} "Encrypted password file %s can't be accessed "
else "(%s). Password encryption is not used.",
{ secret_file,
char errbuf[STRERROR_BUFLEN]; strerror_r(eno, errbuf, sizeof(errbuf)))));
LOGIF(LE, (skygw_log_write_flush( reported = 1;
LOGFILE_ERROR, }
"Error : access for secrets file "
"[%s] failed. Error %d, %s.",
secret_file,
eno,
strerror_r(eno, errbuf, sizeof(errbuf)))));
}
return NULL;
} }
else
{
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : access for secrets file "
"[%s] failed. Error %d, %s.",
secret_file,
eno,
strerror_r(eno, errbuf, sizeof(errbuf)))));
}
return NULL;
}
/* open secret file */ /* open secret file */
if ((fd = open(secret_file, O_RDONLY)) < 0) if ((fd = open(secret_file, O_RDONLY)) < 0)
{ {
int eno = errno; int eno = errno;
errno = 0; errno = 0;
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : Failed opening secret " "Error : Failed opening secret "
"file [%s]. Error %d, %s.", "file [%s]. Error %d, %s.",
secret_file, secret_file,
eno, eno,
strerror_r(eno, errbuf, sizeof(errbuf))))); strerror_r(eno, errbuf, sizeof(errbuf)))));
return NULL; return NULL;
} }
/* accessing file details */ /* accessing file details */
if (fstat(fd, &secret_stats) < 0) { if (fstat(fd, &secret_stats) < 0) {
int eno = errno; int eno = errno;
errno = 0; errno = 0;
close(fd); close(fd);
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : fstat for secret file %s " "Error : fstat for secret file %s "
"failed. Error %d, %s.", "failed. Error %d, %s.",
secret_file, secret_file,
eno, eno,
strerror_r(eno, errbuf, sizeof(errbuf))))); strerror_r(eno, errbuf, sizeof(errbuf)))));
return NULL; return NULL;
} }
if (secret_stats.st_size != sizeof(MAXKEYS)) if (secret_stats.st_size != sizeof(MAXKEYS))
{ {
int eno = errno; int eno = errno;
errno = 0; errno = 0;
close(fd); close(fd);
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : Secrets file %s has " "Error : Secrets file %s has "
"incorrect size. Error %d, %s.", "incorrect size. Error %d, %s.",
secret_file, secret_file,
eno, eno,
strerror_r(eno, errbuf, sizeof(errbuf))))); strerror_r(eno, errbuf, sizeof(errbuf)))));
return NULL; return NULL;
} }
if (secret_stats.st_mode != (S_IRUSR|S_IFREG))
{
close(fd);
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Ignoring secrets file "
"%s, invalid permissions.",
secret_file)));
return NULL;
}
if ((keys = (MAXKEYS *)malloc(sizeof(MAXKEYS))) == NULL) if (secret_stats.st_mode != (S_IRUSR|S_IFREG))
{ {
close(fd); close(fd);
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : Memory allocation failed " "Error : Ignoring secrets file "
"for key structure."))); "%s, invalid permissions.",
return NULL; secret_file)));
} return NULL;
}
/** if ((keys = (MAXKEYS *)malloc(sizeof(MAXKEYS))) == NULL)
* Read all data from file. {
* MAXKEYS (secrets.h) is struct for key, _not_ length-related macro. close(fd);
*/ LOGIF(LE, (skygw_log_write_flush(
len = read(fd, keys, sizeof(MAXKEYS)); LOGFILE_ERROR,
"Error : Memory allocation failed "
"for key structure.")));
return NULL;
}
if (len != sizeof(MAXKEYS)) /**
{ * Read all data from file.
int eno = errno; * MAXKEYS (secrets.h) is struct for key, _not_ length-related macro.
errno = 0; */
close(fd); len = read(fd, keys, sizeof(MAXKEYS));
free(keys);
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Read from secrets file "
"%s failed. Read %d, expected %d bytes. Error %d, %s.",
secret_file,
len,
sizeof(MAXKEYS),
eno,
strerror_r(eno, errbuf, sizeof(errbuf)))));
return NULL;
}
/* Close the file */ if (len != sizeof(MAXKEYS))
if (close(fd) < 0) { {
int eno = errno; int eno = errno;
errno = 0; errno = 0;
free(keys); close(fd);
char errbuf[STRERROR_BUFLEN]; free(keys);
LOGIF(LE, (skygw_log_write_flush( char errbuf[STRERROR_BUFLEN];
LOGFILE_ERROR, LOGIF(LE, (skygw_log_write_flush(
"Error : Failed closing the " LOGFILE_ERROR,
"secrets file %s. Error %d, %s.", "Error : Read from secrets file "
secret_file, "%s failed. Read %d, expected %d bytes. Error %d, %s.",
eno, secret_file,
strerror_r(eno, errbuf, sizeof(errbuf))))); len,
return NULL; sizeof(MAXKEYS),
} eno,
ss_dassert(keys != NULL); strerror_r(eno, errbuf, sizeof(errbuf)))));
return keys; return NULL;
}
/* Close the file */
if (close(fd) < 0) {
int eno = errno;
errno = 0;
free(keys);
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Failed closing the "
"secrets file %s. Error %d, %s.",
secret_file,
eno,
strerror_r(eno, errbuf, sizeof(errbuf)))));
return NULL;
}
ss_dassert(keys != NULL);
return keys;
} }
/** /**
@ -224,105 +231,105 @@ static int reported = 0;
* @param secret_file The file with secret keys * @param secret_file The file with secret keys
* @return 0 on success and 1 on failure * @return 0 on success and 1 on failure
*/ */
int secrets_writeKeys(char *path) int secrets_writeKeys(const char *path)
{ {
int fd,randfd; int fd,randfd;
unsigned int randval; unsigned int randval;
MAXKEYS key; MAXKEYS key;
char secret_file[PATH_MAX + 10]; char secret_file[PATH_MAX + 10];
if(strlen(path) > PATH_MAX) if (strlen(path) > PATH_MAX)
{
skygw_log_write(LOGFILE_ERROR,"Error: Pathname too long.");
return 1;
}
snprintf(secret_file,PATH_MAX + 9,"%s/.secrets",path);
secret_file[PATH_MAX + 9] = '\0';
/* Open for writing | Create | Truncate the file for writing */
if ((fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR)) < 0)
{
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : failed opening secret "
"file [%s]. Error %d, %s.",
secret_file,
errno,
strerror_r(errno, errbuf, sizeof(errbuf)))));
return 1;
}
/* Open for writing | Create | Truncate the file for writing */
if ((randfd = open("/dev/random", O_RDONLY)) < 0)
{
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : failed opening /dev/random. Error %d, %s.",
errno,
strerror_r(errno, errbuf, sizeof(errbuf)))));
close(fd);
return 1;
}
if(read(randfd,(void*)&randval,sizeof(unsigned int)) < 1)
{ {
LOGIF(LE, (skygw_log_write_flush( skygw_log_write(LOGFILE_ERROR,"Error: Pathname too long.");
LOGFILE_ERROR, return 1;
"Error : failed to read /dev/random."))); }
close(fd);
close(randfd); snprintf(secret_file,PATH_MAX + 9,"%s/.secrets",path);
return 1; secret_file[PATH_MAX + 9] = '\0';
/* Open for writing | Create | Truncate the file for writing */
if ((fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR)) < 0)
{
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : failed opening secret "
"file [%s]. Error %d, %s.",
secret_file,
errno,
strerror_r(errno, errbuf, sizeof(errbuf)))));
return 1;
}
/* Open for writing | Create | Truncate the file for writing */
if ((randfd = open("/dev/random", O_RDONLY)) < 0)
{
char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : failed opening /dev/random. Error %d, %s.",
errno,
strerror_r(errno, errbuf, sizeof(errbuf)))));
close(fd);
return 1;
}
if (read(randfd,(void*)&randval,sizeof(unsigned int)) < 1)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : failed to read /dev/random.")));
close(fd);
close(randfd);
return 1;
} }
close(randfd); close(randfd);
srand(randval); srand(randval);
secrets_random_str(key.enckey, MAXSCALE_KEYLEN); secrets_random_str(key.enckey, MAXSCALE_KEYLEN);
secrets_random_str(key.initvector, MAXSCALE_IV_LEN); secrets_random_str(key.initvector, MAXSCALE_IV_LEN);
/* Write data */ /* Write data */
if (write(fd, &key, sizeof(key)) < 0) if (write(fd, &key, sizeof(key)) < 0)
{ {
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : failed writing into " "Error : failed writing into "
"secret file [%s]. Error %d, %s.", "secret file [%s]. Error %d, %s.",
secret_file, secret_file,
errno, errno,
strerror_r(errno, errbuf, sizeof(errbuf))))); strerror_r(errno, errbuf, sizeof(errbuf)))));
close(fd); close(fd);
return 1; return 1;
} }
/* close file */ /* close file */
if (close(fd) < 0) if (close(fd) < 0)
{ {
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : failed closing the " "Error : failed closing the "
"secret file [%s]. Error %d, %s.", "secret file [%s]. Error %d, %s.",
secret_file, secret_file,
errno, errno,
strerror_r(errno, errbuf, sizeof(errbuf))))); strerror_r(errno, errbuf, sizeof(errbuf)))));
} }
if( chmod(secret_file, S_IRUSR) < 0) if (chmod(secret_file, S_IRUSR) < 0)
{ {
char errbuf[STRERROR_BUFLEN]; char errbuf[STRERROR_BUFLEN];
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"Error : failed to change the permissions of the" "Error : failed to change the permissions of the"
"secret file [%s]. Error %d, %s.", "secret file [%s]. Error %d, %s.",
secret_file, secret_file,
errno, errno,
strerror_r(errno, errbuf, sizeof(errbuf))))); strerror_r(errno, errbuf, sizeof(errbuf)))));
} }
return 0; return 0;
} }
/** /**
@ -333,83 +340,87 @@ if(strlen(path) > PATH_MAX)
* *
* Note the return is always a malloc'd string that the caller must free * Note the return is always a malloc'd string that the caller must free
* *
* @param crypt The encrypted password * @param crypt The encrypted password
* @return The decrypted password * @return The decrypted password
*/ */
char * char *
decryptPassword(char *crypt) decryptPassword(const char *crypt)
{ {
MAXKEYS *keys; MAXKEYS *keys;
AES_KEY aeskey; AES_KEY aeskey;
unsigned char *plain; unsigned char *plain;
char *ptr; const char *ptr;
unsigned char encrypted[80]; unsigned char encrypted[80];
int enlen; int enlen;
keys = secrets_readKeys(NULL); keys = secrets_readKeys(NULL);
if (!keys) if (!keys)
return strdup(crypt); {
/* return strdup(crypt);
** If the input is not a HEX string return the input }
** it probably was not encrypted /*
*/ ** If the input is not a HEX string return the input
for (ptr = crypt; *ptr; ptr++) ** it probably was not encrypted
{ */
if (!isxdigit(*ptr)) for (ptr = crypt; *ptr; ptr++)
{ {
free(keys); if (!isxdigit(*ptr))
return strdup(crypt); {
} free(keys);
} return strdup(crypt);
}
}
enlen = strlen(crypt) / 2; enlen = strlen(crypt) / 2;
gw_hex2bin(encrypted, crypt, strlen(crypt)); gw_hex2bin(encrypted, crypt, strlen(crypt));
if ((plain = (unsigned char *)malloc(80)) == NULL) if ((plain = (unsigned char *)malloc(80)) == NULL)
{ {
free(keys); free(keys);
return NULL; return NULL;
} }
AES_set_decrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey); AES_set_decrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey);
AES_cbc_encrypt(encrypted, plain, enlen, &aeskey, keys->initvector, AES_DECRYPT); AES_cbc_encrypt(encrypted, plain, enlen, &aeskey, keys->initvector, AES_DECRYPT);
free(keys); free(keys);
return (char *)plain; return (char *)plain;
} }
/** /**
* Encrypt a password that can be stored in the MaxScale configuration file. * Encrypt a password that can be stored in the MaxScale configuration file.
* *
* Note the return is always a malloc'd string that the caller must free * Note the return is always a malloc'd string that the caller must free
* @param path Path the the .secrets file * @param path Path the the .secrets file
* @param password The password to encrypt * @param password The password to encrypt
* @return The encrypted password * @return The encrypted password
*/ */
char * char *
encryptPassword(char* path, char *password) encryptPassword(const char* path, const char *password)
{ {
MAXKEYS *keys; MAXKEYS *keys;
AES_KEY aeskey; AES_KEY aeskey;
int padded_len; int padded_len;
char *hex_output; char *hex_output;
unsigned char padded_passwd[80]; unsigned char padded_passwd[80];
unsigned char encrypted[80]; unsigned char encrypted[80];
if ((keys = secrets_readKeys(path)) == NULL) if ((keys = secrets_readKeys(path)) == NULL)
return NULL; {
return NULL;
}
memset(padded_passwd, 0, 80); memset(padded_passwd, 0, 80);
strncpy((char *)padded_passwd, password, 79); strncpy((char *)padded_passwd, password, 79);
padded_len = ((strlen(password) / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE; padded_len = ((strlen(password) / AES_BLOCK_SIZE) + 1) * AES_BLOCK_SIZE;
AES_set_encrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey); AES_set_encrypt_key(keys->enckey, 8 * MAXSCALE_KEYLEN, &aeskey);
AES_cbc_encrypt(padded_passwd, encrypted, padded_len, &aeskey, keys->initvector, AES_ENCRYPT); AES_cbc_encrypt(padded_passwd, encrypted, padded_len, &aeskey, keys->initvector, AES_ENCRYPT);
hex_output = (char *)malloc(padded_len * 2); hex_output = (char *)malloc(padded_len * 2);
gw_bin2hex(hex_output, encrypted, padded_len); gw_bin2hex(hex_output, encrypted, padded_len);
free(keys); free(keys);
return hex_output; return hex_output;
} }

View File

@ -24,8 +24,8 @@
* @verbatim * @verbatim
* Revision History * Revision History
* *
* Date Who Description * Date Who Description
* 23/06/2013 Massimiliano Pinto Initial implementation * 23/06/2013 Massimiliano Pinto Initial implementation
* *
* @endverbatim * @endverbatim
*/ */
@ -40,18 +40,19 @@
#include <openssl/aes.h> #include <openssl/aes.h>
#define MAXSCALE_KEYLEN 32 #define MAXSCALE_KEYLEN 32
#define MAXSCALE_IV_LEN 16 #define MAXSCALE_IV_LEN 16
/** /**
* The key structure held in the secrets file * The key structure held in the secrets file
*/ */
typedef struct maxkeys { typedef struct maxkeys
unsigned char enckey[MAXSCALE_KEYLEN]; {
unsigned char initvector[MAXSCALE_IV_LEN]; unsigned char enckey[MAXSCALE_KEYLEN];
unsigned char initvector[MAXSCALE_IV_LEN];
} MAXKEYS; } MAXKEYS;
extern int secrets_writeKeys(char *filename); extern int secrets_writeKeys(const char *filename);
extern char *decryptPassword(char *); extern char *decryptPassword(const char *);
extern char *encryptPassword(char*,char *); extern char *encryptPassword(const char*, const char *);
#endif #endif