pop3: some mail servers including gmail return wrong mail sizes
[pop3.git] / conn_mbedtls.c
blobf5132ca0b9c81bc79485dadddc8417921aea664b
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>
13 #include <mbedtls/ssl.h>
14 #include <mbedtls/entropy.h>
15 #include <mbedtls/ctr_drbg.h>
16 #include <mbedtls/net_sockets.h>
18 struct conn {
19 int fd;
20 int tls;
21 mbedtls_ssl_context ssl;
22 mbedtls_ssl_session ssn;
23 mbedtls_ctr_drbg_context ctr_drbg;
24 mbedtls_x509_crt cert;
25 mbedtls_ssl_config conf;
28 int conn_read(struct conn *conn, char *buf, int len)
30 if (conn->tls)
31 return mbedtls_ssl_read(&conn->ssl, (unsigned char *) buf, len);
32 return read(conn->fd, buf, len);
35 int conn_write(struct conn *conn, char *buf, int len)
37 if (conn->tls)
38 return mbedtls_ssl_write(&conn->ssl, (unsigned char *) buf, len);
39 return write(conn->fd, buf, len);
42 int conn_tls(struct conn *conn, char *certfile)
44 mbedtls_entropy_context entropy;
45 mbedtls_entropy_init(&entropy);
46 mbedtls_ctr_drbg_init(&conn->ctr_drbg);
47 mbedtls_ssl_init(&conn->ssl);
48 mbedtls_ssl_config_init(&conn->conf);
49 mbedtls_ctr_drbg_seed(&conn->ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
50 mbedtls_ssl_config_defaults(&conn->conf, MBEDTLS_SSL_IS_CLIENT,
51 MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
52 mbedtls_ssl_conf_rng(&conn->conf, mbedtls_ctr_drbg_random, &conn->ctr_drbg);
53 if (certfile) {
54 mbedtls_x509_crt_parse_file(&conn->cert, certfile);
55 mbedtls_ssl_conf_ca_chain(&conn->conf, &conn->cert, NULL);
56 mbedtls_ssl_conf_authmode(&conn->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
57 mbedtls_ssl_conf_ca_chain(&conn->conf, &conn->cert, NULL);
58 } else {
59 mbedtls_ssl_conf_authmode(&conn->conf, MBEDTLS_SSL_VERIFY_NONE);
61 if (mbedtls_ssl_setup(&conn->ssl, &conn->conf))
62 return 1;
63 mbedtls_ssl_set_bio(&conn->ssl, &conn->fd, mbedtls_net_send, mbedtls_net_recv, NULL);
64 conn->tls = 1;
65 return mbedtls_ssl_handshake(&conn->ssl);
68 struct conn *conn_connect(char *addr, char *port, char *certfile)
70 struct addrinfo hints, *addrinfo;
71 struct conn *conn;
72 int fd;
74 memset(&hints, 0, sizeof(hints));
75 hints.ai_family = AF_UNSPEC;
76 hints.ai_socktype = SOCK_STREAM;
77 hints.ai_flags = AI_PASSIVE;
79 if (getaddrinfo(addr, port, &hints, &addrinfo))
80 return NULL;
81 fd = socket(addrinfo->ai_family, addrinfo->ai_socktype,
82 addrinfo->ai_protocol);
84 if (connect(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == -1) {
85 close(fd);
86 freeaddrinfo(addrinfo);
87 return NULL;
89 freeaddrinfo(addrinfo);
91 conn = malloc(sizeof(*conn));
92 memset(conn, 0, sizeof(*conn));
93 conn->fd = fd;
94 return conn;
97 int conn_close(struct conn *conn)
99 if (conn->tls) {
100 mbedtls_ssl_close_notify(&conn->ssl);
101 mbedtls_x509_crt_free(&conn->cert);
102 mbedtls_ssl_free(&conn->ssl);
103 mbedtls_ssl_config_free(&conn->conf);
104 mbedtls_ctr_drbg_free(&conn->ctr_drbg);
106 close(conn->fd);
107 free(conn);
108 return 0;