diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | doc/guide.tex | 14 | ||||
-rw-r--r-- | include/ns.hrl | 1 | ||||
-rw-r--r-- | src/ejabberd_auth_external.erl | 2 | ||||
-rw-r--r-- | src/ejabberd_c2s.erl | 127 | ||||
-rw-r--r-- | src/mod_carboncopy.erl | 37 | ||||
-rw-r--r-- | src/mod_muc_log.erl | 31 | ||||
-rw-r--r-- | src/mod_offline.erl | 39 |
8 files changed, 134 insertions, 119 deletions
diff --git a/.travis.yml b/.travis.yml index 5b093b668..f04d55bda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ before_script: script: - ./autogen.sh - - ./configure --enable-transient_supervisors --enable-all --disable-http --disable-odbc + - ./configure --enable-all --disable-http --disable-odbc - make - make test - grep -q 'TEST COMPLETE, \([[:digit:]]*\) ok, .* of \1 ' logs/raw.log diff --git a/doc/guide.tex b/doc/guide.tex index 0919c689a..a7ff11fff 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -907,7 +907,7 @@ The available modules, their purpose and the options allowed by each one are: Options: \texttt{access\_commands}, \texttt{maxsessions}, \texttt{timeout}.\\ You can find option explanations, example configuration in old and new format, and example calls in several languages in the old - \footahref{https://raw.github.com/processone/ejabberd-contrib/master/ejabberd\_xmlrpc/README.txt}{ejabberd\_xmlrpc README.txt} + \footahref{http://www.ejabberd.im/ejabberd\_xmlrpc}{ejabberd\_xmlrpc documentation}. \end{description} @@ -930,8 +930,10 @@ This is a detailed description of each option allowed by the listening modules: \titem{ciphers: Ciphers} OpenSSL ciphers list in the same format accepted by `\verb|openssl ciphers|' command. \titem{protocol\_options: ProtocolOpts} \ind{options!protocol\_options} - List of general options relating to SSL/TLS. These map to \verb|<a href="https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html">OpenSSL's set_options()</a>|. - For a full list of options available in ejabberd, \verb|<a href="https://github.com/processone/tls/blob/master/c_src/options.h">see the source</a>|. + List of general options relating to SSL/TLS. These map to + \footahref{https://www.openssl.org/docs/ssl/SSL\_CTX\_set\_options.html}{OpenSSL's set\_options()}. + For a full list of options available in ejabberd, + \footahref{https://github.com/processone/tls/blob/master/c\_src/options.h}{see the source}. The default entry is: \verb|"no_sslv2"| \titem{default\_host: undefined|HostName\}} If the HTTP request received by ejabberd contains the HTTP header \term{Host} @@ -1110,8 +1112,10 @@ There are some additional global options that can be specified in the ejabberd c \titem{s2s\_ciphers: Ciphers} \ind{options!s2s\_ciphers} OpenSSL ciphers list in the same format accepted by `\verb|openssl ciphers|' command. \titem{s2s\_protocol\_options: ProtocolOpts} \ind{options!s2s\_protocol\_options} - List of general options relating to SSL/TLS. These map to \verb|<a href="https://www.openssl.org/docs/ssl/SSL_CTX_set_options.html">OpenSSL's set_options()</a>|. - For a full list of options available in ejabberd, \verb|<a href="https://github.com/processone/tls/blob/protocol_options/c_src/options.h">see the source</a>|. + List of general options relating to SSL/TLS. These map to + \footahref{https://www.openssl.org/docs/ssl/SSL\_CTX\_set\_options.html}{OpenSSL's set\_options()}. + For a full list of options available in ejabberd, + \footahref{https://github.com/processone/tls/blob/master/c\_src/options.h}{see the source}. The default entry is: \verb|"no_sslv2"| \titem{outgoing\_s2s\_families: [Family, ...]} \ind{options!outgoing\_s2s\_families} Specify which address families to try, in what order. diff --git a/include/ns.hrl b/include/ns.hrl index aa6150cfd..ac8105e9c 100644 --- a/include/ns.hrl +++ b/include/ns.hrl @@ -42,6 +42,7 @@ -define(NS_IQDATA, <<"jabber:iq:data">>). -define(NS_DELAY91, <<"jabber:x:delay">>). -define(NS_DELAY, <<"urn:xmpp:delay">>). +-define(NS_HINTS, <<"urn:xmpp:hints">>). -define(NS_EXPIRE, <<"jabber:x:expire">>). -define(NS_EVENT, <<"jabber:x:event">>). -define(NS_CHATSTATES, diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl index 51c1c620a..74263f748 100644 --- a/src/ejabberd_auth_external.erl +++ b/src/ejabberd_auth_external.erl @@ -186,6 +186,8 @@ check_password_extauth(User, Server, Password) -> try_register_extauth(User, Server, Password) -> extauth:try_register(User, Server, Password). +check_password_cache(User, Server, Password, 0) -> + check_password_external_cache(User, Server, Password); check_password_cache(User, Server, Password, CacheTime) -> case get_last_access(User, Server) of diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index f29559e67..5d0cc9c08 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -788,18 +788,11 @@ wait_for_feature_request({xmlstreamelement, El}, StateData#state.tls_options)] end, Socket = StateData#state.socket, + BProceed = xml:element_to_binary(#xmlel{name = <<"proceed">>, + attrs = [{<<"xmlns">>, ?NS_TLS}]}), TLSSocket = (StateData#state.sockmod):starttls(Socket, TLSOpts, - xml:element_to_binary(#xmlel{name - = - <<"proceed">>, - attrs - = - [{<<"xmlns">>, - ?NS_TLS}], - children - = - []})), + BProceed), fsm_next_state(wait_for_stream, StateData#state{socket = TLSSocket, streamid = new_id(), @@ -820,17 +813,10 @@ wait_for_feature_request({xmlstreamelement, El}, case xml:get_tag_cdata(Method) of <<"zlib">> -> Socket = StateData#state.socket, + BCompressed = xml:element_to_binary(#xmlel{name = <<"compressed">>, + attrs = [{<<"xmlns">>, ?NS_COMPRESS}]}), ZlibSocket = (StateData#state.sockmod):compress(Socket, - xml:element_to_binary(#xmlel{name - = - <<"compressed">>, - attrs - = - [{<<"xmlns">>, - ?NS_COMPRESS}], - children - = - []})), + BCompressed), fsm_next_state(wait_for_stream, StateData#state{socket = ZlibSocket, streamid = new_id()}); @@ -973,9 +959,7 @@ wait_for_sasl_response(closed, StateData) -> {stop, normal, StateData}. resource_conflict_action(U, S, R) -> - OptionRaw = case ejabberd_sm:is_existing_resource(U, S, - R) - of + OptionRaw = case ejabberd_sm:is_existing_resource(U, S, R) of true -> ejabberd_config:get_option( {resource_conflict, S}, @@ -1096,7 +1080,7 @@ wait_for_session({xmlstreamelement, El}, StateData) -> ?INFO_MSG("(~w) Opened session for ~s", [NewStateData#state.socket, jlib:jid_to_string(JID)]), - Res = jlib:make_result_iq_reply(El#xmlel{children = []}), + Res = jlib:make_result_iq_reply(El#xmlel{children = []}), NewState = send_stanza(NewStateData, Res), change_shaper(NewState, JID), {Fs, Ts} = ejabberd_hooks:run_fold( @@ -1657,7 +1641,7 @@ handle_info({route, From, To, jlib:replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), NewAttrs), FixedPacket = #xmlel{name = Name, attrs = Attrs2, children = Els}, - SentStateData = send_packet(StateData, FixedPacket), + SentStateData = send_packet(NewState, FixedPacket), ejabberd_hooks:run(user_receive_packet, SentStateData#state.server, [SentStateData#state.jid, From, To, FixedPacket]), @@ -1909,12 +1893,11 @@ new_id() -> randoms:get_string(). is_auth_packet(El) -> case jlib:iq_query_info(El) of - #iq{id = ID, type = Type, xmlns = ?NS_AUTH, - sub_el = SubEl} -> - #xmlel{children = Els} = SubEl, - {auth, ID, Type, - get_auth_tags(Els, <<"">>, <<"">>, <<"">>, <<"">>)}; - _ -> false + #iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} -> + #xmlel{children = Els} = SubEl, + {auth, ID, Type, + get_auth_tags(Els, <<"">>, <<"">>, <<"">>, <<"">>)}; + _ -> false end. is_stanza(#xmlel{name = Name, attrs = Attrs}) when Name == <<"message">>; @@ -2237,18 +2220,16 @@ remove_element(E, Set) -> roster_change(IJID, ISubscription, StateData) -> LIJID = jlib:jid_tolower(IJID), - IsFrom = (ISubscription == both) or - (ISubscription == from), + IsFrom = (ISubscription == both) or (ISubscription == from), IsTo = (ISubscription == both) or (ISubscription == to), - OldIsFrom = (?SETS):is_element(LIJID, - StateData#state.pres_f), - FSet = if IsFrom -> - (?SETS):add_element(LIJID, StateData#state.pres_f); - true -> remove_element(LIJID, StateData#state.pres_f) + OldIsFrom = (?SETS):is_element(LIJID, StateData#state.pres_f), + FSet = if + IsFrom -> (?SETS):add_element(LIJID, StateData#state.pres_f); + not IsFrom -> remove_element(LIJID, StateData#state.pres_f) end, - TSet = if IsTo -> - (?SETS):add_element(LIJID, StateData#state.pres_t); - true -> remove_element(LIJID, StateData#state.pres_t) + TSet = if + IsTo -> (?SETS):add_element(LIJID, StateData#state.pres_t); + not IsTo -> remove_element(LIJID, StateData#state.pres_t) end, case StateData#state.pres_last of undefined -> @@ -2342,11 +2323,10 @@ process_privacy_iq(From, To, NewStateData. resend_offline_messages(StateData) -> - case - ejabberd_hooks:run_fold(resend_offline_messages_hook, - StateData#state.server, [], - [StateData#state.user, StateData#state.server]) - of + case ejabberd_hooks:run_fold(resend_offline_messages_hook, + StateData#state.server, [], + [StateData#state.user, StateData#state.server]) + of Rs -> %%when is_list(Rs) -> lists:foreach(fun ({route, From, To, #xmlel{} = Packet}) -> @@ -2366,8 +2346,7 @@ resend_offline_messages(StateData) -> end. resend_subscription_requests(#state{user = User, - server = Server} = - StateData) -> + server = Server} = StateData) -> PendingSubscriptions = ejabberd_hooks:run_fold(resend_subscription_requests_hook, Server, [], [User, Server]), @@ -2379,20 +2358,14 @@ resend_subscription_requests(#state{user = User, get_showtag(undefined) -> <<"unavailable">>; get_showtag(Presence) -> - case xml:get_path_s(Presence, - [{elem, <<"show">>}, cdata]) - of - <<"">> -> <<"available">>; - ShowTag -> ShowTag + case xml:get_path_s(Presence, [{elem, <<"show">>}, cdata]) of + <<"">> -> <<"available">>; + ShowTag -> ShowTag end. get_statustag(undefined) -> <<"">>; get_statustag(Presence) -> - case xml:get_path_s(Presence, - [{elem, <<"status">>}, cdata]) - of - ShowTag -> ShowTag - end. + xml:get_path_s(Presence, [{elem, <<"status">>}, cdata]). process_unauthenticated_stanza(StateData, El) -> NewEl = case xml:get_tag_attr_s(<<"xml:lang">>, El) of @@ -2492,23 +2465,27 @@ is_ip_blacklisted({IP, _Port}) -> %% returns invalid-from|NewElement check_from(El, FromJID) -> case xml:get_tag_attr(<<"from">>, El) of - false -> El; - {value, SJID} -> - JID = jlib:string_to_jid(SJID), - case JID of - error -> 'invalid-from'; - #jid{} -> - if (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) - and (JID#jid.lresource == FromJID#jid.lresource) -> - El; - (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) - and (JID#jid.lresource == <<"">>) -> - El; - true -> 'invalid-from' - end - end + false -> + El; + {value, SJID} -> + JID = jlib:string_to_jid(SJID), + case JID of + error -> + 'invalid-from'; + #jid{} -> + if + (JID#jid.luser == FromJID#jid.luser) and + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == FromJID#jid.lresource) -> + El; + (JID#jid.luser == FromJID#jid.luser) and + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == <<"">>) -> + El; + true -> + 'invalid-from' + end + end end. fsm_limit_opts(Opts) -> diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 16f0c06fc..6f3101fcd 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -143,24 +143,29 @@ check_and_forward(JID, To, #xmlel{name = <<"message">>, attrs = Attrs} = Packet, <<"chat">> -> case xml:get_subtag(Packet, <<"private">>) of false -> - case xml:get_subtag(Packet,<<"received">>) of + case xml:get_subtag(Packet, <<"no-copy">>) of false -> - %% We must check if a packet contains "<sent><forwarded></sent></forwarded>" tags in order to avoid - %% receiving message back to original sender. - SubTag = xml:get_subtag(Packet,<<"sent">>), - if SubTag == false -> - send_copies(JID, To, Packet, Direction); - true -> - case xml:get_subtag(SubTag,<<"forwarded">>) of - false-> - send_copies(JID, To, Packet, Direction); - _ -> - stop - end - end; + case xml:get_subtag(Packet,<<"received">>) of + false -> + %% We must check if a packet contains "<sent><forwarded></sent></forwarded>" + %% tags in order to avoid receiving message back to original sender. + SubTag = xml:get_subtag(Packet,<<"sent">>), + if SubTag == false -> + send_copies(JID, To, Packet, Direction); + true -> + case xml:get_subtag(SubTag,<<"forwarded">>) of + false-> + send_copies(JID, To, Packet, Direction); + _ -> + stop + end + end; + _ -> + %% stop the hook chain, we don't want mod_logdb to register this message (duplicate) + stop + end; _ -> - %% stop the hook chain, we don't want mod_logdb to register this message (duplicate) - stop + ok end; _ -> ok diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index e8724483e..ac6bea4fa 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -233,16 +233,22 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%% Internal functions %%-------------------------------------------------------------------- add_to_log2(text, {Nick, Packet}, Room, Opts, State) -> - case {xml:get_subtag(Packet, <<"subject">>), - xml:get_subtag(Packet, <<"body">>)} + case {xml:get_subtag(Packet, <<"no-store">>), + xml:get_subtag(Packet, <<"no-permanent-store">>)} of - {false, false} -> ok; - {false, SubEl} -> - Message = {body, xml:get_tag_cdata(SubEl)}, - add_message_to_log(Nick, Message, Room, Opts, State); - {SubEl, _} -> - Message = {subject, xml:get_tag_cdata(SubEl)}, - add_message_to_log(Nick, Message, Room, Opts, State) + {false, false} -> + case {xml:get_subtag(Packet, <<"subject">>), + xml:get_subtag(Packet, <<"body">>)} + of + {false, false} -> ok; + {false, SubEl} -> + Message = {body, xml:get_tag_cdata(SubEl)}, + add_message_to_log(Nick, Message, Room, Opts, State); + {SubEl, _} -> + Message = {subject, xml:get_tag_cdata(SubEl)}, + add_message_to_log(Nick, Message, Room, Opts, State) + end; + {_, _} -> ok end; add_to_log2(roomconfig_change, _Occupants, Room, Opts, State) -> @@ -779,7 +785,7 @@ fw(F, S, O, FileFormat) -> S1y = ejabberd_regexp:greplace(S1x, ?PLAINTEXT_IN, <<"<">>), ejabberd_regexp:greplace(S1y, ?PLAINTEXT_OUT, <<">">>) end, - io:format(F, S2, []). + file:write(F, S2). put_header(_, _, _, _, _, _, _, _, _, plaintext) -> ok; put_header(F, Room, Date, CSSFile, Lang, Hour_offset, @@ -1016,7 +1022,9 @@ htmlize2(S1, NoFollow) -> <<"\\ \\ ">>), S7 = ejabberd_regexp:greplace(S6, <<"\\t">>, <<"\\ \\ \\ \\ ">>), - ejabberd_regexp:greplace(S7, <<226, 128, 174>>, + S8 = ejabberd_regexp:greplace(S7, <<"~">>, + <<"~~">>), + ejabberd_regexp:greplace(S8, <<226, 128, 174>>, <<"[RLO]">>). link_regexp(false) -> <<"<a href=\"&\">&</a>">>; @@ -1240,5 +1248,6 @@ calc_hour_offset(TimeHere) -> 3600, TimeHereHour - TimeZeroHour. +fjoin([]) -> <<"/">>; fjoin(FileList) -> list_to_binary(filename:join([binary_to_list(File) || File <- FileList])). diff --git a/src/mod_offline.erl b/src/mod_offline.erl index fca227d31..f27d35830 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -237,22 +237,39 @@ store_packet(From, To, Packet) -> Type = xml:get_tag_attr_s(<<"type">>, Packet), if (Type /= <<"error">>) and (Type /= <<"groupchat">>) and (Type /= <<"headline">>) -> - case check_event(From, To, Packet) of - true -> - #jid{luser = LUser, lserver = LServer} = To, - TimeStamp = now(), - #xmlel{children = Els} = Packet, - Expire = find_x_expire(TimeStamp, Els), - gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! - #offline_msg{us = {LUser, LServer}, - timestamp = TimeStamp, expire = Expire, - from = From, to = To, packet = Packet}, - stop; + case has_no_storage_hint(Packet) of + false -> + case check_event(From, To, Packet) of + true -> + #jid{luser = LUser, lserver = LServer} = To, + TimeStamp = now(), + #xmlel{children = Els} = Packet, + Expire = find_x_expire(TimeStamp, Els), + gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! + #offline_msg{us = {LUser, LServer}, + timestamp = TimeStamp, expire = Expire, + from = From, to = To, packet = Packet}, + stop; + _ -> ok + end; _ -> ok end; true -> ok end. +has_no_storage_hint(Packet) -> + case xml:get_subtag(Packet, <<"no-store">>) of + #xmlel{attrs = Attrs} -> + case xml:get_attr_s(<<"xmlns">>, Attrs) of + ?NS_HINTS -> + true; + _ -> + false + end; + _ -> + false + end. + %% Check if the packet has any content about XEP-0022 or XEP-0085 check_event(From, To, Packet) -> #xmlel{name = Name, attrs = Attrs, children = Els} = |