Compare commits
6 Commits
bba7c19d6c
...
a4b431c196
Author | SHA1 | Date |
---|---|---|
Andreas Eversberg | a4b431c196 | |
Andreas Eversberg | c25cf594d4 | |
Andreas Eversberg | 7016dc46d8 | |
Andreas Eversberg | 08bea4502b | |
Andreas Eversberg | 105ec37f86 | |
Andreas Eversberg | 0181ef5789 |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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, ¶m->value, enc_auts);
|
||||
pj_list_insert_before(&auth_hdr->credential.digest.other_param, param);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue