Advertisement
Guest User

Untitled

a guest
Mar 18th, 2012
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 8.51 KB | None | 0 0
  1. %%%----------------------------------------------------------------------
  2. %%% File    : ejabberd_auth_odbc.erl
  3. %%% Author  : Alexey Shchepin <[email protected]>
  4. %%% Purpose : Authentification via ODBC
  5. %%% Created : 12 Dec 2004 by Alexey Shchepin <[email protected]>
  6. %%%
  7. %%%
  8. %%% ejabberd, Copyright (C) 2002-2010   ProcessOne
  9. %%%
  10. %%% This program is free software; you can redistribute it and/or
  11. %%% modify it under the terms of the GNU General Public License as
  12. %%% published by the Free Software Foundation; either version 2 of the
  13. %%% License, or (at your option) any later version.
  14. %%%
  15. %%% This program is distributed in the hope that it will be useful,
  16. %%% but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18. %%% General Public License for more details.
  19. %%%
  20. %%% You should have received a copy of the GNU General Public License
  21. %%% along with this program; if not, write to the Free Software
  22. %%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  23. %%% 02111-1307 USA
  24. %%%
  25. %%%----------------------------------------------------------------------
  26.  
  27. -module(ejabberd_auth_odbc).
  28. -author('[email protected]').
  29.  
  30. %% External exports
  31. -export([start/1,
  32.      set_password/3,
  33.      check_password/3,
  34.      check_password/5,
  35.      try_register/3,
  36.      dirty_get_registered_users/0,
  37.      get_vh_registered_users/1,
  38.      get_vh_registered_users/2,
  39.      get_vh_registered_users_number/1,
  40.      get_vh_registered_users_number/2,
  41.      get_password/2,
  42.      get_password_s/2,
  43.      is_user_exists/2,
  44.      remove_user/2,
  45.      remove_user/3,
  46.      plain_password_required/0
  47.     ]).
  48.  
  49. -include("ejabberd.hrl").
  50.  
  51. %%%----------------------------------------------------------------------
  52. %%% Custom SHA added by Henrik P. Hessel 05/15/2011
  53. %%%----------------------------------------------------------------------
  54. sha_pass(Pass) ->
  55.     sha2:hexdigest512(string:concat(Pass, "YOUR SALT")).
  56.  
  57. %%%----------------------------------------------------------------------
  58. %%% API
  59. %%%----------------------------------------------------------------------
  60. start(_Host) ->
  61.     ok.
  62.  
  63. plain_password_required() ->
  64.     false.
  65.  
  66. %% @spec (User, Server, Password) -> true | false | {error, Error}
  67. check_password(User, Server, Password) ->
  68.     ShaPassword = sha_pass(Password),
  69.     case jlib:nodeprep(User) of
  70.     error ->
  71.         false;
  72.     LUser ->
  73.         Username = ejabberd_odbc:escape(LUser),
  74.         LServer = jlib:nameprep(Server),
  75.         try odbc_queries:get_password(LServer, Username) of
  76.         {selected, ["password"], [{ShaPassword}]} ->
  77.             Password /= ""; %% Password is correct, and not empty
  78.         {selected, ["password"], [{_Password2}]} ->
  79.             false; %% Password is not correct
  80.         {selected, ["password"], []} ->
  81.             false; %% Account does not exist
  82.         {error, _Error} ->
  83.             false %% Typical error is that table doesn't exist
  84.         catch
  85.         _:_ ->
  86.             false %% Typical error is database not accessible
  87.         end
  88.     end.
  89.  
  90. %% @spec (User, Server, Password, Digest, DigestGen) -> true | false | {error, Error}
  91. check_password(User, Server, Password, Digest, DigestGen) ->
  92.     ShaPassword = sha_pass(Password),
  93.     case jlib:nodeprep(User) of
  94.     error ->
  95.         false;
  96.     LUser ->
  97.         Username = ejabberd_odbc:escape(LUser),
  98.         LServer = jlib:nameprep(Server),
  99.         try odbc_queries:get_password(LServer, Username) of
  100.         %% Account exists, check if password is valid
  101.         {selected, ["password"], [{Passwd}]} ->
  102.             DigRes = if
  103.                  Digest /= "" ->
  104.                      Digest == DigestGen(Passwd);
  105.                  true ->
  106.                      false
  107.                  end,
  108.             if DigRes ->
  109.                 true;
  110.                true ->
  111.                 (Passwd == ShaPassword) and (Password /= "")
  112.             end;
  113.         {selected, ["password"], []} ->
  114.             false; %% Account does not exist
  115.         {error, _Error} ->
  116.             false %% Typical error is that table doesn't exist
  117.         catch
  118.         _:_ ->
  119.             false %% Typical error is database not accessible
  120.         end
  121.     end.
  122.  
  123. %% @spec (User::string(), Server::string(), Password::string()) ->
  124. %%       ok | {error, invalid_jid}
  125. set_password(User, Server, Password) ->
  126.     case jlib:nodeprep(User) of
  127.     error ->
  128.         {error, invalid_jid};
  129.     LUser ->
  130.         Username = ejabberd_odbc:escape(LUser),
  131.         Pass = ejabberd_odbc:escape(Password),
  132.         ShaPassword = sha_pass(Pass),
  133.         LServer = jlib:nameprep(Server),
  134.         case catch odbc_queries:set_password_t(LServer, Username, ShaPassword) of
  135.             {atomic, ok} -> ok;
  136.             Other -> {error, Other}
  137.         end
  138.     end.
  139.  
  140.  
  141. %% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid}
  142. try_register(User, Server, Password) ->
  143.     case jlib:nodeprep(User) of
  144.     error ->
  145.         {error, invalid_jid};
  146.     LUser ->
  147.         Username = ejabberd_odbc:escape(LUser),
  148.         Pass = ejabberd_odbc:escape(Password),
  149.         ShaPassword = sha_pass(Pass),
  150.         LServer = jlib:nameprep(Server),
  151.         case catch odbc_queries:add_user(LServer, Username, ShaPassword) of
  152.         {updated, 1} ->
  153.             {atomic, ok};
  154.         _ ->
  155.             {atomic, exists}
  156.         end
  157.     end.
  158.  
  159. dirty_get_registered_users() ->
  160.     Servers = ejabberd_config:get_vh_by_auth_method(odbc),
  161.     lists:flatmap(
  162.       fun(Server) ->
  163.           get_vh_registered_users(Server)
  164.       end, Servers).
  165.  
  166. get_vh_registered_users(Server) ->
  167.     LServer = jlib:nameprep(Server),
  168.     case catch odbc_queries:list_users(LServer) of
  169.     {selected, ["username"], Res} ->
  170.         [{U, LServer} || {U} <- Res];
  171.     _ ->
  172.         []
  173.     end.
  174.  
  175. get_vh_registered_users(Server, Opts) ->
  176.     LServer = jlib:nameprep(Server),
  177.     case catch odbc_queries:list_users(LServer, Opts) of
  178.     {selected, ["username"], Res} ->
  179.         [{U, LServer} || {U} <- Res];
  180.     _ ->
  181.         []
  182.     end.
  183.  
  184. get_vh_registered_users_number(Server) ->
  185.     LServer = jlib:nameprep(Server),
  186.     case catch odbc_queries:users_number(LServer) of
  187.     {selected, [_], [{Res}]} ->
  188.         list_to_integer(Res);
  189.     _ ->
  190.         0
  191.     end.
  192.  
  193. get_vh_registered_users_number(Server, Opts) ->
  194.     LServer = jlib:nameprep(Server),
  195.     case catch odbc_queries:users_number(LServer, Opts) of
  196.     {selected, [_], [{Res}]} ->
  197.         list_to_integer(Res);
  198.     _Other ->
  199.         0
  200.     end.
  201.  
  202. get_password(User, Server) ->
  203.     case jlib:nodeprep(User) of
  204.     error ->
  205.         false;
  206.     LUser ->
  207.         Username = ejabberd_odbc:escape(LUser),
  208.         LServer = jlib:nameprep(Server),
  209.         case catch odbc_queries:get_password(LServer, Username) of
  210.         {selected, ["password"], [{Password}]} ->
  211.             Password;
  212.         _ ->
  213.             false
  214.         end
  215.     end.
  216.  
  217. get_password_s(User, Server) ->
  218.     case jlib:nodeprep(User) of
  219.     error ->
  220.         "";
  221.     LUser ->
  222.         Username = ejabberd_odbc:escape(LUser),
  223.         LServer = jlib:nameprep(Server),
  224.         case catch odbc_queries:get_password(LServer, Username) of
  225.         {selected, ["password"], [{Password}]} ->
  226.             Password;
  227.         _ ->
  228.             ""
  229.         end
  230.     end.
  231.  
  232. %% @spec (User, Server) -> true | false | {error, Error}
  233. is_user_exists(User, Server) ->
  234.     case jlib:nodeprep(User) of
  235.     error ->
  236.         false;
  237.     LUser ->
  238.         Username = ejabberd_odbc:escape(LUser),
  239.         LServer = jlib:nameprep(Server),
  240.         try odbc_queries:get_password(LServer, Username) of
  241.         {selected, ["password"], [{_Password}]} ->
  242.             true; %% Account exists
  243.         {selected, ["password"], []} ->
  244.             false; %% Account does not exist
  245.         {error, Error} ->
  246.             {error, Error} %% Typical error is that table doesn't exist
  247.         catch
  248.         _:B ->
  249.             {error, B} %% Typical error is database not accessible
  250.         end
  251.     end.
  252.  
  253. %% @spec (User, Server) -> ok | error
  254. %% @doc Remove user.
  255. %% Note: it may return ok even if there was some problem removing the user.
  256. remove_user(User, Server) ->
  257.     case jlib:nodeprep(User) of
  258.     error ->
  259.         error;
  260.     LUser ->
  261.         Username = ejabberd_odbc:escape(LUser),
  262.         LServer = jlib:nameprep(Server),
  263.         catch odbc_queries:del_user(LServer, Username),
  264.         ok
  265.     end.
  266.  
  267. %% @spec (User, Server, Password) -> ok | error | not_exists | not_allowed
  268. %% @doc Remove user if the provided password is correct.
  269. remove_user(User, Server, Password) ->
  270.     case jlib:nodeprep(User) of
  271.     error ->
  272.         error;
  273.     LUser ->
  274.         Username = ejabberd_odbc:escape(LUser),
  275.         Pass = ejabberd_odbc:escape(Password),
  276.         LServer = jlib:nameprep(Server),
  277.         F = fun() ->
  278.             Result = odbc_queries:del_user_return_password(
  279.                    LServer, Username, Pass),
  280.             case Result of
  281.                 {selected, ["password"], [{Password}]} ->
  282.                 ok;
  283.                 {selected, ["password"], []} ->
  284.                 not_exists;
  285.                 _ ->
  286.                 not_allowed
  287.             end
  288.         end,
  289.         {atomic, Result} = odbc_queries:sql_transaction(LServer, F),
  290.         Result
  291.     end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement