예제 #1
0
static int pgsql_get_user_key(u08bits *usname, u08bits *realm, hmackey_t key) {
  int ret = -1;
	PGconn * pqc = get_pqdb_connection();
	if(pqc) {
		char statement[TURN_LONG_STRING_SIZE];
		/* direct user input eliminated - there is no SQL injection problem (since version 4.4.5.3) */
		snprintf(statement,sizeof(statement),"select hmackey from turnusers_lt where name='%s' and realm='%s'",usname,realm);
		PGresult *res = PQexec(pqc, statement);

		if(!res || (PQresultStatus(res) != PGRES_TUPLES_OK) || (PQntuples(res)!=1)) {
			TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving PostgreSQL DB information: %s\n",PQerrorMessage(pqc));
		} else {
			char *kval = PQgetvalue(res,0,0);
			int len = PQgetlength(res,0,0);
			if(kval) {
				size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
				if(((size_t)len<sz*2)||(strlen(kval)<sz*2)) {
					TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s, user %s\n",kval,usname);
				} else if(convert_string_key_to_binary(kval, key, sz)<0) {
					TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n",kval,usname);
				} else {
					ret = 0;
				}
			} else {
				TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong hmackey data for user %s: NULL\n",usname);
			}
		}

		if(res)
			PQclear(res);

	}
  return ret;
}
예제 #2
0
static int mongo_get_user_key(u08bits *usname, u08bits * realm, hmackey_t key) {

//    mongoc_collection_t * collection = mongo_get_collection("turnusers_lt");
  mongoc_collection_t * collection = mongo_get_collection("users");

  if(!collection)
    return -1;
    
  bson_t query;
  bson_init(&query);

  BSON_APPEND_UTF8(&query, "auth.email", (const char *)usname);

  bson_t fields;
  bson_init(&fields);
    
  BSON_APPEND_INT32(&fields, "auth.secret", 1);
  
  mongoc_cursor_t * cursor;
  cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, &fields, NULL);
  
  int ret = -1;

  if (!cursor) {
		TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error querying MongoDB collection 'turnusers_lt'\n");
  } else {
      
  {
    // DEBUG
      /*
      const bson_t * doc = 0;
      char *str = 0;
      while (mongoc_cursor_next (cursor, &doc)) {
          str = bson_as_json (doc, NULL);
          fprintf (stdout, "%s\n", str);
          bson_free (str);
      }
       */
   }
      
      
    const bson_t * item;
    uint32_t length;
    bson_iter_t iter;
    const char* password;
    if (mongoc_cursor_next(cursor, &item)) {
        bson_iter_t sub_iter;
        if (bson_iter_init(&iter, item) && bson_iter_find_descendant(&iter, "auth.secret", &sub_iter) && BSON_ITER_HOLDS_UTF8(&sub_iter)) {
            
	  password = bson_iter_utf8(&sub_iter, &length);
	  size_t sz = get_hmackey_size(SHATYPE_DEFAULT) * 2;

          char skey[sizeof(hmackey_t) * 2 + 1];
          password2hmac(password, usname, realm, skey);
                    
          if(convert_string_key_to_binary(skey, key, sz / 2) < 0) {
	    TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", skey, usname);
            } else {
	    ret = 0;
	  }
      }
    }
    mongoc_cursor_destroy(cursor);
  }
  mongoc_collection_destroy(collection);
  bson_destroy(&query);
  bson_destroy(&fields);
  return ret;
}
예제 #3
0
/*
 * Password retrieval
 */
int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *usname, u08bits *realm, hmackey_t key, ioa_network_buffer_handle nbh)
{

    /* Decode certificate */
    struct certificate cert;
    memset(&cert, 0, sizeof cert);
    unsigned char const *secret_key = (unsigned char *)turn_params.secret_key;
    unsigned char const *iv = (unsigned char *)turn_params.secret_iv;
    
    stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh), STUN_ATTRIBUTE_SOFTWARE);
    if (sar)
    {
        int token_len = stun_attr_get_len(sar);
        const u08bits* token_ptr = stun_attr_get_value(sar);
        u08bits token[128];
        memcpy(token, token_ptr, token_len);
        token[token_len]=0;
        int err = stun_check_message_certificate(token, token_len, &cert, secret_key, iv);
        if(token_len && err == 0)
         {
             const char* password = cert.call_id;
             size_t sz = get_hmackey_size(SHATYPE_DEFAULT) * 2;
             
             char skey[sizeof(hmackey_t) * 2 + 1];
             password2hmac(password, usname, realm, skey);
             
             if(convert_string_key_to_binary(skey, key, sz / 2) < 0) {
                 TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", skey, usname);
             }

             char buff[20];
             struct tm * timeinfo;
             timeinfo = localtime (&cert.deadline);
             strftime(buff, sizeof(buff), "%Y %b %d %H:%M", timeinfo);
             
             time_t     now;
             now = time(NULL);
             
       /*      if(now - cert.deadline < -60 || // server's time's wrong? more tann 60 sec time diff
                now - cert.deadline > 60*60*24 ) // too much diff, something wrong
             {
                 TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Token expired: user: %s token: %s time: %s time_diff: %d sec\n", usname, token, buff, now - cert.deadline);
                 return -1;
             } */

             TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Token decrypted: user:%s seq:%s time:%s call:%s \n", usname, cert.seq, buff, cert.call_id);
             return 0;
         }
        else
        {
            TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Incorrect token: user %s token: %s Error: %d\n", usname, token, err);
            return -1;
        }
    }
    else
        TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Tokent not found: user %s\n", usname);
    
    int ret = -1;
    
	if(max_session_time)
		*max_session_time = 0;

	if(in_oauth && out_oauth && usname && usname[0]) {

		stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh),
								ioa_network_buffer_get_size(nbh),
								STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN);
		if(sar) {

			int len = stun_attr_get_len(sar);
			const u08bits *value = stun_attr_get_value(sar);

			*out_oauth = 1;

			if(len>0 && value) {

				const turn_dbdriver_t * dbd = get_dbdriver();

				if (dbd && dbd->get_oauth_key) {

					oauth_key_data_raw rawKey;
					ns_bzero(&rawKey,sizeof(rawKey));

					int gres = (*(dbd->get_oauth_key))(usname,&rawKey);
					if(gres<0)
						return ret;

					if(!rawKey.kid[0])
						return ret;

					if(rawKey.lifetime) {
						if(!turn_time_before(turn_time(),(turn_time_t)(rawKey.timestamp + rawKey.lifetime+OAUTH_TIME_DELTA))) {
							return ret;
						}
					}

					oauth_key_data okd;
					ns_bzero(&okd,sizeof(okd));

					convert_oauth_key_data_raw(&rawKey, &okd);

					char err_msg[1025] = "\0";
					size_t err_msg_size = sizeof(err_msg) - 1;

					oauth_key okey;
					ns_bzero(&okey,sizeof(okey));

					if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) {
						TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s\n", err_msg);
						return -1;
					}

					oauth_token dot;
					ns_bzero((&dot),sizeof(dot));

					encoded_oauth_token etoken;
					ns_bzero(&etoken,sizeof(etoken));

					if((size_t)len > sizeof(etoken.token)) {
						TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Encoded oAuth token is too large\n");
						return -1;
					}
					ns_bcopy(value,etoken.token,(size_t)len);
					etoken.size = (size_t)len;

					const char* server_name = (char*)turn_params.oauth_server_name;
					if(!(server_name && server_name[0])) {
						server_name = (char*)realm;
						if(!(server_name && server_name[0])) {
							TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot determine oAuth server name");
							return -1;
						}
					}

					if (decode_oauth_token((const u08bits *) server_name, &etoken,&okey, &dot) < 0) {
						TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot decode oauth token\n");
						return -1;
					}

					switch(dot.enc_block.key_length) {
					case SHA1SIZEBYTES:
						break;
					case SHA256SIZEBYTES:
					case SHA384SIZEBYTES:
					case SHA512SIZEBYTES:
					default:
						TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(3): %d\n",(int)dot.enc_block.key_length);
						return -1;
					};

					password_t pwdtmp;
					if(stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM,
								ioa_network_buffer_data(nbh),
								ioa_network_buffer_get_size(nbh),
								dot.enc_block.mac_key,
								pwdtmp,
								SHATYPE_DEFAULT)>0) {

						turn_time_t lifetime = (turn_time_t)(dot.enc_block.lifetime);
						if(lifetime) {
							turn_time_t ts = (turn_time_t)(dot.enc_block.timestamp >> 16);
							turn_time_t to = ts + lifetime + OAUTH_TIME_DELTA;
							turn_time_t ct = turn_time();
							if(!turn_time_before(ct,to)) {
								TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "oAuth token is too old\n");
								return -1;
							}
							if(max_session_time) {
								*max_session_time = to - ct;
							}
						}

						ns_bcopy(dot.enc_block.mac_key,key,dot.enc_block.key_length);

						ret = 0;
					}
				}
			}