/[imapfilter]/imapfilter/socket.c
ViewVC logotype

Contents of /imapfilter/socket.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations)
Tue Oct 23 09:23:08 2001 UTC (22 years, 5 months ago) by lefcha
Branch: MAIN
Changes since 1.1: +14 -18 lines
File MIME type: text/plain
Small changes.

1 #include <string.h>
2 #include <errno.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 #include <netdb.h>
8 #include <fcntl.h>
9
10 #include "config.h"
11 #include "imapfilter.h"
12
13 #ifdef SSL_TLS
14 #include <openssl/ssl.h>
15 #include <openssl/err.h>
16
17
18 static SSL *ssl;
19 #endif
20
21 static int sock;
22
23
24 /*
25 * Connect to mail server.
26 */
27 #ifndef SSL_TLS
28 int init_connection(char *serv, unsigned int port)
29 #else
30 int init_connection(char *serv, unsigned int port, unsigned int protocol)
31 #endif
32 {
33 struct sockaddr_in sa;
34 struct hostent *he;
35
36 memset((char *) &sa, 0, sizeof(struct sockaddr_in));
37
38 sock = socket(PF_INET, SOCK_STREAM, 0);
39
40 if (sock < 0) {
41 error("imapfilter: create socket; %s\n", strerror(errno));
42 return ERROR_NETWORK;
43 }
44 if (!(he = gethostbyname(serv))) {
45 error("imapfilter: get network host entry; %s\n", strerror(errno));
46 close_connection();
47 return ERROR_NETWORK;
48 }
49 sa.sin_family = AF_INET;
50 sa.sin_port = htons(port);
51 sa.sin_addr = *(struct in_addr *) he->h_addr;
52
53 if (connect(sock, (struct sockaddr *) & sa, sizeof(struct sockaddr))) {
54 error("imapfilter: initiating connection; %s\n", strerror(errno));
55 close_connection();
56 return ERROR_NETWORK;
57 }
58 strncpy(serv, he->h_name, SERVER_LEN - 1);
59
60 log_info(LOG_SERVER, serv);
61
62 #ifdef SSL_TLS
63 if (protocol != SSL_DISABLED) {
64 ssl_init(protocol);
65 info("Connected to %s using %s.\n", serv, SSL_get_cipher(ssl));
66 } else {
67 ssl = NULL;
68 #endif
69 info("Connected to %s.\n", serv);
70 #ifdef SSL_TLS
71 }
72 #endif
73
74
75 return 0;
76 }
77
78
79 #ifdef SSL_TLS
80 /*
81 * Initialize Secure Socket Layer connection.
82 */
83 int ssl_init(unsigned int protocol)
84 {
85 int e;
86 SSL_CTX *ctx;
87 SSL_METHOD *method = NULL;
88
89 SSL_library_init();
90
91 switch (protocol) {
92 case SSL_SSL_V2:
93 method = SSLv2_client_method();
94 break;
95 case SSL_SSL_V3:
96 method = SSLv3_client_method();
97 break;
98 case SSL_TLS_V1:
99 method = TLSv1_client_method();
100 break;
101 }
102
103 if (!(ctx = SSL_CTX_new(method)))
104 return ERROR_SSL;
105
106 if (!(ssl = SSL_new(ctx)))
107 return ERROR_SSL;
108
109 SSL_set_fd(ssl, sock);
110
111 e = SSL_connect(ssl);
112
113 if (e <= 0) {
114 error("imapfilter: initiating SSL connection; %s",
115 ERR_error_string(e, NULL));
116 return ERROR_SSL;
117 }
118 SSL_CTX_free(ctx);
119
120 return 0;
121 }
122 #endif
123
124
125 /*
126 * Disconnect from mail server.
127 */
128 int close_connection(void)
129 {
130 #ifdef SSL_TLS
131 if (ssl) {
132 SSL_shutdown(ssl);
133 SSL_free(ssl);
134 }
135 #endif
136
137 if (close(sock)) {
138 error("imapfilter: closing socket; %s\n", strerror(errno));
139 return ERROR_NETWORK;
140 } else
141 return 0;
142 }
143
144
145 /*
146 * Read data from socket.
147 */
148 int socket_read(char *buf)
149 {
150 int flags, e;
151 fd_set fds;
152 struct timeval tv;
153
154 memset(buf, 0, RESPONSE_BUF);
155
156 tv.tv_sec = 20;
157 tv.tv_usec = 0;
158
159 flags = fcntl(sock, F_GETFL, 0);
160 fcntl(sock, F_SETFL, flags | O_NONBLOCK);
161
162 FD_ZERO(&fds);
163 FD_SET(sock, &fds);
164
165 if ((select(sock + 1, &fds, NULL, NULL, &tv) > 0)
166 && FD_ISSET(sock, &fds)) {
167
168 #ifdef SSL_TLS
169 if (ssl)
170 e = SSL_read(ssl, buf, RESPONSE_BUF - 1);
171 else
172 #endif
173 e = read(sock, buf, RESPONSE_BUF - 1);
174
175 fcntl(sock, F_SETFL, flags);
176
177 #ifdef SSL_TLS
178 if (ssl) {
179 if (e <= 0)
180 fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
181 ERR_error_string(e, NULL));
182 } else
183 #endif
184 if (e == -1)
185 fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
186 strerror(errno));
187
188 return 0;
189 }
190 fcntl(sock, F_SETFL, flags);
191
192 fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",
193 strerror(errno));
194
195 return ERROR_NETWORK; /* NEVER REACHED. */
196 }
197
198
199 /*
200 * Write data to socket.
201 */
202 int socket_write(char *data)
203 {
204 #ifdef SSL_TLS
205 int e;
206
207 if (ssl) {
208 e = SSL_write(ssl, data, strlen(data));
209 if (e <= 0)
210 fatal(ERROR_NETWORK,
211 "imapfilter: sending data; %s",
212 ERR_error_string(e, NULL));
213 } else
214 #endif
215 if (write(sock, data, strlen(data)) == -1)
216 fatal(ERROR_NETWORK, "imapfilter: sending data; %s",
217 strerror(errno));
218
219 return 0;
220 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26