Improvied access control semantics. Allows for a finger control for
allowing and denying hosts.
This commit is contained in:
parent
322a53eb56
commit
de6f42d9fa
214
src/acl.c
Normal file
214
src/acl.c
Normal file
@ -0,0 +1,214 @@
|
||||
/* $Id: acl.c,v 1.1 2000-09-12 00:08:48 rjkaes Exp $
|
||||
*
|
||||
* This system handles Access Control for use of this daemon. A list of
|
||||
* domains, or IP addresses (including IP blocks) are stored in a list
|
||||
* which is then used to compare incoming connections.
|
||||
*
|
||||
* Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "tinyproxy.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "acl.h"
|
||||
#include "log.h"
|
||||
#include "sock.h"
|
||||
|
||||
struct acl_s {
|
||||
acl_access_t access;
|
||||
enum { ACL_STRING, ACL_NUMERIC } type;
|
||||
char *location;
|
||||
int netmask;
|
||||
struct acl_s *next;
|
||||
};
|
||||
|
||||
static struct acl_s *access_list = NULL;
|
||||
|
||||
/*
|
||||
* Take a netmask number (between 0 and 32) and returns a network ordered
|
||||
* value for comparison. Somebody please clean this up. :)
|
||||
*/
|
||||
static in_addr_t make_netmask(int netmask_num)
|
||||
{
|
||||
in_addr_t netmasks[] = {
|
||||
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
|
||||
0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
|
||||
0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
|
||||
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
|
||||
0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
|
||||
0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
|
||||
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
|
||||
0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe,
|
||||
0xffffffff
|
||||
};
|
||||
|
||||
return htonl(netmasks[netmask_num]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts a new access control into the list. The function will figure out
|
||||
* whether the location is an IP address (with optional netmask) or a
|
||||
* domain name.
|
||||
*
|
||||
* Returns:
|
||||
* -1 on failure
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int insert_acl(char *location, acl_access_t access_type)
|
||||
{
|
||||
unsigned int i;
|
||||
struct acl_s **rev_acl_ptr, *acl_ptr, *new_acl_ptr;
|
||||
char *nptr;
|
||||
|
||||
/*
|
||||
* First check to see if the location is a string or numeric.
|
||||
*/
|
||||
for (i = 0; i < strlen(location); i++) {
|
||||
if (isdigit(location[i]) != 0 && location[i] != '.') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a new ACL to the list.
|
||||
*/
|
||||
rev_acl_ptr = &access_list;
|
||||
acl_ptr = access_list;
|
||||
while (acl_ptr) {
|
||||
rev_acl_ptr = &acl_ptr->next;
|
||||
acl_ptr = acl_ptr->next;
|
||||
}
|
||||
new_acl_ptr = malloc(sizeof(struct acl_s));
|
||||
if (!new_acl_ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
new_acl_ptr->access = access_type;
|
||||
|
||||
if (i != strlen(location)) {
|
||||
/* We did break early, so this a numeric location.
|
||||
* Check for a netmask.
|
||||
*/
|
||||
new_acl_ptr->type = ACL_NUMERIC;
|
||||
nptr = strchr(location, '/');
|
||||
if (nptr) {
|
||||
*nptr++ = '\0';
|
||||
|
||||
new_acl_ptr->netmask = atoi(nptr);
|
||||
if (new_acl_ptr->netmask < 0 || new_acl_ptr->netmask > 32) {
|
||||
free(new_acl_ptr);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
new_acl_ptr->netmask = 32;
|
||||
}
|
||||
} else {
|
||||
new_acl_ptr->type = ACL_STRING;
|
||||
new_acl_ptr->netmask = 32;
|
||||
}
|
||||
|
||||
new_acl_ptr->location = strdup(location);
|
||||
if (!new_acl_ptr->location) {
|
||||
free(new_acl_ptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*rev_acl_ptr = new_acl_ptr;
|
||||
new_acl_ptr->next = acl_ptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks where file descriptor is allowed.
|
||||
*
|
||||
* Returns:
|
||||
* 1 if allowed
|
||||
* 0 if denied
|
||||
* -1 if error
|
||||
*/
|
||||
int check_acl(int fd)
|
||||
{
|
||||
struct acl_s *aclptr;
|
||||
char ip_address[PEER_IP_LENGTH];
|
||||
char string_address[PEER_STRING_LENGTH];
|
||||
|
||||
/*
|
||||
* If there is no access list allow everything.
|
||||
*/
|
||||
aclptr = access_list;
|
||||
if (!aclptr)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Get the IP address and the string domain.
|
||||
*/
|
||||
getpeer_ip(fd, ip_address);
|
||||
getpeer_string(fd, string_address);
|
||||
|
||||
while (aclptr) {
|
||||
if (aclptr->type == ACL_STRING) {
|
||||
int test_length = strlen(string_address);
|
||||
int match_length = strlen(aclptr->location);
|
||||
|
||||
if (test_length < match_length) {
|
||||
aclptr = aclptr->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(string_address + (test_length - match_length), aclptr->location) == 0) {
|
||||
if (aclptr->access == ACL_DENY) {
|
||||
log(LOG_NOTICE, "Unauthorized access from %s", string_address);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct in_addr test_addr, match_addr;
|
||||
in_addr_t netmask_addr;
|
||||
|
||||
if (ip_address[0] == 0) {
|
||||
aclptr = aclptr->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
inet_aton(ip_address, &test_addr);
|
||||
inet_aton(aclptr->location, &match_addr);
|
||||
|
||||
netmask_addr = make_netmask(aclptr->netmask);
|
||||
|
||||
if ((test_addr.s_addr & netmask_addr) == (match_addr.s_addr & netmask_addr)) {
|
||||
if (aclptr->access == ACL_DENY) {
|
||||
log(LOG_NOTICE, "Unauthorized access from %s", ip_address);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Dropped through... go on to the next one.
|
||||
*/
|
||||
aclptr = aclptr->next;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deny all connections by default.
|
||||
*/
|
||||
log(LOG_NOTICE, "Unauthorized connection from %s [%s]", string_address, ip_address);
|
||||
return 0;
|
||||
}
|
26
src/acl.h
Normal file
26
src/acl.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* $Id: acl.h,v 1.1 2000-09-12 00:08:48 rjkaes Exp $
|
||||
*
|
||||
* See 'acl.c' for detailed information.
|
||||
*
|
||||
* Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _TINYPROXY_ACL_H_
|
||||
#define _TINYPROXY_ACL_H_
|
||||
|
||||
typedef enum { ACL_ALLOW, ACL_DENY } acl_access_t;
|
||||
|
||||
extern int insert_acl(char *location, acl_access_t access_type);
|
||||
extern int check_acl(int fd);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user