Building.Open.Source.Network.Security.Tools.Components.And.Techniques [Electronic resources] نسخه متنی

This is a Digital Library

With over 100,000 free electronic resource in Persian, Arabic and English

Building.Open.Source.Network.Security.Tools.Components.And.Techniques [Electronic resources] - نسخه متنی

Mike D. Schiffman

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Sample Code–Clutch

The following two source files comprise the Clutch codebase. To preserve readability, we richly comment the code—but no book-text appears inside the code. You can download the full source files from this book's companion Web site at http://www.wiley.com/compbooks/schiffman.


clutch.h



/*
* $Id: clutch.h,v 1.3 2002/05/05 19:30:20 route Exp $
*
* Building Open Source Network Security Tools
* clutch.h - libdnet example code
*
* Copyright (c) 2002 Mike D. Schiffman <mike@infonexus.com>
* All rights reserved.
*
*/
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dnet.h>
/* mode types */
#define ARP 0x1
#define ROUTE 0x2
/* control flags */
#define VERBOSE 0x1
#define ENFORCE 0x2
/* simple macros for code clean up */
#define STEPOVER_WS (b) while (!isgraph(*b)) { b++; } #define STEPOVER_NONWS(b) while (isgraph(*b)) { b++; } struct clutch_pack
{
u_char flags; /* control flags */
arp_t *a; /* arp cache handle */
route_t *r; /* route table handle */
struct clutch_arp_entry *cae;/* linked list of arp cache entries */
struct clutch_route_entry *cre;/* linked list of route table
entries */
};
struct clutch_arp_entry
{
struct addr mac; /* ethernet address */
struct addr ip; /* ip address */
struct clutch_arp_entry *next; /* next entry in list */
};
struct clutch_route_entry
{
struct addr ip; /* ip address */
struct addr gw; /* gateway */
struct clutch_route_entry *next;/* next entry in list */
};
int init_clutch(struct clutch_pack *, char *);
int parse_config(struct clutch_pack *, FILE *);
int new_list_entry(struct clutch_pack **, int, struct addr *,
struct addr *);
char *get_time();
void free_cp(struct clutch_pack *);
int check_arp_cache(const struct arp_entry *, void *);
int check_route_table(const struct route_entry *, void *);
void usage(char *);
/* EOF */


clutch.c



/*
* $Id: clutch.c,v 1.3 2002/05/05 19:30:20 route Exp $
*
* Building Open Source Network Security Tools
* clutch.c - libdnet example code
*
* Copyright (c) 2002 Mike D. Schiffman <mike@infonexus.com>
* All rights reserved.
*
*/
#include "./clutch.h"
int
main(int argc, char **argv)
{
int c, n, sleep_int;
char *filename;
struct clutch_pack cp;
printf("Clutch 1.0 [ARP cache / route table monitoring tool]\n");
printf("<ctrl-c> to quit\n");
sleep_int = 1;
filename = NULL;
while ((c = getopt(argc, argv, "c:ehs:v")) != EOF)
{
switch (c)
{
case 'c':
filename = optarg;
break;
case 'e':
cp.flags |= ENFORCE;
break;
case 'h':
usage(argv[0]);
exit(EXIT_FAILURE);
case 'v':
cp.flags |= VERBOSE;
break;
case 's':
sleep_int = atoi(optarg);
break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
if (filename == NULL)
{
usage(argv[0]);
exit(EXIT_FAILURE);
}
if (cp.flags & VERBOSE)
{
printf("Verbose mode is on.\n");
}
if (cp.flags & ENFORCE)
{
printf("Strict policy enforcement in effect.\n");
}
/*
* Initialize the program. Open all file handles and parse the
* configuration file.
*/
n = init_clutch(&cp, filename);
if (n == -1)
{
return (EXIT_FAILURE);
}
if (n == 0)
{
fprintf(stderr, "No rules to process!\n");
return (EXIT_FAILURE);
}
fprintf(stderr, "State database loaded (%d rule(s)).\n", n);
fprintf(stderr, "Program initialized, watching for
violations...\n");
for (; ; sleep(sleep_int))
{
/*
* Run through the ARP cache and routing table and check them
* against our rules to ensure no malcontents have tampered
* with them.
*
* One thing to notice about this program is that we don't
* explicitly free memory anywhere. This isn't considered a
* high priority however, since once we malloc memory for our
* state database, we need all of it until the program quits,
* in which case we rely on the operating system to reclaim
* our used resources. Besides, we're done at that point, so
* who cares!
*/
if (arp_loop(cp.a, check_arp_cache, &cp) == -1)
{
fprintf(stderr, "error checking ARP cache\n");
}
if (route_loop(cp.r, check_route_table, &cp) == -1)
{
fprintf(stderr, "error checking route table\n");
}
}
exit(EXIT_SUCCESS);
}
int
init_clutch(struct clutch_pack *cp, char *filename)
{
int n;
FILE *fp;
/* open the config file passed in the by user at the CLI */
fp = fopen(filename, "r+");
if (fp == NULL)
{
perror("init_clutch: fopen");
return (-1);
}
/* get an ARP cache handle */
cp->a = arp_open();
if (cp->a == NULL)
{
perror("init_clutch: arp_open");
goto bad;
}
/* get a route table handle */
cp->r = route_open();
if (cp->r == NULL)
{
perror("init_clutch: route_open");
goto bad;
}
/*
* Parse the configuration file and build the state table for
* Clutch.
*/
n = parse_config(cp, fp);
if (n == -1)
{
fprintf(stderr, "parse_config fatal error\n");
goto bad;
}
else
{
return (n);
}
bad:
arp_close(cp-> a);
route_close (cp-> r);
return (-1);
}
int
parse_config(struct clutch_pack *cp, FILE *fp)
{
int l, m;
char buf[BUFSIZ];
char *mac_p, *ip_p, *gw_p, *end_p;
struct addr ip;
struct addr gw;
struct addr mac;
/*
* Parse the config file with the following logic:
*
* - Ignore all lines beginning with "#" or a whitespace character
* - If a line starts with ARP, parse it as an ARP mapping:
* - Expect "x:x:x:x:x:x -> y.y.y.y"
* - Non-fatal continue error if there's a lexical problem
* - Otherwise store it in the ARP cache mapping list
* - If a line starts with INT, parse it as an interface entry:
* - Expect "device flags"
* - Non-fatal continue error if there's a lexical problem
* - Otherwise store it in the interface list
* - If a line starts with RTE, parse it as a route entry:
* - Expect "x.x.x.x -> y.y.y.y"
* - Non-fatal continue error if there's a lexical problem
* - Otherwise store it in the route table list
* - Everything else is a non-fatal error
*/
l = 0;
m = 0;
while (fgets(buf, sizeof (buf) - 1, fp))
{
/* count configuration file lines */
1++;
if (isspace(buf[0]) || buf[0] == '#')
{
/* blank link or comment */
continue;
}
if (strstr(buf, "ARP"))
{
mac_p = buf;
ip_p = strstr(buf, "-> ");
if (ip_p == NULL)
{
goto error;
}
/* step past "ARP" */
mac_p += 3;
/* step past "->" */
ip_p += 2;
/* remove whitespace */
STEPOVER_WS(mac_p);
end_p = mac_p;
/* get to the end of the MAC */
while (isgraph(*end_p) && !(*end_p == '-'))
{
end_p++;
}
*end_p = NULL;
if (addr_aton(mac_p, &mac) == -1)
{
goto error;
}
/* remove whitespace */
STEPOVER_WS(ip_p);
end_p = ip_p;
/* get to the end of IP */
STEPOVER_NONWS(end_p);
*end_p = NULL;
if (addr_aton(ip_p, &ip) == -1)
{
goto error;
}
/* scrape together some memory for the ARP entry here */
if (new_list_entry(&cp, ARP, &mac, &ip) == -1)
{
perror("malloc");
return (-1);
}
m++;
if ((cp->flags) & VERBOSE)
{
printf("added ARP mapping rule %s -> %s\n",
addr_ntoa(&mac),
addr_ntoa(&ip));
}
}
else if (strstr(buf, "RTE"))
{
ip_p = buf;
gw_p = strstr(buf, "->"); // find next part of the data
gw_p += 2;
ip_p += 3;
/* remove whitespace */
STEPOVER_WS(ip_p);
end_p = ip_p;
/* get to the end of IP */
while (isgraph(*end_p) && !(*end_p == '-'))
{
end_p++;
}
*end_p = NULL;
if (addr_aton(ip_p, &ip) == -1)
{
goto error;
}
/* remove whitespace */
STEPOVER_WS(gw_p);
end_p = gw_p;
STEPOVER_NONWS(end_p);
*end_p = NULL;
if (addr_aton(gw_p, &gw) == -1)
{
goto error;
}
/* scrape together some memory for the route entry here */
if (new_list_entry(&cp, ROUTE, &ip, &gw) == -1)
{
perror("malloc");
return (-1);
}
m++;
if ((cp-> flags) & VERBOSE)
{
printf("added route table rule %s -> %s\n",
addr_ntoa(&ip),
addr_ntoa(&gw));
}
}
else
{
error:
fprintf(stderr,
"unknown or malformed rule at line %03d\n", 1);
}
}
return (m);
}
int
new_list_entry(struct clutch_pack **cp, int type, struct addr *al,
struct addr *a2)
{
switch (type)
{
case ARP:
{
struct clutch_arp_entry *p;
if ((*cp)->cae == NULL)
{
/* create the head node on the list */
(*cp)-> cae = malloc(sizeof (struct clutch_arp_entry));
if ((*cp)-> cae == NULL)
{
return (-1);
}
memset((*cp)-> cae, 0, sizeof (struct clutch_arp_entry));
memcpy(&(*cp)-> cae->mac, al, sizeof (struct addr));
memcpy(&(*cp)->cae->ip, a2, sizeof (struct addr));
(*cp)-> cae-> next = NULL;
return (1);
}
else
{
/* walk to the end of the list */
for (p = (*cp)-> cae; p-> next; p = p-> next);
p->next = malloc(sizeof (struct clutch_arp_entry));
if (p-> next == NULL)
{
return (-1);
}
memset(p->next, 0, sizeof (struct clutch_arp_entry) );
p = p-> next;
memcpy(&p->mac, al, sizeof (struct addr));
memcpy(&p->ip, a2, sizeof (struct addr));
p->next = NULL;
return (1);
}
}
case ROUTE:
{
struct clutch_route_entry *p;
if ((*cp)-> cre == NULL)
{
/* create the head node on the list */
(*cp)-> cre = malloc(sizeof (struct clutch_route_entry));
if ((*cp)-> cre == NULL)
{
return (-1);
}
memset((*cp)-> cre, 0, sizeof (struct
clutch_route_entry));
memcpy(&(*cp)-> cre->ip, a1, sizeof (struct addr));
memcpy(&(*cp)-> cre->gw, a2, sizeof (struct addr));
(*cp)-> cre-> next = NULL;
return (1);
}
else
{
/* walk to the end of the list */
for (p = (*cp)->cre; p->next; p = p->next);
p->next = malloc(sizeof (struct clutch_route_entry));
if (p-> next == NULL)
{
return (-1);
}
memset(p->next, 0, sizeof (struct clutch_route_entry));
p = p-> next;
memcpy(&p->ip, al, sizeof (struct addr));
memcpy(&p->gw, a2, sizeof (struct addr));
p->next = NULL;
}
return (1);
}
default:
{
return (-1);
}
}
return (-1);
}
int
check_arp_cache(const struct arp_entry *ae, void *cp)
{
struct clutch_pack *p;
struct clutch_arp_entry *cae;
const struct addr *pa;
const struct addr *ha;
p = (struct clutch_pack *)cp;
pa = &ae->arp_pa;
ha = &ae->arp_ha;
/* run through the ARP cache rules */
for (cae = (struct clutch_arp_entry *)p->cae; cae; cae = cae->next)
{
/* look for a hardware address match in the ARP cache */
if (addr_cmp(ha, &cae->mac) == 0)
{
/* does it match our rule? */
if (addr_cmp(pa, &cae->ip) ! = 0)
{
printf("[%s ARP cache rule violation: %s -> %s] \n",
get_time(), addr_ntoa(ha), addr_ntoa(pa));
if ( (p->flags) & VERBOSE)
{
printf("[entry should be: %s -> %s]\n",
addr_ntoa(&cae->mac), addr_ntoa(&cae->ip));
}
if ((p-> flags) & ENFORCE)
{
/* reset the entry back to what it should be */
if (arp_delete(p-> a, ae) == -1)
{
fprintf(stderr, "[can't reset ARP entry]\n");
}
else
{
/* setup new ARP entry */
struct arp_entry new_ae;
memcpy (&new_ae.arp_pa, &cae->ip,
sizeof (struct addr));
memcpy (&new_ae.arp_ha, &cae->mac,
sizeof (struct addr));
printf("[bogus ARP cache entry deleted]\n");
if (arp_add(p->a, &new_ae) == -1)
{
fprintf(stderr, "[can't reset ARP entry]\n");
}
else
{
printf("[correct ARP cache entry restred]\n");
}
}
}
}
}
}
return (0);
}
int
check_route_table(const struct route_entry *re, void *cp)
{
struct clutch_pack *p;
struct clutch_route_entry *cre;
const struct addr *dst;
const struct addr *gw;
p = (struct clutch_pack *)cp;
dst = &re->route_dst;
gw = &re->route_gw;
/* run through the route table rules */
for (cre = (struct clutch_route_entry *)p->cre; cre; cre = cre->next)
{
/* look for a destination IP match in the route table */
if (addr_cmp(dst, &cre->ip) == 0)
{
/* does it match our rule? */
if (addr_cmp(gw, &cre->gw) ! = 0)
{
printf("[%s route table rule violation: %s ->%s]\n",
get_time(), addr_ntoa(dst), addr_ntoa(gw));
if ((p-> flags) & VERBOSE)
{
printf("[entry should be: %s -> %s]\n",
addr_ntoa(&cre->ip), addr_ntoa(&cre->gw));
}
if ((p->flags) & ENFORCE)
{
/* reset the entry back to what it should be */
if (route_delete(p->r, re) == -1)
{
fprintf(stderr, "[can't reset route entry]\n");
}
else
{
/* setup new route entry */
struct route_entry new_re;
memcpy (&new_re.route_dst, &cre->ip,
sizeof (struct addr));
memcpy (&new_re.route_gw, &cre->gw,
sizeof (struct addr));
printf ("[bogus route table entry deleted]\n");
if (route_add(p->r, &new_re) == -1)
{
fprintf(stderr, "[can't reset rte
entry]\n");
}
else
{
printf(
"[correct route table entry
restored]\n");
}
}
}
}
}
return ( 0 );
}
char *
get_time()
{
int i ;
time_t t;
static char buf[26];
t = time((time_t *)NULL);
strcpy(buf, ctime(&t));
/* cut out the day, year and \n */
for (i = 0; i < 20; i++)
{
buf[i]= buf[i + 4];
}
buf[15]= 0;
return (buf);
}
void
usage(char *name)
{
fprintf(stderr, "usage: %s [options] -c config_file:\n"
"-c filename\tconfiguration file\n"
"-e\t\tenforce rules rather than just warn\n"
"-h\t\tthis jonk here\n"
"-s\t\tsleep interval in seconds\n"
"-v\t\tbe more verbose\n", name);
}
/* EOF */

/ 135