From d4e7b0cda08e6d8b0c7e0bfc2faf39e94a589b8b Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Fri, 30 Dec 2011 16:08:24 +0200 Subject: [PATCH 01/12] mod_private.erl: misc errors cases fixes (thanks to Karim Gemayel) --- src/jlib.hrl | 4 ++ src/mod_private.erl | 159 ++++++++++++++++++++++++++------------------ 2 files changed, 98 insertions(+), 65 deletions(-) diff --git a/src/jlib.hrl b/src/jlib.hrl index 2dc2b53f0..fc10551cc 100644 --- a/src/jlib.hrl +++ b/src/jlib.hrl @@ -100,6 +100,8 @@ [{"code", Code}, {"type", Type}], [{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []}]}). +-define(ERR_BAD_FORMAT, + ?STANZA_ERROR("406", "modify", "bad-format")). -define(ERR_BAD_REQUEST, ?STANZA_ERROR("400", "modify", "bad-request")). -define(ERR_CONFLICT, @@ -154,6 +156,8 @@ {xmlelement, "text", [{"xmlns", ?NS_STANZAS}], [{xmlcdata, translate:translate(Lang, Text)}]}]}). +-define(ERRT_BAD_FORMAT(Lang, Text), + ?STANZA_ERRORT("406", "modify", "bad-format", Lang, Text)). -define(ERRT_BAD_REQUEST(Lang, Text), ?STANZA_ERRORT("400", "modify", "bad-request", Lang, Text)). -define(ERRT_CONFLICT(Lang, Text), diff --git a/src/mod_private.erl b/src/mod_private.erl index f8ba72d47..a123f698b 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -39,6 +39,11 @@ -record(private_storage, {usns, xml}). +-define(Xmlel_Query(Attrs, Children), +( + {xmlelement, "query", Attrs, Children} +)). + start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), mnesia:create_table(private_storage, @@ -56,73 +61,97 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE). -process_sm_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) -> - #jid{luser = LUser, lserver = LServer} = From, - case lists:member(LServer, ?MYHOSTS) of - true -> - {xmlelement, Name, Attrs, Els} = SubEl, - case Type of - set -> - F = fun() -> - lists:foreach( - fun(El) -> - set_data(LUser, LServer, El) - end, Els) - end, - mnesia:transaction(F), - IQ#iq{type = result, - sub_el = [{xmlelement, Name, Attrs, []}]}; - get -> - case catch get_data(LUser, LServer, Els) of - {'EXIT', _Reason} -> - IQ#iq{type = error, - sub_el = [SubEl, - ?ERR_INTERNAL_SERVER_ERROR]}; - Res -> - IQ#iq{type = result, - sub_el = [{xmlelement, Name, Attrs, Res}]} - end - end; - false -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} +process_sm_iq(#jid{luser = LUser, lserver = LServer}, + #jid{luser = LUser, lserver = LServer}, IQ) + when IQ#iq.type == 'set' -> + case IQ#iq.sub_el of + {xmlelement, "query", _, Xmlels} -> + case filter_xmlels(Xmlels) of + [] -> + IQ#iq{ + type = error, + sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE] + }; + Data -> + mnesia:transaction(fun() -> + lists:foreach(fun + (Datum) -> + set_data(LUser, LServer, Datum) + end, Data) + end), + IQ#iq{type = result, sub_el = []} + end; + _ -> + IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE]} + end; +%% +process_sm_iq(#jid{luser = LUser, lserver = LServer}, + #jid{luser = LUser, lserver = LServer}, IQ) + when IQ#iq.type == 'get' -> + case IQ#iq.sub_el of + {xmlelement, "query", Attrs, Xmlels} -> + case filter_xmlels(Xmlels) of + [] -> + IQ#iq{ + type = error, + sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT] + }; + Data -> + case catch get_data(LUser, LServer, Data) of + {'EXIT', _Reason} -> + IQ#iq{ + type = error, + sub_el = [IQ#iq.sub_el, ?ERR_INTERNAL_SERVER_ERROR] + }; + Storage_Xmlels -> + IQ#iq{ + type = result, + sub_el = [?Xmlel_Query(Attrs, Storage_Xmlels)] + } + end + end; + _ -> + IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT]} + end; +%% +process_sm_iq(_From, _To, IQ) -> + IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_FORBIDDEN]}. + + +filter_xmlels(Xmlels) -> + filter_xmlels(Xmlels, []). + +filter_xmlels([], Data) -> + lists:reverse(Data); +filter_xmlels([{xmlelement, _, Attrs, _} = Xmlel | Xmlels], Data) -> + case xml:get_attr_s("xmlns", Attrs) of + "" -> []; + XmlNS -> filter_xmlels(Xmlels, [{XmlNS, Xmlel} | Data]) + end; +filter_xmlels([_ | Xmlels], Data) -> + filter_xmlels(Xmlels, Data). + + +set_data(LUser, LServer, {XmlNS, Xmlel}) -> + mnesia:write(#private_storage{ + usns = {LUser, LServer, XmlNS}, + xml = Xmlel + }). + + +get_data(LUser, LServer, Data) -> + get_data(LUser, LServer, Data, []). + +get_data(_LUser, _LServer, [], Storage_Xmlels) -> + lists:reverse(Storage_Xmlels); +get_data(LUser, LServer, [{XmlNS, Xmlel} | Data], Storage_Xmlels) -> + case mnesia:dirty_read(private_storage, {LUser, LServer, XmlNS}) of + [#private_storage{xml = Storage_Xmlel}] -> + get_data(LUser, LServer, Data, [Storage_Xmlel | Storage_Xmlels]); + _ -> + get_data(LUser, LServer, Data, [Xmlel | Storage_Xmlels]) end. -set_data(LUser, LServer, El) -> - case El of - {xmlelement, _Name, Attrs, _Els} -> - XMLNS = xml:get_attr_s("xmlns", Attrs), - case XMLNS of - "" -> - ignore; - _ -> - mnesia:write( - #private_storage{usns = {LUser, LServer, XMLNS}, - xml = El}) - end; - _ -> - ignore - end. - -get_data(LUser, LServer, Els) -> - get_data(LUser, LServer, Els, []). - -get_data(_LUser, _LServer, [], Res) -> - lists:reverse(Res); -get_data(LUser, LServer, [El | Els], Res) -> - case El of - {xmlelement, _Name, Attrs, _} -> - XMLNS = xml:get_attr_s("xmlns", Attrs), - case mnesia:dirty_read(private_storage, {LUser, LServer, XMLNS}) of - [R] -> - get_data(LUser, LServer, Els, - [R#private_storage.xml | Res]); - [] -> - get_data(LUser, LServer, Els, - [El | Res]) - end; - _ -> - get_data(LUser, LServer, Els, Res) - end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), From 0283c6cdfe74974a1c9cf576e5558c4b29f69e1c Mon Sep 17 00:00:00 2001 From: Badlop Date: Sat, 31 Dec 2011 20:40:04 +0100 Subject: [PATCH 02/12] Revert "Update ejabberd version number to 2.1.10" This reverts commit bcdae191417bbec40ec87d71b8143942da92f2f1. --- doc/dev.html | 4 ++-- doc/features.html | 4 ++-- doc/guide.html | 4 ++-- doc/version.tex | 2 +- src/configure | 18 +++++++++--------- src/ejabberd.app | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/dev.html b/doc/dev.html index 83da3eb10..b86448c56 100644 --- a/doc/dev.html +++ b/doc/dev.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/REC-html40/loose.dtd"> -Ejabberd 2.1.10 Developers Guide +<TITLE>Ejabberd 2.1.x Developers Guide @@ -49,7 +49,7 @@ TD P{margin:0px;}

-

Ejabberd 2.1.10 Developers Guide

Alexey Shchepin
+

Ejabberd 2.1.x Developers Guide

Alexey Shchepin
mailto:alexey@sevcom.net
xmpp:aleksey@jabber.ru

diff --git a/doc/features.html b/doc/features.html index 025511cd3..503ac0d3f 100644 --- a/doc/features.html +++ b/doc/features.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/REC-html40/loose.dtd"> -Ejabberd 2.1.10 Feature Sheet +<TITLE>Ejabberd 2.1.x Feature Sheet @@ -50,7 +50,7 @@ SPAN{width:20%; float:right; text-align:left; margin-left:auto;}

-

Ejabberd 2.1.10 Feature Sheet

Sander Devrieze
+

Ejabberd 2.1.x Feature Sheet

Sander Devrieze
mailto:s.devrieze@pandora.be
xmpp:sander@devrieze.dyndns.org

diff --git a/doc/guide.html b/doc/guide.html index 787ec960b..397491939 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -6,7 +6,7 @@ - ejabberd 2.1.10 + ejabberd 2.1.x Installation and Operation Guide @@ -76,7 +76,7 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}


- +
ejabberd 2.1.10
ejabberd 2.1.x
 
Installation and Operation Guide

diff --git a/doc/version.tex b/doc/version.tex index 40b1b7baa..905ac86f2 100644 --- a/doc/version.tex +++ b/doc/version.tex @@ -1,2 +1,2 @@ % ejabberd version (automatically generated). -\newcommand{\version}{2.1.10} +\newcommand{\version}{2.1.x} diff --git a/src/configure b/src/configure index 14bafa922..89e32a5f1 100755 --- a/src/configure +++ b/src/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for ejabberd 2.1.10. +# Generated by GNU Autoconf 2.68 for ejabberd 2.1.x. # # Report bugs to . # @@ -560,8 +560,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ejabberd' PACKAGE_TARNAME='ejabberd' -PACKAGE_VERSION='2.1.10' -PACKAGE_STRING='ejabberd 2.1.10' +PACKAGE_VERSION='2.1.x' +PACKAGE_STRING='ejabberd 2.1.x' PACKAGE_BUGREPORT='ejabberd@process-one.net' PACKAGE_URL='' @@ -1288,7 +1288,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures ejabberd 2.1.10 to adapt to many kinds of systems. +\`configure' configures ejabberd 2.1.x to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1354,7 +1354,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ejabberd 2.1.10:";; + short | recursive ) echo "Configuration of ejabberd 2.1.x:";; esac cat <<\_ACEOF @@ -1479,7 +1479,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ejabberd configure 2.1.10 +ejabberd configure 2.1.x generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1823,7 +1823,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by ejabberd $as_me 2.1.10, which was +It was created by ejabberd $as_me 2.1.x, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -5690,7 +5690,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by ejabberd $as_me 2.1.10, which was +This file was extended by ejabberd $as_me 2.1.x, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5743,7 +5743,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -ejabberd config.status 2.1.10 +ejabberd config.status 2.1.x configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/src/ejabberd.app b/src/ejabberd.app index 3d4f50f84..3fb342fe8 100644 --- a/src/ejabberd.app +++ b/src/ejabberd.app @@ -2,7 +2,7 @@ {application, ejabberd, [{description, "ejabberd"}, - {vsn, "2.1.10"}, + {vsn, "2.1.x"}, {modules, [acl, adhoc, configure, From 288196c7e8caec6f74297c2c78c2f74b41a86267 Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 4 Jan 2012 19:21:31 +0100 Subject: [PATCH 03/12] Foreign shared rosters items not pushed (thanks to Nathan Bruning)(EJAB-1509) --- src/mod_shared_roster.erl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 6aa746bfe..a19bcba92 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -631,7 +631,7 @@ add_user_to_group(Host, US, Group) -> GroupOpts ++ MoreGroupOpts); nomatch -> %% Push this new user to members of groups where this group is displayed - push_user_to_displayed(LUser, LServer, Group, both), + push_user_to_displayed(LUser, LServer, Group, Host, both), %% Push members of groups that are displayed to this group push_displayed_to_user(LUser, LServer, Group, Host, both), R = #sr_user{us = US, group_host = {Group, Host}}, @@ -668,7 +668,7 @@ remove_user_from_group(Host, US, Group) -> end, Result = mnesia:transaction(F), %% Push removal of the old user to members of groups where the group that this user was members was displayed - push_user_to_displayed(LUser, LServer, Group, remove), + push_user_to_displayed(LUser, LServer, Group, Host, remove), %% Push removal of members of groups that where displayed to the group which this user has left push_displayed_to_user(LUser, LServer, Group, Host, remove), Result @@ -689,7 +689,7 @@ register_user(User, Server) -> %% Get list of groups where this user is member Groups = get_user_groups({User, Server}), %% Push this user to members of groups where is displayed a group which this user is member - [push_user_to_displayed(User, Server, Group, both) || Group <- Groups]. + [push_user_to_displayed(User, Server, Group, Server, both) || Group <- Groups]. remove_user(User, Server) -> push_user_to_members(User, Server, remove). @@ -711,19 +711,19 @@ push_user_to_members(User, Server, Subscription) -> end, get_group_users(LServer, Group, GroupOpts)) end, lists:usort(SpecialGroups++UserGroups)). -push_user_to_displayed(LUser, LServer, Group, Subscription) -> - GroupsOpts = groups_with_opts(LServer), +push_user_to_displayed(LUser, LServer, Group, Host, Subscription) -> + GroupsOpts = groups_with_opts(Host), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), - DisplayedToGroupsOpts = displayed_to_groups(Group, LServer), - [push_user_to_group(LUser, LServer, GroupD, GroupName, Subscription) || {GroupD, _Opts} <- DisplayedToGroupsOpts]. + DisplayedToGroupsOpts = displayed_to_groups(Group, Host), + [push_user_to_group(LUser, LServer, GroupD, Host, GroupName, Subscription) || {GroupD, _Opts} <- DisplayedToGroupsOpts]. -push_user_to_group(LUser, LServer, Group, GroupName, Subscription) -> +push_user_to_group(LUser, LServer, Group, Host, GroupName, Subscription) -> lists:foreach( - fun({U, S}) when (U == LUser) and (S == LServer) -> ok; + fun({U, S}) when (U == LUser) and (S == LServer) -> ok; ({U, S}) -> push_roster_item(U, S, LUser, LServer, GroupName, Subscription) - end, get_group_users(LServer, Group)). + end, get_group_users(Host, Group)). %% Get list of groups to which this group is displayed displayed_to_groups(GroupName, LServer) -> @@ -819,7 +819,7 @@ user_available(New) -> fun(OG) -> ?DEBUG("user_available: pushing ~p @ ~p grp ~p", [LUser, LServer, OG ]), - push_user_to_displayed(LUser, LServer, OG, both) + push_user_to_displayed(LUser, LServer, OG, LServer, both) end, OnlineGroups); _ -> ok @@ -840,7 +840,7 @@ unset_presence(LUser, LServer, Resource, Status) -> fun(OG) -> %% Push removal of the old user to members of groups %% where the group that this uwas members was displayed - push_user_to_displayed(LUser, LServer, OG, remove), + push_user_to_displayed(LUser, LServer, OG, LServer, remove), %% Push removal of members of groups that where %% displayed to the group which thiuser has left push_displayed_to_user(LUser, LServer, OG, LServer,remove) From 1ecc9ac48cd262bf99b33d389bab1a7f9fed9e9b Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Thu, 19 Jan 2012 12:20:02 +0200 Subject: [PATCH 04/12] Fixed ejabberd_http:get_line --- src/web/ejabberd_http.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl index 44d3e161f..abfe40705 100644 --- a/src/web/ejabberd_http.erl +++ b/src/web/ejabberd_http.erl @@ -1132,4 +1132,6 @@ get_line("\r\n" ++ Tail, Cur) -> end end; get_line([H|T], Cur) -> - get_line(T, [H|Cur]). + get_line(T, [H|Cur]); +get_line([], Cur) -> + {incomplete, lists:reverse(Cur)}. From 95928a7cd46e4c45ab26d6779768345595181cf9 Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 19 Jan 2012 13:08:11 +0100 Subject: [PATCH 05/12] http_bind webserver TLS fail on Chrome (thanks to Adam Langley)(EJAB-1530) --- src/tls/tls_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tls/tls_drv.c b/src/tls/tls_drv.c index c4210055a..9311d4f6d 100644 --- a/src/tls/tls_drv.c +++ b/src/tls/tls_drv.c @@ -430,7 +430,8 @@ static ErlDrvSSizeT tls_drv_control(ErlDrvData handle, if (res <= 0) die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ, "SSL_do_handshake failed"); - } else { + } + if (SSL_is_init_finished(d->ssl)) { size = BUF_SIZE + 1; rlen = 1; b = driver_alloc_binary(size); From 89aa7baa5b5601c078d90bcd64deede218c7e5a8 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 31 Jan 2012 11:18:14 +1000 Subject: [PATCH 06/12] Replace a single quote with double quotes in an ODBC escape (thanks to Vladislav Chugunov) --- src/odbc/odbc_queries.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/odbc_queries.erl b/src/odbc/odbc_queries.erl index ab842b66c..3039ff2ec 100644 --- a/src/odbc/odbc_queries.erl +++ b/src/odbc/odbc_queries.erl @@ -557,7 +557,7 @@ escape($\n) -> "\\n"; escape($\t) -> "\\t"; escape($\b) -> "\\b"; escape($\r) -> "\\r"; -escape($') -> "\\'"; +escape($') -> "''"; escape($") -> "\\\""; escape($\\) -> "\\\\"; escape(C) -> C. From 948318ca19cc40bf4becf440dadf597902e9bfe4 Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 1 Feb 2012 00:09:51 +0100 Subject: [PATCH 07/12] Fix the documentation about default value of captcha_cmd option --- doc/guide.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/guide.tex b/doc/guide.tex index f13c58884..9c1590fb3 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -1664,7 +1664,7 @@ The configurable options are: \begin{description} \titem{\{captcha\_cmd, Path\}} Full path to a script that generates the image. - The default value is an empty string: \term{""} + The default value disables the feature: \term{undefined} \titem{\{captcha\_host, ProtocolHostPort\}} ProtocolHostPort is a string with the host, and optionally the Protocol and Port number. It must identify where ejabberd listens for CAPTCHA requests. From 4819738e8f039bf08bfb9867ad279ef8a94b9b5d Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 14 Feb 2012 17:03:08 +1000 Subject: [PATCH 08/12] Receiver should not generate an exception --- src/ejabberd_receiver.erl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl index 702dd108f..3a4e4aafb 100644 --- a/src/ejabberd_receiver.erl +++ b/src/ejabberd_receiver.erl @@ -84,16 +84,16 @@ change_shaper(Pid, Shaper) -> gen_server:cast(Pid, {change_shaper, Shaper}). reset_stream(Pid) -> - gen_server:call(Pid, reset_stream). + do_call(Pid, reset_stream). starttls(Pid, TLSSocket) -> - gen_server:call(Pid, {starttls, TLSSocket}). + do_call(Pid, {starttls, TLSSocket}). compress(Pid, ZlibSocket) -> - gen_server:call(Pid, {compress, ZlibSocket}). + do_call(Pid, {compress, ZlibSocket}). become_controller(Pid, C2SPid) -> - gen_server:call(Pid, {become_controller, C2SPid}). + do_call(Pid, {become_controller, C2SPid}). close(Pid) -> gen_server:cast(Pid, close). @@ -345,3 +345,11 @@ close_stream(undefined) -> ok; close_stream(XMLStreamState) -> xml_stream:close(XMLStreamState). + +do_call(Pid, Msg) -> + case catch gen_server:call(Pid, Msg) of + {'EXIT', Why} -> + {error, Why}; + Res -> + Res + end. From 7d623d5eb4352a7e150f55d9bde938ea9dd6f14b Mon Sep 17 00:00:00 2001 From: Badlop Date: Tue, 14 Feb 2012 11:35:17 +0100 Subject: [PATCH 09/12] Option default_host for handling HTTP requests with ambiguous Host (EJAB-1261) --- doc/guide.tex | 7 ++++++- src/web/ejabberd_http.erl | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/guide.tex b/doc/guide.tex index 9c1590fb3..129151d18 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -826,7 +826,7 @@ The available modules, their purpose and the options allowed by each one are: Options: \texttt{certfile} \titem{\texttt{ejabberd\_http}} Handles incoming HTTP connections.\\ - Options: \texttt{captcha}, \texttt{certfile}, \texttt{http\_bind}, \texttt{http\_poll}, + Options: \texttt{captcha}, \texttt{certfile}, \texttt{default\_host}, \texttt{http\_bind}, \texttt{http\_poll}, \texttt{request\_handlers}, \texttt{tls}, \texttt{trusted\_proxies}, \texttt{web\_admin}\\ \end{description} @@ -847,6 +847,11 @@ This is a detailed description of each option allowed by the listening modules: Simple web page that allows a user to fill a CAPTCHA challenge (see section \ref{captcha}). \titem{\{certfile, Path\}} Full path to a file containing the default SSL certificate. To define a certificate file specific for a given domain, use the global option \term{domain\_certfile}. + \titem{\{default\_host, undefined|HostName\}} + If the HTTP request received by ejabberd contains the HTTP header \term{Host} + with an ambiguous virtual host that doesn't match any one defined in ejabberd (see \ref{hostnames}), + then this configured HostName is set as the request Host. + The default value of this option is: \term{undefined}. \titem{\{hosts, [Hostname, ...], [HostOption, ...]\}} \ind{options!hosts} The external Jabber component that connects to this \term{ejabberd\_service} can serve one or more hostnames. diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl index abfe40705..47ef97a03 100644 --- a/src/web/ejabberd_http.erl +++ b/src/web/ejabberd_http.erl @@ -65,6 +65,7 @@ request_tp, request_headers = [], end_of_request = false, + default_host, trail = "" }). @@ -140,9 +141,12 @@ init({SockMod, Socket}, Opts) -> end, ?DEBUG("S: ~p~n", [RequestHandlers]), + DefaultHost = gen_mod:get_opt(default_host, Opts, undefined), + ?INFO_MSG("started: ~p", [{SockMod1, Socket1}]), State = #state{sockmod = SockMod1, socket = Socket1, + default_host = DefaultHost, request_handlers = RequestHandlers}, receive_headers(State). @@ -261,8 +265,9 @@ process_header(State, Data) -> [State#state.socket, State#state.request_method, element(2, State#state.request_path)]), - {Host, Port, TP} = get_transfer_protocol(SockMod, + {HostProvided, Port, TP} = get_transfer_protocol(SockMod, State#state.request_host), + Host = get_host_really_served(State#state.default_host, HostProvided), State2 = State#state{request_host = Host, request_port = Port, request_tp = TP}, @@ -294,6 +299,14 @@ process_header(State, Data) -> add_header(Name, Value, State) -> [{Name, Value} | State#state.request_headers]. +get_host_really_served(undefined, Provided) -> + Provided; +get_host_really_served(Default, Provided) -> + case lists:member(Provided, ?MYHOSTS) of + true -> Provided; + false -> Default + end. + %% @spec (SockMod, HostPort) -> {Host::string(), Port::integer(), TP} %% where %% SockMod = gen_tcp | tls From 112a18f966b0fa8525d8638e38adec88d048dedb Mon Sep 17 00:00:00 2001 From: Badlop Date: Tue, 14 Feb 2012 13:18:18 +0100 Subject: [PATCH 10/12] Work also with some unicode strings in PgSQL (EJAB-1490) --- src/mod_vcard.erl | 52 +++++++++++++++++++++++------------------- src/mod_vcard_odbc.erl | 30 ++++++++++++++---------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 1820f64b8..46830b020 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -219,17 +219,17 @@ set_vcard(User, LServer, VCARD) -> end, LUser = jlib:nodeprep(User), - LFN = string:to_lower(FN), - LFamily = string:to_lower(Family), - LGiven = string:to_lower(Given), - LMiddle = string:to_lower(Middle), - LNickname = string:to_lower(Nickname), - LBDay = string:to_lower(BDay), - LCTRY = string:to_lower(CTRY), - LLocality = string:to_lower(Locality), - LEMail = string:to_lower(EMail), - LOrgName = string:to_lower(OrgName), - LOrgUnit = string:to_lower(OrgUnit), + LFN = string2lower(FN), + LFamily = string2lower(Family), + LGiven = string2lower(Given), + LMiddle = string2lower(Middle), + LNickname = string2lower(Nickname), + LBDay = string2lower(BDay), + LCTRY = string2lower(CTRY), + LLocality = string2lower(Locality), + LEMail = string2lower(EMail), + LOrgName = string2lower(OrgName), + LOrgUnit = string2lower(OrgUnit), US = {LUser, LServer}, @@ -271,6 +271,12 @@ set_vcard(User, LServer, VCARD) -> ejabberd_hooks:run(vcard_set, LServer, [LUser, LServer, VCARD]) end. +string2lower(String) -> + case stringprep:tolower(String) of + Lower when is_list(Lower) -> Lower; + error -> string:to_lower(String) + end. + -define(TLFIELD(Type, Label, Var), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, @@ -541,7 +547,7 @@ filter_fields([], Match, _LServer) -> Match; filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_list(Val) and (Val /= "") -> - LVal = string:to_lower(Val), + LVal = string2lower(Val), NewMatch = case SVar of "user" -> case gen_mod:get_module_opt(LServer, ?MODULE, @@ -618,17 +624,17 @@ set_vcard_t(R, _) -> OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), {LUser, _LServer} = US, - LFN = string:to_lower(FN), - LFamily = string:to_lower(Family), - LGiven = string:to_lower(Given), - LMiddle = string:to_lower(Middle), - LNickname = string:to_lower(Nickname), - LBDay = string:to_lower(BDay), - LCTRY = string:to_lower(CTRY), - LLocality = string:to_lower(Locality), - LEMail = string:to_lower(EMail), - LOrgName = string:to_lower(OrgName), - LOrgUnit = string:to_lower(OrgUnit), + LFN = string2lower(FN), + LFamily = string2lower(Family), + LGiven = string2lower(Given), + LMiddle = string2lower(Middle), + LNickname = string2lower(Nickname), + LBDay = string2lower(BDay), + LCTRY = string2lower(CTRY), + LLocality = string2lower(Locality), + LEMail = string2lower(EMail), + LOrgName = string2lower(OrgName), + LOrgUnit = string2lower(OrgUnit), if (LUser == error) or diff --git a/src/mod_vcard_odbc.erl b/src/mod_vcard_odbc.erl index a4c23624c..fd1ca9022 100644 --- a/src/mod_vcard_odbc.erl +++ b/src/mod_vcard_odbc.erl @@ -186,17 +186,17 @@ set_vcard(User, LServer, VCARD) -> end, LUser = jlib:nodeprep(User), - LFN = string:to_lower(FN), - LFamily = string:to_lower(Family), - LGiven = string:to_lower(Given), - LMiddle = string:to_lower(Middle), - LNickname = string:to_lower(Nickname), - LBDay = string:to_lower(BDay), - LCTRY = string:to_lower(CTRY), - LLocality = string:to_lower(Locality), - LEMail = string:to_lower(EMail), - LOrgName = string:to_lower(OrgName), - LOrgUnit = string:to_lower(OrgUnit), + LFN = string2lower(FN), + LFamily = string2lower(Family), + LGiven = string2lower(Given), + LMiddle = string2lower(Middle), + LNickname = string2lower(Nickname), + LBDay = string2lower(BDay), + LCTRY = string2lower(CTRY), + LLocality = string2lower(Locality), + LEMail = string2lower(EMail), + LOrgName = string2lower(OrgName), + LOrgUnit = string2lower(OrgUnit), if (LUser == error) or @@ -252,6 +252,12 @@ set_vcard(User, LServer, VCARD) -> ejabberd_hooks:run(vcard_set, LServer, [LUser, LServer, VCARD]) end. +string2lower(String) -> + case stringprep:tolower(String) of + Lower when is_list(Lower) -> Lower; + error -> string:to_lower(String) + end. + -define(TLFIELD(Type, Label, Var), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, @@ -531,7 +537,7 @@ filter_fields([], Match, _LServer) -> end; filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_list(Val) and (Val /= "") -> - LVal = string:to_lower(Val), + LVal = string2lower(Val), NewMatch = case SVar of "user" -> make_val(Match, "lusername", LVal); "fn" -> make_val(Match, "lfn", LVal); From 4900ac31a783d826e9fcddf8fea9518bc9fc7fd8 Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 15 Feb 2012 18:30:16 +0100 Subject: [PATCH 11/12] Add thanks to Ludovic Bocquet for past Guide contributions --- doc/guide.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/guide.tex b/doc/guide.tex index 129151d18..575bea6ef 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -5878,6 +5878,7 @@ Thanks to all people who contributed to this guide: \item Badlop (\ahrefurl{xmpp:badlop@jabberes.org}) \item Evgeniy Khramtsov (\ahrefurl{xmpp:xram@jabber.ru}) \item Florian Zumbiehl (\ahrefurl{xmpp:florz@florz.de}) +\item Ludovic Bocquet (\ahrefurl{xmpp:lbocquet@jabber.org}) \item Marcin Owsiany (\ahrefurl{xmpp:marcin.owsiany@gmail.com}) \item Michael Grigutsch (\ahrefurl{xmpp:migri@jabber.i-pobox.net}) \item Mickael Remond (\ahrefurl{xmpp:mremond@process-one.net}) From f7ffdfa15dfeed84f9960fd8f17fa58e39e6aecb Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Mon, 20 Feb 2012 14:15:08 +0100 Subject: [PATCH 12/12] Fix typo in xep number, bosh is xep0206 (thanks to Ludovic Bocquet) --- src/web/ejabberd_http_bind.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/ejabberd_http_bind.erl b/src/web/ejabberd_http_bind.erl index 63b608682..b28587fce 100644 --- a/src/web/ejabberd_http_bind.erl +++ b/src/web/ejabberd_http_bind.erl @@ -1,7 +1,7 @@ %%%---------------------------------------------------------------------- %%% File : ejabberd_http_bind.erl %%% Author : Stefan Strigler -%%% Purpose : Implements XMPP over BOSH (XEP-0205) (formerly known as +%%% Purpose : Implements XMPP over BOSH (XEP-0206) (formerly known as %%% HTTP Binding) %%% Created : 21 Sep 2005 by Stefan Strigler %%% Modified: may 2009 by Mickael Remond, Alexey Schepin