Hi,

On Sun, 01 Jan 2017 12:13:30 +0100 Salvatore Bonaccorso
<car...@debian.org> wrote:
...

> 
> Hi,
> 
> the following vulnerability was published for rabbitmq-server.
> 
> CVE-2016-9877[0]:
> | An issue was discovered in Pivotal RabbitMQ 3.x before 3.5.8 and 3.6.x
> | before 3.6.6 and RabbitMQ for PCF 1.5.x before 1.5.20, 1.6.x before
> | 1.6.12, and 1.7.x before 1.7.7. MQTT (MQ Telemetry Transport)
> | connection authentication with a username/password pair succeeds if an
> | existing username is provided but the password is omitted from the
> | connection request. Connections that use TLS with a client-provided
> | certificate are not affected.
> 
> If you fix the vulnerability please also make sure to include the
> CVE (Common Vulnerabilities & Exposures) id in your changelog entry.
> 
> For further information see:
> 
> [0] https://security-tracker.debian.org/tracker/CVE-2016-9877
>     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9877
> [1] https://github.com/rabbitmq/rabbitmq-mqtt/pull/98
> [2] https://github.com/rabbitmq/rabbitmq-mqtt/issues/96
> 
> Please adjust the affected versions in the BTS as needed. I was only
> able to check the vulnerability sourcewise for 3.6.5 in unstable,
> older version have not been checked so far.

I'm attaching a proposed patch for jessie which builds fine but has not
been tested further.

Wheezy is not affected since the vulnerable mqtt plugin is not present.

Cheers,
Balint
>From 157948d86d391a325ac9702f78976c175ced58be Mon Sep 17 00:00:00 2001
From: Daniil Fedotov <dfedo...@pivotal.io>
Date: Mon, 5 Sep 2016 12:33:49 +0100
Subject: [PATCH] Auth issue fix 039a3c22e57bf77b325d19494a9b20cd745f1ea7
 backport
 .
 Backported to Debian Jessie's 3.3.5-1.1 by Balint Reczey as part of the
 LTS work.

---
 src/rabbit_mqtt_processor.erl                 | 63 ++++++++++++++-------------
 test/Makefile                                 |  2 +-
 test/src/com/rabbitmq/mqtt/test/MqttTest.java | 12 +++++
 3 files changed, 45 insertions(+), 32 deletions(-)

--- a/plugins-src/rabbitmq-mqtt/src/rabbit_mqtt_processor.erl
+++ b/plugins-src/rabbitmq-mqtt/src/rabbit_mqtt_processor.erl
@@ -75,7 +75,13 @@
             _ ->
                 case creds(Username, Password) of
                     nocreds ->
-                        rabbit_log:error("MQTT login failed - no credentials~n"),
+                        rabbit_log:error("MQTT login failed: no credentials provided~n"),
+                        {?CONNACK_CREDENTIALS, PState};
+                    {invalid_creds, {undefined, Pass}} when is_list(Pass) ->
+                        rabbit_log:error("MQTT login failed: no user username is provided"),
+                        {?CONNACK_CREDENTIALS, PState};
+                    {invalid_creds, {User, undefined}} when is_list(User) ->
+                        rabbit_log:error("MQTT login failed for ~p: no password provided", [User]),
                         {?CONNACK_CREDENTIALS, PState};
                     {UserBin, PassBin} ->
                         case process_login(UserBin, PassBin, ProtoVersion, PState) of
@@ -370,20 +376,25 @@
     DefaultUser = rabbit_mqtt_util:env(default_user),
     DefaultPass = rabbit_mqtt_util:env(default_pass),
     Anon        = rabbit_mqtt_util:env(allow_anonymous),
-    U = case {User =/= undefined, is_binary(DefaultUser), Anon =:= true} of
-             {true,  _,    _   } -> list_to_binary(User);
-             {false, true, true} -> DefaultUser;
-             _                   -> nocreds
-        end,
-    case U of
-        nocreds ->
-            nocreds;
-        _ ->
-            case {Pass =/= undefined, is_binary(DefaultPass), Anon =:= true} of
-                 {true,  _,    _   } -> {U, list_to_binary(Pass)};
-                 {false, true, true} -> {U, DefaultPass};
-                 _                   -> {U, none}
-            end
+    HaveDefaultCreds = Anon =:= true andalso
+                       is_binary(DefaultUser) andalso
+                       is_binary(DefaultPass),
+
+    CredentialsProvided = User =/= undefined orelse
+                          Pass =/= undefined,
+
+    CorrectCredentials = is_list(User) andalso
+                         is_list(Pass),
+
+    case {CredentialsProvided, CorrectCredentials, HaveDefaultCreds} of
+        %% Username and password take priority
+        {true, true, _}          -> {list_to_binary(User),
+                                        list_to_binary(Pass)};
+        %% Either username or password is provided
+        {true, false, _}         -> {invalid_creds, {User, Pass}};
+        %% Anonymous connection uses default credentials
+        {false, false, true} -> {DefaultUser, DefaultPass};
+        _                           -> nocreds
     end.
 
 supported_subs_qos(?QOS_0) -> ?QOS_0;
--- a/plugins-src/rabbitmq-mqtt/test/Makefile
+++ b/plugins-src/rabbitmq-mqtt/test/Makefile
@@ -1,4 +1,4 @@
-UPSTREAM_GIT=https://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.java.git
+UPSTREAM_GIT=https://github.com/eclipse/paho.mqtt.java.git
 REVISION=00b5b2f99ae8410b7d96d106e080a092c5f92546
 
 JC=javac
--- a/plugins-src/rabbitmq-mqtt/test/src/com/rabbitmq/mqtt/test/MqttTest.java
+++ b/plugins-src/rabbitmq-mqtt/test/src/com/rabbitmq/mqtt/test/MqttTest.java
@@ -163,6 +163,18 @@
         }
     }
 
+    public void testEmptyPassword() throws MqttException {
+        MqttClient c = new MqttClient(brokerUrl, clientId, null);
+        MqttConnectOptions opts = new MyConnOpts();
+        opts.setUserName("guest");
+        opts.setPassword(null);
+        try {
+            c.connect(opts);
+            fail("Authentication failure expected");
+        } catch (MqttException ex) {
+            Assert.assertEquals(MqttException.REASON_CODE_FAILED_AUTHENTICATION, ex.getReasonCode());
+        }
+    }
 
     public void testSubscribeQos0() throws MqttException, InterruptedException {
         client.connect(conOpt);

Reply via email to