aboutsummaryrefslogtreecommitdiff
path: root/src/molerat/connect.c
diff options
context:
space:
mode:
authorShav Kinderlehrer <[email protected]>2024-07-23 17:48:28 -0400
committerShav Kinderlehrer <[email protected]>2024-07-23 17:48:28 -0400
commitdc0f2ce9ba97ebb47e05b80a511da6eb29818b63 (patch)
treedc83035069f5a015047be1ca3da6f65781eb4695 /src/molerat/connect.c
parentf638f4bd1e3a03bc2bdd5f9dcd57d4830fd3c553 (diff)
downloadmolehole-ncurses.tar.gz
molehole-ncurses.zip
Merge old-moleholencurses
Diffstat (limited to 'src/molerat/connect.c')
-rwxr-xr-xsrc/molerat/connect.c133
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;
+}