[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#703347: marked as done (unblock: ejabberd 2.1.10-4)



Your message dated Thu, 04 Apr 2013 20:40:50 +0100
with message-id <1365104450.6034.13.camel@jacala.jungle.funky-badger.org>
and subject line Re: Bug#703347: unblock: ejabberd 2.1.10-4
has caused the Debian Bug report #703347,
regarding unblock: ejabberd 2.1.10-4
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
703347: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=703347
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: freeze-exception

Please unblock package ejabberd 2.1.10-4.

It fixes three important bugs:
* Broken import of JPEG images from users' vCards fetched from LDAP [1].
  The patch is trivial as it merely fixes a programming blooper.
* Creation of an extraneous file under /root during installation [2].
  The fix is rather simple as well.
* Incorrect parsing of HTTPS requests split into multiple packets [3].
  The fix for this bug is rather involved but happily the code base
  between the upstream versions 2.1.10 (affected) and 2.1.11 (received
  the fix) almost did not change so the extracted patch was applied
  OK after minimal massaging.  This bug is really several as it is
  reported to reliably break certain web chat applications and BOSH [4]
  connections so I think we should include the fix for it.

The debdiff is attached.

1. http://bugs.debian.org/660186
2. http://bugs.debian.org/691125
3. http://bugs.debian.org/698309
4. http://xmpp.org/extensions/xep-0206.html
diff -u ejabberd-2.1.10/debian/prerm ejabberd-2.1.10/debian/prerm
--- ejabberd-2.1.10/debian/prerm
+++ ejabberd-2.1.10/debian/prerm
@@ -15,15 +15,23 @@
 #          <conflicting-package> <version>
 # for details, see /usr/doc/packaging-manual/
 
+ctl() {
+	local cmd='/usr/sbin/ejabberdctl'
+	for arg in "$@"; do
+		cmd="$cmd '$arg'"
+	done
+	su ejabberd -c "$cmd"
+}
+
 case "$1" in
     remove|upgrade)
-	if ejabberdctl status >/dev/null ; then
+	if ctl status >/dev/null ; then
 	    # Use timestamp to make database restoring easier
 	    TIME=$(date +%Y-%m-%dT%H:%M:%S)
 	    BACKUPDIR=$(mktemp -d -p /var/backups/ ejabberd-$TIME.XXXXXX)
 	    chown ejabberd:ejabberd $BACKUPDIR
 	    BACKUP=$BACKUPDIR/ejabberd-database
-	    ejabberdctl backup $BACKUP
+	    ctl backup $BACKUP
 	    # Change ownership to root:root because ejabberd user might be
 	    # removed on package removal.
 	    chown -R root:root $BACKUPDIR
diff -u ejabberd-2.1.10/debian/changelog ejabberd-2.1.10/debian/changelog
--- ejabberd-2.1.10/debian/changelog
+++ ejabberd-2.1.10/debian/changelog
@@ -1,3 +1,15 @@
+ejabberd (2.1.10-4) unstable; urgency=low
+
+  [ Konstantin Khomoutov ]
+  * Do not run ejabberdctl as root in prerm and logrotate scripts
+    (closes: #691125, thanks to Michael Stapelberg and Felix Geyer).
+  * Add upstream patch fixing receiving JPEG vCard photos via LDAP
+    (closes: #660186).
+  * Add upstream patch fixing parsing HTTPS requests split into
+    multiple packets (closes: #698309).
+
+ -- Konstantin Khomoutov <flatworm@users.sourceforge.net>  Sat, 16 Feb 2013 16:59:21 +0000
+
 ejabberd (2.1.10-3) unstable; urgency=low
 
   [ Konstantin Khomoutov ]
diff -u ejabberd-2.1.10/debian/logrotate ejabberd-2.1.10/debian/logrotate
--- ejabberd-2.1.10/debian/logrotate
+++ ejabberd-2.1.10/debian/logrotate
@@ -10,5 +10,5 @@
 	sharedscripts
 	postrotate
-		/usr/sbin/ejabberdctl reopen-log > /dev/null
+		su ejabberd -c '/usr/sbin/ejabberdctl reopen-log' > /dev/null
 	endscript
 }
diff -u ejabberd-2.1.10/debian/patches/series ejabberd-2.1.10/debian/patches/series
--- ejabberd-2.1.10/debian/patches/series
+++ ejabberd-2.1.10/debian/patches/series
@@ -7,0 +8,2 @@
+fix-ldap-vcard-jpeg-photos.patch
+fix-parsing-split-https-requests.patch
only in patch2:
unchanged:
--- ejabberd-2.1.10.orig/debian/patches/fix-ldap-vcard-jpeg-photos.patch
+++ ejabberd-2.1.10/debian/patches/fix-ldap-vcard-jpeg-photos.patch
@@ -0,0 +1,16 @@
+Description: Fix fetching JPEG vCard photos via LDAP
+Origin: upstream, https://github.com/processone/ejabberd/commit/be33ab890e35ae5c41285dd5ed422db910534040
+Bug-ProcessOne: https://support.process-one.net/browse/EJAB-1526
+Applied-Upstream: 2.1.11
+Last-Update: 2013-02-17
+diff --git a/src/eldap/eldap_filter.erl b/src/eldap/eldap_filter.erl
+index f8f20be..e78ee7e 100644
+--- a/src/eldap/eldap_filter.erl
++++ b/src/eldap/eldap_filter.erl
+@@ -181,5 +181,6 @@ do_sub(S, {RegExp, New, Times}, Iter) ->
+ replace_amps(String) ->
+     lists:flatmap(
+       fun($&) -> "\\&";
++         ($\\) -> "\\\\";
+ 	 (Chr) -> [Chr]
+       end, String).
only in patch2:
unchanged:
--- ejabberd-2.1.10.orig/debian/patches/fix-parsing-split-https-requests.patch
+++ ejabberd-2.1.10/debian/patches/fix-parsing-split-https-requests.patch
@@ -0,0 +1,312 @@
+Description: Fix parsing HTTPS requests split into multiple packets
+  This fixes case when SockMod:recv() calls returns only
+  part of first line of http request (GET/POST/OPTION/HEAD line).
+  Before that change request like that (and if keep-alive was active,
+  all further request) were dropped.
+
+  The patch extracted from the upstream commit has been slightly
+  massaged to apply cleanly to the stock 2.1.10 source code.
+Origin: upstream, https://github.com/processone/ejabberd/commit/5f828467327bbd0fb8df6afc20559c2208bc0603
+Bug-ProcessOne: https://support.process-one.net/browse/EJAB-1537
+Applied-Upstream: 2.1.11
+Last-Update: 2013-02-17
+--- a/src/web/ejabberd_http.erl
++++ b/src/web/ejabberd_http.erl
+@@ -65,7 +65,7 @@
+ 		request_tp,
+ 		request_headers = [],
+ 		end_of_request = false,
+-		trail = ""
++		trail = <<>>
+ 	       }).
+ 
+ 
+@@ -164,12 +164,12 @@
+ 	    exit(normal)
+     end.
+ 
+-receive_headers(State) ->
++receive_headers(#state{trail=Trail} = State) ->
+     SockMod = State#state.sockmod,
+     Socket = State#state.socket,
+     Data = SockMod:recv(Socket, 0, 300000),
+     case State#state.sockmod of
+-	gen_tcp ->
++        gen_tcp ->
+ 	    NewState = process_header(State, Data),
+ 	    case NewState#state.end_of_request of
+ 		true ->
+@@ -177,31 +177,35 @@
+ 		_ ->
+ 		    receive_headers(NewState)
+ 	    end;
+-	_ ->
+-	    case Data of
+-		{ok, Binary} ->
+-		    {Request, Trail} = parse_request(
+-					 State,
+-					 State#state.trail ++ binary_to_list(Binary)),
+-		    State1 = State#state{trail = Trail},
+-		    NewState = lists:foldl(
+-				 fun(D, S) ->
+-					case S#state.end_of_request of
+-					    true ->
+-						S;
+-					    _ ->
+-						process_header(S, D)
+-					end
+-				 end, State1, Request),
+-		    case NewState#state.end_of_request of
+-			true ->
+-			    ok;
+-			_ ->
+-			    receive_headers(NewState)
+-		    end;
++        _ ->
++            case Data of
++                {ok, D} ->
++                    parse_headers(State#state{trail = <<Trail/binary, D/binary>>});
++                {error, _} ->
++                    ok
++            end
++    end.
++
++parse_headers(#state{trail = <<>>} = State) ->
++    receive_headers(State);
++parse_headers(#state{request_method = Method, trail = Data} = State) ->
++    PktType = case Method of
++                  undefined -> http;
++                  _ -> httph
++              end,
++    case decode_packet(PktType, Data) of
++        {ok, Pkt, Rest} ->
++            NewState = process_header(State#state{trail = Rest}, {ok, Pkt}),
++	    case NewState#state.end_of_request of
++		true ->
++		    ok;
+ 		_ ->
+-		    ok
+-	    end
++                    parse_headers(NewState)
++	    end;
++        {more, _} ->
++            receive_headers(State#state{trail = Data});
++        _ ->
++            ok
+     end.
+ 
+ process_header(State, Data) ->
+@@ -506,16 +510,16 @@
+     binary_to_list(list_to_binary(Acc));
+ recv_data(State, Len, Acc) ->
+     case State#state.trail of
+-	[] ->
+-	    case (State#state.sockmod):recv(State#state.socket,   Len, 300000) of
++	<<>> ->
++	    case (State#state.sockmod):recv(State#state.socket, Len, 300000) of
+ 		{ok, Data} ->
+ 		    recv_data(State, Len - size(Data), [Acc | [Data]]);
+ 		_ ->
+ 		    ""
+ 	    end;
+ 	_ ->
+-	    Trail = State#state.trail,
+-	    recv_data(State#state{trail = ""}, Len - length(Trail), [Acc | Trail])
++	    Trail = binary_to_list(State#state.trail),
++	    recv_data(State#state{trail = <<>>}, Len - length(Trail), [Acc | Trail])
+     end.
+ 
+ 
+@@ -796,7 +800,7 @@
+ decode_base64([]) ->
+   [];
+ decode_base64([Sextet1,Sextet2,$=,$=|Rest]) ->
+-  Bits2x6=
++    Bits2x6=
+     (d(Sextet1) bsl 18) bor
+     (d(Sextet2) bsl 12),
+   Octet1=Bits2x6 bsr 16,
+@@ -906,42 +910,29 @@
+ 
+ % The following code is mostly taken from yaws_ssl.erl
+ 
+-parse_request(State, Data) ->
+-    case Data of
+-	[] ->
+-	    {[], []};
+-	_ ->
+-	    ?DEBUG("GOT ssl data ~p~n", [Data]),
+-	    {R, Trail} = case State#state.request_method of
+-			     undefined ->
+-				 {R1, Trail1} = get_req(Data),
+-				 ?DEBUG("Parsed request ~p~n", [R1]),
+-				 {[R1], Trail1};
+-			     _ ->
+-				 {[], Data}
+-			 end,
+-	    {H, Trail2} = get_headers(Trail),
+-	    {R ++ H, Trail2}
++decode_packet(_, <<"\r\n", Rest/binary>>) ->
++    {ok, http_eoh, Rest};
++decode_packet(Type, Data) ->
++    case binary:match(Data, <<"\r\n">>) of
++        {Start, _Len} ->
++            <<LineB:Start/binary, _:2/binary, Rest/binary>> = Data,
++            Line = binary_to_list(LineB),
++            Result = case Type of
++                         http ->
++                             parse_req(Line);
++                         httph ->
++                             parse_line(Line)
++                     end,
++            case Result of
++                {ok, H} ->
++                    {ok, H, Rest};
++                Err ->
++                    {error, Err}
++            end;
++        _ ->
++            {more, undefined}
+     end.
+ 
+-get_req("\r\n\r\n" ++ _) ->
+-    bad_request;
+-get_req("\r\n" ++ Data) ->
+-    get_req(Data);
+-get_req(Data) ->
+-    {FirstLine, Trail} = lists:splitwith(fun not_eol/1, Data),
+-    R = parse_req(FirstLine),
+-    {R, Trail}.
+-
+-
+-not_eol($\r)->
+-    false;
+-not_eol($\n) ->
+-    false;
+-not_eol(_) ->
+-    true.
+-
+-
+ get_word(Line)->
+     {Word, T} = lists:splitwith(fun(X)-> X /= $\  end, Line),
+     {Word, lists:dropwhile(fun(X) -> X == $\  end, T)}.
+@@ -1012,68 +1003,54 @@
+     end.
+ 
+ 
+-get_headers(Tail) ->
+-    get_headers([], Tail).
+-
+-get_headers(H, Tail) ->
+-    case get_line(Tail) of
+-	{incomplete, Tail2} ->
+-	    {H, Tail2};
+-	{line, Line, Tail2} ->
+-	    get_headers(H ++ parse_line(Line), Tail2);
+-	{lastline, Line, Tail2} ->
+-	    {H ++ parse_line(Line) ++ [{ok, http_eoh}], Tail2}
+-    end.
+-
+-
+ parse_line("Connection:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Connection', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Connection', undefined, strip_spaces(Con)}};
+ parse_line("Host:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Host', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Host', undefined, strip_spaces(Con)}};
+ parse_line("Accept:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Accept', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Accept', undefined, strip_spaces(Con)}};
+ parse_line("If-Modified-Since:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'If-Modified-Since', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'If-Modified-Since', undefined, strip_spaces(Con)}};
+ parse_line("If-Match:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'If-Match', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'If-Match', undefined, strip_spaces(Con)}};
+ parse_line("If-None-Match:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'If-None-Match', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'If-None-Match', undefined, strip_spaces(Con)}};
+ parse_line("If-Range:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'If-Range', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'If-Range', undefined, strip_spaces(Con)}};
+ parse_line("If-Unmodified-Since:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'If-Unmodified-Since', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'If-Unmodified-Since', undefined, strip_spaces(Con)}};
+ parse_line("Range:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Range', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Range', undefined, strip_spaces(Con)}};
+ parse_line("User-Agent:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'User-Agent', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'User-Agent', undefined, strip_spaces(Con)}};
+ parse_line("Accept-Ranges:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Accept-Ranges', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Accept-Ranges', undefined, strip_spaces(Con)}};
+ parse_line("Authorization:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Authorization', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Authorization', undefined, strip_spaces(Con)}};
+ parse_line("Keep-Alive:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Keep-Alive', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Keep-Alive', undefined, strip_spaces(Con)}};
+ parse_line("Referer:" ++ Con) ->
+-    [{ok, {http_header,  undefined, 'Referer', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Referer', undefined, strip_spaces(Con)}};
+ parse_line("Content-type:"++Con) ->
+-    [{ok, {http_header,  undefined, 'Content-Type', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Content-Type', undefined, strip_spaces(Con)}};
+ parse_line("Content-Type:"++Con) ->
+-    [{ok, {http_header,  undefined, 'Content-Type', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Content-Type', undefined, strip_spaces(Con)}};
+ parse_line("Content-Length:"++Con) ->
+-    [{ok, {http_header,  undefined, 'Content-Length', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Content-Length', undefined, strip_spaces(Con)}};
+ parse_line("Content-length:"++Con) ->
+-    [{ok, {http_header,  undefined, 'Content-Length', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Content-Length', undefined, strip_spaces(Con)}};
+ parse_line("Cookie:"++Con) ->
+-    [{ok, {http_header,  undefined, 'Cookie', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Cookie', undefined, strip_spaces(Con)}};
+ parse_line("Accept-Language:"++Con) ->
+-    [{ok, {http_header,  undefined, 'Accept-Language', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Accept-Language', undefined, strip_spaces(Con)}};
+ parse_line("Accept-Encoding:"++Con) ->
+-    [{ok, {http_header,  undefined, 'Accept-Encoding', undefined, strip_spaces(Con)}}];
++    {ok, {http_header,  undefined, 'Accept-Encoding', undefined, strip_spaces(Con)}};
+ parse_line(S) ->
+     case lists:splitwith(fun(C)->C /= $: end, S) of
+ 	{Name, [$:|Val]} ->
+-	    [{ok, {http_header,  undefined, Name, undefined, strip_spaces(Val)}}];
++	    {ok, {http_header,  undefined, Name, undefined, strip_spaces(Val)}};
+ 	_ ->
+-	    []
++	    bad_request
+     end.
+ 
+ 
+@@ -1109,27 +1086,3 @@
+ 	    YS
+     end.
+ 
+-is_nb_space(X) ->
+-    lists:member(X, [$\s, $\t]).
+-
+-
+-% ret: {line, Line, Trail} | {lastline, Line, Trail}
+-
+-get_line(L) ->
+-    get_line(L, []).
+-get_line("\r\n\r\n" ++ Tail, Cur) ->
+-    {lastline, lists:reverse(Cur), Tail};
+-get_line("\r\n" ++ Tail, Cur) ->
+-    case Tail of
+-	[] ->
+-	    {incomplete, lists:reverse(Cur) ++ "\r\n"};
+-	_ ->
+-	    case is_nb_space(hd(Tail)) of
+-		true ->  %% multiline ... continue
+-		    get_line(Tail, [$\n, $\r | Cur]);
+-		false ->
+-		    {line, lists:reverse(Cur), Tail}
+-	    end
+-    end;
+-get_line([H|T], Cur) ->
+-    get_line(T, [H|Cur]).

--- End Message ---
--- Begin Message ---
On Mon, 2013-03-18 at 21:09 +0400, Konstantin Khomoutov wrote:
> Please unblock package ejabberd 2.1.10-4.

This got done in #698647. Why there were two unblocks for the same
package...

Regards,

Adam

--- End Message ---

Reply to: