Merge branch 'mysql-password-encryption'
This commit is contained in:
commit
a88c1eed78
@ -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':
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,×);
|
||||
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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user