Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
ZAUTH(3)			  CZMQ Manual			      ZAUTH(3)

NAME
       zauth - Class for authentication	for ZeroMQ security mechanisms

SYNOPSIS
       #define CURVE_ALLOW_ANY "*"

       //  CZMQ	v3 API (for use	with zsock, not	zsocket, which is deprecated).
       //
       //  Create new zauth actor instance. This installs authentication on all
       //  zsock sockets. Until	you add	policies, all incoming NULL connections	are
       //  allowed (classic ZeroMQ behaviour), and all PLAIN and CURVE connections
       //  are denied:
       //
       //      zactor_t	*auth =	zactor_new (zauth, NULL);
       //
       //  Destroy zauth instance. This	removes	authentication and allows all
       //  connections to pass,	without	authentication:
       //
       //      zactor_destroy (&auth);
       //
       //  Note	that all zauth commands	are synchronous, so your application always
       //  waits for a signal from the actor after each	command.
       //
       //  Enable verbose logging of commands and activity. Verbose logging can	help
       //  debug non-trivial authentication policies:
       //
       //      zstr_send (auth,	"VERBOSE");
       //      zsock_wait (auth);
       //
       //  Allow (whitelist) a list of IP addresses. For NULL, all clients from
       //  these addresses will	be accepted. For PLAIN and CURVE, they will be
       //  allowed to continue with authentication. You	can call this method
       //  multiple times to whitelist more IP addresses. If you whitelist one
       //  or more addresses, any non-whitelisted addresses are	treated	as
       //  blacklisted:
       //
       //      zstr_sendx (auth, "ALLOW", "127.0.0.1", "127.0.0.2", NULL);
       //      zsock_wait (auth);
       //
       //  Deny	(blacklist) a list of IP addresses. For	all security mechanisms,
       //  this	rejects	the connection without any further authentication. Use
       //  either a whitelist, or a blacklist, not not both. If	you define both
       //  a whitelist and a blacklist,	only the whitelist takes effect:
       //
       //      zstr_sendx (auth, "DENY", "192.168.0.1",	"192.168.0.2", NULL);
       //      zsock_wait (auth);
       //
       //  Configure PLAIN authentication using	a plain-text password file. You	can
       //  modify the password file at any time; zauth will reload it automatically
       //  if modified externally:
       //
       //      zstr_sendx (auth, "PLAIN", filename, NULL);
       //      zsock_wait (auth);
       //
       //  Configure CURVE authentication, using a directory that holds	all public
       //  client certificates,	i.e. their public keys.	The certificates must be in
       //  zcert_save format. You can add and remove certificates in that directory
       //  at any time.	To allow all client keys without checking, specify
       //  CURVE_ALLOW_ANY for the directory name:
       //
       //      zstr_sendx (auth, "CURVE", directory, NULL);
       //      zsock_wait (auth);
       //
       //  Configure GSSAPI authentication, using an underlying	mechanism (usually
       //  Kerberos) to	establish a secure context and perform mutual authentication:
       //
       //      zstr_sendx (auth, "GSSAPI", NULL);
       //      zsock_wait (auth);
       //
       //  This	is the zauth constructor as a zactor_fn:
       CZMQ_EXPORT void
	   zauth (zsock_t *pipe, void *certstore);

       //  Selftest
       CZMQ_EXPORT void
	   zauth_test (bool verbose);
       Please add '@interface' section in './../src/zauth.c'.

DESCRIPTION
       A zauth actor takes over	authentication for all incoming	connections in
       its context. You	can whitelist or blacklist peers based on IP address,
       and define policies for securing	PLAIN, CURVE, and GSSAPI connections.

       This class replaces zauth_v2, and is meant for applications that	use
       the CZMQ	v3 API (meaning, zsock).

EXAMPLE
       From zauth_test method.

	   const char *SELFTEST_DIR_RW = "src/selftest-rw";

	   const char *testbasedir  = ".test_zauth";
	   const char *testpassfile = "password-file";
	   const char *testcertfile = "mycert.txt";
	   char	*basedirpath = NULL;   // subdir in a test, under SELFTEST_DIR_RW
	   char	*passfilepath =	NULL;  // pathname to testfile in a test, in dirpath
	   char	*certfilepath =	NULL;  // pathname to testfile in a test, in dirpath

	   basedirpath = zsys_sprintf ("%s/%s",	SELFTEST_DIR_RW, testbasedir);
	   assert (basedirpath);
	   passfilepath	= zsys_sprintf ("%s/%s", basedirpath, testpassfile);
	   assert (passfilepath);
	   certfilepath	= zsys_sprintf ("%s/%s", basedirpath, testcertfile);
	   assert (certfilepath);

	   // Make sure	old aborted tests do not hinder	us
	   zdir_t *dir = zdir_new (basedirpath,	NULL);
	   if (dir) {
	       zdir_remove (dir, true);
	       zdir_destroy (&dir);
	   }
	   zsys_file_delete (passfilepath);
	   zsys_file_delete (certfilepath);
	   zsys_dir_delete  (basedirpath);

	   //  Create temporary	directory for test files
	   zsys_dir_create (basedirpath);

	   //  Check there's no	authentication
	   zsock_t *server = zsock_new (ZMQ_PULL);
	   assert (server);
	   zsock_t *client = zsock_new (ZMQ_PUSH);
	   assert (client);
	   bool	success	= s_can_connect	(&server, &client, true);
	   assert (success);

	   //  Install the authenticator
	   zactor_t *auth = zactor_new (zauth, NULL);
	   assert (auth);
	   if (verbose)	{
	       zstr_sendx (auth, "VERBOSE", NULL);
	       zsock_wait (auth);
	   }
	   //  Check there's no	authentication on a default NULL server
	   success = s_can_connect (&server, &client, true);
	   assert (success);

	   //  When we set a domain on the server, we switch on	authentication
	   //  for NULL	sockets, but with no policies, the client connection
	   //  will be allowed.
	   zsock_set_zap_domain	(server, "global");
	   success = s_can_connect (&server, &client, true);
	   assert (success);

	   //  Blacklist 127.0.0.1, connection should fail
	   zsock_set_zap_domain	(server, "global");
	   zstr_sendx (auth, "DENY", "127.0.0.1", NULL);
	   zsock_wait (auth);
	   success = s_can_connect (&server, &client, true);
	   assert (!success);

	   //  Whitelist our address, which overrides the blacklist
	   zsock_set_zap_domain	(server, "global");
	   zstr_sendx (auth, "ALLOW", "127.0.0.1", NULL);
	   zsock_wait (auth);
	   success = s_can_connect (&server, &client, true);
	   assert (success);

	   //  Try PLAIN authentication
	   zsock_set_zap_domain	(server, "global");
	   zsock_set_plain_server (server, 1);
	   zsock_set_plain_username (client, "admin");
	   zsock_set_plain_password (client, "Password");
	   success = s_can_connect (&server, &client, true);
	   assert (!success);

	   FILE	*password = fopen (passfilepath, "w");
	   assert (password);
	   fprintf (password, "admin=Password\n");
	   fclose (password);
	   zsock_set_zap_domain	(server, "global");
	   zsock_set_plain_server (server, 1);
	   zsock_set_plain_username (client, "admin");
	   zsock_set_plain_password (client, "Password");
	   zstr_sendx (auth, "PLAIN", passfilepath, NULL);
	   zsock_wait (auth);
	   success = s_can_connect (&server, &client, false);
	   assert (success);

	   #if (ZMQ_VERSION >= ZMQ_MAKE_VERSION	(4, 1, 0))
	   // Test that	the User-Id metadata is	present
	   zframe_t *frame = zframe_recv (server);
	   assert (frame != NULL);
	   const char *user_id = zframe_meta (frame, "User-Id");
	   assert (user_id != NULL);
	   assert (streq (user_id, "admin"));
	   zframe_destroy (&frame);
	   #endif
	   s_renew_sockets(&server, &client);

	   zsock_set_zap_domain	(server, "global");
	   zsock_set_plain_server (server, 1);
	   zsock_set_plain_username (client, "admin");
	   zsock_set_plain_password (client, "Bogus");
	   success = s_can_connect (&server, &client, true);
	   assert (!success);

	   if (zsys_has_curve ()) {
	       //  Try CURVE authentication
	       //  We'll create	two new	certificates and save the client public
	       //  certificate on disk;	in a real case we'd transfer this securely
	       //  from	the client machine to the server machine.
	       zcert_t *server_cert = zcert_new	();
	       assert (server_cert);
	       zcert_t *client_cert = zcert_new	();
	       assert (client_cert);
	       const char *server_key =	zcert_public_txt (server_cert);

	       //  Test	without	setting-up any authentication
	       zcert_apply (server_cert, server);
	       zcert_apply (client_cert, client);
	       zsock_set_curve_server (server, 1);
	       zsock_set_curve_serverkey (client, server_key);
	       zsock_set_zap_domain (server, "global");
	       success = s_can_connect (&server, &client, true);
	       assert (!success);

	       //  Test	CURVE_ALLOW_ANY
	       zcert_apply (server_cert, server);
	       zcert_apply (client_cert, client);
	       zsock_set_curve_server (server, 1);
	       zsock_set_curve_serverkey (client, server_key);
	       zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL);
	       zsock_wait (auth);
	       success = s_can_connect (&server, &client, true);
	       assert (success);

	       //  Test	full client authentication using certificates
	       zcert_set_meta (client_cert, "Hello", "%s", "World!");
	       zcert_apply (server_cert, server);
	       zcert_apply (client_cert, client);
	       zsock_set_curve_server (server, 1);
	       zsock_set_curve_serverkey (client, server_key);
	       zcert_save_public (client_cert, certfilepath);
	       zstr_sendx (auth, "CURVE", basedirpath, NULL);
	       zsock_wait (auth);
	       zsock_set_zap_domain (server, "global");
	       success = s_can_connect (&server, &client, false);
	       assert (success);

	   #if (ZMQ_VERSION >= ZMQ_MAKE_VERSION	(4, 1, 0))
	       // Test send/recv certificate metadata
	       zframe_t	*frame = zframe_recv (server);
	       assert (frame !=	NULL);
	       const char *meta	= zframe_meta (frame, "Hello");
	       assert (meta != NULL);
	       assert (streq (meta, "World!"));
	       const char *user_id = zframe_meta (frame, "User-Id");
	       assert (user_id != NULL);
	       assert (streq (user_id, zcert_public_txt(client_cert)));
	       zframe_destroy (&frame);
	       s_renew_sockets(&server,	&client);
	   #endif

	       zcert_destroy (&server_cert);
	       zcert_destroy (&client_cert);

	       // Test custom zcertstore
	       zcertstore_t *certstore = zcertstore_new	(NULL);
	       zcertstore_set_loader (certstore, s_test_loader,	NULL, NULL);
	       zactor_destroy(&auth);
	       auth = zactor_new (zauth, certstore);
	       assert (auth);
	       if (verbose) {
		   zstr_sendx (auth, "VERBOSE",	NULL);
		   zsock_wait (auth);
	       }

	       byte public_key [32] = {	105, 76, 150, 58, 214, 191, 218, 65, 50, 172,
					131, 188, 247, 211, 136, 170, 227, 26, 57, 170,
					185, 63, 246, 225, 177,	230, 12, 8, 134, 136,
					105, 106 };
	       byte secret_key [32] = {	245, 217, 172, 73, 106,	28, 195, 17, 218, 132,
					135, 209, 99, 240, 98, 232, 7, 137, 244, 100,
					242, 23, 29, 114, 70, 223, 83, 1, 113, 207,
					132, 149 };
	       zcert_t *shared_cert = zcert_new_from (public_key, secret_key);
	       assert (shared_cert);
	       zcert_apply (shared_cert, server);
	       zcert_apply (shared_cert, client);
	       zsock_set_curve_server (server, 1);
	       zsock_set_curve_serverkey (client, "x?T*N/1Y{8goubv{Ts}#&#f}TXJ//DVe#D2HkoLU");
	       success = s_can_connect (&server, &client, true);
	       assert (success);
	       zcert_destroy (&shared_cert);
	   }
	   //  Remove the authenticator	and check a normal connection works
	   zactor_destroy (&auth);
	   success = s_can_connect (&server, &client, true);
	   assert (success);

	   zsock_destroy (&client);
	   zsock_destroy (&server);

	   //  Delete all test files
	   dir = zdir_new (basedirpath,	NULL);
	   assert (dir);
	   zdir_remove (dir, true);
	   zdir_destroy	(&dir);

	   zstr_free (&passfilepath);
	   zstr_free (&certfilepath);
	   zstr_free (&basedirpath);

	   #endif

	   #if defined (__WINDOWS__)
	   zsys_shutdown();
	   #endif

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

RESOURCES
       Main web	site:

       Report bugs to the email	<zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT
       Copyright (c) the Contributors as noted in the AUTHORS file. This file
       is part of CZMQ,	the high-level C binding for 0MQ:
       http://czmq.zeromq.org. This Source Code	Form is	subject	to the terms
       of the Mozilla Public License, v. 2.0. If a copy	of the MPL was not
       distributed with	this file, You can obtain one at
       http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
       distribution.

NOTES
	1. zeromq-dev@lists.zeromq.org
	   mailto:zeromq-dev@lists.zeromq.org

CZMQ 4.1.1			  08/10/2020			      ZAUTH(3)

NAME | SYNOPSIS | DESCRIPTION | EXAMPLE | AUTHORS | RESOURCES | COPYRIGHT | NOTES

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=zauth&sektion=3&manpath=FreeBSD+12.2-RELEASE+and+Ports>

home | help