mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Document every functions to clarify the types to give and returned.
PR: EJABP-1 SVN Revision: 1852
This commit is contained in:
parent
35926b96b4
commit
b5c8b99272
@ -1,3 +1,9 @@
|
|||||||
|
2009-01-23 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||||
|
|
||||||
|
* src/cyrsasl.erl, src/cyrsasl_plain.erl, src/cyrsasl_anonymous.erl,
|
||||||
|
src/cyrsasl_digest.erl: Document every functions to clarify the types
|
||||||
|
to give and returned.
|
||||||
|
|
||||||
2009-01-23 Badlop <badlop@process-one.net>
|
2009-01-23 Badlop <badlop@process-one.net>
|
||||||
|
|
||||||
* src/odbc/mysql.sql: Fix complain about comment syntax
|
* src/odbc/mysql.sql: Fix complain about comment syntax
|
||||||
|
132
src/cyrsasl.erl
132
src/cyrsasl.erl
@ -34,18 +34,39 @@
|
|||||||
server_start/3,
|
server_start/3,
|
||||||
server_step/2]).
|
server_step/2]).
|
||||||
|
|
||||||
|
%% @type saslmechanism() = {sasl_mechanism, Mechanism, Module, Require_Plain}
|
||||||
|
%% Mechanism = string()
|
||||||
|
%% Module = atom()
|
||||||
|
%% Require_Plain = bool().
|
||||||
|
%% Registry entry of a supported SASL mechanism.
|
||||||
|
|
||||||
-record(sasl_mechanism, {mechanism, module, require_plain_password}).
|
-record(sasl_mechanism, {mechanism, module, require_plain_password}).
|
||||||
|
|
||||||
|
%% @type saslstate() = {sasl_state, Service, Myname, Realm, GetPassword, CheckPassword, Mech_Mod, Mech_State}
|
||||||
|
%% Service = string()
|
||||||
|
%% Myname = string()
|
||||||
|
%% Realm = string()
|
||||||
|
%% GetPassword = function()
|
||||||
|
%% CheckPassword = function()
|
||||||
|
%% Mech_Mod = atom()
|
||||||
|
%% Mech_State = term().
|
||||||
|
%% State of this process.
|
||||||
|
|
||||||
-record(sasl_state, {service, myname, realm,
|
-record(sasl_state, {service, myname, realm,
|
||||||
get_password, check_password,
|
get_password, check_password,
|
||||||
mech_mod, mech_state}).
|
mech_mod, mech_state}).
|
||||||
|
|
||||||
-export([behaviour_info/1]).
|
-export([behaviour_info/1]).
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
behaviour_info(callbacks) ->
|
behaviour_info(callbacks) ->
|
||||||
[{mech_new, 3}, {mech_step, 2}];
|
[{mech_new, 3}, {mech_step, 2}];
|
||||||
behaviour_info(_Other) ->
|
behaviour_info(_Other) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
|
%% @spec () -> ok
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
ets:new(sasl_mechanism, [named_table,
|
ets:new(sasl_mechanism, [named_table,
|
||||||
public,
|
public,
|
||||||
@ -55,35 +76,46 @@ start() ->
|
|||||||
cyrsasl_anonymous:start([]),
|
cyrsasl_anonymous:start([]),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
%% @spec (Mechanism, Module, Require_Plain) -> true
|
||||||
|
%% Mechanism = string()
|
||||||
|
%% Module = atom()
|
||||||
|
%% Require_Plain = bool()
|
||||||
|
|
||||||
register_mechanism(Mechanism, Module, RequirePlainPassword) ->
|
register_mechanism(Mechanism, Module, RequirePlainPassword) ->
|
||||||
ets:insert(sasl_mechanism,
|
ets:insert(sasl_mechanism,
|
||||||
#sasl_mechanism{mechanism = Mechanism,
|
#sasl_mechanism{mechanism = Mechanism,
|
||||||
module = Module,
|
module = Module,
|
||||||
require_plain_password = RequirePlainPassword}).
|
require_plain_password = RequirePlainPassword}).
|
||||||
|
|
||||||
%%% TODO: use callbacks
|
% TODO use callbacks
|
||||||
%%-include("ejabberd.hrl").
|
%-include("ejabberd.hrl").
|
||||||
%%-include("jlib.hrl").
|
%-include("jlib.hrl").
|
||||||
%%check_authzid(_State, Props) ->
|
%check_authzid(_State, Props) ->
|
||||||
%% AuthzId = xml:get_attr_s(authzid, Props),
|
% AuthzId = xml:get_attr_s(authzid, Props),
|
||||||
%% case jlib:string_to_jid(AuthzId) of
|
% case jlib:string_to_jid(AuthzId) of
|
||||||
%% error ->
|
% error ->
|
||||||
%% {error, "invalid-authzid"};
|
% {error, "invalid-authzid"};
|
||||||
%% JID ->
|
% JID ->
|
||||||
%% LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
% LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
||||||
%% {U, S, R} = jlib:jid_tolower(JID),
|
% {U, S, R} = jlib:jid_tolower(JID),
|
||||||
%% case R of
|
% case R of
|
||||||
%% "" ->
|
% "" ->
|
||||||
%% {error, "invalid-authzid"};
|
% {error, "invalid-authzid"};
|
||||||
%% _ ->
|
% _ ->
|
||||||
%% case {LUser, ?MYNAME} of
|
% case {LUser, ?MYNAME} of
|
||||||
%% {U, S} ->
|
% {U, S} ->
|
||||||
%% ok;
|
% ok;
|
||||||
%% _ ->
|
% _ ->
|
||||||
%% {error, "invalid-authzid"}
|
% {error, "invalid-authzid"}
|
||||||
%% end
|
% end
|
||||||
%% end
|
% end
|
||||||
%% end.
|
% end.
|
||||||
|
|
||||||
|
%% @spec (State, Props) -> ok | {error, 'not-authorized'}
|
||||||
|
%% State = saslstate()
|
||||||
|
%% Props = [{Key, Value}]
|
||||||
|
%% Key = atom()
|
||||||
|
%% Value = string()
|
||||||
|
|
||||||
check_credentials(_State, Props) ->
|
check_credentials(_State, Props) ->
|
||||||
case proplists:get_value(username, Props) of
|
case proplists:get_value(username, Props) of
|
||||||
@ -96,6 +128,10 @@ check_credentials(_State, Props) ->
|
|||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% @spec (Host) -> [Mechanism]
|
||||||
|
%% Host = string()
|
||||||
|
%% Mechanism = string()
|
||||||
|
|
||||||
listmech(Host) ->
|
listmech(Host) ->
|
||||||
RequirePlainPassword = ejabberd_auth:plain_password_required(Host),
|
RequirePlainPassword = ejabberd_auth:plain_password_required(Host),
|
||||||
|
|
||||||
@ -112,6 +148,14 @@ listmech(Host) ->
|
|||||||
['$1']}]),
|
['$1']}]),
|
||||||
filter_anonymous(Host, Mechs).
|
filter_anonymous(Host, Mechs).
|
||||||
|
|
||||||
|
%% @spec (Service, ServerFQDN, UserRealm, SecFlags, GetPassword, CheckPassword) -> saslstate()
|
||||||
|
%% Service = string()
|
||||||
|
%% ServerFQDN = string()
|
||||||
|
%% UserRealm = string()
|
||||||
|
%% SecFlags = [term()]
|
||||||
|
%% GetPassword = function()
|
||||||
|
%% CheckPassword = function()
|
||||||
|
|
||||||
server_new(Service, ServerFQDN, UserRealm, _SecFlags,
|
server_new(Service, ServerFQDN, UserRealm, _SecFlags,
|
||||||
GetPassword, CheckPassword) ->
|
GetPassword, CheckPassword) ->
|
||||||
#sasl_state{service = Service,
|
#sasl_state{service = Service,
|
||||||
@ -120,6 +164,22 @@ server_new(Service, ServerFQDN, UserRealm, _SecFlags,
|
|||||||
get_password = GetPassword,
|
get_password = GetPassword,
|
||||||
check_password = CheckPassword}.
|
check_password = CheckPassword}.
|
||||||
|
|
||||||
|
%% @spec (State, Mech, ClientIn) -> Ok | Continue | Error
|
||||||
|
%% State = saslstate()
|
||||||
|
%% Mech = string()
|
||||||
|
%% ClientIn = string()
|
||||||
|
%% Ok = {ok, Props}
|
||||||
|
%% Props = [Prop]
|
||||||
|
%% Prop = [{Key, Value}]
|
||||||
|
%% Key = atom()
|
||||||
|
%% Value = string()
|
||||||
|
%% Continue = {continue, ServerOut, New_State}
|
||||||
|
%% ServerOut = string()
|
||||||
|
%% New_State = saslstate()
|
||||||
|
%% Error = {error, Reason} | {error, Username, Reason}
|
||||||
|
%% Reason = term()
|
||||||
|
%% Username = string()
|
||||||
|
|
||||||
server_start(State, Mech, ClientIn) ->
|
server_start(State, Mech, ClientIn) ->
|
||||||
case lists:member(Mech, listmech(State#sasl_state.myname)) of
|
case lists:member(Mech, listmech(State#sasl_state.myname)) of
|
||||||
true ->
|
true ->
|
||||||
@ -139,6 +199,21 @@ server_start(State, Mech, ClientIn) ->
|
|||||||
{error, 'invalid-mechanism'}
|
{error, 'invalid-mechanism'}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% @spec (State, ClientIn) -> Ok | Continue | Error
|
||||||
|
%% State = saslstate()
|
||||||
|
%% ClientIn = string()
|
||||||
|
%% Ok = {ok, Props}
|
||||||
|
%% Props = [Prop]
|
||||||
|
%% Prop = [{Key, Value}]
|
||||||
|
%% Key = atom()
|
||||||
|
%% Value = string()
|
||||||
|
%% Continue = {continue, ServerOut, New_State}
|
||||||
|
%% ServerOut = string()
|
||||||
|
%% New_State = saslstate()
|
||||||
|
%% Error = {error, Reason} | {error, Username, Reason}
|
||||||
|
%% Reason = term()
|
||||||
|
%% Username = string()
|
||||||
|
|
||||||
server_step(State, ClientIn) ->
|
server_step(State, ClientIn) ->
|
||||||
Module = State#sasl_state.mech_mod,
|
Module = State#sasl_state.mech_mod,
|
||||||
MechState = State#sasl_state.mech_state,
|
MechState = State#sasl_state.mech_state,
|
||||||
@ -159,8 +234,15 @@ server_step(State, ClientIn) ->
|
|||||||
{error, Error}
|
{error, Error}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% Remove the anonymous mechanism from the list if not enabled for the given
|
%% @spec (Host, Mechs) -> [Filtered_Mechs]
|
||||||
%% host
|
%% Host = string()
|
||||||
|
%% Mechs = [Mech]
|
||||||
|
%% Mech = string()
|
||||||
|
%% Filtered_Mechs = [Mech]
|
||||||
|
%%
|
||||||
|
%% @doc Remove the anonymous mechanism from the list if not enabled for
|
||||||
|
%% the given host.
|
||||||
|
|
||||||
filter_anonymous(Host, Mechs) ->
|
filter_anonymous(Host, Mechs) ->
|
||||||
case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(Host) of
|
case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(Host) of
|
||||||
true -> Mechs;
|
true -> Mechs;
|
||||||
|
@ -31,18 +31,42 @@
|
|||||||
|
|
||||||
-behaviour(cyrsasl).
|
-behaviour(cyrsasl).
|
||||||
|
|
||||||
|
%% @type mechstate() = {state, Server}
|
||||||
|
%% Server = string().
|
||||||
|
|
||||||
-record(state, {server}).
|
-record(state, {server}).
|
||||||
|
|
||||||
|
%% @spec (Opts) -> true
|
||||||
|
%% Opts = term()
|
||||||
|
|
||||||
start(_Opts) ->
|
start(_Opts) ->
|
||||||
cyrsasl:register_mechanism("ANONYMOUS", ?MODULE, false),
|
cyrsasl:register_mechanism("ANONYMOUS", ?MODULE, false),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
%% @spec () -> ok
|
||||||
|
|
||||||
stop() ->
|
stop() ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
%% @spec (Host, GetPassword, CheckPassword) -> {ok, State}
|
||||||
|
%% Host = string()
|
||||||
|
%% GetPassword = function()
|
||||||
|
%% CheckPassword = function()
|
||||||
|
%% State = mechstate()
|
||||||
|
|
||||||
mech_new(Host, _GetPassword, _CheckPassword) ->
|
mech_new(Host, _GetPassword, _CheckPassword) ->
|
||||||
{ok, #state{server = Host}}.
|
{ok, #state{server = Host}}.
|
||||||
|
|
||||||
|
%% @spec (State, ClientIn) -> Ok | Error
|
||||||
|
%% State = mechstate()
|
||||||
|
%% ClientIn = string()
|
||||||
|
%% Ok = {ok, Props}
|
||||||
|
%% Props = [Prop]
|
||||||
|
%% Prop = {username, Username} | {auth_module, AuthModule}
|
||||||
|
%% Username = string()
|
||||||
|
%% AuthModule = ejabberd_auth_anonymous
|
||||||
|
%% Error = {error, 'not-authorized'}
|
||||||
|
|
||||||
mech_step(State, _ClientIn) ->
|
mech_step(State, _ClientIn) ->
|
||||||
%% We generate a random username:
|
%% We generate a random username:
|
||||||
User = lists:concat([randoms:get_string() | tuple_to_list(now())]),
|
User = lists:concat([randoms:get_string() | tuple_to_list(now())]),
|
||||||
|
@ -18,21 +18,56 @@
|
|||||||
|
|
||||||
-behaviour(cyrsasl).
|
-behaviour(cyrsasl).
|
||||||
|
|
||||||
|
%% @type mechstate() = {state, Step, Nonce, Username, AuthzId, GetPassword, AuthModule, Host}
|
||||||
|
%% Step = 1 | 3 | 5
|
||||||
|
%% Nonce = string()
|
||||||
|
%% Username = string()
|
||||||
|
%% AuthzId = string()
|
||||||
|
%% GetPassword = function()
|
||||||
|
%% AuthModule = atom()
|
||||||
|
%% Host = string().
|
||||||
|
|
||||||
-record(state, {step, nonce, username, authzid, get_password, auth_module,
|
-record(state, {step, nonce, username, authzid, get_password, auth_module,
|
||||||
host}).
|
host}).
|
||||||
|
|
||||||
|
%% @spec (Opts) -> true
|
||||||
|
%% Opts = term()
|
||||||
|
|
||||||
start(_Opts) ->
|
start(_Opts) ->
|
||||||
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true).
|
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true).
|
||||||
|
|
||||||
|
%% @spec () -> ok
|
||||||
|
|
||||||
stop() ->
|
stop() ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
%% @spec (Host, GetPassword, CheckPassword) -> {ok, State}
|
||||||
|
%% Host = string()
|
||||||
|
%% GetPassword = function()
|
||||||
|
%% CheckPassword = function()
|
||||||
|
%% State = mechstate()
|
||||||
|
|
||||||
mech_new(Host, GetPassword, _CheckPassword) ->
|
mech_new(Host, GetPassword, _CheckPassword) ->
|
||||||
{ok, #state{step = 1,
|
{ok, #state{step = 1,
|
||||||
nonce = randoms:get_string(),
|
nonce = randoms:get_string(),
|
||||||
host = Host,
|
host = Host,
|
||||||
get_password = GetPassword}}.
|
get_password = GetPassword}}.
|
||||||
|
|
||||||
|
%% @spec (State, ClientIn) -> Ok | Continue | Error
|
||||||
|
%% State = mechstate()
|
||||||
|
%% ClientIn = string()
|
||||||
|
%% Ok = {ok, Props}
|
||||||
|
%% Props = [Prop]
|
||||||
|
%% Prop = {username, Username} | {authzid, AuthzId} | {auth_module, AuthModule}
|
||||||
|
%% Username = string()
|
||||||
|
%% AuthzId = string()
|
||||||
|
%% AuthModule = atom()
|
||||||
|
%% Continue = {continue, ServerOut, New_State}
|
||||||
|
%% ServerOut = string()
|
||||||
|
%% New_State = mechstate()
|
||||||
|
%% Error = {error, Reason} | {error, Reason, Username}
|
||||||
|
%% Reason = term()
|
||||||
|
|
||||||
mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
|
mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
|
||||||
{continue,
|
{continue,
|
||||||
"nonce=\"" ++ Nonce ++
|
"nonce=\"" ++ Nonce ++
|
||||||
@ -85,9 +120,16 @@ mech_step(A, B) ->
|
|||||||
?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]),
|
?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]),
|
||||||
{error, 'bad-protocol'}.
|
{error, 'bad-protocol'}.
|
||||||
|
|
||||||
|
%% @spec (S) -> [{Key, Value}] | bad
|
||||||
|
%% S = string()
|
||||||
|
%% Key = string()
|
||||||
|
%% Value = string()
|
||||||
|
|
||||||
parse(S) ->
|
parse(S) ->
|
||||||
parse1(S, "", []).
|
parse1(S, "", []).
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
parse1([$= | Cs], S, Ts) ->
|
parse1([$= | Cs], S, Ts) ->
|
||||||
parse2(Cs, lists:reverse(S), "", Ts);
|
parse2(Cs, lists:reverse(S), "", Ts);
|
||||||
parse1([$, | Cs], [], Ts) ->
|
parse1([$, | Cs], [], Ts) ->
|
||||||
@ -101,6 +143,8 @@ parse1([], [], T) ->
|
|||||||
parse1([], _S, _T) ->
|
parse1([], _S, _T) ->
|
||||||
bad.
|
bad.
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
parse2([$\" | Cs], Key, Val, Ts) ->
|
parse2([$\" | Cs], Key, Val, Ts) ->
|
||||||
parse3(Cs, Key, Val, Ts);
|
parse3(Cs, Key, Val, Ts);
|
||||||
parse2([C | Cs], Key, Val, Ts) ->
|
parse2([C | Cs], Key, Val, Ts) ->
|
||||||
@ -108,6 +152,8 @@ parse2([C | Cs], Key, Val, Ts) ->
|
|||||||
parse2([], _, _, _) ->
|
parse2([], _, _, _) ->
|
||||||
bad.
|
bad.
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
parse3([$\" | Cs], Key, Val, Ts) ->
|
parse3([$\" | Cs], Key, Val, Ts) ->
|
||||||
parse4(Cs, Key, Val, Ts);
|
parse4(Cs, Key, Val, Ts);
|
||||||
parse3([$\\, C | Cs], Key, Val, Ts) ->
|
parse3([$\\, C | Cs], Key, Val, Ts) ->
|
||||||
@ -117,6 +163,8 @@ parse3([C | Cs], Key, Val, Ts) ->
|
|||||||
parse3([], _, _, _) ->
|
parse3([], _, _, _) ->
|
||||||
bad.
|
bad.
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
parse4([$, | Cs], Key, Val, Ts) ->
|
parse4([$, | Cs], Key, Val, Ts) ->
|
||||||
parse1(Cs, "", [{Key, lists:reverse(Val)} | Ts]);
|
parse1(Cs, "", [{Key, lists:reverse(Val)} | Ts]);
|
||||||
parse4([$\s | Cs], Key, Val, Ts) ->
|
parse4([$\s | Cs], Key, Val, Ts) ->
|
||||||
@ -127,6 +175,10 @@ parse4([], Key, Val, Ts) ->
|
|||||||
parse1([], "", [{Key, lists:reverse(Val)} | Ts]).
|
parse1([], "", [{Key, lists:reverse(Val)} | Ts]).
|
||||||
|
|
||||||
|
|
||||||
|
%% @spec (DigestURICase, JabberHost) -> bool()
|
||||||
|
%% DigestURICase = string()
|
||||||
|
%% JabberHost = string()
|
||||||
|
%%
|
||||||
%% @doc Check if the digest-uri is valid.
|
%% @doc Check if the digest-uri is valid.
|
||||||
%% RFC-2831 allows to provide the IP address in Host,
|
%% RFC-2831 allows to provide the IP address in Host,
|
||||||
%% however ejabberd doesn't allow that.
|
%% however ejabberd doesn't allow that.
|
||||||
@ -134,6 +186,7 @@ parse4([], Key, Val, Ts) ->
|
|||||||
%% is provided by several hosts (being one of them server3.example.org),
|
%% is provided by several hosts (being one of them server3.example.org),
|
||||||
%% then digest-uri can be like xmpp/server3.example.org/jabber.example.org
|
%% then digest-uri can be like xmpp/server3.example.org/jabber.example.org
|
||||||
%% In that case, ejabberd only checks the service name, not the host.
|
%% In that case, ejabberd only checks the service name, not the host.
|
||||||
|
|
||||||
is_digesturi_valid(DigestURICase, JabberHost) ->
|
is_digesturi_valid(DigestURICase, JabberHost) ->
|
||||||
DigestURI = exmpp_stringprep:to_lower(DigestURICase),
|
DigestURI = exmpp_stringprep:to_lower(DigestURICase),
|
||||||
case catch string:tokens(DigestURI, "/") of
|
case catch string:tokens(DigestURI, "/") of
|
||||||
@ -148,14 +201,20 @@ is_digesturi_valid(DigestURICase, JabberHost) ->
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
digit_to_xchar(D) when (D >= 0) and (D < 10) ->
|
digit_to_xchar(D) when (D >= 0) and (D < 10) ->
|
||||||
D + 48;
|
D + 48;
|
||||||
digit_to_xchar(D) ->
|
digit_to_xchar(D) ->
|
||||||
D + 87.
|
D + 87.
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
hex(S) ->
|
hex(S) ->
|
||||||
hex(S, []).
|
hex(S, []).
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
hex([], Res) ->
|
hex([], Res) ->
|
||||||
lists:reverse(Res);
|
lists:reverse(Res);
|
||||||
hex([N | Ns], Res) ->
|
hex([N | Ns], Res) ->
|
||||||
@ -163,6 +222,16 @@ hex([N | Ns], Res) ->
|
|||||||
digit_to_xchar(N div 16) | Res]).
|
digit_to_xchar(N div 16) | Res]).
|
||||||
|
|
||||||
|
|
||||||
|
%% @spec (KeyVals, User, Passwd, Nonce, AuthzId, A2Prefix) -> string()
|
||||||
|
%% KeyVals = [{Key, Value}]
|
||||||
|
%% Key = string()
|
||||||
|
%% Value = string()
|
||||||
|
%% User = string()
|
||||||
|
%% Passwd = string()
|
||||||
|
%% Nonce = string()
|
||||||
|
%% AuthzId = nil() | string()
|
||||||
|
%% A2Prefix = string()
|
||||||
|
|
||||||
response(KeyVals, User, Passwd, Nonce, AuthzId, A2Prefix) ->
|
response(KeyVals, User, Passwd, Nonce, AuthzId, A2Prefix) ->
|
||||||
Realm = proplists:get_value("realm", KeyVals, ""),
|
Realm = proplists:get_value("realm", KeyVals, ""),
|
||||||
CNonce = proplists:get_value("cnonce", KeyVals, ""),
|
CNonce = proplists:get_value("cnonce", KeyVals, ""),
|
||||||
|
@ -31,18 +31,44 @@
|
|||||||
|
|
||||||
-behaviour(cyrsasl).
|
-behaviour(cyrsasl).
|
||||||
|
|
||||||
|
%% @type mechstate() = {state, CheckPassword}
|
||||||
|
%% CheckPassword = function().
|
||||||
|
|
||||||
-record(state, {check_password}).
|
-record(state, {check_password}).
|
||||||
|
|
||||||
|
%% @spec (Opts) -> true
|
||||||
|
%% Opts = term()
|
||||||
|
|
||||||
start(_Opts) ->
|
start(_Opts) ->
|
||||||
cyrsasl:register_mechanism("PLAIN", ?MODULE, false),
|
cyrsasl:register_mechanism("PLAIN", ?MODULE, false),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
%% @spec () -> ok
|
||||||
|
|
||||||
stop() ->
|
stop() ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
%% @spec (Host, GetPassword, CheckPassword) -> {ok, State}
|
||||||
|
%% Host = string()
|
||||||
|
%% GetPassword = function()
|
||||||
|
%% CheckPassword = function()
|
||||||
|
%% State = mechstate()
|
||||||
|
|
||||||
mech_new(_Host, _GetPassword, CheckPassword) ->
|
mech_new(_Host, _GetPassword, CheckPassword) ->
|
||||||
{ok, #state{check_password = CheckPassword}}.
|
{ok, #state{check_password = CheckPassword}}.
|
||||||
|
|
||||||
|
%% @spec (State, ClientIn) -> Ok | Error
|
||||||
|
%% State = mechstate()
|
||||||
|
%% ClientIn = string()
|
||||||
|
%% Ok = {ok, Props}
|
||||||
|
%% Props = [Prop]
|
||||||
|
%% Prop = {username, Username} | {authzid, AuthzId} | {auth_module, AuthModule}
|
||||||
|
%% Username = string()
|
||||||
|
%% AuthzId = string()
|
||||||
|
%% AuthModule = atom()
|
||||||
|
%% Error = {error, Reason} | {error, Reason, Username}
|
||||||
|
%% Reason = term()
|
||||||
|
|
||||||
mech_step(State, ClientIn) ->
|
mech_step(State, ClientIn) ->
|
||||||
case parse(ClientIn) of
|
case parse(ClientIn) of
|
||||||
[AuthzId, User, Password] ->
|
[AuthzId, User, Password] ->
|
||||||
@ -58,9 +84,13 @@ mech_step(State, ClientIn) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
parse(S) ->
|
parse(S) ->
|
||||||
parse1(S, "", []).
|
parse1(S, "", []).
|
||||||
|
|
||||||
|
%% @hidden
|
||||||
|
|
||||||
parse1([0 | Cs], S, T) ->
|
parse1([0 | Cs], S, T) ->
|
||||||
parse1(Cs, "", [lists:reverse(S) | T]);
|
parse1(Cs, "", [lists:reverse(S) | T]);
|
||||||
parse1([C | Cs], S, T) ->
|
parse1([C | Cs], S, T) ->
|
||||||
|
Loading…
Reference in New Issue
Block a user