pop3: report error responses
[pop3.git] / conn_openssl.c
blob2b1db0bafadc9c861867392ec831de5173194150
1 #include <arpa/inet.h>
2 #include <netinet/in.h>
3 #include <netdb.h>
4 #include <signal.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/socket.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <time.h>
12 #include <unistd.h>
14 #include <openssl/crypto.h>
15 #include <openssl/x509.h>
16 #include <openssl/pem.h>
17 #include <openssl/ssl.h>
18 #include <openssl/err.h>
20 struct conn {
21 int fd;
22 SSL_CTX *ctx;
23 SSL *ssl;
26 int conn_read(struct conn *conn, char *buf, int len)
28 if (conn->ssl)
29 return SSL_read(conn->ssl, buf, len);
30 return read(conn->fd, buf, len);
33 int conn_write(struct conn *conn, char *buf, int len)
35 if (conn->ssl)
36 return SSL_write(conn->ssl, buf, len);
37 return write(conn->fd, buf, len);
40 int conn_tls(struct conn *conn, char *certfile)
42 SSLeay_add_ssl_algorithms();
43 SSL_load_error_strings();
44 conn->ctx = SSL_CTX_new(SSLv23_method());
45 if (!conn->ctx)
46 return 1;
47 conn->ssl = SSL_new(conn->ctx);
48 if (!conn->ssl)
49 return 1;
50 if (certfile) {
51 SSL_CTX_set_verify(conn->ctx, SSL_VERIFY_PEER, NULL);
52 SSL_CTX_load_verify_locations(conn->ctx, certfile, NULL);
54 SSL_set_fd(conn->ssl, conn->fd);
55 if (SSL_connect(conn->ssl) != 1)
56 return 1;
57 if (certfile && SSL_get_verify_result(conn->ssl) != X509_V_OK)
58 return 1;
59 return 0;
62 struct conn *conn_connect(char *addr, char *port, char *certfile)
64 struct addrinfo hints, *addrinfo;
65 struct conn *conn;
66 int fd;
68 memset(&hints, 0, sizeof(hints));
69 hints.ai_family = AF_UNSPEC;
70 hints.ai_socktype = SOCK_STREAM;
71 hints.ai_flags = AI_PASSIVE;
73 if (getaddrinfo(addr, port, &hints, &addrinfo))
74 return NULL;
75 fd = socket(addrinfo->ai_family, addrinfo->ai_socktype,
76 addrinfo->ai_protocol);
78 if (connect(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == -1) {
79 close(fd);
80 freeaddrinfo(addrinfo);
81 return NULL;
83 freeaddrinfo(addrinfo);
85 conn = malloc(sizeof(*conn));
86 memset(conn, 0, sizeof(*conn));
87 conn->fd = fd;
88 return conn;
91 int conn_close(struct conn *conn)
93 if (conn->ssl) {
94 SSL_shutdown(conn->ssl);
95 SSL_free(conn->ssl);
96 SSL_CTX_free(conn->ctx);
98 close(conn->fd);
99 free(conn);
100 return 0;