[zeromq-dev] ZMTP3.0 authentication protocol bug with ZeroMQ4.0?
Pieter Hintjens
ph at imatix.com
Thu Oct 2 23:34:25 CEST 2014
Hi Hugo,
The downgrade attack has been reported and fixed in the 4.x stable
release (so for 4.0.5).
The error handling has been quite heavily modified in libzmq master
(so for 4.1.0).
Would you be able to retest against the two github masters?
-Pieter
On Thu, Oct 2, 2014 at 10:24 PM, Hugo Landau <hlandau at devever.net> wrote:
> I've identified what appear to be two issues; one with how ZeroMQ (v4.0.4)
> implements ZMTP/3.0, and the other with the ZMTP/3.0 specification itself.
>
> When a client attempts to connect to a ZeroMQ server, and the client is
> configured to use NULL authentication but the server is configured to use PLAIN
> authentication, the server will send a READY command and wait for the client to
> send HELLO, even though according to ZMTP/3.0 it should close the connection.
> The specification doesn't specify exactly when the connection should be
> terminated in the event of authentication mismatch but I think it's implied
> that it should be done immediately, and there's no need to postpone closure.
>
> What follows is a protocol dump indicating this issue. Client and server source
> code are at the end of this message.
>
> SERVER
> 00000000 ff 00 00 00 00 00 00 00 01 7f ........ ..
> CLIENT
> 00000000 ff 00 00 00 00 00 00 00 01 7f 03 ........ ...
> SERVER
> 0000000A 03 00 50 4c 41 49 4e 00 00 00 00 00 00 00 00 00 ..PLAIN. ........
> 0000001A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
> 0000002A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
> 0000003A 00 00 00 00 00 00 ......
> CLIENT
> 0000000B 00 4e 55 4c 4c 00 00 00 00 00 00 00 00 00 00 00 .NULL... ........
> 0000001B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
> 0000002B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
> 0000003B 00 00 00 00 00 .....
> SERVER
> 00000040 04 19 05 52 45 41 44 59 0b 53 6f 63 6b 65 74 2d ...READY .Socket-
> 00000050 54 79 70 65 00 00 00 03 52 45 50 Type.... REP
> CLIENT
> 00000040 04 08 05 48 45 4c 4c 4f 00 00 ...HELLO ..
> (connection closed)
>
> The ZMTP/3.0 specification also seems flawed in how it outlines how
> authentication errors are to be dealt with. It clearly states that
> mechanism-specific authentication errors (i.e., those occurring after mechanism
> negotiation) should result in an ERROR command, which ensures that reconnects
> are not attempted. But mechanism mismatches just result in the connection being
> closed, which is indistinguishable from some lower-level issue (such as a loss
> of network connectivity).
>
> The end result of this is that the client keeps trying to connect perpetually,
> hammering the server even though connection is impossible due to the mechanism
> mismatch. This is what actually happens with ZeroMQ 4.0.4; the client just
> keeps hammering the server at approximately half-second intervals.
>
> It would be better if the ZMTP specification made provision for mechanism
> mismatches to inhibit reconnection just as mechanism-specific errors do.
>
> The ZMTP/3.0 specification also specifies that an increasing reconnection
> interval should be used, but ZMQ_RECONNECT_IVL_MAX is disabled by default.
>
> /* CLIENT */
> #include <zmq.h>
> #include <stdio.h>
> #include <assert.h>
>
> int main(int argc, char **argv) {
> void *ctx = zmq_ctx_new();
> void *req = zmq_socket(ctx, ZMQ_REQ);
> int rc = zmq_connect(req, "tcp://127.0.0.1:1234");
> assert(rc == 0);
>
> char buf[64] = {};
> zmq_send(req, "Request#1", 9, 0);
> zmq_recv(req, buf, 64, 0);
> printf("RX: %s\n", buf);
>
> return 0;
> }
>
> /* SERVER */
> #include <zmq.h>
> #include <stdio.h>
> #include <assert.h>
> #include <czmq.h>
> #include <stdbool.h>
>
> int main(int argc, char **argv) {
> zctx_t *ctx = zctx_new();
> assert(ctx);
>
> zauth_t *auth = zauth_new(ctx);
> assert(auth);
> zauth_set_verbose(auth, true);
>
> void *resp = zsocket_new(ctx, ZMQ_REP);
> zsocket_set_zap_domain(resp, "a");
> zsocket_set_plain_server(resp, true);
> zauth_configure_plain(auth, "*", "passwords.txt");
>
> int rc = zmq_bind(resp, "tcp://*:1234");
> assert(rc == 0);
>
> printf("Ready\n");
> for (;;) {
> char buf[64] = {};
> rc = zmq_recv(resp, buf, 64, 0);
> if (rc < 0)
> break;
> printf("RX: %s\n", buf);
> zmq_send(resp, "(response)", 10, 0);
> }
>
> return 0;
> }
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
More information about the zeromq-dev
mailing list