Merge branch 'mysql-password-encryption'

This commit is contained in:
Mészáros Mihály 2018-08-16 07:44:48 +02:00
commit a88c1eed78
10 changed files with 484 additions and 127 deletions

View File

@ -17,6 +17,7 @@ Version 4.5.0.8 'dan Eider':
- Update total allocation usage on client shutdown
- fix total and user quota mix-up
- Fixed typos in postinstall.txt (by Prashanth Rajaram)
- MySQL password encryption (by Mustafa Bingül & Erdem Duman)
12/10/2017 Oleg Moskalenko <mom040267@gmail.com>
Version 4.5.0.7 'dan Eider':

View File

@ -86,6 +86,8 @@ Only sha256 is supported as the hash function.
-g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.
-G, --list-realm-options List realm params.
-E, --generate-encrypted-password-aes Generate and print to the standard output
an encrypted form of password with AES-128
Options with required values:
@ -103,6 +105,9 @@ Options with required values:
-u, --user User name.
-r, --realm Realm.
-p, --password Password.
-x, --key-path Generates a 128 bit key into the given path.
-f, --file-key-path Contains a 128 bit key in the given path.
-v, --verify Verify a given base64 encrypted type password.
-o, --origin Origin
--max-bps Set value of realm's max-bps parameter.
--total-quota Set value of realm's total-quota parameter.
@ -158,7 +163,20 @@ $ turnadmin --redis-userdb="<db-connection-string>" -I
List the origin-to-realm relations in PostgreSQL DB for a single realm:
$ turnadmin --psql-userdb="<db-connection-string>" -I -r <realm>
Create new key file for mysql password encryption:
$ turnadmin -E --key-path <key-file>
Create encrypted mysql password:
$ turnadmin -E --file-key-path <key-file> -p <secret>
Verify/decrypt encrypted password:
$ turnadmin --file-key-path <key-file> -v <encrypted>
Help:
$ turnadmin -h

View File

@ -120,6 +120,12 @@ User database settings:
(see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the
command options description).
--secret-key-file If you want to use password as encrpyted in the mysql connection string MySQL encrypted connection, this is key path.
This is the file path which contain secret key of aes encryption while using password encryption.
This attribute should be use if allow-encoding-with-aes set to 1.
--allow-encoding-with-aes If you want to use password as encrpyted in the mysql connection string. Set allow-encoding-with-aes to 1.
If you want to use clearteaxt password in the mysql connection string. Set allow-encoding-with-aes to 0.
You have to enable secret-key-file attribute above as a key location.
-J, --mongo-userdb User database connection string for MongoDB.
This database can be used for long-term credentials mechanism,
and it can store the secret value

View File

@ -276,6 +276,16 @@
#
#mysql-userdb="host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> port=<port> connect_timeout=<seconds> read_timeout=<seconds>"
#If you want to use password as encrpyted in the mysql connection string MySQL encrypted connection, this is key path.
#This is the file path which contain secret key of aes encryption while using password encryption.
#This attribute should be use if allow-encoding-with-aes set to 1.
#secret-key-file=/path/
#If you want to use password as encrpyted in the mysql connection string. Set allow-encoding-with-aes to 1.
#If you want to use clearteaxt password in the mysql connection string. Set allow-encoding-with-aes to 0.
#You have to enable secret-key-file attribute above as a key location.
#allow-encoding-with-aes=1 or 0
# MongoDB database connection string in the case that we are using MongoDB
# as the user database.
# This database can be used for long-term credential mechanism

View File

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "11 December 2017" "" ""
.TH TURN 1 "15 August 2018" "" ""
.SH GENERAL INFORMATION
\fIturnadmin\fP is a TURN administration tool. This tool can be used to manage
@ -139,6 +139,11 @@ Set realm params: max\-bps, total\-quota, user\-quota.
List realm params.
.TP
.B
\fB\-E\fP, \fB\-\-generate\-encrypted\-password\-aes\fP
Generate and print to the standard output
an encrypted form of password with AES\-128
.TP
.B
Options with required values:
.TP
.B
@ -180,6 +185,18 @@ Realm.
Password.
.TP
.B
\fB\-x\fP, \fB\-\-key\-path\fP
Generates a 128 bit key into the given path.
.TP
.B
\fB\-f\fP, \fB\-\-file\-key\-path\fP
Contains a 128 bit key in the given path.
.TP
.B
\fB\-v\fP, \fB\-\-verify\fP
Verify a given base64 encrypted type password.
.TP
.B
\fB\-o\fP, \fB\-\-origin\fP
Origin
.TP
@ -249,6 +266,22 @@ $ \fIturnadmin\fP \fB\-\-redis\-userdb\fP="<db\-connection\-string>" \fB\-I\fP
List the origin\-to\-realm relations in PostgreSQL DB for a single realm:
.PP
$ \fIturnadmin\fP \fB\-\-psql\-userdb\fP="<db\-connection\-string>" \fB\-I\fP \fB\-r\fP <realm>
.PP
Create new key file for mysql password encryption:
.PP
$ \fIturnadmin\fP \fB\-E\fP \fB\-\-key\-path\fP <key\-file>
.PP
Create encrypted mysql password:
.PP
$ \fIturnadmin\fP \fB\-E\fP \fB\-\-file\-key\-path\fP <key\-file> \fB\-p\fP <secret>
.PP
Verify/decrypt encrypted password:
.PP
$ \fIturnadmin\fP \fB\-\-file\-key\-path\fP <key\-file> \fB\-v\fP <encrypted>
.RE
.PP
.RS
.TP
.B
Help:

View File

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "11 December 2017" "" ""
.TH TURN 1 "15 August 2018" "" ""
.SH GENERAL INFORMATION
The \fBTURN Server\fP project contains the source code of a TURN server and TURN client
@ -180,6 +180,18 @@ command \fIoptions\fP description).
.RE
.TP
.B
\fB\-\-secret\-key\-file\fP
If you want to use password as encrpyted in the mysql connection string MySQL encrypted connection, this is key path.
This is the file path which contain secret key of aes encryption while using password encryption.
This attribute should be use if allow\-encoding\-with\-aes set to 1.
.TP
.B
\fB\-\-allow\-encoding\-with\-aes\fP
If you want to use password as encrpyted in the mysql connection string. Set allow\-encoding\-with\-aes to 1.
If you want to use clearteaxt password in the mysql connection string. Set allow\-encoding\-with\-aes to 0.
You have to enable secret\-key\-file attribute above as a key location.
.TP
.B
\fB\-J\fP, \fB\-\-mongo\-userdb\fP
User database connection string for MongoDB.
This database can be used for long\-term credentials mechanism,

View File

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "11 December 2017" "" ""
.TH TURN 1 "15 August 2018" "" ""
.SH GENERAL INFORMATION
A set of turnutils_* programs provides some utility functionality to be used

View File

@ -35,6 +35,7 @@
#if !defined(TURN_NO_MYSQL)
#include <mysql.h>
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static int donot_print_connection_success = 0;
@ -72,6 +73,33 @@ static void MyconninfoFree(Myconninfo *co) {
ns_bzero(co,sizeof(Myconninfo));
}
}
struct ctr_state state;
char* decryptPassword(char* in, const unsigned char* mykey){
char *out;
unsigned char iv[8] = {0}; //changed
AES_KEY key;
unsigned char outdata[256]; //changed
AES_set_encrypt_key(mykey, 128, &key);
int newTotalSize=decodedTextSize(in);
int bytes_to_decode = strlen(in);
unsigned char *encryptedText = base64decode(in, bytes_to_decode); //changed
char last[1024]="";
init_ctr(&state, iv);
memset(outdata,'\0', sizeof(outdata));
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
CRYPTO_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num,(block128_f)AES_encrypt);
#else
AES_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num);
#endif
strcat(last,(char*)outdata);
out=malloc(sizeof(char)*strlen(last));
strcpy(out,last);
return out;
}
static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
Myconninfo *co = (Myconninfo*)turn_malloc(sizeof(Myconninfo));
@ -234,6 +262,11 @@ static MYSQL *get_mydb_connection(void) {
if(co->ca || co->capath || co->cert || co->cipher || co->key) {
mysql_ssl_set(mydbconnection, co->key, co->cert, co->ca, co->capath, co->cipher);
}
if(turn_params.allow_encoding){
co->password = decryptPassword(co->password, turn_params.secret_key);
}
MYSQL *conn = mysql_real_connect(mydbconnection, co->host, co->user, co->password, co->dbname, co->port, NULL, CLIENT_IGNORE_SIGPIPE);
if(!conn) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection: <%s>, runtime error\n",pud->userdb);
@ -245,6 +278,10 @@ static MYSQL *get_mydb_connection(void) {
mydbconnection=NULL;
} else if(!donot_print_connection_success) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL DB connection success: %s\n",pud->userdb);
if(turn_params.allow_encoding)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is secure.\n");
else
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is not secure.\n");
donot_print_connection_success = 1;
}
}

View File

@ -116,7 +116,7 @@ DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,1,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,NULL,NULL,NULL
},
{NULL, 0},{NULL, 0},
NEV_UNKNOWN,
NEV_UNKNOWN,
{ "Unknown", "UDP listening socket per session", "UDP thread per network endpoint", "UDP thread per CPU core" },
//////////////// Relay servers //////////////////////////////////
LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"",
@ -151,7 +151,11 @@ TURN_CREDENTIALS_NONE, /* ct */
///////////// Users DB //////////////
{ (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL, {NULL,0}} },
///////////// CPUs //////////////////
DEFAULT_CPUS_NUMBER
DEFAULT_CPUS_NUMBER,
///////// Encryption /////////
"", /* secret_key_file */
"", /* secret_key */
0 /* allow_encoding */
};
//////////////// OpenSSL Init //////////////////////
@ -487,12 +491,18 @@ static char Usage[] = "Usage: turnserver [options]\n"
" This database can be used for long-term credentials mechanism users,\n"
" and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
" The connection string my be space-separated list of parameters:\n"
" \"host=<ip-addr> dbname=<database-name> user=<database-user> \\\n password=<database-user-password> port=<db-port> connect_timeout=<seconds> read_timeout=<seconds>\".\n\n"
" \"host=<ip-addr> dbname=<database-name> user=<database-user> \\\n password=<database-user-password> port=<db-port> connect_timeout=<seconds> read_timeout=<seconds>\".\n\n"
" The connection string parameters for the secure communications (SSL):\n"
" ca, capath, cert, key, cipher\n"
" (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the\n"
" command options description).\n\n"
" All connection-string parameters are optional.\n\n"
"--secret-key-file <filename> If you want to use password as encrpyted in the mysql connection string MySQL encrypted connection, this is key path.\n"
" This is the file path which contain secret key of aes encryption while using password encryption.\n"
" This attribute should be use if allow-encoding-with-aes set to 1.\n"
"--allow-encoding-with-aes <1/0> If you want to use password as encrpyted in the mysql connection string. Set allow-encoding-with-aes to 1.\n"
" If you want to use clearteaxt password in the mysql connection string. Set allow-encoding-with-aes to 0.\n"
" You have to enable secret-key-file attribute above as a key location.\n"
#endif
#if !defined(TURN_NO_MONGO)
" -J, --mongo-userdb <connection-string> MongoDB connection string, if used (default - empty, no MongoDB used).\n"
@ -588,10 +598,10 @@ static char Usage[] = "Usage: turnserver [options]\n"
" See the docs for more information.\n"
" -C, --rest-api-separator <SYMBOL> This is the timestamp/username separator symbol (character) in TURN REST API.\n"
" The default value is ':'.\n"
" --max-allocate-timeout=<seconds> Max time, in seconds, allowed for full allocation establishment. Default is 60.\n"
" --allowed-peer-ip=<ip[-ip]> Specifies an ip or range of ips that are explicitly allowed to connect to the \n"
" --max-allocate-timeout=<seconds> Max time, in seconds, allowed for full allocation establishment. Default is 60.\n"
" --allowed-peer-ip=<ip[-ip]> Specifies an ip or range of ips that are explicitly allowed to connect to the \n"
" turn server. Multiple allowed-peer-ip can be set.\n"
" --denied-peer-ip=<ip[-ip]> Specifies an ip or range of ips that are not allowed to connect to the turn server.\n"
" --denied-peer-ip=<ip[-ip]> Specifies an ip or range of ips that are not allowed to connect to the turn server.\n"
" Multiple denied-peer-ip can be set.\n"
" --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n"
" Default is /var/run/turnserver.pid (if superuser account is used) or\n"
@ -650,6 +660,8 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
" -I, --list-origins List origin-to-realm relations.\n"
" -g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.\n"
" -G, --list-realm-options List realm params.\n"
" -E, --generate-encrypted-password-aes Generate and print to the standard\n"
" output an encrypted form of password with AES-128\n"
"\nOptions with mandatory values:\n\n"
#if !defined(TURN_NO_SQLITE)
" -b, --db, --userdb SQLite database file, default value is /var/db/turndb or\n"
@ -670,6 +682,9 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
" -u, --user Username\n"
" -r, --realm Realm\n"
" -p, --password Password\n"
" -x, --key-path Generates a 128 bit key into the given path.\n"
" -f, --file-key-path Contains a 128 bit key in the given path.\n"
" -v, --verify Verify a given base64 encrypted type password.\n"
#if !defined(TURN_NO_SQLITE) || !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || !defined(TURN_NO_HIREDIS)
" -o, --origin Origin\n"
#endif
@ -682,8 +697,8 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
" -h, --help Help\n";
#define OPTIONS "c:d:p:L:E:X:i:m:l:r:u:b:B:e:M:J:N:O:q:Q:s:C:vVofhznaAS"
#define ADMIN_OPTIONS "PgGORIHKYlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h"
#define ADMIN_OPTIONS "PEgGORIHKYlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h:x:v:f:"
enum EXTRA_OPTS {
NO_UDP_OPT=256,
@ -751,7 +766,9 @@ enum EXTRA_OPTS {
SERVER_NAME_OPT,
OAUTH_OPT,
PROD_OPT,
NO_HTTP_OPT
NO_HTTP_OPT,
SECRET_KEY_OPT,
ALLOW_ENCODING_OPT
};
struct myoption {
@ -870,11 +887,14 @@ static const struct myoption long_options[] = {
{ "no-tlsv1", optional_argument, NULL, NO_TLSV1_OPT },
{ "no-tlsv1_1", optional_argument, NULL, NO_TLSV1_1_OPT },
{ "no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT },
{ "secret-key-file", required_argument, NULL, SECRET_KEY_OPT },
{ "allow-encoding-with-aes", required_argument, NULL, ALLOW_ENCODING_OPT},
{ NULL, no_argument, NULL, 0 }
};
static const struct myoption admin_long_options[] = {
{"generate-encrypted-password", no_argument, NULL, 'P' },
{"generate-encrypted-password-aes", no_argument, NULL, 'E'},
{ "key", no_argument, NULL, 'k' },
{ "add", no_argument, NULL, 'a' },
{ "delete", no_argument, NULL, 'd' },
@ -906,6 +926,9 @@ static const struct myoption admin_long_options[] = {
{ "user", required_argument, NULL, 'u' },
{ "realm", required_argument, NULL, 'r' },
{ "password", required_argument, NULL, 'p' },
{ "file-key-path", required_argument, NULL, 'f' },
{ "verify", required_argument, NULL, 'v' },
{ "key-path", required_argument, NULL, 'x'},
{ "add-origin", no_argument, NULL, 'O' },
{ "del-origin", no_argument, NULL, 'R' },
{ "list-origins", required_argument, NULL, 'I' },
@ -919,6 +942,142 @@ static const struct myoption admin_long_options[] = {
{ NULL, no_argument, NULL, 0 }
};
struct ctr_state state;
int init_ctr(struct ctr_state *state, const unsigned char iv[8]){
state->num = 0;
memset(state->ecount, 0, 16);
memset(state->ivec + 8, 0, 8);
memcpy(state->ivec, iv, 8);
return 1;
}
unsigned char *base64encode (const void *b64_encode_this, int encode_this_many_bytes){
BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data.
b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO.
mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO.
BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain.
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less.
BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data.
BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters.
BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure.
BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed.
BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null.
(*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail.
return (unsigned char*)(*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct).
}
void encrypt_aes_128(unsigned char* in, const unsigned char* mykey){
int j=0,k=0;
int totalSize=0;
AES_KEY key;
unsigned char iv[8] = {0}; //changed
unsigned char out[1024]; //changed
AES_set_encrypt_key(mykey, 128, &key);
char total[256];
int size=0;
init_ctr(&state, iv);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
CRYPTO_ctr128_encrypt(in, out, strlen((char*)in), &key, state.ivec, state.ecount, &state.num, (block128_f)AES_encrypt);
#else
AES_ctr128_encrypt(in, out, strlen((char*)in), &key, state.ivec, state.ecount, &state.num);
#endif
totalSize += strlen((char*)in);
size = strlen((char*)in);
for (j = 0; j< size; j++) {
total[k++]=out[j];
}
unsigned char *base64_encoded = base64encode(total, totalSize);
printf("%s\n",base64_encoded);
}
void generate_aes_128_key(char* filePath, unsigned char* returnedKey){
int i;
int part;
FILE* fptr;
char key[16];
struct timespec times;
clock_gettime(CLOCK_REALTIME,&times);
srand(times.tv_nsec);
for (i = 0; i < 16; i++) {
part = (rand() % 3);
if(part == 0){
key[i] = (rand() % 10) + 48;
}
else if(part == 1){
key[i] = (rand() % 26) + 65;
}
else if(part == 2){
key[i] = (rand() % 26) + 97;
}
}
fptr = fopen(filePath, "w");
for(i = 0; i < 16; i++){
fputc(key[i], fptr);
}
strcpy((char*)returnedKey, key);
fclose(fptr);
}
unsigned char *base64decode (const void *b64_decode_this, int decode_this_many_bytes){
BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
unsigned char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null.
b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO.
mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO.
BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source.
BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain.
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines.
int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written.
while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte.
decoded_byte_index++; //Increment the index until read of BIO decoded data is complete.
} //Once we're done reading decoded data, BIO_read returns -1 even though there's no error.
BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
return base64_decoded; //Returns base-64 decoded data with trailing null terminator.
}
int decodedTextSize(char *input){
int i=0;
int result=0,padding=0;
int size=strlen(input);
for (i = 0; i < size; ++i) {
if(input[i]=='='){
padding++;
}
}
result=(strlen(input)/4*3)-padding;
return result;
}
void decrypt_aes_128(char* in, const unsigned char* mykey){
unsigned char iv[8] = {0};
AES_KEY key;
unsigned char outdata[256];
AES_set_encrypt_key(mykey, 128, &key);
int newTotalSize=decodedTextSize(in);
int bytes_to_decode = strlen(in);
unsigned char *encryptedText = base64decode(in, bytes_to_decode);
char last[1024]="";
init_ctr(&state, iv);
memset(outdata,'\0', sizeof(outdata));
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
CRYPTO_ctr128_encrypt(encryptedText,outdata,newTotalSize,&key, state.ivec, state.ecount, &state.num, (block128_f)AES_encrypt);
#else
AES_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num);
#endif
strcat(last,(char*)outdata);
printf("%s\n",last);
}
static int get_int_value(const char* s, int default_value)
{
if (!s || !(s[0]))
@ -1305,6 +1464,12 @@ static void set_option(int c, char *value)
case DH_FILE_OPT:
STRCPY(turn_params.dh_file,value);
break;
case SECRET_KEY_OPT:
STRCPY(turn_params.secret_key_file,value);
break;
case ALLOW_ENCODING_OPT:
turn_params.allow_encoding = atoi(value);
break;
case PKEY_FILE_OPT:
STRCPY(turn_params.pkey_file,value);
break;
@ -1492,6 +1657,8 @@ static int adminmain(int argc, char **argv)
TURNADMIN_COMMAND_TYPE ct = TA_COMMAND_UNKNOWN;
int is_admin = 0;
FILE* fptr;
unsigned char generated_key[16]; //changed
u08bits user[STUN_MAX_USERNAME_SIZE+1]="\0";
u08bits realm[STUN_MAX_REALM_SIZE+1]="\0";
@ -1504,84 +1671,88 @@ static int adminmain(int argc, char **argv)
uo.u.m = admin_long_options;
int print_enc_password = 0;
int print_enc_aes_password = 0;
while (((c = getopt_long(argc, argv, ADMIN_OPTIONS, uo.u.o, NULL)) != -1)) {
switch (c){
case 'P':
if(pwd[0]) {
char result[257];
generate_new_enc_password((char*)pwd, result);
printf("%s\n",result);
exit(0);
}
print_enc_password = 1;
break;
case 'g':
ct = TA_SET_REALM_OPTION;
break;
case 'G':
ct = TA_LIST_REALM_OPTIONS;
break;
case ADMIN_USER_QUOTA_OPT:
po.user_quota = (vint)atoi(optarg);
break;
case ADMIN_TOTAL_QUOTA_OPT:
po.total_quota = (vint)atoi(optarg);
break;
case ADMIN_MAX_BPS_OPT:
po.max_bps = (vint)atoi(optarg);
break;
case 'O':
ct = TA_ADD_ORIGIN;
break;
case 'R':
ct = TA_DEL_ORIGIN;
break;
case 'I':
ct = TA_LIST_ORIGINS;
break;
case 'o':
STRCPY(origin,optarg);
break;
case 'k':
ct = TA_PRINT_KEY;
break;
case 'a':
ct = TA_UPDATE_USER;
break;
case 'd':
ct = TA_DELETE_USER;
break;
case 'A':
ct = TA_UPDATE_USER;
is_admin = 1;
break;
case 'D':
ct = TA_DELETE_USER;
is_admin = 1;
break;
case 'l':
ct = TA_LIST_USERS;
break;
case 'L':
ct = TA_LIST_USERS;
is_admin = 1;
break;
case 's':
ct = TA_SET_SECRET;
STRCPY(secret,optarg);
break;
case 'S':
ct = TA_SHOW_SECRET;
break;
case 'X':
ct = TA_DEL_SECRET;
if(optarg)
STRCPY(secret,optarg);
break;
case DEL_ALL_AUTH_SECRETS_OPT:
ct = TA_DEL_SECRET;
break;
case 'P':
if(pwd[0]) {
char result[257];
generate_new_enc_password((char*)pwd, result);
printf("%s\n",result);
exit(0);
}
print_enc_password = 1;
break;
case 'E':
print_enc_aes_password = 1;
break;
case 'g':
ct = TA_SET_REALM_OPTION;
break;
case 'G':
ct = TA_LIST_REALM_OPTIONS;
break;
case ADMIN_USER_QUOTA_OPT:
po.user_quota = (vint)atoi(optarg);
break;
case ADMIN_TOTAL_QUOTA_OPT:
po.total_quota = (vint)atoi(optarg);
break;
case ADMIN_MAX_BPS_OPT:
po.max_bps = (vint)atoi(optarg);
break;
case 'O':
ct = TA_ADD_ORIGIN;
break;
case 'R':
ct = TA_DEL_ORIGIN;
break;
case 'I':
ct = TA_LIST_ORIGINS;
break;
case 'o':
STRCPY(origin,optarg);
break;
case 'k':
ct = TA_PRINT_KEY;
break;
case 'a':
ct = TA_UPDATE_USER;
break;
case 'd':
ct = TA_DELETE_USER;
break;
case 'A':
ct = TA_UPDATE_USER;
is_admin = 1;
break;
case 'D':
ct = TA_DELETE_USER;
is_admin = 1;
break;
case 'l':
ct = TA_LIST_USERS;
break;
case 'L':
ct = TA_LIST_USERS;
is_admin = 1;
break;
case 's':
ct = TA_SET_SECRET;
STRCPY(secret,optarg);
break;
case 'S':
ct = TA_SHOW_SECRET;
break;
case 'X':
ct = TA_DEL_SECRET;
if(optarg)
STRCPY(secret,optarg);
break;
case DEL_ALL_AUTH_SECRETS_OPT:
ct = TA_DEL_SECRET;
break;
#if !defined(TURN_NO_SQLITE)
case 'b':
STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg);
@ -1612,45 +1783,67 @@ static int adminmain(int argc, char **argv)
turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS;
break;
#endif
case 'u':
STRCPY(user,optarg);
if(!is_secure_username((u08bits*)user)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user);
exit(-1);
}
if(SASLprep((u08bits*)user)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user);
exit(-1);
}
break;
case 'r':
set_default_realm_name(optarg);
STRCPY(realm,optarg);
if(SASLprep((u08bits*)realm)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm);
exit(-1);
}
break;
case 'p':
STRCPY(pwd,optarg);
if(SASLprep((u08bits*)pwd)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd);
exit(-1);
}
if(print_enc_password) {
char result[257];
generate_new_enc_password((char*)pwd, result);
printf("%s\n",result);
exit(0);
}
break;
case 'h':
printf("\n%s\n", AdminUsage);
exit(0);
break;
default:
fprintf(stderr,"\n%s\n", AdminUsage);
exit(-1);
case 'u':
STRCPY(user,optarg);
if(!is_secure_username((u08bits*)user)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user);
exit(-1);
}
if(SASLprep((u08bits*)user)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user);
exit(-1);
}
break;
case 'r':
set_default_realm_name(optarg);
STRCPY(realm,optarg);
if(SASLprep((u08bits*)realm)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm);
exit(-1);
}
break;
case 'p':
STRCPY(pwd,optarg);
if(SASLprep((u08bits*)pwd)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd);
exit(-1);
}
if(print_enc_password) {
char result[257];
generate_new_enc_password((char*)pwd, result);
printf("%s\n",result);
exit(0);
}
if(print_enc_aes_password){
encrypt_aes_128(pwd, generated_key);
exit(0);
}
break;
case 'x':
generate_aes_128_key(optarg, generated_key);
exit(0);
break;
case 'f':
fptr = fopen((char*)optarg, "r");
if(fptr == NULL){
printf("No such file like %s\n", (char*)optarg);
}
else{
fseek (fptr, 0, SEEK_SET);
fread (generated_key, sizeof(char), 16, fptr);
fclose (fptr);
}
break;
case 'v':
decrypt_aes_128((char*)optarg, generated_key);
exit(0);
case 'h':
printf("\n%s\n", AdminUsage);
exit(0);
break;
default:
fprintf(stderr,"\n%s\n", AdminUsage);
exit(-1);
}
}
@ -1950,6 +2143,10 @@ int main(int argc, char **argv)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name);
if(turn_params.allow_encoding){
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "allow-encoding-with-aes activated.\n");
}
if(turn_params.oauth && turn_params.oauth_server_name[0]) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name);
}
@ -2652,6 +2849,21 @@ static void set_ctx(SSL_CTX** out, const char *protocol, const SSL_METHOD* metho
}
}
{//secret key
if(turn_params.secret_key_file[0]) {
FILE *f = fopen(turn_params.secret_key_file, "r");
if (!f) {
perror("Cannot open Secret-Key file");
} else {
fseek (f, 0, SEEK_SET);
fread (turn_params.secret_key, sizeof(char), 16, f);
fclose (f);
}
}
}
{
int op = 0;

View File

@ -77,6 +77,11 @@
#include "ns_ioalib_impl.h"
#include <openssl/aes.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/modes.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -309,6 +314,11 @@ typedef struct _turn_params_ {
unsigned long cpus;
///////// Encryption /////////
char secret_key_file[1025];
unsigned char secret_key[1025];
int allow_encoding;
} turn_params_t;
extern turn_params_t turn_params;
@ -357,6 +367,24 @@ void set_bps_capacity(band_limit_t value);
band_limit_t get_max_bps(void);
void set_max_bps(band_limit_t value);
///////// AES ENCRYPTION AND DECRYPTION ////////
struct ctr_state {
unsigned char ivec[16];
unsigned int num;
unsigned char ecount[16];
};
void generate_aes_128_key(char* filePath, unsigned char* returnedKey);
unsigned char *base64encode (const void *b64_encode_this, int encode_this_many_bytes);
void encrypt_aes_128(unsigned char* in, const unsigned char* mykey);
unsigned char *base64decode (const void *b64_decode_this, int decode_this_many_bytes);
void decrypt_aes_128(char* in, const unsigned char* mykey);
int decodedTextSize(char *input);
char* decryptPassword(char* in, const unsigned char* mykey);
int init_ctr(struct ctr_state *state, const unsigned char iv[8]);
///////////////////////////////
#ifdef __cplusplus