gods

a simple blocklist for ssh
Log | Files | Refs | README | LICENSE

commit 2b2a60bd562c173f972f78761f4200750bb0401e
Author: Naveen Narayanan <zerous@nocebo.space>
Date:   Sat, 18 Sep 2021 14:27:39 +0200

Initial commit

Diffstat:
AMakefile | 32++++++++++++++++++++++++++++++++
AREADME | 8++++++++
Aconfig.mk | 4++++
Amain.c | 41+++++++++++++++++++++++++++++++++++++++++
Aparam.h | 15+++++++++++++++
Aparser.c | 257+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 357 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,32 @@ +include config.mk + +OBJ = \ + main.o \ + parser.o \ + +BIN = sdog + +all: $(BIN) + +clean: + rm -f $(BIN) $(OBJ) + +install: all + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1 + +uninstall: + cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) + cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) + +.PHONY: all clean install uninstall + +.SUFFIXES: .c .o + +.c.o: + $(CC) $(CFLAGS) -c $< + +sdog: $(OBJ) + $(CC) -o $@ $(OBJ) diff --git a/README b/README @@ -0,0 +1,8 @@ +gods +--- + +A simple watch dog for ssh. + +Why gods? +--- +It is just an anagram for sdog. diff --git a/config.mk b/config.mk @@ -0,0 +1,4 @@ +VERSION = 0.0 +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/man +CFLAGS = -g -Werror -Wall diff --git a/main.c b/main.c @@ -0,0 +1,41 @@ +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include "param.h" + +#define BUFSZ 512 + +char buf[BUFSZ]; + +int +main(int argc, char **argv) +{ + FILE *fp; + char *line; + int c; + + fp = fopen("./authlog", "r"); + if (!fp) + fprintf(stderr, "fopen failed: %s\n", strerror(errno)); + + for (;;) { + line = buf; + while ((c = fgetc(fp)) != EOF) { + if (c == '\n') { + *line = '\0'; + break; + } + *line++ = c; + } + + printf("line: %s\n", buf); + + if (parse(buf)) + fprintf(stderr, "parse failed\n"); + if (c == EOF) + break; + } + + return 0; +} diff --git a/param.h b/param.h @@ -0,0 +1,15 @@ +#ifndef _PARAM_H +#define _PARAM_H + +struct user { + char *ipaddr; + int isattack; + int isblocked; + char nprobe; +}; + +struct user *users; + +int parse(char *); + +#endif diff --git a/parser.c b/parser.c @@ -0,0 +1,257 @@ +#include <sys/param.h> + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "param.h" + +#define MAXTOKENLEN 256 + +static char token[MAXTOKENLEN]; +static char ip[16]; +static char *tp; +static char *lp; +time_t probtim; + +char *month[] = { + "JAN", + "FEB", + "MAR", + "APR", + "MAY", + "JUN", + "JUL", + "AUG", + "SEP", + "OCT", + "NOV", + "DEC", +}; + +static int +accept(int c) +{ + if (*tp == c) { + ++tp; + return 1; + } + return 0; +} + +static int +range(char *s, int min, int max) +{ + int t; + + errno = 0; + printf("range str: %s\n", s); + t = atoi(s); + printf("range t: %d\n", t); + if (errno) + return -1; + if (t < min || t > max) + return -1; + + return t; +} + +static int +mon(struct tm *tm) +{ + int n, i; + + char str[4]; + + if ((n = strlen(tp)) != 3) + return 0; + + for (i = 0; i < n; ++i) + str[i] = toupper(*tp++); + str[i] = '\0'; + printf("month: %s\n", str); + for (int i = 0; i < 12; ++i) + if (!strcmp(month[i], str)) { + printf("mon found\n"); + tm->tm_mon = i; + return 1; + } + + return 0; +} + +static int +day(struct tm *tm) +{ + int n, d, i; + + char str[3]; + + if ((n = strlen(tp)) > 2 && n == 0) + return 0; + + for (int i = 0; i < n; ++i) + str[i] = *tp++; + str[i] = '\0'; + printf("day str: %s\n", str); + if ((d = range(str, 1, 31)) == -1) + return 0; + printf("day: %d\n", d); + tm->tm_mday = d; + + return 1; +} + +static int +hms(struct tm *tm) +{ + int n, i, h, m, s; + + char str[2]; + + printf("tp: %s\n", tp); + if ((n = strlen(tp)) != 8) + return 0; + printf("strlen == 8\n"); + for (i = 0; i < 2; ++i) { + printf("%c:", *tp); + str[i] = *tp++; + printf("%c ", str[i]); + } + str[i] = '\0'; + printf("\nh: %s\n", str); + if ((h = range(str, 0, 23)) == -1) + return 0; + tm->tm_hour = h; + + if (!accept(':')) + return 0; + for (i = 0; i < 2; ++i) { + printf("%c:", *tp); + str[i] = *tp++; + printf("%c ", str[i]); + } + str[i] = '\0'; + printf("\nm: %s\n", str); + if ((m = range(str, 0, 59)) == -1) + return 0; + tm->tm_min = m; + + if (!accept(':')) + return 0; + for (i = 0; i < 2; ++i) + str[i] = *tp++; + str[i] = '\0'; + + if ((s = range(str, 0, 60)) == -1) + return 0; + tm->tm_sec = s; + + return 1; +} + +static int +word() +{ + int n; + + while(isspace(*lp)) + ++lp; + + if (!(n = strcspn(lp, " "))) + return 0; + + for (int i = 0; i < n; ++i) + token[i] = *lp++; + token[n] = '\0'; + tp = token; + + printf("word: %s \n", token); + return 1; +} + +static int +timestamp() +{ + struct tm tm; + int n; + + printf("timestamp\n"); + if (!word() || !mon(&tm)) + return 0; + printf("mon ok\n"); + if (!word() || !day(&tm)) + return 0; + printf("day ok\n"); + if (!word() || !hms(&tm)) + return 0; + printf("hms ok\n"); + printf("timestamp: %d %d %d:%d:%d\n", tm.tm_mon, tm.tm_mday, tm.tm_hour, + tm.tm_min, tm.tm_sec); + + return 1; +} + +static int +hostname() +{ + return 0; +} + +static int +procid() +{ + return 1; +} + +static int +constat() +{ + return 1; +} + +static int +ipaddr() +{ + return 1; +} + +static int +portnum() +{ + return 1; +} + +static int +misc() +{ + return 1; +} + +int +parse(char *line) +{ + lp = line; + tp = token; + printf("parse: line: %s\n", lp); + if (!timestamp()) + return 0; + if (!hostname()) + return 0; + if (!procid()) + return 0; + if (!constat()) + return 0; + if (!ipaddr()) + return 0; + if (!portnum()) + return 0; + if (!misc()) + return 0; + + return 1; +}