X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_ssl/sslViewer/ioSock.c diff --git a/libsecurity_ssl/sslViewer/ioSock.c b/libsecurity_ssl/sslViewer/ioSock.c deleted file mode 100644 index dbc18da1..00000000 --- a/libsecurity_ssl/sslViewer/ioSock.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (c) 2006-2008,2010-2012 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * ioSock.c - socket-based I/O routines for use with Secure Transport - */ - -#include "ioSock.h" -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* debugging for this module */ -#define SSL_OT_DEBUG 1 - -/* log errors to stdout */ -#define SSL_OT_ERRLOG 1 - -/* trace all low-level network I/O */ -#define SSL_OT_IO_TRACE 0 - -/* if SSL_OT_IO_TRACE, only log non-zero length transfers */ -#define SSL_OT_IO_TRACE_NZ 1 - -/* pause after each I/O (only meaningful if SSL_OT_IO_TRACE == 1) */ -#define SSL_OT_IO_PAUSE 0 - -/* print a stream of dots while I/O pending */ -#define SSL_OT_DOT 1 - -/* dump some bytes of each I/O (only meaningful if SSL_OT_IO_TRACE == 1) */ -#define SSL_OT_IO_DUMP 0 -#define SSL_OT_IO_DUMP_SIZE 256 - -/* indicate errSSLWouldBlock with a '.' */ -#define SSL_DISPL_WOULD_BLOCK 0 - -/* general, not-too-verbose debugging */ -#if SSL_OT_DEBUG -#define dprintf(s) printf s -#else -#define dprintf(s) -#endif - -/* errors --> stdout */ -#if SSL_OT_ERRLOG -#define eprintf(s) printf s -#else -#define eprintf(s) -#endif - -/* trace completion of every r/w */ -#if SSL_OT_IO_TRACE -static void tprintf( - const char *str, - UInt32 req, - UInt32 act, - const UInt8 *buf) -{ - #if SSL_OT_IO_TRACE_NZ - if(act == 0) { - return; - } - #endif - printf("%s(%u): moved (%u) bytes\n", str, (unsigned)req, (unsigned)act); - #if SSL_OT_IO_DUMP - { - unsigned i; - - for(i=0; i= (SSL_OT_IO_DUMP_SIZE - 1)) { - break; - } - } - printf("\n"); - } - #endif - #if SSL_OT_IO_PAUSE - { - char instr[20]; - printf("CR to continue: "); - gets(instr); - } - #endif -} - -#else -#define tprintf(str, req, act, buf) -#endif /* SSL_OT_IO_TRACE */ - -/* - * If SSL_OT_DOT, output a '.' every so often while waiting for - * connection. This gives user a chance to do something else with the - * UI. - */ - -#if SSL_OT_DOT - -static time_t lastTime = (time_t)0; -#define TIME_INTERVAL 3 - -static void outputDot() -{ - time_t thisTime = time(0); - - if((thisTime - lastTime) >= TIME_INTERVAL) { - printf("."); fflush(stdout); - lastTime = thisTime; - } -} -#else -#define outputDot() -#endif - - -/* - * One-time only init. - */ -void initSslOt(void) -{ - -} - -/* - * Connect to server. - */ -#define GETHOST_RETRIES 3 - -OSStatus MakeServerConnection( - const char *hostName, - int port, - int nonBlocking, // 0 or 1 - otSocket *socketNo, // RETURNED - PeerSpec *peer) // RETURNED -{ - struct sockaddr_in addr; - struct hostent *ent; - struct in_addr host; - int sock = 0; - - *socketNo = 0; - if (hostName[0] >= '0' && hostName[0] <= '9') - { - host.s_addr = inet_addr(hostName); - } - else { - unsigned dex; - /* seeing a lot of soft failures here that I really don't want to track down */ - for(dex=0; dexh_addr, sizeof(struct in_addr)); - } - sock = socket(AF_INET, SOCK_STREAM, 0); - addr.sin_addr = host; - addr.sin_port = htons((u_short)port); - - addr.sin_family = AF_INET; - if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - { printf("connect returned error\n"); - return errSecIO; - } - - if(nonBlocking) { - /* OK to do this after connect? */ - int rtn = fcntl(sock, F_SETFL, O_NONBLOCK); - if(rtn == -1) { - perror("fctnl(O_NONBLOCK)"); - return errSecIO; - } - } - - peer->ipAddr = addr.sin_addr.s_addr; - peer->port = htons((u_short)port); - *socketNo = (otSocket)sock; - return errSecSuccess; -} - -/* - * Set up an otSocket to listen for client connections. Call once, then - * use multiple AcceptClientConnection calls. - */ -OSStatus ListenForClients( - int port, - int nonBlocking, // 0 or 1 - otSocket *socketNo) // RETURNED -{ - struct sockaddr_in addr; - struct hostent *ent; - int len; - int sock; - - sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock < 1) { - perror("socket"); - return errSecIO; - } - - int reuse = 1; - int err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); - if (err != 0) { - perror("setsockopt"); - return err; - } - - ent = gethostbyname("localhost"); - if (!ent) { - perror("gethostbyname"); - return errSecIO; - } - memcpy(&addr.sin_addr, ent->h_addr, sizeof(struct in_addr)); - - addr.sin_port = htons((u_short)port); - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_family = AF_INET; - len = sizeof(struct sockaddr_in); - if (bind(sock, (struct sockaddr *) &addr, len)) { - int theErr = errno; - perror("bind"); - if(theErr == EADDRINUSE) { - return errSecOpWr; - } - else { - return errSecIO; - } - } - if(nonBlocking) { - int rtn = fcntl(sock, F_SETFL, O_NONBLOCK); - if(rtn == -1) { - perror("fctnl(O_NONBLOCK)"); - return errSecIO; - } - } - - for(;;) { - int rtn = listen(sock, 1); - switch(rtn) { - case 0: - *socketNo = (otSocket)sock; - rtn = errSecSuccess; - break; - case EWOULDBLOCK: - continue; - default: - perror("listen"); - rtn = errSecIO; - break; - } - return rtn; - } - /* NOT REACHED */ - return 0; -} - -/* - * Accept a client connection. - */ - -/* - * Currently we always get back a different peer port number on successive - * connections, no matter what the client is doing. To test for resumable - * session support, force peer port = 0. - */ -#define FORCE_ACCEPT_PEER_PORT_ZERO 1 - -OSStatus AcceptClientConnection( - otSocket listenSock, // obtained from ListenForClients - otSocket *acceptSock, // RETURNED - PeerSpec *peer) // RETURNED -{ - struct sockaddr_in addr; - int sock; - socklen_t len; - - len = sizeof(struct sockaddr_in); - do { - sock = accept((int)listenSock, (struct sockaddr *) &addr, &len); - if (sock < 0) { - if(errno == EAGAIN) { - /* nonblocking, no connection yet */ - continue; - } - else { - perror("accept"); - return errSecIO; - } - } - else { - break; - } - } while(1); - *acceptSock = (otSocket)sock; - peer->ipAddr = addr.sin_addr.s_addr; - #if FORCE_ACCEPT_PEER_PORT_ZERO - peer->port = 0; - #else - peer->port = ntohs(addr.sin_port); - #endif - return errSecSuccess; -} - -/* - * Shut down a connection. - */ -void endpointShutdown( - otSocket sock) -{ - close((int)sock); -} - -/* - * R/W. Called out from SSL. - */ -OSStatus SocketRead( - SSLConnectionRef connection, - void *data, /* owned by - * caller, data - * RETURNED */ - size_t *dataLength) /* IN/OUT */ -{ - UInt32 bytesToGo = *dataLength; - UInt32 initLen = bytesToGo; - UInt8 *currData = (UInt8 *)data; - int sock = (int)((long)connection); - OSStatus rtn = errSecSuccess; - UInt32 bytesRead; - ssize_t rrtn; - - *dataLength = 0; - - for(;;) { - bytesRead = 0; - /* paranoid check, ensure errno is getting written */ - errno = -555; - rrtn = recv(sock, currData, bytesToGo, 0); - if (rrtn <= 0) { - if(rrtn == 0) { - /* closed, EOF */ - rtn = errSSLClosedGraceful; - break; - } - int theErr = errno; - switch(theErr) { - case ENOENT: - /* - * Undocumented but I definitely see this. - * Non-blocking sockets only. Definitely retriable - * just like an EAGAIN. - */ - dprintf(("SocketRead RETRYING on ENOENT, rrtn %d\n", - (int)rrtn)); - /* normal... */ - //rtn = errSSLWouldBlock; - /* ...for temp testing.... */ - rtn = errSecIO; - break; - case ECONNRESET: - /* explicit peer abort */ - rtn = errSSLClosedAbort; - break; - case EAGAIN: - /* nonblocking, no data */ - rtn = errSSLWouldBlock; - break; - default: - dprintf(("SocketRead: read(%u) error %d, rrtn %d\n", - (unsigned)bytesToGo, theErr, (int)rrtn)); - rtn = errSecIO; - break; - } - /* in any case, we're done with this call if rrtn <= 0 */ - break; - } - bytesRead = rrtn; - bytesToGo -= bytesRead; - currData += bytesRead; - - if(bytesToGo == 0) { - /* filled buffer with incoming data, done */ - break; - } - } - *dataLength = initLen - bytesToGo; - tprintf("SocketRead", initLen, *dataLength, (UInt8 *)data); - - #if SSL_OT_DOT || (SSL_OT_DEBUG && !SSL_OT_IO_TRACE) - if((rtn == 0) && (*dataLength == 0)) { - /* keep UI alive */ - outputDot(); - } - #endif - #if SSL_DISPL_WOULD_BLOCK - if(rtn == errSSLWouldBlock) { - printf("."); fflush(stdout); - } - #endif - return rtn; -} - -int oneAtATime = 0; - -OSStatus SocketWrite( - SSLConnectionRef connection, - const void *data, - size_t *dataLength) /* IN/OUT */ -{ - size_t bytesSent = 0; - int sock = (int)((long)connection); - int length; - size_t dataLen = *dataLength; - const UInt8 *dataPtr = (UInt8 *)data; - OSStatus ortn; - - if(oneAtATime && (*dataLength > 1)) { - size_t i; - size_t outLen; - size_t thisMove; - - outLen = 0; - for(i=0; i 0) && - ( (bytesSent += length) < dataLen) ); - - if(length <= 0) { - int theErr = errno; - switch(theErr) { - case EAGAIN: - ortn = errSSLWouldBlock; break; - case EPIPE: - ortn = errSSLClosedAbort; break; - default: - dprintf(("SocketWrite: write(%u) error %d\n", - (unsigned)(dataLen - bytesSent), theErr)); - ortn = errSecIO; - break; - } - } - else { - ortn = errSecSuccess; - } - tprintf("SocketWrite", dataLen, bytesSent, dataPtr); - *dataLength = bytesSent; - return ortn; -}