plain_server.cpp 12.8 KB
Newer Older
1
/*
2
    Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3

4
    This file is part of libzmq, the ZeroMQ core engine in C++.
5

6 7 8
    libzmq is free software; you can redistribute it and/or modify it under
    the terms of the GNU Lesser General Public License (LGPL) as published
    by the Free Software Foundation; either version 3 of the License, or
9 10
    (at your option) any later version.

11 12 13 14 15 16 17 18 19 20 21 22 23 24
    As a special exception, the Contributors give you permission to link
    this library with independent modules to produce an executable,
    regardless of the license terms of these independent modules, and to
    copy and distribute the resulting executable under terms of your choice,
    provided that you also meet, for each linked independent module, the
    terms and conditions of the license of that module. An independent
    module is a module which is not derived from or based on this library.
    If you modify this library, you must extend this exception to your
    version of the library.

    libzmq is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    License for more details.
25 26 27 28 29

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

30
#include "precompiled.hpp"
31 32 33 34 35 36 37 38
#include "platform.hpp"
#ifdef ZMQ_HAVE_WINDOWS
#include "windows.hpp"
#endif

#include <string>

#include "msg.hpp"
39
#include "session_base.hpp"
40
#include "err.hpp"
41
#include "plain_server.hpp"
42 43
#include "wire.hpp"

44 45 46
zmq::plain_server_t::plain_server_t (session_base_t *session_,
                                     const std::string &peer_address_,
                                     const options_t &options_) :
47
    mechanism_t (options_),
48
    session (session_),
49
    peer_address (peer_address_),
50
    state (waiting_for_hello)
51 52 53
{
}

54
zmq::plain_server_t::~plain_server_t ()
55 56 57
{
}

58
int zmq::plain_server_t::next_handshake_command (msg_t *msg_)
59 60 61 62
{
    int rc = 0;

    switch (state) {
63
        case sending_welcome:
64
            rc = produce_welcome (msg_);
65 66 67 68
            if (rc == 0)
                state = waiting_for_initiate;
            break;
        case sending_ready:
69
            rc = produce_ready (msg_);
70 71 72
            if (rc == 0)
                state = ready;
            break;
73 74 75 76 77
        case sending_error:
            rc = produce_error (msg_);
            if (rc == 0)
                state = error_command_sent;
            break;
78 79 80
        default:
            errno = EAGAIN;
            rc = -1;
81 82 83 84
    }
    return rc;
}

85
int zmq::plain_server_t::process_handshake_command (msg_t *msg_)
86 87 88 89
{
    int rc = 0;

    switch (state) {
90
        case waiting_for_hello:
91
            rc = process_hello (msg_);
92 93
            break;
        case waiting_for_initiate:
94
            rc = process_initiate (msg_);
95 96
            break;
        default:
97 98
            //  Temporary support for security debugging
            puts ("PLAIN I: invalid handshake command");
99
            errno = EPROTO;
100
            rc = -1;
101
            break;
102 103 104 105 106 107 108
    }
    if (rc == 0) {
        rc = msg_->close ();
        errno_assert (rc == 0);
        rc = msg_->init ();
        errno_assert (rc == 0);
    }
109
    return rc;
110 111
}

112
zmq::mechanism_t::status_t zmq::plain_server_t::status () const
113
{
114 115 116 117 118 119 120
    if (state == ready)
        return mechanism_t::ready;
    else
    if (state == error_command_sent)
        return mechanism_t::error;
    else
        return mechanism_t::handshaking;
121 122
}

123
int zmq::plain_server_t::zap_msg_available ()
124 125 126 127 128 129 130
{
    if (state != waiting_for_zap_reply) {
        errno = EFSM;
        return -1;
    }
    const int rc = receive_and_process_zap_reply ();
    if (rc == 0)
131 132 133
        state = status_code == "200"
            ? sending_welcome
            : sending_error;
134 135
    return rc;
}
136

137
int zmq::plain_server_t::process_hello (msg_t *msg_)
138 139 140 141
{
    const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
    size_t bytes_left = msg_->size ();

142
    if (bytes_left < 6 || memcmp (ptr, "\x05HELLO", 6)) {
143 144
        //  Temporary support for security debugging
        puts ("PLAIN I: invalid PLAIN client, did not send HELLO");
145 146 147
        errno = EPROTO;
        return -1;
    }
148 149
    ptr += 6;
    bytes_left -= 6;
150 151

    if (bytes_left < 1) {
152 153
        //  Temporary support for security debugging
        puts ("PLAIN I: invalid PLAIN client, did not send username");
154 155 156
        errno = EPROTO;
        return -1;
    }
Martin Hurton's avatar
Martin Hurton committed
157
    const size_t username_length = static_cast <size_t> (*ptr++);
158 159 160
    bytes_left -= 1;

    if (bytes_left < username_length) {
161 162
        //  Temporary support for security debugging
        puts ("PLAIN I: invalid PLAIN client, sent malformed username");
163 164 165 166 167 168 169
        errno = EPROTO;
        return -1;
    }
    const std::string username = std::string ((char *) ptr, username_length);
    ptr += username_length;
    bytes_left -= username_length;
    if (bytes_left < 1) {
170 171
        //  Temporary support for security debugging
        puts ("PLAIN I: invalid PLAIN client, did not send password");
172 173 174
        errno = EPROTO;
        return -1;
    }
175

Martin Hurton's avatar
Martin Hurton committed
176
    const size_t password_length = static_cast <size_t> (*ptr++);
177 178
    bytes_left -= 1;
    if (bytes_left < password_length) {
179 180
        //  Temporary support for security debugging
        puts ("PLAIN I: invalid PLAIN client, sent malformed password");
181 182 183
        errno = EPROTO;
        return -1;
    }
184

185 186 187 188
    const std::string password = std::string ((char *) ptr, password_length);
    ptr += password_length;
    bytes_left -= password_length;
    if (bytes_left > 0) {
189 190
        //  Temporary support for security debugging
        puts ("PLAIN I: invalid PLAIN client, sent extraneous data");
191 192 193
        errno = EPROTO;
        return -1;
    }
194

195
    //  Use ZAP protocol (RFC 27) to authenticate the user.
196
    int rc = session->zap_connect ();
197 198 199
    if (rc == 0) {
        send_zap_request (username, password);
        rc = receive_and_process_zap_reply ();
200 201 202 203 204 205 206 207 208
        if (rc == 0)
            state = status_code == "200"
                ? sending_welcome
                : sending_error;
        else
        if (errno == EAGAIN)
            state = waiting_for_zap_reply;
        else
            return -1;
209
    }
210 211
    else
        state = sending_welcome;
212

213 214 215
    return 0;
}

216
int zmq::plain_server_t::produce_welcome (msg_t *msg_) const
217 218 219
{
    const int rc = msg_->init_size (8);
    errno_assert (rc == 0);
220
    memcpy (msg_->data (), "\x07WELCOME", 8);
221 222 223
    return 0;
}

224
int zmq::plain_server_t::process_initiate (msg_t *msg_)
225 226
{
    const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
227
    const size_t bytes_left = msg_->size ();
228

229
    if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) {
230 231
        //  Temporary support for security debugging
        puts ("PLAIN I: invalid PLAIN client, did not send INITIATE");
232 233 234
        errno = EPROTO;
        return -1;
    }
235 236 237 238
    const int rc = parse_metadata (ptr + 9, bytes_left - 9);
    if (rc == 0)
        state = sending_ready;
    return rc;
239 240
}

241
int zmq::plain_server_t::produce_ready (msg_t *msg_) const
242 243 244 245 246 247
{
    unsigned char * const command_buffer = (unsigned char *) malloc (512);
    alloc_assert (command_buffer);

    unsigned char *ptr = command_buffer;

248
    //  Add command name
249
    memcpy (ptr, "\x05READY", 6);
250
    ptr += 6;
251 252 253 254 255 256 257 258

    //  Add socket type property
    const char *socket_type = socket_type_string (options.type);
    ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type));

    //  Add identity property
    if (options.type == ZMQ_REQ
    ||  options.type == ZMQ_DEALER
Pieter Hintjens's avatar
Pieter Hintjens committed
259
    ||  options.type == ZMQ_ROUTER)
260 261
        ptr += add_property (
            ptr, "Identity", options.identity, options.identity_size);
262 263 264 265 266 267 268 269 270 271

    const size_t command_size = ptr - command_buffer;
    const int rc = msg_->init_size (command_size);
    errno_assert (rc == 0);
    memcpy (msg_->data (), command_buffer, command_size);
    free (command_buffer);

    return 0;
}

272 273 274
int zmq::plain_server_t::produce_error (msg_t *msg_) const
{
    zmq_assert (status_code.length () == 3);
275
    const int rc = msg_->init_size (6 + 1 + status_code.length ());
276 277 278
    zmq_assert (rc == 0);
    char *msg_data = static_cast <char *> (msg_->data ());
    memcpy (msg_data, "\5ERROR", 6);
279
    msg_data [6] = (char) status_code.length ();
280
    memcpy (msg_data + 7, status_code.c_str (), status_code.length ());
281 282 283
    return 0;
}

284 285
void zmq::plain_server_t::send_zap_request (const std::string &username,
                                            const std::string &password)
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
{
    int rc;
    msg_t msg;

    //  Address delimiter frame
    rc = msg.init ();
    errno_assert (rc == 0);
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

    //  Version frame
    rc = msg.init_size (3);
    errno_assert (rc == 0);
    memcpy (msg.data (), "1.0", 3);
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

305
    //  Request id frame
306 307 308 309 310 311 312 313
    rc = msg.init_size (1);
    errno_assert (rc == 0);
    memcpy (msg.data (), "1", 1);
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

    //  Domain frame
314
    rc = msg.init_size (options.zap_domain.length ());
315
    errno_assert (rc == 0);
316
    memcpy (msg.data (), options.zap_domain.c_str (), options.zap_domain.length ());
317 318 319 320
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

321 322 323 324 325 326 327 328
    //  Address frame
    rc = msg.init_size (peer_address.length ());
    errno_assert (rc == 0);
    memcpy (msg.data (), peer_address.c_str (), peer_address.length ());
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

329
    //  Identity frame
330
    rc = msg.init_size (options.identity_size);
331
    errno_assert (rc == 0);
332 333 334 335 336
    memcpy (msg.data (), options.identity, options.identity_size);
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
    //  Mechanism frame
    rc = msg.init_size (5);
    errno_assert (rc == 0);
    memcpy (msg.data (), "PLAIN", 5);
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

    //  Username frame
    rc = msg.init_size (username.length ());
    errno_assert (rc == 0);
    memcpy (msg.data (), username.c_str (), username.length ());
    msg.set_flags (msg_t::more);
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);

    //  Password frame
    rc = msg.init_size (password.length ());
    errno_assert (rc == 0);
    memcpy (msg.data (), password.c_str (), password.length ());
    rc = session->write_zap_msg (&msg);
    errno_assert (rc == 0);
}

361
int zmq::plain_server_t::receive_and_process_zap_reply ()
362 363
{
    int rc = 0;
364
    msg_t msg [7];  //  ZAP reply consists of 7 frames
365

366 367
    //  Initialize all reply frames
    for (int i = 0; i < 7; i++) {
368 369 370 371
        rc = msg [i].init ();
        errno_assert (rc == 0);
    }

372
    for (int i = 0; i < 7; i++) {
373 374 375
        rc = session->read_zap_msg (&msg [i]);
        if (rc == -1)
            break;
376
        if ((msg [i].flags () & msg_t::more) == (i < 6? 0: msg_t::more)) {
377 378
            //  Temporary support for security debugging
            puts ("PLAIN I: ZAP handler sent incomplete reply message");
379 380 381 382 383 384 385 386 387 388 389
            errno = EPROTO;
            rc = -1;
            break;
        }
    }

    if (rc != 0)
        goto error;

    //  Address delimiter frame
    if (msg [0].size () > 0) {
390 391
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler sent malformed reply message");
392
        errno = EPROTO;
393
        rc = -1;
394 395 396 397 398
        goto error;
    }

    //  Version frame
    if (msg [1].size () != 3 || memcmp (msg [1].data (), "1.0", 3)) {
399 400
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler sent bad version number");
401
        errno = EPROTO;
402
        rc = -1;
403 404 405
        goto error;
    }

406
    //  Request id frame
407
    if (msg [2].size () != 1 || memcmp (msg [2].data (), "1", 1)) {
408 409
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler sent bad request ID");
410
        rc = -1;
411 412 413 414 415
        errno = EPROTO;
        goto error;
    }

    //  Status code frame
416
    if (msg [3].size () != 3) {
417 418
        //  Temporary support for security debugging
        puts ("PLAIN I: ZAP handler rejected client authentication");
419
        errno = EACCES;
420
        rc = -1;
421 422 423
        goto error;
    }

424 425 426
    //  Save status code
    status_code.assign (static_cast <char *> (msg [3].data ()), 3);

427 428 429
    //  Save user id
    set_user_id (msg [5].data (), msg [5].size ());

430 431
    //  Process metadata frame
    rc = parse_metadata (static_cast <const unsigned char*> (msg [6].data ()),
432
                         msg [6].size (), true);
433

434
error:
435
    for (int i = 0; i < 7; i++) {
436 437 438 439 440 441
        const int rc2 = msg [i].close ();
        errno_assert (rc2 == 0);
    }

    return rc;
}