Compare commits
2 Commits
a4b431c196
...
bde5092a06
Author | SHA1 | Date |
---|---|---|
Andreas Eversberg | bde5092a06 | |
Andreas Eversberg | dcffb4e1b1 |
|
@ -400,7 +400,7 @@ int ast_sip_initialize_sorcery_auth(void)
|
|||
ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "nonce_lifetime",
|
||||
"32", OPT_UINT_T, 0, FLDSET(struct ast_sip_auth, nonce_lifetime));
|
||||
ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "usim_ami",
|
||||
"no", OPT_BOOL_T, 0, FLDSET(struct ast_sip_auth, usim_ami));
|
||||
"no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_auth, usim_ami));
|
||||
ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "usim_opc",
|
||||
"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, usim_opc));
|
||||
ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "usim_k",
|
||||
|
|
|
@ -388,10 +388,14 @@ struct sip_outbound_registration {
|
|||
enum ims_state {
|
||||
/* !\brief Send first registration. */
|
||||
IMS_STATE_REGISTER,
|
||||
/* !\brief Wait for SIM keys to be provided. */
|
||||
IMS_STATE_REGISTER_SIM,
|
||||
/* !\brief Send second registration with authentication response. */
|
||||
IMS_STATE_RESPONSE,
|
||||
IMS_STATE_REGISTER_RESPONSE,
|
||||
/* !\brief Send second registration with resync token. */
|
||||
IMS_STATE_RESYNC,
|
||||
/* !\brief Wait for SIM keys to be provided after resync. */
|
||||
IMS_STATE_RESYNC_SIM,
|
||||
/* !\brief Send third registration with authentication response after resync. */
|
||||
IMS_STATE_RESYNC_RESPONSE,
|
||||
/* !\breif IMS registration process failed. */
|
||||
|
@ -885,8 +889,11 @@ static pj_status_t registration_client_send(struct sip_outbound_registration_cli
|
|||
|
||||
/* Create initial IMS headers and reset transport. */
|
||||
if (client_state->ims_aka && client_state->ims_state == IMS_STATE_REGISTER) {
|
||||
if (ims_registration_client(client_state, tdata))
|
||||
if (ims_registration_client(client_state, tdata)) {
|
||||
pjsip_tx_data_dec_ref(tdata);
|
||||
ao2_ref(client_state, -1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
status = pjsip_regc_send(client_state->client, tdata);
|
||||
|
@ -1392,7 +1399,8 @@ static int handle_ims_unauthorized(struct registration_response *response, uint8
|
|||
{
|
||||
struct security_server sec;
|
||||
struct ast_sip_auth *auth;
|
||||
uint8_t out_ik[16], out_ck[16];
|
||||
pj_str_t algo;
|
||||
uint8_t rand[16], autn[16], out_ik[16], out_ck[16];
|
||||
int rc;
|
||||
|
||||
/* Remove existing autorization header. */
|
||||
|
@ -1406,12 +1414,29 @@ static int handle_ims_unauthorized(struct registration_response *response, uint8
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (volte_get_auth(&response->client_state->volte, response->rdata,
|
||||
(response->code == 401) ? PJSIP_H_WWW_AUTHENTICATE : PJSIP_H_PROXY_AUTHENTICATE,
|
||||
&algo, rand, autn)) {
|
||||
ast_log(LOG_ERROR, "Failed to parse the authenticate 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,
|
||||
if (auth->usim_ami) {
|
||||
volte_send_authrequest(&algo, rand, autn);
|
||||
if (response->client_state->ims_state == IMS_STATE_REGISTER)
|
||||
response->client_state->ims_state = IMS_STATE_REGISTER_SIM;
|
||||
else
|
||||
response->client_state->ims_state = IMS_STATE_RESYNC_SIM;
|
||||
return 0;
|
||||
#warning das folgende muss gesplittet werden, es muss volte_auth aufgerufen werden oder es muss der authrequest gesendet werden. der authresponse muss weitermachen, aber nur wenn ein pendig-authrequest gesendet wurde.
|
||||
#warning das register muss per AMI gesteuert werden. wie muss die config aussehen,damit das nicht automatisch geht?
|
||||
}
|
||||
|
||||
rc = volte_authenticate(&response->client_state->volte, auth->usim_opc, auth->usim_k,
|
||||
auth->usim_sqn, rand, autn, (uint8_t *)auth->ims_res,
|
||||
out_ik, out_ck, out_auts);
|
||||
if (rc == -EAGAIN) {
|
||||
if (response->client_state->ims_state == IMS_STATE_RESYNC) {
|
||||
|
@ -1440,7 +1465,7 @@ static int handle_ims_unauthorized(struct registration_response *response, uint8
|
|||
return -1;
|
||||
}
|
||||
if (response->client_state->ims_state == IMS_STATE_REGISTER)
|
||||
response->client_state->ims_state = IMS_STATE_RESPONSE;
|
||||
response->client_state->ims_state = IMS_STATE_REGISTER_RESPONSE;
|
||||
else
|
||||
response->client_state->ims_state = IMS_STATE_RESYNC_RESPONSE;
|
||||
response->client_state->auth_attempted = 0;
|
||||
|
@ -1448,6 +1473,13 @@ static int handle_ims_unauthorized(struct registration_response *response, uint8
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ami_authresponse(struct mansession *s, const struct message *m)
|
||||
{
|
||||
// astman_send_error(s, m, "Park action failed\n");
|
||||
manager_event(0, "HALLO", "Meetme: \r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \brief Callback function for handling a response to a registration attempt */
|
||||
static int handle_registration_response(void *data)
|
||||
{
|
||||
|
@ -1475,6 +1507,11 @@ static int handle_registration_response(void *data)
|
|||
response->client_state->ims_state = IMS_STATE_FAILED;
|
||||
goto ims_failed;
|
||||
}
|
||||
/* Wait for the SIM to respond. */
|
||||
if (response->client_state->ims_state == IMS_STATE_REGISTER_SIM ||
|
||||
response->client_state->ims_state == IMS_STATE_RESYNC_SIM)
|
||||
return 0;
|
||||
#warning do ao2_ref(response, -1); once the sim responded or timed out
|
||||
}
|
||||
|
||||
if (response->code == 408 || response->code == 503) {
|
||||
|
@ -2982,6 +3019,7 @@ static int unload_module(void)
|
|||
ast_manager_unregister("PJSIPShowRegistrationsOutbound");
|
||||
ast_manager_unregister("PJSIPUnregister");
|
||||
ast_manager_unregister("PJSIPRegister");
|
||||
ast_manager_unregister("AuthResponse");
|
||||
|
||||
ast_cli_unregister_multiple(cli_outbound_registration, ARRAY_LEN(cli_outbound_registration));
|
||||
ast_sip_unregister_cli_formatter(cli_formatter);
|
||||
|
@ -3115,6 +3153,7 @@ static int load_module(void)
|
|||
ast_manager_register_xml("PJSIPUnregister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_unregister);
|
||||
ast_manager_register_xml("PJSIPRegister", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_register);
|
||||
ast_manager_register_xml("PJSIPShowRegistrationsOutbound", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, ami_show_outbound_registrations);
|
||||
ast_manager_register_xml_core("AuthResponse", 0, ami_authresponse);
|
||||
|
||||
/* Clear any previous statsd gauges in case we weren't shutdown cleanly */
|
||||
ast_statsd_log("PJSIP.registrations.count", AST_STATSD_GAUGE, 0);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "asterisk.h"
|
||||
#include "asterisk/utils.h"
|
||||
#include "asterisk/manager.h"
|
||||
|
||||
#include <pjsip.h>
|
||||
|
||||
|
@ -25,6 +26,7 @@
|
|||
#include "milenage.h"
|
||||
|
||||
#define fmt_str(str) (int)(str).slen, (str).ptr
|
||||
#define fmt_strp(strp) (int)(strp)->slen, (strp)->ptr
|
||||
|
||||
/* Socket for transform configuration */
|
||||
static struct mnl_socket *g_mnl_socket = NULL;
|
||||
|
@ -507,6 +509,7 @@ pj_status_t volte_reset_transport(struct volte_states *volte)
|
|||
|
||||
/* Cleanup old transport. */
|
||||
old_port_c = pj_sockaddr_get_port(&volte->local_addr_c);
|
||||
printf("port=%d\n", old_port_c);
|
||||
if (old_port_c > 0 && old_port_c < 65535) {
|
||||
if (!volte->transport) {
|
||||
ast_log(LOG_ERROR, "No transport set. Please fix!\n");
|
||||
|
@ -769,15 +772,11 @@ static pj_status_t my_hex_to_octet_string(const char *name, const char *input, u
|
|||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
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_get_auth(struct volte_states *volte, pjsip_rx_data *rdata, pjsip_hdr_e auth_type, pj_str_t *algo,
|
||||
uint8_t *rand, uint8_t *autn)
|
||||
{
|
||||
pjsip_www_authenticate_hdr *auth_hdr;
|
||||
uint8_t opc[16], k[16], sqn[6], rand_auth[32], *rand = rand_auth, *autn = rand_auth + 16;
|
||||
size_t out_res_len = 8;
|
||||
int rc;
|
||||
pj_status_t status;
|
||||
uint8_t rand_autn[32];
|
||||
|
||||
auth_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, auth_type, NULL);
|
||||
if (!auth_hdr || !auth_hdr->challenge.digest.nonce.ptr || !auth_hdr->challenge.digest.algorithm.ptr) {
|
||||
|
@ -794,6 +793,40 @@ pj_status_t volte_authenticate(struct volte_states *volte, pjsip_rx_data *rdata,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
*algo = auth_hdr->challenge.digest.algorithm;
|
||||
|
||||
ast_base64decode(rand_autn, auth_hdr->challenge.digest.nonce.ptr, sizeof(rand_autn));
|
||||
|
||||
memcpy(rand, rand_autn, 16);
|
||||
memcpy(autn, rand_autn + 16, 16);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
pj_status_t volte_send_authrequest(pj_str_t *algo, uint8_t *rand, uint8_t *autn)
|
||||
{
|
||||
char rand_str[33] = " ", autn_str[33] = " ";
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
sprintf(rand_str + 2 * i, "%02x", rand[i]);
|
||||
sprintf(autn_str + 2 * i, "%02x", autn[i]);
|
||||
}
|
||||
manager_event(0, "AuthRequest", "Algorithm:%.*s\r\nRAND:%s\r\nAUTN:%s",
|
||||
fmt_strp(algo), rand_str, autn_str);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
pj_status_t volte_authenticate(struct volte_states *volte, const char *opc_str, const char *k_str, const char *sqn_str,
|
||||
uint8_t *rand, uint8_t *autn, uint8_t *out_res, uint8_t *out_ik, uint8_t *out_ck,
|
||||
uint8_t *out_auts)
|
||||
{
|
||||
uint8_t opc[16], k[16], sqn[6];
|
||||
size_t out_res_len = 8;
|
||||
int rc;
|
||||
pj_status_t status;
|
||||
|
||||
status = my_hex_to_octet_string("OPC", opc_str, opc, sizeof(opc));
|
||||
if (status)
|
||||
return status;
|
||||
|
@ -804,8 +837,6 @@ pj_status_t volte_authenticate(struct volte_states *volte, pjsip_rx_data *rdata,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
ast_base64decode(rand_auth, auth_hdr->challenge.digest.nonce.ptr, sizeof(rand_auth));
|
||||
|
||||
rc = milenage_check(opc, k, sqn, rand, autn, out_ik, out_ck, out_res, &out_res_len, out_auts);
|
||||
if (rc == -1) {
|
||||
ast_log(LOG_ERROR, "Milenage authentication failed.\n");
|
||||
|
|
|
@ -46,7 +46,10 @@ pj_status_t volte_set_transport(struct volte_states *volte, pjsip_tx_data *tdata
|
|||
uint16_t remote_port_c, uint16_t remote_port_s);
|
||||
pj_status_t volte_get_security_server(struct volte_states *volte, pjsip_rx_data *rdata, struct security_server *sec);
|
||||
pj_status_t volte_add_security_verify(struct volte_states *volte, pjsip_tx_data *tdata);
|
||||
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_get_auth(struct volte_states *volte, pjsip_rx_data *rdata, pjsip_hdr_e auth_type, pj_str_t *algo,
|
||||
uint8_t *rand, uint8_t *autn);
|
||||
pj_status_t volte_send_authrequest(pj_str_t *algo, uint8_t *rand, uint8_t *autn);
|
||||
pj_status_t volte_authenticate(struct volte_states *volte, const char *opc_str, const char *k_str, const char *sqn_str,
|
||||
uint8_t *rand, uint8_t *autn, 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);
|
||||
|
|
Loading…
Reference in New Issue