Commit bad06a81 authored by Alexander Withers's avatar Alexander Withers

new gateway binary, removed cabana key

parent 4ec19b5d
all: server client
CFLAGS=--std=c99 -Wall -Wextra $(shell pkg-config --cflags libczmq)
LOADLIBES=$(shell pkg-config --libs libczmq)
server: server.o server_cmd.o keygen_cmd.o zsimpledisco.o
client: client.o zsimpledisco.o
server.static:
cc -o server server.c server_cmd.c zsimpledisco.c -static-libstdc++ -static -static-libgcc -Wall -Wextra -DCZMQ_BUILD_DRAFT_API=1 -DZMQ_BUILD_DRAFT_API=1 $(shell pkg-config --cflags --libs libczmq) -l pthread -lstdc++ -lm
all: gateway
CFLAGS=-Wall -Wextra $(shell pkg-config --cflags libzyre)
LOADLIBES= $(shell pkg-config --libs libzyre)
gateway: main.o keygen_cmd.o server_cmd.o gateway.o zsimpledisco.o
gateway.static: main.c gateway.c server_cmd.c zsimpledisco.c keygen_cmd.c
cc main.c gateway.c keygen_cmd.c server_cmd.c zsimpledisco.c -o gateway -static-libstdc++ -static -static-libgcc -Wall -Wextra $(shell pkg-config --cflags --libs libzyre) -lpthread -lstdc++ -lm
@echo OK!
#include "czmq_library.h"
#include "zsimpledisco.h"
int main(int argn, char *argv[])
{
if(argn < 2) {
fprintf(stderr, "Usage: %s tcp://127.0.0.1:9999 tcp://127.0.0.1:9998|key\n", argv[0]);
exit(1);
}
zsimpledisco_t *disco = zsimpledisco_new();
zsimpledisco_verbose(disco);
const char *private_key_path = getenv("PRIVATE_KEY_PATH");
if(private_key_path) {
zsimpledisco_set_private_key_path(disco, private_key_path);
}
for(int n=1;n<argn;n++) {
zsimpledisco_connect(disco, argv[n]);
}
char *key_str = zsys_sprintf ("Client-%d", getpid());
if(!getenv("QUIET"))
zsimpledisco_publish(disco, key_str, "Hello");
zpoller_t *poller = zpoller_new (NULL);
zpoller_add(poller, zsimpledisco_socket(disco));
zsimpledisco_get_values(disco);
while(1) {
zsock_t *which = zpoller_wait (poller, 1000);
if (which == zsimpledisco_socket (disco)) {
zmsg_t *msg = zmsg_recv (which);
char *key = zmsg_popstr (msg);
char *value = zmsg_popstr (msg);
printf("KEY VALUE PAIR: '%s' '%s'\n", key, value);
free (key);
free (value);
zmsg_destroy (&msg);
}
}
zsimpledisco_destroy(&disco);
}
No preview for this file type
This diff is collapsed.
#ifndef __GATEWAY_H_INCLUDED__
#define __GATEWAY_H_INCLUDED__
int server_cmd(char *bind);
int keygen_cmd(const char *keypair_filename);
int gateway_cmd (char *node_name);
#endif
#include "czmq_library.h"
// https://stackoverflow.com/questions/744766/how-to-compare-ends-of-strings-in-c
int EndsWith(const char *str, const char *suffix)
{
if (!str || !suffix)
return 0;
size_t lenstr = strlen(str);
size_t lensuffix = strlen(suffix);
if (lensuffix > lenstr)
return 0;
return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
}
int keygen_cmd(const char *filename)
{
char *keypair_filename;
const char *keypair_filename_secret;
// The next bit of code ensures that keypair_filename is 'foo' and keypair_filename_secret is 'foo_secret'
// FIXME: this leaks the filenames
if(EndsWith(filename, "_secret")) {
keypair_filename_secret = filename;
keypair_filename = strdup(filename);
char *ptr = keypair_filename + strlen(keypair_filename) - strlen("_secret");
*ptr = '\0';
} else {
keypair_filename = (char *) filename;
keypair_filename_secret = zsys_sprintf("%s_secret", filename);
}
if( access( keypair_filename, F_OK ) != -1 ) {
zsys_info("%s already exists, not creating keys", keypair_filename);
return 0;
}
if( access( keypair_filename_secret, F_OK ) != -1 ) {
zsys_info("%s already exists, not creating keys", keypair_filename);
return 0;
}
zcert_t *cert = zcert_new();
if(!cert) {
perror("Error creating new certificate");
return 1;
}
if(-1 == zcert_save(cert, keypair_filename)) {
zsys_info("Attempting to write keys to %s and %s", keypair_filename, keypair_filename_secret);
perror("Error writing key");
return 1;
}
zsys_info("Keys written to %s and %s", keypair_filename, keypair_filename_secret);
return 0;
}
#include "czmq_library.h"
#include "zsimpledisco.h"
#include "gateway.h"
void usage(char *cmd)
{
fprintf(stderr, "Usage: \n");
fprintf(stderr, " %s node_name\n", cmd);
fprintf(stderr, " %s keygen\n", cmd);
fprintf(stderr, " %s disco tcp://*:9999\n\n", cmd);
fprintf(stderr, "Environment Variables and their defaults:\n"
"UNTRUSTED_PUBLIC_KEY_DIR_PATH ./public_keys_untrusted path to directory to store new public keys\n"
"PRIVATE_KEY_PATH client.key_secret path to private key\n"
"PUBLIC_KEY_DIR_PATH ./public_keys path to directory containing public keys\n"
"ZYRE_BIND tcp://*:5670 the endpoint that the zyre p2p socket should bind to\n"
"DISABLE_CURVE unset set to disable curve encryption for sockets\n"
"PUBSUB_ENDPOINT tcp://127.0.0.1:14000 the endpoint that the gateway should bind to for pubsub\n"
"CONTROL_ENDPOINT tcp://127.0.0.1:14001 the endpoint that the gateway should bind to for control\n"
);
exit (1);
}
int
main (int argc, char *argv [])
{
zsys_init();
if (argc < 2) {
usage(argv[0]);
}
const char *private_key_path = getenv("PRIVATE_KEY_PATH");
if(!private_key_path) {
private_key_path = "client.key_secret";
zsys_info("PRIVATE_KEY_PATH defaulted to '%s'", private_key_path);
}
if (!zsys_file_exists(private_key_path)) {
keygen_cmd(private_key_path);
}
if (argc == 2 && streq(argv[1], "keygen")) {
exit(keygen_cmd(private_key_path));
}
if (argc == 2 && streq(argv[1], "disco")) {
usage(argv[0]);
}
if (argc == 3 && streq(argv[1], "disco")) {
exit(server_cmd(argv[2]));
}
return gateway_cmd(argv[1]);
}
# **** Generated on 2017-07-25 09:29:37 by CZMQ ****
# ZeroMQ CURVE Public Certificate
# Exchange securely, or use a secure mechanism to verify the contents
# of this file after exchange. Store public certificates in your home
# directory, in the .curve subdirectory.
metadata
simpledisco-endpoint = "tcp://cabana.ncsa.illinois.edu:9999"
curve
public-key = ").rnGhuU8zQr&rAyt^DF6+7l45!avpLher:M2{gm"
#!/usr/bin/env python
import logging
import os
import sys
import random
import zmq
import zmq.auth
from zmq.auth.thread import ThreadAuthenticator
import time
import uuid
import json
def make_client(ctx, endpoint):
client = ctx.socket(zmq.REQ)
# We need two certificates, one for the client and one for
# the server. The client must know the server's public key
# to make a CURVE connection.
client_secret_file = os.path.join('private_keys', "client.key_secret")
client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
client.curve_secretkey = client_secret
client.curve_publickey = client_public
server_public_file = os.path.join('public_keys', "server.key")
server_public, _ = zmq.auth.load_certificate(server_public_file)
# The client must know the server's public key to make a CURVE connection.
client.curve_serverkey = server_public
client.connect(endpoint)
return client
def client(server_endpoints, my_id, my_port):
print("Client starting...")
ctx = zmq.Context.instance()
clients = {srv: make_client(ctx, srv) for srv in server_endpoints}
while True:
all_peers = {}
for srv, client in clients.items():
client.send_multipart([b"PUBLISH", my_id, my_port])
if not client.poll(2000):
print("DEAD:", srv)
clients[srv] = make_client(ctx, srv)
continue
msg = client.recv()
print(msg)
client.send_multipart([b"PEERS"])
if not client.poll(2000):
print("DEAD:", srv)
clients[srv] = make_client(ctx, srv)
continue
peers = json.loads(client.recv().decode('utf-8'))
print("peers from", srv)
for U, val in peers:
print("-", U, val)
all_peers[U] = val
print()
print("All peers:")
for u, val in all_peers.items():
print("-", u, val)
print()
time.sleep(2)
if __name__ == '__main__':
if zmq.zmq_version_info() < (4,0):
raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version()))
if '-v' in sys.argv:
level = logging.DEBUG
else:
level = logging.INFO
logging.basicConfig(level=level, format="[%(levelname)s] %(message)s")
servers = sys.argv[1:]
my_id = str(uuid.uuid4()).encode('utf-8')
my_port = str(random.randint(2000,2020)).encode('utf-8')
while True:
client(servers, my_id, my_port)
#!/usr/bin/env python
import logging
import os
import sys
import random
import zmq
import zmq.auth
from zmq.auth.thread import ThreadAuthenticator
import time
import uuid
import json
def make_client(ctx, endpoint):
client = ctx.socket(zmq.DEALER)
client.connect(endpoint)
return client
# We need two certificates, one for the client and one for
# the server. The client must know the server's public key
# to make a CURVE connection.
client_secret_file = os.path.join('private_keys', "client.key_secret")
client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
client.curve_secretkey = client_secret
client.curve_publickey = client_public
server_public_file = os.path.join('public_keys', "server.key")
server_public, _ = zmq.auth.load_certificate(server_public_file)
# The client must know the server's public key to make a CURVE connection.
client.curve_serverkey = server_public
client.connect(endpoint)
return client
def client(server_endpoints, my_id, my_port):
print("Client starting...")
ctx = zmq.Context.instance()
clients = {srv: make_client(ctx, srv) for srv in server_endpoints}
while True:
all_peers = {}
for srv, client in clients.items():
client.send_multipart([b"PUBLISH", my_id, my_port])
if not client.poll(2000):
print("DEAD:", srv)
clients[srv] = make_client(ctx, srv)
continue
msg = client.recv()
print(msg)
client.send_multipart([b"VALUES"])
if not client.poll(2000):
print("DEAD:", srv)
clients[srv] = make_client(ctx, srv)
continue
#peers = json.loads(client.recv().decode('utf-8'))
print(client.recv())
continue
print("peers from", srv)
for U, val in peers:
print("-", U, val)
all_peers[U] = val
print()
print("All peers:")
for u, val in all_peers.items():
print("-", u, val)
print()
time.sleep(4)
if __name__ == '__main__':
if zmq.zmq_version_info() < (4,0):
raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version()))
if '-v' in sys.argv:
level = logging.DEBUG
else:
level = logging.INFO
logging.basicConfig(level=level, format="[%(levelname)s] %(message)s")
servers = sys.argv[1:]
my_id = str(uuid.uuid4()).encode('utf-8')
my_port = str(random.randint(2000,2020)).encode('utf-8')
while True:
client(servers, my_id, my_port)
#!/usr/bin/env python
"""
Generate client and server CURVE certificate files then move them into the
appropriate store directory, private_keys or public_keys. The certificates
generated by this script are used by the stonehouse and ironhouse examples.
In practice this would be done by hand or some out-of-band process.
Author: Chris Laws
"""
import os
import shutil
import zmq.auth
def generate_certificates(base_dir):
''' Generate client and server CURVE certificate files'''
keys_dir = os.path.join(base_dir, 'certificates')
public_keys_dir = os.path.join(base_dir, 'public_keys')
secret_keys_dir = os.path.join(base_dir, 'private_keys')
# Create directories for certificates, remove old content if necessary
for d in [keys_dir, public_keys_dir, secret_keys_dir]:
if os.path.exists(d):
shutil.rmtree(d)
os.mkdir(d)
# create new keys in certificates dir
server_public_file, server_secret_file = zmq.auth.create_certificates(keys_dir, "server")
client_public_file, client_secret_file = zmq.auth.create_certificates(keys_dir, "client")
# move public keys to appropriate directory
for key_file in os.listdir(keys_dir):
if key_file.endswith(".key"):
shutil.move(os.path.join(keys_dir, key_file),
os.path.join(public_keys_dir, '.'))
# move secret keys to appropriate directory
for key_file in os.listdir(keys_dir):
if key_file.endswith(".key_secret"):
shutil.move(os.path.join(keys_dir, key_file),
os.path.join(secret_keys_dir, '.'))
if __name__ == '__main__':
if zmq.zmq_version_info() < (4,0):
raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version()))
generate_certificates(os.path.dirname(__file__))
#!/usr/bin/env python
import logging
import os
import sys
from collections import namedtuple
import time
import json
import zmq
import zmq.auth
from zmq.auth.thread import ThreadAuthenticator
from zmq.auth.certs import load_certificates
Peer = namedtuple("Peer", "uuid endpoint last_seen")
PEER_TIMEOUT = 10
def clean(data):
new_data = {}
now = time.time()
for peer in data.values():
if now - peer.last_seen < PEER_TIMEOUT:
new_data[peer.uuid] = peer
return new_data
def dump_data(data):
now = time.time()
print()
print("Peer list:")
for uuid, peer in data.items():
print("-",peer, "age is {:.2f}".format(now - peer.last_seen))
print()
def server(bind):
ctx = zmq.Context.instance()
# Start an authenticator for this context.
auth = ThreadAuthenticator(ctx)
auth.start()
auth.allow('127.0.0.1')
# Tell authenticator to use the certificate in a directory
auth.configure_curve(domain='*', location='public_keys')
server = ctx.socket(zmq.XREP)
server_secret_file = os.path.join('private_keys', "server.key_secret")
server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
server.curve_secretkey = server_secret
server.curve_publickey = server_public
server.curve_server = True # must come before bind
server.bind(bind)
data = {}
while True:
#Does not auto reload like zcertstore
trusted_keys = {k.decode('utf-8') for k in load_certificates("public_keys")}
raw = server.recv_multipart(copy=False)
md = {}
for k in 'User-Id', 'Identity', 'Peer-Address':
md[k] = raw[-1].get(k)
#print ("Meta is", md)
if md['User-Id'] not in trusted_keys:
print (md["User-Id"], "does not exist, ignoring")
continue
m = [x.bytes for x in raw]
ident, _, func, *args = m
print("Received", func, args)
if func == b'PUBLISH':
uuid, port = args
uuid = uuid.decode('utf-8')
endpoint = "tcp://{}:{}".format(md['Peer-Address'], port)
peer = Peer(uuid, endpoint, time.time())
data[uuid] = peer
#print("Set", uuid, "to", peer)
resp = b'OK'
if func == b'PEERS':
peers = [(p.uuid, p.endpoint) for p in data.values()]
resp = json.dumps(peers).encode('utf-8')
response = [ident, b'', resp]
server.send_multipart(response)
#cleanup
dump_data(data)
data = clean(data)
if __name__ == "__main__":
if zmq.zmq_version_info() < (4,0):
raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version()))
if '-v' in sys.argv:
level = logging.DEBUG
else:
level = logging.INFO
bind = sys.argv[1]
logging.basicConfig(level=level, format="[%(levelname)s] %(message)s")
server(bind)
#include "czmq_library.h"
#include "zsimpledisco.h"
#include "gateway.h"
int main(int argn, char *argv[])
{
if(argn < 2) {
fprintf(stderr, "Usage: %s tcp://*:9999\n", argv[0]);
exit(1);
}
char* bind = argv[1];
return server_cmd(bind);
}
#include "czmq_library.h"
#include "zsimpledisco.h"
#include "gateway.h"
int server_cmd(char *bind_endpoint)
{
zsimpledisco_t *disco = zsimpledisco_new();
zsimpledisco_verbose(disco);
const char *certstore_path = getenv("PUBLIC_KEY_DIR_PATH");
const char *private_key_path = getenv("PRIVATE_KEY_PATH");
const char *disable_curve = getenv("DISABLE_CURVE");
if(!certstore_path) {
certstore_path = "public_keys";
zsys_info("zsimpledisco: PUBLIC_KEY_DIR_PATH defaulted to '%s'", certstore_path);
}
if(!private_key_path) {
private_key_path = "client.key_secret";
zsys_info("zsimpledisco: PRIVATE_KEY_PATH defaulted to '%s'", private_key_path);
}
if(!disable_curve) {
if(keygen_cmd(private_key_path)) {
zsimpledisco_destroy(&disco);
return 1;
}
zsys_info("zsimpledisco: Enabling curve crypto. Disable using DISABLE_CURVE=1");
zsimpledisco_set_certstore_path(disco, certstore_path);
zsimpledisco_set_private_key_path(disco, private_key_path);
} else {
zsys_info("zsimpledisco: curve crypto disabled using DISABLE_CURVE");
}
zsimpledisco_bind(disco, bind_endpoint);
zpoller_t *poller = zpoller_new (NULL);
zpoller_add(poller, zsimpledisco_socket(disco));
while(1) {
zpoller_wait (poller, 1000);
if(zpoller_terminated(poller))
break;
}
zsimpledisco_destroy(&disco);
return 0;
}
#!/usr/bin/env bash
#ensure ip is in the path
PATH=$PATH:/sbin:/usr/sbin
IP=$(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}')
echo "Using IP Address $IP"
export NO_BEACON_PLZ=1 #hack for now
export ZYRE_BIND="tcp://${IP}:5670"
./gateway keygen || true
echo '##################################################'
cat client.key
echo '##################################################'
echo "Starting in 5 seconds..."
sleep 5
./gateway $(hostname)
This diff is collapsed.
#ifndef __ZSIMPLEDISCO_H_INCLUDED__
#define __ZSIMPLEDISCO_H_INCLUDED__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _zsimpledisco_t zsimpledisco_t;
CZMQ_EXPORT zsimpledisco_t *
zsimpledisco_new();
CZMQ_EXPORT zsock_t *
zsimpledisco_socket (zsimpledisco_t *self);
CZMQ_EXPORT void
zsimpledisco_destroy (zsimpledisco_t **self_p);
CZMQ_EXPORT void
zsimpledisco_actor (zsock_t *pipe, void *unused);
CZMQ_EXPORT void
zsimpledisco_connect(zsimpledisco_t *self, const char *endpoint);
CZMQ_EXPORT void
zsimpledisco_bind(zsimpledisco_t *self, const char *endpoint);
CZMQ_EXPORT void
zsimpledisco_verbose(zsimpledisco_t *self);
CZMQ_EXPORT void
zsimpledisco_publish(zsimpledisco_t *self, const char *key, const char* value);
CZMQ_EXPORT void
zsimpledisco_get_values(zsimpledisco_t *self);
CZMQ_EXPORT int
zsimpledisco_dump_hash(zhash_t *h);
CZMQ_EXPORT int
zsimpledisco_set_certstore_path(zsimpledisco_t *self, const char *certstore_path);
CZMQ_EXPORT int
zsimpledisco_set_private_key_path(zsimpledisco_t *self, const char *private_key_path);
#ifdef __cplusplus
}
#endif
#endif
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