lynxis lazus has uploaded this change for review. (
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36217?usp=email )
Change subject: WIP: implement sim auth resync
......................................................................
WIP: implement sim auth resync
Change-Id: I75413b0c4b491425c3b01d75fdd1674cf7f3bbde
---
M src/aaa_diameter_swm.erl
M src/aaa_diameter_swx.erl
M src/aaa_ue_fsm.erl
M src/epdg_diameter_swm.erl
M src/epdg_ue_fsm.erl
M src/gsup_server.erl
6 files changed, 65 insertions(+), 32 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/17/36217/1
diff --git a/src/aaa_diameter_swm.erl b/src/aaa_diameter_swm.erl
index 7fdc247..46798af 100644
--- a/src/aaa_diameter_swm.erl
+++ b/src/aaa_diameter_swm.erl
@@ -20,7 +20,7 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
-export([code_change/3, terminate/2]).
--export([auth_request/3, auth_compl_request/2, session_termination_request/1]).
+-export([auth_request/3, auth_request/4, auth_compl_request/2,
session_termination_request/1]).
-export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
-define(SERVER, ?MODULE).
@@ -48,7 +48,11 @@
% Rx from emulated SWm wire:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
auth_request(Imsi, PdpTypeNr, Apn) ->
- gen_server:cast(?SERVER, {epdg_auth_req, Imsi, PdpTypeNr, Apn}).
+ Authorization = [],
+ gen_server:cast(?SERVER, {epdg_auth_req, Imsi, PdpTypeNr, Apn, Authorization}).
+
+auth_request(Imsi, PdpTypeNr, Apn, Authorization) ->
+ gen_server:cast(?SERVER, {epdg_auth_req, Imsi, PdpTypeNr, Apn, Authorization}).
auth_compl_request(Imsi, Apn) ->
gen_server:cast(?SERVER, {epdg_auth_compl_req, Imsi, Apn}).
@@ -56,9 +60,9 @@
session_termination_request(Imsi) ->
gen_server:cast(?SERVER, {str, Imsi}).
-handle_cast({epdg_auth_req, Imsi, PdpTypeNr, Apn}, State0) ->
+handle_cast({epdg_auth_req, Imsi, PdpTypeNr, Apn, Authorization}, State0) ->
{Sess, State1} = find_or_new_swm_session(Imsi, State0),
- aaa_ue_fsm:ev_swm_auth_req(Sess#swm_session.pid, {PdpTypeNr, Apn}),
+ aaa_ue_fsm:ev_swm_auth_req(Sess#swm_session.pid, {PdpTypeNr, Apn, Authorization}),
{noreply, State1};
handle_cast({epdg_auth_compl_req, Imsi, Apn}, State) ->
@@ -153,4 +157,4 @@
delete_swm_session(Imsi, State) ->
SetRemoved = sets:del_element(Imsi, State#swm_state.ues),
- State#swm_state{ues = SetRemoved}.
\ No newline at end of file
+ State#swm_state{ues = SetRemoved}.
diff --git a/src/aaa_diameter_swx.erl b/src/aaa_diameter_swx.erl
index be301f2..6fa7a58 100644
--- a/src/aaa_diameter_swx.erl
+++ b/src/aaa_diameter_swx.erl
@@ -50,7 +50,7 @@
%% gen_server Function Exports
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
-export([code_change/3]).
--export([multimedia_auth_request/7]).
+-export([multimedia_auth_request/8]).
-export([server_assignment_request/3]).
-export([test/0, test/1]).
@@ -140,11 +140,11 @@
test("001011234567890").
test(IMSI) ->
- multimedia_auth_request(IMSI, 3, "EAP-AKA", 1, [], [], 33).
+ multimedia_auth_request(IMSI, 3, "EAP-AKA", 1, [], [], 33, []).
-multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey,
PdpTypeNr) ->
+multimedia_auth_request(IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey,
PdpTypeNr, Authorization) ->
gen_server:call(?SERVER,
- {mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey,
PdpTypeNr}}).
+ {mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey,
PdpTypeNr, Authorization}}).
% APN is optional and should be []
server_assignment_request(IMSI, Type, APN) ->
gen_server:call(?SERVER,
@@ -185,7 +185,7 @@
parse_saa(Saa) ->
{unknown_err, []}.
-handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr}},
{Pid, _Tag} = _From, State) ->
+handle_call({mar, {IMSI, NumAuthItems, AuthScheme, RAT, CKey, IntegrityKey, PdpTypeNr,
Authorization}}, {Pid, _Tag} = _From, State) ->
SessionId = diameter:session_id(application:get_env(?ENV_APP_NAME, origin_host,
?ENV_DEFAULT_ORIG_HOST)),
% RFC 4005 6.11.1 Framed-IP-Address AVP:
% "0xFFFFFFFE indicates that the NAS should select an address for the user
@@ -219,6 +219,7 @@
'SIP-Authentication-Scheme' = [AuthScheme],
'Confidentiality-Key' = CKey,
'Integrity-Key' = IntegrityKey,
+ 'SIP-Authorization' = Authorization,
'Framed-IP-Address' = IPv4Opt,
'Framed-IPv6-Prefix' = IPv6Opt
},
diff --git a/src/aaa_ue_fsm.erl b/src/aaa_ue_fsm.erl
index 7f70005..7297b6d 100644
--- a/src/aaa_ue_fsm.erl
+++ b/src/aaa_ue_fsm.erl
@@ -66,10 +66,10 @@
lager:info("ue_fsm start_link(~p)~n", [ServerName]),
gen_statem:start_link({local, ServerName}, ?MODULE, Imsi, [{debug, [trace]}]).
-ev_swm_auth_req(Pid, {PdpTypeNr, Apn}) ->
+ev_swm_auth_req(Pid, {PdpTypeNr, Apn, Authorization}) ->
lager:info("ue_fsm ev_swm_auth_req~n", []),
try
- gen_statem:call(Pid, {swm_auth_req, PdpTypeNr, Apn})
+ gen_statem:call(Pid, {swm_auth_req, PdpTypeNr, Apn, Authorization})
catch
exit:Err ->
{error, Err}
@@ -152,12 +152,10 @@
state_new(enter, _OldState, Data) ->
{keep_state, Data};
-state_new({call, From}, {swm_auth_req, PdpTypeNr, Apn}, Data) ->
- lager:info("ue_fsm state_new event=swm_auth_req {~p, ~p}, ~p~n",
[PdpTypeNr, Apn, Data]),
+state_new({call, From}, {swm_auth_req, PdpTypeNr, Apn, Authorization}, Data) ->
+ lager:info("ue_fsm state_new event=swm_auth_req {~p, ~p, ~p}, ~p~n",
[PdpTypeNr, Apn, Authorization, Data]),
% request the diameter code for a tuple
- CKey = [],
- IntegrityKey = [],
- case aaa_diameter_swx:multimedia_auth_request(Data#ue_fsm_data.imsi, 1,
"EAP-AKA", 1, CKey, IntegrityKey, PdpTypeNr) of
+ case aaa_diameter_swx:multimedia_auth_request(Data#ue_fsm_data.imsi, 1,
"EAP-AKA", 1, [], [], PdpTypeNr, Authorization) of
ok -> {next_state, state_wait_swx_maa, Data, [{reply,From,ok}]};
{error, Err} -> {keep_state, Data, [{reply,From,{error, Err}}]}
end;
@@ -274,4 +272,4 @@
Data1 = Data#ue_fsm_data{pgw_sess_active = false, s6b_resp_pid =
undefined},
{next_state, state_new, Data1, [{reply,From,ok}]}
end
- end.
\ No newline at end of file
+ end.
diff --git a/src/epdg_diameter_swm.erl b/src/epdg_diameter_swm.erl
index 9b010d9..d80a3b7 100644
--- a/src/epdg_diameter_swm.erl
+++ b/src/epdg_diameter_swm.erl
@@ -19,7 +19,7 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
-export([code_change/3, terminate/2]).
--export([auth_request/3, auth_compl_request/2, session_termination_request/1]).
+-export([auth_request/5, auth_compl_request/2, session_termination_request/1]).
-export([auth_response/2, auth_compl_response/2, session_termination_answer/2]).
-define(SERVER, ?MODULE).
@@ -33,13 +33,18 @@
{ok, #swm_state{}}.
-auth_request(Imsi, PdpTypeNr, Apn) ->
+auth_request(Imsi, PdpTypeNr, Apn, Auts, Rand) ->
% In Diameter we use Imsi as strings, as done by diameter module.
ImsiStr = binary_to_list(Imsi),
+ case {Auts, Rand} of
+ {[Auts2], [Rand2]} -> Authorization = [binary_to_list(<<Rand2/binary,
Auts2/binary>>)];
+ _ -> Authorization = []
+ end,
% epdg_auth_req: Swm Diameter message Diameter-EAP-Request 3GPP TS 29.273 7.2.2.1.1
% PdpTypeNr: SWm Diameter AVP "UE-Local-IP-Address"
% Apn: SWm Diameter AVP "Service-Selection"
- Result = gen_server:call(?SERVER, {epdg_auth_req, ImsiStr, PdpTypeNr, Apn}),
+ % Authorization: SWx Diameter AVP SIP-Authorization for resynchronisation of the
Simcard
+ Result = gen_server:call(?SERVER, {epdg_auth_req, ImsiStr, PdpTypeNr, Apn,
Authorization}),
case Result of
{ok, _Mar} ->
epdg_ue_fsm:received_swm_auth_response(self(), Result),
@@ -71,10 +76,10 @@
_ -> Result
end.
-handle_call({epdg_auth_req, Imsi, PdpTypeNr, Apn}, {Pid, _Tag} = _From, State0) ->
+handle_call({epdg_auth_req, Imsi, PdpTypeNr, Apn, Authorization}, {Pid, _Tag} = _From,
State0) ->
% we yet don't implement the Diameter SWm interface on the wire, we process the call
internally:
{_Sess, State1} = find_or_new_swm_session(Imsi, Pid, State0),
- ok = aaa_diameter_swm:auth_request(Imsi, PdpTypeNr, Apn),
+ ok = aaa_diameter_swm:auth_request(Imsi, PdpTypeNr, Apn, Authorization),
{reply, ok, State1};
handle_call({epdg_auth_compl_req, Imsi, Apn}, _From, State) ->
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl
index 291df26..d28b2d0 100644
--- a/src/epdg_ue_fsm.erl
+++ b/src/epdg_ue_fsm.erl
@@ -75,10 +75,10 @@
stop(SrvRef) ->
gen_statem:stop(SrvRef).
-auth_request(Pid, {PdpTypeNr, Apn}) ->
+auth_request(Pid, {PdpTypeNr, Apn, Auts, Rand}) ->
lager:info("ue_fsm auth_request~n", []),
try
- gen_statem:call(Pid, {auth_request, PdpTypeNr, Apn})
+ gen_statem:call(Pid, {auth_request, PdpTypeNr, Apn, Auts, Rand})
catch
exit:Err ->
{error, Err}
@@ -193,9 +193,9 @@
state_new(enter, _OldState, Data) ->
{keep_state, Data};
-state_new({call, From}, {auth_request, PdpTypeNr, Apn}, Data) ->
- lager:info("ue_fsm state_new event=auth_request {~p, ~p}, ~p~n",
[PdpTypeNr, Apn, Data]),
- case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi, PdpTypeNr, Apn) of
+state_new({call, From}, {auth_request, PdpTypeNr, Apn, Auts, Rand}, Data) ->
+ lager:info("ue_fsm state_new event=auth_request {~p, ~p}, ~p (Resync: ~p/~p)
~n", [PdpTypeNr, Apn, Data, Auts, Rand]),
+ case epdg_diameter_swm:auth_request(Data#ue_fsm_data.imsi, PdpTypeNr, Apn, Auts,
Rand) of
ok -> {next_state, state_wait_auth_resp, Data, [{reply,From,ok}]};
{error, Err} -> {stop_and_reply, Err, Data, [{reply,From,{error,Err}}]}
end;
@@ -222,6 +222,10 @@
state_authenticating(enter, _OldState, Data) ->
{keep_state, Data};
+state_authenticating({call, _From}, {auth_request, PdpTypeNr, Apn, Auts, Rand}, Data)
->
+ lager:info("ue_fsm state_authenticated event=auth_request {~p, ~p},
~p~n", [PdpTypeNr, Apn, Data]),
+ {next_state, state_new, Data, [postpone]};
+
state_authenticating({call, From}, lu_request, Data) ->
lager:info("ue_fsm state_authenticating event=lu_request, ~p~n",
[Data]),
% Rx "GSUP CEAI LU Req" is our way of saying Rx "Swm Diameter-EAP
REQ (DER) with EAP AVP containing successuful auth":
@@ -247,7 +251,7 @@
state_authenticated(enter, _OldState, Data) ->
{keep_state, Data};
-state_authenticated({call, _From}, {auth_request, PdpTypeNr, Apn}, Data) ->
+state_authenticated({call, _From}, {auth_request, PdpTypeNr, Apn, Auts, Rand}, Data)
->
lager:info("ue_fsm state_authenticated event=auth_request {~p, ~p},
~p~n", [PdpTypeNr, Apn, Data]),
{next_state, state_new, Data, [postpone]};
@@ -312,7 +316,7 @@
state_active(enter, _OldState, Data) ->
{keep_state, Data};
-state_active({call, _From}, {auth_request, PdpTypeNr, Apn}, Data) ->
+state_active({call, _From}, {auth_request, PdpTypeNr, Apn, Auts, Rand}, Data) ->
lager:info("ue_fsm state_active event=auth_request {~p, ~p}, ~p~n",
[PdpTypeNr, Apn, Data]),
gtp_u_tun:delete_pdp_context(Data#ue_fsm_data.tun_pdp_ctx),
Data1 = Data#ue_fsm_data{tun_pdp_ctx = undefined},
diff --git a/src/gsup_server.erl b/src/gsup_server.erl
index 3b69849..3715742 100644
--- a/src/gsup_server.erl
+++ b/src/gsup_server.erl
@@ -244,8 +244,20 @@
PdpTypeNr = ?GTP_PDP_ADDR_TYPE_NR_IPv4,
Apn = "*"
end,
+ case maps:find(auts, GsupMsgRx) of
+ {ok, <<_Auts:14/binary>>} ->
+ Auts = [_Auts];
+ error -> % Use some sane defaults:
+ Auts = []
+ end,
+ case maps:find(rand, GsupMsgRx) of
+ {ok, <<_Rand:16/binary>>} ->
+ Rand = [_Rand];
+ error -> % Use some sane defaults:
+ Rand = []
+ end,
{UE, State1} = find_or_new_gsups_ue(Imsi, State0),
- case epdg_ue_fsm:auth_request(UE#gsups_ue.pid, {PdpTypeNr, Apn}) of
+ case epdg_ue_fsm:auth_request(UE#gsups_ue.pid, {PdpTypeNr, Apn, Auts, Rand}) of
ok -> State2 = State1;
{error, Err} ->
lager:error("Auth Req for Imsi ~p failed: ~p~n", [Imsi, Err]),
@@ -423,4 +435,4 @@
case find_gsups_ue_by_imsi(Imsi, State) of
undefined -> State;
UE-> delete_gsups_ue(UE, State)
- end.
\ No newline at end of file
+ end.
--
To view, visit
https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36217?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: erlang/osmo-epdg
Gerrit-Branch: master
Gerrit-Change-Id: I75413b0c4b491425c3b01d75fdd1674cf7f3bbde
Gerrit-Change-Number: 36217
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lynxis(a)fe80.eu>
Gerrit-MessageType: newchange