libzmq/tests/test_security.cpp
Jeremy Rossi 19ca8a0fc0 Add the Socket Identity info to the ZAP Messages
This change adds the socket identity infomartion from the socket to the
zap frames.  In doing this the ZAP is able preform different operations
based on different sockets.  This is not compaitable with the current ZAP
RFC, but that can be updated.  As the ZAP rfc is currently draft for I
did not change the version number.

Tests also modified and passing.
2013-08-20 13:48:05 -04:00

230 lines
6.5 KiB
C++

/*
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
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 "../include/zmq_utils.h"
#include <string.h>
#include <stdlib.h>
#include "testutil.hpp"
static void zap_handler (void *zap)
{
char *version = s_recv (zap);
char *sequence = s_recv (zap);
char *domain = s_recv (zap);
char *address = s_recv (zap);
char *identity = s_recv(zap);
char *mechanism = s_recv (zap);
char *username = s_recv (zap);
char *password = s_recv (zap);
printf("identity: %s\n", identity);
assert (streq (version, "1.0"));
assert (streq (mechanism, "PLAIN"));
assert (streq (identity, "IDENT"));
s_sendmore (zap, version);
s_sendmore (zap, sequence);
if (streq (username, "admin")
&& streq (password, "password")) {
s_sendmore (zap, "200");
s_sendmore (zap, "OK");
s_sendmore (zap, "anonymous");
s_send (zap, "");
}
else {
s_sendmore (zap, "400");
s_sendmore (zap, "Invalid username or password");
s_sendmore (zap, "");
s_send (zap, "");
}
free (version);
free (sequence);
free (domain);
free (address);
free (identity);
free (mechanism);
free (username);
free (password);
int rc = zmq_close (zap);
assert (rc == 0);
}
int main (void)
{
setup_test_environment();
void *ctx = zmq_ctx_new ();
assert (ctx);
// Server socket will accept connections
void *server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
// Client socket that will try to connect to server
void *client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
// Check NULL security configuration
int rc;
size_t optsize;
int mechanism;
int as_server;
optsize = sizeof (int);
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_NULL);
rc = zmq_getsockopt (server, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_NULL);
rc = zmq_getsockopt (client, ZMQ_PLAIN_SERVER, &as_server, &optsize);
assert (rc == 0);
assert (as_server == 0);
rc = zmq_getsockopt (server, ZMQ_PLAIN_SERVER, &as_server, &optsize);
assert (rc == 0);
assert (as_server == 0);
rc = zmq_bind (server, "tcp://*:9999");
assert (rc == 0);
rc = zmq_connect (client, "tcp://localhost:9999");
assert (rc == 0);
bounce (server, client);
rc = zmq_close (client);
assert (rc == 0);
rc = zmq_close (server);
assert (rc == 0);
// Check PLAIN security
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
rc = zmq_setsockopt(server, ZMQ_IDENTITY, "IDENT",6);
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
char username [256];
optsize = 256;
rc = zmq_getsockopt (client, ZMQ_PLAIN_USERNAME, username, &optsize);
assert (rc == 0);
assert (optsize == 1); // Null string is one byte long
char password [256];
optsize = 256;
rc = zmq_getsockopt (client, ZMQ_PLAIN_PASSWORD, password, &optsize);
assert (rc == 0);
assert (optsize == 1); // Null string is one byte long
strcpy (username, "admin");
strcpy (password, "password");
rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username));
assert (rc == 0);
rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password));
assert (rc == 0);
optsize = 256;
rc = zmq_getsockopt (client, ZMQ_PLAIN_USERNAME, username, &optsize);
assert (rc == 0);
assert (optsize == 5 + 1);
optsize = 256;
rc = zmq_getsockopt (client, ZMQ_PLAIN_PASSWORD, password, &optsize);
assert (rc == 0);
assert (optsize == 8 + 1);
as_server = 1;
rc = zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int));
assert (rc == 0);
optsize = sizeof (int);
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_PLAIN);
rc = zmq_getsockopt (server, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_PLAIN);
rc = zmq_getsockopt (client, ZMQ_PLAIN_SERVER, &as_server, &optsize);
assert (rc == 0);
assert (as_server == 0);
rc = zmq_getsockopt (server, ZMQ_PLAIN_SERVER, &as_server, &optsize);
assert (rc == 0);
assert (as_server == 1);
// Create and bind ZAP socket
void *zap = zmq_socket (ctx, ZMQ_REP);
assert (zap);
rc = zmq_bind (zap, "inproc://zeromq.zap.01");
assert (rc == 0);
// Spawn ZAP handler
void* zap_thread = zmq_threadstart(&zap_handler, zap);
rc = zmq_bind (server, "tcp://*:9998");
assert (rc == 0);
rc = zmq_connect (client, "tcp://localhost:9998");
assert (rc == 0);
bounce (server, client);
rc = zmq_close (client);
assert (rc == 0);
rc = zmq_close (server);
assert (rc == 0);
// Wait until ZAP handler terminates.
zmq_threadclose(zap_thread);
// Check PLAIN security -- two servers trying to talk to each other
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
rc = zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int));
assert (rc == 0);
rc = zmq_setsockopt (client, ZMQ_PLAIN_SERVER, &as_server, sizeof (int));
assert (rc == 0);
rc = zmq_bind (server, "tcp://*:9997");
assert (rc == 0);
rc = zmq_connect (client, "tcp://localhost:9997");
assert (rc == 0);
//TODO: this test fails without any error
// bounce (server, client);
rc = zmq_close (client);
assert (rc == 0);
rc = zmq_close (server);
assert (rc == 0);
// Shutdown
rc = zmq_ctx_term (ctx);
assert (rc == 0);
return 0;
}