Compare commits

...

5 Commits

Author SHA1 Message Date
ovadbar 7f5194c4f4
Merge 406bd88f1b into 3b58ebc5f3 2025-01-21 00:17:21 +00:00
junction1153b 3b58ebc5f3
[mod_sofia] Update Polycom UA to recognize new Poly phones
We observed that the new Poly phones (formerly known as Polycom) were not getting sent a SIP UPDATE in certain circumstances (example: retrieving a parked call, and therefore, Caller ID would not show the parked caller). I renamed Polycom to Poly which will catch all Poly AND Polycom UA's. I also added Acrobits, and Ringotel to extend such functionality to those UA's. There were also other minor compatibility issues with the new Poly phones which have been resolved with tweaking the UA recognition on the code.

Co-authored-by: Joseph <junction1153@gmail.com>
2025-01-21 00:57:25 +03:00
ovadbar 406bd88f1b
Merge branch 'signalwire:master' into gcs2 2024-01-12 14:20:51 -08:00
Baroukh Ovadia bed779239b Changes for gcs2 2021-08-06 04:10:57 +00:00
Baroukh Ovadia 81f41b28c7 Changes To allow GCS in mod_http_cache 2021-08-04 17:13:19 +00:00
12 changed files with 631 additions and 13 deletions

View File

@ -2,7 +2,7 @@ include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_http_cache
noinst_LTLIBRARIES = libhttpcachemod.la
libhttpcachemod_la_SOURCES = mod_http_cache.c common.c aws.c azure.c
libhttpcachemod_la_SOURCES = mod_http_cache.c common.c aws.c azure.c gcs.c
mod_LTLIBRARIES = mod_http_cache.la
mod_http_cache_la_SOURCES =
@ -11,12 +11,16 @@ mod_http_cache_la_CPPFLAGS = $(CURL_CFLAGS) $(AM_CPPFLAGS)
mod_http_cache_la_LIBADD = $(switch_builddir)/libfreeswitch.la libhttpcachemod.la
mod_http_cache_la_LDFLAGS = $(CURL_LIBS) -avoid-version -module -no-undefined -shared
noinst_PROGRAMS = test/test_aws
noinst_PROGRAMS = test/test_aws test/test_gcs
test_test_aws_SOURCES = test/test_aws.c
test_test_aws_CFLAGS = $(AM_CFLAGS) -I. -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\"
test_test_aws_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
test_test_aws_LDADD = libhttpcachemod.la
TESTS = $(noinst_PROGRAMS)
test_test_gcs_SOURCES = test/test_gcs.c
test_test_gcs_CFLAGS = $(AM_CFLAGS) -I. -DSWITCH_TEST_BASE_DIR_FOR_CONF=\"${abs_builddir}/test\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\"${abs_builddir}/test\"
test_test_gcs_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) -lcurl
test_test_gcs_LDADD = libhttpcachemod.la
TESTS = $(noinst_PROGRAMS)

View File

@ -42,8 +42,11 @@ struct http_profile {
char *aws_s3_access_key_id;
char *secret_access_key;
char *base_domain;
char *region; // AWS region. Used by AWS S3
char *region; // AWS region. Used by AWS S3 // Used by gcs as token uri
char *gcs_email; // GCS service account email
char *gcs_credentials; // GCS credencial token
switch_time_t expires; // Expiration time in seconds for URL signature. Default is 604800 seconds. Used by AWS S3
// GCS Expiration used for when the gcs_credentials expires
switch_size_t bytes_per_block;
int header_count;
char** header_names;

View File

@ -0,0 +1,351 @@
/*
* gcs.c for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2020
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is gcs.c for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* gcs.c -- Some GCS Blob Service helper functions
*
*/
#include "gcs.h"
#include <switch.h>
#include <switch_curl.h>
#if defined(HAVE_OPENSSL)
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#endif
struct http_data {
switch_stream_handle_t stream;
switch_size_t bytes;
switch_size_t max_bytes;
int err;
};
#if defined(HAVE_OPENSSL)
char *encoded_token(const char *token_uri, const char *client_email, const char *private_key_id, int *token_length, time_t now) {
time_t then = now + 3600;
int tlength = 1 + snprintf(NULL, 0, "{\"typ\":\"JWT\",\"alg\":\"RS256\",\"kid\":\"%s\"}", private_key_id);
int payload_length = 1 + snprintf(NULL, 0, "{\"iat\":\"%ld\",\"exp\":\"%ld\",\"iss\":\"%s\",\"aud\":\"%s\",\"scope\":\"https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/devstorage.read_only https://www.googleapis.com/auth/devstorage.read_write\"}", now, then, client_email,token_uri);
char token[tlength];
char payload[payload_length];
int encoded_tlength = tlength * 4 / 3 + (tlength % 3 ? 1 : 0);
int encoded_playload_length = payload_length * 4 / 3 + (payload_length % 3 ? 1 : 0);
char *tokenb64 = malloc(encoded_tlength * sizeof(char));
char *payloadb64 = malloc(encoded_playload_length* sizeof(char));
int signee_length = encoded_tlength + encoded_playload_length;
char *signee = malloc((signee_length) * sizeof(char));
sprintf(token,"{\"typ\":\"JWT\",\"alg\":\"RS256\",\"kid\":\"%s\"}", private_key_id);
sprintf(payload, "{\"iat\":\"%ld\",\"exp\":\"%ld\",\"iss\":\"%s\",\"aud\":\"%s\",\"scope\":\"https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/devstorage.read_only https://www.googleapis.com/auth/devstorage.read_write\"}", now, then, client_email,token_uri);
*token_length = signee_length - 1;
switch_b64_encode((unsigned char *) token,sizeof(token), (unsigned char *) tokenb64, encoded_tlength);
switch_b64_encode((unsigned char *) payload,sizeof(payload), (unsigned char *) payloadb64, encoded_playload_length);
sprintf(signee, "%s.%s", tokenb64, payloadb64);
free(tokenb64);
free(payloadb64);
return signee;
}
void signtoken(char *token, int tokenlen,char *pkey, char *out) {
unsigned char *sig = NULL;
BIO *b = NULL;
RSA *r = NULL;
unsigned int sig_len;
unsigned char *md = malloc(SHA256_DIGEST_LENGTH * sizeof(char));
unsigned char *digest = SHA256((const unsigned char *) token, tokenlen, md);
b = BIO_new_mem_buf(pkey, -1);
r = PEM_read_bio_RSAPrivateKey(b, NULL, NULL, NULL);
BIO_set_close(b, BIO_CLOSE);
BIO_free(b);
sig = malloc(RSA_size(r));
RSA_sign(NID_sha256, digest, sizeof(char) * SHA256_DIGEST_LENGTH, sig, &sig_len, r);
switch_b64_encode(sig,(switch_size_t) sizeof(char) * sig_len,(unsigned char *) out, 343 * sizeof(char));
free(sig);
free(md);
RSA_free(r);
}
char *gcs_auth_request(char *content, char *url);
switch_status_t gcs_refresh_authorization (http_profile_t *profile)
{
int token_length;
char *token = NULL;
char *encoded = NULL;
char *assertion = NULL;
char *auth = NULL;
char content[GCS_SIGNATURE_LENGTH_MAX];
char *signature_url_encoded = NULL;
time_t exp;
time_t now = time(NULL);
token = encoded_token(profile->region, profile->gcs_email, profile->aws_s3_access_key_id, &token_length, now);
encoded = malloc(sizeof(char) * 343);
signtoken(token, token_length, profile->secret_access_key, encoded);
assertion = malloc(sizeof(char) * (1 + token_length + 343));
sprintf(assertion, "%s.%s", token, encoded);
free(token);
signature_url_encoded = switch_string_replace(assertion, "+", "%2B");
sprintf(content,"%s%s", "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=", signature_url_encoded);
auth = gcs_auth_request(content, profile->region);
profile->gcs_credentials = auth;
exp = now + 3540;
profile->expires = exp;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Credentials Expries Unix Time: %ld", exp);
switch_safe_free(assertion);
return SWITCH_STATUS_SUCCESS;
}
#endif
/**
* Append the specific GCS Blob Service headers
* @param http_profile_t the provile
* @param headers the list of headers to append to
*/
switch_curl_slist_t *gcs_append_headers(http_profile_t *profile, switch_curl_slist_t *headers, const char *verb,unsigned int content_length, const char *content_type, const char *url, const unsigned int block_num, char **query_string)
{
char header[1024];
#if defined(HAVE_OPENSSL)
switch_time_t now = time(NULL);
if (profile->expires < now) {
gcs_refresh_authorization(profile);
}
switch_snprintf(header, sizeof(header), "Authorization: Bearer %s", profile->gcs_credentials);
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Credecials Token: %s", profile->gcs_credentials);
headers = switch_curl_slist_append(headers, header);
#endif
return headers;
}
/**
* Read the GCS Blob Service profile
* @param name the name of the profile
* @param xml the portion of the XML document containing the profile
* @param access_key_id returned value of access_key_id in the configuration
* @param secret_access_key returned value of secret_access_key in the configuration
* @param base_domain returned value of base_domain in the configuration
* @param bytes_per_block returned value of bytes_per_block in the configuration
* @return SWITCH_STATUS_SUCCESS on success
*/
switch_status_t gcs_config_profile(switch_xml_t xml, http_profile_t *profile,switch_memory_pool_t *pool)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
#if defined(HAVE_OPENSSL)
char *file = NULL;
char *envfile = getenv("GOOGLE_APPLICATION_CREDENTIALS");
switch_xml_t base_domain_xml = switch_xml_child(xml, "base-domain");
profile->append_headers_ptr = gcs_append_headers;
/* check if environment variables set the keys */
if (!zstr(envfile)) {
file = switch_core_strdup(pool, envfile);
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
// "Using GOOGLE_APPLICATION_CREDENTIALS environment variables for GCS access on profile \"%s\"\n", profile->name);
} else {
/* use configuration for keys */
switch_xml_t creds = switch_xml_child(xml, "credential_file");
if (creds) {
file = switch_strip_whitespace(switch_xml_txt(creds));
}
}
if (switch_file_exists(file, pool) == SWITCH_STATUS_SUCCESS) {
char *contents = NULL;
char *jsonstr = NULL;
switch_file_t *fd;
switch_status_t status;
switch_size_t size;
cJSON *json = {0};
status = switch_file_open(&fd, file, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD, pool);
if (status != SWITCH_STATUS_SUCCESS) {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERR, "Could not open credencial file\n", profile->bytes_per_block);
switch_safe_free(file);
return status;
}
size = switch_file_get_size(fd);
if (size) {
contents = malloc(size);
switch_file_read(fd, (void *) contents, &size);
} else {
switch_safe_free(file);
return SWITCH_STATUS_FALSE;
}
status = switch_file_close(fd);
if (status != SWITCH_STATUS_SUCCESS) {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERR, "Could not close credencial file\n", profile->bytes_per_block);
switch_safe_free(file);
return status;
}
json = cJSON_Parse(contents);
if (cJSON_GetObjectItem(json,"private_key_id") != NULL) {
jsonstr = cJSON_GetObjectItem(json,"private_key_id")->valuestring;
profile->aws_s3_access_key_id = malloc(sizeof(char) * (1+ strlen(jsonstr)));
strcpy(profile->aws_s3_access_key_id, jsonstr);
}
if (cJSON_GetObjectItem(json,"private_key") != NULL) {
jsonstr = cJSON_GetObjectItem(json,"private_key")->valuestring;
profile->secret_access_key = malloc(sizeof(char) * (1+ strlen(jsonstr)));
strcpy(profile->secret_access_key, jsonstr);
}
if (cJSON_GetObjectItem(json,"client_email") != NULL) {
jsonstr = cJSON_GetObjectItem(json,"client_email")->valuestring;
profile->gcs_email = malloc(sizeof(char) * (1+ strlen(jsonstr)));
strcpy(profile->gcs_email, jsonstr);
}
if (cJSON_GetObjectItem(json,"token_uri") != NULL) {
jsonstr = cJSON_GetObjectItem(json,"token_uri")->valuestring;
profile->region = malloc(sizeof(char) * (1+ strlen(jsonstr)));
strcpy(profile->region, jsonstr);
}
cJSON_Delete(json);
free(contents);
} else {
switch_xml_t private_key = switch_xml_child(xml, "private_key");
switch_xml_t private_key_id = switch_xml_child(xml, "private_key_id");
switch_xml_t client_email = switch_xml_child(xml, "client_email");
switch_xml_t token_uri = switch_xml_child(xml, "token_uri");
if (private_key_id) {
profile->aws_s3_access_key_id = switch_strip_whitespace(switch_xml_txt(private_key_id));
} else {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing key private_key_id\n");
switch_safe_free(file);
return SWITCH_STATUS_FALSE;
}
if (private_key) {
profile->secret_access_key = switch_xml_txt(private_key);
} else {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing key private_key\n");
switch_safe_free(file);
return SWITCH_STATUS_FALSE;
}
if (client_email) {
profile->gcs_email = switch_strip_whitespace(switch_xml_txt(client_email));
} else {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing key client_email\n");
switch_safe_free(file);
return SWITCH_STATUS_FALSE;
}
if (token_uri) {
profile->region = switch_strip_whitespace(switch_xml_txt(token_uri));
} else {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing key token_uri\n");
switch_safe_free(file);
return SWITCH_STATUS_FALSE;
}
}
switch_safe_free(file);
profile->bytes_per_block = 4e6;
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set number of bytes per block to %zu\n", profile->bytes_per_block);
status = gcs_refresh_authorization(profile);
if (status != SWITCH_STATUS_SUCCESS){
return status;
}
if (base_domain_xml) {
profile->base_domain = switch_strip_whitespace(switch_xml_txt(base_domain_xml));
if (zstr(profile->base_domain)) {
switch_safe_free(profile->base_domain);
}
}
#endif
return status;
}
#if defined(HAVE_OPENSSL)
static size_t gcs_auth_callback(void *ptr, size_t size, size_t nmemb, void *data)
{
register unsigned int realsize = (unsigned int) (size * nmemb);
struct http_data *http_data = data;
http_data->bytes += realsize;
if (http_data->bytes > http_data->max_bytes) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int) http_data->bytes);
http_data->err = 1;
return 0;
}
http_data->stream.write_function(&http_data->stream, "%.*s", realsize, ptr);
return realsize;
}
char *gcs_auth_request(char *content, char *url) {
switch_CURL *curl_handle = NULL;
long httpRes = 0;
char *response = NULL;
switch_curl_slist_t *headers = NULL;
char *ct = "Content-Type: application/x-www-form-urlencoded";
struct http_data http_data;
CURLcode res;
memset(&http_data, 0, sizeof(http_data));
http_data.max_bytes = 10240;
SWITCH_STANDARD_STREAM(http_data.stream);
curl_handle = switch_curl_easy_init();
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url);
switch_curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, content);
switch_curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 5);
switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 10);
headers = switch_curl_slist_append(headers, ct);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-curl/1.0");
switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, gcs_auth_callback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&http_data);
res = switch_curl_easy_perform(curl_handle);
switch_curl_easy_cleanup(curl_handle);
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
switch_curl_easy_strerror(res));
if (http_data.stream.data && !zstr((char *) http_data.stream.data) && strcmp(" ", http_data.stream.data)) {
cJSON *json = {0};
json = cJSON_Parse(http_data.stream.data);
if (cJSON_GetObjectItem(json,"access_token") != NULL) {
char *jsonstr;
jsonstr = cJSON_GetObjectItem(json,"access_token")->valuestring;
response = malloc(sizeof(char) * (1+strlen(jsonstr)));
strcpy(response, jsonstr);
}
cJSON_Delete(json);
}
return response;
}
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet
*/

View File

@ -0,0 +1,53 @@
/*
* gcs.h for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2014, Grasshopper
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is gcs.h for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is Baroukh Ovadia
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Baroukh Ovadia <ovadbar@gmail.com>
*
* gcs.h - Some Google Cloud Storage helper functions
*
*/
#ifndef GCS_H
#define GCS_H
#include <switch.h>
#include <switch_curl.h>
#include <common.h>
/* (SHA1_LENGTH * 1.37 base64 bytes per byte * 3 url-encoded bytes per byte) */
#define GCS_SIGNATURE_LENGTH_MAX 1024
SWITCH_MOD_DECLARE(switch_curl_slist_t*) gcs_append_headers(http_profile_t *profile, switch_curl_slist_t *headers,
const char *verb, unsigned int content_length, const char *content_type, const char *url, const unsigned int block_num, char **query_string);
SWITCH_MOD_DECLARE(switch_status_t) gcs_config_profile(switch_xml_t xml, http_profile_t *profile,switch_memory_pool_t *pool);
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet
*/

View File

@ -36,6 +36,7 @@
#include <switch_curl.h>
#include "aws.h"
#include "azure.h"
#include "gcs.h"
#include <stdlib.h>
@ -1698,14 +1699,21 @@ static switch_status_t do_config(url_cache_t *cache)
continue;
}
} else {
profile_xml = switch_xml_child(profile, "default");
profile_xml = switch_xml_child(profile, "gcs");
if (profile_xml) {
if (default_config_profile(profile_xml, profile_obj, cache->pool) == SWITCH_STATUS_FALSE) {
if (gcs_config_profile(profile_xml, profile_obj, cache->pool) == SWITCH_STATUS_FALSE) {
continue;
}
} else {
profile_xml = switch_xml_child(profile, "default");
if (profile_xml) {
if (default_config_profile(profile_xml, profile_obj, cache->pool) == SWITCH_STATUS_FALSE) {
continue;
}
}
}
}
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Adding profile \"%s\" to cache\n", name);
switch_core_hash_insert(cache->profiles, profile_obj->name, profile_obj);

View File

@ -0,0 +1,151 @@
/*
* aws.h for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2014, Grasshopper
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is aws.h for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is Grasshopper
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris.rienzo@grasshopper.com>
* Quoc-Bao Nguyen <baonq5@vng.com.vn>
*
* test_aws.c - Unit tests for functions in aws.c
*
*/
#include <switch.h>
#include <test/switch_test.h>
#include "../gcs.c"
#include <stdlib.h>
// Run test
// make && libtool --mode=execute valgrind --leak-check=full --log-file=vg.log ./test/test_aws && cat vg.log
FST_BEGIN()
{
FST_SUITE_BEGIN()
{
FST_SETUP_BEGIN()
{
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
#if defined(HAVE_OPENSSL)
FST_TEST_BEGIN(encoded_token)
{
//char *encoded_token(const char *token_uri, const char *client_email, const char *private_key_id, int *token_length, time_t now) {
time_t now = 1615402513;
char *token = NULL;
int token_length;
/*
char *tkn = "TESTER";
int encoded_tlength = 8;
unsigned char *tknb64 = malloc(encoded_tlength * sizeof(char));
switch_b64_encode((unsigned char *) tkn,sizeof(tkn), tknb64, encoded_tlength);
*/
token = encoded_token("https://accounts.google.com/o/oauth2/token", "gcs@freeswitch.com", "667265657377697463682D676373", &token_length, now);
fst_check_string_equals("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjY2NzI2NTY1NzM3NzY5NzQ2MzY4MkQ2NzYzNzMifQ.eyJpYXQiOiIxNjE1NDAyNTEzIiwiZXhwIjoiMTYxNTQwNjExMyIsImlzcyI6Imdjc0BmcmVlc3dpdGNoLmNvbSIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsInNjb3BlIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9kZXZzdG9yYWdlLmZ1bGxfY29udHJvbCBodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2RldnN0b3JhZ2UucmVhZF9vbmx5IGh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvZGV2c3RvcmFnZS5yZWFkX3dyaXRlIn0", token);
free(token);
}
FST_TEST_END()
FST_TEST_BEGIN(signtoken)
{
//void signtoken(char *token, int tokenlen,char *pkey, char *out) {
char *encoded = NULL;
char *pkey = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCXiVOV3h61llym\nnpHamUHsuVjrdDiEQnNX1KA4k/kcfP+gqRjL9m3YAxXfUA9GFCIC2OYvdciW3Ggm\nt4CSYmSltljKjbN2JHs7iNQw4CcFfiAXhxL0TYNhNE9wBDOZRsC1Uusv38RPwqwd\n922pAGzF+PqNE2j+zSxlNOnlJfyJDMKrqCGV8CclS+j/u41MaT6cpOlHP6KgaS01\nJJVyaqLpnMLWAx9/5G6Y/YWah+obEyn7yoDva/1Yhlnq20CMHlh3ifDfYYrS9rtp\nhdutz4fESKFPKymlG9aGfFuCME3GP8Rn8ZdPbsAWZ2cf388CLjlxEid1EU8klr2X\n+G1+3di/AgMBAAECggEAHL6UZ9+/5IMWpRZ8JUKgAjbwWo1rsQ7n0TfIgqLzBIfj\nd4bL6NigYnLHYdpOY2UrRG3/T+5gM9mwOfPiBCJ85AAwXI+/hIAMDjF4yqKiVETl\n8oCRRF01uCkTjnSFkyQcJukJKsYf918+hdqq5v1pJK6DXGJbrsWdj78XRPvNKPPD\naEEvSNwdet12Jz9wkmj2g7zg8KMX18v3IUyf7HKjb/cjomB0WuIDfJchDRYlxrfJ\n4DShcIfMi+04C/FFN+vbP77tXQM7O3Z81uqDQAO3k3NoXTTNBZGLP+SOyDUSRZQS\nCNb3J6cwTC737e0M6K+zVP1f03ynuU2u+dHiVVMTtQKBgQDNw/19HSxoJ/5nGHbD\nLW1g33Jm4Nr05lYnetEPS0wkruzEbTy3B6prl34KUslreuUTAuhtFxCLsEgT/sMO\nrxX/OM7RaNUILrpLrzen/eVNeiquM1wLEI52VNkRU5GlTZEJohGE+a3YP+kQTLe5\n8xmzKfJUllyfpXGxDNkryjaeSwKBgQC8iBqDJs6h9tkdxC/XC8+qSJ+WBk5tr3PM\nyx/x1NGKO5TpgdhRr98GYYUhoph+TIp0/8/+d2lVDzO4SAOzms3xnANPEzJcLi7c\nCa8ECOW3S4HhWE61QsbVY5xA83hGAO2WQN22vu9KwhyFU145aSQH0tJrQoevkdBl\ndpqtP15W3QKBgQCsL8gePJ1+g4k2SJiJd6hCGnoncR6JNX7/Bp2PiNktEVx8e1UF\nbNrFsj388Y4v7OVo5VQOhfCIlHmckeI0lXt42dboEivC7ydiUjvmzmZmUUcKA1yQ\nvcgZaaNEBoSoqaInR4IVnsJFZiXoR+qvJqlo7j8lXbYgulfLaw8Iv+y4xQKBgGK6\no6eq2urWajy8UJE9DjMOdQQLqWanSu0kMkZiPJk3OnROGwosH48n4qAKlfEOBDPh\nAvsvbWmt3FfU3ptfphmwqcrvMqAzTzbLm2txfVrPn+RyakViAt4cm+cnmQSP19un\nfHQG6SktHeJ0FhPai5PNQ4QIAyZeJdP8mGPBm5XBAoGBAJWnXiapFMcHi3DgsVb4\n+ni8Qvs293OvsdjHlo2eent/Kwbrdytw/V8uhq9awJb1npdgVd54RrbZ+Jq4x19K\nt06Jz9/EAoLLfL+tqzpEiKvSLjdKpedPm1Cgfj0KTM+MqoSU0bv4gMssnM428luJ\nv5ptWjeaHoYpJzvGfGBouVCI\n-----END PRIVATE KEY-----\n";
int tlength = snprintf(NULL, 0, "%s", pkey);
encoded = malloc(sizeof(char) * 343);
signtoken("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjY2NzI2NTY1NzM3NzY5NzQ2MzY4MkQ2NzYzNzMifQ.eyJpYXQiOiIxNjE1NDAyNTEzIiwiZXhwIjoiMTYxNTQwNjExMyIsImlzcyI6Imdjc0BmcmVlc3dpdGNoLmNvbSIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsInNjb3BlIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9kZXZzdG9yYWdlLmZ1bGxfY29udHJvbCBodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9hdXRoL2RldnN0b3JhZ2UucmVhZF9vbmx5IGh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvZGV2c3RvcmFnZS5yZWFkX3dyaXRlIn0", tlength, pkey, encoded);
fst_check_string_equals("iSNfnz8gn1q8cYUrs7+m3hhXRalFRemt9SXvlnrzr1tyYx2ztL0m/882jghpsHMDVcti59avBjamcbrwMRDah7KXomu2cuCEwuYaGo6C7KTe9WZf+J0ep2shOAJJwnDKvUfuyVT21EEf/rWXfy8lblsq/YK0D7982FsXUgPDFU5NzPiw2fWk6YEPWbET3Yy+gJiTqYj5P0Fo1s66LNrLIX1RbH6/GW7d+lDl2RNMCZxGTtEygLdAXj+l0OPQG4Qvfzeymi9zWEq6j0rAChT0OppjZKqWf9IjMRbPUbuwIpNmgntfU7OcYtTFeiLy+W9fFutXEbSrq72MxMOrDEWWhQ", encoded);
free(encoded);
}
FST_TEST_END()
FST_TEST_BEGIN(parse_xml_config_with_gcs)
{
switch_xml_t cfg, profiles, profile, gcs_profile;
http_profile_t http_profile;
int fd;
int i = 0;
fd = open("test_gcs_http_cache.conf.xml", O_RDONLY);
if (fd < 0) {
//printf("Open in test dir\n");
fd = open("test/parse_xml_config_with_gcs", O_RDONLY);
}
fst_check(fd > 0);
cfg = switch_xml_parse_fd(fd);
fst_check(cfg != NULL);
profiles = switch_xml_child(cfg, "profiles");
fst_check(profiles);
for (profile = switch_xml_child(profiles, "profile"); profile; profile = profile->next) {
const char *name = NULL;
switch_memory_pool_t *pool;
switch_core_new_memory_pool(&pool);
i++;
fst_check(profile);
name = switch_xml_attr_soft(profile, "name");
fst_check(name);
http_profile.name = name;
http_profile.aws_s3_access_key_id = NULL;
http_profile.secret_access_key = NULL;
http_profile.base_domain = NULL;
http_profile.region = NULL;
gcs_profile = switch_xml_child(profile, "gcs");
gcs_config_profile(gcs_profile, &http_profile, pool);
//aws_s3_access_key_id, secret_access_key, gcs_email, region
fst_check(!zstr(http_profile.region));
fst_check(!zstr(http_profile.aws_s3_access_key_id));
fst_check(!zstr(http_profile.secret_access_key));
switch_safe_free(http_profile.region);
switch_safe_free(http_profile.aws_s3_access_key_id);
switch_safe_free(http_profile.secret_access_key);
switch_safe_free(http_profile.base_domain);
switch_core_destroy_memory_pool(&pool);
}
fst_check(i == 1); // test data contain two config
switch_xml_free(cfg);
}
FST_TEST_END()
#endif
}
FST_SUITE_END()
}
FST_END()

View File

@ -0,0 +1,12 @@
{
"type": "service_account",
"project_id": "freeswitch-gcs",
"private_key_id": "667265657377697463682D676373",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCXiVOV3h61llym\nnpHamUHsuVjrdDiEQnNX1KA4k/kcfP+gqRjL9m3YAxXfUA9GFCIC2OYvdciW3Ggm\nt4CSYmSltljKjbN2JHs7iNQw4CcFfiAXhxL0TYNhNE9wBDOZRsC1Uusv38RPwqwd\n922pAGzF+PqNE2j+zSxlNOnlJfyJDMKrqCGV8CclS+j/u41MaT6cpOlHP6KgaS01\nJJVyaqLpnMLWAx9/5G6Y/YWah+obEyn7yoDva/1Yhlnq20CMHlh3ifDfYYrS9rtp\nhdutz4fESKFPKymlG9aGfFuCME3GP8Rn8ZdPbsAWZ2cf388CLjlxEid1EU8klr2X\n+G1+3di/AgMBAAECggEAHL6UZ9+/5IMWpRZ8JUKgAjbwWo1rsQ7n0TfIgqLzBIfj\nd4bL6NigYnLHYdpOY2UrRG3/T+5gM9mwOfPiBCJ85AAwXI+/hIAMDjF4yqKiVETl\n8oCRRF01uCkTjnSFkyQcJukJKsYf918+hdqq5v1pJK6DXGJbrsWdj78XRPvNKPPD\naEEvSNwdet12Jz9wkmj2g7zg8KMX18v3IUyf7HKjb/cjomB0WuIDfJchDRYlxrfJ\n4DShcIfMi+04C/FFN+vbP77tXQM7O3Z81uqDQAO3k3NoXTTNBZGLP+SOyDUSRZQS\nCNb3J6cwTC737e0M6K+zVP1f03ynuU2u+dHiVVMTtQKBgQDNw/19HSxoJ/5nGHbD\nLW1g33Jm4Nr05lYnetEPS0wkruzEbTy3B6prl34KUslreuUTAuhtFxCLsEgT/sMO\nrxX/OM7RaNUILrpLrzen/eVNeiquM1wLEI52VNkRU5GlTZEJohGE+a3YP+kQTLe5\n8xmzKfJUllyfpXGxDNkryjaeSwKBgQC8iBqDJs6h9tkdxC/XC8+qSJ+WBk5tr3PM\nyx/x1NGKO5TpgdhRr98GYYUhoph+TIp0/8/+d2lVDzO4SAOzms3xnANPEzJcLi7c\nCa8ECOW3S4HhWE61QsbVY5xA83hGAO2WQN22vu9KwhyFU145aSQH0tJrQoevkdBl\ndpqtP15W3QKBgQCsL8gePJ1+g4k2SJiJd6hCGnoncR6JNX7/Bp2PiNktEVx8e1UF\nbNrFsj388Y4v7OVo5VQOhfCIlHmckeI0lXt42dboEivC7ydiUjvmzmZmUUcKA1yQ\nvcgZaaNEBoSoqaInR4IVnsJFZiXoR+qvJqlo7j8lXbYgulfLaw8Iv+y4xQKBgGK6\no6eq2urWajy8UJE9DjMOdQQLqWanSu0kMkZiPJk3OnROGwosH48n4qAKlfEOBDPh\nAvsvbWmt3FfU3ptfphmwqcrvMqAzTzbLm2txfVrPn+RyakViAt4cm+cnmQSP19un\nfHQG6SktHeJ0FhPai5PNQ4QIAyZeJdP8mGPBm5XBAoGBAJWnXiapFMcHi3DgsVb4\n+ni8Qvs293OvsdjHlo2eent/Kwbrdytw/V8uhq9awJb1npdgVd54RrbZ+Jq4x19K\nt06Jz9/EAoLLfL+tqzpEiKvSLjdKpedPm1Cgfj0KTM+MqoSU0bv4gMssnM428luJ\nv5ptWjeaHoYpJzvGfGBouVCI\n-----END PRIVATE KEY-----\n",
"client_email": "gcs@freeswitch.com",
"client_id": "105862293685176461395",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gcs%40freeswitch.com"
}

View File

@ -0,0 +1,34 @@
<configuration name="http_cache.conf" description="HTTP GET cache">
<settings>
<!-- set to true if you want to enable http:// and https:// formats. Do not use if mod_httapi is also loaded -->
<param name="enable-file-formats" value="true"/>
<param name="max-urls" value="10000"/>
<param name="location" value="$${cache_dir}"/>
<param name="default-max-age" value="86400"/>
<param name="prefetch-thread-count" value="8"/>
<param name="prefetch-queue-size" value="100"/>
<!-- absolute path to CA bundle file -->
<param name="ssl-cacert" value="$${certs_dir}/cacert.pem"/>
<!-- verify certificates -->
<param name="ssl-verifypeer" value="true"/>
<!-- verify host name matches certificate -->
<param name="ssl-verifyhost" value="true"/>
<!-- default is 300 seconds, override here -->
<!--param name="connect-timeout" value="300"/-->
<!-- default is 300 seconds, override here -->
<!--param name="download-timeout" value="300"/-->
</settings>
<profiles>
<!-- amazon s3 security credentials -->
<profile name="gcs">
<!-- optional list of domains that this profile will automatically be applied to -->
<!-- if you wish to apply the s3 credentials to a domain not listed here, then use
{profile=s3}http://foo.s3... -->
<domains>
<!-- FORMAT https://<bucket>.storage.googleapis.com -->
<domain name="dyl1.storage.googleapis.com"/>
</domains>
<credential_file>test_gcs.json</credential_file>
</profile>
</profiles>
</configuration>

View File

@ -254,7 +254,7 @@ char *generate_pai_str(private_object_t *tech_pvt)
callee_number = switch_sanitize_number(switch_core_session_strdup(session, callee_number));
callee_name = switch_sanitize_number(switch_core_session_strdup(session, callee_name));
if (!zstr(callee_number) && (zstr(ua) || !switch_stristr("polycom", ua))) {
if (!zstr(callee_number) && (zstr(ua) || !switch_stristr("poly", ua))) {
callee_number = switch_core_session_sprintf(session, "sip:%s@%s", callee_number, host);
}
@ -2075,13 +2075,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END());
} else if (update_allowed && ua && (switch_channel_var_true(tech_pvt->channel, "update_ignore_ua") ||
switch_stristr("polycom", ua) ||
switch_stristr("poly", ua) ||
(switch_stristr("aastra", ua) && !switch_stristr("Intelligate", ua)) ||
(switch_stristr("cisco/spa50", ua) ||
switch_stristr("cisco/spa525", ua)) ||
switch_stristr("cisco/spa30", ua) ||
switch_stristr("Fanvil", ua) ||
switch_stristr("Grandstream", ua) ||
switch_stristr("Ringotel", ua) ||
switch_stristr("Groundwire", ua) ||
switch_stristr("Yealink", ua) ||
switch_stristr("Mitel", ua) ||
switch_stristr("Panasonic", ua))) {
@ -2152,7 +2154,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
SIPTAG_PAYLOAD_STR(message),
TAG_IF(!zstr(session_id_header), SIPTAG_HEADER_STR(session_id_header)),
TAG_END());
} else if (ua && switch_stristr("polycom", ua)) {
} else if (ua && switch_stristr("poly", ua)) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_update(tech_pvt->nh,
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),

View File

@ -10476,7 +10476,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
(!is_tcp && !is_tls && (zstr(network_ip) || !switch_check_network_list_ip(network_ip, profile->local_network)) &&
profile->server_rport_level >= 2 && sip->sip_user_agent &&
sip->sip_user_agent->g_string &&
(!strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7) || !strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20)))
(!strncasecmp(sip->sip_user_agent->g_string, "Poly", 4) || !strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20)))
) {
if (sip->sip_via) {
const char *port = sip->sip_via->v_port;

View File

@ -2501,7 +2501,7 @@ static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *r
{
char *ret = NULL;
if (switch_stristr("polycom", user_agent)) {
if (switch_stristr("poly", user_agent)) {
*ct = "application/xpidf+xml";
/* If unknown/none prpid is provided, just show the user as online. */

View File

@ -1661,7 +1661,7 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
if (!is_tcp && !is_tls && (zstr(network_ip) || !switch_check_network_list_ip(network_ip, profile->local_network)) &&
profile->server_rport_level >= 2 && sip->sip_user_agent &&
sip->sip_user_agent->g_string &&
( !strncasecmp(sip->sip_user_agent->g_string, "Polycom", 7) ||
( !strncasecmp(sip->sip_user_agent->g_string, "Poly", 4) ||
!strncasecmp(sip->sip_user_agent->g_string, "KIRK Wireless Server", 20) ||
!strncasecmp(sip->sip_user_agent->g_string, "ADTRAN_Total_Access", 19) )) {
if (sip->sip_via) {