diff --git a/gck-rpc-daemon-standalone.c b/gck-rpc-daemon-standalone.c index 7b60ad9eb97b88bb7aa4922adc055c95691b57c6..7214bb078eb5f56d12a6d5345b2a72abdfeabcc9 100644 --- a/gck-rpc-daemon-standalone.c +++ b/gck-rpc-daemon-standalone.c @@ -58,7 +58,7 @@ static int is_running = 1; static int usage(void) { - fprintf(stderr, "usage: gck-rpc-daemon pkcs11-module\n"); + fprintf(stderr, "usage: pkcs11-daemon pkcs11-module [<socket>|\"-\"]\n\tUsing \"-\" results in a single-thread inetd-type daemon\n"); exit(2); } @@ -73,7 +73,7 @@ int main(int argc, char *argv[]) CK_RV rv; /* The module to load is the argument */ - if (argc != 2) + if (argc != 2 || argc != 3) usage(); /* Load the library */ @@ -113,15 +113,20 @@ int main(int argc, char *argv[]) } path = getenv("PKCS11_DAEMON_SOCKET"); - if (!path) - path = SOCKET_PATH; - - sock = gck_rpc_layer_initialize(path, funcs); - if (sock == -1) - exit(1); - - is_running = 1; - while (is_running) { + if (!path && argc == 3) + path = argv[2]; + if (!path) + path = SOCKET_PATH; + + if (strcmp(path,"-") == 0) { + gck_rpc_layer_inetd(); + } else { + sock = gck_rpc_layer_initialize(path, funcs); + if (sock == -1) + exit(1); + + is_running = 1; + while (is_running) { FD_ZERO(&read_fds); FD_SET(sock, &read_fds); ret = select(sock + 1, &read_fds, NULL, NULL, NULL); @@ -135,9 +140,10 @@ int main(int argc, char *argv[]) if (FD_ISSET(sock, &read_fds)) gck_rpc_layer_accept(); - } + } - gck_rpc_layer_uninitialize(); + gck_rpc_layer_uninitialize(); + } rv = (funcs->C_Finalize) (NULL); if (rv != CKR_OK) diff --git a/gck-rpc-dispatch.c b/gck-rpc-dispatch.c index e1f3bd1b64ff5ed51235eec931333d96a138228e..de6f55886e34dd2cc09a3c4dbc03fb0c5a276435 100644 --- a/gck-rpc-dispatch.c +++ b/gck-rpc-dispatch.c @@ -63,6 +63,8 @@ typedef struct _CallState { uint64_t appid; int call; int sock; + int (*read)(int, unsigned char *,size_t); + int (*write)(int, unsigned char *,size_t); } CallState; typedef struct _DispatchState { @@ -2097,7 +2099,7 @@ static void run_dispatch_loop(CallState *cs) assert(cs->sock != -1); /* The client application */ - if (!read_all(cs->sock, (unsigned char *)&cs->appid, sizeof (cs->appid))) { + if (!cs->read(cs->sock, (unsigned char *)&cs->appid, sizeof (cs->appid))) { gck_rpc_warn("Can't read appid\n"); return ; } @@ -2116,7 +2118,7 @@ static void run_dispatch_loop(CallState *cs) call_reset(cs); /* Read the number of bytes ... */ - if (!read_all(cs->sock, buf, 4)) + if (!cs->read(cs->sock, buf, 4)) break; /* Calculate the number of bytes */ @@ -2135,7 +2137,7 @@ static void run_dispatch_loop(CallState *cs) } /* ... and read/parse in the actual message */ - if (!read_all(cs->sock, cs->req->buffer.buf, len)) + if (!cs->read(cs->sock, cs->req->buffer.buf, len)) break; egg_buffer_add_empty(&cs->req->buffer, len); @@ -2149,8 +2151,8 @@ static void run_dispatch_loop(CallState *cs) /* .. send back response length, and then response data */ egg_buffer_encode_uint32(buf, cs->resp->buffer.len); - if (!write_all(cs->sock, buf, 4) || - !write_all(cs->sock, cs->resp->buffer.buf, cs->resp->buffer.len)) + if (!cs->write(cs->sock, buf, 4) || + !cs->write(cs->sock, cs->resp->buffer.buf, cs->resp->buffer.len)) break; } @@ -2221,6 +2223,8 @@ void gck_rpc_layer_accept(void) ds->socket = new_fd; ds->cs.sock = new_fd; + ds->cs.read = &read_all; + ds->cs.write = &write_all; error = pthread_create(&ds->thread, NULL, run_dispatch_thread, &(ds->cs)); @@ -2236,6 +2240,18 @@ void gck_rpc_layer_accept(void) pthread_mutex_unlock(&pkcs11_dispatchers_mutex); } +void gck_rpc_layer_inetd(void) +{ + CallState cs; + + memset(&cs, 0, sizeof(cs)); + cs.sock = STDIN_FILENO; + cs.read = &read; + cs.write = &write; + + run_dispatch_thread(&cs); +} + int gck_rpc_layer_initialize(const char *prefix, CK_FUNCTION_LIST_PTR module) { struct sockaddr_un addr; diff --git a/gck-rpc-layer.h b/gck-rpc-layer.h index 8a6318fe34b19a39de5b9ef1cf33f79ab5050aed..be6cdeb0c2e8c26692282d2b9c7e5c217971c7a0 100644 --- a/gck-rpc-layer.h +++ b/gck-rpc-layer.h @@ -16,4 +16,7 @@ void gck_rpc_layer_uninitialize(void); /* Accept a new connection. Should be called when above fd has read */ void gck_rpc_layer_accept(void); +/* Run a single connection off of STDIN - call from inetd or stunnel */ +void gck_rpc_layer_inetd(void); + #endif /* GCKRPC_LAYER_H_ */