[Cryptech-Commits] [sw/libhal] branch pymux updated: Convert "daemon" mode of C client code to use Python RPC MUX.

git at cryptech.is git at cryptech.is
Wed Jan 4 23:53:54 UTC 2017


This is an automated email from the git hooks/post-receive script.

sra at hactrn.net pushed a commit to branch pymux
in repository sw/libhal.

The following commit(s) were added to refs/heads/pymux by this push:
     new 17366b5  Convert "daemon" mode of C client code to use Python RPC MUX.
17366b5 is described below

commit 17366b5296920cd37f716426fd7c653063dd5d78
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Wed Jan 4 18:52:51 2017 -0500

    Convert "daemon" mode of C client code to use Python RPC MUX.
---
 Makefile            |  13 +--
 cryptech_rpcmuxd    |   0
 daemon.c            | 330 ----------------------------------------------------
 hal_internal.h      |   2 +-
 rpc_client_daemon.c |  41 +++++--
 5 files changed, 34 insertions(+), 352 deletions(-)

diff --git a/Makefile b/Makefile
index c0a136b..1e7316a 100644
--- a/Makefile
+++ b/Makefile
@@ -144,16 +144,12 @@ endif
 # the C preprocessor: we can use symbolic names so long as they're defined as macros
 # in the C code, but we can't use things like C enum symbols.
 
-ifneq "${RPC_MODE}" "server"
-  OBJ += rpc_serial.o
-endif
-
 RPC_CLIENT_OBJ = rpc_client.o
 
 ifeq "${RPC_TRANSPORT}" "loopback"
   RPC_CLIENT_OBJ += rpc_client_loopback.o
 else ifeq "${RPC_TRANSPORT}" "serial"
-  RPC_CLIENT_OBJ += rpc_client_serial.o
+  RPC_CLIENT_OBJ += rpc_serial.o rpc_client_serial.o
 else ifeq "${RPC_TRANSPORT}" "daemon"
   RPC_CLIENT_OBJ += rpc_client_daemon.o
 endif
@@ -225,13 +221,10 @@ server:
 serial:
 	${MAKE} RPC_MODE=client-mixed RPC_TRANSPORT=serial
 
-daemon: mixed cryptech_rpcd
+daemon: mixed
 
 .PHONY: client mixed server serial daemon
 
-cryptech_rpcd: daemon.o ${LIB}
-	${CC} ${CFLAGS} -o $@ $^ ${LDFLAGS}
-
 ${OBJ}: ${INC}
 
 ${LIB}: ${OBJ}
@@ -251,7 +244,7 @@ test: all
 	cd tests; ${MAKE} -k $@
 
 clean:
-	rm -f *.o ${LIB} cryptech_rpcd
+	rm -f *.o ${LIB}
 	cd tests; ${MAKE} $@
 	cd utils; ${MAKE} $@
 
diff --git a/cryptech_rpcmuxd b/cryptech_rpcmuxd
old mode 100644
new mode 100755
diff --git a/daemon.c b/daemon.c
deleted file mode 100644
index ff95353..0000000
--- a/daemon.c
+++ /dev/null
@@ -1,330 +0,0 @@
-#define DEBUG
-/*
- * daemon.c
- * --------
- * A daemon to arbitrate shared access to a serial connection to the HSM.
- *
- * Copyright (c) 2016, NORDUnet A/S All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * - Redistributions of source code must retain the above copyright notice,
- *   this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of the NORDUnet nor the names of its contributors may
- *   be used to endorse or promote products derived from this software
- *   without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <poll.h>
-#include <getopt.h>             /* required with -std=c99 */
-#include <termios.h>            /* for default speed */
-
-#include "hal_internal.h"
-#include "slip_internal.h"
-#include "xdr_internal.h"
-
-static char usage[] =
-    "usage: %s [-n socketname] [-d ttydevice] [-s ttyspeed]\n";
-
-/*
- * Work around glibc "feature test" insanity.  This isn't the correct
- * definition according to the POSIX, but it does what seems to be the
- * normal hack on Linux (where this is broken more often than not).
- */
-
-#ifndef SUN_LEN
-#define SUN_LEN(_sun_ptr_)  (sizeof(*(_sun_ptr_)))
-#endif
-
-/* select() is hopelessly broken, and epoll() is Linux-specific, so we'll use
- * poll() until such a time as libevent or libev seems more appropriate.
- * Unfortunately, poll() doesn't come with any macros or functions to manage
- * the pollfd array, so we have to invent them.
- */
-
-static struct pollfd *pollfds = NULL;
-static nfds_t nfds = 0;
-static nfds_t npollfds = 0;
-
-static void poll_add(int fd)
-{
-    /* add 4 entries at a time to avoid having to realloc too often */
-#define NNEW 4
-
-    /* expand the array if necessary */
-    if (nfds == npollfds) {
-        npollfds = nfds + NNEW;
-        pollfds = realloc(pollfds, npollfds * sizeof(struct pollfd));
-        if (pollfds == NULL) {
-            perror("realloc");
-            exit(EXIT_FAILURE);
-        }
-        /* zero the new entries for hygiene */
-        memset(&pollfds[nfds], 0, NNEW * sizeof(struct pollfd));
-    }
-
-    /* populate the new entry */
-    pollfds[nfds].fd = fd;
-    pollfds[nfds].events = POLLIN;
-    ++nfds;
-}
-
-static void poll_remove(int fd)
-{
-    nfds_t i;
-
-    /* search the pollfd array */
-    for (i = 0; i < nfds; ++i) {
-        if (pollfds[i].fd == fd) {
-            /* shift remainder of the array left by one */
-            memmove(&pollfds[i], &pollfds[i + 1], (nfds - i - 1) * sizeof(struct pollfd));
-            /* zero the last entry for hygiene */
-            memset(&pollfds[nfds - 1], 0, sizeof(struct pollfd));
-            --nfds;
-            return;
-        }
-    }
-    /* if it's not found, return without an error */
-}
-
-typedef struct {
-    size_t len;
-    uint8_t buf[HAL_RPC_MAX_PKT_SIZE];
-} rpc_buffer_t;
-static rpc_buffer_t ibuf, obuf;
-
-const char *socket_name = HAL_CLIENT_DAEMON_DEFAULT_SOCKET_NAME;
-
-/* Set up an atexit handler to remove the filesystem entry for the unix domain
- * socket. This will trigger on error exits, but not on the "normal" SIGKILL.
- */
-void atexit_cleanup(void)
-{
-    unlink(socket_name);
-}
-
-#ifdef DEBUG
-static void hexdump(uint8_t *buf, uint32_t len)
-{
-    for (uint32_t i = 0; i < len; ++i)
-        printf("%02x%c", buf[i], ((i & 0x07) == 0x07) ? '\n' : ' ');
-    if ((len & 0x07) != 0)
-        printf("\n");
-}
-#endif
-
-int main(int argc, char *argv[])
-{
-    struct sockaddr_un name;
-    int ret;
-    int lsock;
-    int dsock;
-    int opt;
-    const char *device = getenv(HAL_CLIENT_SERIAL_DEVICE_ENVVAR);
-    const char *speed_ = getenv(HAL_CLIENT_SERIAL_SPEED_ENVVAR);
-    uint32_t    speed  = HAL_CLIENT_SERIAL_DEFAULT_SPEED;
-
-    if (device == NULL)
-        device = HAL_CLIENT_SERIAL_DEFAULT_DEVICE;
-
-    if (speed_ != NULL)
-        speed = (uint32_t) strtoul(speed_, NULL, 10);
-
-    while ((opt = getopt(argc, argv, "hn:d:s:")) != -1) {
-        switch (opt) {
-        case 'h':
-            printf(usage, argv[0]);
-            exit(EXIT_SUCCESS);
-        case 'n':
-            socket_name = optarg;
-            break;
-        case 'd':
-            device = optarg;
-            break;
-        case 's':
-	    speed = (uint32_t) strtoul(optarg, NULL, 10);
-            switch (speed) {
-            case 115200:
-            case 921600:
-                break;
-            default:
-                printf("invalid speed value %s\n", optarg);
-                exit(EXIT_FAILURE);
-            }
-            break;
-        default:
-            printf(usage, argv[0]);
-            exit(EXIT_FAILURE);
-        }
-    }
-
-    if (atexit(atexit_cleanup) != 0) {
-        perror("atexit");
-        exit(EXIT_FAILURE);
-    }
-
-    if (hal_serial_init(device, speed) != HAL_OK)
-        exit(EXIT_FAILURE);
-
-    int serial_fd = hal_serial_get_fd();
-    poll_add(serial_fd);
-
-    /* Remove the filesystem entry for the unix domain socket. The usual way
-     * to stop a daemon is SIGKILL, which we can't catch, so the file remains,
-     * and will prevent us from binding the socket.
-     *
-     * XXX We should also scan the process table, to make sure the daemon
-     * isn't already running.
-     */
-    unlink(socket_name);
-
-    /* Create the listening socket.
-     */
-    lsock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-    if (lsock == -1) {
-        perror("socket");
-        exit(EXIT_FAILURE);
-    }
-    poll_add(lsock);
-
-    /* For portability, clear the whole address structure, since some
-     * implementations have additional (nonstandard) fields in the structure.
-     */
-    memset(&name, 0, sizeof(struct sockaddr_un));
-
-    /* Bind the listening socket.  On some platforms, we have to pass the "real"
-     * (number of bytes in use) length of the sockaddr_un to get the name bound
-     * correctly, so use the SUN_LEN() macro to calculate that.
-     */
-    name.sun_family = AF_UNIX;
-    strncpy(name.sun_path, socket_name, sizeof(name.sun_path) - 1);
-    ret = bind(lsock, (const struct sockaddr *) &name, SUN_LEN(&name));
-    if (ret == -1) {
-        perror("bind");
-        exit(EXIT_FAILURE);
-    }
-
-    /* Prepare to accept connections.
-     */
-    ret = listen(lsock, 20);
-    if (ret == -1) {
-        perror("listen");
-        exit(EXIT_FAILURE);
-    }
-
-    /* The main loop.
-     */
-    for (;;) {
-
-        /* Blocking poll on all descriptors of interest.
-         */
-        ret = poll(pollfds, nfds, -1);
-        if (ret == -1) {
-            perror("poll");
-            exit(EXIT_FAILURE);
-        }
-
-        for (nfds_t i = 0; i < nfds; ++i) {
-            if (pollfds[i].revents != 0) {
-                /* XXX POLLERR|POLLHUP|POLLNVAL */
-
-                /* serial port */
-                if (pollfds[i].fd == serial_fd) {
-		    int complete;
-                    hal_slip_recv_char(ibuf.buf, &ibuf.len, sizeof(ibuf.buf), &complete);
-                    if (complete) {
-#ifdef DEBUG
-                        printf("serial port received response:\n");
-                        hexdump(ibuf.buf, ibuf.len);
-#endif
-                        /* We've got a complete rpc response packet. */
-                        const uint8_t *bufptr = ibuf.buf + 4;
-                        const uint8_t * const limit = ibuf.buf + ibuf.len;
-                        uint32_t sock;
-                        /* Second word of the response is the client ID. */
-                        hal_xdr_decode_int(&bufptr, limit, &sock);
-                        /* Pass response on to the client that requested it. */
-                        send(sock, ibuf.buf, ibuf.len, 0);
-                        /* Reinitialize the receive buffer. */
-                        memset(&ibuf, 0, sizeof(ibuf));
-                    }
-                }
-
-                /* listening socket */
-                else if (pollfds[i].fd == lsock) {
-                    /* Accept incoming connection. */
-                    dsock = accept(lsock, NULL, NULL);
-                    if (ret == -1) {
-                        perror("accept");
-                        exit(EXIT_FAILURE);
-                    }
-                    poll_add(dsock);
-#ifdef DEBUG
-                    printf("listening socket accept data socket %d\n", dsock);
-#endif
-                }
-
-                /* client data socket */
-                else {
-                    const uint8_t * const limit = obuf.buf + HAL_RPC_MAX_PKT_SIZE;
-                    /* Get the client's rpc request packet. */
-                    obuf.len = recv(pollfds[i].fd, obuf.buf, HAL_RPC_MAX_PKT_SIZE, 0);
-#ifdef DEBUG
-                    printf("data socket %d received request:\n", pollfds[i].fd);
-                    hexdump(obuf.buf, obuf.len);
-#endif
-
-		    /* Fill in the client handle arg - first field after opcode. */
-                    uint8_t *bufptr = obuf.buf + 4;
-                    hal_xdr_encode_int(&bufptr, limit, pollfds[i].fd);
-
-                    if (obuf.len > 0) {
-#ifdef DEBUG
-                        printf("passing to serial port:\n");
-                        hexdump(obuf.buf, obuf.len);
-#endif
-                        /* Pass it on to the serial port. */
-                        hal_slip_send(obuf.buf, obuf.len);
-                    }
-                    else {
-#ifdef DEBUG
-                        printf("closing data socket\n");
-#endif
-                        /* Client has closed the socket. */
-                        close(pollfds[i].fd);
-                        poll_remove(pollfds[i].fd);
-                    }
-                    /* Reinitialize the transmit buffer. */
-                    memset(&obuf, 0, sizeof(obuf));
-                }
-            }
-        }
-    }
-
-    /*NOTREACHED*/
-    exit(EXIT_SUCCESS);
-}
diff --git a/hal_internal.h b/hal_internal.h
index a8f88e2..ef3dd49 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -880,7 +880,7 @@ typedef enum {
  */
 
 #ifndef HAL_CLIENT_DAEMON_DEFAULT_SOCKET_NAME
-#define HAL_CLIENT_DAEMON_DEFAULT_SOCKET_NAME   "/tmp/cryptech_rpcd.socket"
+#define HAL_CLIENT_DAEMON_DEFAULT_SOCKET_NAME   "/tmp/.cryptech_rpcmuxd"
 #endif
 
 /*
diff --git a/rpc_client_daemon.c b/rpc_client_daemon.c
index dea352f..7ff3f21 100644
--- a/rpc_client_daemon.c
+++ b/rpc_client_daemon.c
@@ -45,17 +45,18 @@ static int sock = -1;
 
 hal_error_t hal_rpc_client_transport_init(void)
 {
+    const char *sockname = getenv("CRYPTECH_RPC_CLIENT_SOCKET_NAME");
     struct sockaddr_un name;
-    int ret;
 
-    sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+    sock = socket(AF_UNIX, SOCK_STREAM, 0);
     if (sock == -1)
         return perror("socket"), HAL_ERROR_RPC_TRANSPORT;
+    if (sockname == NULL)
+        sockname = HAL_CLIENT_DAEMON_DEFAULT_SOCKET_NAME;
     memset(&name, 0, sizeof(struct sockaddr_un));
     name.sun_family = AF_UNIX;
-    strncpy(name.sun_path, HAL_CLIENT_DAEMON_DEFAULT_SOCKET_NAME, sizeof(name.sun_path) - 1);
-    ret = connect(sock, (const struct sockaddr *) &name, sizeof(struct sockaddr_un));
-    if (ret == -1)
+    strncpy(name.sun_path, sockname, sizeof(name.sun_path) - 1);
+    if (connect(sock, (const struct sockaddr *) &name, sizeof(struct sockaddr_un)) < 0)
         return perror("connect"), HAL_ERROR_RPC_TRANSPORT;
     return HAL_OK;
 }
@@ -69,17 +70,35 @@ hal_error_t hal_rpc_client_transport_close(void)
     return HAL_OK;
 }
 
+
 hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len)
 {
-    ssize_t ret = send(sock, (const void *)buf, len, 0);
-    return (ret == -1) ? HAL_ERROR_RPC_TRANSPORT : HAL_OK;
+    return hal_slip_send(buf, len);
 }
 
 hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len)
 {
-    ssize_t ret = recv(sock, (void *)buf, *len, 0);
-    if (ret == -1)
-	return HAL_ERROR_RPC_TRANSPORT;
-    *len = (size_t)ret;
+    size_t maxlen = *len;
+    *len = 0;
+    hal_error_t err = hal_slip_recv(buf, len, maxlen);
+    return err;
+}
+
+/*
+ * These two are sort of mis-named, fix eventually, but this is what
+ * the code in slip.c expects.
+ */
+
+hal_error_t hal_serial_send_char(const uint8_t c)
+{
+    if (write(sock, &c, 1) != 1)
+	return perror("write"), HAL_ERROR_RPC_TRANSPORT;
+    return HAL_OK;
+}
+
+hal_error_t hal_serial_recv_char(uint8_t * const c)
+{
+    if (read(sock, c, 1) != 1)
+	return perror("read"), HAL_ERROR_RPC_TRANSPORT;
     return HAL_OK;
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Commits mailing list