1 /****************************************************************************
2 * *
3 * cryptlib TCP/IP Interface Routines *
4 * Copyright Peter Gutmann 1998-2014 *
5 * *
6 ****************************************************************************/
7
8 #include <ctype.h>
9 #if defined( INC_ALL )
10 #include "crypt.h"
11 #include "stream_int.h"
12 #include "tcp.h"
13 #else
14 #include "crypt.h"
15 #include "io/stream_int.h"
16 #include "io/tcp.h"
17 #endif /* Compiler-specific includes */
18
19 #ifdef USE_TCP
20
21 /****************************************************************************
22 * *
23 * Init/Shutdown Routines *
24 * *
25 ****************************************************************************/
26
27 /* Forward declarations for socket pool functions */
28
29 CHECK_RETVAL \
30 static int initSocketPool( void );
31 static void endSocketPool( void );
32
33 #ifdef __WINDOWS__
34
35 #ifndef TEXT
36 #define TEXT /* Win32 windows.h defines this, but not the Win16 one */
37 #endif /* TEXT */
38
39 #ifdef _MSC_VER
40 #pragma warning( disable: 4127 ) /* False-positive in winsock.h */
41 #endif /* VC++ */
42
43 /* Global function pointers. These are necessary because the functions need
44 to be dynamically linked since not all systems contain the necessary
45 libraries */
46
47 static INSTANCE_HANDLE hTCP, hIPv6;
48
49 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
50 SOCKET ( SOCKET_API *ACCEPT )( IN SOCKET s, OUT struct sockaddr *addr,
51 INOUT int *addrlen );
52 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
53 int ( SOCKET_API *BIND )( IN SOCKET s,
54 const struct sockaddr FAR *addr,
55 IN_LENGTH_DNS int namelen );
56 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
57 int ( SOCKET_API *CONNECT )( IN SOCKET s, IN_BUFFER( namelen ) \
58 const struct sockaddr *name,
59 IN_LENGTH_DNS int namelen );
60 typedef STDC_NONNULL_ARG( ( 4, 5 ) ) \
61 int ( SOCKET_API *GETSOCKOPT )( IN SOCKET s, IN int level,
62 IN int optname,
63 OUT_BUFFER_FIXED( *optlen ) char *optval,
64 INOUT int FAR *optlen );
65 typedef CHECK_RETVAL \
66 int ( SOCKET_API *LISTEN )( IN SOCKET s, IN int backlog );
67 typedef CHECK_RETVAL RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
68 int ( SOCKET_API *RECV )( IN SOCKET s,
69 OUT_BUFFER( len, return ) char *buf,
70 IN_LENGTH int len, IN int flags );
71 typedef CHECK_RETVAL RETVAL STDC_NONNULL_ARG( ( 2, 5, 6 ) ) \
72 int ( SOCKET_API *RECVFROM )( IN SOCKET s,
73 OUT_BUFFER( len, return ) char *buf,
74 IN_LENGTH int len, IN int flags,
75 OUT_BUFFER_FIXED( *fromlen ) struct sockaddr *from,
76 OUT_LENGTH int *fromlen );
77 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 4, 5 ) ) \
78 int ( SOCKET_API *SELECT )( IN int nfds, INOUT_OPT fd_set *readfds,
79 INOUT_OPT fd_set *writefds,
80 INOUT fd_set *exceptfds,
81 const struct timeval *timeout );
82 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
83 int ( SOCKET_API *SEND )( IN SOCKET s,
84 IN_BUFFER( len ) const char *buf,
85 IN_LENGTH int len, IN int flags );
86 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 5 ) ) \
87 int ( SOCKET_API *SENDTO )( IN SOCKET s,
88 IN_BUFFER( len ) const char *buf,
89 IN_LENGTH int len, IN int flags,
90 IN_BUFFER( tolen ) const struct sockaddr *to,
91 IN_LENGTH int tolen );
92 typedef STDC_NONNULL_ARG( ( 4 ) ) \
93 int ( SOCKET_API *SETSOCKOPT )( IN SOCKET s, IN int level, \
94 IN int optname,
95 IN_BUFFER( optlen ) char *optval,
96 IN int optlen );
97 typedef int ( SOCKET_API *SHUTDOWN )( IN SOCKET s, IN int how );
98 typedef CHECK_RETVAL \
99 SOCKET ( SOCKET_API *SOCKETFN )( IN int af, IN int type,
100 IN int protocol );
101 #ifdef __WINDOWS__
102 typedef int ( SOCKET_API *CLOSESOCKET )( IN SOCKET s );
103 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
104 int ( SOCKET_API *FDISSETFN )( IN SOCKET s, fd_set *fds );
105 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
106 int ( SOCKET_API *IOCTLSOCKET )( IN SOCKET s, IN long cmd,
107 INOUT u_long FAR *argp );
108 typedef int ( SOCKET_API *WSACLEANUP )( void );
109 typedef CHECK_RETVAL \
110 int ( SOCKET_API *WSAGETLASTERROR )( void );
111 typedef CHECK_RETVAL \
112 int ( SOCKET_API *WSASTARTUP )( IN WORD wVersionRequested,
113 OUT LPWSADATA lpWSAData );
114 #endif /* __WINDOWS__ */
115 static ACCEPT paccept = NULL;
116 static BIND pbind = NULL;
117 static CONNECT pconnect = NULL;
118 static GETSOCKOPT pgetsockopt = NULL;
119 static LISTEN plisten = NULL;
120 static RECV precv = NULL;
121 static RECVFROM precvfrom = NULL;
122 static SELECT pselect = NULL;
123 static SEND psend = NULL;
124 static SENDTO psendto = NULL;
125 static SETSOCKOPT psetsockopt = NULL;
126 static SHUTDOWN pshutdown = NULL;
127 static SOCKETFN psocket = NULL;
128 #ifdef __WINDOWS__
129 static CLOSESOCKET pclosesocket = NULL;
130 static FDISSETFN pFDISSETfn = NULL;
131 static IOCTLSOCKET pioctlsocket = NULL;
132 static WSACLEANUP pWSACleanup = NULL;
133 static WSAGETLASTERROR pWSAGetLastError = NULL;
134 static WSASTARTUP pWSAStartup = NULL;
135 #endif /* __WINDOWS__ */
136 #if ( defined( sun ) && OSVERSION > 4 )
137 static int *h_errnoPtr;
138
139 #undef getHostErrorCode
140 #define getHostErrorCode() *h_errnoPtr
141 #endif /* Slowaris */
142
143 #define accept paccept
144 #define bind pbind
145 #define connect pconnect
146 #define getsockopt pgetsockopt
147 #define listen plisten
148 #define recv precv
149 #define recvfrom precvfrom
150 #define select pselect
151 #define send psend
152 #define sendto psendto
153 #define setsockopt psetsockopt
154 #define shutdown pshutdown
155 #define socket psocket
156 #ifdef __WINDOWS__
157 #define closesocket pclosesocket
158 #define __WSAFDIsSet pFDISSETfn
159 #define ioctlsocket pioctlsocket
160 #define WSACleanup pWSACleanup
161 #ifndef WSAGetLastError
162 /* In some environments WSAGetLastError() is a macro that maps to
163 GetLastError() */
164 #define WSAGetLastError pWSAGetLastError
165 #define DYNLOAD_WSAGETLASTERROR
166 #endif /* WSAGetLastError */
167 #define WSAStartup pWSAStartup
168 #endif /* __WINDOWS__ */
169
170 /* Dynamically load and unload any necessary TCP/IP libraries. Under Windows
171 the dynamic loading is complicated by the existence of Winsock 1 vs.
172 Winsock 2, all recent systems use Winsock 2 but we allow for Winsock 1 as
173 well just in case */
174
175 #ifdef __WINDOWS__
176 #ifdef __WIN16__
177 #define TCP_LIBNAME "winsock.dll"
178 #elif defined( __WIN32__ )
179 #define TCP_LIBNAME TEXT( "ws2_32.dll" )
180 #define WINSOCK_OLD_LIBNAME TEXT( "wsock32.dll" )
181 #elif defined( __WINCE__ )
182 #define TCP_LIBNAME TEXT( "ws2.dll" )
183 #else
184 #error Unknown Windows variant encountered
185 #endif /* Win16/Win32/WinCE */
186 #else
187 #define TCP_LIBNAME "libsocket.so"
188 #define TEXT( x ) x
189 #endif /* OS-specific TCP/IP library naming */
190
191 RETVAL \
netInitTCP(void)192 int netInitTCP( void )
193 {
194 #ifdef __WINDOWS__
195 WSADATA wsaData;
196 #ifdef __WIN16__
197 UINT errorMode;
198 #endif /* __WIN16__ */
199 BOOLEAN ip6inWinsock = FALSE;
200 int status;
201 #endif /* __WINDOWS__ */
202
203 /* Obtain a handle to the modules containing the TCP/IP functions */
204 #ifdef __WINDOWS__
205 hTCP = hIPv6 = NULL_INSTANCE;
206 #if defined( __WIN16__ )
207 errorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX );
208 hTCP = DynamicLoad( TCP_LIBNAME );
209 SetErrorMode( errorMode );
210 if( hTCP < HINSTANCE_ERROR )
211 {
212 hTCP = NULL_INSTANCE;
213 return( CRYPT_ERROR );
214 }
215 #elif defined( __WIN32__ )
216 if( ( hTCP = DynamicLoad( TCP_LIBNAME ) ) == NULL_INSTANCE && \
217 ( hTCP = DynamicLoad( WINSOCK_OLD_LIBNAME ) ) == NULL_INSTANCE )
218 return( CRYPT_ERROR );
219 if( DynamicBind( hTCP, "getaddrinfo" ) != NULL )
220 ip6inWinsock = TRUE;
221 else
222 {
223 /* Newer releases of Windows put the IPv6 functions in the Winsock 2
224 library, older (non-IPv6-enabled) releases had it available as an
225 experimental add-on using the IPv6 Technology Preview library */
226 hIPv6 = DynamicLoad( "wship6.dll" );
227 }
228 #elif defined( __WINCE__ )
229 if( ( hTCP = DynamicLoad( TCP_LIBNAME ) ) == NULL_INSTANCE )
230 return( CRYPT_ERROR );
231 if( DynamicBind( hTCP, TEXT( "getaddrinfo" ) ) != NULL )
232 ip6inWinsock = TRUE;
233 #endif /* Win16/Win32/WinCE */
234 #else
235 if( ( hTCP = DynamicLoad( TCP_LIBNAME ) ) == NULL_INSTANCE )
236 return( CRYPT_ERROR );
237 #endif /* OS-specific dynamic load */
238
239 /* Now get pointers to the functions */
240 accept = ( ACCEPT ) DynamicBind( hTCP, TEXT( "accept" ) );
241 bind = ( BIND ) DynamicBind( hTCP, TEXT( "bind" ) );
242 connect = ( CONNECT ) DynamicBind( hTCP, TEXT( "connect" ) );
243 getsockopt = ( GETSOCKOPT ) DynamicBind( hTCP, TEXT( "getsockopt" ) );
244 listen = ( LISTEN ) DynamicBind( hTCP, TEXT( "listen" ) );
245 recv = ( RECV ) DynamicBind( hTCP, TEXT( "recv" ) );
246 recvfrom = ( RECVFROM ) DynamicBind( hTCP, TEXT( "recvfrom" ) );
247 select = ( SELECT ) DynamicBind( hTCP, TEXT( "select" ) );
248 send = ( SEND ) DynamicBind( hTCP, TEXT( "send" ) );
249 sendto = ( SENDTO ) DynamicBind( hTCP, TEXT( "sendto" ) );
250 setsockopt = ( SETSOCKOPT ) DynamicBind( hTCP, TEXT( "setsockopt" ) );
251 shutdown = ( SHUTDOWN ) DynamicBind( hTCP, TEXT( "shutdown" ) );
252 socket = ( SOCKETFN ) DynamicBind( hTCP, TEXT( "socket" ) );
253 #ifdef __WINDOWS__
254 closesocket = ( CLOSESOCKET ) DynamicBind( hTCP, TEXT( "closesocket" ) );
255 __WSAFDIsSet = ( FDISSETFN ) DynamicBind( hTCP, TEXT( "__WSAFDIsSet" ) );
256 ioctlsocket = ( IOCTLSOCKET ) DynamicBind( hTCP, TEXT( "ioctlsocket" ) );
257 WSACleanup = ( WSACLEANUP ) DynamicBind( hTCP, TEXT( "WSACleanup" ) );
258 #ifdef DYNLOAD_WSAGETLASTERROR
259 WSAGetLastError = ( WSAGETLASTERROR ) DynamicBind( hTCP, TEXT( "WSAGetLastError" ) );
260 #endif /* DYNLOAD_WSAGETLASTERROR */
261 WSAStartup = ( WSASTARTUP ) DynamicBind( hTCP, TEXT( "WSAStartup" ) );
262 if( ip6inWinsock || hIPv6 != NULL_INSTANCE )
263 status = initDNS( hTCP, ip6inWinsock ? hTCP : hIPv6 );
264 else
265 status = initDNS( hTCP, NULL_INSTANCE );
266 if( cryptStatusError( status ) )
267 {
268 if( hIPv6 != NULL_INSTANCE )
269 {
270 DynamicUnload( hIPv6 );
271 hIPv6 = NULL_INSTANCE;
272 }
273 DynamicUnload( hTCP );
274 hTCP = NULL_INSTANCE;
275 return( CRYPT_ERROR );
276 }
277 #endif /* __WINDOWS__ */
278 #if ( defined( sun ) && OSVERSION > 4 )
279 h_errnoPtr = ( int * ) DynamicBind( hTCP, "h_errno" );
280 if( h_errnoPtr == NULL )
281 {
282 DynamicUnload( hTCP );
283 hTCP = NULL_INSTANCE;
284 return( CRYPT_ERROR );
285 }
286 #endif /* Slowaris */
287
288 /* Make sure that we got valid pointers for every TCP/IP function */
289 if( accept == NULL || bind == NULL || connect == NULL || \
290 getsockopt == NULL || listen == NULL || recv == NULL || \
291 recvfrom == NULL || select == NULL || send == NULL || \
292 sendto == NULL || setsockopt == NULL || shutdown == NULL || \
293 socket == NULL )
294 {
295 endDNS( hTCP );
296 DynamicUnload( hTCP );
297 hTCP = NULL_INSTANCE;
298 if( hIPv6 != NULL_INSTANCE )
299 {
300 DynamicUnload( hIPv6 );
301 hIPv6 = NULL_INSTANCE;
302 }
303 return( CRYPT_ERROR );
304 }
305
306 #ifdef __WINDOWS__
307 if( closesocket == NULL || __WSAFDIsSet == NULL || \
308 ioctlsocket == NULL || WSACleanup == NULL ||
309 #ifdef DYNLOAD_WSAGETLASTERROR
310 WSAGetLastError == NULL ||
311 #endif /* DYNLOAD_WSAGETLASTERROR */
312 WSAStartup == NULL || \
313 ( WSAStartup( 2, &wsaData ) && WSAStartup( 1, &wsaData ) ) )
314 {
315 endDNS( hTCP );
316 DynamicUnload( hTCP );
317 hTCP = NULL_INSTANCE;
318 if( hIPv6 != NULL_INSTANCE )
319 {
320 DynamicUnload( hIPv6 );
321 hIPv6 = NULL_INSTANCE;
322 }
323 return( CRYPT_ERROR );
324 }
325 #endif /* __WINDOWS__ */
326
327 /* Set up the socket pool state information */
328 return( initSocketPool() );
329 }
330
netEndTCP(void)331 void netEndTCP( void )
332 {
333 /* Clean up the socket pool state information */
334 endSocketPool();
335
336 endDNS( hTCP );
337 if( hIPv6 != NULL_INSTANCE )
338 DynamicUnload( hIPv6 );
339 if( hTCP != NULL_INSTANCE )
340 {
341 #ifdef __WINDOWS__
342 /* Wipe the Sheets Afterwards and Cleanup */
343 WSACleanup();
344 #endif /* __WINDOWS__ */
345 DynamicUnload( hTCP );
346 }
347 hTCP = hIPv6 = NULL_INSTANCE;
348 }
349
350 /* Return the status of the network interface */
351
352 CHECK_RETVAL_BOOL \
transportOKFunction(void)353 static BOOLEAN transportOKFunction( void )
354 {
355 return( hTCP != NULL_INSTANCE ? TRUE : FALSE );
356 }
357 #else
358
359 RETVAL \
netInitTCP(void)360 int netInitTCP( void )
361 {
362 #ifdef __SCO_VERSION__
363 struct sigaction act, oact;
364
365 /* Work around the broken SCO/UnixWare signal-handling, which sometimes
366 sends a nonblocking socket a SIGIO (thus killing the process) when
367 waiting in a select() (this may have been fixed by the switch to
368 blocking sockets necessitated by Winsock bugs with non-blocking
369 sockets, and will be fixed long-term when SCO's long death march
370 eventually ends). Since SIGIO is an alias for SIGPOLL, SCO doesn't
371 help by reporting this as a "polling alarm". To fix this we need to
372 catch and swallow SIGIOs */
373 memset( &act, 0, sizeof( act ) );
374 act.sa_handler = SIG_IGN;
375 sigemptyset( &act.sa_mask );
376 if( sigaction( SIGIO, &act, &oact ) < 0 )
377 {
378 /* This assumes that stderr is open, i.e. that we're not a daemon.
379 This should be the case, at least during the development/debugging
380 stage */
381 fprintf( stderr, "cryptlib: sigaction failed, errno = %d, "
382 "file = %s, line = %d.\n", errno, __FILE__, __LINE__ );
383 abort();
384 }
385
386 /* Check for handler override. */
387 if( oact.sa_handler != SIG_DFL && oact.sa_handler != SIG_IGN )
388 {
389 /* We overwrote the caller's handler, reinstate the old handler and
390 warn them about this */
391 fprintf( stderr, "Warning: Conflicting SIGIO handling detected in "
392 "UnixWare socket bug\n workaround, file " __FILE__
393 ", line %d. This may cause\n false SIGIO/SIGPOLL "
394 "errors.\n", __LINE__ );
395 sigaction( SIGIO, &oact, &act );
396 }
397 #endif /* UnixWare/SCO */
398
399 /* Set up the socket pool state information */
400 return( initSocketPool() );
401 }
402
netEndTCP(void)403 void netEndTCP( void )
404 {
405 /* Clean up the socket pool state information */
406 endSocketPool();
407
408 #ifdef __SCO_VERSION__
409 signal( SIGIO, SIG_DFL );
410 #endif /* UnixWare/SCO */
411 }
412
413 CHECK_RETVAL_BOOL \
transportOKFunction(void)414 static BOOLEAN transportOKFunction( void )
415 {
416 #if defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ )
417 static BOOLEAN transportOK = FALSE;
418
419 if( !transportOK )
420 {
421 SOCKET netSocket;
422
423 /* If the networking subsystem isn't enabled, attempting any network
424 operations will return ENOENT (which isn't a normal return code,
425 but is the least inappropriate thing to return). In order to
426 check this before we get deep into the networking code, we create
427 a test socket here to make sure that everything is OK. If the
428 network transport is unavailable, we re-try each time we're
429 called in case it's been enabled in the meantime */
430 netSocket = socket( PF_INET, SOCK_STREAM, 0 );
431 if( !isBadSocket( netSocket ) )
432 {
433 closesocket( netSocket );
434 transportOK = TRUE;
435 }
436 }
437 return( transportOK );
438 #else
439 return( TRUE );
440 #endif /* OS-specific socket availability check */
441 }
442 #endif /* __WINDOWS__ */
443
444 /****************************************************************************
445 * *
446 * Utility Routines *
447 * *
448 ****************************************************************************/
449
450 /* Map of common error codes to strings. The error code supplied by the
451 caller is usually used as the return status code, however if a more
452 specific error code than the default is available it's specified via the
453 cryptSpecificCode member */
454
455 typedef struct {
456 const int errorCode; /* Native error code */
457 const int cryptSpecificCode;/* Specific cryptlib error code */
458 const BOOLEAN isFatal; /* Seriousness level */
459 BUFFER_FIXED( errorStringLength ) \
460 const char FAR_BSS *errorString;
461 const int errorStringLength;/* Error message */
462 } SOCKETERROR_INFO;
463
464 #if defined( __WINDOWS__ )
465
466 static const SOCKETERROR_INFO FAR_BSS socketErrorInfo[] = {
467 { WSAECONNREFUSED, CRYPT_ERROR_PERMISSION, TRUE,
468 "WSAECONNREFUSED: The attempt to connect was rejected", 52 },
469 { WSAEADDRNOTAVAIL, CRYPT_ERROR_NOTFOUND, TRUE,
470 "WSAEADDRNOTAVAIL: The remote address is not a valid address", 59 },
471 { WSAECONNABORTED, CRYPT_OK, TRUE,
472 "WSAECONNABORTED: Connection was terminated due to a time-out or "
473 "other failure", 77 },
474 { WSAECONNRESET, CRYPT_OK, TRUE,
475 "WSAECONNRESET: Connection was reset by the remote host executing "
476 "a close", 72 },
477 { WSAEHOSTUNREACH, CRYPT_OK, TRUE,
478 "WSAEHOSTUNREACH: Remote host cannot be reached from this host at "
479 "this time", 74 },
480 { WSAEMSGSIZE, CRYPT_ERROR_OVERFLOW, FALSE,
481 "WSAEMSGSIZE: Message is larger than the maximum supported by the "
482 "underlying transport", 85 },
483 { WSAENETDOWN, CRYPT_OK, FALSE,
484 "WSAENETDOWN: The network subsystem has failed", 45 },
485 { WSAENETRESET, CRYPT_OK, FALSE,
486 "WSAENETRESET: Connection was broken due to keep-alive detecting a "
487 "failure while operation was in progress", 105 },
488 { WSAENETUNREACH, CRYPT_ERROR_NOTAVAIL, FALSE,
489 "WSAENETUNREACH: Network cannot be reached from this host at this "
490 "time", 69 },
491 { WSAENOBUFS, CRYPT_ERROR_MEMORY, FALSE,
492 "WSAENOBUFS: No buffer space available", 37 },
493 { WSAENOTCONN, CRYPT_OK, TRUE,
494 "WSAENOTCONN: Socket is not connected", 36 },
495 { WSAETIMEDOUT, CRYPT_ERROR_TIMEOUT, FALSE,
496 "WSAETIMEDOUT: Function timed out before completion", 50 },
497 { WSAHOST_NOT_FOUND, CRYPT_ERROR_NOTFOUND, FALSE,
498 "WSAHOST_NOT_FOUND: Host not found", 34 },
499 { WSATRY_AGAIN, CRYPT_OK, FALSE,
500 "WSATRY_AGAIN: Host not found (non-authoritative)", 48 },
501 { WSANO_ADDRESS, CRYPT_OK, FALSE,
502 "WSANO_ADDRESS: No address record available for this name", 56 },
503 { WSANO_DATA, CRYPT_OK, FALSE,
504 "WSANO_DATA: Valid name, no data record of requested type", 56 },
505 { CRYPT_ERROR }, { CRYPT_ERROR }
506 };
507 #define hostErrorInfo socketErrorInfo /* Winsock uses unified error codes */
508
509 #define TIMEOUT_ERROR WSAETIMEDOUT /* Code for timeout error */
510 #define NONBLOCKCONNECT_ERROR WSAECONNREFUSED /* Code for nonb-conn.error */
511
512 #elif defined( __Nucleus__ )
513
514 static const SOCKETERROR_INFO FAR_BSS socketErrorInfo[] = {
515 { NU_INVALID_PROTOCOL, CRYPT_OK, TRUE,
516 "NU_INVALID_PROTOCOL: Invalid network protocol", 45 },
517 { NU_NO_DATA_TRANSFER, CRYPT_OK, TRUE,
518 "NU_NO_DATA_TRANSFER: Data was not written/read during send/receive "
519 "function", 75 },
520 { NU_NO_PORT_NUMBER, CRYPT_OK, TRUE,
521 "NU_NO_PORT_NUMBER: No local port number was stored in the socket "
522 "descriptor", 75 },
523 { NU_NO_TASK_MATCH, CRYPT_OK, TRUE,
524 "NU_NO_TASK_MATCH: No task/port number combination existed in the "
525 "task table", 75 },
526 { NU_NO_SOCKET_SPACE, CRYPT_OK, TRUE,
527 "NU_NO_SOCKET_SPACE: The socket structure list was full when a new "
528 "socket descriptor was requested", 97 },
529 { NU_NO_ACTION, CRYPT_OK, TRUE,
530 "NU_NO_ACTION: No action was processed by the function", 53 },
531 { NU_NOT_CONNECTED, CRYPT_OK, TRUE,
532 "NU_NOT_CONNECTED: A connection has been closed by the network", 61 },
533 { NU_INVALID_SOCKET, CRYPT_OK, TRUE,
534 "NU_INVALID_SOCKET: The socket ID passed in was not in a valid "
535 "range", 67 },
536 { NU_NO_SOCK_MEMORY, CRYPT_OK, TRUE,
537 "NU_NO_SOCK_MEMORY: Memory allocation failed for internal sockets "
538 "structure", 64 },
539 { NU_INVALID_ADDRESS, CRYPT_OK, TRUE,
540 "NU_INVALID_ADDRESS: An incomplete address was sent", 50 },
541 { NU_NO_HOST_NAME, CRYPT_OK, TRUE,
542 "NU_NO_HOST_NAME: No host name specified in a in a connect call "
543 "where a machine was not previously set up", 104 },
544 { NU_RARP_INIT_FAILED, CRYPT_OK, TRUE,
545 "NU_RARP_INIT_FAILED: During initialization RARP failed", 54 },
546 { NU_BOOTP_INIT_FAILED, CRYPT_OK, TRUE,
547 "NU_BOOTP_INIT_FAILED: During initialization BOOTP failed", 56 },
548 { NU_INVALID_PORT, CRYPT_OK, TRUE,
549 "NU_INVALID_PORT: The port number passed in was not in a valid "
550 "range", 67 },
551 { NU_NO_BUFFERS, CRYPT_OK, TRUE,
552 "NU_NO_BUFFERS: There were no buffers to place the outgoing packet "
553 "in", 68 },
554 { NU_NOT_ESTAB, CRYPT_OK, TRUE,
555 "NU_NOT_ESTAB: A connection is open but not in an established state", 66 },
556 { NU_WINDOW_FULL, CRYPT_OK, TRUE,
557 "NU_WINDOW_FULL: The foreign host's in window is full", 52 },
558 { NU_NO_SOCKETS, CRYPT_OK, TRUE,
559 "NU_NO_SOCKETS: No sockets were specified", 40 },
560 { NU_NO_DATA, CRYPT_OK, TRUE,
561 "NU_NO_DATA: None of the specified sockets were data ready", 57 },
562 /* NU_Setsockopt()/NU_Getsockopt() errors */
563 { NU_INVALID_LEVEL, CRYPT_OK, TRUE,
564 "NU_INVALID_LEVEL: The specified level is invalid", 48 },
565 { NU_INVALID_OPTION, CRYPT_OK, TRUE,
566 "NU_INVALID_OPTION: The specified option is invalid", 50 },
567 { NU_INVAL, CRYPT_OK, TRUE,
568 "NU_INVAL: General purpose error condition", 41 },
569 { NU_ACCESS, CRYPT_OK, TRUE,
570 "NU_ACCESS: The attempted operation is not allowed on the socket", 63 },
571 /* Standard socket errors again */
572 { NU_ADDRINUSE, CRYPT_OK, TRUE,
573 "NU_ADDRINUSE: The IP Multicast membership already exists", 56 },
574 { NU_HOST_UNREACHABLE, CRYPT_OK, TRUE,
575 "NU_HOST_UNREACHABLE: Host unreachable", 37 },
576 { NU_MSGSIZE, CRYPT_OK, TRUE,
577 "NU_MSGSIZE: Packet is to large for interface", 44 },
578 { NU_NOBUFS, CRYPT_OK, TRUE,
579 "NU_NOBUFS: Could not allocate a memory buffer", 45 },
580 { NU_UNRESOLVED_ADDR, CRYPT_OK, TRUE,
581 "NU_UNRESOLVED_ADDR: The MAC address was not resolved", 52 },
582 { NU_CLOSING, CRYPT_OK, TRUE,
583 "NU_CLOSING: The other side in a TCP connection has sent a FIN", 61 },
584 { NU_MEM_ALLOC, CRYPT_OK, TRUE,
585 "NU_MEM_ALLOC: Failed to allocate memory", 39 },
586 { NU_RESET, CRYPT_OK, TRUE,
587 "NU_RESET: A multicast membership was added and the MAC chip needs "
588 "to be reset", 77 },
589 { NU_DEVICE_DOWN, CRYPT_OK, TRUE,
590 "NU_DEVICE_DOWN: A device being used by the socket has gone down", 63 },
591 /* DNS errors */
592 { NU_INVALID_LABEL, CRYPT_OK, TRUE,
593 "NU_INVALID_LABEL: Domain name with an invalid label", 51 },
594 { NU_FAILED_QUERY, CRYPT_OK, TRUE,
595 "NU_FAILED_QUERY: No response received for a DNS Query", 53 },
596 { NU_DNS_ERROR, CRYPT_OK, TRUE,
597 "NU_DNS_ERROR: A general DNS error status", 40 },
598 { NU_NOT_A_HOST, CRYPT_OK, TRUE,
599 "NU_NOT_A_HOST: The host name was not found", 42 },
600 { NU_INVALID_PARM, CRYPT_OK, TRUE,
601 "NU_INVALID_PARM: A parameter has an invalid value", 49 },
602 { NU_NO_DNS_SERVER, CRYPT_OK, TRUE,
603 "NU_NO_DNS_SERVER: No DNS server has been registered with the "
604 "stack", 66 },
605 /* Standard socket errors again */
606 { NU_NO_ROUTE_TO_HOST, CRYPT_OK, TRUE,
607 "NU_NO_ROUTE_TO_HOST: ICMP Destination Unreachable specific "
608 "error", 64 },
609 { NU_CONNECTION_REFUSED, CRYPT_OK, TRUE,
610 "NU_CONNECTION_REFUSED: ICMP Destination Unreachable specific "
611 "error", 66 },
612 { NU_MSG_TOO_LONG, CRYPT_OK, TRUE,
613 "NU_MSG_TOO_LONG: ICMP Destination Unreachable specific error", 60 },
614 { NU_BAD_SOCKETD, CRYPT_OK, TRUE,
615 "NU_BAD_SOCKETD: Socket descriptor is not valid for the current "
616 "operation", 72 },
617 { NU_BAD_LEVEL, CRYPT_OK, TRUE,
618 "NU_BAD_LEVEL: ???", 17 },
619 { NU_BAD_OPTION, CRYPT_OK, TRUE,
620 "NU_BAD_OPTION: ???", 18 },
621 /* IPv6 errors */
622 { NU_DUP_ADDR_FAILED, CRYPT_OK, TRUE,
623 "NU_DUP_ADDR_FAILED: ???", 23 },
624 { NU_DISCARD_PACKET, CRYPT_OK, TRUE,
625 "NU_DISCARD_PACKET: ???", 22 },
626 /* ICMP errors */
627 { NU_DEST_UNREACH_ADMIN, CRYPT_OK, TRUE,
628 "NU_DEST_UNREACH_ADMIN: ICMP Destination Unreachable: Packet was "
629 "rejected due to administration reasons", 102 },
630 { NU_DEST_UNREACH_ADDRESS, CRYPT_OK, TRUE,
631 "NU_DEST_UNREACH_ADDRESS: ICMP Destination Unreachable: Packet was "
632 "rejected because destination address doesn't match an address on "
633 "the node", 139 },
634 { NU_DEST_UNREACH_PORT, CRYPT_OK, TRUE,
635 "NU_DEST_UNREACH_PORT: ICMP Destination Unreachable: Destination "
636 "port is not listening on the node", 97 },
637 { NU_TIME_EXCEED_HOPLIMIT, CRYPT_OK, TRUE,
638 "NU_TIME_EXCEED_HOPLIMIT: ICMP Time Exceeded: Packet has exceeded "
639 "the number of hops that it may make", 100 },
640 { NU_TIME_EXCEED_REASM, CRYPT_OK, TRUE,
641 "NU_TIME_EXCEED_REASM: ICMP Time Exceeded: Packet could not be "
642 "reassembled in the maximum allowable time", 103 },
643 { NU_PARM_PROB_HEADER, CRYPT_OK, TRUE,
644 "NU_PARM_PROB_HEADER: ICMP Parameter Problem: Packet has an error "
645 "in the IP header", 81 },
646 { NU_PARM_PROB_NEXT_HDR, CRYPT_OK, TRUE,
647 "NU_PARM_PROB_NEXT_HDR: ICMP Parameter Problem: Packet has an "
648 "invalid next header value in the IPv6 header", 105 },
649 { NU_PARM_PROB_OPTION, CRYPT_OK, TRUE,
650 "NU_PARM_PROB_OPTION: ICMP Parameter Problem: Invalid option "
651 "specified in the IP header", 86 },
652 { NU_DEST_UNREACH_NET, CRYPT_OK, TRUE,
653 "NU_DEST_UNREACH_NET: ICMP Destination Unreachable: Network is "
654 "unreachable", 73 },
655 { NU_DEST_UNREACH_HOST, CRYPT_OK, TRUE,
656 "NU_DEST_UNREACH_HOST: ICMP Destination Unreachable: Host is "
657 "unreachable", 71 },
658 { NU_DEST_UNREACH_PROT, CRYPT_OK, TRUE,
659 "NU_DEST_UNREACH_PROT: ICMP Destination Unreachable: Protocol is "
660 "not recognized on the node", 90 },
661 { NU_DEST_UNREACH_FRAG, CRYPT_OK, TRUE,
662 "NU_DEST_UNREACH_FRAG: ICMP Destination Unreachable: Packet "
663 "requires fragmentation but the node does not support "
664 "fragmentation", 125 },
665 { NU_DEST_UNREACH_SRCFAIL, CRYPT_OK, TRUE,
666 "NU_DEST_UNREACH_SRCFAIL: ICMP Destination Unreachable: Source "
667 "route failed", 75 },
668 { NU_PARM_PROB, CRYPT_OK, TRUE,
669 "NU_PARM_PROB: ICMP Parameter Problem: Packet has an error in the "
670 "IP header", 74 },
671 { NU_SOURCE_QUENCH, CRYPT_OK, TRUE,
672 "NU_SOURCE_QUENCH: ICMP Source Quench: Node is receiving too many "
673 "packets to process", 83 },
674 /* Nonblocking socket operation errors */
675 { NU_WOULD_BLOCK, CRYPT_OK, TRUE,
676 "NU_WOULD_BLOCK: Socket is non-blocking but blocking is required to "
677 "complete the requested action", 96 },
678 /* TCP Keepalive errors */
679 { NU_CONNECTION_TIMED_OUT, CRYPT_OK, TRUE,
680 "NU_CONNECTION_TIMED_OUT: Connection has been closed due to TCP "
681 "Keepalive probes not being answered", 98 },
682 /* Nonblocking connect errors */
683 { NU_IS_CONNECTING, CRYPT_OK, TRUE,
684 "NU_IS_CONNECTING: Socket is non-blocking and the connection is "
685 "being established", 80 },
686 /* Standard socket errors again */
687 { NU_SOCKET_CLOSED, CRYPT_OK, TRUE,
688 "NU_SOCKET_CLOSED: The specified socket has been closed", 54 },
689 { NU_TABLE_FULL, CRYPT_OK, TRUE,
690 "NU_TABLE_FULL: ???", 18 },
691 { NU_NOT_FOUND, CRYPT_OK, TRUE,
692 "NU_NOT_FOUND: ???", 17 },
693 /* IPv6 extension header errors */
694 { NU_INVAL_NEXT_HEADER, CRYPT_OK, TRUE,
695 "NU_INVAL_NEXT_HEADER: ???", 25 },
696 { NU_SEND_ICMP_ERROR, CRYPT_OK, TRUE,
697 "NU_SEND_ICMP_ERROR: ???", 23 },
698 /* Multicast errors */
699 { NU_MULTI_TOO_MANY_SRC_ADDRS, CRYPT_OK, TRUE,
700 "NU_MULTI_TOO_MANY_SRC_ADDRS: Number of source addresses specified "
701 "for multicast IP address filtering exceeds "
702 "MAX_MULTICAST_SRC_ADDR", 131 },
703 { NU_NOT_A_GROUP_MEMBER, CRYPT_OK, TRUE,
704 "NU_NOT_A_GROUP_MEMBER: Socket is not a member of the multicast "
705 "group specified", 78 },
706 { NU_TOO_MANY_GROUP_MEMBERS, CRYPT_OK, TRUE,
707 "NU_TOO_MANY_GROUP_MEMBERS: Number of multicast groups has been "
708 "reached", 70 },
709 /* Physical layer errors */
710 { NU_ETH_CABLE_UNPLUGGED, CRYPT_OK, TRUE,
711 "NU_ETH_CABLE_UNPLUGGED: Ethernet cable is unplugged", 51 },
712 { NU_ETH_CABLE_PLUGGED_IN, CRYPT_OK, TRUE,
713 "NU_ETH_CABLE_PLUGGED_IN: Ethernet cable has been plugged in", 59 },
714 { CRYPT_ERROR }, { CRYPT_ERROR }
715 };
716 #define hostErrorInfo socketErrorInfo /* Nucleus uses unified error codes */
717
718 #define TIMEOUT_ERROR NU_TIMEOUT /* Code for timeout error */
719 #define NONBLOCKCONNECT_ERROR NU_CONNECTION_REFUSED /* Code for nonb-conn.error */
720
721 #else
722
723 static const SOCKETERROR_INFO FAR_BSS socketErrorInfo[] = {
724 { EACCES, CRYPT_ERROR_PERMISSION, TRUE,
725 "EACCES: Permission denied", 25 },
726 { EADDRINUSE, CRYPT_OK, TRUE,
727 "EADDRINUSE: Address in use", 26 },
728 { EADDRNOTAVAIL, CRYPT_ERROR_NOTFOUND, TRUE,
729 "EADDRNOTAVAIL: Specified address is not available from the local "
730 "machine", 72 },
731 { EAFNOSUPPORT, CRYPT_ERROR_NOTAVAIL, TRUE,
732 "EAFNOSUPPORT: Address family not supported", 42 },
733 { EALREADY, CRYPT_OK, FALSE,
734 "EALREADY: Connection already in progress", 41 },
735 { EBADF, CRYPT_OK, FALSE,
736 "EBADF: Bad file descriptor", 26 },
737 #if !( defined( __PALMOS__ ) || defined( __SYMBIAN32__ ) )
738 { ECONNABORTED, CRYPT_OK, TRUE,
739 "ECONNABORTED: Software caused connection abort", 46 },
740 { ECONNRESET, CRYPT_OK, TRUE,
741 "ECONNRESET: Connection was forcibly closed by remote host", 57 },
742 #endif /* PalmOS || Symbian OS */
743 { ECONNREFUSED, CRYPT_ERROR_PERMISSION, TRUE,
744 "ECONNREFUSED: Attempt to connect was rejected", 45 },
745 { EINPROGRESS, CRYPT_OK, FALSE,
746 "EINPROGRESS: Operation in progress", 34 },
747 { EINTR, CRYPT_OK, FALSE,
748 "EINTR: Function was interrupted by a signal", 43 },
749 { EIO, CRYPT_OK, TRUE,
750 "EIO: Input/output error", 24 },
751 { EISCONN, CRYPT_OK, FALSE,
752 "EISCONN: Socket is connected", 28 },
753 { EMFILE, CRYPT_OK, FALSE,
754 "EMFILE: Per-process descriptor table is full", 44 },
755 #ifndef __SYMBIAN32__
756 { EMSGSIZE, CRYPT_ERROR_OVERFLOW, FALSE,
757 "EMSGSIZE: Message is too large to be sent all at once", 53 },
758 { ENETUNREACH, CRYPT_OK, FALSE,
759 "ENETUNREACH: No route to the network or host is present", 55 },
760 { ENOBUFS, CRYPT_ERROR_MEMORY, FALSE,
761 "ENOBUFS: Insufficient system resources available to complete the "
762 "call", 69 },
763 { ENODEV, CRYPT_OK, TRUE,
764 "ENODEV: No such device", 22 },
765 { ENOPROTOOPT, CRYPT_OK, TRUE,
766 "ENOPROTOOPT: Protocol not available", 35 },
767 { ENOTCONN, CRYPT_OK, TRUE,
768 "ENOTCONN: Socket is not connected", 33 },
769 { ENOTSOCK, CRYPT_OK, TRUE,
770 "ENOTSOCK: Not a socket", 22 },
771 #endif /* Symbian OS */
772 { EPERM, CRYPT_ERROR_PERMISSION, TRUE,
773 "EPERM: Operation not permitted", 30 },
774 { EPROTOTYPE, CRYPT_ERROR_NOTAVAIL, TRUE,
775 "EPROTOTYPE: Protocol wrong type for socket", 42 },
776 { ETIMEDOUT, CRYPT_ERROR_TIMEOUT, FALSE,
777 "ETIMEDOUT: Function timed out before completion", 47 },
778 { HOST_NOT_FOUND, CRYPT_ERROR_NOTFOUND, TRUE,
779 "HOST_NOT_FOUND: Not an official hostname or alias", 49 },
780 #ifndef __ECOS__
781 { NO_ADDRESS, CRYPT_ERROR_NOTFOUND, TRUE,
782 "NO_ADDRESS: Name is valid but does not have an IP address at the "
783 "name server", 76 },
784 #endif /* __ECOS__ */
785 { TRY_AGAIN, CRYPT_OK, FALSE,
786 "TRY_AGAIN: Local server did not receive a response from an "
787 "authoritative server", 79 },
788 { CRYPT_ERROR }, { CRYPT_ERROR }
789 };
790
791 #define TIMEOUT_ERROR ETIMEDOUT /* Code for timeout error */
792 #define NONBLOCKCONNECT_ERROR ECONNREFUSED /* Code for nonb-conn.error */
793
794 static const SOCKETERROR_INFO FAR_BSS hostErrorInfo[] = {
795 { HOST_NOT_FOUND, CRYPT_ERROR_NOTFOUND, TRUE,
796 "HOST_NOT_FOUND: Host not found", 30 },
797 #ifndef __ECOS__
798 { NO_ADDRESS, CRYPT_ERROR_NOTFOUND, TRUE,
799 "NO_ADDRESS: No address record available for this name", 53 },
800 #endif /* __ECOS__ */
801 { NO_DATA, CRYPT_ERROR_NOTFOUND, TRUE,
802 "NO_DATA: Valid name, no data record of requested type", 53 },
803 { TRY_AGAIN, CRYPT_OK, FALSE,
804 "TRY_AGAIN: Local server did not receive a response from an "
805 "authoritative server", 79 },
806 { CRYPT_ERROR }, { CRYPT_ERROR }
807 };
808 #endif /* System-specific socket error codes */
809
810 /* Get and set the low-level error information from a socket- and host-
811 lookup-based error. In theory under Windows we could also use the
812 Network List Manager to try and get additional diagnostic information
813 but this is only available under Vista and requires playing with COM
814 objects, the significant extra complexity caused by this isn't worth the
815 tiny additional level of granularity that we might gain in reporting
816 errors. In any case the NLM functionality seems primarily intended for
817 interactively obtaining information before any networking actions are
818 initiated ("Do we currently have an Internet connection?") rather than
819 diagnosing problems afterwards ("What went wrong with the attempt to
820 initiate an Internet connection?") */
821
822 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
mapError(NET_STREAM_INFO * netStream,const int netStreamErrorCode,const BOOLEAN useHostErrorInfo,IN_ERROR int status)823 static int mapError( NET_STREAM_INFO *netStream,
824 const int netStreamErrorCode,
825 const BOOLEAN useHostErrorInfo,
826 IN_ERROR int status )
827 {
828 const SOCKETERROR_INFO *errorInfo = \
829 useHostErrorInfo ? hostErrorInfo : socketErrorInfo;
830 const int errorInfoSize = useHostErrorInfo ? \
831 FAILSAFE_ARRAYSIZE( hostErrorInfo, SOCKETERROR_INFO ) : \
832 FAILSAFE_ARRAYSIZE( socketErrorInfo, SOCKETERROR_INFO );
833 int i;
834
835 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
836 assert( cryptStatusError( status ) );
837
838 REQUIRES( cryptStatusError( status ) );
839
840 clearErrorString( &netStream->errorInfo );
841 if( netStreamErrorCode == 0 )
842 {
843 /* There's no further error information available, we can't report
844 any more detail */
845 return( status );
846 }
847 for( i = 0; i < errorInfoSize && \
848 errorInfo[ i ].errorCode != CRYPT_ERROR; i++ )
849 {
850 if( errorInfo[ i ].errorCode == netStreamErrorCode )
851 {
852 REQUIRES( errorInfo[ i ].errorStringLength > 16 && \
853 errorInfo[ i ].errorStringLength < 150 );
854 setErrorString( NETSTREAM_ERRINFO, errorInfo[ i ].errorString,
855 errorInfo[ i ].errorStringLength );
856 if( errorInfo[ i ].cryptSpecificCode != CRYPT_OK )
857 {
858 /* There's a more specific error code than the generic one
859 that we've been given available, use that instead */
860 status = errorInfo[ i ].cryptSpecificCode;
861 }
862 if( errorInfo[ i ].isFatal )
863 {
864 /* It's a fatal error, make it persistent for the stream */
865 netStream->persistentStatus = status;
866 }
867 break;
868 }
869 }
870 ENSURES( i < errorInfoSize );
871
872 return( status );
873 }
874
875 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
getSocketError(NET_STREAM_INFO * netStream,IN_ERROR const int status,OUT_INT_Z int * socketErrorCode)876 int getSocketError( NET_STREAM_INFO *netStream,
877 IN_ERROR const int status,
878 OUT_INT_Z int *socketErrorCode )
879 {
880 const int errorCode = getErrorCode();
881
882 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
883 assert( isWritePtr( socketErrorCode, sizeof( int ) ) );
884
885 REQUIRES( cryptStatusError( status ) );
886
887 /* Get the low-level error code and map it to an error string if
888 possible */
889 *socketErrorCode = errorCode;
890
891 return( mapError( netStream, errorCode, FALSE, status ) );
892 }
893
894 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
getHostError(NET_STREAM_INFO * netStream,IN_ERROR const int status)895 int getHostError( NET_STREAM_INFO *netStream,
896 IN_ERROR const int status )
897 {
898 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
899
900 REQUIRES( cryptStatusError( status ) );
901
902 /* Get the low-level error code and map it to an error string if
903 possible */
904 return( mapError( netStream, getHostErrorCode(), TRUE, status ) );
905 }
906
907 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
setSocketError(INOUT NET_STREAM_INFO * netStream,IN_BUFFER (errorMessageLength)const char * errorMessage,IN_LENGTH_ERRORMESSAGE const int errorMessageLength,IN_ERROR const int status,const BOOLEAN isFatal)908 int setSocketError( INOUT NET_STREAM_INFO *netStream,
909 IN_BUFFER( errorMessageLength ) const char *errorMessage,
910 IN_LENGTH_ERRORMESSAGE const int errorMessageLength,
911 IN_ERROR const int status, const BOOLEAN isFatal )
912 {
913 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
914 assert( isReadPtr( errorMessage, 16 ) );
915
916 REQUIRES( errorMessageLength > 16 && \
917 errorMessageLength <= MAX_INTLENGTH_SHORT );
918 /* MAX_ERRORMESSAGE_SIZE isn't defined at this level */
919 REQUIRES( cryptStatusError( status ) );
920
921 /* Set a cryptlib-supplied socket error message */
922 setErrorString( NETSTREAM_ERRINFO, errorMessage, errorMessageLength );
923 if( isFatal )
924 {
925 /* It's a fatal error, make it persistent for the stream */
926 netStream->persistentStatus = status;
927 }
928 return( status );
929 }
930
931 /* Some buggy firewall software will block any data transfer attempts made
932 after the initial connection setup, if we're in a situation where this
933 can happen then we check for the presence of a software firewall and
934 report a problem due to the firewall rather than a general networking
935 problem if we find one */
936
937 #ifdef __WIN32__
938
939 #define MAX_DRIVERS 1024
940
941 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
checkFirewallError(INOUT NET_STREAM_INFO * netStream)942 int checkFirewallError( INOUT NET_STREAM_INFO *netStream )
943 {
944 INSTANCE_HANDLE hPSAPI = NULL_INSTANCE;
945 typedef BOOL ( WINAPI *ENUMDEVICEDRIVERS )( LPVOID *lpImageBase, DWORD cb,
946 LPDWORD lpcbNeeded );
947 typedef DWORD ( WINAPI *GETDEVICEDRIVERBASENAME )( LPVOID ImageBase,
948 LPTSTR lpBaseName,
949 DWORD nSize );
950 ENUMDEVICEDRIVERS pEnumDeviceDrivers;
951 GETDEVICEDRIVERBASENAME pGetDeviceDriverBaseName;
952 LPVOID drivers[ MAX_DRIVERS + 8 ];
953 DWORD cbNeeded;
954 int i;
955
956 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
957
958 /* Use the PSAPI library to check for the presence of firewall filter
959 drivers. Since this operation is rarely performed and is only called
960 as part of an error handler in which performance isn't a major factor
961 we load the library on demand each time (which we'd have to do in any
962 case because it's not supported on older systems) rather than using
963 an on-init load as we do for the networking functions */
964 if( ( hPSAPI = DynamicLoad( "psapi.dll" ) ) == NULL_INSTANCE )
965 return( CRYPT_ERROR_TIMEOUT );
966 pEnumDeviceDrivers = ( ENUMDEVICEDRIVERS ) \
967 GetProcAddress( hPSAPI, "EnumDeviceDrivers" );
968 pGetDeviceDriverBaseName = ( GETDEVICEDRIVERBASENAME ) \
969 GetProcAddress( hPSAPI, "GetDeviceDriverBaseNameA" );
970 if( pEnumDeviceDrivers == NULL || \
971 pGetDeviceDriverBaseName == NULL || \
972 !pEnumDeviceDrivers( drivers, MAX_DRIVERS * sizeof( DWORD ),
973 &cbNeeded ) )
974 {
975 DynamicUnload( hPSAPI );
976 return( CRYPT_ERROR_TIMEOUT );
977 }
978
979 /* Check whether a suspect filter driver is present */
980 for( i = 0; i < cbNeeded / sizeof( DWORD ); i++ )
981 {
982 typedef struct {
983 const char *name;
984 const int nameLen;
985 const BOOLEAN isMcafee;
986 } DRIVER_INFO;
987 static const DRIVER_INFO driverInfoTbl[] = {
988 { "firelm01.sys", 8, TRUE }, /* McAfee Host IPS */
989 { "firehk4x.sys", 8, TRUE }, /* McAfee Host IPS */
990 { "firehk5x.sys", 8, TRUE }, /* McAfee Host IPS */
991 { "fw220.sys", 5, TRUE }, /* McAfee FW */
992 { "mpfirewall.sys", 10, TRUE }, /* McAfee personal FW */
993 { "symtdi.sys", 6, FALSE }, /* Symantec TDI */
994 { "spbbcdrv.sys", 8, FALSE }, /* Norton Personal FW */
995 { "teefer2.sys", 11, FALSE }, /* Norton/Symantec FW */
996 { NULL, 0, FALSE }, { NULL, 0, FALSE }
997 };
998 char driverName[ 256 + 8 ];
999 int driverNameLen, driverIndex;
1000
1001 driverNameLen = pGetDeviceDriverBaseName( drivers[ i ],
1002 driverName, 256 );
1003 if( driverNameLen <= 0 )
1004 continue;
1005 for( driverIndex = 0;
1006 driverInfoTbl[ driverIndex ].name != NULL && \
1007 driverIndex < FAILSAFE_ARRAYSIZE( driverInfoTbl, \
1008 DRIVER_INFO );
1009 driverIndex++ )
1010 {
1011 if( driverNameLen >= driverInfoTbl[ driverIndex ].nameLen && \
1012 !strnicmp( driverName, driverInfoTbl[ driverIndex ].name,
1013 driverInfoTbl[ driverIndex ].nameLen ) )
1014 {
1015 DynamicUnload( hPSAPI );
1016 retExt( CRYPT_ERROR_TIMEOUT,
1017 ( CRYPT_ERROR_TIMEOUT, NETSTREAM_ERRINFO,
1018 "Network data transfer blocked, probably due to "
1019 "%s firewall software installed on the PC",
1020 driverInfoTbl[ driverIndex ].isMcafee ? \
1021 "McAfee" : "Symantec/Norton" ) );
1022 }
1023 }
1024 }
1025 DynamicUnload( hPSAPI );
1026
1027 return( CRYPT_ERROR_TIMEOUT );
1028 }
1029 #else
1030 #define checkFirewallError( netStream ) CRYPT_ERROR_TIMEOUT
1031 #endif /* Win32 */
1032
1033 #if defined( __BEOS__ ) && !defined( BONE_VERSION )
1034
1035 /* BeOS doesn't support checking for anything except readability in select()
1036 and only supports one or two socket options so we define our own versions
1037 of these functions that no-op out unsupported options */
1038
1039 #undef select /* Restore normal select() around the wrapper */
1040
my_select(int socket_range,struct fd_set * read_bits,struct fd_set * write_bits,struct fd_set * exception_bits,struct timeval * timeout)1041 static int my_select( int socket_range, struct fd_set *read_bits,
1042 struct fd_set *write_bits,
1043 struct fd_set *exception_bits,
1044 struct timeval *timeout )
1045 {
1046 /* BeOS doesn't support nonblocking connects, it always waits about a
1047 minute for the connect and then times out, so it we get a wait on a
1048 connecting socket we report it as being successful by exiting with
1049 the fds as set by the caller and a successful return status */
1050 if( read_bits != NULL && write_bits != NULL )
1051 return( 1 );
1052
1053 /* If we're checking for writeability the best that we can do is to
1054 always report the socket as writeable. Since the socket is a
1055 blocking socket the data will (eventually) get written */
1056 if( read_bits == NULL && write_bits != NULL )
1057 {
1058 if( exception_bits != NULL )
1059 FD_ZERO( exception_bits );
1060 return( 1 );
1061 }
1062
1063 /* Since BeOS doesn't support checking for writeability or errors, we
1064 have to clear these values before we call select() so that the
1065 caller won't find anything still set when we return */
1066 if( write_bits != NULL )
1067 FD_ZERO( write_bits );
1068 if( exception_bits != NULL )
1069 FD_ZERO( exception_bits );
1070
1071 return( select( socket_range, read_bits, NULL, NULL, timeout ) );
1072 }
1073
1074 #define select( sockets, readFD, writeFD, exceptFD, timeout ) \
1075 my_select( sockets, readFD, writeFD, exceptFD, timeout )
1076
my_setsockopt(int socket,int level,int option,const void * data,uint size)1077 static int my_setsockopt( int socket, int level, int option,
1078 const void *data, uint size )
1079 {
1080 if( option != SO_NONBLOCK && option != SO_REUSEADDR )
1081 return( 0 );
1082 return( setsockopt( socket, level, option, data, size ) );
1083 }
1084
my_getsockopt(int socket,int level,int option,void * data,uint * size)1085 static int my_getsockopt( int socket, int level, int option,
1086 void *data, uint *size )
1087 {
1088 if( option != SO_ERROR )
1089 return( 0 );
1090 *( ( int * ) data ) = 0; /* Clear return status */
1091
1092 /* It's unclear whether the following setsockopt actually does anything
1093 under BeOS or not. If it fails, the alternative below may work */
1094 #if 1
1095 return( setsockopt( socket, level, option, data, *size ) );
1096 #else
1097 BYTE buffer[ 8 + 8 ];
1098 int count;
1099
1100 count = recv( socket, buffer, 0, 0 );
1101 printf( "recv( 0 ) = %d, errno = %d.\n", count, errno );
1102 if( count < 0 )
1103 *( ( int * ) data ) = errno;
1104 #endif /* 1 */
1105 }
1106 #endif /* BeOS without BONE */
1107
1108 /****************************************************************************
1109 * *
1110 * Network I/O Wait Management *
1111 * *
1112 ****************************************************************************/
1113
1114 /* Wait for I/O to become possible on a socket. The particular use of
1115 select that we employ here is reasonably optimal under load because we're
1116 only asking select() to monitor a single descriptor. There are a variety
1117 of inefficiencies related to select that fall into either the category of
1118 user <-> kernel copying or of descriptor list scanning. For the first
1119 category, when calling select() the system has to copy an entire list of
1120 descriptors into kernel space and then back out again. Large selects can
1121 potentially contain hundreds or thousands of descriptors, which can in
1122 turn involve allocating memory in the kernel and freeing it on return.
1123 We're only using one so the amount of data to copy is minimal.
1124
1125 The second category involves scanning the descriptor list, an O(n)
1126 activity. First the kernel has to scan the list to see whether there's
1127 pending activity on a descriptor. If there aren't any descriptors with
1128 activity pending it has to update the descriptor's selinfo entry in the
1129 event that the calling process calls tsleep() (used to handle event-based
1130 process blocking in the kernel) while waiting for activity on the
1131 descriptor. After the select() returns or the process is woken up from a
1132 tsleep() the user process in turn has to scan the list to see which
1133 descriptors the kernel indicated as needing attention. As a result, the
1134 list has to be scanned three times.
1135
1136 These problems arise because select() (and it's cousin poll()) are
1137 stateless by design so everything has to be recalculated on each call.
1138 After various false starts the kqueue interface is now seen as the best
1139 solution to this problem. However cryptlib's use of only a single
1140 descriptor per select() avoids the need to use system-specific and rather
1141 non-portable interfaces like kqueue (and earlier alternatives like Sun's
1142 /dev/poll, FreeBSD's get_next_event(), and SGI's /dev/imon) */
1143
1144 typedef enum {
1145 IOWAIT_NONE, /* No I/O wait type */
1146 IOWAIT_READ, /* Wait for read availability */
1147 IOWAIT_WRITE, /* Wait for write availability */
1148 IOWAIT_CONNECT, /* Wait for connect to complete */
1149 IOWAIT_ACCEPT, /* Wait for accept to complete */
1150 IOWAIT_LAST /* Last possible wait type */
1151 } IOWAIT_TYPE;
1152
1153 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
ioWait(INOUT NET_STREAM_INFO * netStream,IN_INT_Z const int timeout,const BOOLEAN previousDataRead,IN_ENUM (IOWAIT)const IOWAIT_TYPE type)1154 static int ioWait( INOUT NET_STREAM_INFO *netStream,
1155 IN_INT_Z const int timeout,
1156 const BOOLEAN previousDataRead,
1157 IN_ENUM( IOWAIT ) const IOWAIT_TYPE type )
1158 {
1159 static const struct {
1160 const int status;
1161 const char *errorString;
1162 } errorInfo[] = {
1163 { CRYPT_ERROR_OPEN, "unknown" },
1164 { CRYPT_ERROR_READ, "read" }, /* IOWAIT_READ */
1165 { CRYPT_ERROR_WRITE, "write" }, /* IOWAIT_WRITE */
1166 { CRYPT_ERROR_OPEN, "connect" }, /* IOWAIT_CONNECT */
1167 { CRYPT_ERROR_OPEN, "accept" }, /* IOWAIT_ACCEPT */
1168 { CRYPT_ERROR_OPEN, "unknown" }, { CRYPT_ERROR_OPEN, "unknown" }
1169 };
1170 MONOTIMER_INFO timerInfo;
1171 struct timeval tv;
1172 fd_set readfds, writefds, exceptfds;
1173 fd_set *readFDPtr = ( type == IOWAIT_READ || \
1174 type == IOWAIT_CONNECT || \
1175 type == IOWAIT_ACCEPT ) ? &readfds : NULL;
1176 fd_set *writeFDPtr = ( type == IOWAIT_WRITE || \
1177 type == IOWAIT_CONNECT ) ? &writefds : NULL;
1178 int selectIterations = 0, status;
1179
1180 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
1181
1182 REQUIRES( timeout >= 0 && timeout < MAX_INTLENGTH );
1183 REQUIRES( type > IOWAIT_NONE && type < IOWAIT_LAST );
1184
1185 /* Check for overflows in FD_SET(). This is an ugly implementation
1186 issue in which, for sufficiently badly-implemented FD_SET() macros
1187 (and there are plenty of these around), the macro will just take the
1188 provided socket descriptor and use it to index the fd_set bitmask.
1189 This occurs for the most common implementations under Unix (BSD) and
1190 BSD-derived embedded OSes, Windows gets it right and uses a bounds-
1191 checked array.
1192
1193 The maximum socket descriptor is normally given by FD_SETSIZE,
1194 typically 64 under Windows (but we don't have to worry this since it
1195 does FD_SET() right) and 256 or sometimes 1024 under Unix, however
1196 this can be increased explicitly using setrlimit() or, from the
1197 shell, 'ulimit -n 512' to make it 512, which will cause an overflow.
1198 To deal with this, we reject any socket values less than zero (if
1199 it's a signed variable) or greater than FD_SETSIZE */
1200 #ifndef __WINDOWS__
1201 REQUIRES( netStream->netSocket >= 0 && \
1202 netStream->netSocket <= FD_SETSIZE );
1203 #endif /* !Windows */
1204
1205 /* Set up the information needed to handle timeouts and wait on the
1206 socket. If there's no timeout, we wait at least 5ms on the theory
1207 that it isn't noticeable to the caller but ensures that we at least
1208 get a chance to get anything that may be pending.
1209
1210 The exact wait time depends on the system, but usually it's quantised
1211 to the system timer quantum. This means that on Unix systems with a
1212 1ms timer resolution the wait time is quantised on a 1ms boundary.
1213 Under everything newer than early Windows NT systems it's quantised
1214 on a 10ms boundary (some early NT systems had a granularity ranging
1215 from 7.5 - 15ms but all newer systems use 10ms) and for Win95/98/ME
1216 it was quantised on a 55ms boundary. In other words when performing
1217 a select() on a Win95 box it would either return immediately or wait
1218 some multiple of 55ms even with the time set to 1ms, but we don't
1219 have to worry about those Windows versions any more.
1220
1221 In theory we shouldn't have to reset either the fds or the timeval
1222 each time through the loop since we're only waiting on one descriptor
1223 so it's always set and the timeval is a const, however some versions
1224 of Linux can update it if the select fails due to an EINTR (which is
1225 the exact reason why we'd be going through the loop a second time in
1226 the first place) and/or if a file descriptor changes status (e.g. due
1227 to data becoming available) so we have to reset it each time to be on
1228 the safe side. It would actually be nice if the tv value were
1229 updated reliably to reflect how long the select() had to wait since
1230 it'd provide a nice source of entropy for the randomness pool (we
1231 could simulate this by readig a high-res timer before and after the
1232 select() but that would adds a pile of highly system-dependent code
1233 and defeat the intent of making use of using the "free" entropy
1234 that's provided as a side-effect of the select().
1235
1236 The wait on connect is a slightly special case, the socket will
1237 become writeable if the connect succeeds normally, but both readable
1238 and writeable if there's an error on the socket or if there's data
1239 already waiting on the connection (i.e. it arrives as part of the
1240 connect). It's up to the caller to check for these conditions */
1241 status = setMonoTimer( &timerInfo, timeout );
1242 if( cryptStatusError( status ) )
1243 return( status );
1244 do
1245 {
1246 if( readFDPtr != NULL )
1247 {
1248 FD_ZERO( readFDPtr );
1249 FD_SET( netStream->netSocket, readFDPtr );
1250 }
1251 if( writeFDPtr != NULL )
1252 {
1253 FD_ZERO( writeFDPtr );
1254 FD_SET( netStream->netSocket, writeFDPtr );
1255 }
1256 FD_ZERO( &exceptfds );
1257 FD_SET( netStream->netSocket, &exceptfds );
1258 tv.tv_sec = timeout;
1259 tv.tv_usec = ( timeout <= 0 ) ? 5000 : 0;
1260
1261 /* See if we can perform the I/O */
1262 status = select( netStream->netSocket + 1, readFDPtr, writeFDPtr,
1263 &exceptfds, &tv );
1264
1265 /* If there's a problem and it's not something transient like an
1266 interrupted system call, exit. For a transient problem, we just
1267 retry the select until the overall timeout expires */
1268 if( isSocketError( status ) && !isRestartableError() )
1269 {
1270 int dummy;
1271
1272 return( getSocketError( netStream, errorInfo[ type ].status,
1273 &dummy ) );
1274 }
1275 }
1276 while( isSocketError( status ) && \
1277 !checkMonoTimerExpired( &timerInfo ) && \
1278 selectIterations++ < FAILSAFE_ITERATIONS_MED );
1279 if( selectIterations > FAILSAFE_ITERATIONS_MED )
1280 {
1281 char errorMessage[ 128 + 8 ];
1282 int errorMessageLength;
1283
1284 /* We've gone through the select loop a suspiciously large number
1285 of times, there's something wrong. In theory we could report
1286 this as a more serious error than a simple timeout since it means
1287 that there's either a bug in our code or a bug in the select()
1288 implementation, but without knowing in advance what caused this
1289 can't-occur condition it's difficult to anticipate the correct
1290 action to take, so all that we do is warn in the debug build */
1291 DEBUG_DIAG(( "select() went through %d iterations without "
1292 "returning data", FAILSAFE_ITERATIONS_MED ));
1293 assert( DEBUG_WARN );
1294 errorMessageLength = sprintf_s( errorMessage, 128,
1295 "select() on %s went through %d "
1296 "iterations without returning a "
1297 "result",
1298 errorInfo[ type ].errorString,
1299 selectIterations );
1300 return( setSocketError( netStream, errorMessage, errorMessageLength,
1301 CRYPT_ERROR_TIMEOUT, FALSE ) );
1302 }
1303
1304 /* If the wait timed out, either explicitly in the select (status == 0)
1305 or implicitly in the wait loop (isSocketError()), report it as a
1306 select() timeout error */
1307 if( status == 0 || isSocketError( status ) )
1308 {
1309 char errorMessage[ 128 + 8 ];
1310 int errorMessageLength;
1311
1312 /* If we've already received data from a previous I/O, tell the
1313 caller to use that as the transferred byte count even though we
1314 timed out this time round */
1315 if( previousDataRead )
1316 return( OK_SPECIAL );
1317
1318 /* If it's a nonblocking wait (usually used as a poll to determine
1319 whether I/O is possible) then a timeout isn't an error (this can
1320 be distinguished from the previous OK_SPECIAL return by whether
1321 previousDataRead is set or not) */
1322 if( timeout <= 0 )
1323 return( OK_SPECIAL );
1324
1325 /* The select() timed out, exit */
1326 errorMessageLength = sprintf_s( errorMessage, 128,
1327 "Timeout on %s (select()) after %d "
1328 "second%s",
1329 errorInfo[ type ].errorString,
1330 timeout, ( timeout > 1 ) ? "s" : "" );
1331 ENSURES( errorMessageLength > 0 && \
1332 errorMessageLength < 128 );
1333 return( setSocketError( netStream, errorMessage, errorMessageLength,
1334 CRYPT_ERROR_TIMEOUT, FALSE ) );
1335 }
1336
1337 /* If there's an exception condition on a socket, exit. This is
1338 implementation-specific, traditionally under Unix this only indicates
1339 the arrival of out-of-band data rather than any real error condition,
1340 but in some cases it can be used to signal errors. In these cases we
1341 have to explicitly check for an exception condition because some
1342 types of errors will result in select() timing out waiting for
1343 readability rather than indicating an error and returning. In
1344 addition for OOB data we could just ignore the notification (which
1345 happens automatically with the default setting of SO_OOBINLINE =
1346 false and a socket owner to receive SIGURG's not set, the OOB data
1347 byte just languishes in a side-buffer), however we shouldn't be
1348 receiving OOB data so we treat that as an error too */
1349 if( FD_ISSET( netStream->netSocket, &exceptfds ) )
1350 {
1351 int socketErrorCode;
1352
1353 status = getSocketError( netStream, errorInfo[ type ].status,
1354 &socketErrorCode );
1355 if( socketErrorCode != 0 )
1356 return( status );
1357
1358 /* We got a no-error error code even though there's an exception
1359 condition present, this typically only happens under Windows.
1360 The most common case is when we're waiting on a nonblocking
1361 connect (type = IOWAIT_CONNECT), in which case a failure to
1362 connect due to e.g. an ECONNREFUSED can be reported as a select()
1363 error. This is a bit tricky to report on because we can't be
1364 sure what the actual problem is without adding our own timer
1365 handling, in which case a fast reject would be due to an explicit
1366 notification like ECONNREFUSED while a slow reject might be an
1367 ENETUNREACH or something similar (a genuine timeout error should
1368 have been caught by the "wait timed out" code above). Another
1369 option is to retry the connect as a blocking one to get a genuine
1370 error code, but that defeats the point of using a nonblocking
1371 connect to deal with problem conditions.
1372
1373 The conflict here is between an honest but rather useless
1374 CRYPT_ERROR_OPEN and a guessed and far more useful, but
1375 potentially misleading, ECONNREFUSED. Given that this is an
1376 oddball condition to begin with it's unclear how far we should
1377 go down this rathole, for now we assume an ECONNREFUSED */
1378 if( type == IOWAIT_CONNECT )
1379 {
1380 ( void ) mapError( netStream, NONBLOCKCONNECT_ERROR, FALSE,
1381 CRYPT_ERROR_OPEN );
1382 return( status );
1383 }
1384
1385 /* This is probably a mis-handled select() timeout, which can happen
1386 with Winsock under certain circumstances and seems to be related
1387 to another socket-using application performing network I/O at the
1388 same time as we do the select() wait. Non-Winsock cases can occur
1389 because some implementations don't treat a soft timeout as an
1390 error, and at least one (Tandem) returns EINPROGRESS rather than
1391 ETIMEDOUT, so we insert a timeout error code ourselves.
1392
1393 Since we're merely updating the extended internal error
1394 information (we already know what the actual error status is) we
1395 don't need to do anything with the mapError() return value */
1396 ( void ) mapError( netStream, TIMEOUT_ERROR, FALSE,
1397 CRYPT_ERROR_TIMEOUT );
1398 return( status );
1399 }
1400
1401 /* The socket is read for reading or writing */
1402 ENSURES( status > 0 );
1403 ENSURES( ( type == IOWAIT_READ && \
1404 FD_ISSET( netStream->netSocket, &readfds ) ) || \
1405 ( type == IOWAIT_WRITE && \
1406 FD_ISSET( netStream->netSocket, &writefds ) ) || \
1407 ( type == IOWAIT_CONNECT && \
1408 ( FD_ISSET( netStream->netSocket, &readfds ) || \
1409 FD_ISSET( netStream->netSocket, &writefds ) ) ) || \
1410 ( type == IOWAIT_ACCEPT ) );
1411 return( CRYPT_OK );
1412 }
1413
1414 /****************************************************************************
1415 * *
1416 * Network Diganostic Routines *
1417 * *
1418 ****************************************************************************/
1419
1420 /* If a socket open fails we generally can't provide much information to the
1421 caller beyond "socket open failed". This occurs for two reasons, the
1422 first being that the network stack dumbs down a lot of the lower-level
1423 error information that's returned in the case of a problem (for example
1424 ICMP error codes 0, 1, and 5-12 are all combined into "No route to host",
1425 2 and 3 both become "Connection refused", and parameter problem
1426 notifications all become "Protocol not available". The second reason is
1427 that the caller may be connecting to the wrong port or some similar
1428 operator error.
1429
1430 To deal with this we perform an opportunistic ping of the first address
1431 associated with the name to see if the ICMP reply can tell us more about
1432 what's wrong */
1433
1434 #define getIPVersion( value ) ( ( ( value ) & 0xF0 ) >> 4 )
1435 #define getIP4HeaderLength( value ) ( ( ( value ) & 0x0F ) << 2 )
1436 #define PACKET_OFFSET_IPVERSION 0 /* Offset of IP version field */
1437 #define PACKET_OFFSET_NEXTHEADER 6 /* Offset of IPv6 next-header field */
1438 #define PACKET_OFFSET_PROTOCOL 9 /* Offset of IPv4 protocol field */
1439 #define IP4_MIN_HEADERSIZE 20 /* Minimum IPv4 header size */
1440 #define IP6_HEADERSIZE 40 /* IPv6 header size */
1441 #define ICMP_MIN_PACKETSIZE 8 /* Minimum ICMP packet size */
1442 #define ICMP_TYPE_ECHO_REPLY 0 /* ICMP packet type = echo reply */
1443
1444 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
diagnoseConnectionProblem(INOUT NET_STREAM_INFO * netStream,IN_BUFFER (hostNameLen)const char * host,IN_LENGTH_DNS const int hostNameLen,IN_ERROR const int originalStatus)1445 static int diagnoseConnectionProblem( INOUT NET_STREAM_INFO *netStream,
1446 IN_BUFFER( hostNameLen ) const char *host,
1447 IN_LENGTH_DNS const int hostNameLen,
1448 IN_ERROR const int originalStatus )
1449 {
1450 NET_STREAM_INFO diagnosticNetStream;
1451 SOCKET netSocket = INVALID_SOCKET;
1452 static const BYTE pingPacket[] = {
1453 0x08, /* Type 8 = Echo request */
1454 0x00, /* Code 0 */
1455 0xF7, 0xFF, /* Checksum, ~0x0800 */
1456 0x00, 0x00, /* Unique ID */
1457 0x00, 0x00 /* Sequence number */
1458 };
1459 BYTE buffer[ 512 + 8 ];
1460 struct addrinfo *addrInfoPtr, *addrInfoCursor;
1461 int addressCount, length DUMMY_INIT, offset, status;
1462
1463 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
1464 assert( isReadPtr( host, hostNameLen ) );
1465
1466 REQUIRES( hostNameLen > 0 && hostNameLen <= MAX_DNS_SIZE );
1467 REQUIRES( cryptStatusError( originalStatus ) );
1468
1469 /* Create an ICMP socket (we use a dummy port of 514 for the address
1470 lookup which for UDP is the syslog port, ICMP itself doesn't use
1471 ports). Under Unix only the superuser can create raw sockets (a
1472 restriction dating back to the "if it's on a port < 1024 then you
1473 can trust it because root on that machine and I were at Oxford
1474 together" days designed to prevent users sending custom packets
1475 onto the net) so this will only work on non-Unix systems, but since
1476 what we're doing here is opportunistic anyway there's no great need
1477 to make it work everywhere.
1478
1479 We also always use ICMPv4 (via the hardcoded IPPROTO_ICMP rather than
1480 choosing IPPROTO_ICMPV6), which also simplifies other special-case
1481 handling such as the fact that for an ICMPv6 socket the checksum is
1482 calculated for us since there's an additional pseudo-header included
1483 while for ICMPv4 we have to calculate it ourselves), since again this
1484 is an opportunistic probe and IPv4 is the one most likely to work.
1485
1486 Finally, as mentioned in the comment at the start of this function,
1487 we only try for the first address rather than trying to iterate
1488 through everything that's potentially available */
1489 status = getAddressInfo( netStream, &addrInfoPtr, host, hostNameLen,
1490 514, FALSE, TRUE );
1491 if( cryptStatusError( status ) )
1492 return( originalStatus );
1493 ANALYSER_HINT( addrInfoPtr != NULL );
1494 for( addrInfoCursor = addrInfoPtr, addressCount = 0;
1495 addrInfoCursor != NULL && addressCount < IP_ADDR_COUNT;
1496 addrInfoCursor = addrInfoCursor->ai_next, addressCount++ )
1497 {
1498 /* If it's not an IPv4 address, continue */
1499 if( addrInfoCursor->ai_family != AF_INET )
1500 continue;
1501
1502 /* We've found an IPv4 address, create a socket for it */
1503 netSocket = socket( addrInfoCursor->ai_family, SOCK_RAW,
1504 IPPROTO_ICMP );
1505 break;
1506 }
1507 if( isBadSocket( netSocket ) )
1508 {
1509 freeAddressInfo( addrInfoPtr );
1510 return( originalStatus );
1511 }
1512
1513 /* Send a rudimentary ping packet to the remote system. Apart from
1514 making the checksum calculation easier, the minimal packet size also
1515 means that we sidestep any potential MTU/fragmentation issues. Note
1516 that we don't connect() the remote system's port and address to the
1517 socket (if that's even possible for a raw/ICMP socket) because we
1518 want to receive all ICMP messages sent to us, not just something
1519 returned from the specific remote system that we're targeting */
1520 status = sendto( netSocket, pingPacket, 8, 0, addrInfoCursor->ai_addr,
1521 addrInfoCursor->ai_addrlen );
1522 if( isSocketError( status ) )
1523 {
1524 closesocket( netSocket );
1525 freeAddressInfo( addrInfoPtr );
1526 return( originalStatus );
1527 }
1528
1529 /* Try and read the ping response. We don't go to too much trouble in
1530 terms of handling exception conditions here since this is an
1531 opportunistic check only, so we only send a single ping with a 10s
1532 timeout.
1533
1534 The details of what we get back for a raw socket get rather complex.
1535 In general raw sockets can end up receiving most non-TCP/UDP packets
1536 (that is, most ICMP/IGMP and all unknown-protocol packets), however
1537 by explicitly selecting IPPROTO_ICMP we've told the kernel that we
1538 only want to get ICMP packets. However since we haven't bound the
1539 socket to a remote address (see the comment for sendto() above) we're
1540 going to get copies of all ICMP packets that arrive, not just our
1541 ones. This makes things a bit complicated since we can't easily
1542 tell whether an incoming ICMP error packet from an address other than
1543 the target address is from (say) a router telling us that our ping
1544 can't get through or something related to network traffic from
1545 another process on the system.
1546
1547 Under IPv6 we could perform additional filtering with:
1548
1549 #include <netinet/icmp6.h>
1550
1551 struct icmp6_filter filter;
1552
1553 ICMP6_FILTER_SETBLOCKALL( &filter );
1554 ICMP6_FILTER_SETPASS( ND_xxx, &filter );
1555 setsockopt( socket, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1556 sizeof( filter ) );
1557
1558 Even then we have to be careful because there's a race condition,
1559 ICMP packets that arrive between the socket() and setsockopt() will
1560 be enqueued for the raw socket, the filtering is a performance
1561 optimisation rather than an absolute block-list */
1562 memset( &diagnosticNetStream, 0, sizeof( NET_STREAM_INFO ) );
1563 diagnosticNetStream.netSocket = netSocket;
1564 status = ioWait( &diagnosticNetStream, 10, TRUE, IOWAIT_READ );
1565 if( cryptStatusOK( status ) )
1566 {
1567 struct sockaddr recvAddr;
1568 int recvAddrSize = sizeof( struct sockaddr );
1569
1570 /* Read the response data. For the reason given above, we only try
1571 and read the first 512 bytes of response, ignore ICMP checksum
1572 problems (other layers should be taking care of this, IPv6 removes
1573 the checksums entirely for this reason), and don't check whether
1574 the response came from the intended source (which we could do by
1575 comparing addrInfoCursor->ai_addr->sa_data with recvAddr.sa_data)
1576 since it could be an ICMP error message from an intermediate
1577 system. Performing this address check would also cause problems
1578 if the server was multihomed, so if the incoming socket is bound
1579 to the wildcard address and our packet is sent to a non-primary
1580 address (alias) but comes back from the primary address then we'll
1581 appear to have a non-match */
1582 status = length = recvfrom( netSocket, buffer, 512, 0, &recvAddr,
1583 &recvAddrSize );
1584 if( isSocketError( status ) || \
1585 length < IP4_MIN_HEADERSIZE + ICMP_MIN_PACKETSIZE || \
1586 length > 512 )
1587 status = CRYPT_ERROR_READ; /* Convert to cryptlib error */
1588 }
1589 closesocket( netSocket );
1590 freeAddressInfo( addrInfoPtr );
1591 if( cryptStatusError( status ) )
1592 return( originalStatus );
1593
1594 /* Postcondition: We've read enough data for an ICMP packet */
1595 ENSURES( length >= IP4_MIN_HEADERSIZE + ICMP_MIN_PACKETSIZE && \
1596 length <= 512 );
1597
1598 /* We got back some sort of ICMP response. Unfortunately despite the
1599 fact that this is an IPPROTO_ICMP socket, what we get back is a raw
1600 IP packet (due to the use of SOCK_RAW), so first we have to pick
1601 apart the IP packet to find the ICMP packet within it:
1602
1603 +-----------+-----------+-----------+-----------+
1604 | IPv4 hdr | IPv4 opts | ICMPv4 hdr| ICMP data |
1605 +-----------+-----------+-----------+-----------+
1606 |<-- 20 --> |<- 0..40 ->|<--- 8 --->| */
1607 if( getIPVersion( buffer[ PACKET_OFFSET_IPVERSION ] ) == 4 )
1608 {
1609 const int headerLength = getIP4HeaderLength( buffer[ 0 ] );
1610
1611 /* Make sure that we've got enough data for an ICMP reply back */
1612 if( headerLength < IP4_MIN_HEADERSIZE || \
1613 headerLength > length - ICMP_MIN_PACKETSIZE )
1614 return( originalStatus );
1615
1616 /* Now make sure that we've got an ICMP reply */
1617 if( buffer[ PACKET_OFFSET_PROTOCOL ] != IPPROTO_ICMP )
1618 return( originalStatus );
1619
1620 offset = headerLength;
1621 }
1622 else
1623 {
1624 /* It wasn't IPv4, check for an IPv6 packet and make sure that we've
1625 got enough data for an ICMP reply:
1626
1627 +-----------+-----------+-----------+
1628 | IPv6 hdr | ICMPv6 hdr| ICMP data |
1629 +-----------+-----------+-----------+
1630 |<-- 40 --> |<--- 8 --->| */
1631 if( getIPVersion( buffer[ PACKET_OFFSET_IPVERSION ] ) != 6 || \
1632 length < IP6_HEADERSIZE + ICMP_MIN_PACKETSIZE )
1633 return( originalStatus );
1634
1635 /* Now make sure that we've got an ICMP reply. The latter serves
1636 two purposes, it checks that we have what we're after and it
1637 rejects packets with extra extension headers between the IPv6
1638 header and the payload, which we don't bother trying to parse */
1639 if( buffer[ PACKET_OFFSET_NEXTHEADER ] != IPPROTO_ICMP )
1640 return( originalStatus );
1641
1642 offset = IP6_HEADERSIZE;
1643 }
1644
1645 /* Report the result of the ICMP ping to the caller */
1646 if( buffer[ offset ] == ICMP_TYPE_ECHO_REPLY )
1647 {
1648 retExtErrAlt( originalStatus,
1649 ( originalStatus, NETSTREAM_ERRINFO,
1650 ", however an ICMP ping to the host succeeded, "
1651 "indicating that the host is up" ) );
1652 }
1653 retExtErrAlt( originalStatus,
1654 ( originalStatus, NETSTREAM_ERRINFO,
1655 ", and an ICMP ping to the host returned ICMP packet "
1656 "type %d, code %d", buffer[ offset ],
1657 buffer[ offset + 1 ] ) );
1658 }
1659
1660 /****************************************************************************
1661 * *
1662 * Network Socket Manager *
1663 * *
1664 ****************************************************************************/
1665
1666 /* cryptlib's separation kernel causes some problems with objects that use
1667 sockets because it doesn't allow sharing of sockets, which is a problem
1668 because the Unix server programming model assumes that a single process
1669 will listen on a socket and fork off children to handle incoming
1670 connections (in fact the accept() function more or less forces you to do
1671 this whether you want to or not). A second problem occurs because when a
1672 thread is blocked in an object waiting on a socket there's no way to
1673 unblock it apart from killing the thread (actually we could create some
1674 sort of lookback socket and wait for it alongside the listen socket in
1675 the pre-accept select wait, signalling a shutdown by closing the loopback
1676 socket, but this starts to get ugly). In order to work around this we
1677 maintain a socket pool that serves two functions:
1678
1679 - Maintains a list of sockets that an object is listening on to allow a
1680 listening socket to be reused rather than having to listen on a
1681 socket and close it as soon as an incoming connection is made in
1682 order to switch to the connected socket.
1683
1684 - Allows sockets to be closed from another thread, which results in any
1685 objects waiting on them being woken up and exiting.
1686
1687 For now we limit the socket pool to a maximum of 256 sockets (16 in
1688 resource-constrained environments) both as a safety feature to protect
1689 against runaway use of sockets in the calling application and because
1690 cryptlib was never designed to function as a high-volume server
1691 application. If necessary this can be changed to dynamically expand the
1692 socket pool in the same way that the kernel dynamically expands its
1693 object table. However it's not a good idea to simply remove the
1694 restriction entirely (or set it to too high a value) because this can
1695 cause problems with excess consumption of kernel resources. For example
1696 under Windows opening several tens of thousands of connections will
1697 eventually return WSAENOBUFS when the nonpaged pool is exhausted. At
1698 this point things start to get problematic because many drivers don't
1699 handle the inability to allocate memory very well, and can start to fail
1700 and render the whole system unstable. This is a general resource-
1701 consumption problem that affects all users of the shared nonpaged pool,
1702 but we can at least make sure that we're not the cause of any crashes by
1703 limiting our own consumption */
1704
1705 #ifdef CONFIG_CONSERVE_MEMORY
1706 #define SOCKETPOOL_SIZE 16
1707 #else
1708 #define SOCKETPOOL_SIZE 256
1709 #endif /* CONFIG_CONSERVE_MEMORY */
1710
1711 typedef struct {
1712 SOCKET netSocket; /* Socket handle */
1713 int refCount; /* Reference count for the socket */
1714 int iChecksum; /* Family, interface, and port */
1715 BYTE iData[ 32 + 8 ]; /* info for server socket */
1716 size_t iDataLen;
1717 } SOCKET_INFO;
1718
1719 static SOCKET_INFO *socketInfo;
1720 static const SOCKET_INFO SOCKET_INFO_TEMPLATE = \
1721 { INVALID_SOCKET, 0, 0, { 0 }, 0 };
1722
1723 /* Initialise and shut down the socket pool */
1724
1725 CHECK_RETVAL \
initSocketPool(void)1726 static int initSocketPool( void )
1727 {
1728 int i;
1729
1730 /* Allocate and clear the socket pool */
1731 if( ( socketInfo = \
1732 clAlloc( "initSocketPool", SOCKETPOOL_SIZE * \
1733 sizeof( SOCKET_INFO ) ) ) == NULL )
1734 return( CRYPT_ERROR_MEMORY );
1735 for( i = 0; i < SOCKETPOOL_SIZE; i++ )
1736 socketInfo[ i ] = SOCKET_INFO_TEMPLATE;
1737
1738 return( CRYPT_OK );
1739 }
1740
endSocketPool(void)1741 static void endSocketPool( void )
1742 {
1743 clFree( "endSocketPool", socketInfo );
1744 }
1745
1746 /* Create/add and remove a socket to/from the pool. The difference between
1747 creating and adding a socket is that newSocket() creates and adds a
1748 completely new socket while addSocket() adds an externally-created (via
1749 accept()) socket */
1750
1751 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
newSocket(OUT SOCKET * newSocketPtr,const struct addrinfo * addrInfoPtr,const BOOLEAN isServer)1752 static int newSocket( OUT SOCKET *newSocketPtr,
1753 const struct addrinfo *addrInfoPtr,
1754 const BOOLEAN isServer )
1755 {
1756 SOCKET netSocket;
1757 int iCheck DUMMY_INIT, i, status;
1758
1759 assert( isWritePtr( newSocketPtr, sizeof( SOCKET ) ) );
1760 assert( isReadPtr( addrInfoPtr, sizeof( struct addrinfo ) ) );
1761
1762 /* Clear return value */
1763 *newSocketPtr = INVALID_SOCKET;
1764
1765 /* Perform any required pre-calculations before we acquire the mutex */
1766 if( isServer )
1767 {
1768 iCheck = checksumData( addrInfoPtr->ai_addr,
1769 addrInfoPtr->ai_addrlen );
1770 }
1771
1772 status = krnlEnterMutex( MUTEX_SOCKETPOOL );
1773 if( cryptStatusError( status ) )
1774 return( status );
1775
1776 /* If this is a server socket (i.e. one bound to a specific interface and
1777 port), check to see whether there's already a socket bound here and if
1778 there is, return the existing socket rather than creating a new one.
1779 This check isn't currently totally foolproof since it compares some
1780 nonessential fields that may differ for otherwise identical sockets
1781 (it's difficult to do this in a clean manner because the comparison
1782 becomes very protocol- and implementation-specific). A workaround
1783 would be to check whether the sin_family is AF_INET or AF_INET6 and
1784 perform an appropriate situation-specific comparison, but this will
1785 break the nice portability that was added by the RFC 2553
1786 reorganisation of socket functions for IPv6 */
1787 if( isServer )
1788 {
1789 for( i = 0; i < SOCKETPOOL_SIZE; i++ )
1790 {
1791 if( socketInfo[ i ].refCount > 0 && \
1792 socketInfo[ i ].iChecksum == iCheck && \
1793 socketInfo[ i ].iDataLen == addrInfoPtr->ai_addrlen && \
1794 !memcmp( socketInfo[ i ].iData, addrInfoPtr->ai_addr,
1795 addrInfoPtr->ai_addrlen ) )
1796 {
1797 if( socketInfo[ i ].refCount >= 10000 )
1798 {
1799 krnlExitMutex( MUTEX_SOCKETPOOL );
1800 DEBUG_DIAG(( "Socket in pool has reference count > 10,000" ));
1801 assert( DEBUG_WARN );
1802 return( CRYPT_ERROR_OVERFLOW );
1803 }
1804 ENSURES( socketInfo[ i ].refCount > 0 && \
1805 socketInfo[ i ].refCount < 10000 );
1806 ENSURES( !isBadSocket( socketInfo[ i ].netSocket ) );
1807 socketInfo[ i ].refCount++;
1808 *newSocketPtr = socketInfo[ i ].netSocket;
1809 krnlExitMutex( MUTEX_SOCKETPOOL );
1810
1811 /* The socket already exists, don't perform any further
1812 initialisation with it */
1813 return( CRYPT_OK );
1814 }
1815 }
1816 }
1817
1818 /* Create a new socket entry */
1819 for( i = 0; i < SOCKETPOOL_SIZE; i++ )
1820 {
1821 /* Check whether this is a zombie socket that we couldn't close
1822 earlier, usually due to written data being left in the TCP/IP
1823 stack. As a result it's probably trapped in the TIME_WAIT
1824 state, so we periodically try and close it to free up the
1825 resource */
1826 if( socketInfo[ i ].refCount <= 0 && \
1827 !isBadSocket( socketInfo[ i ].netSocket ) )
1828 {
1829 status = closesocket( socketInfo[ i ].netSocket );
1830 if( !isSocketError( status ) )
1831 socketInfo[ i ] = SOCKET_INFO_TEMPLATE;
1832 }
1833
1834 if( isBadSocket( socketInfo[ i ].netSocket ) )
1835 break;
1836 }
1837 if( i >= SOCKETPOOL_SIZE )
1838 {
1839 krnlExitMutex( MUTEX_SOCKETPOOL );
1840 DEBUG_DIAG(( "Tried to add more than %d sockets to socket pool",
1841 SOCKETPOOL_SIZE ));
1842 assert( DEBUG_WARN );
1843 return( CRYPT_ERROR_OVERFLOW ); /* Should never happen */
1844 }
1845 netSocket = socket( addrInfoPtr->ai_family,
1846 addrInfoPtr->ai_socktype, 0 );
1847 if( isBadSocket( netSocket ) )
1848 {
1849 krnlExitMutex( MUTEX_SOCKETPOOL );
1850 return( CRYPT_ERROR_OPEN );
1851 }
1852 socketInfo[ i ].netSocket = netSocket;
1853 if( isServer )
1854 {
1855 const int addrInfoSize = min( addrInfoPtr->ai_addrlen, 32 );
1856
1857 /* Remember the details for this socket so that we can detect another
1858 attempt to bind to it */
1859 socketInfo[ i ].iChecksum = checksumData( addrInfoPtr->ai_addr,
1860 addrInfoPtr->ai_addrlen );
1861 memcpy( socketInfo[ i ].iData, addrInfoPtr->ai_addr,
1862 addrInfoSize );
1863 socketInfo[ i ].iDataLen = addrInfoSize;
1864 }
1865 socketInfo[ i ].refCount = 1;
1866 *newSocketPtr = netSocket;
1867
1868 /* If we're creating a new server socket we can't unlock the socket info
1869 yet because we need to bind it to a port before we do anything else
1870 with it. If we were to unlock the socket info another thread could
1871 perform an accept() on the incompletely set up socket, so we return
1872 with the socket info still locked. When the caller has finished
1873 setting it up they call newSocketDone() to signal that the socket is
1874 now really ready for use */
1875 if( isServer )
1876 return( OK_SPECIAL );
1877
1878 krnlExitMutex( MUTEX_SOCKETPOOL );
1879
1880 return( CRYPT_OK );
1881 }
1882
newSocketDone(void)1883 static void newSocketDone( void )
1884 {
1885 /* The caller has finished setting up a new server socket, unlock the
1886 socket info to allow others to access it */
1887 krnlExitMutex( MUTEX_SOCKETPOOL );
1888 }
1889
1890 CHECK_RETVAL \
addSocket(const SOCKET netSocket)1891 static int addSocket( const SOCKET netSocket )
1892 {
1893 int i, status;
1894
1895 REQUIRES( !isBadSocket( netSocket ) );
1896
1897 status = krnlEnterMutex( MUTEX_SOCKETPOOL );
1898 if( cryptStatusError( status ) )
1899 return( status );
1900
1901 /* Add an existing socket entry */
1902 for( i = 0; i < SOCKETPOOL_SIZE; i++ )
1903 {
1904 if( isBadSocket( socketInfo[ i ].netSocket ) )
1905 break;
1906 }
1907 if( i >= SOCKETPOOL_SIZE )
1908 {
1909 krnlExitMutex( MUTEX_SOCKETPOOL );
1910 DEBUG_DIAG(( "Tried to add more than %d sockets to socket pool",
1911 SOCKETPOOL_SIZE ));
1912 assert( DEBUG_WARN );
1913 return( CRYPT_ERROR_OVERFLOW );
1914 }
1915 socketInfo[ i ] = SOCKET_INFO_TEMPLATE;
1916 socketInfo[ i ].netSocket = netSocket;
1917 socketInfo[ i ].refCount = 1;
1918
1919 krnlExitMutex( MUTEX_SOCKETPOOL );
1920
1921 return( CRYPT_OK );
1922 }
1923
deleteSocket(const SOCKET netSocket)1924 static void deleteSocket( const SOCKET netSocket )
1925 {
1926 int i, status;
1927
1928 REQUIRES_V( !isBadSocket( netSocket ) );
1929
1930 status = krnlEnterMutex( MUTEX_SOCKETPOOL );
1931 if( cryptStatusError( status ) )
1932 return;
1933
1934 /* Find the entry for this socket in the pool. There may not be one
1935 present if the pool has received a shutdown signal and closed all
1936 network sockets, so if we don't find it we just exit normally */
1937 for( i = 0; i < SOCKETPOOL_SIZE; i++ )
1938 {
1939 if( socketInfo[ i ].netSocket == netSocket )
1940 break;
1941 }
1942 if( i >= SOCKETPOOL_SIZE )
1943 {
1944 krnlExitMutex( MUTEX_SOCKETPOOL );
1945 return;
1946 }
1947 REQUIRES_V( socketInfo[ i ].refCount > 0 );
1948
1949 /* Decrement the socket's reference count */
1950 socketInfo[ i ].refCount--;
1951 if( socketInfo[ i ].refCount <= 0 )
1952 {
1953 /* If the reference count has reached zero, close the socket
1954 and delete the pool entry */
1955 status = closesocket( socketInfo[ i ].netSocket );
1956 if( isSocketError( status ) )
1957 {
1958 /* There was a problem closing the socket, mark it as not-
1959 present for matching purposes but keep its entry active so
1960 that we'll periodically try and close it when we search the
1961 socket pool for these slots, and again when we close down */
1962 socketInfo[ i ].iChecksum = 0;
1963 memset( socketInfo[ i ].iData, 0,
1964 sizeof( socketInfo[ i ].iData ) );
1965 socketInfo[ i ].iDataLen = 0;
1966
1967 DEBUG_DIAG(( "Couldn't close socket pool socket" ));
1968 assert( DEBUG_WARN );
1969 }
1970 else
1971 socketInfo[ i ] = SOCKET_INFO_TEMPLATE;
1972 }
1973
1974 krnlExitMutex( MUTEX_SOCKETPOOL );
1975 }
1976
1977 /* Force all objects waiting on sockets to exit by closing their sockets.
1978 This is the only portable and reliable way to cause them to terminate
1979 since an object waiting on a socket is marked as busy by the cryptlib
1980 kernel, and in fact will be blocked inside the OS out of reach of even
1981 the cryptlib kernel. Alternatively, the user can provide their own
1982 socket externally and close it from the outside, which will unblock the
1983 thread waiting on it.
1984
1985 A somewhat less drastic alternative to closing the socket is to use
1986 shutdown(), but the behaviour of this is somewhat implementation-specific.
1987 For example under Slowaris 5.x trying to shutdown a listening socket (to
1988 unlock a thread blocking in accept()) returns ENOTCONN, so the shutdown
1989 requires setting up a dummy connection to the socket to be shut down
1990 before it can actually be shut down. Trying to shut down a thread blocked
1991 in connect() is more or less impossible under Slowaris 5.x. Other systems
1992 are more flexible, but there's not enough consistency to rely on this */
1993
netSignalShutdown(void)1994 void netSignalShutdown( void )
1995 {
1996 int i, status;
1997
1998 /* Exactly what to do if we can't acquire the mutex is a bit complicated
1999 because at this point our primary goal is to force all objects to exit
2000 rather than worrying about socket-pool consistency. On the other
2001 hand if another object is currently in the middle of cleaning up and
2002 is holding the socket pool mutex we don't want to stomp on it while
2003 it's doing its cleanup. Since failing to acquire the mutex is a
2004 special-case exception condition, it's not even possible to plan for
2005 this since it's uncertain under which conditions (if ever) this
2006 situation would occur. For now we play it by the book and don't do
2007 anything if we can't acquire the mutex, which is at least
2008 consistent */
2009 status = krnlEnterMutex( MUTEX_SOCKETPOOL );
2010 if( cryptStatusError( status ) )
2011 retIntError_Void();
2012
2013 /* For each open socket, close it and set its reference count to zero */
2014 for( i = 0; i < SOCKETPOOL_SIZE; i++ )
2015 {
2016 if( !isBadSocket( socketInfo[ i ].netSocket ) )
2017 {
2018 closesocket( socketInfo[ i ].netSocket );
2019 socketInfo[ i ] = SOCKET_INFO_TEMPLATE;
2020 }
2021 }
2022
2023 krnlExitMutex( MUTEX_SOCKETPOOL );
2024 }
2025
2026 /****************************************************************************
2027 * *
2028 * Network Socket Interface *
2029 * *
2030 ****************************************************************************/
2031
2032 /* Disable Nagle on a socket. In theory this call can fail, but there's not
2033 much that we can do about it, and in any case things will usually keep
2034 working anyway, so we don't try and handle any errors for this situation */
2035
disableNagle(const SOCKET netSocket)2036 static void disableNagle( const SOCKET netSocket )
2037 {
2038 static const int trueValue = 1;
2039
2040 ( void ) setsockopt( netSocket, IPPROTO_TCP, TCP_NODELAY,
2041 ( void * ) &trueValue, sizeof( int ) );
2042 }
2043
2044 /* Open a connection to a remote server or wait for a connection from a
2045 remote client. The connection-open function performs that most amazing
2046 of all things, the nonblocking connect. This is currently done in order
2047 to allow a shorter timeout than the default fortnight or so but it also
2048 allows for two-phase connects in which we start the connect operation,
2049 perform further processing (e.g. signing and encrypting data prior to
2050 sending it over the connected socket) and then complete the connect
2051 before the first read or write. Currently we just use a wrapper that
2052 performs the two back-to-back as a single operation, so for now it only
2053 functions as a timeout-management mechanism - the high-level API for
2054 this would be a bit difficult to handle since there's no readily-
2055 available facility for handling an interruptible sNetConnect(), the best
2056 option would be to handle it via a complete-connect IOCTL. However since
2057 we've got at least a little time to play with in most cases we could at
2058 least perform a quick entropy poll in the idle interval, if nothing
2059 else */
2060
2061 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
preOpenSocket(INOUT NET_STREAM_INFO * netStream,IN_BUFFER (hostNameLen)const char * host,IN_LENGTH_DNS const int hostNameLen,IN_PORT const int port)2062 static int preOpenSocket( INOUT NET_STREAM_INFO *netStream,
2063 IN_BUFFER( hostNameLen ) const char *host,
2064 IN_LENGTH_DNS const int hostNameLen,
2065 IN_PORT const int port )
2066 {
2067 SOCKET netSocket DUMMY_INIT;
2068 struct addrinfo *addrInfoPtr, *addrInfoCursor;
2069 BOOLEAN nonBlockWarning = FALSE;
2070 BOOLEAN isDgramSocket = ( netStream->nFlags & STREAM_NFLAG_DGRAM ) ? \
2071 TRUE : FALSE;
2072 int addressCount, status;
2073
2074 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
2075 assert( isReadPtr( host, hostNameLen ) );
2076
2077 REQUIRES( hostNameLen > 0 && hostNameLen <= MAX_DNS_SIZE );
2078 REQUIRES( port >= 22 && port < 65536L );
2079
2080 /* Clear return value */
2081 netStream->netSocket = CRYPT_ERROR;
2082
2083 /* Set up addressing information */
2084 status = getAddressInfo( netStream, &addrInfoPtr, host, hostNameLen, port,
2085 FALSE, isDgramSocket );
2086 if( cryptStatusError( status ) )
2087 return( status );
2088 ANALYSER_HINT( addrInfoPtr != NULL );
2089
2090 /* Create a socket, make it nonblocking, and start the connect to the
2091 remote server, falling back through alternative addresses if the
2092 connect fails. Since this is a nonblocking connect it could still
2093 fail during the second phase where we can no longer try to recover
2094 by falling back to an alternative address, but it's better than just
2095 giving up after the first address that we try (this is actually what
2096 happens in some cases under Vista/Win7 which, like most other IPv6-
2097 enabled systems preferentially tries to provide an IPv6 address for
2098 "localhost" (see the long comment in openServerSocket()) and allows a
2099 connect() to the IPv6 address, but then returns a WSAETIMEDOUT if the
2100 target application is only listening on an IPv4 address) */
2101 for( addrInfoCursor = addrInfoPtr, addressCount = 0;
2102 addrInfoCursor != NULL && addressCount < IP_ADDR_COUNT;
2103 addrInfoCursor = addrInfoCursor->ai_next, addressCount++ )
2104 {
2105 /* If it's not an IPv4 or IPv6 address, continue */
2106 if( !allowedAddressFamily( addrInfoCursor->ai_family ) )
2107 continue;
2108
2109 /* Create a socket and start the connect process */
2110 status = newSocket( &netSocket, addrInfoCursor, FALSE );
2111 if( cryptStatusError( status ) )
2112 continue;
2113 setSocketNonblocking( netSocket );
2114 status = connect( netSocket, addrInfoCursor->ai_addr,
2115 addrInfoCursor->ai_addrlen );
2116 nonBlockWarning = isNonblockWarning();
2117 if( status >= 0 || nonBlockWarning )
2118 {
2119 /* We've got a successfully-started connect, exit */
2120 break;
2121 }
2122 deleteSocket( netSocket );
2123 }
2124 if( addressCount >= IP_ADDR_COUNT )
2125 {
2126 /* We went through a suspiciously large number of remote server
2127 addresses without being able to even initiate a connect attempt
2128 to any of them, there's something wrong */
2129 DEBUG_DIAG(( "Iterated through %d server addresses without being "
2130 "able to connect", IP_ADDR_COUNT ));
2131 assert( DEBUG_WARN );
2132 return( mapError( netStream, 0, FALSE, CRYPT_ERROR_OPEN ) );
2133 }
2134 freeAddressInfo( addrInfoPtr );
2135 if( status < 0 && !nonBlockWarning )
2136 {
2137 /* There was an error condition other than a notification that the
2138 operation hasn't completed yet */
2139 return( mapError( netStream, getErrorCode(), FALSE,
2140 CRYPT_ERROR_OPEN ) );
2141 }
2142 if( status == 0 )
2143 {
2144 /* If we're connecting to a local host the connect can complete
2145 immediately rather than returning an in-progress status, in
2146 which case we don't need to do anything else */
2147 netStream->netSocket = netSocket;
2148 return( CRYPT_OK );
2149 }
2150
2151 /* The connect is in progress, mark the stream as not-quite-ready for
2152 use */
2153 /* netStream->xxx = yyy; */
2154 netStream->netSocket = netSocket;
2155
2156 return( CRYPT_OK );
2157 }
2158
2159 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
completeOpen(INOUT NET_STREAM_INFO * netStream)2160 static int completeOpen( INOUT NET_STREAM_INFO *netStream )
2161 {
2162 const STM_TRANSPORTDISCONNECT_FUNCTION transportDisconnectFunction = \
2163 FNPTR_GET( netStream->transportDisconnectFunction );
2164 SIZE_TYPE intLength = sizeof( int );
2165 int value, status;
2166
2167 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
2168 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
2169
2170 REQUIRES( transportDisconnectFunction != NULL );
2171
2172 /* Wait around until the connect completes. Some select()s limit the
2173 size of the second count so we set it to a maximum of about a week,
2174 although why anyone would wait around that long (and whether any
2175 network stack would even maintain a SYN_SENT for that amount of time)
2176 is unclear.
2177
2178 BeOS doesn't allow setting a timeout (that is, it doesn't allow
2179 asynchronous connects), but it hardcodes in a timeout of about a
2180 minute so we get a vaguely similar effect */
2181 status = ioWait( netStream, min( netStream->timeout, 500000L ), FALSE,
2182 IOWAIT_CONNECT );
2183 if( cryptStatusError( status ) )
2184 {
2185 transportDisconnectFunction( netStream, TRUE );
2186 return( status );
2187 }
2188
2189 /* The socket is readable or writeable, however this may be because of
2190 an error (it's readable and writeable) or because everything's OK
2191 (it's writeable) or because everything's OK and there's data waiting
2192 (it's readable and writeable), so we have to see what the error
2193 condition is for the socket to determine what's really happening.
2194
2195 How to best determine all of these conditions is a bit tricky. Other
2196 possibilities include calling recv() with a length of zero bytes
2197 (returns an error if the connect failed), calling connect() again
2198 (fails with EISCONN if the connect succeeded), and calling
2199 getmsg( netSocket, NULL, NULL, &( flags = 0 ) ) (fails with
2200 errno == EAGAIN or EWOULDBLOCK if the only error is that there's
2201 nothing available yet), but these are somewhat implementation-
2202 specific and not consistent across different platforms */
2203 status = getsockopt( netStream->netSocket, SOL_SOCKET, SO_ERROR,
2204 ( void * ) &value, &intLength );
2205 if( status == 0 )
2206 {
2207 /* Berkeley-derived implementation, error is in value variable */
2208 if( value != 0 )
2209 {
2210 status = mapError( netStream, value, FALSE, CRYPT_ERROR_OPEN );
2211 transportDisconnectFunction( netStream, TRUE );
2212 return( status );
2213 }
2214 }
2215 else
2216 {
2217 /* Slowaris, error is in errno */
2218 if( isSocketError( status ) )
2219 {
2220 int dummy;
2221
2222 status = getSocketError( netStream, CRYPT_ERROR_OPEN, &dummy );
2223 transportDisconnectFunction( netStream, TRUE );
2224 return( status );
2225 }
2226 }
2227
2228 /* Turn off Nagle if it's a TCP socket (since we do our own optimised
2229 TCP handling) and make the socket blocking again. This is necessary
2230 because with a nonblocking socket Winsock will occasionally return 0
2231 bytes from recv() (a sign that the other side has closed the
2232 connection, see the comment in readSocketFunction()) even though the
2233 connection is still fully open, and in any case there's no real need
2234 for a nonblocking socket since we have select() handling timeouts/
2235 blocking for us.
2236
2237 In theory these calls can fail, but there's not much that we can do
2238 about it, and in any case things will usually keep working anyway, so
2239 we don't try and handle any errors for this situation */
2240 if( !( netStream->nFlags & STREAM_NFLAG_DGRAM ) )
2241 disableNagle( netStream->netSocket );
2242 setSocketBlocking( netStream->netSocket );
2243
2244 return( CRYPT_OK );
2245 }
2246
2247 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
openServerSocket(INOUT NET_STREAM_INFO * netStream,IN_BUFFER_OPT (hostNameLen)const char * host,IN_LENGTH_DNS_Z const int hostNameLen,IN_PORT const int port)2248 static int openServerSocket( INOUT NET_STREAM_INFO *netStream,
2249 IN_BUFFER_OPT( hostNameLen ) const char *host,
2250 IN_LENGTH_DNS_Z const int hostNameLen,
2251 IN_PORT const int port )
2252 {
2253 SOCKET listenSocket DUMMY_INIT, netSocket;
2254 SOCKADDR_STORAGE clientAddr;
2255 struct addrinfo *addrInfoPtr, *addrInfoCursor;
2256 static const int trueValue = 1;
2257 static const int falseValue = 0;
2258 SIZE_TYPE clientAddrLen = sizeof( SOCKADDR_STORAGE );
2259 BOOLEAN isDgramSocket = ( netStream->nFlags & STREAM_NFLAG_DGRAM ) ? \
2260 TRUE : FALSE;
2261 char hostNameBuffer[ MAX_DNS_SIZE + 1 + 8 ];
2262 int addressCount, errorCode = 0, status;
2263
2264 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
2265 assert( ( host == NULL && hostNameLen == 0 ) || \
2266 isReadPtr( host, hostNameLen ) );
2267
2268 REQUIRES( ( host == NULL && hostNameLen == 0 ) || \
2269 ( host != NULL && \
2270 hostNameLen > 0 && hostNameLen <= MAX_DNS_SIZE ) );
2271 REQUIRES( port >= 22 && port < 65536L );
2272
2273 /* Clear return value */
2274 netStream->netSocket = CRYPT_ERROR;
2275
2276 /* Convert the host name into the null-terminated string required by the
2277 sockets API if necessary */
2278 if( host != NULL )
2279 {
2280 REQUIRES( hostNameLen > 0 && hostNameLen < MAX_DNS_SIZE );
2281
2282 memcpy( hostNameBuffer, host, hostNameLen );
2283 hostNameBuffer[ hostNameLen ] = '\0';
2284 host = hostNameBuffer;
2285 }
2286
2287 /* Set up addressing information. If we're not binding to a specified
2288 interface we allow connections on any interface. Note that in
2289 combination with SO_REUSEADDR and old unpatched Unix kernels this
2290 allows port hijacking by another process running on the same machine
2291 that binds to the port with a more specific binding than "any". It
2292 also allows port hijacking under Windows, where the situation is a
2293 bit more complex. Actually it's representative of the problem of the
2294 port-binding situation in general so it's informative to walk through
2295 the issue.
2296
2297 Windows provides a socket option SO_EXCLUSIVEADDRUSE that can be used
2298 to exclude re-binding to a socket. Unfortunately what this means is
2299 that if this option is set for a socket then the port can't be re-
2300 used right after the socket is closed but only after the connection
2301 is no longer active, where "active" means that it's not only not in
2302 the ESTABLISHED state but also not in the FIN, FIN_WAIT, FIN_WAIT_2,
2303 or LAST_ACK state. However the ability to re-bind to the port at
2304 this point is exactly what SO_REUSEADDR is supposed to allow. In
2305 other words use of SO_EXCLUSIVEADDRUSE is a bit like not setting
2306 SO_REUSEADDR (with a few technical differences based on how
2307 SO_EXCLUSIVEADDRUSE works that aren't important here). So we have
2308 to not only close the socket but wait for the system to send all
2309 buffered data, hang around for data acks, send a disconnect to the
2310 remote system, and wait to get a disconnect back. If the remote
2311 system (or a MITM) advertises a zero-length window or something
2312 similar then the connection can remain "active" (in the sense of
2313 preventing a re-bind, although not necessarily doing anything) more
2314 or less indefinitely.
2315
2316 This is a nasty situation because while SO_EXCLUSIVEADDRUSE can
2317 prevent local socket-hijacking attacks it opens us up to remote
2318 network-based DoS attacks. In theory if we have complete control
2319 of the application we can use a background thread to wait in a recv()
2320 loop until all data is read after performing a shutdown( SD_SEND )
2321 and if necessary alert the user that something funny is going on, but
2322 since we're a library (and sometimes running as a UI-less service) we
2323 can't really do this.
2324
2325 Given the choice between allowing a local session-hijack or a remote
2326 DoS, we opt for the session hijack. Since we're using secured
2327 protocols over the socket this isn't nearly as serious as (say) a
2328 socket being used for straight HTTP */
2329 status = getAddressInfo( netStream, &addrInfoPtr, host, hostNameLen,
2330 port, TRUE, isDgramSocket );
2331 if( cryptStatusError( status ) )
2332 return( status );
2333 ANALYSER_HINT( addrInfoPtr != NULL );
2334
2335 /* Create a new server socket, falling back through alternative
2336 interfaces if the initial socket creation fails. This may seem less
2337 necessary than for the client-side connect but is required because
2338 getaddrinfo() usually preferentially provides an IPv6 interface even
2339 if there's no IPv6 configured for the system (see the long comment in
2340 getAddressInfo() for more on this), so we have to step through until
2341 we get to an IPv4 interface, or at least one that we can listen on.
2342 Qui habet aures audiendi audiat (the speaker appears to be speaking
2343 metaphorically with 'ears' referring to 'network sockets', latin
2344 having no native term for the latter) */
2345 for( addrInfoCursor = addrInfoPtr, addressCount = 0;
2346 addrInfoCursor != NULL && addressCount < IP_ADDR_COUNT;
2347 addrInfoCursor = addrInfoCursor->ai_next, addressCount++ )
2348 {
2349 #ifdef IPv6
2350 SIZE_TYPE valueLen = sizeof( int );
2351 int value;
2352 #endif /* IPv6 */
2353
2354 /* If it's not an IPv4 or IPv6 address, continue */
2355 if( !allowedAddressFamily( addrInfoCursor->ai_family ) )
2356 continue;
2357
2358 status = newSocket( &listenSocket, addrInfoCursor, TRUE );
2359 if( status == CRYPT_OK )
2360 {
2361 /* It's a second thread listening on an existing socket,
2362 we're done */
2363 break;
2364 }
2365 if( status != OK_SPECIAL )
2366 {
2367 /* There was a problem creating the socket, try again with
2368 another interface */
2369 continue;
2370 }
2371
2372 /* At this point we still have the socket pool locked while we
2373 complete initialisation so we need to call newSocketDone()
2374 before we break out of the loop at any point */
2375
2376 /* Now we run into some problems with IPv4/IPv6 dual stacks, see
2377 the long comment about this in io/dns.c, in brief what happens
2378 is that if there's a choice between using IPv4 or IPv6, most
2379 systems will use IPv6 first. This is typically encountered
2380 through the first entry in the addrInfo list being an IPv6
2381 interface and the second one being an IPv4 interface, which means
2382 that the default first match will be to an IPv6 interface and not
2383 an IPv4 one. There's an option to listen on both IPv6 and IPv4
2384 interfaces, but whether this is enabled is system-dependent, most
2385 Unix systems enable it but Windows disables it.
2386
2387 In order for things to work as expected we check for the use of
2388 IPv6 and, if that's being used, check whether the dual-stack
2389 option is enabled (indicated, somewhat counterintuitively, by
2390 having the IPV6_V6ONLY socket option set to FALSE). If it's not
2391 enabled then we explicitly enable it for the socket */
2392 #ifdef IPv6
2393 if( addrInfoCursor->ai_family == AF_INET6 && \
2394 getsockopt( listenSocket, IPPROTO_IPV6, IPV6_V6ONLY,
2395 ( char * ) &value, &valueLen ) == 0 && value == 1 )
2396 {
2397 setsockopt( listenSocket, IPPROTO_IPV6, IPV6_V6ONLY,
2398 ( char * ) &falseValue, sizeof( int ) );
2399 }
2400 #endif /* IPv6 */
2401
2402 /* This is a new socket, set SO_REUSEADDR to avoid TIME_WAIT
2403 problems and prepare to accept connections (nemo surdior est
2404 quam is qui non audiet). Note that BeOS can only bind to one
2405 interface at a time, so if we're binding to INADDR_ANY under
2406 BeOS we actually bind to the first interface that we find */
2407 if( setsockopt( listenSocket, SOL_SOCKET, SO_REUSEADDR,
2408 ( char * ) &trueValue, sizeof( int ) ) || \
2409 bind( listenSocket, addrInfoCursor->ai_addr,
2410 addrInfoCursor->ai_addrlen ) || \
2411 listen( listenSocket, 5 ) )
2412 {
2413 /* Remember the error code now in case there's a later error
2414 in the cleanup functions that overwrites it */
2415 errorCode = getErrorCode();
2416
2417 /* Clean up so that we can try again, making sure that we have
2418 an appropriate error status set when we continue in case this
2419 was our last iteration through the loop */
2420 deleteSocket( listenSocket );
2421 newSocketDone();
2422 status = CRYPT_ERROR_OPEN;
2423 continue;
2424 }
2425
2426 /* We've finished initialising the socket, tell the socket pool
2427 manager that it's safe to let others access the pool */
2428 newSocketDone();
2429 status = CRYPT_OK;
2430 break;
2431 }
2432 freeAddressInfo( addrInfoPtr );
2433 if( addressCount >= IP_ADDR_COUNT )
2434 {
2435 /* We went through a suspiciously large number of server addresses
2436 without being able to even initiate a listen attempt on any of
2437 them, there's something wrong */
2438 DEBUG_DIAG(( "Iterated through %d server addresses without being "
2439 "able to listen", IP_ADDR_COUNT ));
2440 assert( DEBUG_WARN );
2441 return( mapError( netStream, 0, FALSE, CRYPT_ERROR_OPEN ) );
2442 }
2443 if( cryptStatusError( status ) )
2444 {
2445 /* There was an error setting up the socket, don't try anything
2446 further */
2447 return( mapError( netStream,
2448 ( errorCode == 0 ) ? getErrorCode() : errorCode,
2449 FALSE, CRYPT_ERROR_OPEN ) );
2450 }
2451
2452 /* Wait for a connection. At the moment this always waits forever
2453 (actually some select()s limit the size of the second count so we
2454 set it to a maximum of 1 year's worth), but in the future we could
2455 have a separate timeout value for accepting incoming connections to
2456 mirror the connection-wait timeout for outgoing connections.
2457
2458 Because of the way that accept works, the socket that we eventually
2459 and up with isn't the one that we listen on, but we have to
2460 temporarily make it the one associated with the stream in order for
2461 ioWait() to work */
2462 netStream->netSocket = listenSocket;
2463 status = ioWait( netStream, min( netStream->timeout, 30000000L ), FALSE,
2464 IOWAIT_ACCEPT );
2465 netStream->netSocket = CRYPT_ERROR;
2466 if( cryptStatusError( status ) )
2467 return( status );
2468
2469 /* We have an incoming connection ready to go, accept it. There's a
2470 potential complication here in that if a client connects and then
2471 immediately sends a RST after the TCP handshake has completed,
2472 ioWait() will return with an indication that there's an incoming
2473 connection ready to go but the following accept(), if it's called
2474 after the RST has arrived, will block waiting for the next incoming
2475 connection. This is rather unlikely in practice, but could occur
2476 as part of a DoS by setting the SO_LINGER time to 0 and disconnecting
2477 immediately. This has the effect of turning the accept() with
2478 timeout into an indefinite-wait accept().
2479
2480 To get around this we make the socket temporarily non-blocking, so
2481 that accept() returns an error if the client has closed the
2482 connection. The exact error varies, BSD implementations handle the
2483 error internally and return to the accept() while SVR4
2484 implementations return either EPROTO (older, pre-Posix behaviour) or
2485 ECONNABORTED (newer Posix-compliant behaviour, since EPROTO is also
2486 used for other protocol-related errors).
2487
2488 Since BSD implementations hide the problem they wouldn't normally
2489 return an error, however by temporarily making the socket non-
2490 blocking we force it to return an EWOULDBLOCK if this situation
2491 occurs. Since this could lead to a misleading returned error, we
2492 intercept it and substitute a custom error string. Note that when
2493 we make the listen socket blocking again, we also have to make the
2494 newly-created ephemeral socket blocking, since it inherits its
2495 attributes from the listen socket.
2496
2497 In addition to all of the blocking/nonblocking shenanigans, we also
2498 need to disable Nagle on the accepted socket. This may or may not
2499 be necessary depending on the sockets implementation, we always
2500 explicitly set it to be on the safe side */
2501 setSocketNonblocking( listenSocket );
2502 netSocket = accept( listenSocket, ( struct sockaddr * ) &clientAddr,
2503 &clientAddrLen );
2504 if( isBadSocket( netSocket ) )
2505 {
2506 if( isNonblockWarning() )
2507 {
2508 status = setSocketError( netStream,
2509 "Remote system closed the connection "
2510 "after completing the TCP handshake",
2511 70, CRYPT_ERROR_OPEN, TRUE );
2512 }
2513 else
2514 {
2515 int dummy;
2516
2517 status = getSocketError( netStream, CRYPT_ERROR_OPEN, &dummy );
2518 }
2519 setSocketBlocking( listenSocket );
2520 deleteSocket( listenSocket );
2521 return( status );
2522 }
2523 setSocketBlocking( listenSocket );
2524 setSocketBlocking( netSocket );
2525
2526 /* Get the IP address of the connected client. We could get its full
2527 name, but this can slow down connections because of the time that it
2528 takes to do the lookup and is less authoritative because of potential
2529 spoofing. In any case the caller can still look up the name if they
2530 need it. Since we don't want to abort an entire network connect just
2531 because we can't return the peer's IP address, do don't do anything
2532 with the return value of this function */
2533 ( void ) getNameInfo( ( const struct sockaddr * ) &clientAddr,
2534 clientAddrLen, netStream->clientAddress,
2535 CRYPT_MAX_TEXTSIZE / 2,
2536 &netStream->clientAddressLen,
2537 &netStream->clientPort );
2538
2539 /* Turn off Nagle, since we do our own optimised TCP handling. In
2540 theory this call can fail, but there's not much that we can do about
2541 it, and in any case things will usually keep working anyway, so we
2542 don't try and handle any errors for this situation */
2543 disableNagle( netSocket );
2544
2545 /* We've got a new connection, add the socket to the pool. Since this
2546 was created externally to the pool we don't use newSocket() to create
2547 a new socket but only add the existing socket */
2548 status = addSocket( netSocket );
2549 if( cryptStatusError( status ) )
2550 {
2551 /* There was a problem adding the new socket, close it and exit.
2552 We don't call deleteSocket() since it wasn't added to the pool,
2553 instead we call closesocket() directly */
2554 closesocket( netSocket );
2555 return( setSocketError( netStream,
2556 "Couldn't add socket to socket pool", 34,
2557 status, FALSE ) );
2558 }
2559 netStream->netSocket = netSocket;
2560 netStream->listenSocket = listenSocket;
2561
2562 return( CRYPT_OK );
2563 }
2564
2565 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
openSocketFunction(INOUT NET_STREAM_INFO * netStream,IN_BUFFER_OPT (hostNameLen)const char * hostName,IN_LENGTH_DNS_Z const int hostNameLen,IN_PORT const int port)2566 static int openSocketFunction( INOUT NET_STREAM_INFO *netStream,
2567 IN_BUFFER_OPT( hostNameLen) const char *hostName,
2568 IN_LENGTH_DNS_Z const int hostNameLen,
2569 IN_PORT const int port )
2570 {
2571 int status;
2572
2573 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
2574 assert( ( hostName == NULL && hostNameLen == 0 ) || \
2575 isReadPtr( hostName, hostNameLen ) );
2576
2577 REQUIRES( ( hostName == NULL && hostNameLen == 0 ) || \
2578 ( hostName != NULL && \
2579 hostNameLen > 0 && hostNameLen <= MAX_DNS_SIZE ) );
2580 REQUIRES( port >= 22 && port < 65536L );
2581 REQUIRES( ( netStream->nFlags & STREAM_NFLAG_ISSERVER ) || \
2582 hostName != NULL );
2583
2584 /* If it's a server stream, open a listening socket */
2585 if( netStream->nFlags & STREAM_NFLAG_ISSERVER )
2586 {
2587 const int savedTimeout = netStream->timeout;
2588
2589 /* Timeouts for server sockets are actually three-level rather than
2590 the usual two-level model, there's an initial (pre-connect)
2591 timeout while we wait for an incoming connection to arrive, and
2592 then we go to the usual session connect vs. session read/write
2593 timeout mechanism. To handle the pre-connect phase we set an
2594 (effectively infinite) timeout at this point to ensure that the
2595 server always waits forever for an incoming connection to
2596 appear */
2597 netStream->timeout = MAX_INTLENGTH;
2598 status = openServerSocket( netStream, hostName, hostNameLen, port );
2599 netStream->timeout = savedTimeout;
2600 return( status );
2601 }
2602
2603 ENSURES( hostName != NULL && \
2604 ( hostNameLen > 0 && hostNameLen <= MAX_DNS_SIZE ) );
2605
2606 /* It's a client stream, perform a two-part nonblocking open. Currently
2607 the two portions are performed back-to-back, in the future we can
2608 interleave the two and perform general crypto processing (e.g. hash/
2609 MAC context setup for SSL) while the open is completing */
2610 status = preOpenSocket( netStream, hostName, hostNameLen, port );
2611 if( cryptStatusOK( status ) )
2612 status = completeOpen( netStream );
2613 ENSURES( ( cryptStatusError( status ) && \
2614 netStream->netSocket == CRYPT_ERROR ) || \
2615 ( cryptStatusOK( status ) && \
2616 netStream->netSocket != CRYPT_ERROR ) );
2617 if( cryptStatusError( status ) )
2618 {
2619 /* There was a problem opening the socket, see if we can return
2620 something a bit better than the often rather generic socket-
2621 connect error code */
2622 return( diagnoseConnectionProblem( netStream, hostName,
2623 hostNameLen, status ) );
2624 }
2625
2626 return( CRYPT_OK );
2627 }
2628
2629 /* Close a connection. Safely handling closes is extremely difficult due to
2630 a combination of the way TCP/IP (and TCP stacks) work and various bugs
2631 and quirks in implementations. After a close (and particularly if short-
2632 timeout non-blocking writes are used) there can still be data left in
2633 TCP send buffers, and also as unacknowledged segments on the network. At
2634 this point there's no easy way for the TCP stack to know how long it
2635 should hang around trying to get the data out and waiting for acks to
2636 come back. If it doesn't wait long enough, it'll end up discarding
2637 unsent data. If it waits too long, it could potentially wait forever in
2638 the presence of network outages or crashed peers. What's worse, since
2639 the socket is now closed, there's no way to report any problems that may
2640 occur at this point back to the caller.
2641
2642 We try and handle this with a combination of shutdown() and close(), but
2643 due to implementation bugs/quirks and the TCP stack issues mentioned
2644 above this doesn't work all of the time. The details get very
2645 implementation-specific, for example with glibc the manpage says that
2646 setting SO_LINGER causes shutdown() not to return until queued messages
2647 are sent (which is wrong, and non-glibc implementations like PHUX and
2648 Solaris specifically point out that only close() is affected), but that
2649 shutdown() discards unsent data. glibc in turn is dependent on the
2650 kernel it's running on top of, under Linux shutdown() returns immediately
2651 but data is still sent regardless of the SO_LINGER setting.
2652
2653 BSD Net/2 and later (which many stacks are derived from, including non-
2654 Unix systems like OS/2) returned immediately from a close() but still
2655 sent queued data on a best-effort basis. With SO_LINGER set and a zero
2656 timeout the close was abortive (which Linux also implemented starting
2657 with the 2.4 kernel), and with a non-zero timeout it would wait until all
2658 the data was sent, which meant that it could block almost indefinitely
2659 (minutes or even hours, this is the worst-case behaviour mentioned
2660 above). This was finally fixed in 4.4BSD (although a lot of 4.3BSD-
2661 derived stacks ended up with the indefinite-wait behaviour), but even
2662 then there was some confusion as to whether the wait time was in machine-
2663 specific ticks or seconds (Posix finally declared it to be seconds).
2664 Under Winsock, close() simply discards queued data while shutdown() has
2665 the same effect as under Linux, sending enqueued data asynchronously
2666 regardless of the SO_LINGER setting.
2667
2668 This is a real mess to sort out safely, the best that we can do is to
2669 perform a shutdown() followed later by a close(). Messing with SO_LINGER
2670 is too risky and something like performing an ioWait() doesn't work
2671 either because it just results in whoever initiated the shutdown being
2672 blocked for the I/O wait time, and waiting for a recv() of 0 bytes isn't
2673 safe because the higher-level code may need to read back a shutdown ack
2674 from the other side which a recv() performed at this point would
2675 interfere with. Under Windows we could handle it by waiting for an
2676 FD_CLOSE to be posted but this requires the use of a window handle which
2677 we don't have access to, and which may not even exist for some classes of
2678 applications */
2679
2680 STDC_NONNULL_ARG( ( 1 ) ) \
closeSocketFunction(INOUT NET_STREAM_INFO * netStream,const BOOLEAN fullDisconnect)2681 static void closeSocketFunction( INOUT NET_STREAM_INFO *netStream,
2682 const BOOLEAN fullDisconnect )
2683 {
2684 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
2685
2686 /* If it's a partial disconnect, close only the send side of the channel.
2687 The send-side close can help with ensuring that all data queued for
2688 transmission is sent */
2689 if( !fullDisconnect )
2690 {
2691 if( netStream->netSocket != CRYPT_ERROR )
2692 shutdown( netStream->netSocket, SHUT_WR );
2693 return;
2694 }
2695
2696 /* If it's an open-on-demand HTTP stream then the socket isn't
2697 necessarily open even if the stream was successfully connected so we
2698 only close it if necessary. It's easier handling it at this level
2699 than expecting the caller to distinguish between an opened-stream-but-
2700 not-opened-socket and a conventional open stream */
2701 if( netStream->netSocket != CRYPT_ERROR )
2702 deleteSocket( netStream->netSocket );
2703 if( netStream->listenSocket != CRYPT_ERROR )
2704 deleteSocket( netStream->listenSocket );
2705 netStream->netSocket = netStream->listenSocket = CRYPT_ERROR;
2706 }
2707
2708 /* Check an externally-supplied socket to make sure that it's set up as
2709 required by cryptlib. See the long comment in tcp.h about the numerous
2710 problems that this theoretically simple operation actually causes */
2711
2712 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
checkSocketFunction(INOUT NET_STREAM_INFO * netStream)2713 static int checkSocketFunction( INOUT NET_STREAM_INFO *netStream )
2714 {
2715 int value;
2716
2717 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
2718
2719 /* Check that we've been passed a valid network socket, and that it's
2720 blocking socket. getSocketNonblockingStatus() is a complex macro
2721 that tries to return the non-blocking status as a boolean */
2722 getSocketNonblockingStatus( netStream->netSocket, value );
2723 if( value )
2724 {
2725 return( setSocketError( netStream, "Socket is non-blocking", 22,
2726 CRYPT_ARGERROR_NUM1, TRUE ) );
2727 }
2728 return( CRYPT_OK );
2729 }
2730
2731 /* Read and write data from and to a socket. Because data can appear in
2732 bits and pieces when reading we have to implement timeout handling at two
2733 levels, once via ioWait() and a second time as an overall timeout. If we
2734 only used ioWait() this could potentially stretch the overall timeout to
2735 (length * timeout) so we also perform a time check that leads to a worst-
2736 case timeout of (timeout-1 + timeout). This is the same as the
2737 implementation of SO_SND/RCVTIMEO in Berkeley-derived implementations,
2738 where the timeout value is actually an interval timer rather than a
2739 absolute timer.
2740
2741 In addition to the standard stream-based timeout behaviour we can also be
2742 called with flags specifying explicit blocking behaviour (for a read
2743 where we know that we're expecting a certain amount of data) or explicit
2744 nonblocking behaviour (for speculative reads to fill a buffer). These
2745 flags are used by the buffered-read routines, which try and speculatively
2746 read as much data as possible to avoid the many small reads required by
2747 some protocols. We don't do the blocking read using MSG_WAITALL since
2748 this can (potentially) block forever if not all of the data arrives.
2749
2750 Finally, if we're performing an explicit blocking read (which is usually
2751 done when we're expecting a predetermined number of bytes) we dynamically
2752 adjust the timeout so that if data is streaming in at a steady rate we
2753 don't abort the read just because there's more data to transfer than we
2754 can manage in the originally specified timeout interval. This is
2755 especially useful when transferring large data amounts, for which a one-
2756 size-fits-all fixed timeout doesn't accurately reflect the amount of time
2757 required to transfer the full data amount.
2758
2759 Handling of return values is as follows:
2760
2761 timeout byteCount return
2762 ------- --------- ------
2763 0 0 0
2764 0 > 0 byteCount
2765 > 0 0 CRYPT_ERROR_TIMEOUT
2766 > 0 > 0 byteCount
2767
2768 At the sread()/swrite() level if the partial-read/write flags aren't set
2769 for the stream, a byteCount < length is also converted to a
2770 CRYPTO_ERROR_TIMEOUT */
2771
2772 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
readSocketFunction(INOUT STREAM * stream,OUT_BUFFER (maxLength,* length)BYTE * buffer,IN_DATALENGTH const int maxLength,OUT_DATALENGTH_Z int * length,IN_FLAGS_Z (TRANSPORT)const int flags)2773 static int readSocketFunction( INOUT STREAM *stream,
2774 OUT_BUFFER( maxLength, *length ) BYTE *buffer,
2775 IN_DATALENGTH const int maxLength,
2776 OUT_DATALENGTH_Z int *length,
2777 IN_FLAGS_Z( TRANSPORT ) const int flags )
2778 {
2779 NET_STREAM_INFO *netStream = ( NET_STREAM_INFO * ) stream->netStreamInfo;
2780 MONOTIMER_INFO timerInfo;
2781 BYTE *bufPtr = buffer;
2782 const int timeout = ( flags & TRANSPORT_FLAG_NONBLOCKING ) ? 0 : \
2783 ( flags & TRANSPORT_FLAG_BLOCKING ) ? \
2784 max( NET_TIMEOUT_READ, netStream->timeout ) : \
2785 netStream->timeout;
2786 int bytesToRead, byteCount = 0, iterationCount, status;
2787
2788 assert( isWritePtr( stream, sizeof( STREAM ) ) );
2789 assert( isWritePtr( buffer, maxLength ) );
2790 assert( isWritePtr( length, sizeof( int ) ) );
2791
2792 REQUIRES_S( stream->type == STREAM_TYPE_NETWORK );
2793 REQUIRES_S( maxLength > 0 && maxLength < MAX_BUFFER_SIZE );
2794 REQUIRES_S( ( ( flags & TRANSPORT_FLAG_NONBLOCKING ) && \
2795 timeout == 0 ) || \
2796 ( !( flags & TRANSPORT_FLAG_NONBLOCKING ) && \
2797 timeout >= 0 && timeout < MAX_INTLENGTH ) );
2798 REQUIRES_S( flags == TRANSPORT_FLAG_NONE || \
2799 flags == TRANSPORT_FLAG_NONBLOCKING || \
2800 flags == TRANSPORT_FLAG_BLOCKING );
2801
2802 /* Clear return value */
2803 *length = 0;
2804
2805 status = setMonoTimer( &timerInfo, timeout );
2806 if( cryptStatusError( status ) )
2807 return( status );
2808 for( bytesToRead = maxLength, iterationCount = 0;
2809 bytesToRead > 0 && \
2810 ( timeout <= 0 || !checkMonoTimerExpired( &timerInfo ) ) && \
2811 iterationCount < FAILSAFE_ITERATIONS_MAX;
2812 iterationCount++ )
2813 {
2814 int bytesRead;
2815
2816 /* Wait for data to become available */
2817 status = ioWait( netStream, timeout,
2818 ( byteCount > 0 ) ? TRUE : FALSE, IOWAIT_READ );
2819 if( status == OK_SPECIAL )
2820 {
2821 /* We got a timeout but either there's already data present from
2822 a previous read or it's a nonblocking wait, so this isn't an
2823 error */
2824 if( byteCount > 0 )
2825 *length = byteCount;
2826 return( CRYPT_OK );
2827 }
2828 if( cryptStatusError( status ) )
2829 {
2830 /* Some buggy firewall software will block any data transfer
2831 attempts made after the initial connection setup
2832 (specifically they'll allow the initial SYN/SYN/ACK to
2833 establish connection state but then block any further
2834 information from being transferred), to handle this we
2835 check whether we get a timeout on the first read and if we
2836 do then we check for the presence of the software firewall,
2837 reporting a problem due to the firewall rather than a
2838 general networking problem if we find one */
2839 if( status == CRYPT_ERROR_TIMEOUT && \
2840 ( netStream->nFlags & STREAM_NFLAG_FIRSTREADOK ) )
2841 {
2842 return( checkFirewallError( netStream ) );
2843 }
2844 return( status );
2845 }
2846
2847 /* We've got data waiting, read it */
2848 bytesRead = recv( netStream->netSocket, bufPtr, bytesToRead, 0 );
2849 if( isSocketError( bytesRead ) )
2850 {
2851 int dummy;
2852
2853 /* If it's a restartable read due to something like an
2854 interrupted system call, retry the read */
2855 if( isRestartableError() )
2856 {
2857 assert( !"Restartable read, recv() indicated error" );
2858 continue;
2859 }
2860
2861 /* There was a problem with the read */
2862 return( getSocketError( netStream, CRYPT_ERROR_READ, &dummy ) );
2863 }
2864 if( bytesRead <= 0 )
2865 {
2866 /* Under some odd circumstances (bugs in older versions of
2867 Winsock when using non-blocking sockets, or calling select()
2868 with a timeout of 0), recv() can return zero bytes without an
2869 EOF condition being present, even though it should return an
2870 error status if this happens (this could also happen under
2871 very old SysV implementations using O_NDELAY for nonblocking
2872 I/O).
2873
2874 One situation in which we can legitimately get this (although
2875 the status is misleading) is when we don't get an ACK for a
2876 previous data send. If we get here before the ACK timeout
2877 occurs then we won't get the ECONNABORTED but instead get
2878 recv() == 0 (exactly how we can get recv() == 0 due to the
2879 lack of ACK but not an ECONNABORTED at the same point remains
2880 a mystery).
2881
2882 An example of a situation in which we can get an ECONNABORTED
2883 is when the client sends an HTTP POST to the server, which
2884 looks at the HTTP request header, rejects it (e.g. due to
2885 excessive content length, which cryptlib will do in order to
2886 avoid being DoS'ed by the other side), and sends back an
2887 error response and closes the connection without trying to
2888 read the body of the request. The connection is now half-
2889 closed, with the client still writing the HTTP body to its
2890 side of the connection, which means that it gets buffered in
2891 the TCP stack but not sent. At this point the client tries
2892 to read the HTTP response, but in the meantime the outgoing
2893 retransmission of the buffered data has failed and the TCP
2894 stack on the client shuts down the connection. This means
2895 that the HTTP response that the server sent is never read,
2896 and the client gets an ECONNABORTED.
2897
2898 Dealing with this particular situation is quite difficult,
2899 see the comment in the code block for handling
2900 byteCount == 0 at the end of this function.
2901
2902 To try and catch the more general situation we check for a
2903 restartable read due to something like an interrupted system
2904 call and retry the read if it is. This doesn't catch the
2905 Winsock zero-delay bug but it may catch problems in other
2906 implementations.
2907
2908 Unfortunately this doesn't work under all circumstances
2909 either. If the connection is genuinely closed select() will
2910 return a data-available status and recv() will return zero,
2911 both without changing errno. If the last status set in errno
2912 matches the isRestartableError() check, the code will loop
2913 forever. Because of this we can't use the following check,
2914 although since it doesn't catch the Winsock zero-delay bug
2915 anyway it's probably no big deal.
2916
2917 The real culprit here is the design flaw in recv(), which
2918 uses a valid bytes-received value to indicate an out-of-band
2919 condition that should be reported via an error code ("There's
2920 nowt wrong with owt what mitherin clutterbucks don't barley
2921 grummit") */
2922 #if 0 /* See above comment */
2923 if( isRestartableError() )
2924 {
2925 assert( !"Restartable read, recv() indicated no error" );
2926 continue;
2927 }
2928 #endif /* 0 */
2929
2930 /* Once we encounter this problem, we've fallen and can't get up
2931 any more. WSAGetLastError() reports no error, select()
2932 reports data available for reading, and recv() reports zero
2933 bytes read. If the following is used, the code will loop
2934 endlessly (or at least until the loop iteration watchdog
2935 triggers) waiting for data that can never be read */
2936 #if 0 /* See above comment */
2937 getSocketError( stream, CRYPT_ERROR_READ, &dummy );
2938 status = ioWait( stream, 0, 0, IOWAIT_READ );
2939 if( cryptStatusOK( status ) )
2940 continue;
2941 #endif /* 0 */
2942
2943 /* "It said its piece, and then it sodded off" - Baldrick,
2944 Blackadder's Christmas Carol */
2945 bytesToRead = 0; /* Force exit from loop */
2946 continue;
2947 }
2948 bufPtr += bytesRead;
2949 bytesToRead -= bytesRead;
2950 byteCount += bytesRead;
2951 ENSURES_S( bytesToRead >= 0 && bytesToRead < MAX_BUFFER_SIZE );
2952 ENSURES_S( byteCount > 0 && byteCount < MAX_BUFFER_SIZE );
2953
2954 /* Remember that we've got some data, used for error diagnosis (see
2955 the long comment above) */
2956 netStream->nFlags |= STREAM_NFLAG_FIRSTREADOK;
2957
2958 /* If this is a blocking read and we've been moving data at a
2959 reasonable rate (~1K/s) and we're about to time out, adjust the
2960 timeout to give us a bit more time. This is an adaptive process
2961 that grants us more time for the read if data is flowing at
2962 a reasonable rate, but ensures that we don't hang around forever
2963 if data is trickling in at a few bytes a second */
2964 if( flags & TRANSPORT_FLAG_BLOCKING )
2965 {
2966 ENSURES( timeout > 0 );
2967
2968 /* If the timer expiry is imminent but data is still flowing in,
2969 extend the timing duration to allow for further data to
2970 arrive. Because of the minimum flow-rate limit that's
2971 imposed above this is unlikely to be subject to much of a DoS
2972 problem (at worst an attacker can limit us to reading data
2973 at 1K/s, which means 16s for SSL/TLS packets and 32s for SSH
2974 packets), but to make things a bit less predictable we dither
2975 the timeout a bit */
2976 if( ( byteCount / timeout ) >= 1000 && \
2977 checkMonoTimerExpiryImminent( &timerInfo, 5 ) )
2978 {
2979 extendMonoTimer( &timerInfo,
2980 ( getRandomInteger() % 5 ) + 2 );
2981 }
2982 }
2983 }
2984 ENSURES_S( iterationCount < FAILSAFE_ITERATIONS_MAX );
2985 if( maxLength > 0 && byteCount <= 0 )
2986 {
2987 /* We didn't get anything because the other side closed the
2988 connection. We report this as a read-complete status rather than
2989 a read error since it isn't necessarily a real error.
2990
2991 One situation in which we can get this is when we don't get an
2992 ACK for a previous data send, however if we get here before the
2993 ACK timeout occurs then we won't get the ECONNABORTED/
2994 WSAECONNABORTED but instead get recv() == 0. Getting the
2995 ECONNABORTED is quite difficult, just adding a delay won't work
2996 so we need to wait and then perform a second read. Because this
2997 is somewhat system-specific, we make it Windows-only for now */
2998 #ifdef __WINDOWS__
2999 BYTE dummyBuffer[ 8 + 8 ];
3000 int errorCode;
3001
3002 Sleep( 500 );
3003 ( void ) recv( netStream->netSocket, dummyBuffer, 8, 0 );
3004 ( void ) getSocketError( netStream, CRYPT_ERROR_READ, &errorCode );
3005 if( errorCode == WSAECONNABORTED )
3006 return( CRYPT_ERROR_COMPLETE );
3007 #endif /* __WINDOWS__ */
3008 return( setSocketError( netStream,
3009 "No data was read because the remote system "
3010 "closed the connection (recv() == 0)", 78,
3011 CRYPT_ERROR_COMPLETE, TRUE ) );
3012 }
3013 *length = byteCount;
3014
3015 return( CRYPT_OK );
3016 }
3017
3018 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
writeSocketFunction(INOUT STREAM * stream,IN_BUFFER (maxLength)const BYTE * buffer,IN_DATALENGTH const int maxLength,OUT_DATALENGTH_Z int * length,IN_FLAGS_Z (TRANSPORT)const int flags)3019 static int writeSocketFunction( INOUT STREAM *stream,
3020 IN_BUFFER( maxLength ) const BYTE *buffer,
3021 IN_DATALENGTH const int maxLength,
3022 OUT_DATALENGTH_Z int *length,
3023 IN_FLAGS_Z( TRANSPORT ) const int flags )
3024 {
3025 NET_STREAM_INFO *netStream = ( NET_STREAM_INFO * ) stream->netStreamInfo;
3026 MONOTIMER_INFO timerInfo;
3027 const BYTE *bufPtr = buffer;
3028 const int timeout = ( flags & TRANSPORT_FLAG_NONBLOCKING ) ? 0 : \
3029 ( flags & TRANSPORT_FLAG_BLOCKING ) ? \
3030 max( NET_TIMEOUT_WRITE, netStream->timeout ) : \
3031 netStream->timeout;
3032 int bytesToWrite, byteCount = 0, iterationCount, status;
3033
3034 assert( isWritePtr( stream, sizeof( STREAM ) ) );
3035 assert( isReadPtr( buffer, maxLength ) );
3036 assert( isWritePtr( length, sizeof( int ) ) );
3037
3038 REQUIRES_S( stream->type == STREAM_TYPE_NETWORK );
3039 REQUIRES_S( maxLength > 0 && maxLength < MAX_BUFFER_SIZE );
3040 REQUIRES_S( ( ( flags & TRANSPORT_FLAG_NONBLOCKING ) && \
3041 timeout == 0 ) || \
3042 ( !( flags & TRANSPORT_FLAG_NONBLOCKING ) && \
3043 timeout >= 0 && timeout < MAX_INTLENGTH ) );
3044 REQUIRES_S( flags == TRANSPORT_FLAG_NONE || \
3045 flags == TRANSPORT_FLAG_NONBLOCKING || \
3046 flags == TRANSPORT_FLAG_BLOCKING );
3047
3048 /* Clear return value */
3049 *length = 0;
3050
3051 /* Send data to the remote system. As with the receive-data code we
3052 have to work around a large number of quirks and socket
3053 implementation bugs, although most of the systems that exhibited
3054 these are now extinct or close to it. Some very old Winsock stacks
3055 (Win3.x and early Win95 era) would almost always indicate that a
3056 socket was writeable even when it wasn't. Even older (mid-1980s)
3057 Berkeley-derived implementations could return EWOULDBLOCK on a
3058 blocking socket if they couldn't get required mbufs so that even if
3059 select() indicated that the socket was writeable, an actual attempt
3060 to write would return an error since there were no mbufs available.
3061 Under Win95 select() could fail to block on a non-blocking socket,
3062 so that the send() would return EWOULDBLOCK. One possible reason
3063 (related to the mbuf problem) for this was that another thread couled
3064 have grabed memory between the select() and the send() so that there
3065 was no buffer space available when the send() needed it, although
3066 this should really have returned WSAENOBUFS rather than
3067 WSAEWOULDBLOCK. There was also a known bug in Win95 (and possibly
3068 Win98 as well, Q177346) under which a select() would indicate
3069 writeability but send() returns EWOULDBLOCK. Another select()
3070 executed after the failed send() then causes select() to suddenly
3071 realise that the socket is non-writeable (accidit in puncto, quod non
3072 seperatur in anno). Finally, in some cases send() can return an
3073 error but WSAGetLastError() indicates that there's no error, so we
3074 treat it as noise and try again */
3075 status = setMonoTimer( &timerInfo, timeout );
3076 if( cryptStatusError( status ) )
3077 return( status );
3078 for( bytesToWrite = maxLength, iterationCount = 0;
3079 bytesToWrite > 0 && \
3080 ( timeout <= 0 || !checkMonoTimerExpired( &timerInfo ) ) && \
3081 iterationCount < FAILSAFE_ITERATIONS_MAX;
3082 iterationCount++ )
3083 {
3084 int bytesWritten;
3085
3086 /* Wait for the socket to become available */
3087 status = ioWait( netStream, timeout,
3088 ( byteCount > 0 ) ? TRUE : FALSE, IOWAIT_WRITE );
3089 if( status == OK_SPECIAL )
3090 {
3091 /* We got a timeout but either there's already data present from
3092 a previous read or it's a nonblocking wait, so this isn't an
3093 error */
3094 if( byteCount > 0 )
3095 {
3096 *length = byteCount;
3097
3098 return( CRYPT_OK );
3099 }
3100 return( CRYPT_OK );
3101 }
3102 if( cryptStatusError( status ) )
3103 return( status );
3104
3105 /* Write the data */
3106 bytesWritten = send( netStream->netSocket, bufPtr, bytesToWrite,
3107 MSG_NOSIGNAL );
3108 if( isSocketError( bytesWritten ) )
3109 {
3110 int dummy;
3111
3112 /* If it's a restartable write due to something like an
3113 interrupted system call (or a sockets bug), retry the
3114 write */
3115 if( isRestartableError() )
3116 {
3117 assert( !"Restartable write, send() indicated error" );
3118 continue;
3119 }
3120
3121 #ifdef __WINDOWS__
3122 /* If it's a Winsock bug, treat it as a restartable write */
3123 if( WSAGetLastError() < WSABASEERR )
3124 {
3125 assert( !"send() failed but WSAGetLastError() indicated no "
3126 "error, ignoring" );
3127 continue;
3128 }
3129 #endif /* __WINDOWS__ */
3130
3131 /* There was a problem with the write */
3132 return( getSocketError( netStream, CRYPT_ERROR_WRITE, &dummy ) );
3133 }
3134 bufPtr += bytesWritten;
3135 bytesToWrite -= bytesWritten;
3136 byteCount += bytesWritten;
3137 ENSURES_S( bytesToWrite >= 0 && bytesToWrite < MAX_BUFFER_SIZE );
3138 ENSURES_S( byteCount > 0 && byteCount < MAX_BUFFER_SIZE );
3139 }
3140 ENSURES_S( iterationCount < FAILSAFE_ITERATIONS_MAX );
3141 *length = byteCount;
3142
3143 return( CRYPT_OK );
3144 }
3145
3146 STDC_NONNULL_ARG( ( 1 ) ) \
setAccessMethodTCP(INOUT NET_STREAM_INFO * netStream)3147 void setAccessMethodTCP( INOUT NET_STREAM_INFO *netStream )
3148 {
3149 assert( isWritePtr( netStream, sizeof( NET_STREAM_INFO ) ) );
3150
3151 /* Set the access method pointers */
3152 FNPTR_SET( netStream->transportConnectFunction, openSocketFunction );
3153 FNPTR_SET( netStream->transportDisconnectFunction, closeSocketFunction );
3154 FNPTR_SET( netStream->transportReadFunction, readSocketFunction );
3155 FNPTR_SET( netStream->transportWriteFunction, writeSocketFunction );
3156 FNPTR_SET( netStream->transportOKFunction, transportOKFunction );
3157 FNPTR_SET( netStream->transportCheckFunction, checkSocketFunction );
3158 }
3159 #endif /* USE_TCP */
3160