5 |
#include <netinet/in.h> |
#include <netinet/in.h> |
6 |
#include <netdb.h> |
#include <netdb.h> |
7 |
#include <sys/socket.h> |
#include <sys/socket.h> |
8 |
#include <sys/types.h> /* IEEE Std 1003.1-2001 non-conformance. */ |
#include <sys/types.h> /* For POSIX.1-2001 non-conformant systems. */ |
9 |
#include <sys/time.h> /* IEEE Std 1003.1-2001 non-conformance. */ |
#include <sys/time.h> /* For POSIX.1-2001 non-conformant systems. */ |
10 |
#include <sys/select.h> |
#include <sys/select.h> |
11 |
#include <fcntl.h> |
#include <fcntl.h> |
12 |
|
|
19 |
#endif |
#endif |
20 |
|
|
21 |
|
|
22 |
extern unsigned int options; |
extern options_t opts; |
23 |
extern conn_t connpri, connaux; |
extern connection_t connpri, connaux; |
|
|
|
|
long timeout = -1; /* Server non-response timeout in seconds. */ |
|
24 |
|
|
25 |
|
|
26 |
/* |
/* |
27 |
* Connect to mail server. |
* Connect to mail server. |
28 |
*/ |
*/ |
29 |
int |
int |
30 |
init_connection(conn_t * conn, char *serv, unsigned short int port, |
init_connection(connection_t * conn, char *serv, unsigned short int port, |
31 |
unsigned int protocol) |
unsigned int protocol) |
32 |
{ |
{ |
33 |
struct sockaddr_in sa; |
struct sockaddr_in sa; |
56 |
} |
} |
57 |
sa.sin_family = AF_INET; |
sa.sin_family = AF_INET; |
58 |
sa.sin_port = htons(port); |
sa.sin_port = htons(port); |
59 |
sa.sin_addr = *(struct in_addr *) he->h_addr; |
sa.sin_addr = *(struct in_addr *)he->h_addr; |
60 |
|
|
61 |
if (connect(conn->sock, (struct sockaddr *) & sa, |
if (connect(conn->sock, (struct sockaddr *)&sa, |
62 |
sizeof(struct sockaddr))) { |
sizeof(struct sockaddr))) { |
63 |
error("initiating connection to %s; %s\n", serv, |
error("initiating connection to %s; %s\n", serv, |
64 |
strerror(errno)); |
strerror(errno)); |
65 |
close_connection(conn); |
close_connection(conn); |
87 |
* Initialize Secure Socket Layer connection. |
* Initialize Secure Socket Layer connection. |
88 |
*/ |
*/ |
89 |
int |
int |
90 |
init_secure_connection(conn_t * conn, unsigned int protocol) |
init_secure_connection(connection_t * conn, unsigned int protocol) |
91 |
{ |
{ |
92 |
int e; |
int e; |
93 |
SSL_CTX *ctx; |
SSL_CTX *ctx; |
122 |
ERR_error_string(ERR_get_error(), NULL)); |
ERR_error_string(ERR_get_error(), NULL)); |
123 |
goto fail; |
goto fail; |
124 |
} |
} |
125 |
if (options & OPTION_DETAILS_VERBOSE) { |
if (opts.verbosity >= 1) { |
126 |
SSL_CIPHER *cipher; |
SSL_CIPHER *cipher; |
127 |
char *ver; |
char *ver; |
128 |
const char *name; |
const char *name; |
155 |
* Disconnect from mail server. |
* Disconnect from mail server. |
156 |
*/ |
*/ |
157 |
int |
int |
158 |
close_connection(conn_t * conn) |
close_connection(connection_t * conn) |
159 |
{ |
{ |
160 |
|
|
161 |
#ifdef SSL_TLS |
#ifdef SSL_TLS |
162 |
if (conn->ssl) { |
if (conn->ssl) { |
163 |
SSL_shutdown(conn->ssl); |
SSL_shutdown(conn->ssl); |
179 |
* Read data from socket. |
* Read data from socket. |
180 |
*/ |
*/ |
181 |
int |
int |
182 |
socket_read(conn_t * conn, char *buf) |
socket_read(connection_t * conn, char *buf) |
183 |
{ |
{ |
184 |
int f, e, s; |
int f, e, s; |
185 |
fd_set fds; |
fd_set fds; |
192 |
|
|
193 |
memset(buf, 0, RESPONSE_BUF + 1); |
memset(buf, 0, RESPONSE_BUF + 1); |
194 |
|
|
195 |
if (timeout >= 0) { |
if (opts.timeout >= 0) { |
196 |
tv.tv_sec = timeout; |
tv.tv_sec = opts.timeout; |
197 |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
198 |
tvp = &tv; |
tvp = &tv; |
199 |
} |
} |
207 |
if (conn->ssl) { |
if (conn->ssl) { |
208 |
while (SSL_pending(conn->ssl) > 0 || |
while (SSL_pending(conn->ssl) > 0 || |
209 |
((s = select(conn->sock + 1, &fds, NULL, NULL, tvp)) > 0 && |
((s = select(conn->sock + 1, &fds, NULL, NULL, tvp)) > 0 && |
210 |
FD_ISSET(conn->sock, &fds))) { |
FD_ISSET(conn->sock, &fds))) { |
211 |
e = SSL_read(conn->ssl, buf, RESPONSE_BUF); |
e = SSL_read(conn->ssl, buf, RESPONSE_BUF); |
212 |
|
|
213 |
if (e > 0) |
if (e > 0) |
260 |
* Write data to socket. |
* Write data to socket. |
261 |
*/ |
*/ |
262 |
int |
int |
263 |
socket_write(conn_t * conn, char *data) |
socket_write(connection_t * conn, char *data) |
264 |
{ |
{ |
265 |
int f, e, s; |
int f, e, s; |
266 |
fd_set fds; |
fd_set fds; |
270 |
e = 0; |
e = 0; |
271 |
s = 1; |
s = 1; |
272 |
|
|
273 |
if (timeout >= 0) { |
if (opts.timeout >= 0) { |
274 |
tv.tv_sec = timeout; |
tv.tv_sec = opts.timeout; |
275 |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
276 |
tvp = &tv; |
tvp = &tv; |
277 |
} |
} |
284 |
#ifdef SSL_TLS |
#ifdef SSL_TLS |
285 |
if (conn->ssl) { |
if (conn->ssl) { |
286 |
while ((s = select(conn->sock + 1, NULL, &fds, NULL, tvp) > 0 && |
while ((s = select(conn->sock + 1, NULL, &fds, NULL, tvp) > 0 && |
287 |
FD_ISSET(conn->sock, &fds))) { |
FD_ISSET(conn->sock, &fds))) { |
288 |
e = SSL_write(conn->ssl, data, strlen(data)); |
e = SSL_write(conn->ssl, data, strlen(data)); |
289 |
|
|
290 |
if (e > 0) |
if (e > 0) |