diff options
author | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2016-04-20 12:27:32 +0300 |
---|---|---|
committer | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2016-04-20 13:25:42 +0300 |
commit | 1aae8a9fda184b8a8fa139d9fc4bf2aa2c6ba8a0 (patch) | |
tree | 678fb932d5bda2fdc2961c054dbaea64d81f977c /src/ejabberd_auth_odbc.erl | |
parent | Rename ejabberd_sm_odbc -> ejabberd_sm_sql (diff) |
Rename odbc to sql everywhere
Diffstat (limited to 'src/ejabberd_auth_odbc.erl')
-rw-r--r-- | src/ejabberd_auth_odbc.erl | 483 |
1 files changed, 0 insertions, 483 deletions
diff --git a/src/ejabberd_auth_odbc.erl b/src/ejabberd_auth_odbc.erl deleted file mode 100644 index dc3248fe8..000000000 --- a/src/ejabberd_auth_odbc.erl +++ /dev/null @@ -1,483 +0,0 @@ -%%%---------------------------------------------------------------------- -%%% File : ejabberd_auth_odbc.erl -%%% Author : Alexey Shchepin <alexey@process-one.net> -%%% Purpose : Authentification via ODBC -%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2016 ProcessOne -%%% -%%% This program is free software; you can redistribute it and/or -%%% modify it under the terms of the GNU General Public License as -%%% published by the Free Software Foundation; either version 2 of the -%%% License, or (at your option) any later version. -%%% -%%% This program is distributed in the hope that it will be useful, -%%% but WITHOUT ANY WARRANTY; without even the implied warranty of -%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%%% General Public License for more details. -%%% -%%% You should have received a copy of the GNU General Public License along -%%% with this program; if not, write to the Free Software Foundation, Inc., -%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -%%% -%%%---------------------------------------------------------------------- - --module(ejabberd_auth_odbc). - --behaviour(ejabberd_config). - --author('alexey@process-one.net'). - --behaviour(ejabberd_auth). - --export([start/1, set_password/3, check_password/4, - check_password/6, try_register/3, - dirty_get_registered_users/0, get_vh_registered_users/1, - get_vh_registered_users/2, - get_vh_registered_users_number/1, - get_vh_registered_users_number/2, get_password/2, - get_password_s/2, is_user_exists/2, remove_user/2, - remove_user/3, store_type/0, plain_password_required/0, - convert_to_scram/1, opt_type/1]). - --include("ejabberd.hrl"). --include("logger.hrl"). - --define(SALT_LENGTH, 16). - -%%%---------------------------------------------------------------------- -%%% API -%%%---------------------------------------------------------------------- -start(_Host) -> ok. - -plain_password_required() -> - case is_scrammed() of - false -> false; - true -> true - end. - -store_type() -> - case is_scrammed() of - false -> plain; %% allows: PLAIN DIGEST-MD5 SCRAM - true -> scram %% allows: PLAIN SCRAM - end. - -%% @spec (User, AuthzId, Server, Password) -> true | false | {error, Error} -check_password(User, AuthzId, Server, Password) -> - if AuthzId /= <<>> andalso AuthzId /= User -> - false; - true -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - false; - (LUser == <<>>) or (LServer == <<>>) -> - false; - true -> - case is_scrammed() of - true -> - try odbc_queries:get_password_scram(LServer, LUser) of - {selected, - [{StoredKey, ServerKey, Salt, IterationCount}]} -> - Scram = - #scram{storedkey = StoredKey, - serverkey = ServerKey, - salt = Salt, - iterationcount = IterationCount}, - is_password_scram_valid(Password, Scram); - {selected, []} -> - false; %% Account does not exist - {error, _Error} -> - false %% Typical error is that table doesn't exist - catch - _:_ -> - false %% Typical error is database not accessible - end; - false -> - try odbc_queries:get_password(LServer, LUser) of - {selected, [{Password}]} -> - Password /= <<"">>; - {selected, [{_Password2}]} -> - false; %% Password is not correct - {selected, []} -> - false; %% Account does not exist - {error, _Error} -> - false %% Typical error is that table doesn't exist - catch - _:_ -> - false %% Typical error is database not accessible - end - end - end - end. - -%% @spec (User, AuthzId, Server, Password, Digest, DigestGen) -> true | false | {error, Error} -check_password(User, AuthzId, Server, Password, Digest, - DigestGen) -> - if AuthzId /= <<>> andalso AuthzId /= User -> - false; - true -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - false; - (LUser == <<>>) or (LServer == <<>>) -> - false; - true -> - case is_scrammed() of - false -> - try odbc_queries:get_password(LServer, LUser) of - %% Account exists, check if password is valid - {selected, [{Passwd}]} -> - DigRes = if Digest /= <<"">> -> - Digest == DigestGen(Passwd); - true -> false - end, - if DigRes -> true; - true -> (Passwd == Password) and (Password /= <<"">>) - end; - {selected, []} -> - false; %% Account does not exist - {error, _Error} -> - false %% Typical error is that table doesn't exist - catch - _:_ -> - false %% Typical error is database not accessible - end; - true -> - false - end - end - end. - -%% @spec (User::string(), Server::string(), Password::string()) -> -%% ok | {error, invalid_jid} -set_password(User, Server, Password) -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - {error, invalid_jid}; - (LUser == <<>>) or (LServer == <<>>) -> - {error, invalid_jid}; - true -> - case is_scrammed() of - true -> - Scram = password_to_scram(Password), - case catch odbc_queries:set_password_scram_t( - LServer, - LUser, - Scram#scram.storedkey, - Scram#scram.serverkey, - Scram#scram.salt, - Scram#scram.iterationcount - ) - of - {atomic, ok} -> ok; - Other -> {error, Other} - end; - false -> - case catch odbc_queries:set_password_t(LServer, - LUser, Password) - of - {atomic, ok} -> ok; - Other -> {error, Other} - end - end - end. - -%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} -try_register(User, Server, Password) -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - {error, invalid_jid}; - (LUser == <<>>) or (LServer == <<>>) -> - {error, invalid_jid}; - true -> - case is_scrammed() of - true -> - Scram = password_to_scram(Password), - case catch odbc_queries:add_user_scram( - LServer, - LUser, - Scram#scram.storedkey, - Scram#scram.serverkey, - Scram#scram.salt, - Scram#scram.iterationcount - ) of - {updated, 1} -> {atomic, ok}; - _ -> {atomic, exists} - end; - false -> - case catch odbc_queries:add_user(LServer, LUser, - Password) of - {updated, 1} -> {atomic, ok}; - _ -> {atomic, exists} - end - end - end. - -dirty_get_registered_users() -> - Servers = ejabberd_config:get_vh_by_auth_method(odbc), - lists:flatmap(fun (Server) -> - get_vh_registered_users(Server) - end, - Servers). - -get_vh_registered_users(Server) -> - case jid:nameprep(Server) of - error -> []; - <<>> -> []; - LServer -> - case catch odbc_queries:list_users(LServer) of - {selected, Res} -> - [{U, LServer} || {U} <- Res]; - _ -> [] - end - end. - -get_vh_registered_users(Server, Opts) -> - case jid:nameprep(Server) of - error -> []; - <<>> -> []; - LServer -> - case catch odbc_queries:list_users(LServer, Opts) of - {selected, Res} -> - [{U, LServer} || {U} <- Res]; - _ -> [] - end - end. - -get_vh_registered_users_number(Server) -> - case jid:nameprep(Server) of - error -> 0; - <<>> -> 0; - LServer -> - case catch odbc_queries:users_number(LServer) of - {selected, [{Res}]} -> - Res; - _ -> 0 - end - end. - -get_vh_registered_users_number(Server, Opts) -> - case jid:nameprep(Server) of - error -> 0; - <<>> -> 0; - LServer -> - case catch odbc_queries:users_number(LServer, Opts) of - {selected, [{Res}]} -> - Res; - _Other -> 0 - end - end. - -get_password(User, Server) -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - false; - (LUser == <<>>) or (LServer == <<>>) -> - false; - true -> - case is_scrammed() of - true -> - case catch odbc_queries:get_password_scram( - LServer, LUser) of - {selected, - [{StoredKey, ServerKey, Salt, IterationCount}]} -> - {jlib:decode_base64(StoredKey), - jlib:decode_base64(ServerKey), - jlib:decode_base64(Salt), - IterationCount}; - _ -> false - end; - false -> - case catch odbc_queries:get_password(LServer, LUser) - of - {selected, [{Password}]} -> Password; - _ -> false - end - end - end. - -get_password_s(User, Server) -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - <<"">>; - (LUser == <<>>) or (LServer == <<>>) -> - <<"">>; - true -> - case is_scrammed() of - false -> - case catch odbc_queries:get_password(LServer, LUser) of - {selected, [{Password}]} -> Password; - _ -> <<"">> - end; - true -> <<"">> - end - end. - -%% @spec (User, Server) -> true | false | {error, Error} -is_user_exists(User, Server) -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - false; - (LUser == <<>>) or (LServer == <<>>) -> - false; - true -> - try odbc_queries:get_password(LServer, LUser) of - {selected, [{_Password}]} -> - true; %% Account exists - {selected, []} -> - false; %% Account does not exist - {error, Error} -> {error, Error} - catch - _:B -> {error, B} - end - end. - -%% @spec (User, Server) -> ok | error -%% @doc Remove user. -%% Note: it may return ok even if there was some problem removing the user. -remove_user(User, Server) -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - error; - (LUser == <<>>) or (LServer == <<>>) -> - error; - true -> - catch odbc_queries:del_user(LServer, LUser), - ok - end. - -%% @spec (User, Server, Password) -> ok | error | not_exists | not_allowed -%% @doc Remove user if the provided password is correct. -remove_user(User, Server, Password) -> - LServer = jid:nameprep(Server), - LUser = jid:nodeprep(User), - if (LUser == error) or (LServer == error) -> - error; - (LUser == <<>>) or (LServer == <<>>) -> - error; - true -> - case is_scrammed() of - true -> - case check_password(User, <<"">>, Server, Password) of - true -> - remove_user(User, Server), - ok; - false -> not_allowed - end; - false -> - F = fun () -> - Result = odbc_queries:del_user_return_password( - LServer, LUser, Password), - case Result of - {selected, [{Password}]} -> ok; - {selected, []} -> not_exists; - _ -> not_allowed - end - end, - {atomic, Result} = odbc_queries:sql_transaction( - LServer, F), - Result - end - end. - -%%% -%%% SCRAM -%%% - -is_scrammed() -> - scram == - ejabberd_config:get_option({auth_password_format, ?MYNAME}, - fun(V) -> V end). - -password_to_scram(Password) -> - password_to_scram(Password, - ?SCRAM_DEFAULT_ITERATION_COUNT). - -password_to_scram(Password, IterationCount) -> - Salt = crypto:rand_bytes(?SALT_LENGTH), - SaltedPassword = scram:salted_password(Password, Salt, - IterationCount), - StoredKey = - scram:stored_key(scram:client_key(SaltedPassword)), - ServerKey = scram:server_key(SaltedPassword), - #scram{storedkey = jlib:encode_base64(StoredKey), - serverkey = jlib:encode_base64(ServerKey), - salt = jlib:encode_base64(Salt), - iterationcount = IterationCount}. - -is_password_scram_valid(Password, Scram) -> - IterationCount = Scram#scram.iterationcount, - Salt = jlib:decode_base64(Scram#scram.salt), - SaltedPassword = scram:salted_password(Password, Salt, - IterationCount), - StoredKey = - scram:stored_key(scram:client_key(SaltedPassword)), - jlib:decode_base64(Scram#scram.storedkey) == StoredKey. - --define(BATCH_SIZE, 1000). - -set_password_scram_t(Username, - StoredKey, ServerKey, Salt, IterationCount) -> - odbc_queries:update_t(<<"users">>, - [<<"username">>, - <<"password">>, - <<"serverkey">>, - <<"salt">>, - <<"iterationcount">>], - [Username, StoredKey, - ServerKey, Salt, - IterationCount], - [<<"username='">>, Username, - <<"'">>]). - -convert_to_scram(Server) -> - LServer = jid:nameprep(Server), - if - LServer == error; - LServer == <<>> -> - {error, {incorrect_server_name, Server}}; - true -> - F = fun () -> - case ejabberd_odbc:sql_query_t( - [<<"select username, password from users where " - "iterationcount=0 limit ">>, - integer_to_binary(?BATCH_SIZE), - <<";">>]) of - {selected, [<<"username">>, <<"password">>], []} -> - ok; - {selected, [<<"username">>, <<"password">>], Rs} -> - lists:foreach( - fun([LUser, Password]) -> - Username = ejabberd_odbc:escape(LUser), - Scram = password_to_scram(Password), - set_password_scram_t( - Username, - ejabberd_odbc:escape(Scram#scram.storedkey), - ejabberd_odbc:escape(Scram#scram.serverkey), - ejabberd_odbc:escape(Scram#scram.salt), - integer_to_binary(Scram#scram.iterationcount) - ) - end, Rs), - continue; - Err -> {bad_reply, Err} - end - end, - case odbc_queries:sql_transaction(LServer, F) of - {atomic, ok} -> ok; - {atomic, continue} -> convert_to_scram(Server); - {atomic, Error} -> {error, Error}; - Error -> Error - end - end. - -opt_type(auth_password_format) -> fun (V) -> V end; -opt_type(_) -> [auth_password_format]. |