Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20064948
assuan-socket.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
18 KB
Subscribers
None
assuan-socket.c
View Options
/* assuan-socket.c
Copyright (C) 2004, 2005, 2009 Free Software Foundation, Inc.
This file is part of Assuan.
Assuan is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
Assuan is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include
<config.h>
#endif
#include
<stdio.h>
#include
<stdlib.h>
#ifdef HAVE_W32_SYSTEM
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <wincrypt.h>
#ifndef HAVE_W32CE_SYSTEM
# include <io.h>
#endif
#else
# include <sys/types.h>
# include <sys/socket.h>
#endif
#include
<errno.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include
<fcntl.h>
#endif
#include
<assert.h>
#include
"assuan-defs.h"
#include
"debug.h"
/* Hacks for Slowaris. */
#ifndef PF_LOCAL
# ifdef PF_UNIX
# define PF_LOCAL PF_UNIX
# else
# define PF_LOCAL AF_UNIX
# endif
#endif
#ifndef AF_LOCAL
# define AF_LOCAL AF_UNIX
#endif
#ifdef HAVE_W32_SYSTEM
#ifndef S_IRUSR
# define S_IRUSR 0
# define S_IWUSR 0
#endif
#ifndef S_IRGRP
# define S_IRGRP 0
# define S_IWGRP 0
#endif
#endif
#ifndef ENAMETOOLONG
# define ENAMETOOLONG EINVAL
#endif
#ifndef SUN_LEN
# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
+ strlen ((ptr)->sun_path))
#endif
#ifdef HAVE_W32_SYSTEM
#ifdef HAVE_W32CE_SYSTEM
static
wchar_t
*
utf8_to_wchar
(
const
char
*
string
)
{
int
n
;
size_t
nbytes
;
wchar_t
*
result
;
if
(
!
string
)
return
NULL
;
n
=
MultiByteToWideChar
(
CP_UTF8
,
0
,
string
,
-1
,
NULL
,
0
);
if
(
n
<
0
)
return
NULL
;
nbytes
=
(
size_t
)(
n
+
1
)
*
sizeof
(
*
result
);
if
(
nbytes
/
sizeof
(
*
result
)
!=
(
n
+
1
))
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
NULL
;
}
result
=
malloc
(
nbytes
);
if
(
!
result
)
return
NULL
;
n
=
MultiByteToWideChar
(
CP_UTF8
,
0
,
string
,
-1
,
result
,
n
);
if
(
n
<
0
)
{
n
=
GetLastError
();
free
(
result
);
result
=
NULL
;
SetLastError
(
n
);
}
return
result
;
}
static
HANDLE
MyCreateFile
(
LPCSTR
lpFileName
,
DWORD
dwDesiredAccess
,
DWORD
dwSharedMode
,
LPSECURITY_ATTRIBUTES
lpSecurityAttributes
,
DWORD
dwCreationDisposition
,
DWORD
dwFlagsAndAttributes
,
HANDLE
hTemplateFile
)
{
wchar_t
*
filename
;
HANDLE
result
;
int
err
;
filename
=
utf8_to_wchar
(
lpFileName
);
if
(
!
filename
)
return
INVALID_HANDLE_VALUE
;
result
=
CreateFileW
(
filename
,
dwDesiredAccess
,
dwSharedMode
,
lpSecurityAttributes
,
dwCreationDisposition
,
dwFlagsAndAttributes
,
hTemplateFile
);
err
=
GetLastError
();
free
(
filename
);
SetLastError
(
err
);
return
result
;
}
static
int
MyDeleteFile
(
LPCSTR
lpFileName
)
{
wchar_t
*
filename
;
int
result
,
err
;
filename
=
utf8_to_wchar
(
lpFileName
);
if
(
!
filename
)
return
0
;
result
=
DeleteFileW
(
filename
);
err
=
GetLastError
();
free
(
filename
);
SetLastError
(
err
);
return
result
;
}
#else
/*!HAVE_W32CE_SYSTEM*/
#define MyCreateFile CreateFileA
#define MyDeleteFile DeleteFileA
#endif
/*!HAVE_W32CE_SYSTEM*/
int
_assuan_sock_wsa2errno
(
int
err
)
{
switch
(
err
)
{
case
WSAENOTSOCK
:
return
EINVAL
;
case
WSAEWOULDBLOCK
:
return
EAGAIN
;
case
ERROR_BROKEN_PIPE
:
return
EPIPE
;
case
WSANOTINITIALISED
:
return
ENOSYS
;
default
:
return
EIO
;
}
}
/* W32: Fill BUFFER with LENGTH bytes of random. Returns -1 on
failure, 0 on success. Sets errno on failure. */
static
int
get_nonce
(
char
*
buffer
,
size_t
nbytes
)
{
HCRYPTPROV
prov
;
int
ret
=
-1
;
if
(
!
CryptAcquireContext
(
&
prov
,
NULL
,
NULL
,
PROV_RSA_FULL
,
(
CRYPT_VERIFYCONTEXT
|
CRYPT_SILENT
))
)
gpg_err_set_errno
(
ENODEV
);
else
{
if
(
!
CryptGenRandom
(
prov
,
nbytes
,
(
unsigned
char
*
)
buffer
))
gpg_err_set_errno
(
ENODEV
);
else
ret
=
0
;
CryptReleaseContext
(
prov
,
0
);
}
return
ret
;
}
/* W32: The buffer for NONCE needs to be at least 16 bytes. Returns 0 on
success and sets errno on failure. */
static
int
read_port_and_nonce
(
const
char
*
fname
,
unsigned
short
*
port
,
char
*
nonce
)
{
FILE
*
fp
;
char
buffer
[
50
],
*
p
;
size_t
nread
;
int
aval
;
fp
=
fopen
(
fname
,
"rb"
);
if
(
!
fp
)
return
-1
;
nread
=
fread
(
buffer
,
1
,
sizeof
buffer
-
1
,
fp
);
fclose
(
fp
);
if
(
!
nread
)
{
gpg_err_set_errno
(
ENOENT
);
return
-1
;
}
buffer
[
nread
]
=
0
;
aval
=
atoi
(
buffer
);
if
(
aval
<
1
||
aval
>
65535
)
{
gpg_err_set_errno
(
EINVAL
);
return
-1
;
}
*
port
=
(
unsigned
int
)
aval
;
for
(
p
=
buffer
;
nread
&&
*
p
!=
'\n'
;
p
++
,
nread
--
)
;
if
(
*
p
!=
'\n'
||
nread
!=
17
)
{
gpg_err_set_errno
(
EINVAL
);
return
-1
;
}
p
++
;
nread
--
;
memcpy
(
nonce
,
p
,
16
);
return
0
;
}
#endif
/*HAVE_W32_SYSTEM*/
#ifndef HAVE_W32_SYSTEM
/* Find a redirected socket name for fname and return a malloced setup
filled sockaddr. If this does not work out NULL is returned and
ERRNO is set. If the file seems to be a redirect True is stored at
R_REDIRECT. Note that this function uses the standard malloc and
not the assuan wrapped one. The format of the file is:
%Assuan%
socket=NAME
where NAME is the actual socket to use. No white spaces are
allowed, both lines must be terminated by a single LF, extra lines
are not allowed. Environment variables are interpreted in NAME if
given in "${VAR} notation; no escape characters are defined, if
"${" shall be used verbatim, you need to use an environment
variable with that content.
The use of an absolute NAME is strongly suggested. The length of
the file is limited to 511 bytes which is more than sufficient for
that common value of 107 for sun_path. */
static
struct
sockaddr_un
*
eval_redirection
(
const
char
*
fname
,
int
*
r_redirect
)
{
FILE
*
fp
;
char
buffer
[
512
],
*
name
;
size_t
n
;
struct
sockaddr_un
*
addr
;
char
*
p
,
*
pend
;
const
char
*
s
;
*
r_redirect
=
0
;
fp
=
fopen
(
fname
,
"rb"
);
if
(
!
fp
)
return
NULL
;
n
=
fread
(
buffer
,
1
,
sizeof
buffer
-
1
,
fp
);
fclose
(
fp
);
if
(
!
n
)
{
gpg_err_set_errno
(
ENOENT
);
return
NULL
;
}
buffer
[
n
]
=
0
;
/* Check that it is a redirection file. We also check that the
first byte of the name is not a LF because that would lead to an
zero length name. */
if
(
n
<
17
||
buffer
[
n
-1
]
!=
'\n'
||
memcmp
(
buffer
,
"%Assuan%
\n
socket="
,
16
)
||
buffer
[
16
]
==
'\n'
)
{
gpg_err_set_errno
(
EINVAL
);
return
NULL
;
}
buffer
[
n
-1
]
=
0
;
name
=
buffer
+
16
;
*
r_redirect
=
1
;
addr
=
calloc
(
1
,
sizeof
*
addr
);
if
(
!
addr
)
return
NULL
;
addr
->
sun_family
=
AF_LOCAL
;
n
=
0
;
for
(
p
=
name
;
*
p
;
p
++
)
{
if
(
*
p
==
'$'
&&
p
[
1
]
==
'{'
)
{
p
+=
2
;
pend
=
strchr
(
p
,
'}'
);
if
(
!
pend
)
{
free
(
addr
);
gpg_err_set_errno
(
EINVAL
);
return
NULL
;
}
*
pend
=
0
;
if
(
*
p
&&
(
s
=
getenv
(
p
)))
{
for
(;
*
s
;
s
++
)
{
if
(
n
<
sizeof
addr
->
sun_path
-
1
)
addr
->
sun_path
[
n
++
]
=
*
s
;
else
{
free
(
addr
);
gpg_err_set_errno
(
ENAMETOOLONG
);
return
NULL
;
}
}
}
p
=
pend
;
}
else
if
(
*
p
==
'\n'
)
break
;
/* Be nice and stop at the first LF. */
else
if
(
n
<
sizeof
addr
->
sun_path
-
1
)
addr
->
sun_path
[
n
++
]
=
*
p
;
else
{
free
(
addr
);
gpg_err_set_errno
(
ENAMETOOLONG
);
return
NULL
;
}
}
return
addr
;
}
#endif
/*!HAVE_W32_SYSTEM*/
/* Return a new socket. Note that under W32 we consider a socket the
same as an System Handle; all functions using such a handle know
about this dual use and act accordingly. */
assuan_fd_t
_assuan_sock_new
(
assuan_context_t
ctx
,
int
domain
,
int
type
,
int
proto
)
{
#ifdef HAVE_W32_SYSTEM
assuan_fd_t
res
;
if
(
domain
==
AF_UNIX
||
domain
==
AF_LOCAL
)
domain
=
AF_INET
;
res
=
SOCKET2HANDLE
(
_assuan_socket
(
ctx
,
domain
,
type
,
proto
));
return
res
;
#else
return
_assuan_socket
(
ctx
,
domain
,
type
,
proto
);
#endif
}
int
_assuan_sock_connect
(
assuan_context_t
ctx
,
assuan_fd_t
sockfd
,
struct
sockaddr
*
addr
,
int
addrlen
)
{
#ifdef HAVE_W32_SYSTEM
if
(
addr
->
sa_family
==
AF_LOCAL
||
addr
->
sa_family
==
AF_UNIX
)
{
struct
sockaddr_in
myaddr
;
struct
sockaddr_un
*
unaddr
;
unsigned
short
port
;
char
nonce
[
16
];
int
ret
;
unaddr
=
(
struct
sockaddr_un
*
)
addr
;
if
(
read_port_and_nonce
(
unaddr
->
sun_path
,
&
port
,
nonce
))
return
-1
;
myaddr
.
sin_family
=
AF_INET
;
myaddr
.
sin_port
=
htons
(
port
);
myaddr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_LOOPBACK
);
/* Set return values. */
unaddr
->
sun_family
=
myaddr
.
sin_family
;
unaddr
->
sun_port
=
myaddr
.
sin_port
;
unaddr
->
sun_addr
.
s_addr
=
myaddr
.
sin_addr
.
s_addr
;
ret
=
_assuan_connect
(
ctx
,
HANDLE2SOCKET
(
sockfd
),
(
struct
sockaddr
*
)
&
myaddr
,
sizeof
myaddr
);
if
(
!
ret
)
{
/* Send the nonce. */
ret
=
_assuan_write
(
ctx
,
sockfd
,
nonce
,
16
);
if
(
ret
>=
0
&&
ret
!=
16
)
{
gpg_err_set_errno
(
EIO
);
ret
=
-1
;
}
}
return
ret
;
}
else
{
int
res
;
res
=
_assuan_connect
(
ctx
,
HANDLE2SOCKET
(
sockfd
),
addr
,
addrlen
);
return
res
;
}
#else
# if HAVE_STAT
if
(
addr
->
sa_family
==
AF_LOCAL
||
addr
->
sa_family
==
AF_UNIX
)
{
struct
sockaddr_un
*
unaddr
;
struct
stat
statbuf
;
int
redirect
,
res
;
unaddr
=
(
struct
sockaddr_un
*
)
addr
;
if
(
!
stat
(
unaddr
->
sun_path
,
&
statbuf
)
&&
!
S_ISSOCK
(
statbuf
.
st_mode
)
&&
S_ISREG
(
statbuf
.
st_mode
))
{
/* The given socket file is not a socket but a regular file.
We use the content of that file to redirect to another
socket file. This can be used to use sockets on file
systems which do not support sockets or if for example a
home directory is shared by several machines. */
unaddr
=
eval_redirection
(
unaddr
->
sun_path
,
&
redirect
);
if
(
unaddr
)
{
res
=
_assuan_connect
(
ctx
,
sockfd
,
(
struct
sockaddr
*
)
unaddr
,
SUN_LEN
(
unaddr
));
free
(
unaddr
);
return
res
;
}
if
(
redirect
)
return
-1
;
/* Continue using the standard connect. */
}
}
# endif
/*HAVE_STAT*/
return
_assuan_connect
(
ctx
,
sockfd
,
addr
,
addrlen
);
#endif
}
int
_assuan_sock_bind
(
assuan_context_t
ctx
,
assuan_fd_t
sockfd
,
struct
sockaddr
*
addr
,
int
addrlen
)
{
#ifdef HAVE_W32_SYSTEM
if
(
addr
->
sa_family
==
AF_LOCAL
||
addr
->
sa_family
==
AF_UNIX
)
{
struct
sockaddr_in
myaddr
;
struct
sockaddr_un
*
unaddr
;
HANDLE
filehd
;
int
len
=
sizeof
myaddr
;
int
rc
;
char
nonce
[
16
];
char
tmpbuf
[
33
+
16
];
DWORD
nwritten
;
if
(
get_nonce
(
nonce
,
16
))
return
-1
;
unaddr
=
(
struct
sockaddr_un
*
)
addr
;
myaddr
.
sin_port
=
0
;
myaddr
.
sin_family
=
AF_INET
;
myaddr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_LOOPBACK
);
filehd
=
MyCreateFile
(
unaddr
->
sun_path
,
GENERIC_WRITE
,
FILE_SHARE_READ
,
NULL
,
CREATE_NEW
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
filehd
==
INVALID_HANDLE_VALUE
)
{
if
(
GetLastError
()
==
ERROR_FILE_EXISTS
)
gpg_err_set_errno
(
WSAEADDRINUSE
);
return
-1
;
}
rc
=
bind
(
HANDLE2SOCKET
(
sockfd
),
(
struct
sockaddr
*
)
&
myaddr
,
len
);
if
(
!
rc
)
rc
=
getsockname
(
HANDLE2SOCKET
(
sockfd
),
(
struct
sockaddr
*
)
&
myaddr
,
&
len
);
if
(
rc
)
{
int
save_e
=
errno
;
CloseHandle
(
filehd
);
MyDeleteFile
(
unaddr
->
sun_path
);
gpg_err_set_errno
(
save_e
);
return
rc
;
}
snprintf
(
tmpbuf
,
sizeof
tmpbuf
,
"%d
\n
"
,
ntohs
(
myaddr
.
sin_port
));
len
=
strlen
(
tmpbuf
);
memcpy
(
tmpbuf
+
len
,
nonce
,
16
);
len
+=
16
;
if
(
!
WriteFile
(
filehd
,
tmpbuf
,
len
,
&
nwritten
,
NULL
))
{
CloseHandle
(
filehd
);
MyDeleteFile
(
unaddr
->
sun_path
);
gpg_err_set_errno
(
EIO
);
return
-1
;
}
CloseHandle
(
filehd
);
return
0
;
}
else
{
int
res
=
bind
(
HANDLE2SOCKET
(
sockfd
),
addr
,
addrlen
);
if
(
res
<
0
)
gpg_err_set_errno
(
_assuan_sock_wsa2errno
(
WSAGetLastError
()));
return
res
;
}
#else
return
bind
(
sockfd
,
addr
,
addrlen
);
#endif
}
/* Setup the ADDR structure for a Unix domain socket with the socket
name FNAME. If this is a redirected socket and R_REDIRECTED is not
NULL, it will be setup for the real socket. Returns 0 on success
and stores 1 at R_REDIRECTED if it is a redirected socket. On
error -1 is returned and ERRNO will be set. */
int
_assuan_sock_set_sockaddr_un
(
const
char
*
fname
,
struct
sockaddr
*
addr
,
int
*
r_redirected
)
{
struct
sockaddr_un
*
unaddr
=
(
struct
sockaddr_un
*
)
addr
;
#if !defined(HAVE_W32_SYSTEM) && defined(HAVE_STAT)
struct
stat
statbuf
;
#endif
if
(
r_redirected
)
*
r_redirected
=
0
;
#if !defined(HAVE_W32_SYSTEM) && defined(HAVE_STAT)
if
(
r_redirected
&&
!
stat
(
fname
,
&
statbuf
)
&&
!
S_ISSOCK
(
statbuf
.
st_mode
)
&&
S_ISREG
(
statbuf
.
st_mode
))
{
/* The given socket file is not a socket but a regular file. We
use the content of that file to redirect to another socket
file. This can be used to use sockets on file systems which
do not support sockets or if for example a home directory is
shared by several machines. */
struct
sockaddr_un
*
unaddr_new
;
int
redirect
;
unaddr_new
=
eval_redirection
(
fname
,
&
redirect
);
if
(
unaddr_new
)
{
memcpy
(
unaddr
,
unaddr_new
,
sizeof
*
unaddr
);
free
(
unaddr_new
);
*
r_redirected
=
1
;
return
0
;
}
if
(
redirect
)
{
*
r_redirected
=
1
;
return
-1
;
/* Error. */
}
/* Fallback to standard setup. */
}
#endif
/*!HAVE_W32_SYSTEM && HAVE_STAT*/
if
(
strlen
(
fname
)
+
1
>=
sizeof
unaddr
->
sun_path
)
{
gpg_err_set_errno
(
ENAMETOOLONG
);
return
-1
;
}
memset
(
unaddr
,
0
,
sizeof
*
unaddr
);
unaddr
->
sun_family
=
AF_LOCAL
;
strncpy
(
unaddr
->
sun_path
,
fname
,
sizeof
unaddr
->
sun_path
-
1
);
unaddr
->
sun_path
[
sizeof
unaddr
->
sun_path
-
1
]
=
0
;
return
0
;
}
int
_assuan_sock_get_nonce
(
assuan_context_t
ctx
,
struct
sockaddr
*
addr
,
int
addrlen
,
assuan_sock_nonce_t
*
nonce
)
{
#ifdef HAVE_W32_SYSTEM
if
(
addr
->
sa_family
==
AF_LOCAL
||
addr
->
sa_family
==
AF_UNIX
)
{
struct
sockaddr_un
*
unaddr
;
unsigned
short
port
;
if
(
sizeof
nonce
->
nonce
!=
16
)
{
gpg_err_set_errno
(
EINVAL
);
return
-1
;
}
nonce
->
length
=
16
;
unaddr
=
(
struct
sockaddr_un
*
)
addr
;
if
(
read_port_and_nonce
(
unaddr
->
sun_path
,
&
port
,
nonce
->
nonce
))
return
-1
;
}
else
{
nonce
->
length
=
42
;
/* Arbitrary value to detect unitialized nonce. */
nonce
->
nonce
[
0
]
=
42
;
}
#else
(
void
)
addr
;
(
void
)
addrlen
;
nonce
->
length
=
0
;
#endif
return
0
;
}
int
_assuan_sock_check_nonce
(
assuan_context_t
ctx
,
assuan_fd_t
fd
,
assuan_sock_nonce_t
*
nonce
)
{
#ifdef HAVE_W32_SYSTEM
char
buffer
[
16
],
*
p
;
size_t
nleft
;
int
n
;
if
(
sizeof
nonce
->
nonce
!=
16
)
{
gpg_err_set_errno
(
EINVAL
);
return
-1
;
}
if
(
nonce
->
length
==
42
&&
nonce
->
nonce
[
0
]
==
42
)
return
0
;
/* Not a Unix domain socket. */
if
(
nonce
->
length
!=
16
)
{
gpg_err_set_errno
(
EINVAL
);
return
-1
;
}
p
=
buffer
;
nleft
=
16
;
while
(
nleft
)
{
n
=
_assuan_read
(
ctx
,
SOCKET2HANDLE
(
fd
),
p
,
nleft
);
if
(
n
<
0
&&
errno
==
EINTR
)
;
else
if
(
n
<
0
&&
errno
==
EAGAIN
)
Sleep
(
100
);
else
if
(
n
<
0
)
return
-1
;
else
if
(
!
n
)
{
gpg_err_set_errno
(
EIO
);
return
-1
;
}
else
{
p
+=
n
;
nleft
-=
n
;
}
}
if
(
memcmp
(
buffer
,
nonce
->
nonce
,
16
))
{
gpg_err_set_errno
(
EACCES
);
return
-1
;
}
#else
(
void
)
fd
;
(
void
)
nonce
;
#endif
return
0
;
}
/* Public API. */
/* In the future, we can allow access to sock_ctx, if that context's
hook functions need to be overridden. There can only be one global
assuan_sock_* user (one library or one application) with this
convenience interface, if non-standard hook functions are
needed. */
static
assuan_context_t
sock_ctx
;
gpg_error_t
assuan_sock_init
()
{
gpg_error_t
err
;
#ifdef HAVE_W32_SYSTEM
WSADATA
wsadat
;
#endif
if
(
sock_ctx
!=
NULL
)
return
0
;
err
=
assuan_new
(
&
sock_ctx
);
#ifdef HAVE_W32_SYSTEM
if
(
!
err
)
WSAStartup
(
0x202
,
&
wsadat
);
#endif
return
err
;
}
void
assuan_sock_deinit
()
{
if
(
sock_ctx
==
NULL
)
return
;
#ifdef HAVE_W32_SYSTEM
WSACleanup
();
#endif
assuan_release
(
sock_ctx
);
sock_ctx
=
NULL
;
}
int
assuan_sock_close
(
assuan_fd_t
fd
)
{
return
_assuan_close
(
sock_ctx
,
fd
);
}
assuan_fd_t
assuan_sock_new
(
int
domain
,
int
type
,
int
proto
)
{
return
_assuan_sock_new
(
sock_ctx
,
domain
,
type
,
proto
);
}
int
assuan_sock_connect
(
assuan_fd_t
sockfd
,
struct
sockaddr
*
addr
,
int
addrlen
)
{
return
_assuan_sock_connect
(
sock_ctx
,
sockfd
,
addr
,
addrlen
);
}
int
assuan_sock_bind
(
assuan_fd_t
sockfd
,
struct
sockaddr
*
addr
,
int
addrlen
)
{
return
_assuan_sock_bind
(
sock_ctx
,
sockfd
,
addr
,
addrlen
);
}
int
assuan_sock_set_sockaddr_un
(
const
char
*
fname
,
struct
sockaddr
*
addr
,
int
*
r_redirected
)
{
return
_assuan_sock_set_sockaddr_un
(
fname
,
addr
,
r_redirected
);
}
int
assuan_sock_get_nonce
(
struct
sockaddr
*
addr
,
int
addrlen
,
assuan_sock_nonce_t
*
nonce
)
{
return
_assuan_sock_get_nonce
(
sock_ctx
,
addr
,
addrlen
,
nonce
);
}
int
assuan_sock_check_nonce
(
assuan_fd_t
fd
,
assuan_sock_nonce_t
*
nonce
)
{
return
_assuan_sock_check_nonce
(
sock_ctx
,
fd
,
nonce
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Feb 23, 7:48 PM (4 h, 37 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
e4/3e/724dfb940643cfbc4d428b3f004d
Attached To
rA Assuan
Event Timeline
Log In to Comment