Compare commits

..

6 Commits

Author SHA1 Message Date
Andreas Eversberg a4b431c196 WIP: Volte support for outgoing SIP registration 2024-04-25 13:54:47 +02:00
Andreas Eversberg c25cf594d4 Add support for IMS AKA authentication configuration 2024-04-25 13:53:36 +02:00
Andreas Eversberg 7016dc46d8 For Work in Progress: Unstage some files 2024-04-25 13:52:09 +02:00
Andreas Eversberg 08bea4502b WIP: PJSIP: Add functions to change TCP transport on the fly
The Transport must be changed during registration from initial TCP
connection to the negotiated IPsec based address/port quadrupel.
2024-04-25 13:52:09 +02:00
Andreas Eversberg 105ec37f86 WIP: Vocal EVS Codec integration
Related: SY#6825
2024-04-25 13:39:47 +02:00
Andreas Eversberg 0181ef5789 Add PJ-Project files to branch, to add patches to it
This should be changed in the future.
2024-04-25 13:39:47 +02:00
10 changed files with 168 additions and 134 deletions

View File

@ -847,7 +847,6 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
usleep(BIND_DELAY_US);
}
printf("TRANSPORT HIER\n");
res = pjsip_tcp_transport_start3(ast_sip_get_pjsip_endpoint(), &cfg,
&temp_state->state->factory);
}

View File

@ -365,7 +365,6 @@ static pj_status_t set_outbound_authentication_credentials(pjsip_auth_clt_sess *
}
if (AST_VECTOR_SIZE(&auth_creds) == 0) {
puts("jolly: hier");
/* No matching auth objects were found. */
res = PJSIP_ENOCREDENTIAL;
goto cleanup;

View File

@ -384,10 +384,18 @@ struct sip_outbound_registration {
unsigned int ims_aka;
};
/*! \brief States of the IMS registration process */
enum ims_state {
/* !\brief Send first registration. */
IMS_STATE_REGISTER,
IMS_STATE_AUTHENTICATE,
IMS_STATE_RESYNC
/* !\brief Send second registration with authentication response. */
IMS_STATE_RESPONSE,
/* !\brief Send second registration with resync token. */
IMS_STATE_RESYNC,
/* !\brief Send third registration with authentication response after resync. */
IMS_STATE_RESYNC_RESPONSE,
/* !\breif IMS registration process failed. */
IMS_STATE_FAILED,
};
/*! \brief Outbound registration client state information (persists for lifetime of regc) */
@ -799,7 +807,7 @@ static pj_status_t ims_registration_client(struct sip_outbound_registration_clie
goto out;
}
if (volte_reset_transport(&client_state->volte, tdata)) {
if (volte_reset_transport(&client_state->volte)) {
ast_log(LOG_ERROR, "Failed to reset transport.\n");
goto out;
}
@ -1073,6 +1081,9 @@ static int handle_client_state_destruction(void *data)
cancel_registration(client_state);
/* Cleanup IPSec translation. */
volte_cleanup_xfrm(&client_state->volte);
if (client_state->client) {
pjsip_regc_info info;
pjsip_tx_data *tdata;
@ -1377,54 +1388,62 @@ cleanup:
return auth;
}
static int handle_ims_unauthorized(struct registration_response *response)
static int handle_ims_unauthorized(struct registration_response *response, uint8_t *out_auts)
{
struct security_server sec;
struct ast_sip_auth *auth;
uint8_t out_ik[16], out_ck[16], out_auts[14];
uint8_t out_ik[16], out_ck[16];
int rc;
if (response->client_state->ims_state == IMS_STATE_REGISTER) {
/* Remove initial autorization header. */
if (volte_del_authorization(response->old_request)) {
ast_log(LOG_ERROR, "Failed to remove authorization header.\n");
return -1;
}
/* Get security server */
if (volte_get_security_server(&response->client_state->volte, response->rdata, &sec)) {
ast_log(LOG_ERROR, "Failed to parse the security server header.\n");
return -1;
}
if (!(auth = ims_get_sip_auth(&response->client_state->outbound_auths)))
return -1;
rc = volte_authenticate(&response->client_state->volte, response->rdata,
(response->code == 401) ? PJSIP_H_WWW_AUTHENTICATE : PJSIP_H_PROXY_AUTHENTICATE,
auth->usim_opc, auth->usim_k, auth->usim_sqn, (uint8_t *)auth->ims_res,
out_ik, out_ck, out_auts);
if (rc == -EAGAIN) {
ast_log(LOG_WARNING, "SQN out of sequence, syncing.\n");
auth->ims_res_len = 0;
return -1;
}
if (rc) {
ast_log(LOG_ERROR, "Authentication failed.\n");
return -1;
}
auth->ims_res_len = 8;
if (volte_set_transport(&response->client_state->volte, response->old_request, &sec.alg, &sec.ealg,
out_ik, pj_strtoul(&sec.spi_c), pj_strtoul(&sec.spi_s),
pj_strtoul(&sec.port_c), pj_strtoul(&sec.port_s))) {
ast_log(LOG_ERROR, "Failed to set transport.\n");
return -1;
}
if (volte_add_security_verify(&response->client_state->volte, response->old_request)) {
ast_log(LOG_ERROR, "Failed to add security verify.\n");
return -1;
}
/* Remove existing autorization header. */
if (volte_del_authorization(response->old_request)) {
ast_log(LOG_ERROR, "Failed to remove authorization header.\n");
return -1;
}
/* Get security server */
if (volte_get_security_server(&response->client_state->volte, response->rdata, &sec)) {
ast_log(LOG_ERROR, "Failed to parse the security server header.\n");
return -1;
}
if (!(auth = ims_get_sip_auth(&response->client_state->outbound_auths)))
return -1;
rc = volte_authenticate(&response->client_state->volte, response->rdata,
(response->code == 401) ? PJSIP_H_WWW_AUTHENTICATE : PJSIP_H_PROXY_AUTHENTICATE,
auth->usim_opc, auth->usim_k, auth->usim_sqn, (uint8_t *)auth->ims_res,
out_ik, out_ck, out_auts);
if (rc == -EAGAIN) {
if (response->client_state->ims_state == IMS_STATE_RESYNC) {
ast_log(LOG_ERROR, "SQN out of sequence again, aborting.\n");
return -1;
}
ast_log(LOG_WARNING, "SQN out of sequence, syncing.\n");
auth->ims_res_len = 0;
response->client_state->ims_state = IMS_STATE_RESYNC;
return 0;
}
if (rc) {
ast_log(LOG_ERROR, "Authentication failed.\n");
return -1;
}
auth->ims_res_len = 8;
if (volte_set_transport(&response->client_state->volte, response->old_request, &sec.alg, &sec.ealg,
out_ik, pj_strtoul(&sec.spi_c), pj_strtoul(&sec.spi_s),
pj_strtoul(&sec.port_c), pj_strtoul(&sec.port_s))) {
ast_log(LOG_ERROR, "Failed to set transport.\n");
return -1;
}
if (volte_add_security_verify(&response->client_state->volte, response->old_request)) {
ast_log(LOG_ERROR, "Failed to add security verify.\n");
return -1;
}
if (response->client_state->ims_state == IMS_STATE_REGISTER)
response->client_state->ims_state = IMS_STATE_RESPONSE;
else
response->client_state->ims_state = IMS_STATE_RESYNC_RESPONSE;
response->client_state->auth_attempted = 0;
return 0;
}
@ -1436,7 +1455,7 @@ static int handle_registration_response(void *data)
pjsip_regc_info info;
char server_uri[PJSIP_MAX_URL_SIZE];
char client_uri[PJSIP_MAX_URL_SIZE];
bool ims_failed = false;
uint8_t auts[14];
if (response->client_state->status == SIP_REGISTRATION_STOPPED) {
ao2_ref(response, -1);
@ -1451,6 +1470,13 @@ static int handle_registration_response(void *data)
ast_debug(1, "Processing REGISTER response %d from server '%s' for client '%s'\n",
response->code, server_uri, client_uri);
if ((response->code == 401 || response->code == 407) && response->client_state->ims_aka) {
if (handle_ims_unauthorized(response, auts)) {
response->client_state->ims_state = IMS_STATE_FAILED;
goto ims_failed;
}
}
if (response->code == 408 || response->code == 503) {
if ((ast_sip_failover_request(response->old_request))) {
int res = registration_client_send(response->client_state, response->old_request);
@ -1468,11 +1494,6 @@ static int handle_registration_response(void *data)
pjsip_cseq_hdr *cseq_hdr;
pjsip_tx_data *tdata;
if (response->client_state->ims_aka) {
if (handle_ims_unauthorized(response))
ims_failed = true;
}
if (response->client_state->security_negotiation == AST_SIP_SECURITY_NEG_MEDIASEC) {
struct sip_outbound_registration *reg = NULL;
struct ast_sip_endpoint *endpt = NULL;
@ -1513,10 +1534,15 @@ static int handle_registration_response(void *data)
schedule_registration(response->client_state, 0);
ao2_ref(response, -1);
return 0;
} else if (!ims_failed && !ast_sip_create_request_with_auth(&response->client_state->outbound_auths,
} else if (!ast_sip_create_request_with_auth(&response->client_state->outbound_auths,
response->rdata, response->old_request, &tdata)) {
if (response->client_state->ims_state == IMS_STATE_RESYNC) {
if (volte_add_auts(&response->client_state->volte, tdata, auts)) {
ast_log(LOG_ERROR, "Failed to add authentication token.\n");
goto ims_failed;
}
}
response->client_state->auth_attempted = 1;
response->client_state->ims_state = IMS_STATE_AUTHENTICATE;
ast_debug(1, "Sending authenticated REGISTER to server '%s' from client '%s'\n",
server_uri, client_uri);
pjsip_tx_data_add_ref(tdata);
@ -1538,6 +1564,7 @@ static int handle_registration_response(void *data)
}
/* Otherwise, fall through so the failure is processed appropriately */
}
ims_failed:
response->client_state->ims_state = IMS_STATE_REGISTER;
response->client_state->auth_attempted = 0;
@ -2045,7 +2072,6 @@ static int ims_add_outbound_initial_authorization(pjsip_tx_data *tdata, const ch
if (!(auth = ims_get_sip_auth(auth_vector)))
return -1;
printf("JOLLY und hier hat auths den pointer %p\n", auth);
volte_init_authorization(tdata, fromdomain, auth->auth_user);

View File

@ -34,6 +34,7 @@ static int aes_128_encrypt_block(const u8 *key, const u8 *plain, u8 *encr)
return 0;
}
#if 0
void hexdump(int level, const char *file, int line, const char *func, const char *text, const uint8_t *data, int len)
{
char s[3 * len + 2], *p;
@ -44,6 +45,7 @@ void hexdump(int level, const char *file, int line, const char *func, const char
}
ast_log(level, file, line, func, "%s: %s\n", text, s);
}
#endif
/**
@ -299,50 +301,66 @@ int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
u8 mac_a[8], ak[6], rx_sqn[6];
const u8 *amf;
#ifdef hexdump
hexdump(LOG_DEBUG, "Milenage: OPC", opc, 16);
hexdump(LOG_DEBUG, "Milenage: K", k, 16);
hexdump(LOG_DEBUG, "Milenage: AUTN", autn, 16);
hexdump(LOG_DEBUG, "Milenage: RAND", _rand, 16);
#endif
if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
return -1;
*res_len = 8;
#ifdef hexdump
hexdump(LOG_DEBUG, "Milenage: RES", res, *res_len);
hexdump(LOG_DEBUG, "Milenage: CK", ck, 16);
hexdump(LOG_DEBUG, "Milenage: IK", ik, 16);
hexdump(LOG_DEBUG, "Milenage: AK", ak, 6);
#endif
/* AUTN = (SQN ^ AK) || AMF || MAC */
for (i = 0; i < 6; i++)
rx_sqn[i] = autn[i] ^ ak[i];
#ifdef hexdump
hexdump(LOG_DEBUG, "Milenage: RX SQN", rx_sqn, 6);
hexdump(LOG_DEBUG, "Milenage: SQN", sqn, 6);
#endif
if (memcmp(rx_sqn, sqn, 6) <= 0) {
u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
return -1;
#ifdef hexdump
hexdump(LOG_DEBUG, "Milenage: AK*", ak, 6);
#endif
for (i = 0; i < 6; i++)
auts[i] = sqn[i] ^ ak[i];
if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6))
return -1;
#ifdef hexdump
hexdump(LOG_DEBUG, "Milenage: AUTS", auts, 14);
#endif
return -2;
}
amf = autn + 6;
#ifdef hexdump
hexdump(LOG_DEBUG, "Milenage: AMF", amf, 2);
#endif
if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL))
return -1;
#ifdef hexdump
hexdump(LOG_DEBUG, "Milenage: MAC_A", mac_a, 8);
#endif
if (memcmp(mac_a, autn + 8, 8) != 0) {
#ifdef hexdump
ast_log(LOG_DEBUG, "Milenage: MAC mismatch");
hexdump(LOG_DEBUG, "Milenage: Received MAC_A",
autn + 8, 8);
#endif
return -1;
}

View File

@ -7,8 +7,6 @@ typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
void hexdump(int level, const char *file, int line, const char *func, const char *text, const uint8_t *data, int len);
int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s);
int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,

View File

@ -81,7 +81,6 @@ static int transceive_mnl(struct mnl_socket *mnl_sock, const struct nlmsghdr *tx
fprintf(stderr, "ERR: cannot create IPsec SA: %s\n", strerror(errno));
return -1;
}
puts("sent");
/* iterate until it is our answer, handing to mnl_cb_run, ... */
while (1) {

View File

@ -118,7 +118,7 @@ void volte_cleanup_xfrm(struct volte_states *volte)
if (volte->local_sa_c_set || volte->local_sa_s_set || volte->remote_sa_c_set || volte->remote_sa_s_set ||
volte->local_sp_c_set || volte->local_sp_s_set || volte->remote_sp_c_set || volte->remote_sp_s_set)
ast_log(LOG_DEBUG, "Remove old security associations/policies\n");
ast_debug(1, "Remove old security associations/policies\n");
/* Remove current security associations and policies. */
if (volte->local_sa_c_set) {
@ -178,16 +178,16 @@ pj_status_t volte_alloc_spi(struct volte_states *volte)
copy_pj_sockaddr_to_sockaddr_storage(&volte->remote_addr_s, &remote_addr_s);
#if 0
ast_log(LOG_DEBUG, "SPI allocation: local client: %s:%d remote server: %s:%d\n",
sockaddr_storage_to_string(&local_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->local_addr_c),
sockaddr_storage_to_string(&remote_addr_s, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->remote_addr_s));
ast_log(LOG_DEBUG, "SPI allocation: remote client: %s:%d local server: %s:%d\n",
sockaddr_storage_to_string(&remote_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->remote_addr_s),
sockaddr_storage_to_string(&local_addr_c, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->local_addr_s));
ast_debug(1, "SPI allocation: local client: %s:%d remote server: %s:%d\n",
sockaddr_storage_to_string(&local_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->local_addr_c),
sockaddr_storage_to_string(&remote_addr_s, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->remote_addr_s));
ast_debug(1, "SPI allocation: remote client: %s:%d local server: %s:%d\n",
sockaddr_storage_to_string(&remote_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->remote_addr_s),
sockaddr_storage_to_string(&local_addr_c, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->local_addr_s));
#endif
/* Allocate SPI-C and SPI-S towards remote peer. */
@ -204,7 +204,7 @@ spi_alloc_failed:
if (status)
goto spi_alloc_failed;
// volte->local_sa_c_set = PJ_TRUE;
ast_log(LOG_DEBUG, "SPI allocation: SPI-C=0x%08x SPI-S=0x%08x\n", volte->local_spi_s, volte->local_spi_c);
ast_debug(1, "SPI allocation: SPI-C=0x%08x SPI-S=0x%08x\n", volte->local_spi_s, volte->local_spi_c);
return PJ_SUCCESS;
}
@ -261,17 +261,17 @@ static pj_status_t volte_set_xfrm(struct volte_states *volte, const pj_str_t *al
copy_pj_sockaddr_to_sockaddr_storage(&volte->local_addr_s, &local_addr_s);
copy_pj_sockaddr_to_sockaddr_storage(&volte->remote_addr_s, &remote_addr_s);
ast_log(LOG_DEBUG, "xfrm: local client: %s:%d (SPI=0x%08x) remote server: %s:%d (SPI=0x%08x)\n",
sockaddr_storage_to_string(&local_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->local_addr_c), volte->local_spi_c,
sockaddr_storage_to_string(&remote_addr_s, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->remote_addr_s), volte->remote_spi_s);
ast_log(LOG_DEBUG, "xfrm: remote client: %s:%d (SPI=0x%08x) local server: %s:%d (SPI=0x%08x)\n",
sockaddr_storage_to_string(&remote_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->remote_addr_s), volte->remote_spi_c,
sockaddr_storage_to_string(&local_addr_c, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->local_addr_s), volte->local_spi_s);
ast_log(LOG_DEBUG, "xfrm: alg: %s ealg: %s\n", auth_algo.algo.alg_name, ciph_algo.algo.alg_name);
ast_debug(1, "xfrm: local client: %s:%d (SPI=0x%08x) remote server: %s:%d (SPI=0x%08x)\n",
sockaddr_storage_to_string(&local_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->local_addr_c), volte->local_spi_c,
sockaddr_storage_to_string(&remote_addr_s, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->remote_addr_s), volte->remote_spi_s);
ast_debug(1, "xfrm: remote client: %s:%d (SPI=0x%08x) local server: %s:%d (SPI=0x%08x)\n",
sockaddr_storage_to_string(&remote_addr_c, src_str, sizeof(src_str)),
pj_sockaddr_get_port(&volte->remote_addr_s), volte->remote_spi_c,
sockaddr_storage_to_string(&local_addr_c, dst_str, sizeof(dst_str)),
pj_sockaddr_get_port(&volte->local_addr_s), volte->local_spi_s);
ast_debug(1, "xfrm: alg: %s ealg: %s\n", auth_algo.algo.alg_name, ciph_algo.algo.alg_name);
status = xfrm_sa_add(g_mnl_socket, volte->remote_spi_s, (const struct sockaddr *)&local_addr_c,
(const struct sockaddr *)&remote_addr_s, volte->remote_spi_s,
@ -471,8 +471,8 @@ pj_status_t volte_init_authorization(pjsip_tx_data *tdata, const char *fromdomai
pj_status_t status;
snprintf(authorization, sizeof(authorization),
"Digest uri=\"sip:%s\",usernmame=\"%s@%s\",response=\"\",realm=\"%s\",nonce=\"\"",
fromdomain, username, fromdomain, fromdomain);
"Digest uri=\"sip:%s\",usernmame=\"%s\",response=\"\",realm=\"%s\",nonce=\"\"",
fromdomain, username, fromdomain);
const pj_str_t authorization_str = {authorization, strlen(authorization)};
status = add_value_string_hdr(tdata, &STR_AUTHORIZATION, &authorization_str);
@ -497,7 +497,7 @@ pj_status_t volte_del_authorization(pjsip_tx_data *tdata)
}
/* Reset old transport and clear IPSec transformations */
pj_status_t volte_reset_transport(struct volte_states *volte, pjsip_tx_data *tdata)
pj_status_t volte_reset_transport(struct volte_states *volte)
{
pj_status_t status;
int old_port_c;
@ -508,22 +508,18 @@ pj_status_t volte_reset_transport(struct volte_states *volte, pjsip_tx_data *tda
/* Cleanup old transport. */
old_port_c = pj_sockaddr_get_port(&volte->local_addr_c);
if (old_port_c > 0 && old_port_c < 65535) {
if (!tdata->tp_info.transport) {
ast_log(LOG_ERROR, "The Message has not transport. Please fix!\n");
if (!volte->transport) {
ast_log(LOG_ERROR, "No transport set. Please fix!\n");
return -ENOTSUP;
}
/* Create socket with default transport port. */
if (!tdata->tp_info.transport->create_new_sock || !tdata->tp_info.transport->connect_new_sock) {
ast_log(LOG_ERROR, "The transport protocol does not support socket change. Please fix!\n");
return -ENOTSUP;
}
status = tdata->tp_info.transport->create_new_sock(tdata->tp_info.transport, NULL);
status = volte->transport->create_new_sock(volte->transport, NULL);
if (status != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Failed to get connection addresses (errno=%d).\n", errno);
return status;
}
status = tdata->tp_info.transport->connect_new_sock(tdata->tp_info.transport,
&volte->local_addr_c, &volte->remote_addr_s);
status = volte->transport->connect_new_sock(volte->transport,
&volte->local_addr_c, &volte->remote_addr_orig);
if (status != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Failed to change connection addresses (errno=%d).\n", errno);
return status;
@ -583,6 +579,7 @@ pj_status_t volte_set_transport(struct volte_states *volte, pjsip_tx_data *tdata
memcpy(&volte->local_addr_s, &tdata->tp_info.transport->factory->local_addr, sizeof(pj_sockaddr));
memcpy(&volte->remote_addr_c, &tdata->tp_info.dst_addr, sizeof(pj_sockaddr));
memcpy(&volte->remote_addr_s, &tdata->tp_info.dst_addr, sizeof(pj_sockaddr));
memcpy(&volte->remote_addr_orig, &tdata->tp_info.dst_addr, sizeof(pj_sockaddr));
pj_sockaddr_set_port(&volte->local_addr_c, local_port_c);
pj_sockaddr_set_port(&volte->local_addr_s, local_port_s);
pj_sockaddr_set_port(&volte->remote_addr_c, remote_port_c);
@ -595,7 +592,7 @@ pj_status_t volte_set_transport(struct volte_states *volte, pjsip_tx_data *tdata
/* Create socket with new transport port. */
if (!tdata->tp_info.transport) {
ast_log(LOG_ERROR, "The Message has not transport. Please fix!\n");
ast_log(LOG_ERROR, "The Message has no transport. Please fix!\n");
return -ENOTSUP;
}
if (!tdata->tp_info.transport->create_new_sock || !tdata->tp_info.transport->connect_new_sock) {
@ -613,6 +610,7 @@ pj_status_t volte_set_transport(struct volte_states *volte, pjsip_tx_data *tdata
ast_log(LOG_ERROR, "Failed to change connection addresses (errno=%d).\n", errno);
return status;
}
volte->transport = tdata->tp_info.transport;
return PJ_SUCCESS;
}
@ -807,16 +805,12 @@ pj_status_t volte_authenticate(struct volte_states *volte, pjsip_rx_data *rdata,
return status;
ast_base64decode(rand_auth, auth_hdr->challenge.digest.nonce.ptr, sizeof(rand_auth));
hexdump(LOG_DEBUG, "nonce", rand_auth, 32);
rc = milenage_check(opc, k, sqn, rand, autn, out_ik, out_ck, out_res, &out_res_len, out_auts);
printf("mileange rc=%d\n", rc);
if (rc == -1) {
ast_log(LOG_ERROR, "Milenage authentication failed.\n");
return -EINVAL;
}
hexdump(LOG_DEBUG, "IK", out_ik, 16);
hexdump(LOG_DEBUG, "CK", out_ck, 16);
if (rc == -2) {
/* Tell the caller to perform resync process. */
@ -825,3 +819,30 @@ hexdump(LOG_DEBUG, "CK", out_ck, 16);
return PJ_SUCCESS;
}
pj_status_t volte_add_auts(struct volte_states *volte, pjsip_tx_data *tdata, uint8_t *auts)
{
pjsip_authorization_hdr *auth_hdr;
char enc_auts[23] = "\" \"";
pjsip_param *param;
auth_hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &STR_AUTHORIZATION, NULL);
if (!auth_hdr) {
ast_log(LOG_ERROR, "Authorization header not found in TX message. Please fix!\n");
return -EINVAL;
}
/* Encode base64. */
ast_base64encode(enc_auts + 1, auts, 14, 21);
enc_auts[21] = '"';
/* Append 'auts' to Authorization header and replace that header. */
param = PJ_POOL_ALLOC_T(tdata->pool, pjsip_param);
if (!param)
return -ENOMEM;
param->name = STR_AUTS;
pj_strdup2(tdata->pool, &param->value, enc_auts);
pj_list_insert_before(&auth_hdr->credential.digest.other_param, param);
return PJ_SUCCESS;
}

View File

@ -12,6 +12,9 @@ struct volte_states {
pj_bool_t local_sp_c_set, remote_sp_s_set;
pj_bool_t remote_sp_c_set, local_sp_s_set;
pjsip_transport *transport;
pj_sockaddr remote_addr_orig;
char security_server[1024];
};
@ -36,7 +39,7 @@ pj_status_t volte_alloc_spi(struct volte_states *volte);
pj_status_t volte_add_sec_agree(pjsip_tx_data *tdata);
pj_status_t volte_init_authorization(pjsip_tx_data *tdata, const char *fromdomain, const char *username);
pj_status_t volte_del_authorization(pjsip_tx_data *tdata);
pj_status_t volte_reset_transport(struct volte_states *volte, pjsip_tx_data *tdata);
pj_status_t volte_reset_transport(struct volte_states *volte);
pj_status_t volte_add_security_client(struct volte_states *volte, pjsip_tx_data *tdata, int port_c, int port_s);
pj_status_t volte_set_transport(struct volte_states *volte, pjsip_tx_data *tdata, const pj_str_t *alg,
const pj_str_t *ealg, uint8_t *ik, uint32_t remote_spi_c, uint32_t remote_spi_s,
@ -46,3 +49,4 @@ pj_status_t volte_add_security_verify(struct volte_states *volte, pjsip_tx_data
pj_status_t volte_authenticate(struct volte_states *volte, pjsip_rx_data *rdata, pjsip_hdr_e auth_type,
const char *opc_str, const char *k_str, const char *sqn_str, uint8_t *out_res,
uint8_t *out_ik, uint8_t *out_ck, uint8_t *out_auts);
pj_status_t volte_add_auts(struct volte_states *volte, pjsip_tx_data *tdata, uint8_t *auts);

View File

@ -912,7 +912,6 @@ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
PJ_ASSERT_RETURN(tr && tdata && addr, PJ_EINVAL);
printf("JOLLY: pjsip_transport_send()\n");
/* Is it currently being sent? */
if (tdata->is_pending) {
pj_assert(!"Invalid operation step!");
@ -2582,7 +2581,6 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
(const pj_sockaddr*) remote,
addr_len, tdata, tp);
} else {
printf("jolly: call create_transport\n");
status = factory->create_transport(factory, mgr, mgr->endpt,
(const pj_sockaddr*) remote,
addr_len, tp);

View File

@ -635,7 +635,6 @@ static pj_status_t tcp_create( struct tcp_listener *listener,
pj_status_t status;
printf("jolly tcp_create() is_server=%d\n", is_server);
PJ_ASSERT_RETURN(sock != PJ_INVALID_SOCKET, PJ_EINVAL);
@ -1011,7 +1010,6 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
listener = (struct tcp_listener*)factory;
printf("jolly socket create sa_family=%d\n", rem_addr->addr.sa_family);
/* Create socket */
status = pj_sock_socket(rem_addr->addr.sa_family,
pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(),
@ -1039,8 +1037,6 @@ printf("jolly socket create sa_family=%d\n", rem_addr->addr.sa_family);
pj_sockaddr_cp(&local_addr, &listener->bound_addr);
pj_sockaddr_set_port(&local_addr, 0);
char buf[100];
printf("jolly socket bind ss_family=%d, addr=%s\n", local_addr.addr.sa_family, pj_sockaddr_print(&local_addr, buf, sizeof(buf), 1));
status = pj_sock_bind(sock, &local_addr,
pj_sockaddr_get_len(&local_addr));
if (status != PJ_SUCCESS) {
@ -1314,9 +1310,7 @@ static pj_status_t tcp_send_msg(pjsip_transport *transport,
* transmit data in the pending transmission list since we can not
* use the socket yet.
*/
printf("jolly socket send message\n");
if (tcp->has_pending_connect) {
printf("jolly socket connect is pending\n");
/*
* Looks like connect() is still in progress. Check again (this time
@ -1394,7 +1388,6 @@ static pj_status_t tcp_shutdown(pjsip_transport *transport)
struct tcp_transport *tcp = (struct tcp_transport*)transport;
/* Stop keep-alive timer. */
printf("jolly socket shutdown\n");
if (tcp->ka_timer.id) {
pjsip_endpt_cancel_timer(tcp->base.endpt, &tcp->ka_timer);
tcp->ka_timer.id = PJ_FALSE;
@ -1509,7 +1502,6 @@ static pj_bool_t on_connect_complete(pj_activesock_t *asock,
status = PJ_ECANCELLED;
}
printf("jolly socket connect complete\n");
/* Check connect() status */
if (status != PJ_SUCCESS) {
@ -1517,7 +1509,6 @@ printf("jolly socket connect complete\n");
/* Cancel all delayed transmits */
while (!pj_list_empty(&tcp->delayed_list)) {
printf("jolly socket queued message send now\n");
struct delayed_tdata *pending_tx;
pj_ioqueue_op_key_t *op_key;
@ -1799,19 +1790,15 @@ static pj_status_t tcp_create_new_sock(struct pjsip_transport *base,
int af = pjsip_transport_type_get_af(listener->factory.type);
pj_sock_t new_sock;
pj_status_t status;
// int addr_len;
pj_sockaddr addr;
puts("1");
/* Close old socket */
if (tcp->new_sock != PJ_INVALID_SOCKET) {
pj_sock_close(tcp->new_sock);
tcp->new_sock = PJ_INVALID_SOCKET;
}
puts("2");
/* Create new socket */
printf("jolly socket create sa_family=%d\n", af);
status = pj_sock_socket(af,
pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(),
0, &new_sock);
@ -1819,17 +1806,16 @@ printf("jolly socket create sa_family=%d\n", af);
return status;
if (!local_addr) {
puts("new addr");
local_addr = &addr;
local_addr = &addr;
pj_bzero(&addr, sizeof(*local_addr));
pj_sockaddr_cp(&addr, &listener->bound_addr);
pj_sockaddr_set_port(&addr, 0);
}
/* Apply QoS, if specified */
status = pj_sock_apply_qos2(new_sock, listener->qos_type,
&listener->qos_params,
2, listener->factory.obj_name,
status = pj_sock_apply_qos2(new_sock, listener->qos_type,
&listener->qos_params,
2, listener->factory.obj_name,
"outgoing SIP TCP socket");
/* Apply socket options, if specified */
@ -1851,10 +1837,7 @@ printf("jolly socket create sa_family=%d\n", af);
}
}
puts("3");
/* Bind new socket */
char buf[100];
printf("jolly socket bind ss_family=%d, addr=%s\n", local_addr->addr.sa_family, pj_sockaddr_print(local_addr, buf, sizeof(buf), 1));
status = pj_sock_bind(new_sock, local_addr,
pj_sockaddr_get_len(local_addr));
if (status != PJ_SUCCESS) {
@ -1862,17 +1845,6 @@ printf("jolly socket bind ss_family=%d, addr=%s\n", local_addr->addr.sa_family,
return status;
}
puts("4");
#if 0
/* Get the local addess */
addr_len = sizeof(*local_addr);
status = pj_sock_getsockname(new_sock, &local_addr, &addr_len);
if (status != PJ_SUCCESS) {
pj_sock_close(new_sock);
return status;
}
#endif
/* Store and return */
tcp->new_sock = new_sock;
return PJ_SUCCESS;