~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/inets/src/mod_security.erl

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
%% ``The contents of this file are subject to the Erlang Public License,
2
 
%% Version 1.1, (the "License"); you may not use this file except in
3
 
%% compliance with the License. You should have received a copy of the
4
 
%% Erlang Public License along with this software. If not, it can be
5
 
%% retrieved via the world wide web at http://www.erlang.org/.
6
 
%% 
7
 
%% Software distributed under the License is distributed on an "AS IS"
8
 
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
 
%% the License for the specific language governing rights and limitations
10
 
%% under the License.
11
 
%% 
12
 
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
 
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
 
%% AB. All Rights Reserved.''
15
 
%% 
16
 
%%     $Id$
17
 
%%
18
 
-module(mod_security).
19
 
 
20
 
%% Security Audit Functionality
21
 
 
22
 
%% User API exports
23
 
-export([list_blocked_users/1, list_blocked_users/2, list_blocked_users/3, 
24
 
         block_user/4, block_user/5, 
25
 
         unblock_user/2, unblock_user/3, unblock_user/4,
26
 
         list_auth_users/1, list_auth_users/2, list_auth_users/3]).
27
 
 
28
 
%% module API exports
29
 
-export([do/1, load/2, store/2, remove/1]).
30
 
 
31
 
-include("httpd.hrl").
32
 
 
33
 
-define(VMODULE,"SEC").
34
 
-include("httpd_verbosity.hrl").
35
 
 
36
 
 
37
 
%% do/1
38
 
do(Info) ->
39
 
    ?vdebug("~n   do with ~n   Info: ~p",[Info]),
40
 
    %% Check and see if any user has been authorized.
41
 
    case httpd_util:key1search(Info#mod.data,remote_user,not_defined_user) of
42
 
        not_defined_user ->
43
 
            %% No user has been authorized.
44
 
            case httpd_util:key1search(Info#mod.data, status) of
45
 
                %% A status code has been generated!
46
 
                {401, PhraseArgs, Reason} ->
47
 
                    case httpd_util:key1search(Info#mod.parsed_header,
48
 
                                               "authorization") of
49
 
                        undefined ->
50
 
                            %% Not an authorization attempt (server just replied to
51
 
                            %% challenge for authentication)
52
 
                            {proceed, Info#mod.data};
53
 
                        [$B,$a,$s,$i,$c,$ |EncodedString] ->
54
 
                            %% Someone tried to authenticate, and obviously failed!
55
 
                            ?vlog("~n   Authentication failed: ~s",
56
 
                                  [EncodedString]),
57
 
                            report_failed(Info, EncodedString,"Failed authentication"),
58
 
                            take_failed_action(Info, EncodedString),
59
 
                            {proceed, Info#mod.data}
60
 
                    end;
61
 
                _ ->
62
 
                    {proceed, Info#mod.data}
63
 
            end;
64
 
        User ->
65
 
            %% A user has been authenticated, now is he blocked ?
66
 
            ?vtrace("user '~p' authentication",[User]),
67
 
            Path = mod_alias:path(Info#mod.data,
68
 
                                  Info#mod.config_db,
69
 
                                  Info#mod.request_uri),
70
 
            {Dir, SDirData} = secretp(Path, Info#mod.config_db),
71
 
            Addr = httpd_util:lookup(Info#mod.config_db, bind_address),
72
 
            Port = httpd_util:lookup(Info#mod.config_db, port),
73
 
            DF   = httpd_util:key1search(SDirData, data_file),
74
 
            case mod_security_server:check_blocked_user(Info, User, 
75
 
                                                        SDirData, 
76
 
                                                        Addr, Port) of
77
 
                true ->
78
 
                    ?vtrace("user blocked",[]),
79
 
                    report_failed(Info,httpd_util:decode_base64(User) ,"User Blocked"),
80
 
                    {proceed, [{status, {403, Info#mod.request_uri, ""}}|Info#mod.data]};
81
 
                false ->
82
 
                    ?vtrace("user not blocked",[]),
83
 
                    EncodedUser=httpd_util:decode_base64(User),
84
 
                    report_failed(Info, EncodedUser,"Authentication Succedded"),
85
 
                    mod_security_server:store_successful_auth(Addr, Port, 
86
 
                                                              User, SDirData),
87
 
                    {proceed, Info#mod.data}
88
 
            end
89
 
    end.
90
 
 
91
 
 
92
 
 
93
 
report_failed(Info, EncodedString,Event) ->
94
 
    Request = Info#mod.request_line,
95
 
    Decoded = httpd_util:decode_base64(EncodedString),
96
 
    {PortNumber,RemoteHost}=(Info#mod.init_data)#init_data.peername,
97
 
    String = RemoteHost++" : " ++ Event ++ " : "++Request++" : "++Decoded,
98
 
    mod_disk_log:security_log(Info,String),
99
 
    mod_log:security_log(Info, String).
100
 
 
101
 
take_failed_action(Info, EncodedString) ->
102
 
    Path = mod_alias:path(Info#mod.data,Info#mod.config_db, Info#mod.request_uri),
103
 
    {Dir, SDirData} = secretp(Path, Info#mod.config_db),
104
 
    Addr = httpd_util:lookup(Info#mod.config_db, bind_address),
105
 
    Port = httpd_util:lookup(Info#mod.config_db, port),
106
 
    DecodedString = httpd_util:decode_base64(EncodedString),
107
 
    mod_security_server:store_failed_auth(Info, Addr, Port, 
108
 
                                          DecodedString, SDirData).
109
 
 
110
 
secretp(Path, ConfigDB) ->
111
 
    Directories = ets:match(ConfigDB,{directory,'$1','_'}),
112
 
    case secret_path(Path, Directories) of
113
 
        {yes, Directory} ->
114
 
            SDirs0 = httpd_util:multi_lookup(ConfigDB, security_directory),
115
 
            SDir = lists:filter(fun(X) ->
116
 
                                        lists:member({path, Directory}, X)
117
 
                                end, SDirs0),
118
 
            {Directory, lists:flatten(SDir)};
119
 
        no ->
120
 
            error_report({internal_error_secretp, ?MODULE}),
121
 
            {[], []}
122
 
    end.
123
 
 
124
 
secret_path(Path,Directories) ->
125
 
    secret_path(Path, httpd_util:uniq(lists:sort(Directories)), to_be_found).
126
 
 
127
 
secret_path(Path, [], to_be_found) ->
128
 
    no;
129
 
secret_path(Path, [], Directory) ->
130
 
    {yes, Directory};
131
 
secret_path(Path, [[NewDirectory]|Rest], Directory) ->
132
 
    case regexp:match(Path, NewDirectory) of
133
 
        {match, _, _} when Directory == to_be_found ->
134
 
            secret_path(Path, Rest, NewDirectory);
135
 
        {match, _, Length} when Length > length(Directory)->
136
 
            secret_path(Path, Rest, NewDirectory);
137
 
        {match, _, Length} ->
138
 
            secret_path(Path, Rest, Directory);
139
 
        nomatch ->
140
 
            secret_path(Path, Rest, Directory)
141
 
    end.
142
 
 
143
 
 
144
 
load([$<,$D,$i,$r,$e,$c,$t,$o,$r,$y,$ |Directory],[]) ->
145
 
    Dir = httpd_conf:custom_clean(Directory,"",">"),
146
 
    {ok, [{security_directory, Dir, [{path, Dir}]}]};
147
 
load(eof,[{security_directory,Directory, DirData}|_]) ->
148
 
    {error, ?NICE("Premature end-of-file in "++Directory)};
149
 
load([$S,$e,$c,$u,$r,$i,$t,$y,$D,$a,$t,$a,$F,$i,$l,$e,$ |FileName],
150
 
     [{security_directory, Dir, DirData}]) ->
151
 
    File = httpd_conf:clean(FileName),
152
 
    {ok, [{security_directory, Dir, [{data_file, File}|DirData]}]};
153
 
load([$S,$e,$c,$u,$r,$i,$t,$y,$C,$a,$l,$l,$b,$a,$c,$k,$M,$o,$d,$u,$l,$e,$ |ModuleName],
154
 
     [{security_directory, Dir, DirData}]) ->
155
 
    Mod = list_to_atom(httpd_conf:clean(ModuleName)),
156
 
    {ok, [{security_directory, Dir, [{callback_module, Mod}|DirData]}]};
157
 
load([$S,$e,$c,$u,$r,$i,$t,$y,$M,$a,$x,$R,$e,$t,$r,$i,$e,$s,$ |Retries],
158
 
     [{security_directory, Dir, DirData}]) ->
159
 
    MaxRetries = httpd_conf:clean(Retries),
160
 
    load_return_int_tag("SecurityMaxRetries", max_retries, 
161
 
                        httpd_conf:clean(Retries), Dir, DirData);
162
 
load([$S,$e,$c,$u,$r,$i,$t,$y,$B,$l,$o,$c,$k,$T,$i,$m,$e,$ |Time],
163
 
     [{security_directory, Dir, DirData}]) ->
164
 
    load_return_int_tag("SecurityBlockTime", block_time,
165
 
                        httpd_conf:clean(Time), Dir, DirData);
166
 
load([$S,$e,$c,$u,$r,$i,$t,$y,$F,$a,$i,$l,$E,$x,$p,$i,$r,$e,$T,$i,$m,$e,$ |Time],
167
 
     [{security_directory, Dir, DirData}]) ->
168
 
    load_return_int_tag("SecurityFailExpireTime", fail_expire_time,
169
 
                        httpd_conf:clean(Time), Dir, DirData);
170
 
load([$S,$e,$c,$u,$r,$i,$t,$y,$A,$u,$t,$h,$T,$i,$m,$e,$o,$u,$t,$ |Time0],
171
 
     [{security_directory, Dir, DirData}]) ->
172
 
    Time = httpd_conf:clean(Time0),
173
 
    load_return_int_tag("SecurityAuthTimeout", auth_timeout,
174
 
                        httpd_conf:clean(Time), Dir, DirData);
175
 
load([$A,$u,$t,$h,$N,$a,$m,$e,$ |Name0],
176
 
     [{security_directory, Dir, DirData}]) ->
177
 
    Name = httpd_conf:clean(Name0),
178
 
    {ok, [{security_directory, Dir, [{auth_name, Name}|DirData]}]};
179
 
load("</Directory>",[{security_directory,Directory, DirData}]) ->
180
 
    {ok, [], {security_directory, Directory, DirData}}.
181
 
 
182
 
load_return_int_tag(Name, Atom, Time, Dir, DirData) ->
183
 
    case Time of
184
 
        "infinity" ->
185
 
            {ok, [{security_directory, Dir, [{Atom, 99999999999999999999999999999}|DirData]}]};
186
 
        Int ->
187
 
            case catch list_to_integer(Time) of
188
 
                {'EXIT', _} ->
189
 
                    {error, Time++" is an invalid "++Name};
190
 
                Val ->
191
 
                    {ok, [{security_directory, Dir, [{Atom, Val}|DirData]}]}
192
 
            end
193
 
    end.
194
 
 
195
 
store({security_directory, Dir0, DirData}, ConfigList) ->
196
 
    ?CDEBUG("store(security_directory) -> ~n"
197
 
            "      Dir0:       ~p~n"
198
 
            "      DirData:    ~p",
199
 
            [Dir0, DirData]),
200
 
    Addr = httpd_util:key1search(ConfigList, bind_address),
201
 
    Port = httpd_util:key1search(ConfigList, port),
202
 
    mod_security_server:start(Addr, Port),
203
 
    SR = httpd_util:key1search(ConfigList, server_root),
204
 
    Dir = 
205
 
        case filename:pathtype(Dir0) of
206
 
            relative ->
207
 
                filename:join(SR, Dir0);
208
 
            _ ->
209
 
                Dir0
210
 
        end,
211
 
    case httpd_util:key1search(DirData, data_file, no_data_file) of
212
 
        no_data_file ->
213
 
            {error, no_security_data_file};
214
 
        DataFile0 ->
215
 
            DataFile = 
216
 
                case filename:pathtype(DataFile0) of
217
 
                    relative ->
218
 
                        filename:join(SR, DataFile0);
219
 
                    _ ->
220
 
                        DataFile0
221
 
                end,
222
 
            case mod_security_server:new_table(Addr, Port, DataFile) of
223
 
                {ok, TwoTables} ->
224
 
                    NewDirData0 = lists:keyreplace(data_file, 1, DirData, 
225
 
                                                   {data_file, TwoTables}),
226
 
                    NewDirData1 = case Addr of
227
 
                                      undefined ->
228
 
                                          [{port,Port}|NewDirData0];
229
 
                                      _ ->
230
 
                                          [{port,Port},{bind_address,Addr}|
231
 
                                           NewDirData0]
232
 
                                  end,
233
 
                    {ok, {security_directory,NewDirData1}};
234
 
                {error, Err} ->
235
 
                    {error, {{open_data_file, DataFile}, Err}}
236
 
            end
237
 
    end.
238
 
 
239
 
 
240
 
remove(ConfigDB) ->
241
 
    Addr = case ets:lookup(ConfigDB, bind_address) of
242
 
               [] -> 
243
 
                   undefined;
244
 
               [{bind_address, Address}] ->
245
 
                   Address
246
 
           end,
247
 
    [{port, Port}] = ets:lookup(ConfigDB, port),
248
 
    mod_security_server:delete_tables(Addr, Port),
249
 
    mod_security_server:stop(Addr, Port).
250
 
    
251
 
 
252
 
%%
253
 
%% User API
254
 
%%
255
 
 
256
 
%% list_blocked_users
257
 
 
258
 
list_blocked_users(Port) ->
259
 
    list_blocked_users(undefined, Port).
260
 
 
261
 
list_blocked_users(Port, Dir) when integer(Port) ->
262
 
    list_blocked_users(undefined,Port,Dir);
263
 
list_blocked_users(Addr, Port) when integer(Port) ->
264
 
    mod_security_server:list_blocked_users(Addr, Port).
265
 
 
266
 
list_blocked_users(Addr, Port, Dir) ->
267
 
    mod_security_server:list_blocked_users(Addr, Port, Dir).
268
 
 
269
 
 
270
 
%% block_user
271
 
 
272
 
block_user(User, Port, Dir, Time) ->
273
 
    block_user(User, undefined, Port, Dir, Time).
274
 
block_user(User, Addr, Port, Dir, Time) ->
275
 
    mod_security_server:block_user(User, Addr, Port, Dir, Time).
276
 
 
277
 
 
278
 
%% unblock_user
279
 
 
280
 
unblock_user(User, Port) ->
281
 
    unblock_user(User, undefined, Port).
282
 
 
283
 
unblock_user(User, Port, Dir) when integer(Port) ->
284
 
    unblock_user(User, undefined, Port, Dir);
285
 
unblock_user(User, Addr, Port) when integer(Port) ->
286
 
    mod_security_server:unblock_user(User, Addr, Port).
287
 
 
288
 
unblock_user(User, Addr, Port, Dir) ->
289
 
    mod_security_server:unblock_user(User, Addr, Port, Dir).
290
 
 
291
 
 
292
 
%% list_auth_users
293
 
 
294
 
list_auth_users(Port) ->
295
 
    list_auth_users(undefined,Port).
296
 
 
297
 
list_auth_users(Port, Dir) when integer(Port) ->
298
 
    list_auth_users(undefined, Port, Dir);
299
 
list_auth_users(Addr, Port) when integer(Port) ->
300
 
    mod_security_server:list_auth_users(Addr, Port).
301
 
 
302
 
list_auth_users(Addr, Port, Dir) ->
303
 
    mod_security_server:list_auth_users(Addr, Port, Dir).
304
 
    
305
 
 
306
 
error_report(M) ->
307
 
    error_logger:error_report(M).