diff options
Diffstat (limited to 'sunrpc/key_call.c')
-rw-r--r-- | sunrpc/key_call.c | 87 |
1 files changed, 84 insertions, 3 deletions
diff --git a/sunrpc/key_call.c b/sunrpc/key_call.c index 0219eaf..0aa49cc 100644 --- a/sunrpc/key_call.c +++ b/sunrpc/key_call.c @@ -32,8 +32,8 @@ /* * The original source is from the RPCSRC 4.0 package from Sun Microsystems. - * The Interface to keyserver protocoll 2 was added by - * Thorsten Kukuk <kukuk@vt.uni-paderborn.de> + * The Interface to keyserver protocoll 2, RPC over AF_UNIX und Linux/doors + * was added by Thorsten Kukuk <kukuk@vt.uni-paderborn.de> */ #include <stdio.h> @@ -50,6 +50,10 @@ #include <rpc/key_prot.h> #include <bits/libc-lock.h> +#ifdef HAVE_DOORS +# include "door/door.h" +#endif + #define KEY_TIMEOUT 5 /* per-try timeout in seconds */ #define KEY_NRETRY 12 /* number of retries */ @@ -479,13 +483,82 @@ key_call_socket (u_long proc, xdrproc_t xdr_arg, char *arg, return result; } -/* returns 0 on failure, 1 on success */ +#ifdef HAVE_DOORS +/* returns 0 on failure, 1 on success */ +static int +internal_function +key_call_door (u_long proc, xdrproc_t xdr_arg, char *arg, + xdrproc_t xdr_rslt, char *rslt) +{ + XDR xdrs; + int fd; + door_arg_t args; + char *data_ptr; + u_long data_len = 0; + char res[255]; + + if ((fd = open("/var/run/keyservdoor", O_RDONLY)) < 0) + return 0; + res[0] = 0; + + data_len = xdr_sizeof (xdr_arg, arg); + data_ptr = calloc (1, data_len + 2 * sizeof (u_long)); + if (data_ptr == NULL) + return 0; + + xdrmem_create (&xdrs, &data_ptr[2 * sizeof (u_long)], data_len, XDR_ENCODE); + if (!xdr_arg (&xdrs, arg)) + { + xdr_destroy (&xdrs); + free (data_ptr); + return 0; + } + xdr_destroy (&xdrs); + + memcpy (data_ptr, &proc, sizeof (u_long)); + memcpy (&data_ptr[sizeof (proc)], &data_len, sizeof (u_long)); + + args.data_ptr = data_ptr; + args.data_size = data_len + 2 * sizeof (u_long); + args.desc_ptr = NULL; + args.desc_num = 0; + args.rbuf = res; + args.rsize = sizeof (res); + + if (__door_call (fd, &args) < 0) + return 0; + + free (data_ptr); + close (fd); + + memcpy (&data_len, args.data_ptr, sizeof (u_long)); + if (data_len != 0) + return 0; + + memcpy (&data_len, &args.data_ptr[sizeof (u_long)], sizeof (u_long)); + xdrmem_create (&xdrs, &args.data_ptr[2 * sizeof (u_long)], + data_len, XDR_DECODE); + if (!xdr_rslt (&xdrs, rslt)) + { + xdr_destroy (&xdrs); + return 0; + } + xdr_destroy (&xdrs); + + return 1; +} +#endif + +/* returns 0 on failure, 1 on success */ static int internal_function key_call (u_long proc, xdrproc_t xdr_arg, char *arg, xdrproc_t xdr_rslt, char *rslt) { static int use_keyenvoy = 0; +#ifdef HAVE_DOORS + static int use_doors = 1; +#endif if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) { @@ -509,6 +582,14 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg, return 1; } +#ifdef HAVE_DOORS + if (use_doors) + { + if (key_call_door (proc, xdr_arg, arg, xdr_rslt, rslt)) + return 1; + use_doors = 0; + } +#endif if (!use_keyenvoy) { if (key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt)) |