/*<copyright> * <year>1999-2008</year> * <holder>Ericsson AB, All Rights Reserved</holder> *</copyright> *<legalnotice> * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Initial Developer of the Original Code is Ericsson AB. *</legalnotice> */ /* * Purpose: Implementation of Secure Socket Layer (SSL). * */ #ifndef ESOCK_H #define ESOCK_H #ifdef __WIN32__ #include "esock_winsock.h" #endif #include <stdio.h> #ifdef __WIN32__ #define INVALID_FD INVALID_SOCKET #define sock_read(fd, buf, len) recv((fd), (buf), (len), 0) #define sock_write(fd, buf, len) send((fd), (buf), (len), 0) #define sock_close(fd) closesocket(fd) #define sock_errno() WSAGetLastError() #define sock_set_errno(err) WSASetLastError(err) #define ERRNO_NONE 0 #define ERRNO_BLOCK WSAEWOULDBLOCK #define ERRNO_CONNREFUSED WSAECONNREFUSED #define ERRNO_PROGRESS WSAEINPROGRESS #define ERRNO_PROTONOSUPPORT WSAEPROTONOSUPPORT #define ERRNO_INVAL WSAEINVAL #define ERRNO_ADDRNOTAVAIL WSAEADDRNOTAVAIL #define ERRNO_NOTSOCK WSAENOTSOCK #define ERRNO_OPNOTSUPP WSAEOPNOTSUPP #define ERRNO_MFILE WSAEMFILE #define SET_BLOCKING(fd) do { \ unsigned long zeroval = 0; \ ioctlsocket((fd), FIONBIO, &zeroval); \ } while (0) #define SET_NONBLOCKING(fd) do { \ unsigned long oneval = 1; \ ioctlsocket((fd), FIONBIO, &oneval); \ } while (0) #else #define INVALID_FD (-1) #define sock_read(fd, buf, len) read((fd), (buf), (len)) #define sock_write(fd, buf, len) write((fd), (buf), (len)) #define sock_close(fd) close(fd) #define sock_errno() errno #define sock_set_errno(err) do {errno = (err);} while(0) #define ERRNO_NONE 0 #define ERRNO_BLOCK EAGAIN #define ERRNO_CONNREFUSED ECONNREFUSED #define ERRNO_PROGRESS EINPROGRESS #define ERRNO_PROTONOSUPPORT EPROTONOSUPPORT #define ERRNO_INVAL EINVAL #define ERRNO_ADDRNOTAVAIL EADDRNOTAVAIL #define ERRNO_NOTSOCK ENOTSOCK #define ERRNO_OPNOTSUPP EOPNOTSUPP #define ERRNO_MFILE EMFILE #define SET_BLOCKING(fd) fcntl((fd), F_SETFL, \ fcntl((fd), F_GETFL, 0) & ~O_NONBLOCK) #define SET_NONBLOCKING(fd) fcntl((fd), F_SETFL, \ fcntl((fd), F_GETFL, 0) | O_NONBLOCK) #endif #define GET_INT8(s) ((s)[0]) #define GET_INT16(s) (((s)[0] << 8) | (s)[1]) #define GET_INT32(s) (((s)[0] << 24) | ((s)[1] << 16) | \ ((s)[2] << 8) | (s)[3]) #define PUT_INT8(x, s) do { (s)[0] = x; } while(0) #define PUT_INT16(x, s) do { (s)[0] = ((x) >> 8) & 0xff; \ (s)[1] = ((x) & 0xff); } while(0) #define PUT_INT32(x, s) do { (s)[0] = ((x) >> 24) & 0xff; \ (s)[1] = ((x) >> 16) & 0xff; \ (s)[2] = ((x) >> 8) & 0xff; \ (s)[3] = (x) & 0xff; } while(0) /* type for Connections */ #define ESOCK_STATE_NONE 0 #define ESOCK_ACTIVE_LISTENING 1 #define ESOCK_PASSIVE_LISTENING 2 #define ESOCK_CONNECTED 3 #define ESOCK_WAIT_CONNECT 4 #define ESOCK_SSL_CONNECT 5 #define ESOCK_SSL_ACCEPT 6 #define ESOCK_TRANSPORT_ACCEPT 7 #define ESOCK_JOINED 8 #define ESOCK_SSL_SHUTDOWN 9 #define ESOCK_DEFUNCT 10 #ifdef __WIN32__ typedef SOCKET FD; #else typedef int FD; #endif /* For the shutdown(fd, how) call */ #ifdef __WIN32__ #define SHUTDOWN_READ SD_RECEIVE #define SHUTDOWN_WRITE SD_SEND #define SHUTDOWN_ALL SD_BOTH #else #define SHUTDOWN_READ 0 #define SHUTDOWN_WRITE 1 #define SHUTDOWN_ALL 2 #endif #define ORIG_LISTEN 0 #define ORIG_ACCEPT 1 #define ORIG_CONNECT 2 typedef struct { int size; /* Total size of buf */ unsigned char *buf; int len; /* Current number of bytes in buf */ int offset; /* Bytes already written */ } WriteQueue; typedef struct _proxy Proxy; typedef struct Connection { FD fd; FD listen_fd; /* Needed for async listen error */ unsigned char state; int acceptors; /* Count acceptors for listen socket */ Proxy *proxy; void *opaque; /* Any suitable ssl structure */ int ssl_want; /* read/write flags */ int eof; /* end of file (read) */ int bp; /* broken pipe (write) */ int clean; /* Clean SSL shutdown initiated */ int close; /* Close if set */ int origin; /* listen, accept or connect */ int encrypted; /* 1 = SSL encrypted, 0 = normal, unencrypted tcp */ char *flags; /* ssl parameters */ FILE *logfp; /* connection log file (not used) */ WriteQueue wq; struct Connection* next; const char* errstr; /* only used to report errors from ssl_accept_init in SSL_ACCEPT */ } Connection; struct _proxy { FD fd; int peer_port; int eof; /* end of file (read) */ int bp; /* broken pipe (write) */ Connection *conn; WriteQueue wq; Proxy *next; }; /* Commands, replies, and error responses */ #define ESOCK_CONNECT_CMD 1 #define ESOCK_CONNECT_WAIT_REP 2 #define ESOCK_CONNECT_REP 3 #define ESOCK_CONNECT_ERR 4 #define ESOCK_TERMINATE_CMD 5 #define ESOCK_CLOSE_CMD 6 #define ESOCK_LISTEN_CMD 7 #define ESOCK_LISTEN_REP 8 #define ESOCK_LISTEN_ERR 9 #define ESOCK_TRANSPORT_ACCEPT_CMD 10 #define ESOCK_NOACCEPT_CMD 11 #define ESOCK_TRANSPORT_ACCEPT_REP 12 #define ESOCK_TRANSPORT_ACCEPT_ERR 13 #define ESOCK_FROMNET_CLOSE_REP 14 #define ESOCK_CONNECT_SYNC_ERR 15 #define ESOCK_LISTEN_SYNC_ERR 16 #define ESOCK_PROXY_PORT_REP 23 #define ESOCK_PROXY_JOIN_CMD 24 #define ESOCK_PROXY_JOIN_REP 25 #define ESOCK_PROXY_JOIN_ERR 26 #define ESOCK_SET_SOCKOPT_CMD 27 #define ESOCK_IOCTL_OK 28 #define ESOCK_IOCTL_ERR 29 #define ESOCK_GETPEERNAME_CMD 30 #define ESOCK_GETPEERNAME_REP 31 #define ESOCK_GETPEERNAME_ERR 32 #define ESOCK_GETSOCKNAME_CMD 33 #define ESOCK_GETSOCKNAME_REP 34 #define ESOCK_GETSOCKNAME_ERR 35 #define ESOCK_GETPEERCERT_CMD 36 #define ESOCK_GETPEERCERT_REP 37 #define ESOCK_GETPEERCERT_ERR 38 #define ESOCK_GETVERSION_CMD 39 #define ESOCK_GETVERSION_REP 40 #define ESOCK_SET_SEED_CMD 41 #define ESOCK_GETCONNINFO_CMD 42 #define ESOCK_GETCONNINFO_REP 43 #define ESOCK_GETCONNINFO_ERR 44 #define ESOCK_SSL_ACCEPT_CMD 45 #define ESOCK_SSL_ACCEPT_REP 46 #define ESOCK_SSL_ACCEPT_ERR 47 #define ESOCK_DUMP_STATE_CMD 48 #define ESOCK_SET_DEBUG_CMD 49 #define ESOCK_SET_DEBUGMSG_CMD 50 /* Option codes for ESOCK_SET_SOCKOPT_CMD */ #define ESOCK_SET_TCP_NODELAY 1 /* SSL want to read or write */ #define ESOCK_SSL_WANT_READ 1 #define ESOCK_SSL_WANT_WRITE 2 /* Protocol version according to ssl_server */ #define ESOCK_SSLv2 1 #define ESOCK_SSLv3 2 #define ESOCK_TLSv1 4 #endif