1 /*
2  * mbsync - mailbox synchronizer
3  * Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
4  * Copyright (C) 2002-2006,2010-2012 Oswald Buddenhagen <ossi@users.sf.net>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  * As a special exception, mbsync may be linked with the OpenSSL library,
20  * despite that library's more restrictive license.
21  */
22 
23 #ifndef SOCKET_H
24 #define SOCKET_H
25 
26 #include "common.h"
27 
28 #ifdef HAVE_LIBZ
29 #include <zlib.h>
30 #endif
31 
32 #ifdef HAVE_LIBSSL
33 # include <openssl/ssl.h>
34 # include <openssl/x509.h>
35 
36 enum {
37 	TLSv1 = 4,
38 	TLSv1_1 = 8,
39 	TLSv1_2 = 16,
40 	TLSv1_3 = 32
41 };
42 #endif
43 
44 typedef struct {
45 	char *tunnel;
46 	char *host;
47 	ushort port;
48 	int timeout;
49 #ifdef HAVE_LIBSSL
50 	char *cert_file;
51 	char *client_certfile;
52 	char *client_keyfile;
53 	char *cipher_string;
54 	char system_certs;
55 	char ssl_versions;
56 
57 	/* these are actually variables and are leaked at the end */
58 	char ssl_ctx_valid;
59 	STACK_OF(X509) *trusted_certs;
60 	SSL_CTX *SSLContext;
61 #endif
62 } server_conf_t;
63 
64 typedef struct buff_chunk {
65 	struct buff_chunk *next;
66 	uint len;
67 	char data[1];
68 } buff_chunk_t;
69 
70 typedef struct {
71 	/* connection */
72 	int fd;
73 	int state;
74 	const server_conf_t *conf; /* needed during connect */
75 #ifdef HAVE_IPV6
76 	struct addrinfo *addrs, *curr_addr; /* needed during connect */
77 #else
78 	struct addr_info *addrs, *curr_addr; /* needed during connect */
79 #endif
80 	char *name;
81 #ifdef HAVE_LIBSSL
82 	SSL *ssl;
83 	wakeup_t ssl_fake;
84 #endif
85 #ifdef HAVE_LIBZ
86 	z_streamp in_z, out_z;
87 	wakeup_t z_fake;
88 	int z_written;
89 #endif
90 
91 	void (*bad_callback)( void *aux ); /* async fail while sending or listening */
92 	void (*read_callback)( void *aux ); /* data available for reading */
93 	void (*write_callback)( void *aux ); /* all *queued* data was sent */
94 	union {
95 		void (*connect)( int ok, void *aux );
96 		void (*starttls)( int ok, void *aux );
97 	} callbacks;
98 	void *callback_aux;
99 
100 	notifier_t notify;
101 	wakeup_t fd_fake;
102 	wakeup_t fd_timeout;
103 
104 	/* writing */
105 	buff_chunk_t *append_buf; /* accumulating buffer */
106 	buff_chunk_t *write_buf, **write_buf_append; /* buffer head & tail */
107 #ifdef HAVE_LIBZ
108 	uint append_avail; /* space left in accumulating buffer */
109 #endif
110 	uint write_offset; /* offset into buffer head */
111 	uint buffer_mem; /* memory currently occupied by buffers in the queue */
112 
113 	/* reading */
114 	uint offset; /* start of filled bytes in buffer */
115 	uint bytes; /* number of filled bytes in buffer */
116 	uint scanoff; /* offset to continue scanning for newline at, relative to 'offset' */
117 	char buf[100000];
118 #ifdef HAVE_LIBZ
119 	char z_buf[100000];
120 #endif
121 } conn_t;
122 
123 /* call this before doing anything with the socket */
socket_init(conn_t * conn,const server_conf_t * conf,void (* bad_callback)(void * aux),void (* read_callback)(void * aux),void (* write_callback)(void * aux),void * aux)124 static INLINE void socket_init( conn_t *conn,
125                                 const server_conf_t *conf,
126                                 void (*bad_callback)( void *aux ),
127                                 void (*read_callback)( void *aux ),
128                                 void (*write_callback)( void *aux ),
129                                 void *aux )
130 {
131 	conn->conf = conf;
132 	conn->bad_callback = bad_callback;
133 	conn->read_callback = read_callback;
134 	conn->write_callback = write_callback;
135 	conn->callback_aux = aux;
136 	conn->fd = -1;
137 	conn->name = NULL;
138 	conn->write_buf_append = &conn->write_buf;
139 }
140 void socket_connect( conn_t *conn, void (*cb)( int ok, void *aux ) );
141 void socket_start_tls(conn_t *conn, void (*cb)( int ok, void *aux ) );
142 void socket_start_deflate( conn_t *conn );
143 void socket_close( conn_t *sock );
144 void socket_expect_activity( conn_t *sock, int expect );
145 int socket_read( conn_t *sock, char *buf, uint len ); /* never waits */
146 char *socket_read_line( conn_t *sock ); /* don't free return value; never waits */
147 typedef enum { KeepOwn = 0, GiveOwn } ownership_t;
148 typedef struct {
149 	char *buf;
150 	uint len;
151 	ownership_t takeOwn;
152 } conn_iovec_t;
153 void socket_write( conn_t *sock, conn_iovec_t *iov, int iovcnt );
154 
155 #endif
156