test_security_curve.cpp 7.18 KB
Newer Older
Ian Barber's avatar
Ian Barber committed
1
/*
2
    Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file
Ian Barber's avatar
Ian Barber committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

    This file is part of 0MQ.

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

    0MQ 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.

    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/>.
*/

#include "testutil.hpp"
21

22 23 24 25 26
//  We'll generate random test keys at startup
static char client_public [41];
static char client_secret [41];
static char server_public [41];
static char server_secret [41];
Ian Barber's avatar
Ian Barber committed
27

28
//  --------------------------------------------------------------------------
Pieter Hintjens's avatar
Pieter Hintjens committed
29 30
//  This methods receives and validates ZAP requestes (allowing or denying
//  each client connection).
31

32
static void zap_handler (void *handler)
Ian Barber's avatar
Ian Barber committed
33
{
34 35
    //  Process ZAP requests forever
    while (true) {
36
        char *version = s_recv (handler);
37 38 39
        if (!version)
            break;          //  Terminating

40 41 42 43 44
        char *sequence = s_recv (handler);
        char *domain = s_recv (handler);
        char *address = s_recv (handler);
        char *identity = s_recv (handler);
        char *mechanism = s_recv (handler);
45
        uint8_t client_key [32];
46
        int size = zmq_recv (handler, client_key, 32, 0);
47 48
        assert (size == 32);

49
        char client_key_text [41];
50
        zmq_z85_encode (client_key_text, client_key, 32);
51

52 53 54 55
        assert (streq (version, "1.0"));
        assert (streq (mechanism, "CURVE"));
        assert (streq (identity, "IDENT"));

56 57
        s_sendmore (handler, version);
        s_sendmore (handler, sequence);
58

59
        if (streq (client_key_text, client_public)) {
60 61 62 63
            s_sendmore (handler, "200");
            s_sendmore (handler, "OK");
            s_sendmore (handler, "anonymous");
            s_send     (handler, "");
64 65
        }
        else {
66 67 68 69
            s_sendmore (handler, "400");
            s_sendmore (handler, "Invalid client public key");
            s_sendmore (handler, "");
            s_send     (handler, "");
70
        }
71 72 73 74 75 76
        free (version);
        free (sequence);
        free (domain);
        free (address);
        free (identity);
        free (mechanism);
MinRK's avatar
MinRK committed
77
    }
78
    zmq_close (handler);
Ian Barber's avatar
Ian Barber committed
79 80
}

MinRK's avatar
MinRK committed
81

Ian Barber's avatar
Ian Barber committed
82 83 84
int main (void)
{
#ifndef HAVE_LIBSODIUM
Pieter Hintjens's avatar
Pieter Hintjens committed
85
    printf ("libsodium not installed, skipping CURVE test\n");
Ian Barber's avatar
Ian Barber committed
86 87
    return 0;
#endif
88 89 90 91 92 93 94

    //  Generate new keypairs for this test
    int rc = zmq_curve_keypair (client_public, client_secret);
    assert (rc == 0);
    rc = zmq_curve_keypair (server_public, server_secret);
    assert (rc == 0);

95
    setup_test_environment ();
Ian Barber's avatar
Ian Barber committed
96 97 98
    void *ctx = zmq_ctx_new ();
    assert (ctx);

99
    //  Spawn ZAP handler
100 101 102 103
    //  We create and bind ZAP socket in main thread to avoid case
    //  where child thread does not start up fast enough.
    void *handler = zmq_socket (ctx, ZMQ_REP);
    assert (handler);
104
    rc = zmq_bind (handler, "inproc://zeromq.zap.01");
105 106
    assert (rc == 0);
    void *zap_thread = zmq_threadstart (&zap_handler, handler);
Ian Barber's avatar
Ian Barber committed
107

108 109 110
    //  Server socket will accept connections
    void *server = zmq_socket (ctx, ZMQ_DEALER);
    assert (server);
111
    int as_server = 1;
112
    rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int));
Pieter Hintjens's avatar
Pieter Hintjens committed
113
    assert (rc == 0);
114
    rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 40);
Pieter Hintjens's avatar
Pieter Hintjens committed
115
    assert (rc == 0);
116 117
    rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6);
    assert (rc == 0);
118
    rc = zmq_bind (server, "tcp://127.0.0.1:9998");
119
    assert (rc == 0);
Ian Barber's avatar
Ian Barber committed
120

121 122 123
    //  Check CURVE security with valid credentials
    void *client = zmq_socket (ctx, ZMQ_DEALER);
    assert (client);
124
    rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40);
Pieter Hintjens's avatar
Pieter Hintjens committed
125
    assert (rc == 0);
126
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40);
Pieter Hintjens's avatar
Pieter Hintjens committed
127
    assert (rc == 0);
128
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40);
Pieter Hintjens's avatar
Pieter Hintjens committed
129
    assert (rc == 0);
Ian Barber's avatar
Ian Barber committed
130 131 132 133 134
    rc = zmq_connect (client, "tcp://localhost:9998");
    assert (rc == 0);
    bounce (server, client);
    rc = zmq_close (client);
    assert (rc == 0);
135

136 137 138
    //  Check CURVE security with a garbage server key
    //  This will be caught by the curve_server class, not passed to ZAP
    char garbage_key [] = "0000111122223333444455556666777788889999";
MinRK's avatar
MinRK committed
139 140
    client = zmq_socket (ctx, ZMQ_DEALER);
    assert (client);
141
    rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 40);
MinRK's avatar
MinRK committed
142
    assert (rc == 0);
143
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40);
MinRK's avatar
MinRK committed
144
    assert (rc == 0);
145
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40);
MinRK's avatar
MinRK committed
146
    assert (rc == 0);
147 148 149 150
    rc = zmq_connect (client, "tcp://localhost:9998");
    assert (rc == 0);
    expect_bounce_fail (server, client);
    close_zero_linger (client);
151

152 153 154 155
    //  Check CURVE security with a garbage client public key
    //  This will be caught by the curve_server class, not passed to ZAP
    client = zmq_socket (ctx, ZMQ_DEALER);
    assert (client);
156
    rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40);
MinRK's avatar
MinRK committed
157
    assert (rc == 0);
158
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 40);
MinRK's avatar
MinRK committed
159
    assert (rc == 0);
160
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40);
MinRK's avatar
MinRK committed
161
    assert (rc == 0);
162
    rc = zmq_connect (client, "tcp://localhost:9998");
MinRK's avatar
MinRK committed
163
    assert (rc == 0);
164 165
    expect_bounce_fail (server, client);
    close_zero_linger (client);
166

167 168 169 170
    //  Check CURVE security with a garbage client secret key
    //  This will be caught by the curve_server class, not passed to ZAP
    client = zmq_socket (ctx, ZMQ_DEALER);
    assert (client);
171
    rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40);
MinRK's avatar
MinRK committed
172
    assert (rc == 0);
173
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40);
MinRK's avatar
MinRK committed
174
    assert (rc == 0);
175
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 40);
MinRK's avatar
MinRK committed
176
    assert (rc == 0);
177
    rc = zmq_connect (client, "tcp://localhost:9998");
MinRK's avatar
MinRK committed
178
    assert (rc == 0);
179 180
    expect_bounce_fail (server, client);
    close_zero_linger (client);
181

182 183
    //  Check CURVE security with bogus client credentials
    //  This must be caught by the ZAP handler
184 185 186
    char bogus_public [41];
    char bogus_secret [41];
    zmq_curve_keypair (bogus_public, bogus_secret);
187

188 189
    client = zmq_socket (ctx, ZMQ_DEALER);
    assert (client);
190
    rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40);
MinRK's avatar
MinRK committed
191
    assert (rc == 0);
192
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 40);
MinRK's avatar
MinRK committed
193
    assert (rc == 0);
194
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 40);
MinRK's avatar
MinRK committed
195
    assert (rc == 0);
196 197
    rc = zmq_connect (client, "tcp://localhost:9998");
    assert (rc == 0);
198
    expect_bounce_fail (server, client);
199
    close_zero_linger (client);
200

Ian Barber's avatar
Ian Barber committed
201
    //  Shutdown
202 203
    rc = zmq_close (server);
    assert (rc == 0);
Ian Barber's avatar
Ian Barber committed
204 205
    rc = zmq_ctx_term (ctx);
    assert (rc == 0);
206

207 208
    //  Wait until ZAP handler terminates
    zmq_threadclose (zap_thread);
Ian Barber's avatar
Ian Barber committed
209 210 211

    return 0;
}