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

Annotation of /imapfilter/socket.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide 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 lefcha 1.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 lefcha 1.2
62 lefcha 1.1 #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 lefcha 1.2
74 lefcha 1.1
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 lefcha 1.2
89 lefcha 1.1 SSL_library_init();
90 lefcha 1.2
91 lefcha 1.1 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 lefcha 1.2
103 lefcha 1.1 if (!(ctx = SSL_CTX_new(method)))
104     return ERROR_SSL;
105 lefcha 1.2
106 lefcha 1.1 if (!(ssl = SSL_new(ctx)))
107     return ERROR_SSL;
108 lefcha 1.2
109 lefcha 1.1 SSL_set_fd(ssl, sock);
110    
111     e = SSL_connect(ssl);
112 lefcha 1.2
113 lefcha 1.1 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 lefcha 1.2
175 lefcha 1.1 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 lefcha 1.2 if (e == -1)
185     fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
186     strerror(errno));
187    
188 lefcha 1.1 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 lefcha 1.2
219 lefcha 1.1 return 0;
220     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26