aboutsummaryrefslogtreecommitdiff
path: root/src/web/ejabberd_http.erl
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2010-12-07 16:47:32 +0100
committerBadlop <badlop@process-one.net>2010-12-07 16:47:55 +0100
commitb83dd9f95433d9dce44944fc7e6ab64c99ea3ada (patch)
tree60c82189dcb1c2d14be2866d44ba85ffa2d02fea /src/web/ejabberd_http.erl
parentupdate pubsub_odbc patch (diff)
Support for X-Forwarded-For HTTP header (EJAB-1356)
Diffstat (limited to 'src/web/ejabberd_http.erl')
-rw-r--r--src/web/ejabberd_http.erl33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl
index 313e0f264..37f56d085 100644
--- a/src/web/ejabberd_http.erl
+++ b/src/web/ejabberd_http.erl
@@ -362,13 +362,15 @@ process_request(#state{request_method = Method,
LQ ->
LQ
end,
- {ok, IP} =
+ {ok, IPHere} =
case SockMod of
gen_tcp ->
inet:peername(Socket);
_ ->
SockMod:peername(Socket)
end,
+ XFF = proplists:get_value('X-Forwarded-For', RequestHeaders, []),
+ IP = analyze_ip_xff(IPHere, XFF, Host),
Request = #request{method = Method,
path = LPath,
q = LQuery,
@@ -409,13 +411,15 @@ process_request(#state{request_method = Method,
request_headers = RequestHeaders,
request_handlers = RequestHandlers} = State)
when (Method=:='POST' orelse Method=:='PUT') andalso is_integer(Len) ->
- {ok, IP} =
+ {ok, IPHere} =
case SockMod of
gen_tcp ->
inet:peername(Socket);
_ ->
SockMod:peername(Socket)
end,
+ XFF = proplists:get_value('X-Forwarded-For', RequestHeaders, []),
+ IP = analyze_ip_xff(IPHere, XFF, Host),
case SockMod of
gen_tcp ->
inet:setopts(Socket, [{packet, 0}]);
@@ -466,6 +470,31 @@ process_request(State) ->
ejabberd_web:make_xhtml([{xmlelement, "h1", [],
[{xmlcdata, "400 Bad Request"}]}])).
+%% Support for X-Forwarded-From
+analyze_ip_xff(IP, [], _Host) ->
+ IP;
+analyze_ip_xff({IPLast, Port}, XFF, Host) ->
+ [ClientIP | ProxiesIPs] = string:tokens(XFF, ", ")
+ ++ [inet_parse:ntoa(IPLast)],
+ TrustedProxies = case ejabberd_config:get_local_option(
+ {trusted_proxies, Host}) of
+ undefined -> [];
+ TPs -> TPs
+ end,
+ IPClient = case is_ipchain_trusted(ProxiesIPs, TrustedProxies) of
+ true ->
+ {ok, IPFirst} = inet_parse:address(ClientIP),
+ ?DEBUG("The IP ~w was replaced with ~w due to header "
+ "X-Forwarded-For: ~s", [IPLast, IPFirst, XFF]),
+ IPFirst;
+ false ->
+ IPLast
+ end,
+ {IPClient, Port}.
+is_ipchain_trusted(_UserIPs, all) ->
+ true;
+is_ipchain_trusted(UserIPs, TrustedIPs) ->
+ [] == UserIPs -- ["127.0.0.1" | TrustedIPs].
recv_data(State, Len) ->
recv_data(State, Len, []).