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

Bug#841724: jessie-pu: package guile-2.0/2.0.11+1-9



Package: release.debian.org
Severity: important
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

I'd like to propose an update for jessie as described by the attached
debdiff.  Though the final upload/diff might be slightly different
(i.e. the dpm hashes).

Both of the changes (patches) have been cherry-picked from upstream as
described in the patch headers.

diff -Nru guile-2.0-2.0.11+1/debian/.git-dpm guile-2.0-2.0.11+1/debian/.git-dpm
--- guile-2.0-2.0.11+1/debian/.git-dpm	2014-10-06 10:07:49.000000000 -0500
+++ guile-2.0-2.0.11+1/debian/.git-dpm	2016-10-14 00:08:24.000000000 -0500
@@ -1,6 +1,6 @@
 # see git-dpm(1) from git-dpm package
-fdc2c9e00af5f2721c4e70180d30f45c15adc65a
-fdc2c9e00af5f2721c4e70180d30f45c15adc65a
+6f697cf7a887fcb4163bef810536bb55cf3b11d3
+6f697cf7a887fcb4163bef810536bb55cf3b11d3
 972fb41f0ce124d97f5cf64bde1075510cd21e18
 972fb41f0ce124d97f5cf64bde1075510cd21e18
 guile-2.0_2.0.11+1.orig.tar.bz2
diff -Nru guile-2.0-2.0.11+1/debian/changelog guile-2.0-2.0.11+1/debian/changelog
--- guile-2.0-2.0.11+1/debian/changelog	2014-10-07 14:49:51.000000000 -0500
+++ guile-2.0-2.0.11+1/debian/changelog	2016-10-22 11:36:24.000000000 -0500
@@ -1,3 +1,19 @@
+guile-2.0 (2.0.11+1-9+deb8u1) jessie; urgency=high
+
+  * Fix REPL server vulnerability (CVE-2016-8606).  Add
+    0017-REPL-Server-Guard-against-HTTP-inter-protocol-exploi.patch to
+    incorporate the fix.  See that file for further information.
+    (Closes: 840555)
+
+  * Fix mkdir umask-related vulnerability (CVE-2016-8605).  Previously,
+    whenever the second argument to mkdir was omitted, it would
+    temporarily change the umask to 0, a change which would also affect
+    any concurrent threads.  Add
+    0018-Remove-umask-calls-from-mkdir.patch to incorporate the fix.
+    See that file for further information. (Closes: 840556)
+
+ -- Rob Browning <rlb@defaultvalue.org>  Sat, 22 Oct 2016 11:36:24 -0500
+
 guile-2.0 (2.0.11+1-9) unstable; urgency=medium
 
   * Always use "gcc" in guile-snarf.  Avoid the gcc-4.8 CC override that
diff -Nru guile-2.0-2.0.11+1/debian/patches/0017-REPL-Server-Guard-against-HTTP-inter-protocol-exploi.patch guile-2.0-2.0.11+1/debian/patches/0017-REPL-Server-Guard-against-HTTP-inter-protocol-exploi.patch
--- guile-2.0-2.0.11+1/debian/patches/0017-REPL-Server-Guard-against-HTTP-inter-protocol-exploi.patch	1969-12-31 18:00:00.000000000 -0600
+++ guile-2.0-2.0.11+1/debian/patches/0017-REPL-Server-Guard-against-HTTP-inter-protocol-exploi.patch	2016-10-14 00:08:23.000000000 -0500
@@ -0,0 +1,337 @@
+From 9de478809f909986c725294d1dc03a317eafa3ff Mon Sep 17 00:00:00 2001
+From: Mark H Weaver <mhw@netris.org>
+Date: Fri, 9 Sep 2016 07:36:52 -0400
+Subject: REPL Server: Guard against HTTP inter-protocol exploitation attacks.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Reported by Christopher Allan Webber <cwebber@dustycloud.org>
+Co-authored-by: Ludovic Courtès <ludo@gnu.org>
+
+This commit adds protection to Guile's REPL servers against HTTP
+inter-protocol exploitation attacks, a scenario whereby an attacker can,
+via an HTML page, cause a web browser to send data to TCP servers
+listening on a loopback interface or private network.  See
+<https://en.wikipedia.org/wiki/Inter-protocol_exploitation> and
+<https://www.jochentopf.com/hfpa/hfpa.pdf>, The HTML Form Protocol
+Attack (2001) by Tochen Topf <jochen@remote.org>.
+
+Here we add a procedure to 'before-read-hook' that looks for a possible
+HTTP request-line in the first line of input from the client socket.  If
+present, the socket is drained and closed, and a loud warning is written
+to stderr (POSIX file descriptor 2).
+
+* module/system/repl/server.scm: Add 'maybe-check-for-http-request'
+to 'before-read-hook' when this module is loaded.
+(with-temporary-port-encoding, with-saved-port-line+column)
+(drain-input-and-close, permissive-http-request-line?)
+(check-for-http-request, guard-against-http-request)
+(maybe-check-for-http-request): New procedures.
+(serve-client): Use 'guard-against-http-request'.
+* module/system/repl/coop-server.scm (start-repl-client): Use
+'guard-against-http-request'.
+* doc/ref/guile-invoke.texi (Command-line Options): In the description
+of the --listen option, make the security warning more prominent.
+Mention the new protection added here.  Recommend using UNIX domain
+sockets for REPL servers.  "a path to" => "the file name of".
+
+Origin: upstream, http://git.savannah.gnu.org/cgit/guile.git/commit/?id=08c021916dbd3a235a9f9cc33df4c418c0724e03
+Bug-Debian: http://bugs.debian.org/840555
+---
+ doc/ref/guile-invoke.texi          |  20 +++-
+ module/system/repl/coop-server.scm |   7 +-
+ module/system/repl/server.scm      | 182 ++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 201 insertions(+), 8 deletions(-)
+
+diff --git a/doc/ref/guile-invoke.texi b/doc/ref/guile-invoke.texi
+index 95493dd..9353e8a 100644
+--- a/doc/ref/guile-invoke.texi
++++ b/doc/ref/guile-invoke.texi
+@@ -1,7 +1,7 @@
+ @c -*-texinfo-*-
+ @c This is part of the GNU Guile Reference Manual.
+-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2010, 2011, 2013
+-@c   Free Software Foundation, Inc.
++@c Copyright (C)  1996, 1997, 2000-2005, 2010, 2011, 2013, 2014,
++@c   2016 Free Software Foundation, Inc.
+ @c See the file guile.texi for copying conditions.
+ 
+ @node Invoking Guile
+@@ -176,7 +176,7 @@ the @file{.guile} file.  @xref{Init File}.
+ While this program runs, listen on a local port or a path for REPL
+ clients.  If @var{p} starts with a number, it is assumed to be a local
+ port on which to listen.  If it starts with a forward slash, it is
+-assumed to be a path to a UNIX domain socket on which to listen.
++assumed to be the file name of a UNIX domain socket on which to listen.
+ 
+ If @var{p} is not given, the default is local port 37146.  If you look
+ at it upside down, it almost spells ``Guile''.  If you have netcat
+@@ -184,12 +184,22 @@ installed, you should be able to @kbd{nc localhost 37146} and get a
+ Guile prompt.  Alternately you can fire up Emacs and connect to the
+ process; see @ref{Using Guile in Emacs} for more details.
+ 
+-Note that opening a port allows anyone who can connect to that port---in
+-the TCP case, any local user---to do anything Guile can do, as the user
++@quotation Note
++Opening a port allows anyone who can connect to that port to do anything
++Guile can do, as the user
+ that the Guile process is running as.  Do not use @option{--listen} on
+ multi-user machines.  Of course, if you do not pass @option{--listen} to
+ Guile, no port will be opened.
+ 
++Guile protects against the
++@uref{https://en.wikipedia.org/wiki/Inter-protocol_exploitation,
++@dfn{HTTP inter-protocol exploitation attack}}, a scenario whereby an
++attacker can, @i{via} an HTML page, cause a web browser to send data to
++TCP servers listening on a loopback interface or private network.
++Nevertheless, you are advised to use UNIX domain sockets, as in
++@code{--listen=/some/local/file}, whenever possible.
++@end quotation
++
+ That said, @option{--listen} is great for interactive debugging and
+ development.
+ 
+diff --git a/module/system/repl/coop-server.scm b/module/system/repl/coop-server.scm
+index c19dda1..ae31ce8 100644
+--- a/module/system/repl/coop-server.scm
++++ b/module/system/repl/coop-server.scm
+@@ -1,6 +1,6 @@
+ ;;; Cooperative REPL server
+ 
+-;; Copyright (C) 2014 Free Software Foundation, Inc.
++;; Copyright (C) 2014, 2016 Free Software Foundation, Inc.
+ 
+ ;; This library is free software; you can redistribute it and/or
+ ;; modify it under the terms of the GNU Lesser General Public
+@@ -29,7 +29,8 @@
+                 #:select (start-repl* prompting-meta-read))
+   #:use-module ((system repl server)
+                 #:select (run-server* make-tcp-server-socket
+-                                      add-open-socket! close-socket!))
++                                      add-open-socket! close-socket!
++                                      guard-against-http-request))
+   #:export (spawn-coop-repl-server
+             poll-coop-repl-server))
+ 
+@@ -173,6 +174,8 @@ and output is sent over the socket CLIENT."
+   ;; another thread.
+   (add-open-socket! client (lambda () (close-fdes (fileno client))))
+ 
++  (guard-against-http-request client)
++
+   (with-continuation-barrier
+    (lambda ()
+      (coop-repl-prompt
+diff --git a/module/system/repl/server.scm b/module/system/repl/server.scm
+index ff9ee5c..9ece947 100644
+--- a/module/system/repl/server.scm
++++ b/module/system/repl/server.scm
+@@ -1,6 +1,6 @@
+ ;;; Repl server
+ 
+-;; Copyright (C)  2003, 2010, 2011, 2014 Free Software Foundation, Inc.
++;; Copyright (C)  2003, 2010, 2011, 2014, 2016 Free Software Foundation, Inc.
+ 
+ ;; This library is free software; you can redistribute it and/or
+ ;; modify it under the terms of the GNU Lesser General Public
+@@ -22,8 +22,13 @@
+ (define-module (system repl server)
+   #:use-module (system repl repl)
+   #:use-module (ice-9 threads)
++  #:use-module (ice-9 rdelim)
+   #:use-module (ice-9 match)
++  #:use-module (ice-9 iconv)
++  #:use-module (rnrs bytevectors)
++  #:use-module (rnrs io ports)
+   #:use-module (srfi srfi-1)
++  #:use-module (srfi srfi-26)           ; cut
+   #:export (make-tcp-server-socket
+             make-unix-domain-server-socket
+             run-server
+@@ -154,6 +159,8 @@
+     ;; Arrange to cancel this thread to forcefully shut down the socket.
+     (add-open-socket! client (lambda () (cancel-thread thread))))
+ 
++  (guard-against-http-request client)
++
+   (with-continuation-barrier
+    (lambda ()
+      (parameterize ((current-input-port client)
+@@ -162,3 +169,176 @@
+                     (current-warning-port client))
+        (with-fluids ((*repl-stack* '()))
+          (start-repl))))))
++
++
++;;;
++;;; The following code adds protection to Guile's REPL servers against
++;;; HTTP inter-protocol exploitation attacks, a scenario whereby an
++;;; attacker can, via an HTML page, cause a web browser to send data to
++;;; TCP servers listening on a loopback interface or private network.
++;;; See <https://en.wikipedia.org/wiki/Inter-protocol_exploitation> and
++;;; <https://www.jochentopf.com/hfpa/hfpa.pdf>, The HTML Form Protocol
++;;; Attack (2001) by Tochen Topf <jochen@remote.org>.
++;;;
++;;; Here we add a procedure to 'before-read-hook' that looks for a possible
++;;; HTTP request-line in the first line of input from the client socket.  If
++;;; present, the socket is drained and closed, and a loud warning is written
++;;; to stderr (POSIX file descriptor 2).
++;;;
++
++(define (with-temporary-port-encoding port encoding thunk)
++  "Call THUNK in a dynamic environment in which the encoding of PORT is
++temporarily set to ENCODING."
++  (let ((saved-encoding #f))
++    (dynamic-wind
++      (lambda ()
++        (unless (port-closed? port)
++          (set! saved-encoding (port-encoding port))
++          (set-port-encoding! port encoding)))
++      thunk
++      (lambda ()
++        (unless (port-closed? port)
++          (set! encoding (port-encoding port))
++          (set-port-encoding! port saved-encoding))))))
++
++(define (with-saved-port-line+column port thunk)
++  "Save the line and column of PORT before entering THUNK, and restore
++their previous values upon normal or non-local exit from THUNK."
++  (let ((saved-line #f) (saved-column #f))
++    (dynamic-wind
++      (lambda ()
++        (unless (port-closed? port)
++          (set! saved-line   (port-line   port))
++          (set! saved-column (port-column port))))
++      thunk
++      (lambda ()
++        (unless (port-closed? port)
++          (set-port-line!   port saved-line)
++          (set-port-column! port saved-column))))))
++
++(define (drain-input-and-close socket)
++  "Drain input from SOCKET using ISO-8859-1 encoding until it would block,
++and then close it.  Return the drained input as a string."
++  (dynamic-wind
++    (lambda ()
++      ;; Enable full buffering mode on the socket to allow
++      ;; 'get-bytevector-some' to return non-trivial chunks.
++      (setvbuf socket _IOFBF))
++    (lambda ()
++      (let loop ((chunks '()))
++        (let ((result (and (char-ready? socket)
++                           (get-bytevector-some socket))))
++          (if (bytevector? result)
++              (loop (cons (bytevector->string result "ISO-8859-1")
++                          chunks))
++              (string-concatenate-reverse chunks)))))
++    (lambda ()
++      ;; Close the socket even in case of an exception.
++      (close-port socket))))
++
++(define permissive-http-request-line?
++  ;; This predicate is deliberately permissive
++  ;; when checking the Request-URI component.
++  (let ((cs (ucs-range->char-set #x20 #x7E))
++        (rx (make-regexp
++             (string-append
++              "^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT) "
++              "[^ ]+ "
++              "HTTP/[0-9]+.[0-9]+$"))))
++    (lambda (line)
++      "Return true if LINE might plausibly be an HTTP request-line,
++otherwise return #f."
++      ;; We cannot simplify this to a simple 'regexp-exec', because
++      ;; 'regexp-exec' cannot cope with NUL bytes.
++      (and (string-every cs line)
++           (regexp-exec  rx line)))))
++
++(define (check-for-http-request socket)
++  "Check for a possible HTTP request in the initial input from SOCKET.
++If one is found, close the socket and print a report to STDERR (fdes 2).
++Otherwise, put back the bytes."
++  ;; Temporarily set the port encoding to ISO-8859-1 to allow lossless
++  ;; reading and unreading of the first line, regardless of what bytes
++  ;; are present.  Note that a valid HTTP request-line contains only
++  ;; ASCII characters.
++  (with-temporary-port-encoding socket "ISO-8859-1"
++    (lambda ()
++      ;; Save the port 'line' and 'column' counters and later restore
++      ;; them, since unreading what we read is not sufficient to do so.
++      (with-saved-port-line+column socket
++        (lambda ()
++          ;; Read up to (but not including) the first CR or LF.
++          ;; Although HTTP mandates CRLF line endings, we are permissive
++          ;; here to guard against the possibility that in some
++          ;; environments CRLF might be converted to LF before it
++          ;; reaches us.
++          (match (read-delimited "\r\n" socket 'peek)
++            ((? eof-object?)
++             ;; We found EOF before any input.  Nothing to do.
++             'done)
++
++            ((? permissive-http-request-line? request-line)
++             ;; The input from the socket began with a plausible HTTP
++             ;; request-line, which is unlikely to be legitimate and may
++             ;; indicate an possible break-in attempt.
++
++             ;; First, set the current port parameters to a void-port,
++             ;; to avoid sending any more data over the socket, to cause
++             ;; the REPL reader to see EOF, and to swallow any remaining
++             ;; output gracefully.
++             (let ((void-port (%make-void-port "rw")))
++               (current-input-port   void-port)
++               (current-output-port  void-port)
++               (current-error-port   void-port)
++               (current-warning-port void-port))
++
++             ;; Read from the socket until we would block,
++             ;; and then close it.
++             (let ((drained-input (drain-input-and-close socket)))
++
++               ;; Print a report to STDERR (POSIX file descriptor 2).
++               ;; XXX Can we do better here?
++               (call-with-port (dup->port 2 "w")
++                 (cut format <> "
++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
++@@ POSSIBLE BREAK-IN ATTEMPT ON THE REPL SERVER                @@
++@@ BY AN HTTP INTER-PROTOCOL EXPLOITATION ATTACK.  See:        @@
++@@ <https://en.wikipedia.org/wiki/Inter-protocol_exploitation> @@
++@@ Possible HTTP request received: ~S
++@@ The associated socket has been closed.                      @@
++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
++                      (string-append request-line
++                                     drained-input)))))
++
++            (start-line
++             ;; The HTTP request-line was not found, so
++             ;; 'unread' the characters that we have read.
++             (unread-string start-line socket))))))))
++
++(define (guard-against-http-request socket)
++  "Arrange for the Guile REPL to check for an HTTP request in the
++initial input from SOCKET, in which case the socket will be closed.
++This guards against HTTP inter-protocol exploitation attacks, a scenario
++whereby an attacker can, via an HTML page, cause a web browser to send
++data to TCP servers listening on a loopback interface or private
++network."
++  (%set-port-property! socket 'guard-against-http-request? #t))
++
++(define* (maybe-check-for-http-request
++          #:optional (socket (current-input-port)))
++  "Apply check-for-http-request to SOCKET if previously requested by
++guard-against-http-request.  This procedure is intended to be added to
++before-read-hook."
++  (when (%port-property socket 'guard-against-http-request?)
++    (check-for-http-request socket)
++    (unless (port-closed? socket)
++      (%set-port-property! socket 'guard-against-http-request? #f))))
++
++;; Install the hook.
++(add-hook! before-read-hook
++           maybe-check-for-http-request)
++
++;;; Local Variables:
++;;; eval: (put 'with-temporary-port-encoding 'scheme-indent-function 2)
++;;; eval: (put 'with-saved-port-line+column  'scheme-indent-function 1)
++;;; End:
diff -Nru guile-2.0-2.0.11+1/debian/patches/0018-Remove-umask-calls-from-mkdir.patch guile-2.0-2.0.11+1/debian/patches/0018-Remove-umask-calls-from-mkdir.patch
--- guile-2.0-2.0.11+1/debian/patches/0018-Remove-umask-calls-from-mkdir.patch	1969-12-31 18:00:00.000000000 -0600
+++ guile-2.0-2.0.11+1/debian/patches/0018-Remove-umask-calls-from-mkdir.patch	2016-10-14 00:08:24.000000000 -0500
@@ -0,0 +1,85 @@
+From 6f697cf7a887fcb4163bef810536bb55cf3b11d3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
+Date: Tue, 11 Oct 2016 10:14:26 +0200
+Subject: Remove 'umask' calls from 'mkdir'.
+
+Fixes <http://bugs.gnu.org/24659>.
+
+* libguile/filesys.c (SCM_DEFINE): Remove calls to 'umask' when MODE is
+unbound; instead, use 0777 as the mode.  Update docstring to clarify
+this.
+* doc/ref/posix.texi (File System): Adjust accordingly.
+* NEWS: Mention it.
+
+Origin: upstream, http://git.savannah.gnu.org/cgit/guile.git/commit/?id=245608911698adb3472803856019bdd5670b6614
+Bug-Debian: http://bugs.debian.org/840556
+---
+ doc/ref/posix.texi |  7 ++++---
+ libguile/filesys.c | 25 ++++++++++---------------
+ 2 files changed, 14 insertions(+), 18 deletions(-)
+
+diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi
+index 7ca2fb0..e40eae4 100644
+--- a/doc/ref/posix.texi
++++ b/doc/ref/posix.texi
+@@ -860,9 +860,10 @@ Create a symbolic link named @var{newpath} with the value (i.e., pointing to)
+ @deffn {Scheme Procedure} mkdir path [mode]
+ @deffnx {C Function} scm_mkdir (path, mode)
+ Create a new directory named by @var{path}.  If @var{mode} is omitted
+-then the permissions of the directory file are set using the current
+-umask (@pxref{Processes}).  Otherwise they are set to the decimal
+-value specified with @var{mode}.  The return value is unspecified.
++then the permissions of the directory are set to @code{#o777}
++masked with the current umask (@pxref{Processes, @code{umask}}).
++Otherwise they are set to the value specified with @var{mode}.
++The return value is unspecified.
+ @end deffn
+ 
+ @deffn {Scheme Procedure} rmdir path
+diff --git a/libguile/filesys.c b/libguile/filesys.c
+index 09f6cf9..de13d54 100644
+--- a/libguile/filesys.c
++++ b/libguile/filesys.c
+@@ -1,5 +1,5 @@
+ /* Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2006,
+- *   2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
++ *   2009, 2010, 2011, 2012, 2013, 2014, 2016 Free Software Foundation, Inc.
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public License
+@@ -1245,26 +1245,21 @@ SCM_DEFINE (scm_getcwd, "getcwd", 0, 0, 0,
+ SCM_DEFINE (scm_mkdir, "mkdir", 1, 1, 0,
+             (SCM path, SCM mode),
+ 	    "Create a new directory named by @var{path}.  If @var{mode} is omitted\n"
+-	    "then the permissions of the directory file are set using the current\n"
+-	    "umask.  Otherwise they are set to the decimal value specified with\n"
+-	    "@var{mode}.  The return value is unspecified.")
++	    "then the permissions of the directory are set to @code{#o777}\n"
++	    "masked with the current umask (@pxref{Processes, @code{umask}}).\n"
++	    "Otherwise they are set to the value specified with @var{mode}.\n"
++	    "The return value is unspecified.")
+ #define FUNC_NAME s_scm_mkdir
+ {
+   int rv;
+-  mode_t mask;
++  mode_t c_mode;
+ 
+-  if (SCM_UNBNDP (mode))
+-    {
+-      mask = umask (0);
+-      umask (mask);
+-      STRING_SYSCALL (path, c_path, rv = mkdir (c_path, 0777 ^ mask));
+-    }
+-  else
+-    {
+-      STRING_SYSCALL (path, c_path, rv = mkdir (c_path, scm_to_uint (mode)));
+-    }
++  c_mode = SCM_UNBNDP (mode) ? 0777 : scm_to_uint (mode);
++
++  STRING_SYSCALL (path, c_path, rv = mkdir (c_path, c_mode));
+   if (rv != 0)
+     SCM_SYSERROR;
++
+   return SCM_UNSPECIFIED;
+ }
+ #undef FUNC_NAME
diff -Nru guile-2.0-2.0.11+1/debian/patches/series guile-2.0-2.0.11+1/debian/patches/series
--- guile-2.0-2.0.11+1/debian/patches/series	2014-10-06 10:07:49.000000000 -0500
+++ guile-2.0-2.0.11+1/debian/patches/series	2016-10-14 00:08:24.000000000 -0500
@@ -14,3 +14,5 @@
 0014-Document-prefix-option-in-use-module-clauses.patch
 0015-Fix-SCM_SMOB_OBJECT-_-_0_-_1_-_2_-_3_-LOC.patch
 0016-peval-Handle-optional-argument-inits-that-refer-to-p.patch
+0017-REPL-Server-Guard-against-HTTP-inter-protocol-exploi.patch
+0018-Remove-umask-calls-from-mkdir.patch
Thanks
-- 
Rob Browning
rlb @defaultvalue.org and @debian.org
GPG as of 2011-07-10 E6A9 DA3C C9FD 1FF8 C676 D2C4 C0F0 39E9 ED1B 597A
GPG as of 2002-11-03 14DD 432F AE39 534D B592 F9A0 25C8 D377 8C7E 73A4

Reply to: