pop3: include a carriage return after commands
[pop3.git] / conn.c
bloba6f4402f8310d785c3fd3731daeea83ff550a87b
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 <polarssl/ssl.h>
14 #include <polarssl/entropy.h>
15 #include <polarssl/ctr_drbg.h>
17 struct conn {
18 int fd;
19 ssl_context ssl;
20 ssl_session ssn;
21 ctr_drbg_context ctr_drbg;
22 x509_cert cert;
25 static int ps_send(void *ctx, const unsigned char *buf, size_t len)
27 return write(*(int *) ctx, buf, len);
30 static int ps_recv(void *ctx, unsigned char *buf, size_t len)
32 return read(*(int *) ctx, buf, len);
35 int conn_read(struct conn *conn, char *buf, int len)
37 return ssl_read(&conn->ssl, (unsigned char *) buf, sizeof(buf));
40 int conn_write(struct conn *conn, char *buf, int len)
42 return ssl_write(&conn->ssl, (unsigned char *) buf, len);
45 static int conns_init(struct conn *conn, char *certfile)
47 entropy_context entropy;
48 entropy_init(&entropy);
49 ctr_drbg_init(&conn->ctr_drbg, entropy_func, &entropy, NULL, 0);
50 if (ssl_init(&conn->ssl))
51 return 1;
52 ssl_set_endpoint(&conn->ssl, SSL_IS_CLIENT);
53 if (certfile) {
54 x509parse_crtfile(&conn->cert, certfile);
55 ssl_set_ca_chain(&conn->ssl, &conn->cert, NULL, NULL);
56 ssl_set_authmode(&conn->ssl, SSL_VERIFY_REQUIRED);
57 } else{
58 ssl_set_authmode(&conn->ssl, SSL_VERIFY_NONE);
60 ssl_set_rng(&conn->ssl, ctr_drbg_random, &conn->ctr_drbg);
61 ssl_set_bio(&conn->ssl, ps_recv, &conn->fd, ps_send, &conn->fd);
62 ssl_set_ciphersuites(&conn->ssl, ssl_default_ciphersuites);
63 ssl_set_session(&conn->ssl, 1, 600, &conn->ssn);
64 return ssl_handshake(&conn->ssl);
67 struct conn *conn_connect(char *addr, char *port, char *certfile)
69 struct addrinfo hints, *addrinfo;
70 struct conn *conn;
71 int fd;
73 memset(&hints, 0, sizeof(hints));
74 hints.ai_family = AF_UNSPEC;
75 hints.ai_socktype = SOCK_STREAM;
76 hints.ai_flags = AI_PASSIVE;
78 if (getaddrinfo(addr, port, &hints, &addrinfo))
79 return NULL;
80 fd = socket(addrinfo->ai_family, addrinfo->ai_socktype,
81 addrinfo->ai_protocol);
83 if (connect(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == -1) {
84 close(fd);
85 freeaddrinfo(addrinfo);
86 return NULL;
88 freeaddrinfo(addrinfo);
90 conn = malloc(sizeof(*conn));
91 memset(conn, 0, sizeof(conn));
92 conn->fd = fd;
93 if (conns_init(conn, certfile)) {
94 free(conn);
95 return NULL;
97 return conn;
100 int conn_close(struct conn *conn)
102 ssl_close_notify(&conn->ssl);
103 x509_free(&conn->cert);
104 ssl_free(&conn->ssl);
106 close(conn->fd);
107 free(conn);
108 return 0;