1ZAUTH(3)                          CZMQ Manual                         ZAUTH(3)
2
3
4

NAME

6       zauth - Class for authentication for ZeroMQ security mechanisms
7

SYNOPSIS

9       #define CURVE_ALLOW_ANY "*"
10
11       //  CZMQ v3 API (for use with zsock, not zsocket, which is deprecated).
12       //
13       //  Create new zauth actor instance. This installs authentication on all
14       //  zsock sockets. Until you add policies, all incoming NULL connections are
15       //  allowed (classic ZeroMQ behaviour), and all PLAIN and CURVE connections
16       //  are denied:
17       //
18       //      zactor_t *auth = zactor_new (zauth, NULL);
19       //
20       //  Destroy zauth instance. This removes authentication and allows all
21       //  connections to pass, without authentication:
22       //
23       //      zactor_destroy (&auth);
24       //
25       //  Note that all zauth commands are synchronous, so your application always
26       //  waits for a signal from the actor after each command.
27       //
28       //  Enable verbose logging of commands and activity. Verbose logging can help
29       //  debug non-trivial authentication policies:
30       //
31       //      zstr_send (auth, "VERBOSE");
32       //      zsock_wait (auth);
33       //
34       //  Allow (whitelist) a list of IP addresses. For NULL, all clients from
35       //  these addresses will be accepted. For PLAIN and CURVE, they will be
36       //  allowed to continue with authentication. You can call this method
37       //  multiple times to whitelist more IP addresses. If you whitelist one
38       //  or more addresses, any non-whitelisted addresses are treated as
39       //  blacklisted:
40       //
41       //      zstr_sendx (auth, "ALLOW", "127.0.0.1", "127.0.0.2", NULL);
42       //      zsock_wait (auth);
43       //
44       //  Deny (blacklist) a list of IP addresses. For all security mechanisms,
45       //  this rejects the connection without any further authentication. Use
46       //  either a whitelist, or a blacklist, not not both. If you define both
47       //  a whitelist and a blacklist, only the whitelist takes effect:
48       //
49       //      zstr_sendx (auth, "DENY", "192.168.0.1", "192.168.0.2", NULL);
50       //      zsock_wait (auth);
51       //
52       //  Configure PLAIN authentication using a plain-text password file. You can
53       //  modify the password file at any time; zauth will reload it automatically
54       //  if modified externally:
55       //
56       //      zstr_sendx (auth, "PLAIN", filename, NULL);
57       //      zsock_wait (auth);
58       //
59       //  Configure CURVE authentication, using a directory that holds all public
60       //  client certificates, i.e. their public keys. The certificates must be in
61       //  zcert_save format. You can add and remove certificates in that directory
62       //  at any time. To allow all client keys without checking, specify
63       //  CURVE_ALLOW_ANY for the directory name:
64       //
65       //      zstr_sendx (auth, "CURVE", directory, NULL);
66       //      zsock_wait (auth);
67       //
68       //  Configure GSSAPI authentication, using an underlying mechanism (usually
69       //  Kerberos) to establish a secure context and perform mutual authentication:
70       //
71       //      zstr_sendx (auth, "GSSAPI", NULL);
72       //      zsock_wait (auth);
73       //
74       //  This is the zauth constructor as a zactor_fn:
75       CZMQ_EXPORT void
76           zauth (zsock_t *pipe, void *certstore);
77
78       //  Selftest
79       CZMQ_EXPORT void
80           zauth_test (bool verbose);
81       Please add '@interface' section in './../src/zauth.c'.
82

DESCRIPTION

84       A zauth actor takes over authentication for all incoming connections in
85       its context. You can whitelist or blacklist peers based on IP address,
86       and define policies for securing PLAIN, CURVE, and GSSAPI connections.
87
88       This class replaces zauth_v2, and is meant for applications that use
89       the CZMQ v3 API (meaning, zsock).
90

EXAMPLE

92       From zauth_test method.
93
94           const char *SELFTEST_DIR_RW = "src/selftest-rw";
95
96           const char *testbasedir  = ".test_zauth";
97           const char *testpassfile = "password-file";
98           const char *testcertfile = "mycert.txt";
99           char *basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
100           char *passfilepath = NULL;  // pathname to testfile in a test, in dirpath
101           char *certfilepath = NULL;  // pathname to testfile in a test, in dirpath
102
103           basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir);
104           assert (basedirpath);
105           passfilepath = zsys_sprintf ("%s/%s", basedirpath, testpassfile);
106           assert (passfilepath);
107           certfilepath = zsys_sprintf ("%s/%s", basedirpath, testcertfile);
108           assert (certfilepath);
109
110           // Make sure old aborted tests do not hinder us
111           zdir_t *dir = zdir_new (basedirpath, NULL);
112           if (dir) {
113               zdir_remove (dir, true);
114               zdir_destroy (&dir);
115           }
116           zsys_file_delete (passfilepath);
117           zsys_file_delete (certfilepath);
118           zsys_dir_delete  (basedirpath);
119
120           //  Create temporary directory for test files
121           zsys_dir_create (basedirpath);
122
123           //  Check there's no authentication
124           zsock_t *server = zsock_new (ZMQ_PULL);
125           assert (server);
126           zsock_t *client = zsock_new (ZMQ_PUSH);
127           assert (client);
128           bool success = s_can_connect (&server, &client, true);
129           assert (success);
130
131           //  Install the authenticator
132           zactor_t *auth = zactor_new (zauth, NULL);
133           assert (auth);
134           if (verbose) {
135               zstr_sendx (auth, "VERBOSE", NULL);
136               zsock_wait (auth);
137           }
138           //  Check there's no authentication on a default NULL server
139           success = s_can_connect (&server, &client, true);
140           assert (success);
141
142           //  When we set a domain on the server, we switch on authentication
143           //  for NULL sockets, but with no policies, the client connection
144           //  will be allowed.
145           zsock_set_zap_domain (server, "global");
146           success = s_can_connect (&server, &client, true);
147           assert (success);
148
149           //  Blacklist 127.0.0.1, connection should fail
150           zsock_set_zap_domain (server, "global");
151           zstr_sendx (auth, "DENY", "127.0.0.1", NULL);
152           zsock_wait (auth);
153           success = s_can_connect (&server, &client, true);
154           assert (!success);
155
156           //  Whitelist our address, which overrides the blacklist
157           zsock_set_zap_domain (server, "global");
158           zstr_sendx (auth, "ALLOW", "127.0.0.1", NULL);
159           zsock_wait (auth);
160           success = s_can_connect (&server, &client, true);
161           assert (success);
162
163           //  Try PLAIN authentication
164           zsock_set_zap_domain (server, "global");
165           zsock_set_plain_server (server, 1);
166           zsock_set_plain_username (client, "admin");
167           zsock_set_plain_password (client, "Password");
168           success = s_can_connect (&server, &client, true);
169           assert (!success);
170
171           FILE *password = fopen (passfilepath, "w");
172           assert (password);
173           fprintf (password, "admin=Password\n");
174           fclose (password);
175           zsock_set_zap_domain (server, "global");
176           zsock_set_plain_server (server, 1);
177           zsock_set_plain_username (client, "admin");
178           zsock_set_plain_password (client, "Password");
179           zstr_sendx (auth, "PLAIN", passfilepath, NULL);
180           zsock_wait (auth);
181           success = s_can_connect (&server, &client, false);
182           assert (success);
183
184           #if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (4, 1, 0))
185           // Test that the User-Id metadata is present
186           zframe_t *frame = zframe_recv (server);
187           assert (frame != NULL);
188           const char *user_id = zframe_meta (frame, "User-Id");
189           assert (user_id != NULL);
190           assert (streq (user_id, "admin"));
191           zframe_destroy (&frame);
192           #endif
193           s_renew_sockets(&server, &client);
194
195           zsock_set_zap_domain (server, "global");
196           zsock_set_plain_server (server, 1);
197           zsock_set_plain_username (client, "admin");
198           zsock_set_plain_password (client, "Bogus");
199           success = s_can_connect (&server, &client, true);
200           assert (!success);
201
202           if (zsys_has_curve ()) {
203               //  Try CURVE authentication
204               //  We'll create two new certificates and save the client public
205               //  certificate on disk; in a real case we'd transfer this securely
206               //  from the client machine to the server machine.
207               zcert_t *server_cert = zcert_new ();
208               assert (server_cert);
209               zcert_t *client_cert = zcert_new ();
210               assert (client_cert);
211               const char *server_key = zcert_public_txt (server_cert);
212
213               //  Test without setting-up any authentication
214               zcert_apply (server_cert, server);
215               zcert_apply (client_cert, client);
216               zsock_set_curve_server (server, 1);
217               zsock_set_curve_serverkey (client, server_key);
218               zsock_set_zap_domain (server, "global");
219               success = s_can_connect (&server, &client, true);
220               assert (!success);
221
222               //  Test CURVE_ALLOW_ANY
223               zcert_apply (server_cert, server);
224               zcert_apply (client_cert, client);
225               zsock_set_curve_server (server, 1);
226               zsock_set_curve_serverkey (client, server_key);
227               zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL);
228               zsock_wait (auth);
229               success = s_can_connect (&server, &client, true);
230               assert (success);
231
232               //  Test full client authentication using certificates
233               zcert_set_meta (client_cert, "Hello", "%s", "World!");
234               zcert_apply (server_cert, server);
235               zcert_apply (client_cert, client);
236               zsock_set_curve_server (server, 1);
237               zsock_set_curve_serverkey (client, server_key);
238               zcert_save_public (client_cert, certfilepath);
239               zstr_sendx (auth, "CURVE", basedirpath, NULL);
240               zsock_wait (auth);
241               zsock_set_zap_domain (server, "global");
242               success = s_can_connect (&server, &client, false);
243               assert (success);
244
245           #if (ZMQ_VERSION >= ZMQ_MAKE_VERSION (4, 1, 0))
246               // Test send/recv certificate metadata
247               zframe_t *frame = zframe_recv (server);
248               assert (frame != NULL);
249               const char *meta = zframe_meta (frame, "Hello");
250               assert (meta != NULL);
251               assert (streq (meta, "World!"));
252               const char *user_id = zframe_meta (frame, "User-Id");
253               assert (user_id != NULL);
254               assert (streq (user_id, zcert_public_txt(client_cert)));
255               zframe_destroy (&frame);
256               s_renew_sockets(&server, &client);
257           #endif
258
259               zcert_destroy (&server_cert);
260               zcert_destroy (&client_cert);
261
262               // Test custom zcertstore
263               zcertstore_t *certstore = zcertstore_new (NULL);
264               zcertstore_set_loader (certstore, s_test_loader, NULL, NULL);
265               zactor_destroy(&auth);
266               auth = zactor_new (zauth, certstore);
267               assert (auth);
268               if (verbose) {
269                   zstr_sendx (auth, "VERBOSE", NULL);
270                   zsock_wait (auth);
271               }
272
273               byte public_key [32] = { 105, 76, 150, 58, 214, 191, 218, 65, 50, 172,
274                                        131, 188, 247, 211, 136, 170, 227, 26, 57, 170,
275                                        185, 63, 246, 225, 177, 230, 12, 8, 134, 136,
276                                        105, 106 };
277               byte secret_key [32] = { 245, 217, 172, 73, 106, 28, 195, 17, 218, 132,
278                                        135, 209, 99, 240, 98, 232, 7, 137, 244, 100,
279                                        242, 23, 29, 114, 70, 223, 83, 1, 113, 207,
280                                        132, 149 };
281               zcert_t *shared_cert = zcert_new_from (public_key, secret_key);
282               assert (shared_cert);
283               zcert_apply (shared_cert, server);
284               zcert_apply (shared_cert, client);
285               zsock_set_curve_server (server, 1);
286               zsock_set_curve_serverkey (client, "x?T*N/1Y{8goubv{Ts}#&#f}TXJ//DVe#D2HkoLU");
287               success = s_can_connect (&server, &client, true);
288               assert (success);
289               zcert_destroy (&shared_cert);
290           }
291           //  Remove the authenticator and check a normal connection works
292           zactor_destroy (&auth);
293           success = s_can_connect (&server, &client, true);
294           assert (success);
295
296           zsock_destroy (&client);
297           zsock_destroy (&server);
298
299           //  Delete all test files
300           dir = zdir_new (basedirpath, NULL);
301           assert (dir);
302           zdir_remove (dir, true);
303           zdir_destroy (&dir);
304
305           zstr_free (&passfilepath);
306           zstr_free (&certfilepath);
307           zstr_free (&basedirpath);
308
309           #endif
310
311           #if defined (__WINDOWS__)
312           zsys_shutdown();
313           #endif
314
315

AUTHORS

317       The czmq manual was written by the authors in the AUTHORS file.
318

RESOURCES

320       Main web site:
321
322       Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
323
325       Copyright (c) the Contributors as noted in the AUTHORS file. This file
326       is part of CZMQ, the high-level C binding for 0MQ:
327       http://czmq.zeromq.org. This Source Code Form is subject to the terms
328       of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
329       distributed with this file, You can obtain one at
330       http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
331       distribution.
332

NOTES

334        1. zeromq-dev@lists.zeromq.org
335           mailto:zeromq-dev@lists.zeromq.org
336
337
338
339CZMQ 4.2.0                        01/28/2020                          ZAUTH(3)
Impressum