diff options
author | Shav Kinderlehrer <[email protected]> | 2024-07-23 17:48:28 -0400 |
---|---|---|
committer | Shav Kinderlehrer <[email protected]> | 2024-07-23 17:48:28 -0400 |
commit | dc0f2ce9ba97ebb47e05b80a511da6eb29818b63 (patch) | |
tree | dc83035069f5a015047be1ca3da6f65781eb4695 /src/molerat/connect.c | |
parent | f638f4bd1e3a03bc2bdd5f9dcd57d4830fd3c553 (diff) | |
download | molehole-ncurses.tar.gz molehole-ncurses.zip |
Merge old-moleholencurses
Diffstat (limited to 'src/molerat/connect.c')
-rwxr-xr-x | src/molerat/connect.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/molerat/connect.c b/src/molerat/connect.c new file mode 100755 index 0000000..96c904b --- /dev/null +++ b/src/molerat/connect.c @@ -0,0 +1,133 @@ +#include <errno.h> +#include <netdb.h> +#include <openssl/ssl.h> +#include <stdbool.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + +#include "connect.h" +#include "status.h" +#include "url.h" + +int connect_socket(struct config *conf, struct url url) { + struct addrinfo hints; + struct addrinfo *servinfo; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + char port[5]; + sprintf(port, "%d", url.port); + int rc = getaddrinfo(url.host, port, &hints, &servinfo); + if (rc != 0) { + error_status(conf, (char *)gai_strerror(rc)); + return ERR_GETADDRINFO; + } + + struct addrinfo *p; + int sockfd; + for (p = servinfo; p != NULL; p = p->ai_next) { + sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (sockfd == -1) { + continue; + } + + rc = connect(sockfd, p->ai_addr, p->ai_addrlen); + if (rc == -1) { + close(sockfd); + continue; + } + + break; + } + + if (p == NULL) { + error_status(conf, strerror(errno)); + return ERR_CONNECT; + } + update_status(conf, "Connected to socket"); + freeaddrinfo(servinfo); + + return sockfd; +} + +int tls_connect(struct config *conf, struct url url) { + char status_msg[strlen(url.host) + 128]; + sprintf(status_msg, "Connecting to %s...", url.host); + update_status(conf, status_msg); + + struct connection *conn = init_connection(); + conf->s.conn = conn; + + int sock; + int rc = connect_socket(conf, url); + if (rc < 0) { + return rc; + } else { + sock = rc; + } + + const SSL_METHOD *method; + method = TLS_method(); + + SSL_CTX *ctx; + ctx = SSL_CTX_new(method); + if (ctx == NULL) { + error_status(conf, "Failed to init SSL"); + return ERR_SSL_CTX; + } + + SSL *ssl; + ssl = SSL_new(ctx); + if (ssl == NULL) { + error_status(conf, "Failed to init SSL"); + return ERR_SSL_SSL; + } + + rc = SSL_set_fd(ssl, sock); + if (rc == 0) { + error_status(conf, "Failed to wrap socket"); + return ERR_SSL_SSL; + } + + rc = SSL_connect(ssl); + if (rc <= 0) { + error_status(conf, "Failed to connect SSL"); + return ERR_SSL_SSL; + } + + conn->ssl = ssl; + conn->sockfd = sock; + conn->used = true; + conf->s.conn = conn; + + update_status(conf, "Connected"); + + return 0; +} + +void tls_cleanup(struct connection *conn) { + if (conn->sockfd) { + shutdown(conn->sockfd, SHUT_RDWR); + close(conn->sockfd); + } + + if (conn->ssl) { + SSL_shutdown(conn->ssl); + SSL_CTX_free(SSL_get_SSL_CTX(conn->ssl)); + SSL_free(conn->ssl); + } + + free(conn); +} + +struct connection *init_connection(void) { + struct connection *conn = malloc(sizeof(struct connection)); + memset(conn, 0, sizeof(struct connection)); + + return conn; +} |