diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-08-24 14:41:49 +0200 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2017-02-16 16:56:40 +0100 |
commit | 89fa381ce5573a925b90da973cd8956937d79caa (patch) | |
tree | 83322f09eaba0267cb5a5490f6b3c8a420f48358 /p11-kit/rpc-transport.c | |
parent | 3bab48000c4e61104b30ac379806cad3e1376ea6 (diff) |
rpc: New rpc_unix transport based on Unix socket
Diffstat (limited to 'p11-kit/rpc-transport.c')
-rw-r--r-- | p11-kit/rpc-transport.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/p11-kit/rpc-transport.c b/p11-kit/rpc-transport.c index 5902157..d8f0cda 100644 --- a/p11-kit/rpc-transport.c +++ b/p11-kit/rpc-transport.c @@ -44,6 +44,7 @@ #include "private.h" #include "rpc.h" #include "rpc-message.h" +#include "path.h" #include <sys/types.h> @@ -1043,6 +1044,84 @@ rpc_exec_init (const char *remote, return &rex->base; } +#ifdef OS_UNIX + +typedef struct { + p11_rpc_transport base; + struct sockaddr_un sa; +} rpc_unix; + +static CK_RV +rpc_unix_connect (p11_rpc_client_vtable *vtable, + void *init_reserved) +{ + rpc_unix *run = (rpc_unix *)vtable; + int fd; + + fd = socket (AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + p11_message_err (errno, "failed to create socket for remote"); + return CKR_GENERAL_ERROR; + } + + if (connect (fd, (struct sockaddr *)&run->sa, sizeof (run->sa)) < 0) { + p11_message_err (errno, "failed to connect to socket"); + close (fd); + return CKR_DEVICE_REMOVED; + } + + run->base.socket = rpc_socket_new (fd); + return_val_if_fail (run->base.socket != NULL, CKR_GENERAL_ERROR); + + return CKR_OK; +} + +static void +rpc_unix_disconnect (p11_rpc_client_vtable *vtable, + void *fini_reserved) +{ + rpc_unix *run = (rpc_unix *)vtable; + + if (run->base.socket) + rpc_socket_close (run->base.socket); + + /* Do the common disconnect stuff */ + rpc_transport_disconnect (vtable, fini_reserved); +} + +static void +rpc_unix_free (void *data) +{ + rpc_unix *run = data; + rpc_unix_disconnect (data, NULL); + rpc_transport_uninit (&run->base); + free (run); +} + +static p11_rpc_transport * +rpc_unix_init (const char *remote, + const char *name) +{ + rpc_unix *run; + + run = calloc (1, sizeof (rpc_unix)); + return_val_if_fail (run != NULL, NULL); + + memset (&run->sa, 0, sizeof (run->sa)); + run->sa.sun_family = AF_UNIX; + snprintf (run->sa.sun_path, sizeof (run->sa.sun_path), "%s", remote); + + run->base.vtable.connect = rpc_unix_connect; + run->base.vtable.disconnect = rpc_unix_disconnect; + run->base.vtable.transport = rpc_transport_buffer; + rpc_transport_init (&run->base, name, rpc_unix_free); + + p11_debug ("initialized rpc socket: %s", remote); + return &run->base; +} + +#endif /* OS_UNIX */ + p11_rpc_transport * p11_rpc_transport_new (p11_virtual *virt, const char *remote, @@ -1058,6 +1137,16 @@ p11_rpc_transport_new (p11_virtual *virt, if (remote[0] == '|') { rpc = rpc_exec_init (remote + 1, name); +#ifdef OS_UNIX + } else if (strncmp (remote, "unix:path=/", 11) == 0) { + /* Only absolute path is supported */ + char *path; + + path = p11_path_decode (remote + 10); + return_val_if_fail (path != NULL, NULL); + rpc = rpc_unix_init (path, name); + free (path); +#endif /* OS_UNIX */ } else { p11_message ("remote not supported: %s", remote); return NULL; |