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

Contents of /imapfilter/socket.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Wed Oct 17 14:03:37 2001 UTC (22 years, 5 months ago) by lefcha
Branch: MAIN
File MIME type: text/plain
Renamed connect.c to socket.c.

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
119 SSL_CTX_free(ctx);
120
121 return 0;
122 }
123 #endif
124
125
126 /*
127 * Disconnect from mail server.
128 */
129 int close_connection(void)
130 {
131 #ifdef SSL_TLS
132 if (ssl) {
133 SSL_shutdown(ssl);
134 SSL_free(ssl);
135 ssl = NULL;
136 }
137 #endif
138
139 if (close(sock)) {
140 error("imapfilter: closing socket; %s\n", strerror(errno));
141 return ERROR_NETWORK;
142 } else
143 return 0;
144 }
145
146
147 /*
148 * Read data from socket.
149 */
150 int socket_read(char *buf)
151 {
152 int flags, e;
153 fd_set fds;
154 struct timeval tv;
155
156 memset(buf, 0, RESPONSE_BUF);
157
158 tv.tv_sec = 20;
159 tv.tv_usec = 0;
160
161 flags = fcntl(sock, F_GETFL, 0);
162 fcntl(sock, F_SETFL, flags | O_NONBLOCK);
163
164 FD_ZERO(&fds);
165 FD_SET(sock, &fds);
166
167 if ((select(sock + 1, &fds, NULL, NULL, &tv) > 0)
168 && FD_ISSET(sock, &fds)) {
169
170 #ifdef SSL_TLS
171 if (ssl)
172 e = SSL_read(ssl, buf, RESPONSE_BUF - 1);
173 else
174 #endif
175 e = read(sock, buf, RESPONSE_BUF - 1);
176
177 fcntl(sock, F_SETFL, flags);
178
179 #ifdef SSL_TLS
180 if (ssl) {
181 if (e <= 0)
182 fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
183 ERR_error_string(e, NULL));
184 } else
185 #endif
186 if(e == -1)
187 fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
188 strerror(errno));
189
190 return 0;
191 }
192
193 fcntl(sock, F_SETFL, flags);
194
195 fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",
196 strerror(errno));
197
198 return ERROR_NETWORK; /* NEVER REACHED. */
199 }
200
201
202 /*
203 * Write data to socket.
204 */
205 int socket_write(char *data)
206 {
207 #ifdef SSL_TLS
208 int e;
209
210 if (ssl) {
211 e = SSL_write(ssl, data, strlen(data));
212 if (e <= 0)
213 fatal(ERROR_NETWORK,
214 "imapfilter: sending data; %s",
215 ERR_error_string(e, NULL));
216 } else
217 #endif
218 if (write(sock, data, strlen(data)) == -1)
219 fatal(ERROR_NETWORK, "imapfilter: sending data; %s",
220 strerror(errno));
221
222 return 0;
223 }
224

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26