aboutsummaryrefslogtreecommitdiff
path: root/src/cyrsasl.erl
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2013-03-14 10:33:02 +0100
committerBadlop <badlop@process-one.net>2013-03-14 10:33:02 +0100
commit9deb294328bb3f9eb6bd2c0e7cd500732e9b5830 (patch)
tree7e1066c130250627ee0abab44a135f583a28d07f /src/cyrsasl.erl
parentlist_to_integer/2 only works in OTP R14 and newer (diff)
Accumulated patch to binarize and indent code
Diffstat (limited to 'src/cyrsasl.erl')
-rw-r--r--src/cyrsasl.erl200
1 files changed, 117 insertions, 83 deletions
diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl
index 9d1377ffc..0672267b2 100644
--- a/src/cyrsasl.erl
+++ b/src/cyrsasl.erl
@@ -25,43 +25,76 @@
%%%----------------------------------------------------------------------
-module(cyrsasl).
+
-author('alexey@process-one.net').
--export([start/0,
- register_mechanism/3,
- listmech/1,
- server_new/7,
- server_start/3,
- server_step/2]).
+-export([start/0, register_mechanism/3, listmech/1,
+ server_new/7, server_start/3, server_step/2]).
-include("ejabberd.hrl").
--record(sasl_mechanism, {mechanism, module, password_type}).
--record(sasl_state, {service, myname, realm,
- get_password, check_password, check_password_digest,
- mech_mod, mech_state}).
+%%
+-export_type([
+ mechanism/0,
+ mechanisms/0,
+ sasl_mechanism/0
+]).
+
+-record(sasl_mechanism,
+ {mechanism = <<"">> :: mechanism() | '$1',
+ module :: atom(),
+ password_type = plain :: password_type() | '$2'}).
+
+-type(mechanism() :: binary()).
+-type(mechanisms() :: [mechanism(),...]).
+-type(password_type() :: plain | digest | scram).
+-type(props() :: [{username, binary()} |
+ {authzid, binary()} |
+ {auth_module, atom()}]).
+
+-type(sasl_mechanism() :: #sasl_mechanism{}).
--export([behaviour_info/1]).
+-record(sasl_state,
+{
+ service,
+ myname,
+ realm,
+ get_password,
+ check_password,
+ check_password_digest,
+ mech_mod,
+ mech_state
+}).
-behaviour_info(callbacks) ->
- [{mech_new, 4}, {mech_step, 2}];
-behaviour_info(_Other) ->
- undefined.
+-callback mech_new(binary(), fun(), fun(), fun()) -> any().
+-callback mech_step(any(), binary()) -> {ok, props()} |
+ {ok, props(), binary()} |
+ {continue, binary(), any()} |
+ {error, binary()} |
+ {error, binary(), binary()}.
start() ->
- ets:new(sasl_mechanism, [named_table,
- public,
- {keypos, #sasl_mechanism.mechanism}]),
+ ets:new(sasl_mechanism,
+ [named_table, public,
+ {keypos, #sasl_mechanism.mechanism}]),
cyrsasl_plain:start([]),
cyrsasl_digest:start([]),
cyrsasl_scram:start([]),
cyrsasl_anonymous:start([]),
ok.
+%%
+-spec(register_mechanism/3 ::
+(
+ Mechanim :: mechanism(),
+ Module :: module(),
+ PasswordType :: password_type())
+ -> any()
+).
+
register_mechanism(Mechanism, Module, PasswordType) ->
ets:insert(sasl_mechanism,
- #sasl_mechanism{mechanism = Mechanism,
- module = Module,
+ #sasl_mechanism{mechanism = Mechanism, module = Module,
password_type = PasswordType}).
%%% TODO: use callbacks
@@ -89,95 +122,96 @@ register_mechanism(Mechanism, Module, PasswordType) ->
%% end.
check_credentials(_State, Props) ->
- User = xml:get_attr_s(username, Props),
+ User = proplists:get_value(username, Props, <<>>),
case jlib:nodeprep(User) of
- error ->
- {error, "not-authorized"};
- "" ->
- {error, "not-authorized"};
- _LUser ->
- ok
+ error -> {error, <<"not-authorized">>};
+ <<"">> -> {error, <<"not-authorized">>};
+ _LUser -> ok
end.
+-spec(listmech/1 ::
+(
+ Host ::binary())
+ -> Mechanisms::mechanisms()
+).
+
listmech(Host) ->
Mechs = ets:select(sasl_mechanism,
[{#sasl_mechanism{mechanism = '$1',
- password_type = '$2',
- _ = '_'},
+ password_type = '$2', _ = '_'},
case catch ejabberd_auth:store_type(Host) of
- external ->
- [{'==', '$2', plain}];
- scram ->
- [{'/=', '$2', digest}];
- {'EXIT',{undef,[{Module,store_type,[]} | _]}} ->
- ?WARNING_MSG("~p doesn't implement the function store_type/0", [Module]),
- [];
- _Else ->
- []
+ external -> [{'==', '$2', plain}];
+ scram -> [{'/=', '$2', digest}];
+ {'EXIT', {undef, [{Module, store_type, []} | _]}} ->
+ ?WARNING_MSG("~p doesn't implement the function store_type/0",
+ [Module]),
+ [];
+ _Else -> []
end,
['$1']}]),
filter_anonymous(Host, Mechs).
server_new(Service, ServerFQDN, UserRealm, _SecFlags,
GetPassword, CheckPassword, CheckPasswordDigest) ->
- #sasl_state{service = Service,
- myname = ServerFQDN,
- realm = UserRealm,
- get_password = GetPassword,
+ #sasl_state{service = Service, myname = ServerFQDN,
+ realm = UserRealm, get_password = GetPassword,
check_password = CheckPassword,
- check_password_digest= CheckPasswordDigest}.
+ check_password_digest = CheckPasswordDigest}.
server_start(State, Mech, ClientIn) ->
- case lists:member(Mech, listmech(State#sasl_state.myname)) of
- true ->
- case ets:lookup(sasl_mechanism, Mech) of
- [#sasl_mechanism{module = Module}] ->
- {ok, MechState} = Module:mech_new(
- State#sasl_state.myname,
- State#sasl_state.get_password,
- State#sasl_state.check_password,
- State#sasl_state.check_password_digest),
- server_step(State#sasl_state{mech_mod = Module,
- mech_state = MechState},
- ClientIn);
- _ ->
- {error, "no-mechanism"}
- end;
- false ->
- {error, "no-mechanism"}
+ case lists:member(Mech,
+ listmech(State#sasl_state.myname))
+ of
+ true ->
+ case ets:lookup(sasl_mechanism, Mech) of
+ [#sasl_mechanism{module = Module}] ->
+ {ok, MechState} =
+ Module:mech_new(State#sasl_state.myname,
+ State#sasl_state.get_password,
+ State#sasl_state.check_password,
+ State#sasl_state.check_password_digest),
+ server_step(State#sasl_state{mech_mod = Module,
+ mech_state = MechState},
+ ClientIn);
+ _ -> {error, <<"no-mechanism">>}
+ end;
+ false -> {error, <<"no-mechanism">>}
end.
server_step(State, ClientIn) ->
Module = State#sasl_state.mech_mod,
MechState = State#sasl_state.mech_state,
case Module:mech_step(MechState, ClientIn) of
- {ok, Props} ->
- case check_credentials(State, Props) of
- ok ->
- {ok, Props};
- {error, Error} ->
- {error, Error}
- end;
- {ok, Props, ServerOut} ->
- case check_credentials(State, Props) of
- ok ->
- {ok, Props, ServerOut};
- {error, Error} ->
- {error, Error}
- end;
- {continue, ServerOut, NewMechState} ->
- {continue, ServerOut,
- State#sasl_state{mech_state = NewMechState}};
- {error, Error, Username} ->
- {error, Error, Username};
- {error, Error} ->
- {error, Error}
+ {ok, Props} ->
+ case check_credentials(State, Props) of
+ ok -> {ok, Props};
+ {error, Error} -> {error, Error}
+ end;
+ {ok, Props, ServerOut} ->
+ case check_credentials(State, Props) of
+ ok -> {ok, Props, ServerOut};
+ {error, Error} -> {error, Error}
+ end;
+ {continue, ServerOut, NewMechState} ->
+ {continue, ServerOut, State#sasl_state{mech_state = NewMechState}};
+ {error, Error, Username} ->
+ {error, Error, Username};
+ {error, Error} ->
+ {error, Error}
end.
%% Remove the anonymous mechanism from the list if not enabled for the given
%% host
+%%
+-spec(filter_anonymous/2 ::
+(
+ Host :: binary(),
+ Mechs :: mechanisms())
+ -> mechanisms()
+).
+
filter_anonymous(Host, Mechs) ->
case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(Host) of
- true -> Mechs;
- false -> Mechs -- ["ANONYMOUS"]
+ true -> Mechs;
+ false -> Mechs -- [<<"ANONYMOUS">>]
end.