It is sometimes useful to support Unix domain sockets on Windows. To do this in a portable way, Assuan provides a set of wrapper functions which may be used on any system but will enhance Windows to support these socket types. The actual implementation is based on local TCP sockets and fully transparent for the client. Server code needs to utilize two extra functions to check the permissions.
gpg_error_t assuan_sock_init (void) ¶Initialize the socket wrappers. Must be called once at startup if any of the socket wrapper functions are used.
gpg_error_t assuan_sock_deinit (void) ¶Deinitialize the socket wrappers.
int assuan_sock_close (assuan_fd_t fd) ¶Wrapper for close which does a closesocket on Windows if needed.
assuan_fd_t assuan_sock_new (int domain, int type, int proto); ¶Wrapper around socket.
assuan_fd_t assuan_sock_accept (assuan_fd_t sockfd, struct sockaddr *addr, socklen_t *p_addrlen) ¶Wrapper around accept.
int assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen) ¶Wrapper around connect. For Unix domain sockets under Windows this
function also does a write immediately after the the connect to send the
nonce as read from the socket’s file. Under Unix this function check
whether the socket file is a redirection file and connects to the
redirected socket instead; see assuan_sock_set_sockaddr_un for
details on the redirection file format.
int assuan_sock_connect_byname (const char * host, unsigned short port, int timeout, const char *credentials, unsigned int flags) ¶Directly connect to port on host given as a name. The
current implementation requires that flags has either
ASSUAN_SOCK_SOCKS or ASSUAN_SOCK_TOR set. On success a
new TCP STREAM socket is returned; on error ASSUAN_INVALID_FD
and ERRNO set. If credentials is not NULL, it is a
string used for password based SOCKS authentication. Username and
password are separated by a colon. timeout specifies timeout
value (in miliseconds) for the connection. timeout with zero
means no timeout (for client side, the SOCKS server may timeout).
timeout with -1 means no wait. To test whether the proxy is
available host and port may be given as NULL/0: If the
proxy is available the function returns a valid socket which is in the
state after credentials sub-negotiation. The caller now knows that
the SOCKS proxy is available and has been authenticated; normally the
caller closes the socket then.
int assuan_sock_bind ( assuan_fd_t sockfd, struct sockaddr *addr, int addrlen) ¶Wrapper around bind. Under Windows this creates a file and writes the port number and a random nonce to this file.
int assuan_sock_set_sockaddr_un ( const char *fname, struct sockaddr *addr, int *r_redirected) ¶This is a helper function to initialize the Unix socket domain address structure addr and store the file name fname there. If r_redirected is not NULL the function checks whether fname already exists, is a regular file, and not a socket. In that case fname is read to see whether this is a redirection to a socket file. If that is the case 1 is stored at r_redirected. If the file does not look like a redirection file 0 will be stored there and fname will be used in the regular way.
The format of a redirection file is
%Assuan% socket=name
With name being is the actual socket to use. No white spaces
are allowed, both lines must be terminated by a single linefeed, and
extra lines are not allowed. Environment variables are interpreted in
name if given in ${VAR} notation. No escape characters
are defined; if the string ${ shall be used in file name, an
environment variable with that content may be used. The length of the
redirection file is limited to 511 bytes which is more than sufficient
for any known implementation of Unix domain sockets.
int assuan_sock_get_nonce ( struct sockaddr *addr, int addrlen, assuan_sock_nonce_t *nonce) ¶This is used by the server after a bind to return the random nonce. To keep the code readable this may also be used on POSIX system.
int assuan_sock_check_nonce ( assuan_fd_t fd, assuan_sock_nonce_t *nonce) ¶If the option ASSUAN_SOCKET_SERVER_ACCEPTED has been used,
Libassuan has no way to check the nonce of the server. Thus an explicit
check of the saved nonce using this function is required. If this
function fails the server should immediately drop the connection. This
function may not be used if Libassuan does the accept call itself
(i.e., ASSUAN_SOCKET_SERVER_ACCEPTED has not been used) because
in this case Libassuan calls this function internally. See also
assuan_set_sock_nonce.
Actually this mechanism is only required on Windows but for cleanness of code it may be used on POSIX systems as well, where this function is a nop.
To control certain properties of the wrapper two additional functions are provided:
int assuan_sock_set_flag ( assuan_fd_t fd, const char *name, int value) ¶Set the flags name for socket fd to value. See below for a list of valid names. Returns 0 on success; on failure sets ERRNO and returns -1.
int assuan_sock_get_flag ( assuan_fd_t fd, const char *name, int *r_value) ¶Store the current value of the flag name for socket fd at r_value. See below for a list of valid names. Returns 0 on success; on failure sets ERRNO and returns -1.
The supported flags are:
cygwinThis flag has an effect only on Windows. If the value is 1, the socket is set into Cygwin mode so that Cygwin clients can connect to such a socket. This flag needs to be set before a bind and should not be changed during the lifetime of the socket. There is no need to set this flag for connecting to a Cygwin style socket because no state is required at the client. On non-Windows platforms setting this flag is ignored, reading the flag always returns a value of 0.
tor-modesocksIf value is 1 globally enable SOCKS5 mode for new connections
using IPv6 or IPv4. fd must be set to ASSUAN_INVALID_FD A
future extension may allow to disable SOCKS5 mode for a specified
socket but globally disabling SOCKS5 mode is not possible. Using the
flag “tor-mode” expects the SOCKS5 proxy to listen on port 9050, the
flag “socks” expects the proxy to listen on port 1080.
Connections to the loopback address are not routed though the SOCKS proxy. UDP requests are not supported at all. The proxy will be connected at address 127.0.0.1; an IPv6 connection to the proxy is not yet supported.