working on oauth
This commit is contained in:
parent
064aca0fa7
commit
6aa1af102c
@ -1,6 +1,13 @@
|
||||
08/22/2014 Oleg Moskalenko <mom040267@gmail.com>
|
||||
Version 4.2.1.1 'Monza':
|
||||
- oAuth security implementation. (TODO)
|
||||
- oAuth security implementation:
|
||||
TODO:
|
||||
- clients's check_integrity method();
|
||||
- security dialog;
|
||||
- authorization process - test;
|
||||
- access-token must be cached and included only in ALLOCATE and REFRESH;
|
||||
- token timeout;
|
||||
- kid timeout;
|
||||
- TLS renegotiation DoS attack prevention implemented;
|
||||
- FQDN as relay-ip and listener-ip parameters (issue 6)
|
||||
(patch provided by Iñaki Baz Castillo);
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
/////////////// extern definitions /////////////////////
|
||||
|
||||
@ -98,7 +99,10 @@ band_limit_t bps = 0;
|
||||
int dual_allocation = 0;
|
||||
|
||||
int oauth = 0;
|
||||
oauth_key_data_raw okdr = {
|
||||
oauth_key okey;
|
||||
oauth_token otoken;
|
||||
|
||||
static oauth_key_data_raw okdr = {
|
||||
"north","Y2FybGVvbg==",0,0,"SHA-256","AES-256-CBC","","HMAC-SHA-256-128",""
|
||||
};
|
||||
|
||||
@ -212,8 +216,26 @@ int main(int argc, char **argv)
|
||||
|
||||
while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:ZvsyhcxXgtTSAPDNOUHMRIGBJ")) != -1) {
|
||||
switch (c){
|
||||
case 'J':
|
||||
case 'J': {
|
||||
|
||||
oauth = 1;
|
||||
|
||||
if(use_short_term) {
|
||||
fprintf(stderr,"Short-term mechanism cannot be used together with oAuth.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
oauth_key_data okd;
|
||||
convert_oauth_key_data_raw(&okdr, &okd);
|
||||
|
||||
char err_msg[1025] = "\0";
|
||||
size_t err_msg_size = sizeof(err_msg) - 1;
|
||||
|
||||
if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) {
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
bps = (band_limit_t)atol(optarg);
|
||||
@ -271,6 +293,10 @@ int main(int argc, char **argv)
|
||||
dual_allocation = 1;
|
||||
break;
|
||||
case 'A':
|
||||
if(oauth) {
|
||||
fprintf(stderr,"Short-term mechanism cannot be used together with oAuth.\n");
|
||||
exit(-1);
|
||||
}
|
||||
use_short_term = 1;
|
||||
break;
|
||||
case 'u':
|
||||
@ -375,6 +401,23 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if(oauth) {
|
||||
|
||||
otoken.enc_block.lifetime = 0;
|
||||
otoken.enc_block.timestamp = 0;
|
||||
|
||||
switch(shatype) {
|
||||
case SHATYPE_SHA256:
|
||||
otoken.enc_block.key_length = 32;
|
||||
break;
|
||||
default:
|
||||
otoken.enc_block.key_length = 20;
|
||||
break;
|
||||
};
|
||||
|
||||
RAND_bytes((unsigned char *)(otoken.enc_block.mac_key), otoken.enc_block.key_length);
|
||||
}
|
||||
|
||||
if(g_use_auth_secret_with_timestamp) {
|
||||
|
||||
if(use_short_term) {
|
||||
|
||||
@ -80,6 +80,9 @@ typedef struct {
|
||||
int broken;
|
||||
u08bits nonce[STUN_MAX_NONCE_SIZE+1];
|
||||
u08bits realm[STUN_MAX_REALM_SIZE+1];
|
||||
/* oAuth */
|
||||
int oauth;
|
||||
u08bits server_name[STUN_MAX_SERVER_NAME_SIZE+1];
|
||||
/* RFC 6062 */
|
||||
app_tcp_conn_info **tcp_conn;
|
||||
size_t tcp_conn_number;
|
||||
|
||||
@ -433,13 +433,8 @@ static int clnet_allocate(int verbose,
|
||||
allocate_finished = 1;
|
||||
|
||||
if(clnet_info->nonce[0] || use_short_term) {
|
||||
SHATYPE sht = clnet_info->shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
message.buf, (size_t)(message.len), g_uname,
|
||||
clnet_info->realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in allocate message received from server\n");
|
||||
if(check_integrity(clnet_info, &message)<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
@ -524,13 +519,8 @@ static int clnet_allocate(int verbose,
|
||||
if(err_code == 300) {
|
||||
|
||||
if(clnet_info->nonce[0] || use_short_term) {
|
||||
SHATYPE sht = clnet_info->shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
message.buf, (size_t)(message.len), g_uname,
|
||||
clnet_info->realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in allocate message received from server\n");
|
||||
if(check_integrity(clnet_info, &message)<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ioa_addr alternate_server;
|
||||
@ -795,13 +785,8 @@ static int turn_channel_bind(int verbose, uint16_t *chn,
|
||||
cb_received = 1;
|
||||
|
||||
if(clnet_info->nonce[0] || use_short_term) {
|
||||
SHATYPE sht = clnet_info->shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
message.buf, (size_t)(message.len), g_uname,
|
||||
clnet_info->realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in channel bind message received from server\n");
|
||||
if(check_integrity(clnet_info, &message)<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
@ -909,13 +894,8 @@ static int turn_create_permission(int verbose, app_ur_conn_info *clnet_info,
|
||||
cp_received = 1;
|
||||
|
||||
if(clnet_info->nonce[0] || use_short_term) {
|
||||
SHATYPE sht = clnet_info->shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
message.buf, (size_t)(message.len), g_uname,
|
||||
clnet_info->realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in create permission message received from server\n");
|
||||
if(check_integrity(clnet_info, &message)<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
@ -1495,13 +1475,8 @@ static int turn_tcp_connection_bind(int verbose, app_ur_conn_info *clnet_info, a
|
||||
if (stun_is_success_response(&message)) {
|
||||
|
||||
if(clnet_info->nonce[0] || use_short_term) {
|
||||
SHATYPE sht = clnet_info->shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
message.buf, (size_t)(message.len), g_uname,
|
||||
clnet_info->realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in connect bind message received from server\n");
|
||||
if(check_integrity(clnet_info, &message)<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(stun_get_method(&message)!=STUN_METHOD_CONNECTION_BIND)
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static int verbose_packets=0;
|
||||
|
||||
@ -510,13 +511,9 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
} else if (stun_is_indication(&(elem->in_buffer))) {
|
||||
|
||||
if(use_short_term) {
|
||||
SHATYPE sht = elem->pinfo.shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
elem->in_buffer.buf, (size_t)(elem->in_buffer.len), g_uname,
|
||||
elem->pinfo.realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in indication message 0x%x received from server\n",(unsigned int)stun_get_method(&(elem->in_buffer)));
|
||||
|
||||
if(check_integrity(&(elem->pinfo), &(elem->in_buffer))<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t method = stun_get_method(&elem->in_buffer);
|
||||
@ -569,13 +566,8 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
} else if (stun_is_success_response(&(elem->in_buffer))) {
|
||||
|
||||
if(elem->pinfo.nonce[0] || use_short_term) {
|
||||
SHATYPE sht = elem->pinfo.shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
elem->in_buffer.buf, (size_t)(elem->in_buffer.len), g_uname,
|
||||
elem->pinfo.realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in success message 0x%x received from server\n",(unsigned int)stun_get_method(&(elem->in_buffer)));
|
||||
if(check_integrity(&(elem->pinfo), &(elem->in_buffer))<0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) {
|
||||
@ -1437,15 +1429,48 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message)
|
||||
return -1;
|
||||
}
|
||||
} else if(clnet_info->nonce[0]) {
|
||||
if(stun_attr_add_integrity_by_user_str(message->buf, (size_t*)&(message->len), g_uname,
|
||||
|
||||
if(oauth && clnet_info->oauth) {
|
||||
encoded_oauth_token etoken;
|
||||
u08bits nonce[12];
|
||||
RAND_bytes((unsigned char*)nonce,12);
|
||||
if(encode_oauth_token(clnet_info->server_name, &etoken, &okey, &otoken, nonce)<0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot encode token\n");
|
||||
return -1;
|
||||
}
|
||||
stun_attr_add_str(message->buf, (size_t*)&(message->len), STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN,
|
||||
(const u08bits*)etoken.token, (int)etoken.size);
|
||||
|
||||
hmackey_t key;
|
||||
ns_bcopy(otoken.enc_block.mac_key,key,otoken.enc_block.key_length);
|
||||
if(stun_attr_add_integrity_by_key_str(message->buf, (size_t*)&(message->len), g_uname,
|
||||
clnet_info->realm, key, clnet_info->nonce, clnet_info->shatype)<0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if(stun_attr_add_integrity_by_user_str(message->buf, (size_t*)&(message->len), g_uname,
|
||||
clnet_info->realm, g_upwd, clnet_info->nonce, clnet_info->shatype)<0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n");
|
||||
return -1;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO," Cannot add integrity to the message\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message)
|
||||
{
|
||||
SHATYPE sht = clnet_info->shatype;
|
||||
if(stun_check_message_integrity_str(get_turn_credentials_type(),
|
||||
message->buf, (size_t)(message->len), g_uname,
|
||||
clnet_info->realm, g_upwd, sht)<1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Wrong integrity in a message received from server\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
||||
|
||||
@ -87,7 +87,8 @@ extern int dual_allocation;
|
||||
extern char origin[STUN_MAX_ORIGIN_SIZE+1];
|
||||
|
||||
extern int oauth;
|
||||
extern oauth_key_data_raw okdr;
|
||||
extern oauth_key okey;
|
||||
extern oauth_token otoken;
|
||||
|
||||
#define is_TCP_relay() (relay_transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)
|
||||
|
||||
@ -103,6 +104,7 @@ void client_input_handler(evutil_socket_t fd, short what, void* arg);
|
||||
turn_credential_type get_turn_credentials_type(void);
|
||||
|
||||
int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message);
|
||||
int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message);
|
||||
|
||||
void recalculate_restapi_hmac(void);
|
||||
|
||||
|
||||
@ -1449,13 +1449,8 @@ int stun_attr_add_integrity_str(turn_credential_type ct, u08bits *buf, size_t *l
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, u08bits *upwd, u08bits *nonce, SHATYPE shatype)
|
||||
int stun_attr_add_integrity_by_key_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, hmackey_t key, u08bits *nonce, SHATYPE shatype)
|
||||
{
|
||||
hmackey_t key;
|
||||
|
||||
if(stun_produce_integrity_key_str(uname, realm, upwd, key, shatype)<0)
|
||||
return -1;
|
||||
|
||||
if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, strlen((s08bits*)uname))<0)
|
||||
return -1;
|
||||
|
||||
@ -1469,6 +1464,16 @@ int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *unam
|
||||
return stun_attr_add_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, len, key, p, shatype);
|
||||
}
|
||||
|
||||
int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, u08bits *upwd, u08bits *nonce, SHATYPE shatype)
|
||||
{
|
||||
hmackey_t key;
|
||||
|
||||
if(stun_produce_integrity_key_str(uname, realm, upwd, key, shatype)<0)
|
||||
return -1;
|
||||
|
||||
return stun_attr_add_integrity_by_key_str(buf, len, uname, realm, key, nonce, shatype);
|
||||
}
|
||||
|
||||
int stun_attr_add_integrity_by_user_short_term_str(u08bits *buf, size_t *len, u08bits *uname, st_password_t pwd, SHATYPE shatype)
|
||||
{
|
||||
if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, strlen((s08bits*)uname))<0)
|
||||
|
||||
@ -183,6 +183,7 @@ void print_bin_func(const char *name, size_t len, const void *s, const char *fun
|
||||
int stun_check_message_integrity_by_key_str(turn_credential_type ct, u08bits *buf, size_t len, hmackey_t key, st_password_t pwd, SHATYPE shatype, int *too_weak);
|
||||
int stun_check_message_integrity_str(turn_credential_type ct, u08bits *buf, size_t len, u08bits *uname, u08bits *realm, u08bits *upwd, SHATYPE shatype);
|
||||
int stun_attr_add_integrity_str(turn_credential_type ct, u08bits *buf, size_t *len, hmackey_t key, st_password_t pwd, SHATYPE shatype);
|
||||
int stun_attr_add_integrity_by_key_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, hmackey_t key, u08bits *nonce, SHATYPE shatype);
|
||||
int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, u08bits *upwd, u08bits *nonce, SHATYPE shatype);
|
||||
int stun_attr_add_integrity_by_user_short_term_str(u08bits *buf, size_t *len, u08bits *uname, st_password_t pwd, SHATYPE shatype);
|
||||
size_t get_hmackey_size(SHATYPE shatype);
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
#define STUN_MAX_USERNAME_SIZE (513)
|
||||
#define STUN_MAX_REALM_SIZE (127)
|
||||
#define STUN_MAX_NONCE_SIZE (127)
|
||||
#define STUN_MAX_SERVER_NAME_SIZE (1025)
|
||||
#define STUN_MAX_PWD_SIZE (127)
|
||||
|
||||
#define STUN_MAGIC_COOKIE (0x2112A442)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user