commit a5ffe13b1502e01adb7da16b879eb99e3c55d49d
parent d6b9c4355d3a6e4cd4d1e0f58ad3b26d10144728
Author: parazyd <parazyd@dyne.org>
Date: Thu, 1 Mar 2018 00:47:39 +0100
Add net functionality.
Currently supports fetching a TLS certificate fingerprint.
Diffstat:
5 files changed, 195 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
@@ -5,7 +5,7 @@
include config.mk
BIN = $(NAME)
-OBJ = $(BIN:=.o) headers.o ind.o sieve.o
+OBJ = $(BIN:=.o) headers.o ind.o sieve.o net.o
all: $(BIN)
cp -f $(NAME) bin
diff --git a/config.mk b/config.mk
@@ -5,8 +5,10 @@ PREFIX = /usr/local
SHAREPREFIX = $(PREFIX)/share/$(NAME)
MANPREFIX = $(PREFIX)/share/man
-CFLAGS = -O2 -Wall -pedantic
-LDFLAGS = -static -s
+CFLAGS = -O2 -Wall -pedantic -std=gnu99
+LDFLAGS = -static -s -lssl -lcrypto
.c.o:
$(CC) $(CFLAGS) -c $<
+
+CC = cc
diff --git a/net.c b/net.c
@@ -0,0 +1,164 @@
+/*
+ * Copy me if you can
+ * by 20h and parazyd
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+
+#include "arg.h"
+#include "ind.h"
+#include "net.h"
+
+char *argv0;
+
+/*
+ * net format:
+ * net!addr!service
+ */
+enum {
+ NET_NET = 0x00,
+ NET_TCP,
+ NET_TCPS
+};
+
+static char *netnames[] = {
+ [NET_NET] = "net",
+ [NET_TCP] = "tcp",
+ [NET_TCPS] = "tcps"
+};
+
+void netusage(void) {
+ die("usage: %s [-f host port]\n"
+ " -f: fetch and print ssl certificate fingerprint\n", argv0);
+}
+
+int net_gettype(char *str) {
+ int i;
+
+ for (i = 0; i < nelem(netnames); i++)
+ if (!strcmp(netnames[i], str))
+ return i;
+ return -1;
+}
+
+net_t *net_new(char *type, char *addr, char *port) {
+ net_t *ret;
+
+ ret = malloc(sizeof(net_t));
+
+ ret->type = net_gettype(type);
+ ret->addr = addr;
+ ret->service = port;
+
+ return ret;
+}
+
+int sslfpr(net_t *net) {
+ int i;
+ unsigned int fpr_size;
+ SSL *sfd;
+ X509 *cert;
+
+ const EVP_MD *fpr_type;
+ unsigned char fpr[EVP_MAX_MD_SIZE];
+
+ struct addrinfo hints, *ai, *rp;
+
+ bzero(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+
+ if (getaddrinfo(net->addr, net->service, &hints, &ai))
+ return 1;
+ if (ai == NULL)
+ return 1;
+
+ SSL_library_init();
+ OpenSSL_add_all_algorithms();
+
+ net->data[1] = SSL_CTX_new(SSLv23_client_method());
+ if (net->data[1] == NULL)
+ goto sslfprerr;
+ SSL_CTX_set_options((SSL_CTX *)net->data[1],
+ SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
+
+ for (rp = ai; rp != NULL; rp = rp->ai_next) {
+ net->fd = socket(rp->ai_family, rp->ai_socktype,
+ rp->ai_protocol);
+ if (connect(net->fd, rp->ai_addr, rp->ai_addrlen))
+ break;
+
+ if ((sfd = SSL_new((SSL_CTX *)net->data[1])) == NULL)
+ goto sslfprerr;
+ SSL_set_fd(sfd, net->fd);
+ if (SSL_connect(sfd) < 1)
+ goto sslfprerr;
+
+
+ cert = SSL_get_peer_certificate(sfd);
+ if (cert == NULL)
+ goto sslfprerr;
+
+ fpr_type = EVP_sha1();
+ if (!X509_digest(cert, fpr_type, fpr, &fpr_size))
+ goto sslfprerr;
+
+ for (i = 0; i < fpr_size; i++)
+ printf("%02X%c", fpr[i], (i+1 == fpr_size) ? '\n':':');
+
+ X509_free(cert);
+ SSL_CTX_free(net->data[1]);
+ SSL_free(sfd);
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+ close(net->fd);
+ }
+
+ return 0;
+
+sslfprerr:
+ SSL_load_error_strings();
+ ERR_print_errors_fp(stderr);
+ ERR_free_strings();
+ return 1;
+}
+
+int netmain(int argc, char *argv[]) {
+
+ int fflag;
+
+ ARGBEGIN {
+ case 'f':
+ fflag = 1;
+ argc++; argv--;
+ break;
+ default:
+ netusage();
+ } ARGEND;
+
+ if (fflag) {
+ if (argc < 2)
+ netusage();
+
+ net_t *net;
+
+ net = net_new("tcps", argv[1], argv[2]);
+ if (sslfpr(net))
+ return 1;
+
+ return 0;
+ }
+
+ netusage();
+
+ return 0;
+}
diff --git a/net.h b/net.h
@@ -0,0 +1,24 @@
+/*
+ * Copy me if you can
+ * by parazyd
+ */
+
+#ifndef __RPNET_H__
+#define __RPNET_H__
+
+typedef struct net_t net_t;
+struct net_t {
+ int fd;
+
+ char *net;
+ char *addr;
+ char *service;
+ char *options;
+ int type;
+
+ void *data[2];
+};
+
+int netmain(int argc, char *argv[]);
+
+#endif
diff --git a/rohrpost.c b/rohrpost.c
@@ -10,6 +10,7 @@
#include "arg.h"
#include "headers.h"
#include "ind.h"
+#include "net.h"
#include "sieve.h"
char *argv0;
@@ -33,6 +34,7 @@ enum {
struct command cmds[] = {
{"rpheaders", DOINSTALL, headersmain},
{"rpsieve", DONTINSTALL, sievemain},
+ {"rpnet", DOINSTALL, netmain},
};
int main(int argc, char *argv[]) {