gods

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

parser.c (4068B)


      1 #include <sys/param.h>
      2 
      3 #include <ctype.h>
      4 #include <errno.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <time.h>
      9 #include <unistd.h>
     10 
     11 #include "ip.h"
     12 #include "util.h"
     13 
     14 #define BUFSZ 256
     15 #define MAXTOKENLEN 256
     16 
     17 extern int ignore;
     18 
     19 char ip[16];
     20 char statmsg[BUFSZ];
     21 char preauth[BUFSZ];
     22 static char token[MAXTOKENLEN];
     23 static char *lp, *tp;
     24 time_t attack;
     25 
     26 char *month[] = {
     27 	"JAN",
     28 	"FEB",
     29 	"MAR",
     30 	"APR",
     31 	"MAY",
     32 	"JUN",
     33 	"JUL",
     34 	"AUG",
     35 	"SEP",
     36 	"OCT",
     37 	"NOV",
     38 	"DEC",
     39 };
     40 
     41 static int
     42 accept(int c)
     43 {
     44 	if (*tp == c) {
     45 		++tp;
     46 		return 1;
     47 	}
     48 	return 0;
     49 }
     50 
     51 static int
     52 mon(struct tm *tm)
     53 {
     54 	int n, i;
     55 	char str[4];
     56 
     57 	if ((n = strlen(tp)) != 3)
     58 		return 0;
     59 
     60 	for (i = 0; i < n; ++i)
     61 		str[i] = toupper(*tp++);
     62 	str[i] = '\0';
     63 
     64 	for (int i = 0; i < 12; ++i)
     65 		if (!strcmp(month[i], str)) {
     66 			tm->tm_mon = i;
     67 			return 1;
     68 		}
     69 
     70 	return 0;
     71 }
     72 
     73 static int
     74 day(struct tm *tm)
     75 {
     76 	int n, d, i;
     77 
     78 	char str[3];
     79 
     80 	if ((n = strlen(tp)) > 2 && n == 0)
     81 		return 0;
     82 
     83 	for (i = 0; i < n; ++i)
     84 		str[i] = *tp++;
     85 	str[i] = '\0';
     86 
     87 	if ((d = range(str, 1, 31)) == -1)
     88 		return 0;
     89 
     90 	tm->tm_mday = d;
     91 
     92 	return 1;
     93 }
     94 
     95 static int
     96 hms(struct tm *tm)
     97 {
     98 	int n, i, h, m, s;
     99 
    100 	char str[2];
    101 
    102 	if ((n = strlen(tp)) != 8)
    103 		return 0;
    104 
    105 	for (i = 0; i < 2; ++i)
    106 		str[i] = *tp++;
    107 	str[i] = '\0';
    108 
    109 	if ((h = range(str, 0, 23)) == -1)
    110 		return 0;
    111 	tm->tm_hour = h;
    112 
    113 	if (!accept(':'))
    114 		return 0;
    115 	for (i = 0; i < 2; ++i)
    116 		str[i] = *tp++;
    117 	str[i] = '\0';
    118 
    119 	if ((m = range(str, 0, 59)) == -1)
    120 		return 0;
    121 	tm->tm_min = m;
    122 
    123 	if (!accept(':'))
    124 		return 0;
    125 	for (i = 0; i < 2; ++i)
    126 		str[i] = *tp++;
    127 	str[i] = '\0';
    128 
    129 	if ((s = range(str, 0, 60)) == -1)
    130 		return 0;
    131 	tm->tm_sec = s;
    132 
    133 	return 1;
    134 }
    135 
    136 static int
    137 word()
    138 {
    139 	int n;
    140 
    141 	if (!strlen(lp))
    142 		return 0;
    143 
    144 	while(isspace(*lp))
    145 		++lp;
    146 
    147 	if (!(n = strcspn(lp, " ")))
    148 		return 0;
    149 
    150 	for (int i = 0; i < n; ++i)
    151 		token[i] = *lp++;
    152 	token[n] = '\0';
    153 	tp = token;
    154 
    155 	return 1;
    156 }
    157 
    158 static int
    159 undoword()
    160 {
    161 	lp -= strlen(token);
    162 
    163 	return 1;
    164 }
    165 
    166 static int
    167 timestamp(time_t now)
    168 {
    169 	struct tm tm;
    170 
    171 	if (!word() || !mon(&tm))
    172 		return 0;
    173 
    174 	if (!word() || !day(&tm))
    175 		return 0;
    176 
    177 	if (!word() || !hms(&tm))
    178 		return 0;
    179 
    180 	tm.tm_year = 121;	/* XXX Call time and setup year? */
    181 	attack = mktime(&tm);
    182 	ignore = (attack < now);
    183 
    184 	return 1;
    185 }
    186 
    187 static int
    188 hostname()
    189 {
    190 	char str[MAXHOSTNAMELEN];
    191 	char *sp;
    192 
    193 	if (gethostname(str, MAXHOSTNAMELEN) == -1)
    194 		return 0;
    195 
    196 	if (!word())
    197 		return 0;
    198 
    199 	/* truncate str to hostname from FQDN */
    200 	sp = strchr(str, '.');
    201 	if (sp)
    202 		*sp = '\0';
    203 	if (strcmp(token, str))
    204 		return 0;
    205 
    206 	return 1;
    207 }
    208 
    209 static int
    210 procid()
    211 {
    212 	char str[32], *k;
    213 	int n;
    214 
    215 	if (!word())
    216 		return 0;
    217 
    218 	if (!(k = strchr(token, '[')))
    219 		return 0;
    220 
    221 	n = strspn(k+1, "0123456789");
    222 	if (n > 32)
    223 		return 0;
    224 
    225 	memcpy(str, k+1, n);
    226 	str[n] = '\0';
    227 
    228 	return 1;
    229 }
    230 
    231 static int
    232 constat()
    233 {
    234 	char *sp = statmsg;
    235 
    236 	while (word()) {
    237 		if (*tp) {
    238 			if (isdigit(*tp) && isip(tp)) {
    239 				undoword();
    240 				break;
    241 			}
    242 			for ( ; *tp; )
    243 				*sp++ = *tp++;
    244 		}
    245 		*sp++ = ' ';
    246 	}
    247 	*sp = '\0';
    248 
    249 	if (sp == statmsg)
    250 		return 0;
    251 
    252 	return 1;
    253 }
    254 
    255 static int
    256 ipaddr()
    257 {
    258 	if (!word())
    259 		return 0;
    260 
    261 	if (isip(token))
    262 		strcpy(ip, token);
    263 
    264 	return 1;
    265 }
    266 
    267 static int
    268 portnum()
    269 {
    270 	int p;
    271 
    272 	if (!word())
    273 		return 0;
    274 	if (strcmp(token, "port"))
    275 		return 0;
    276 	if (!word())
    277 		return 0;
    278 	if ((p = range(token, 1, 65535)) == -1)
    279 		return 0;
    280 
    281 	return 1;
    282 }
    283 
    284 static int
    285 misc()
    286 {
    287 	if (word())
    288 		strcpy(preauth, tp);
    289 
    290 	return 1;
    291 }
    292 
    293 int
    294 parse(char *line, time_t now)
    295 {
    296 	lp = line;
    297 	tp = token;
    298 
    299 	fprintf(stderr, "parse: line: %s\n", lp);
    300 	if (!timestamp(now)) {
    301 		fprintf(stderr, "timestamp not found\n");
    302 		return -1;
    303 	}
    304 	if (!hostname()) {
    305 		fprintf(stderr, "hostname not found\n");
    306 		return -1;
    307 	}
    308 	if (!procid()) {
    309 		fprintf(stderr, "procid not found\n");
    310 		return -1;
    311 	}
    312 	if (!constat()) {
    313 		fprintf(stderr, "constat not found\n");
    314 		return -1;
    315 	}
    316 	if (!ipaddr()) {
    317 		fprintf(stderr, "ipaddr not found\n");
    318 		return -1;
    319 	}
    320 	if (!portnum()) {
    321 		fprintf(stderr, "portnum not found\n");
    322 		return -1;
    323 	}
    324 	if (!misc()) {
    325 		fprintf(stderr, "misc not found\n");
    326 		return -1;
    327 	}
    328 
    329 	return 1;
    330 }