Commit e1f797b0 authored by Pieter Hintjens's avatar Pieter Hintjens

Added configuration for PLAIN security

* ZMQ_PLAIN_SERVER, ZMQ_PLAIN_USERNAME, ZMQ_PLAIN_PASSWORD options
* Man page changes to zmq_setsockopt and zmq_getsockopt
* Man pages for ZMQ_NULL, ZMQ_PLAIN, and ZMQ_CURVE
* Test program test_security
parent 8ea779c8
......@@ -47,6 +47,7 @@ tests/test_raw_sock
tests/test_disconnect_inproc
tests/test_ctx_options
tests/test_iov
tests/test_security
src/platform.hpp*
src/stamp-h1
perf/local_lat
......
......@@ -8,9 +8,10 @@ MAN3 = zmq_bind.3 zmq_unbind.3 zmq_connect.3 zmq_disconnect.3 zmq_close.3 \
zmq_getsockopt.3 zmq_setsockopt.3 \
zmq_socket.3 zmq_socket_monitor.3 zmq_poll.3 \
zmq_errno.3 zmq_strerror.3 zmq_version.3 zmq_proxy.3 \
zmq_sendmsg.3 zmq_recvmsg.3 zmq_init.3 zmq_term.3
zmq_sendmsg.3 zmq_recvmsg.3 zmq_init.3 zmq_term.3
MAN7 = zmq.7 zmq_tcp.7 zmq_pgm.7 zmq_epgm.7 zmq_inproc.7 zmq_ipc.7
MAN7 = zmq.7 zmq_tcp.7 zmq_pgm.7 zmq_epgm.7 zmq_inproc.7 zmq_ipc.7 \
zmq_null.7 zmq_plain.7 zmq_curve.7
MAN_DOC = $(MAN1) $(MAN3) $(MAN7)
......
......@@ -177,6 +177,23 @@ two sockets, opaquely. A proxy may optionally capture all traffic to a third
socket. To start a proxy in an application thread, use linkzmq:zmq_proxy[3].
Security
~~~~~~~~
A 0MQ socket can select a security mechanism. Both peers must use the same
security mechanism.
The following security mechanisms are provided for IPC and TCP connections:
Null security::
linkzmq:zmq_null[7]
Clear-text authentication using username and password::
linkzmq:zmq_clear[7]
Secure authentication and encryption::
linkzmq:zmq_curve[7]
ERROR HANDLING
--------------
The 0MQ library functions handle errors using the standard conventions found on
......
zmq_curve(7)
============
NAME
----
zmq_curve - clear-text authentication
SYNOPSIS
--------
The CURVE mechanism defines a mechanism for secure authentication and
confidentiality for communications between a client and a server. CURVE
is intended for use on public networks. The CURVE mechanism is defined
by this document: <http://rfc.zeromq.org/spec:25>.
SERVER AND CLIENT ROLES
-----------------------
To use CURVE, the server shall set the ZMQ_CURVE_SERVER option, and the
client shall set the ZMQ_CURVE_PUBLICKEY and ZMQ_CURVE_SERVERKEY socket
options. Which peer binds, and which connects, is not relevant.
NOTE: this isn't implemented and not fully defined. The server keypair
needs to be persistent, and it would be sensible to define a format for
this in CurveZMQ
SEE ALSO
--------
linkzmq:zmq_setsockopt[3]
linkzmq:zmq_null[7]
linkzmq:zmq_plain[7]
linkzmq:zmq[7]
AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.
......@@ -431,7 +431,7 @@ a ZMQ DSN. Note that if the TCP host is INADDR_ANY, indicated by a *, then
the returned address will be 0.0.0.0 (for IPv4).
[horizontal]
Option value type:: character string
Option value type:: NULL-terminated character string
Option value unit:: N/A
Default value:: NULL
Applicable socket types:: all, when binding TCP or IPC transports
......@@ -451,8 +451,9 @@ Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option (where
supported by OS). The default value of `-1` means to skip any overrides and
leave it to OS default.
[horizontal]
Option value type:: int
......@@ -485,6 +486,57 @@ Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.
ZMQ_MECHANISM: Retrieve the current security mechanism
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_MECHANISM' option shall retrieve the current security mechanism
for the socket.
[horizontal]
Option value type:: int
Option value unit:: ZMQ_NULL, ZMQ_PLAIN, or ZMQ_CURVE
Default value:: ZMQ_NULL
Applicable socket types:: all, when using TCP or IPC transports
ZMQ_PLAIN_SERVER: Retrieve the PLAIN server role
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns the 'ZMQ_PLAIN_SERVER' option, if any, previously set on the socket.
[horizontal]
Option value type:: int
Option value unit:: 0, 1
Default value:: int
Applicable socket types:: all, when using TCP or IPC transports
ZMQ_PLAIN_USERNAME: Retrieve the last username set
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_PLAIN_USERNAME' option shall retrieve the last username set for
the PLAIN security mechanism. The returned value shall be a NULL-terminated
string and MAY be empty. The returned size SHALL include the terminating
null byte.
[horizontal]
Option value type:: NULL-terminated character string
Option value unit:: N/A
Default value:: null string
Applicable socket types:: all, when using TCP or IPC transports
ZMQ_PLAIN_PASSWORD: Retrieve the last password set
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_PLAIN_PASSWORD' option shall retrieve the last password set for
the PLAIN security mechanism. The returned value shall be a NULL-terminated
string and MAY be empty. The returned size SHALL include the terminating
null byte.
[horizontal]
Option value type:: NULL-terminated character string
Option value unit:: N/A
Default value:: null string
Applicable socket types:: all, when using TCP or IPC transports
RETURN VALUE
------------
The _zmq_getsockopt()_ function shall return zero if successful. Otherwise it
......
zmq_null(7)
===========
NAME
----
zmq_null - no security or confidentiality
SYNOPSIS
--------
The NULL mechanism is defined by the ZMTP 3.0 specification:
<http://rfc.zeromq.org/spec:23>. This is the default security mechanism
for ZeroMQ sockets.
SEE ALSO
--------
linkzmq:zmq_plain[7]
linkzmq:zmq_curve[7]
linkzmq:zmq[7]
AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.
zmq_plain(7)
============
NAME
----
zmq_plain - clear-text authentication
SYNOPSIS
--------
The PLAIN mechanism defines a simple username/password mechanism that
lets a server authenticate a client. PLAIN makes no attempt at security
or confidentiality. It is intended for use on internal networks where
security requirements are low. The PLAIN mechanism is defined by this
document: <http://rfc.zeromq.org/spec:24>.
USAGE
-----
To use PLAIN, the server shall set the ZMQ_PLAIN_SERVER option, and the
client shall set the ZMQ_PLAIN_USERNAME and ZMQ_PLAIN_PASSWORD socket
options. Which peer binds, and which connects, is not relevant.
SEE ALSO
--------
linkzmq:zmq_setsockopt[3]
linkzmq:zmq_null[7]
linkzmq:zmq_curve[7]
linkzmq:zmq[7]
AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.
......@@ -437,6 +437,7 @@ Applicable socket types:: ZMQ_XPUB
ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'SO_KEEPALIVE' socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.
......@@ -449,8 +450,10 @@ Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option (where
supported by OS). The default value of `-1` means to skip any overrides and
leave it to OS default.
[horizontal]
Option value type:: int
......@@ -461,8 +464,9 @@ Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPCNT' socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.
Override 'TCP_KEEPCNT' socket option(where supported by OS). The default
value of `-1` means to skip any overrides and leave it to OS default.
[horizontal]
Option value type:: int
......@@ -473,8 +477,9 @@ Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPINTVL' socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.
Override 'TCP_KEEPINTVL' socket option(where supported by OS). The default
value of `-1` means to skip any overrides and leave it to OS default.
[horizontal]
Option value type:: int
......@@ -485,11 +490,12 @@ Applicable socket types:: all, when using TCP transports.
ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Assign arbitrary number of filters that will be applied for each new TCP transport
connection on a listening socket.
If no filters applied, then TCP transport allows connections from any ip.
If at least one filter is applied then new connection source ip should be matched.
To clear all filters call zmq_setsockopt(socket, ZMQ_TCP_ACCEPT_FILTER, NULL, 0).
Assign an arbitrary number of filters that will be applied for each new TCP
transport connection on a listening socket. If no filters are applied, then
the TCP transport allows connections from any IP address. If at least one
filter is applied then new connection source ip should be matched. To clear
all filters call zmq_setsockopt(socket, ZMQ_TCP_ACCEPT_FILTER, NULL, 0).
Filter is a null-terminated string with ipv6 or ipv4 CIDR.
[horizontal]
......@@ -499,6 +505,52 @@ Default value:: no filters (allow from all)
Applicable socket types:: all listening sockets, when using TCP transports.
ZMQ_PLAIN_SERVER: Set PLAIN server role
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines whether the socket will act as server for PLAIN security, see
linkzmq:zmq_plain[3]. A value of '1' means the socket will act as
PLAIN server. A value of '0' means the socket will not act as PLAIN
server, and its security role then depends on other option settings.
Setting this to '0' shall reset the socket security to NULL.
[horizontal]
Option value type:: int
Option value unit:: 0, 1
Default value:: 0
Applicable socket types:: all, when using TCP or IPC transports
ZMQ_PLAIN_USERNAME: Set PLAIN security username
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the username for outgoing connections over TCP or IPC. If you set this
to a non-null value, the security mechanism used for connections shall be
PLAIN, see linkzmq:zmq_plain[3]. If you set this to a null value, the security
mechanism used for connections shall be NULL, see linkzmq:zmq_null[3].
[horizontal]
Option value type:: character string
Option value unit:: N/A
Default value:: not set
Applicable socket types:: all, when using TCP or IPC transports
ZMQ_PLAIN_PASSWORD: Set PLAIN security password
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the password for outgoing connections over TCP or IPC. If you set this
to a non-null value, the security mechanism used for connections shall be
PLAIN, see linkzmq:zmq_plain[7]. If you set this to a null value, the security
mechanism used for connections shall be NULL, see linkzmq:zmq_null[3].
[horizontal]
Option value type:: character string
Option value unit:: N/A
Default value:: not set
Applicable socket types:: all, when using TCP or IPC transports
RETURN VALUE
------------
The _zmq_setsockopt()_ function shall return zero if successful. Otherwise it
......@@ -550,6 +602,8 @@ SEE ALSO
--------
linkzmq:zmq_getsockopt[3]
linkzmq:zmq_socket[3]
linkzmq:zmq_plain[7]
linkzmq:zmq_curve[7]
linkzmq:zmq[7]
......
......@@ -253,6 +253,13 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
#define ZMQ_XPUB_VERBOSE 40
#define ZMQ_ROUTER_RAW 41
#define ZMQ_IPV6 42
#define ZMQ_MECHANISM 43
#define ZMQ_PLAIN_SERVER 44
#define ZMQ_PLAIN_USERNAME 45
#define ZMQ_PLAIN_PASSWORD 46
#define ZMQ_CURVE_SERVER 47
#define ZMQ_CURVE_PUBLICKEY 48
#define ZMQ_CURVE_SERVERKEY 49
/* Message options */
#define ZMQ_MORE 1
......@@ -261,6 +268,11 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
#define ZMQ_DONTWAIT 1
#define ZMQ_SNDMORE 2
/* Security mechanisms */
#define ZMQ_NULL 0
#define ZMQ_PLAIN 1
#define ZMQ_CURVE 2
/* Deprecated aliases */
#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
......
This diff is collapsed.
......@@ -123,10 +123,17 @@ namespace zmq
typedef std::vector <tcp_address_mask_t> tcp_accept_filters_t;
tcp_accept_filters_t tcp_accept_filters;
// Security mechanism for all connections on this socket
int mechanism;
// Security credentials for PLAIN mechanism
std::string plain_username;
std::string plain_password;
int plain_server;
// ID of the socket.
int socket_id;
};
}
#endif
......@@ -376,7 +376,9 @@ int zmq_send (void *s_, const void *buf_, size_t len_, int flags_)
return rc;
}
// Send multiple messages.
// TODO: this function has no man page
//
// If flag bit ZMQ_SNDMORE is set the vector is treated as
// a single multi-part message, i.e. the last message has
......@@ -477,7 +479,7 @@ int zmq_recv (void *s_, void *buf_, size_t len_, int flags_)
//
// The iov_base* buffers of each iovec *a_ filled in by this
// function may be freed using free().
//
// TODO: this function has no man page
//
int zmq_recviov (void *s_, iovec *a_, size_t *count_, int flags_)
{
......
......@@ -21,6 +21,7 @@ noinst_PROGRAMS = test_pair_inproc \
test_raw_sock \
test_disconnect_inproc \
test_ctx_options \
test_security \
test_iov
if !ON_MINGW
......@@ -49,6 +50,7 @@ test_raw_sock_SOURCES = test_raw_sock.cpp
test_disconnect_inproc_SOURCES = test_disconnect_inproc.cpp
test_ctx_options_SOURCES = test_ctx_options.cpp
test_iov_SOURCES = test_iov.cpp
test_security_SOURCES = test_security.cpp
if !ON_MINGW
test_shutdown_stress_SOURCES = test_shutdown_stress.cpp
test_pair_ipc_SOURCES = test_pair_ipc.cpp testutil.hpp
......
/*
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.h"
#include <string.h>
#include <stdbool.h>
#undef NDEBUG
#include <assert.h>
int main (void)
{
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;
optsize = sizeof (int);
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_NULL);
optsize = sizeof (int);
rc = zmq_getsockopt (server, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_NULL);
// Check PLAIN security
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);
optsize = sizeof (int);
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_PLAIN);
int as_server = 1;
rc = zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int));
assert (rc == 0);
optsize = sizeof (int);
rc = zmq_getsockopt (server, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_PLAIN);
// Check we can switch back to NULL security
rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, NULL, 0);
assert (rc == 0);
rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, NULL, 0);
assert (rc == 0);
optsize = sizeof (int);
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
assert (rc == 0);
assert (mechanism == ZMQ_NULL);
rc = zmq_close (client);
assert (rc == 0);
rc = zmq_close (server);
assert (rc == 0);
rc = zmq_ctx_term (ctx);
assert (rc == 0);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment