42
48
# define AF_LOCAL AF_UNIX
46
_assuan_close (int fd)
48
#if defined (HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
49
int rc = closesocket (fd);
51
#ifdef HAVE_W32_SYSTEM
59
#ifdef HAVE_W32_SYSTEM
61
_assuan_sock_wsa2errno (int err)
69
case ERROR_BROKEN_PIPE:
71
case WSANOTINITIALISED:
79
/* W32: Fill BUFFER with LENGTH bytes of random. Returns -1 on
80
failure, 0 on success. Sets errno on failure. */
82
get_nonce (char *buffer, size_t nbytes)
87
if (!CryptAcquireContext (&prov, NULL, NULL, PROV_RSA_FULL,
88
(CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) )
92
if (!CryptGenRandom (prov, nbytes, buffer))
96
CryptReleaseContext (prov, 0);
102
/* W32: The buffer for NONCE needs to be at least 16 bytes. Returns 0 on
103
success and sets errno on failure. */
105
read_port_and_nonce (const char *fname, unsigned short *port, char *nonce)
112
fp = fopen (fname, "rb");
115
nread = fread (buffer, 1, sizeof buffer - 1, fp);
123
aval = atoi (buffer);
124
if (aval < 1 || aval > 65535)
129
*port = (unsigned int)aval;
130
for (p=buffer; nread && *p != '\n'; p++, nread--)
132
if (*p != '\n' || nread != 17)
138
memcpy (nonce, p, 16);
141
#endif /*HAVE_W32_SYSTEM*/
146
_assuan_close (assuan_fd_t fd)
148
#ifdef _ASSUAN_CUSTOM_IO
149
return _assuan_custom_close (fd);
151
#ifdef (HAVE_W32_SYSTEM)
152
int rc = closesocket (HANDLE2SOCKET(fd));
154
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
50
155
if (rc && WSAGetLastError () == WSAENOTSOCK)
51
rc = CloseHandle (fd);
157
rc = CloseHandle (fd);
54
164
return close (fd);
170
/* Return a new socket. Note that under W32 we consider a socket the
171
same as an System Handle; all functions using such a handle know
172
about this dual use and act accordingly. */
60
174
_assuan_sock_new (int domain, int type, int proto)
62
#ifndef HAVE_W32_SYSTEM
63
return socket (domain, type, proto);
176
#ifdef HAVE_W32_SYSTEM
65
178
if (domain == AF_UNIX || domain == AF_LOCAL)
181
#ifdef _ASSUAN_CUSTOM_IO
182
return _assuan_custom_socket (domain, type, proto);
184
res = SOCKET2HANDLE(socket (domain, type, proto));
185
if (res == ASSUAN_INVALID_FD)
186
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
192
#ifdef _ASSUAN_CUSTOM_IO
193
return _gpgme_io_socket (domain, type, proto);
67
195
return socket (domain, type, proto);
73
_assuan_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
203
_assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
75
#ifndef HAVE_W32_SYSTEM
205
#ifdef HAVE_W32_SYSTEM
206
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
208
struct sockaddr_in myaddr;
209
struct sockaddr_un *unaddr;
214
unaddr = (struct sockaddr_un *)addr;
215
if (read_port_and_nonce (unaddr->sun_path, &port, nonce))
218
myaddr.sin_family = AF_INET;
219
myaddr.sin_port = htons (port);
220
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
222
/* Set return values. */
223
unaddr->sun_family = myaddr.sin_family;
224
unaddr->sun_port = myaddr.sin_port;
225
unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
227
#ifdef _ASSUAN_CUSTOM_IO
228
ret = _assuan_custom_connect (sockfd,
229
(struct sockaddr *)&myaddr, sizeof myaddr);
231
ret = connect (HANDLE2SOCKET(sockfd),
232
(struct sockaddr *)&myaddr, sizeof myaddr);
237
/* Send the nonce. */
239
ret = _assuan_io_write (sockfd, nonce, 16);
240
if (ret >= 0 && ret != 16)
247
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
253
res = connect (HANDLE2SOCKET (sockfd), addr, addrlen);
255
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
260
#ifdef _ASSUAN_CUSTOM_IO
261
return _assuan_custom_connect (sockfd, addr, addrlen);
76
263
return connect (sockfd, addr, addrlen);
78
struct sockaddr_in myaddr;
79
struct sockaddr_un * unaddr;
83
unaddr = (struct sockaddr_un *)addr;
84
fp = fopen (unaddr->sun_path, "rb");
87
fscanf (fp, "%d", &port);
89
/* XXX: set errno in this case */
90
if (port < 0 || port > 65535)
93
myaddr.sin_family = AF_INET;
94
myaddr.sin_port = port;
95
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
97
/* we need this later. */
98
unaddr->sun_family = myaddr.sin_family;
99
unaddr->sun_port = myaddr.sin_port;
100
unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
102
return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr);
108
_assuan_sock_bind (int sockfd, struct sockaddr * addr, int addrlen)
271
_assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
110
#ifndef HAVE_W32_SYSTEM
111
return bind (sockfd, addr, addrlen);
273
#ifdef HAVE_W32_SYSTEM
113
274
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
115
276
struct sockaddr_in myaddr;
116
struct sockaddr_un * unaddr;
277
struct sockaddr_un *unaddr;
118
280
int len = sizeof myaddr;
284
if (get_nonce (nonce, 16))
287
unaddr = (struct sockaddr_un *)addr;
121
289
myaddr.sin_port = 0;
122
290
myaddr.sin_family = AF_INET;
123
291
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
125
rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
128
rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
131
unaddr = (struct sockaddr_un *)addr;
132
fp = fopen (unaddr->sun_path, "wb");
293
filefd = open (unaddr->sun_path,
294
(O_WRONLY|O_CREAT|O_EXCL|O_BINARY),
295
(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP));
299
errno = WSAEADDRINUSE;
302
fp = fdopen (filefd, "wb");
135
fprintf (fp, "%d", myaddr.sin_port);
311
rc = bind (HANDLE2SOCKET (sockfd), (struct sockaddr *)&myaddr, len);
313
rc = getsockname (HANDLE2SOCKET (sockfd),
314
(struct sockaddr *)&myaddr, &len);
319
remove (unaddr->sun_path);
323
fprintf (fp, "%d\n", ntohs (myaddr.sin_port));
324
fwrite (nonce, 16, 1, fp);
138
/* we need this later. */
139
unaddr->sun_family = myaddr.sin_family;
140
unaddr->sun_port = myaddr.sin_port;
141
unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
331
int res = bind (HANDLE2SOCKET(sockfd), addr, addrlen);
333
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
145
337
return bind (sockfd, addr, addrlen);
343
_assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
344
assuan_sock_nonce_t *nonce)
346
#ifdef HAVE_W32_SYSTEM
347
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
349
struct sockaddr_un *unaddr;
352
if (sizeof nonce->nonce != 16)
358
unaddr = (struct sockaddr_un *)addr;
359
if (read_port_and_nonce (unaddr->sun_path, &port, nonce->nonce))
364
nonce->length = 42; /* Arbitrary valuie to detect unitialized nonce. */
365
nonce->nonce[0] = 42;
377
_assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
379
#ifdef HAVE_W32_SYSTEM
384
if (sizeof nonce->nonce != 16)
390
if (nonce->length == 42 && nonce->nonce[0] == 42)
391
return 0; /* Not a Unix domain socket. */
393
if (nonce->length != 16)
403
n = _assuan_io_read (SOCKET2HANDLE(fd), p, nleft);
404
if (n < 0 && errno == EINTR)
406
else if (n < 0 && errno == EAGAIN)
421
if (memcmp (buffer, nonce->nonce, 16))
436
assuan_sock_close (assuan_fd_t fd)
438
return _assuan_close (fd);
442
assuan_sock_new (int domain, int type, int proto)
444
return _assuan_sock_new (domain, type, proto);
448
assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
450
return _assuan_sock_connect (sockfd, addr, addrlen);
454
assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
456
return _assuan_sock_bind (sockfd, addr, addrlen);
460
assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
461
assuan_sock_nonce_t *nonce)
463
return _assuan_sock_get_nonce (addr, addrlen, nonce);
467
assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
469
return _assuan_sock_check_nonce (fd, nonce);