Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ in.ipscrompd: $(FW_OBJS) in.ipscrompd.o common.o auth_proto_v2.o
auth_proto_v2.o $(FW_OBJS) $(LDFLAGS) $(LIBS)

fw_test: $(FW_OBJS) common.o fw_test.o
$(CC) $(CFLAGS) -o fw_test $(FW_OBJS) common.o fw_test.o $(LIBS)
$(CC) $(CFLAGS) -o fw_test $(FW_OBJS) common.o fw_test.o $(LDFLAGS) $(LIBS)

ipscromp_gatekeeper: ipscromp_gatekeeper.o
$(CC) $(CFLAGS) -o ipscromp_gatekeeper ipscromp_gatekeeper.c $(LIBS)
$(CC) $(CFLAGS) -o ipscromp_gatekeeper ipscromp_gatekeeper.c $(LDFLAGS) $(LIBS)


clean:;
Expand Down
34 changes: 17 additions & 17 deletions auth_proto_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ char *pass_for(char *user)
return NULL;
}

while(pass == NULL && !feof(passfile)) {
char *colon;
if (fgets(buffer, PASS_BUFFSIZE, passfile) != NULL
&& (colon = index(buffer, ':')) != NULL) {
*colon = '\0';
if (strcmp(buffer, user) == 0) {
chomp(colon + 1);
pass = strdup(colon + 1);
}
}
while(pass == NULL && !feof(passfile)) {
char *colon;
if (fgets(buffer, PASS_BUFFSIZE, passfile) != NULL
&& (colon = strchr(buffer, ':')) != NULL) {
*colon = '\0';
if (strcmp(buffer, user) == 0) {
chomp(colon + 1);
pass = strdup(colon + 1);
}
}
}

fclose(passfile);
Expand Down Expand Up @@ -95,13 +95,13 @@ errorcode auth_proto_v2(authrequest *req)
return ERROR_CREDENTIALS;
}

auth_len = strlen(req->user) + strlen(challenge) + strlen(pass) + 3;
if (alt_ip != NULL) {
if (inet_aton(alt_ip, &req->ip_to_add) == 0) {
syslog(LOG_ERR, "Invalid IP specified with IPERMIT, got '%s'", response);
return ERROR_IP_INVALID;
}
auth_len += strlen(alt_ip) + 1;
auth_len = strlen(req->user) + strlen(challenge) + strlen(pass) + 3;
if (alt_ip != NULL) {
if (string_to_sockaddr(alt_ip, &req->ip_to_add, &req->ip_to_add_len) < 0) {
syslog(LOG_ERR, "Invalid IP specified with IPERMIT, got '%s'", response);
return ERROR_IP_INVALID;
}
auth_len += strlen(alt_ip) + 1;
}

if ((auth_str = malloc(auth_len)) == NULL) {
Expand Down
74 changes: 71 additions & 3 deletions common.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
#include <ctype.h>
#include <stdarg.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#ifdef USE_MD
#include <md5.h>
Expand Down Expand Up @@ -145,11 +150,11 @@ void chomp(char *string)
{
char *c;

if ((c = index(string, '\n')) != NULL) {
if ((c = strchr(string, '\n')) != NULL) {
*c = '\0';
}

if ((c = index(string, '\r')) != NULL) {
if ((c = strchr(string, '\r')) != NULL) {
*c = '\0';
}
}
Expand Down Expand Up @@ -225,7 +230,7 @@ char *hash(int version, char *fmt, ...)

char *progname(char *progpath)
{
char *progname = rindex(progpath, '/');
char *progname = strrchr(progpath, '/');

if (progname == NULL) {
progname = progpath;
Expand All @@ -236,3 +241,66 @@ char *progname(char *progpath)

return progname;
}


/*
* Convert a sockaddr_storage to a string representation
* Returns a newly allocated string that must be freed by caller
*/
char *sockaddr_to_string(struct sockaddr_storage *ss, socklen_t sslen)
{
char buffer[INET6_ADDRSTRLEN];
void *addr;

if (ss->ss_family == AF_INET) {
addr = &((struct sockaddr_in *)ss)->sin_addr;
}
else if (ss->ss_family == AF_INET6) {
addr = &((struct sockaddr_in6 *)ss)->sin6_addr;
}
else {
return NULL;
}

if (inet_ntop(ss->ss_family, addr, buffer, sizeof(buffer)) == NULL) {
return NULL;
}

return strdup(buffer);
}


/*
* Convert a string (hostname or IP) to a sockaddr_storage
* Returns 0 on success, -1 on error
* Prefers IPv6 if available, falls back to IPv4
*/
int string_to_sockaddr(const char *str, struct sockaddr_storage *ss, socklen_t *sslen)
{
struct addrinfo hints, *res, *rp;
int rc;

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_ADDRCONFIG; /* Only return addresses we can use */

rc = getaddrinfo(str, NULL, &hints, &res);
if (rc != 0) {
dbg("getaddrinfo(%s) failed: %s\n", str, gai_strerror(rc));
return -1;
}

/* Try each address until we find one that works */
for (rp = res; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family == AF_INET || rp->ai_family == AF_INET6) {
memcpy(ss, rp->ai_addr, rp->ai_addrlen);
*sslen = rp->ai_addrlen;
freeaddrinfo(res);
return 0;
}
}

freeaddrinfo(res);
return -1;
}
7 changes: 7 additions & 0 deletions common.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

#include <sys/socket.h>
#include <netinet/in.h>

extern int debug;
extern int debug_to_syslog;

Expand All @@ -11,3 +14,7 @@ extern char *progname(char *progpath);
extern void random_string(char *buffer, size_t bufflen);
extern void dbg(char *fmt, ...);

/* New dual-stack helper functions */
extern char *sockaddr_to_string(struct sockaddr_storage *ss, socklen_t sslen);
extern int string_to_sockaddr(const char *str, struct sockaddr_storage *ss, socklen_t *sslen);

7 changes: 4 additions & 3 deletions fw_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@
int main(int argc, char *argv[])
{
int rc;
struct in_addr addr;
struct sockaddr_storage addr;
socklen_t addrlen;

if (argc != 3)
{
fprintf(stderr, "Usage: %s <ip> <user>\n", progname(argv[0]));
return 1;
}

if (inet_aton(argv[1], &addr) == 0)
if (string_to_sockaddr(argv[1], &addr, &addrlen) < 0)
{
printf("%s is not a valid IP\n", argv[1]);
}
else if ((rc = fw_add_ip(addr, argv[2])) >= 0)
else if ((rc = fw_add_ip(&addr, addrlen, argv[2])) >= 0)
{
printf("%s added successfully. Limited to %d hours\n", argv[1], rc);
}
Expand Down
55 changes: 50 additions & 5 deletions fw_touch.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdlib.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
Expand All @@ -15,18 +16,57 @@
#error You must define FW_DIRECTORY for fw_touch.c
#endif

/* Helper function to make IP address safe for use as filename */
/* Replaces : with _ for IPv6 addresses */
static char *ip_to_filename(char *ip_str)
{
char *result, *p;

if (ip_str == NULL) {
return NULL;
}

result = strdup(ip_str);
if (result == NULL) {
return NULL;
}

/* Replace colons with underscores for IPv6 */
for (p = result; *p != '\0'; p++) {
if (*p == ':') {
*p = '_';
}
}

return result;
}


// this routine creates a file in FW_DIRECTORY/<ip addr>
// and then runs the firewall reload script...
//
int fw_add_ip(struct in_addr ip, char *user)
int fw_add_ip(struct sockaddr_storage *addr, socklen_t addrlen, char *user)
{
FILE *fp;
struct stat st;
char path[512];
char path[1024], cmd[1024];
char need_fw=0;
char *ip_str, *filename_str;

sprintf(path, "%s/%s", FW_DIRECTORY, inet_ntoa(ip));
ip_str = sockaddr_to_string(addr, addrlen);
if (ip_str == NULL) {
syslog(LOG_ERR, "Unable to convert address to string");
return -EINVAL;
}

filename_str = ip_to_filename(ip_str);
if (filename_str == NULL) {
syslog(LOG_ERR, "Unable to create filename for IP");
free(ip_str);
return -ENOMEM;
}

snprintf(path, sizeof(path), "%s/%s", FW_DIRECTORY, filename_str);

// if IP has already been auth'd, simply touch the spool file but
// don't invoke dynfw again...
Expand All @@ -38,17 +78,22 @@ int fw_add_ip(struct in_addr ip, char *user)
//
if ((fp = fopen(path, "w")) == NULL) {
syslog(LOG_ERR, "Unable to open '%s': %m", path);
free(filename_str);
free(ip_str);
return -errno;
}

fprintf(fp, "%s\n", user);
fclose(fp);

if (need_fw) {
sprintf(path, "/usr/local/sbin/ipscromp_dynfw open %s > /dev/null 2>&1", inet_ntoa(ip));
system(path);
snprintf(cmd, sizeof(cmd), "/usr/local/sbin/ipscromp_dynfw open %s > /dev/null 2>&1", ip_str);
system(cmd);
}

free(filename_str);
free(ip_str);

// system("/etc/rc.d/rc.fw > /dev/null 2> /dev/null");

return 0;
Expand Down
Loading