Your message dated Wed, 27 Feb 2013 08:59:50 +0000
with message-id <4a199d849c7ad9d93dc01709a209a...@mail.adsl.funky-badger.org>
and subject line Re: Bug#701098: pre-approval unblock: ruby-rack/1.4.1-2.1
has caused the Debian Bug report #701098,
regarding pre-approval unblock: ruby-rack/1.4.1-2.1
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 ow...@bugs.debian.org
immediately.)


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

Dear release team,

Please unblock package ruby-rack, which fixes grave security bugs:
#698440
#700173
#700226

3 BTS contains 5 CVE adviseries tracked as:
https://security-tracker.debian.org/tracker/source-package/ruby-rack
All patches are backported from upstream fix.

I've prepared nmu with maintainer's permission, and debdiff is below:
(or, staging at mentors at: 
http://mentors.debian.net/debian/pool/main/r/ruby-rack/ruby-rack_1.4.1-2.1.dsc )
I'll ask for upload sponsor after this request would be approved.

diff -Nru ruby-rack-1.4.1/debian/changelog ruby-rack-1.4.1/debian/changelog
--- ruby-rack-1.4.1/debian/changelog    2012-06-26 03:07:51.000000000 +0900
+++ ruby-rack-1.4.1/debian/changelog    2013-02-20 21:21:25.000000000 +0900
@@ -1,3 +1,19 @@
+ruby-rack (1.4.1-2.1) testing-security; urgency=high
+
+  [ KURASHIKI Satoru ]
+  * Non-maintainer upload.
+  * Create cherry-picked patches for Security Fix (Closes: #700173 #700226).
+    - CVE-2013-0262: 0004-Prevent-symlink-path-traversals.patch
+    - CVE-2013-0263: 0005-Use-secure_compare-for-hmac-comparison.patch
+
+  [ Youhei SASAKI ]
+  * Create cherry-picked patches for Security Fix (Closes: #698440).
+    - CVE-2012-6109: 0001-Fix-parsing-performance-for-unquoted-filenames.patch
+    - CVE-2013-0183: 0002-multipart-parser-avoid-unbounded-gets-method.patch
+    - CVE-2013-0184: 0003-Reimplement-auth-scheme-fix.patch
+
+ -- KURASHIKI Satoru <lur...@gmail.com>  Wed, 20 Feb 2013 20:56:31 +0900
+
 ruby-rack (1.4.1-2) unstable; urgency=low
 
   * Bump build dependency on gem2deb to >= 0.3.0~
diff -Nru 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
--- 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
    1970-01-01 09:00:00.000000000 +0900
+++ 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
    2013-02-10 23:07:16.000000000 +0900
@@ -0,0 +1,67 @@
+From: James Tucker <jftuc...@gmail.com>
+Date: Sun, 13 May 2012 15:02:17 -0700
+Subject: Fix parsing performance for unquoted filenames
+
+Special thanks to Paul Rogers & Eric Wong
+
+Origin: upstream, 
https://github.com/rack/rack/commit/4fc44671b3cad569421f4f8b775c0590b86f575e
+Bug: https://security-tracker.debian.org/tracker/CVE-2012-6109
+Bug-Debian: http://bugs.debian.org/698440
+
+---
+ lib/rack/multipart.rb  |    4 ++--
+ test/spec_multipart.rb |   21 +++++++++++++++++++++
+ 2 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/lib/rack/multipart.rb b/lib/rack/multipart.rb
+index 3777106..6849248 100644
+--- a/lib/rack/multipart.rb
++++ b/lib/rack/multipart.rb
+@@ -12,7 +12,7 @@ module Rack
+     MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n
+     TOKEN = /[^\s()<>,;:\\"\/\[\]?=]+/
+     CONDISP = /Content-Disposition:\s*#{TOKEN}\s*/i
+-    DISPPARM = /;\s*(#{TOKEN})=("(?:\\"|[^"])*"|#{TOKEN})*/
++    DISPPARM = /;\s*(#{TOKEN})=("(?:\\"|[^"])*"|#{TOKEN})/
+     RFC2183 = /^#{CONDISP}(#{DISPPARM})+$/i
+     BROKEN_QUOTED = 
/^#{CONDISP}.*;\sfilename="(.*?)"(?:\s*$|\s*;\s*#{TOKEN}=)/i
+     BROKEN_UNQUOTED = /^#{CONDISP}.*;\sfilename=(#{TOKEN})/i
+@@ -31,4 +31,4 @@ module Rack
+     end
+
+   end
+-end
+\ No newline at end of file
++end
+diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb
+index b0bf57c..e4e5981 100644
+--- a/test/spec_multipart.rb
++++ b/test/spec_multipart.rb
+@@ -48,6 +48,27 @@ describe Rack::Multipart do
+     params['profile']['bio'].should.include 'hello'
+   end
+
++  should "parse very long unquoted multipart file names" do
++    data = <<-EOF
++--AaB03x\r
++Content-Type: text/plain\r
++Content-Disposition: attachment; name=file; filename=#{'long' * 100}\r
++\r
++contents\r
++--AaB03x--\r
++    EOF
++
++    options = {
++      "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
++      "CONTENT_LENGTH" => data.length.to_s,
++      :input => StringIO.new(data)
++    }
++    env = Rack::MockRequest.env_for("/", options)
++    params = Rack::Utils::Multipart.parse_multipart(env)
++
++    params["file"][:filename].should.equal('long' * 100)
++  end
++
+   should "parse multipart upload with text file" do
+     env = Rack::MockRequest.env_for("/", multipart_fixture(:text))
+     params = Rack::Multipart.parse_multipart(env)
diff -Nru 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
--- 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
      1970-01-01 09:00:00.000000000 +0900
+++ 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
      2013-02-10 23:07:16.000000000 +0900
@@ -0,0 +1,104 @@
+From: Eric Wong <normalper...@yhbt.net>
+Date: Wed, 22 Aug 2012 22:48:23 +0000
+Subject: multipart/parser: avoid unbounded #gets method
+
+Malicious clients may send excessively long lines
+to trigger out-of-memory errors in a Rack web server.
+
+Origin: upstream, 
https://github.com/rack/rack/commit/f95113402b7239f225282806673e1b6424522b18
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0183
+Bug-Debian: http://bugs.debian.org/698440
+
+---
+ lib/rack/multipart/parser.rb |   13 ++++++++---
+ test/spec_multipart.rb       |   53 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+), 3 deletions(-)
+
+diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb
+index 98eceaa..3773de7 100644
+--- a/lib/rack/multipart/parser.rb
++++ b/lib/rack/multipart/parser.rb
+@@ -68,9 +68,16 @@ module Rack
+
+       def fast_forward_to_first_boundary
+         loop do
+-          read_buffer = @io.gets
+-          break if read_buffer == full_boundary
+-          raise EOFError, "bad content body" if read_buffer.nil?
++          content = @io.read(BUFSIZE)
++          raise EOFError, "bad content body" unless content
++          @buf << content
++
++          while @buf.gsub!(/\A([^\n]*\n)/, '')
++            read_buffer = $1
++            return if read_buffer == full_boundary
++          end
++
++          raise EOFError, "bad content body" if Utils.bytesize(@buf) >= 
BUFSIZE
+         end
+       end
+
+diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb
+index e4e5981..1c50d9a 100644
+--- a/test/spec_multipart.rb
++++ b/test/spec_multipart.rb
+@@ -69,6 +69,59 @@ contents\r
+     params["file"][:filename].should.equal('long' * 100)
+   end
+
++  should "reject insanely long boundaries" do
++    # using a pipe since a tempfile can use up too much space
++    rd, wr = IO.pipe
++
++    # we only call rewind once at start, so make sure it succeeds
++    # and doesn't hit ESPIPE
++    def rd.rewind; end
++    wr.sync = true
++
++    # mock out length to make this pipe look like a Tempfile
++    def rd.length
++      1024 * 1024 * 8
++    end
++
++    # write to a pipe in a background thread, this will write a lot
++    # unless Rack (properly) shuts down the read end
++    thr = Thread.new do
++      begin
++        wr.write("--AaB03x")
++
++        # make the initial boundary a few gigs long
++        longer = "0123456789" * 1024 * 1024
++        (1024 * 1024).times { wr.write(longer) }
++
++        wr.write("\r\n")
++        wr.write('Content-Disposition: form-data; name="a"; filename="a.txt"')
++        wr.write("\r\n")
++        wr.write("Content-Type: text/plain\r\n")
++        wr.write("\r\na")
++        wr.write("--AaB03x--\r\n")
++        wr.close
++      rescue => err # this is EPIPE if Rack shuts us down
++        err
++      end
++    end
++
++    fixture = {
++      "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
++      "CONTENT_LENGTH" => rd.length.to_s,
++      :input => rd,
++    }
++
++    env = Rack::MockRequest.env_for '/', fixture
++    lambda {
++      Rack::Multipart.parse_multipart(env)
++    }.should.raise(EOFError)
++    rd.close
++
++    err = thr.value
++    err.should.be.instance_of Errno::EPIPE
++    wr.close
++  end
++
+   should "parse multipart upload with text file" do
+     env = Rack::MockRequest.env_for("/", multipart_fixture(:text))
+     params = Rack::Multipart.parse_multipart(env)
diff -Nru ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch 
ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch
--- ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch       
1970-01-01 09:00:00.000000000 +0900
+++ ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch       
2013-02-11 11:20:43.000000000 +0900
@@ -0,0 +1,131 @@
+From: James Tucker <jftuc...@gmail.com>
+Date: Sun, 13 Jan 2013 13:10:20 -0800
+Subject: Reimplement auth scheme fix
+
+ * Add Rack::Auth.add_scheme to enable folks to fix anything that breaks
+ * Add common auth schemes, MS ones, AWS ones, etc are missing, as unlikely
+ * Checked Rails - they don't use our authorization code
+ * Checked Warden - uses rails
+ * Checked Omniauth - uses rails
+ * Checked doorkeeper - users rails
+ * Checked rack-authentication - does it's own thing
+ * Checked warden-oauth - doesn't do headers
+ * Checked devise - uses rails
+ * Checked oauth2-rack - header creation only
+ * Checked rack-oauth2-server - does it's own thing
+ * Probably missed a bunch, but that'll have to do
+
+Origin: upstream, 
https://github.com/rack/rack/commit/87df8796a6e4555ec8fd3817c419c6b44b7ca459
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0184
+Bug-Debian: http://bugs.debian.org/698440
+
+---
+ lib/rack.rb                       |   12 ++++++++
+ lib/rack/auth/abstract/request.rb |    6 +++-
+ test/spec_auth.rb                 |   57 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 74 insertions(+), 1 deletion(-)
+ create mode 100644 test/spec_auth.rb
+
+diff --git a/lib/rack.rb b/lib/rack.rb
+index acfcb5a..18d5097 100644
+--- a/lib/rack.rb
++++ b/lib/rack.rb
+@@ -73,6 +73,18 @@ module Rack
+       autoload :Params, "rack/auth/digest/params"
+       autoload :Request, "rack/auth/digest/request"
+     end
++
++    # Not all of the following schemes are "standards", but they are used 
often.
++    @schemes = %w[basic digest bearer mac token oauth oauth2]
++
++    def self.add_scheme scheme
++      @schemes << scheme
++      @schemes.uniq!
++    end
++
++    def self.schemes
++      @schemes.dup
++    end
+   end
+
+   module Session
+diff --git a/lib/rack/auth/abstract/request.rb 
b/lib/rack/auth/abstract/request.rb
+index 9e15c72..c1553bf 100644
+--- a/lib/rack/auth/abstract/request.rb
++++ b/lib/rack/auth/abstract/request.rb
+@@ -21,7 +21,11 @@ module Rack
+       end
+
+       def scheme
+-        @scheme ||= parts.first.downcase.to_sym
++        @scheme ||=
++          begin
++            s = parts.first.downcase
++            Rack::Auth.schemes.include?(s) ? s.to_sym : s
++          end
+       end
+
+       def params
+diff --git a/test/spec_auth.rb b/test/spec_auth.rb
+new file mode 100644
+index 0000000..6588bd1
+--- /dev/null
++++ b/test/spec_auth.rb
+@@ -0,0 +1,57 @@
++require 'rack'
++
++describe Rack::Auth do
++  it "should have all common authentication schemes" do
++    Rack::Auth.schemes.should.include? 'basic'
++    Rack::Auth.schemes.should.include? 'digest'
++    Rack::Auth.schemes.should.include? 'bearer'
++    Rack::Auth.schemes.should.include? 'token'
++  end
++
++  it "should allow registration of new auth schemes" do
++    Rack::Auth.schemes.should.not.include "test"
++    Rack::Auth.add_scheme "test"
++    Rack::Auth.schemes.should.include "test"
++  end
++end
++
++describe Rack::Auth::AbstractRequest do
++  it "should symbolize known auth schemes" do
++    env = Rack::MockRequest.env_for('/')
++    env['HTTP_AUTHORIZATION'] = 'Basic aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :basic
++
++
++    env['HTTP_AUTHORIZATION'] = 'Digest aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :digest
++
++    env['HTTP_AUTHORIZATION'] = 'Bearer aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :bearer
++
++    env['HTTP_AUTHORIZATION'] = 'MAC aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :mac
++
++    env['HTTP_AUTHORIZATION'] = 'Token aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :token
++
++    env['HTTP_AUTHORIZATION'] = 'OAuth aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :oauth
++
++    env['HTTP_AUTHORIZATION'] = 'OAuth2 aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :oauth2
++  end
++
++  it "should not symbolize unknown auth schemes" do
++    env = Rack::MockRequest.env_for('/')
++    env['HTTP_AUTHORIZATION'] = 'magic aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == "magic"
++  end
++end
diff -Nru 
ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch 
ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch
--- ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch   
1970-01-01 09:00:00.000000000 +0900
+++ ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch   
2013-02-20 21:41:42.000000000 +0900
@@ -0,0 +1,40 @@
+Description: Prevent symlink path traversals
+ rack/file.rb (Rack::File) in Rack 1.5.x before 1.5.2 and 1.4.x before 1.4.5
+ allows attackers to access arbitrary files outside the intended root
+ directory via a crafted PATH_INFO environment variable, probably a directory
+ traversal vulnerability that is remotely exploitable, aka "symlink path 
traversals."
+
+Origin: upstream, 
https://github.com/rack/rack/commit/6f237e4c9fab649d3750482514f0fde76c56ab30
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0262
+Bug-Debian: http://bugs.debian.org/700173
+
+Index: ruby-rack/lib/rack/file.rb
+===================================================================
+--- ruby-rack.orig/lib/rack/file.rb    2013-02-20 21:36:40.000000000 +0900
++++ ruby-rack/lib/rack/file.rb 2013-02-20 21:39:58.265999186 +0900
+@@ -40,19 +40,14 @@
+       @path_info = Utils.unescape(env["PATH_INFO"])
+       parts = @path_info.split SEPS
+ 
+-      parts.inject(0) do |depth, part|
+-        case part
+-        when '', '.'
+-          depth
+-        when '..'
+-          return fail(404, "Not Found") if depth - 1 < 0
+-          depth - 1
+-        else
+-          depth + 1
+-        end
++      clean = []
++
++      parts.each do |part|
++        next if part.empty? || part == '.'
++        part == '..' ? clean.pop : clean << part
+       end
+ 
+-      @path = F.join(@root, *parts)
++      @path = F.join(@root, *clean)
+ 
+       available = begin
+         F.file?(@path) && F.readable?(@path)
diff -Nru 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
--- 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
    1970-01-01 09:00:00.000000000 +0900
+++ 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
    2013-02-20 23:15:59.000000000 +0900
@@ -0,0 +1,65 @@
+Description: Use secure compare for hmac comparison
+ Rack::Session::Cookie in Rack 1.5.x before 1.5.2, 1.4.x before 1.4.5,
+ 1.3.x before 1.3.10, 1.2.x before 1.2.8, and 1.1.x before 1.1.6 allows
+ remote attackers to guess the session cookie, gain privileges, and
+ execute arbitrary code via a timing attack involving am HMAC
+ comparison function that does not run in constant time.
+
+Origin: upstream,
+ https://github.com/rack/rack/commit/0cd7e9aa397f8ebb3b8481d67dbac8b4863a7f07,
+ https://github.com/rack/rack/commit/9a81b961457805f6d1a5c275d053068440421e11
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0263
+Bug-Debian: http://bugs.debian.org/700226
+
+Index: ruby-rack/lib/rack/session/cookie.rb
+===================================================================
+--- ruby-rack.orig/lib/rack/session/cookie.rb  2013-02-11 15:09:25.000000000 
+0900
++++ ruby-rack/lib/rack/session/cookie.rb       2013-02-20 23:11:19.091085974 
+0900
+@@ -108,7 +108,7 @@
+ 
+             if session_data && digest
+               ok = @secrets.any? do |secret|
+-                secret && digest == generate_hmac(session_data, secret)
++                secret && Rack::Utils.secure_compare(digest, 
generate_hmac(session_data, secret))
+               end
+             end
+ 
+Index: ruby-rack/lib/rack/utils.rb
+===================================================================
+--- ruby-rack.orig/lib/rack/utils.rb   2013-02-11 15:09:25.000000000 +0900
++++ ruby-rack/lib/rack/utils.rb        2013-02-20 23:12:39.171087876 +0900
+@@ -336,6 +336,18 @@
+     end
+     module_function :byte_ranges
+ 
++    # Constant time string comparison.
++    def secure_compare(a, b)
++      return false unless bytesize(a) == bytesize(b)
++
++      l = a.unpack("C*")
++
++      r, i = 0, -1
++      b.each_byte { |v| r |= v ^ l[i+=1] }
++      r == 0
++    end
++    module_function :secure_compare
++
+     # Context allows the use of a compatible middleware at different points
+     # in a request handling stack. A compatible middleware must define
+     # #context which should take the arguments env and app. The first of which
+Index: ruby-rack/test/spec_utils.rb
+===================================================================
+--- ruby-rack.orig/test/spec_utils.rb  2013-02-11 15:09:25.000000000 +0900
++++ ruby-rack/test/spec_utils.rb       2013-02-20 23:13:55.627089693 +0900
+@@ -322,6 +322,11 @@
+     Rack::Utils.bytesize("FOO\xE2\x82\xAC").should.equal 6
+   end
+ 
++  should "should perform constant time string comparison" do
++    Rack::Utils.secure_compare('a', 'a').should.equal true
++    Rack::Utils.secure_compare('a', 'b').should.equal false
++  end
++
+   should "return status code for integer" do
+     Rack::Utils.status_code(200).should.equal 200
+   end
diff -Nru ruby-rack-1.4.1/debian/patches/series 
ruby-rack-1.4.1/debian/patches/series
--- ruby-rack-1.4.1/debian/patches/series       1970-01-01 09:00:00.000000000 
+0900
+++ ruby-rack-1.4.1/debian/patches/series       2013-02-21 21:10:07.000000000 
+0900
@@ -0,0 +1,5 @@
+0001-Fix-parsing-performance-for-unquoted-filenames.patch
+0002-multipart-parser-avoid-unbounded-gets-method.patch
+0003-Reimplement-auth-scheme-fix.patch
+0004-Prevent-symlink-path-traversals.patch
+0005-Use-secure_compare-for-hmac-comparison.patch

unblock ruby-rack/1.4.1-2.1

-- System Information:
Debian Release: 7.0
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=ja_JP.UTF-8, LC_CTYPE=ja_JP.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

--- End Message ---
--- Begin Message ---
On 21.02.2013 23:54, Satoru KURASHIKI wrote:
hi,

On Fri, Feb 22, 2013 at 12:45 AM, Adam D. Barratt
<a...@adam-barratt.org.uk> wrote:
On 21.02.2013 14:31, KURASHIKI Satoru wrote:
We can't unblock packages which aren't in the archive...

#698440
#700173
#700226


... and you don't need pre-approval to fix RC bugs.

OK, I will seek for spnsor to upload into unstable.

Looks like that happened. Unblocked; thanks.

Regards,

Adam

--- End Message ---

Reply via email to