Second piece of connmgr removal: bye bye agent, bye bye libs.
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
cmmoduledir = $(libdir)/connmgr
|
||||
cmmodule_LTLIBRARIES :=
|
||||
|
||||
sbin_PROGRAMS += bongoconnmgr
|
||||
|
||||
bongoconnmgr_SOURCES := \
|
||||
src/agents/connmgr/connmgr.c \
|
||||
src/agents/connmgr/connmgrp.h \
|
||||
src/agents/connmgr/modules.c
|
||||
|
||||
bongoconnmgr_LDADD := \
|
||||
libbongomanagement.la \
|
||||
libbongomsgapi.la \
|
||||
libbongomdb.la \
|
||||
libbongologger.la \
|
||||
libbongoconnio.la \
|
||||
libbongomemmgr.la \
|
||||
libbongoutil.la \
|
||||
libbongoxpl.la \
|
||||
$(top_builddir)/import/log4c/log4c/libbongolog4c.la \
|
||||
$(SQLITE_LIBS) \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/all: bongoconnmgr \
|
||||
src/agents/connmgr/cmmodules/rbl/all \
|
||||
src/agents/connmgr/cmmodules/rdns/all \
|
||||
src/agents/connmgr/cmmodules/user/all \
|
||||
src/agents/connmgr/cmmodules/lists/all
|
||||
|
||||
src/agents/connmgr/clean: clean
|
||||
src/agents/connmgr/install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) sbin_PROGRAMS=bongoconnmgr \
|
||||
install-sbinPROGRAMS install-cmmoduleLTLIBRARIES
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -1,19 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmlists.la
|
||||
|
||||
libcmlists_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/lists/cmlists.c \
|
||||
src/agents/connmgr/cmmodules/lists/cmlists.h
|
||||
|
||||
libcmlists_la_LDFLAGS := -module -avoid-version
|
||||
libcmlists_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/lists/all: libcmlists.la
|
||||
src/agents/connmgr/cmmodules/lists/clean: clean
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -1,350 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <xplresolve.h>
|
||||
#include <mdb.h>
|
||||
#include <msgapi.h>
|
||||
|
||||
#include "cmlists.h"
|
||||
|
||||
/* Globals */
|
||||
BOOL ListUnloadOk = TRUE;
|
||||
ListGlobal List;
|
||||
|
||||
static BOOL ReadConfiguration(void);
|
||||
|
||||
|
||||
EXPORT int ListsVerify(ConnMgrCommand *command, ConnMgrResult *result)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
/* Check Allowed List */
|
||||
if ((XplStrCaseCmp(command->event, CM_EVENT_RELAY) == 0) || (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0)) {
|
||||
for (i = 0; i < List.allowed.count; i++) {
|
||||
if ((List.allowed.start[i] <= (long) command->address) && ((long) command->address <= List.allowed.end[i])) {
|
||||
/* We like the guy */
|
||||
return(CM_MODULE_ACCEPT | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check Blocked List */
|
||||
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
|
||||
for (i = 0; i < List.blocked.count; i++) {
|
||||
if ((List.blocked.start[i] <= (long) command->address) && ((long) command->address <= List.blocked.end[i])) {
|
||||
/* We don't like the guy */
|
||||
return(CM_MODULE_DENY | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
CMLISTSInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
|
||||
{
|
||||
if (ListUnloadOk == TRUE) {
|
||||
XplSafeWrite(List.threadCount, 0);
|
||||
|
||||
List.directoryHandle = (MDBHandle) MsgInit();
|
||||
if (List.directoryHandle) {
|
||||
ListUnloadOk = FALSE;
|
||||
|
||||
List.logHandle = LoggerOpen("cmlist");
|
||||
if (List.logHandle == NULL) {
|
||||
XplConsolePrintf("cmlist: Unable to initialize logging. Logging disabled.\r\n");
|
||||
}
|
||||
|
||||
/* Fill out registration information */
|
||||
registration->priority = 1; /* It is important that the lists are early */
|
||||
registration->Shutdown = ListsShutdown;
|
||||
registration->Verify = ListsVerify;
|
||||
registration->Notify = NULL;
|
||||
|
||||
XplSafeIncrement(List.threadCount);
|
||||
|
||||
strcpy(List.config.datadir, datadir);
|
||||
|
||||
return(ReadConfiguration());
|
||||
} else {
|
||||
XplConsolePrintf("cmlist: Failed to obtain directory handle\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
AddBlockedAddress(const unsigned char *AddressStart, const unsigned char *AddressEnd)
|
||||
{
|
||||
if ((List.blocked.count + 1) > List.blocked.allocated) {
|
||||
List.blocked.start = MemRealloc(List.blocked.start, (List.blocked.allocated + 5) * sizeof(unsigned long));
|
||||
List.blocked.end = MemRealloc(List.blocked.end, (List.blocked.allocated + 5) * sizeof(unsigned long));
|
||||
|
||||
if (!List.blocked.start || !List.blocked.end) {
|
||||
LoggerEvent(List.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, ((List.blocked.allocated+5) + (List.blocked.allocated+5)) * sizeof(unsigned long), __LINE__, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
List.blocked.allocated += 5;
|
||||
}
|
||||
|
||||
if ((List.blocked.start[List.blocked.count] = inet_addr(AddressStart)) != -1) {
|
||||
List.blocked.start[List.blocked.count] = ntohl(List.blocked.start[List.blocked.count]);
|
||||
|
||||
if ((List.blocked.end[List.blocked.count] = inet_addr(AddressEnd)) != -1) {
|
||||
List.blocked.end[List.blocked.count] = ntohl(List.blocked.end[List.blocked.count]);
|
||||
List.blocked.count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FreeBlockedAddresses(void)
|
||||
{
|
||||
if (List.blocked.start) {
|
||||
MemFree(List.blocked.start);
|
||||
}
|
||||
|
||||
List.blocked.start = NULL;
|
||||
|
||||
if (List.blocked.end) {
|
||||
MemFree(List.blocked.end);
|
||||
}
|
||||
List.blocked.end = NULL;
|
||||
|
||||
List.blocked.allocated = 0;
|
||||
List.blocked.count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
AddAllowedAddress(const unsigned char *AddressStart, const unsigned char *AddressEnd)
|
||||
{
|
||||
if ((List.allowed.count + 1) > List.allowed.allocated) {
|
||||
List.allowed.start = MemRealloc(List.allowed.start, (List.allowed.allocated + 5) * sizeof(unsigned long));
|
||||
List.allowed.end = MemRealloc(List.allowed.end, (List.allowed.allocated + 5) * sizeof(unsigned long));
|
||||
|
||||
if (!List.allowed.start || !List.allowed.end) {
|
||||
LoggerEvent(List.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, ((List.allowed.allocated+5) + (List.allowed.allocated+5)) * sizeof(unsigned long), __LINE__, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
List.allowed.allocated += 5;
|
||||
}
|
||||
|
||||
if ((List.allowed.start[List.allowed.count] = inet_addr(AddressStart)) != -1) {
|
||||
List.allowed.start[List.allowed.count] = ntohl(List.allowed.start[List.allowed.count]);
|
||||
|
||||
if ((List.allowed.end[List.allowed.count] = inet_addr(AddressEnd)) != -1) {
|
||||
List.allowed.end[List.allowed.count] = ntohl(List.allowed.end[List.allowed.count]);
|
||||
List.allowed.count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FreeAllowedAddresses(void)
|
||||
{
|
||||
if (List.allowed.start) {
|
||||
MemFree(List.allowed.start);
|
||||
}
|
||||
|
||||
List.allowed.start = NULL;
|
||||
|
||||
if (List.allowed.end) {
|
||||
MemFree(List.allowed.end);
|
||||
}
|
||||
|
||||
List.allowed.end = NULL;
|
||||
|
||||
List.allowed.allocated = 0;
|
||||
List.allowed.count = 0;
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
ListsShutdown(void)
|
||||
{
|
||||
XplSafeDecrement(List.threadCount);
|
||||
|
||||
if (ListUnloadOk == FALSE) {
|
||||
ListUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library lists are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(List.threadCount)) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
LoggerClose(List.logHandle);
|
||||
FreeBlockedAddresses();
|
||||
FreeAllowedAddresses();
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(List.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(List.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(List.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ReadConfiguration(void)
|
||||
{
|
||||
MDBValueStruct *config;
|
||||
const unsigned char *Address;
|
||||
MDBEnumStruct *e;
|
||||
unsigned char *ptr;
|
||||
|
||||
config = MDBCreateValueStruct(List.directoryHandle, MsgGetServerDN(NULL));
|
||||
e = MDBCreateEnumStruct(config);
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_DISABLED, config)) {
|
||||
if (atol(config->Value[0]) == 1) {
|
||||
MDBDestroyValueStruct(config);
|
||||
ListsShutdown();
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_CONFIG_CHANGED, config)) {
|
||||
List.config.last = atol(config->Value[0]);
|
||||
MDBFreeValues(config);
|
||||
} else {
|
||||
List.config.last = 0;
|
||||
}
|
||||
|
||||
while ((Address = MDBReadEx(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_BLOCKED_ADDRESS, e, config)) != NULL) {
|
||||
ptr = strchr(Address, '-');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
AddBlockedAddress(Address, ptr + 1);
|
||||
*ptr = '-';
|
||||
} else {
|
||||
AddBlockedAddress(Address, Address);
|
||||
}
|
||||
}
|
||||
MDBFreeValues(config);
|
||||
|
||||
while ((Address = MDBReadEx(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_ALLOWED_ADDRESS, e, config)) != NULL) {
|
||||
ptr = strchr(Address, '-');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
AddAllowedAddress(Address, ptr + 1);
|
||||
*ptr = '-';
|
||||
} else {
|
||||
AddAllowedAddress(Address, Address);
|
||||
}
|
||||
}
|
||||
MDBFreeValues(config);
|
||||
|
||||
MDBDestroyEnumStruct(e, config);
|
||||
MDBDestroyValueStruct(config);
|
||||
|
||||
if (List.blocked.count == 0 && List.allowed.count == 0) {
|
||||
#if VERBOSE
|
||||
XplConsolePrintf("cmlists: No addresses blocked or allowed\n");
|
||||
#endif
|
||||
|
||||
ListsShutdown();
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
Below are "stock" functions that are basically infrastructure.
|
||||
However, one might want to add initialization code to main
|
||||
and takedown code to the signal handler
|
||||
*/
|
||||
void
|
||||
ListShutdownSigHandler(int Signal)
|
||||
{
|
||||
int oldtgid = XplSetThreadGroupID(List.tgid);
|
||||
|
||||
if (ListUnloadOk == FALSE) {
|
||||
ListUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library lists are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(List.threadCount) > 1) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
/* Do any required cleanup */
|
||||
LoggerClose(List.logHandle);
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(List.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(List.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(List.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
XplSetThreadGroupID(oldtgid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
_NonAppCheckUnload(void)
|
||||
{
|
||||
if (ListUnloadOk == FALSE) {
|
||||
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
|
||||
XplConsolePrintf("\rIt does not allow manual unloading.\n");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* init globals */
|
||||
List.tgid = XplGetThreadGroupID();
|
||||
|
||||
XplRenameThread(GetThreadID(), "Gate Keeper List Module");
|
||||
XplOpenLocalSemaphore(List.shutdownSemaphore, 0);
|
||||
XplSignalHandler(ListShutdownSigHandler);
|
||||
|
||||
/*
|
||||
This will "park" the module 'til we get unloaded;
|
||||
it would not be neccessary to do this on NetWare,
|
||||
but to prevent from automatically exiting on Unix
|
||||
we need to keep main around...
|
||||
*/
|
||||
XplWaitOnLocalSemaphore(List.shutdownSemaphore);
|
||||
XplSignalLocalSemaphore(List.shutdownSemaphore);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <mdb.h>
|
||||
#include <logger.h>
|
||||
|
||||
#include <connmgr.h>
|
||||
|
||||
#define PRODUCT_SHORT_NAME "cmlist.nlm"
|
||||
#define PRODUCT_NAME "Bongo Connection Manager Block and Allow List Module"
|
||||
|
||||
typedef struct _ListGlobal {
|
||||
/* Handles */
|
||||
void *logHandle;
|
||||
MDBHandle directoryHandle;
|
||||
|
||||
/* Module State */
|
||||
time_t timeStamp;
|
||||
int tgid;
|
||||
BOOL unloadOK;
|
||||
XplSemaphore shutdownSemaphore;
|
||||
XplAtomic threadCount;
|
||||
|
||||
struct {
|
||||
long last;
|
||||
|
||||
unsigned char datadir[XPL_MAX_PATH + 1];
|
||||
} config;
|
||||
|
||||
struct {
|
||||
long *start;
|
||||
long *end;
|
||||
unsigned long count;
|
||||
unsigned long allocated;
|
||||
} blocked;
|
||||
|
||||
struct {
|
||||
long *start;
|
||||
long *end;
|
||||
unsigned long count;
|
||||
unsigned long allocated;
|
||||
} allowed;
|
||||
} ListGlobal;
|
||||
|
||||
extern ListGlobal List;
|
||||
|
||||
/* cmlist.c */
|
||||
void ListShutdownSigHandler(int Signal);
|
||||
int _NonAppCheckUnload(void);
|
||||
|
||||
EXPORT BOOL CMLISTSInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
|
||||
EXPORT BOOL ListsShutdown(void);
|
||||
EXPORT int ListsVerify(ConnMgrCommand *command, ConnMgrResult *result);
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmrbl.la
|
||||
|
||||
libcmrbl_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/rbl/cmrbl.c \
|
||||
src/agents/connmgr/cmmodules/rbl/cmrbl.h
|
||||
|
||||
libcmrbl_la_CPPFLAGS := $(AM_CPPFLAGS) \
|
||||
$(SQLITE_CFLAGS)
|
||||
|
||||
libcmrbl_la_LDFLAGS := -module -avoid-version
|
||||
libcmrbl_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(SQLITE_LIBS) \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/rbl/all: libcmrbl.la
|
||||
src/agents/connmgr/cmmodules/rbl/clean: clean
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -1,495 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <xplresolve.h>
|
||||
#include <mdb.h>
|
||||
#include <msgapi.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "cmrbl.h"
|
||||
|
||||
/* Globals */
|
||||
BOOL RBLUnloadOk = TRUE;
|
||||
RBLGlobal RBL;
|
||||
|
||||
static BOOL ReadConfiguration(void);
|
||||
|
||||
|
||||
EXPORT int RBLVerify(ConnMgrCommand *command, ConnMgrResult *result)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
|
||||
XplDnsRecord *dns = NULL;
|
||||
BOOL blocked = FALSE;
|
||||
int rc = -1;
|
||||
int commentID = -1;
|
||||
|
||||
/* Check for a cached value */
|
||||
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
|
||||
|
||||
sqlite3_bind_int(RBL.sqlite.stmt.get, 1, command->address);
|
||||
|
||||
if ((rc = sqlite3_step(RBL.sqlite.stmt.get)) == SQLITE_ROW) {
|
||||
blocked = sqlite3_column_int(RBL.sqlite.stmt.get, 0);
|
||||
strncpy(result->comment, sqlite3_column_text(RBL.sqlite.stmt.get, 1), sizeof(result->comment));
|
||||
}
|
||||
|
||||
sqlite3_reset(RBL.sqlite.stmt.get);
|
||||
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
|
||||
|
||||
if (rc != SQLITE_ROW) {
|
||||
/* Perform the RBL check */
|
||||
for (i = 0; i < RBL.rbl.count; i++) {
|
||||
unsigned char buffer[MAXEMAILNAMESIZE];
|
||||
struct in_addr ip;
|
||||
|
||||
ip.s_addr = command->address;
|
||||
|
||||
/* address is in host byte order. RBL checks require least significant first. */
|
||||
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.%s",
|
||||
ip.s_net,
|
||||
ip.s_host,
|
||||
ip.s_lh,
|
||||
ip.s_impno,
|
||||
RBL.rbl.hosts[i]);
|
||||
|
||||
rc = XplDnsResolve(buffer, &dns, XPL_RR_A);
|
||||
if (dns) {
|
||||
MemFree(dns);
|
||||
}
|
||||
|
||||
if (rc == XPL_DNS_SUCCESS) {
|
||||
blocked = TRUE;
|
||||
commentID = RBL.rbl.ids[i];
|
||||
strncpy(result->comment, RBL.rbl.comments[i], sizeof(result->comment));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store new value */
|
||||
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
|
||||
|
||||
/*
|
||||
Insert the new value into the table. The time for a negative result is a
|
||||
full day. The time for a positive result is only 15 minutes however,
|
||||
because a positive result simply means that the servers do not know anything
|
||||
about the address.
|
||||
*/
|
||||
sqlite3_bind_int(RBL.sqlite.stmt.add, 1, command->address);
|
||||
sqlite3_bind_text(RBL.sqlite.stmt.add, 2, blocked ? RBL.config.blockTimeout : RBL.config.allowTimeout, -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(RBL.sqlite.stmt.add, 3, blocked);
|
||||
sqlite3_bind_int(RBL.sqlite.stmt.add, 4, commentID);
|
||||
|
||||
sqlite3_step(RBL.sqlite.stmt.add);
|
||||
|
||||
sqlite3_reset(RBL.sqlite.stmt.add);
|
||||
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
|
||||
}
|
||||
|
||||
if (blocked) {
|
||||
/* He was blocked by RBL */
|
||||
return(CM_MODULE_DENY | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
|
||||
} else {
|
||||
/* He was not blocked, don't force it though */
|
||||
return(CM_MODULE_ACCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
TransactionController(void *ignored)
|
||||
{
|
||||
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
|
||||
if (sqlite3_exec(RBL.sqlite.handle, SQL_BEGIN, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
XplConsolePrintf("cmrbl: Failed to start transaction controller\n");
|
||||
}
|
||||
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
|
||||
|
||||
while (!RBLUnloadOk) {
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < 15 && !RBLUnloadOk; i++) {
|
||||
XplDelay(1000);
|
||||
}
|
||||
|
||||
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
|
||||
if (sqlite3_exec(RBL.sqlite.handle, SQL_SAVE, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
XplConsolePrintf("cmrbl: Failed to save cache data\n");
|
||||
}
|
||||
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
|
||||
}
|
||||
|
||||
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
|
||||
if (sqlite3_exec(RBL.sqlite.handle, SQL_END, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
XplConsolePrintf("cmrbl: Failed to end transaction controller\n");
|
||||
}
|
||||
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
CMRBLInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
|
||||
{
|
||||
if (RBLUnloadOk == TRUE) {
|
||||
XplSafeWrite(RBL.threadCount, 0);
|
||||
|
||||
RBL.directoryHandle = (MDBHandle) MsgInit();
|
||||
if (RBL.directoryHandle) {
|
||||
RBLUnloadOk = FALSE;
|
||||
|
||||
RBL.logHandle = LoggerOpen("cmrbl");
|
||||
if (RBL.logHandle == NULL) {
|
||||
XplConsolePrintf("cmrbl: Unable to initialize logging. Logging disabled.\r\n");
|
||||
}
|
||||
|
||||
/* Fill out registration information */
|
||||
registration->priority = 1; /* It is important that the rbl are early */
|
||||
registration->Shutdown = RBLShutdown;
|
||||
registration->Verify = RBLVerify;
|
||||
registration->Notify = NULL;
|
||||
|
||||
XplSafeIncrement(RBL.threadCount);
|
||||
|
||||
strcpy(RBL.config.datadir, datadir);
|
||||
|
||||
XplOpenLocalSemaphore(RBL.sqlite.semaphore, 1);
|
||||
|
||||
if (ReadConfiguration()) {
|
||||
unsigned char buffer[XPL_MAX_PATH + 1];
|
||||
int ccode;
|
||||
XplThreadID id;
|
||||
sqlite3_stmt *stmt;
|
||||
sqlite3_stmt *stmt2;
|
||||
unsigned long i;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s/cache.db", datadir);
|
||||
if (sqlite3_open(buffer, &RBL.sqlite.handle) != SQLITE_OK) {
|
||||
printf("cmrbl: Failed to open database: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
|
||||
}
|
||||
|
||||
if (sqlite3_exec(RBL.sqlite.handle, SQL_CREATE, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
#if 0
|
||||
printf("bongogatekeeper: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
|
||||
#endif
|
||||
sqlite3_exec(RBL.sqlite.handle, SQL_ROLLBACK, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if ((sqlite3_prepare(RBL.sqlite.handle, SQL_ADD, -1, &RBL.sqlite.stmt.add, 0) != SQLITE_OK) ||
|
||||
(sqlite3_prepare(RBL.sqlite.handle, SQL_GET, -1, &RBL.sqlite.stmt.get, 0) != SQLITE_OK) ||
|
||||
(sqlite3_prepare(RBL.sqlite.handle, SQL_CLEAN, -1, &RBL.sqlite.stmt.clean,0) != SQLITE_OK))
|
||||
{
|
||||
printf("cmrbl: Failed to prepare sql: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
sqlite3_exec(RBL.sqlite.handle, SQL_COMMENTS_CLEAN1, NULL, NULL, NULL);
|
||||
|
||||
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_CLEAN2, -1, &stmt, 0);
|
||||
for (i = 0; i < RBL.rbl.count; i++) {
|
||||
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
|
||||
sqlite3_step(stmt);
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
sqlite3_exec(RBL.sqlite.handle, SQL_COMMENTS_CLEAN3, NULL, NULL, NULL);
|
||||
|
||||
/* Ok, add any new ones */
|
||||
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_ADD, -1, &stmt, 0);
|
||||
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_UPDATE, -1, &stmt2, 0);
|
||||
for (i = 0; i < RBL.rbl.count; i++) {
|
||||
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt, 2, RBL.rbl.comments[i], -1, SQLITE_TRANSIENT);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
/* It is already there, so just update the comment in case it changed */
|
||||
sqlite3_bind_text(stmt2, 1, RBL.rbl.comments[i], -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_text(stmt2, 2, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
|
||||
|
||||
sqlite3_step(stmt2);
|
||||
sqlite3_reset(stmt2);
|
||||
}
|
||||
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
sqlite3_finalize(stmt2);
|
||||
|
||||
/* Get the IDs for them */
|
||||
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_GET_ID, -1, &stmt, 0);
|
||||
for (i = 0; i < RBL.rbl.count; i++) {
|
||||
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
|
||||
if (sqlite3_step(stmt) == SQLITE_ROW) {
|
||||
RBL.rbl.ids[i] = sqlite3_column_int(RBL.sqlite.stmt.get, 0);
|
||||
} else {
|
||||
RBL.rbl.ids[i] = -1;
|
||||
}
|
||||
sqlite3_reset(stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
/* Begin the transaction controller thread */
|
||||
XplBeginThread(&id, TransactionController, (1024 * 32), NULL, ccode);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
} else {
|
||||
XplConsolePrintf("cmrbl: Failed to obtain directory handle\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
RBLShutdown(void)
|
||||
{
|
||||
XplSafeDecrement(RBL.threadCount);
|
||||
|
||||
if (RBLUnloadOk == FALSE) {
|
||||
unsigned long i;
|
||||
|
||||
RBLUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library rbl are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(RBL.threadCount)) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
LoggerClose(RBL.logHandle);
|
||||
|
||||
sqlite3_finalize(RBL.sqlite.stmt.add);
|
||||
sqlite3_finalize(RBL.sqlite.stmt.get);
|
||||
sqlite3_finalize(RBL.sqlite.stmt.clean);
|
||||
|
||||
sqlite3_close(RBL.sqlite.handle);
|
||||
XplCloseLocalSemaphore(RBL.sqlite.semaphore);
|
||||
|
||||
for (i = 0; i < RBL.rbl.count; i++) {
|
||||
MemFree(RBL.rbl.hosts[i]);
|
||||
MemFree(RBL.rbl.comments[i]);
|
||||
}
|
||||
|
||||
if (RBL.rbl.hosts) {
|
||||
MemFree(RBL.rbl.hosts);
|
||||
}
|
||||
|
||||
if (RBL.rbl.comments) {
|
||||
MemFree(RBL.rbl.comments);
|
||||
}
|
||||
|
||||
if (RBL.rbl.ids) {
|
||||
MemFree(RBL.rbl.ids);
|
||||
}
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(RBL.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(RBL.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ReadConfiguration(void)
|
||||
{
|
||||
MDBValueStruct *config;
|
||||
|
||||
config = MDBCreateValueStruct(RBL.directoryHandle, MsgGetServerDN(NULL));
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_DISABLED, config)) {
|
||||
if (atol(config->Value[0]) == 1) {
|
||||
MDBDestroyValueStruct(config);
|
||||
RBLShutdown();
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_CONFIG_CHANGED, config)) {
|
||||
RBL.config.last = atol(config->Value[0]);
|
||||
MDBFreeValues(config);
|
||||
} else {
|
||||
RBL.config.last = 0;
|
||||
}
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_RBL_HOST, config) > 0) {
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < RBL.rbl.count; i++) {
|
||||
MemFree(RBL.rbl.hosts[i]);
|
||||
MemFree(RBL.rbl.comments[i]);
|
||||
}
|
||||
|
||||
if (RBL.rbl.hosts) {
|
||||
MemFree(RBL.rbl.hosts);
|
||||
}
|
||||
|
||||
if (RBL.rbl.comments) {
|
||||
MemFree(RBL.rbl.comments);
|
||||
}
|
||||
|
||||
if (RBL.rbl.ids) {
|
||||
MemFree(RBL.rbl.ids);
|
||||
}
|
||||
|
||||
RBL.rbl.count = config->Used;
|
||||
RBL.rbl.hosts = MemMalloc(config->Used * sizeof(char *));
|
||||
RBL.rbl.comments = MemMalloc(config->Used * sizeof(char *));
|
||||
RBL.rbl.ids = MemMalloc(config->Used * sizeof(long));
|
||||
|
||||
if (!RBL.rbl.hosts || !RBL.rbl.comments || !RBL.rbl.ids) {
|
||||
LoggerEvent(RBL.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, config->Used * sizeof(char *) * 2, __LINE__, NULL, 0);
|
||||
} else {
|
||||
for (i = 0; i < RBL.rbl.count; i++) {
|
||||
unsigned char *ptr = strchr(config->Value[i], ';');
|
||||
|
||||
if (ptr) {
|
||||
ptr[0] = '\0';
|
||||
}
|
||||
|
||||
RBL.rbl.hosts[i] = MemStrdup(config->Value[i]);
|
||||
if (ptr) {
|
||||
RBL.rbl.comments[i] = MemStrdup(ptr + 1);
|
||||
} else {
|
||||
RBL.rbl.comments[i] = MemMalloc(sizeof(BLOCKED_STRING) + strlen(RBL.rbl.hosts[i]));
|
||||
sprintf(RBL.rbl.comments[i], BLOCKED_STRING, RBL.rbl.hosts[i]);
|
||||
}
|
||||
|
||||
LoggerEvent(RBL.logHandle, LOGGER_SUBSYSTEM_CONFIGURATION, LOGGER_EVENT_CONFIGURATION_STRING, LOG_INFO, 0, "MSGSRV_A_RBL_HOST", config->Value[i], 0, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
MDBFreeValues(config);
|
||||
}
|
||||
|
||||
/*
|
||||
Store the timeout strings. It is faster to do this once, instead of storing the long value
|
||||
and creating the string each time, since it must be a string that is bound to the SQL statement.
|
||||
*/
|
||||
snprintf(RBL.config.blockTimeout, sizeof(RBL.config.blockTimeout), "%d minutes", (24 * 60)); /* Default to 1 day for a block */
|
||||
snprintf(RBL.config.allowTimeout, sizeof(RBL.config.blockTimeout), "%d minutes", 15); /* Default to 15 minutes for allow */
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_CONFIGURATION, config) > 0) {
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < config->Used; i++) {
|
||||
if (XplStrNCaseCmp(config->Value[i], BLOCK_TIMEOUT_PREFIX, sizeof(BLOCK_TIMEOUT_PREFIX) - 1) == 0) {
|
||||
snprintf(RBL.config.blockTimeout, sizeof(RBL.config.blockTimeout), "%lu minutes", atol(config->Value[i] + sizeof(BLOCK_TIMEOUT_PREFIX) - 1));
|
||||
} else if (XplStrNCaseCmp(config->Value[i], ALLOW_TIMEOUT_PREFIX, sizeof(ALLOW_TIMEOUT_PREFIX) - 1) == 0) {
|
||||
snprintf(RBL.config.allowTimeout, sizeof(RBL.config.allowTimeout), "%lu minutes", atol(config->Value[i] + sizeof(ALLOW_TIMEOUT_PREFIX) - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MDBDestroyValueStruct(config);
|
||||
|
||||
if (RBL.rbl.count == 0) {
|
||||
#if VERBOSE
|
||||
XplConsolePrintf("cmrbl: No RBL zones configured. RBL check is disabled.\n");
|
||||
#endif
|
||||
RBLShutdown();
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
Below are "stock" functions that are basically infrastructure.
|
||||
However, one might want to add initialization code to main
|
||||
and takedown code to the signal handler
|
||||
*/
|
||||
void
|
||||
RBLShutdownSigHandler(int Signal)
|
||||
{
|
||||
int oldtgid = XplSetThreadGroupID(RBL.tgid);
|
||||
|
||||
if (RBLUnloadOk == FALSE) {
|
||||
RBLUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library rbl are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(RBL.threadCount) > 1) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
/* Do any required cleanup */
|
||||
LoggerClose(RBL.logHandle);
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(RBL.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(RBL.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
XplSetThreadGroupID(oldtgid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
_NonAppCheckUnload(void)
|
||||
{
|
||||
if (RBLUnloadOk == FALSE) {
|
||||
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
|
||||
XplConsolePrintf("\rIt does not allow manual unloading.\n");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* init globals */
|
||||
RBL.tgid = XplGetThreadGroupID();
|
||||
|
||||
XplRenameThread(GetThreadID(), "Gate Keeper RBL Module");
|
||||
XplOpenLocalSemaphore(RBL.shutdownSemaphore, 0);
|
||||
XplSignalHandler(RBLShutdownSigHandler);
|
||||
|
||||
/*
|
||||
This will "park" the module 'til we get unloaded;
|
||||
it would not be neccessary to do this on NetWare,
|
||||
but to prevent from automatically exiting on Unix
|
||||
we need to keep main around...
|
||||
*/
|
||||
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore);
|
||||
XplSignalLocalSemaphore(RBL.shutdownSemaphore);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <mdb.h>
|
||||
#include <logger.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <connmgr.h>
|
||||
|
||||
#define PRODUCT_SHORT_NAME "cmrbl.nlm"
|
||||
#define PRODUCT_NAME "Bongo Connection Manager RBL Module"
|
||||
|
||||
#define BLOCKED_STRING "Blocked by RBL %s"
|
||||
|
||||
typedef struct _RBLGlobal {
|
||||
/* Handles */
|
||||
void *logHandle;
|
||||
MDBHandle directoryHandle;
|
||||
|
||||
/* Module State */
|
||||
time_t timeStamp;
|
||||
int tgid;
|
||||
BOOL unloadOK;
|
||||
XplSemaphore shutdownSemaphore;
|
||||
XplAtomic threadCount;
|
||||
|
||||
struct {
|
||||
long last;
|
||||
|
||||
unsigned char datadir[XPL_MAX_PATH + 1];
|
||||
unsigned char blockTimeout[256];
|
||||
unsigned char allowTimeout[256];
|
||||
} config;
|
||||
|
||||
struct {
|
||||
unsigned char **hosts;
|
||||
unsigned char **comments;
|
||||
unsigned long *ids;
|
||||
unsigned long count;
|
||||
unsigned long allocated;
|
||||
} rbl;
|
||||
|
||||
struct {
|
||||
sqlite3 *handle;
|
||||
XplSemaphore semaphore;
|
||||
|
||||
struct {
|
||||
sqlite3_stmt *add;
|
||||
sqlite3_stmt *get;
|
||||
sqlite3_stmt *clean;
|
||||
} stmt;
|
||||
} sqlite;
|
||||
} RBLGlobal;
|
||||
|
||||
extern RBLGlobal RBL;
|
||||
|
||||
/* cmrbl.c */
|
||||
void RBLShutdownSigHandler(int Signal);
|
||||
int _NonAppCheckUnload(void);
|
||||
|
||||
EXPORT BOOL CMRBLInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
|
||||
EXPORT BOOL RBLShutdown(void);
|
||||
EXPORT int RBLVerify(ConnMgrCommand *command, ConnMgrResult *result);
|
||||
|
||||
/* Config Prefixes */
|
||||
#define BLOCK_TIMEOUT_PREFIX "RBLBlockTimeout:"
|
||||
#define ALLOW_TIMEOUT_PREFIX "RBLAllowTimeout:"
|
||||
|
||||
/* SQL */
|
||||
#define SQL_CREATE "BEGIN TRANSACTION;" \
|
||||
"CREATE TABLE cache (" \
|
||||
"ip INTEGER PRIMARY KEY NOT NULL," \
|
||||
"timeout DATETIME," \
|
||||
"block BOOL," \
|
||||
"commentID INTEGER" \
|
||||
");" \
|
||||
"CREATE TABLE comments (" \
|
||||
"key INTEGER PRIMARY KEY AUTOINCREMENT," \
|
||||
"zone TEXT UNIQUE," \
|
||||
"comment TEXT," \
|
||||
"keep BOOL default 1" \
|
||||
");" \
|
||||
"CREATE INDEX timeout_idx ON cache (timeout);" \
|
||||
"CREATE INDEX comment_idx ON cache (commentID);"\
|
||||
"END TRANSACTION;"
|
||||
|
||||
#define SQL_ROLLBACK "ROLLBACK;"
|
||||
|
||||
#define SQL_ADD "INSERT OR REPLACE INTO cache (ip, timeout, block, commentID) VALUES (?, DATETIME('now', ?), ?, ?);"
|
||||
#define SQL_GET "SELECT cache.block, comments.comment FROM cache INNER JOIN comments ON cache.commentID=comments.key WHERE ip=? AND julianday('now') < julianday(timeout);"
|
||||
#define SQL_CLEAN "DELETE FROM cache WHERE julianday('now') >= julianday(timeout);"
|
||||
|
||||
#define SQL_BEGIN "BEGIN TRANSACTION;"
|
||||
#define SQL_END "END TRANSACTION;"
|
||||
#define SQL_SAVE SQL_CLEAN SQL_END SQL_BEGIN
|
||||
|
||||
#define SQL_COMMENTS_CLEAN1 "UPDATE comments SET keep=0;"
|
||||
#define SQL_COMMENTS_CLEAN2 "UPDATE comments SET keep=1 WHERE zone=?;"
|
||||
#define SQL_COMMENTS_CLEAN3 "DELETE FROM comments WHERE keep=0"
|
||||
#define SQL_COMMENTS_ADD "INSERT INTO comments (zone, comment) VALUES (?, ?);"
|
||||
#define SQL_COMMENTS_UPDATE "UPDATE comments SET comment=? WHERE zone=?;"
|
||||
#define SQL_COMMENTS_GET_ID "SELECT key FROM comments WHERE zone=?;"
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmrdns.la
|
||||
|
||||
libcmrdns_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/rdns/cmrdns.c \
|
||||
src/agents/connmgr/cmmodules/rdns/cmrdns.h
|
||||
|
||||
libcmrdns_la_CPPFLAGS := $(AM_CPPFLAGS) \
|
||||
$(SQLITE_CFLAGS)
|
||||
|
||||
libcmrdns_la_LDFLAGS := -module -avoid-version
|
||||
libcmrdns_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(SQLITE_LIBS) \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/rdns/all: libcmrdns.la
|
||||
src/agents/connmgr/cmmodules/rdns/clean: clean
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -1,360 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <xplresolve.h>
|
||||
#include <mdb.h>
|
||||
#include <msgapi.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "cmrdns.h"
|
||||
|
||||
/* Globals */
|
||||
BOOL RDNSUnloadOk = TRUE;
|
||||
RDNSGlobal RDNS;
|
||||
|
||||
static BOOL ReadConfiguration(void);
|
||||
|
||||
|
||||
EXPORT int RDNSVerify(ConnMgrCommand *command, ConnMgrResult *result)
|
||||
{
|
||||
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
|
||||
XplDnsRecord *dns = NULL;
|
||||
BOOL blocked = FALSE;
|
||||
int rc = -1;
|
||||
|
||||
/* Check for a cached value */
|
||||
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
|
||||
sqlite3_bind_int(RDNS.sqlite.stmt.get, 1, command->address);
|
||||
|
||||
if ((rc = sqlite3_step(RDNS.sqlite.stmt.get)) == SQLITE_ROW) {
|
||||
blocked = sqlite3_column_int(RDNS.sqlite.stmt.get, 0);
|
||||
}
|
||||
|
||||
sqlite3_reset(RDNS.sqlite.stmt.get);
|
||||
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
|
||||
if (rc != SQLITE_ROW) {
|
||||
unsigned char buffer[MAXEMAILNAMESIZE];
|
||||
struct in_addr ip;
|
||||
|
||||
/* Perform the RDNS check */
|
||||
|
||||
ip.s_addr = command->address;
|
||||
|
||||
/* ip is in host byte order. Reverse DNS requires most significant first. (unless providing the .in-addr.arpa extension) */
|
||||
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d",
|
||||
ip.s_impno,
|
||||
ip.s_lh,
|
||||
ip.s_host,
|
||||
ip.s_net);
|
||||
|
||||
rc = XplDnsResolve(buffer, &dns, XPL_RR_PTR);
|
||||
|
||||
if (dns) {
|
||||
MemFree(dns);
|
||||
}
|
||||
|
||||
if (rc != XPL_DNS_SUCCESS) {
|
||||
/* We don't like the guy */
|
||||
blocked = TRUE;
|
||||
}
|
||||
|
||||
/* Store new value */
|
||||
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
|
||||
/*
|
||||
Insert the new value into the table. The time for a negative result is a
|
||||
full day. The time for a positive result is only 15 minutes however,
|
||||
because a positive result simply means that the servers do not know anything
|
||||
about the address.
|
||||
*/
|
||||
sqlite3_bind_int(RDNS.sqlite.stmt.add, 1, command->address);
|
||||
sqlite3_bind_text(RDNS.sqlite.stmt.add, 2, blocked ? RDNS.config.blockTimeout : RDNS.config.allowTimeout, -1, SQLITE_TRANSIENT);
|
||||
sqlite3_bind_int(RDNS.sqlite.stmt.add, 3, blocked);
|
||||
|
||||
sqlite3_step(RDNS.sqlite.stmt.add);
|
||||
|
||||
sqlite3_reset(RDNS.sqlite.stmt.add);
|
||||
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
}
|
||||
|
||||
if (blocked) {
|
||||
/* He was blocked by RDNS */
|
||||
strncpy(result->comment, CM_COMMENT, sizeof(result->comment));
|
||||
}
|
||||
|
||||
result->detail.connect.requireAuth = blocked;
|
||||
return(CM_MODULE_ACCEPT);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
TransactionController(void *ignored)
|
||||
{
|
||||
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
if (sqlite3_exec(RDNS.sqlite.handle, SQL_BEGIN, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
XplConsolePrintf("cmrdns: Failed to start transaction controller\n");
|
||||
}
|
||||
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
|
||||
while (!RDNSUnloadOk) {
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < 15 && !RDNSUnloadOk; i++) {
|
||||
XplDelay(1000);
|
||||
}
|
||||
|
||||
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
if (sqlite3_exec(RDNS.sqlite.handle, SQL_SAVE, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
XplConsolePrintf("cmrdns: Failed to save cache data\n");
|
||||
}
|
||||
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
}
|
||||
|
||||
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
if (sqlite3_exec(RDNS.sqlite.handle, SQL_END, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
XplConsolePrintf("cmrdns: Failed to end transaction controller\n");
|
||||
}
|
||||
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
CMRDNSInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
|
||||
{
|
||||
if (RDNSUnloadOk == TRUE) {
|
||||
XplSafeWrite(RDNS.threadCount, 0);
|
||||
|
||||
RDNS.directoryHandle = (MDBHandle) MsgInit();
|
||||
if (RDNS.directoryHandle) {
|
||||
RDNSUnloadOk = FALSE;
|
||||
|
||||
RDNS.logHandle = LoggerOpen("cmrdns");
|
||||
if (RDNS.logHandle == NULL) {
|
||||
XplConsolePrintf("cmrdns: Unable to initialize logging. Logging disabled.\r\n");
|
||||
}
|
||||
|
||||
/* Fill out registration information */
|
||||
registration->priority = 1; /* It is important that the rdns are early */
|
||||
registration->Shutdown = RDNSShutdown;
|
||||
registration->Verify = RDNSVerify;
|
||||
registration->Notify = NULL;
|
||||
|
||||
XplSafeIncrement(RDNS.threadCount);
|
||||
|
||||
strcpy(RDNS.config.datadir, datadir);
|
||||
|
||||
XplOpenLocalSemaphore(RDNS.sqlite.semaphore, 1);
|
||||
|
||||
if (ReadConfiguration()) {
|
||||
unsigned char buffer[XPL_MAX_PATH + 1];
|
||||
int ccode;
|
||||
XplThreadID id;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s/cache.db", datadir);
|
||||
if (sqlite3_open(buffer, &RDNS.sqlite.handle) != SQLITE_OK) {
|
||||
printf("cmrdns: Failed to open database: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
|
||||
}
|
||||
|
||||
if (sqlite3_exec(RDNS.sqlite.handle, SQL_CREATE, NULL, NULL, NULL) != SQLITE_OK) {
|
||||
#if 0
|
||||
printf("bongogatekeeper: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
|
||||
#endif
|
||||
sqlite3_exec(RDNS.sqlite.handle, SQL_ROLLBACK, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if ((sqlite3_prepare(RDNS.sqlite.handle, SQL_ADD, -1, &RDNS.sqlite.stmt.add, 0) != SQLITE_OK) ||
|
||||
(sqlite3_prepare(RDNS.sqlite.handle, SQL_GET, -1, &RDNS.sqlite.stmt.get, 0) != SQLITE_OK) ||
|
||||
(sqlite3_prepare(RDNS.sqlite.handle, SQL_CLEAN, -1, &RDNS.sqlite.stmt.clean,0) != SQLITE_OK))
|
||||
{
|
||||
printf("cmrdns: Failed to prepare sql: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
|
||||
}
|
||||
|
||||
/* Begin the transaction controller thread */
|
||||
XplBeginThread(&id, TransactionController, (1024 * 32), NULL, ccode);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
} else {
|
||||
XplConsolePrintf("cmrdns: Failed to obtain directory handle\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
RDNSShutdown(void)
|
||||
{
|
||||
XplSafeDecrement(RDNS.threadCount);
|
||||
|
||||
if (RDNSUnloadOk == FALSE) {
|
||||
RDNSUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library rdns are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(RDNS.threadCount)) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
LoggerClose(RDNS.logHandle);
|
||||
|
||||
sqlite3_finalize(RDNS.sqlite.stmt.add);
|
||||
sqlite3_finalize(RDNS.sqlite.stmt.get);
|
||||
sqlite3_finalize(RDNS.sqlite.stmt.clean);
|
||||
|
||||
sqlite3_close(RDNS.sqlite.handle);
|
||||
XplCloseLocalSemaphore(RDNS.sqlite.semaphore);
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(RDNS.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(RDNS.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ReadConfiguration(void)
|
||||
{
|
||||
MDBValueStruct *config;
|
||||
|
||||
config = MDBCreateValueStruct(RDNS.directoryHandle, MsgGetServerDN(NULL));
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_DISABLED, config)) {
|
||||
if (atol(config->Value[0]) == 1) {
|
||||
MDBDestroyValueStruct(config);
|
||||
RDNSShutdown();
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_CONFIG_CHANGED, config)) {
|
||||
RDNS.config.last = atol(config->Value[0]);
|
||||
MDBFreeValues(config);
|
||||
} else {
|
||||
RDNS.config.last = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Store the timeout strings. It is faster to do this once, instead of storing the long value
|
||||
and creating the string each time, since it must be a string that is bound to the SQL statement.
|
||||
*/
|
||||
snprintf(RDNS.config.blockTimeout, sizeof(RDNS.config.blockTimeout), "%d minutes", (3 * 60)); /* Default to 3 hours */
|
||||
snprintf(RDNS.config.allowTimeout, sizeof(RDNS.config.blockTimeout), "%d minutes", (3 * 60)); /* Default to 3 hours */
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_CONFIGURATION, config) > 0) {
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < config->Used; i++) {
|
||||
if (XplStrNCaseCmp(config->Value[i], BLOCK_TIMEOUT_PREFIX, sizeof(BLOCK_TIMEOUT_PREFIX) - 1) == 0) {
|
||||
snprintf(RDNS.config.blockTimeout, sizeof(RDNS.config.blockTimeout), "%lu minutes", atol(config->Value[i] + sizeof(BLOCK_TIMEOUT_PREFIX) - 1));
|
||||
} else if (XplStrNCaseCmp(config->Value[i], ALLOW_TIMEOUT_PREFIX, sizeof(ALLOW_TIMEOUT_PREFIX) - 1) == 0) {
|
||||
snprintf(RDNS.config.allowTimeout, sizeof(RDNS.config.allowTimeout), "%lu minutes", atol(config->Value[i] + sizeof(ALLOW_TIMEOUT_PREFIX) - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MDBDestroyValueStruct(config);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
Below are "stock" functions that are basically infrastructure.
|
||||
However, one might want to add initialization code to main
|
||||
and takedown code to the signal handler
|
||||
*/
|
||||
void
|
||||
RDNSShutdownSigHandler(int Signal)
|
||||
{
|
||||
int oldtgid = XplSetThreadGroupID(RDNS.tgid);
|
||||
|
||||
if (RDNSUnloadOk == FALSE) {
|
||||
RDNSUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library rdns are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(RDNS.threadCount) > 1) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
/* Do any required cleanup */
|
||||
LoggerClose(RDNS.logHandle);
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(RDNS.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(RDNS.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
XplSetThreadGroupID(oldtgid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
_NonAppCheckUnload(void)
|
||||
{
|
||||
if (RDNSUnloadOk == FALSE) {
|
||||
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
|
||||
XplConsolePrintf("\rIt does not allow manual unloading.\n");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* init globals */
|
||||
RDNS.tgid = XplGetThreadGroupID();
|
||||
|
||||
XplRenameThread(GetThreadID(), "Gate Keeper RDNS Module");
|
||||
XplOpenLocalSemaphore(RDNS.shutdownSemaphore, 0);
|
||||
XplSignalHandler(RDNSShutdownSigHandler);
|
||||
|
||||
/*
|
||||
This will "park" the module 'til we get unloaded;
|
||||
it would not be neccessary to do this on NetWare,
|
||||
but to prevent from automatically exiting on Unix
|
||||
we need to keep main around...
|
||||
*/
|
||||
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore);
|
||||
XplSignalLocalSemaphore(RDNS.shutdownSemaphore);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <mdb.h>
|
||||
#include <logger.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <connmgr.h>
|
||||
|
||||
#define PRODUCT_SHORT_NAME "cmrdns.nlm"
|
||||
#define PRODUCT_NAME "Bongo Connection Manager Reverse DNS Module"
|
||||
|
||||
#define CM_COMMENT "Your computer does not have a hostname, access blocked"
|
||||
|
||||
typedef struct _RDNSGlobal {
|
||||
/* Handles */
|
||||
void *logHandle;
|
||||
MDBHandle directoryHandle;
|
||||
|
||||
/* Module State */
|
||||
time_t timeStamp;
|
||||
int tgid;
|
||||
BOOL unloadOK;
|
||||
XplSemaphore shutdownSemaphore;
|
||||
XplAtomic threadCount;
|
||||
|
||||
struct {
|
||||
long last;
|
||||
|
||||
unsigned char datadir[XPL_MAX_PATH + 1];
|
||||
unsigned char blockTimeout[256];
|
||||
unsigned char allowTimeout[256];
|
||||
} config;
|
||||
|
||||
struct {
|
||||
sqlite3 *handle;
|
||||
XplSemaphore semaphore;
|
||||
|
||||
struct {
|
||||
sqlite3_stmt *add;
|
||||
sqlite3_stmt *get;
|
||||
sqlite3_stmt *clean;
|
||||
} stmt;
|
||||
} sqlite;
|
||||
} RDNSGlobal;
|
||||
|
||||
extern RDNSGlobal RDNS;
|
||||
|
||||
/* cmrdns.c */
|
||||
void RDNSShutdownSigHandler(int Signal);
|
||||
int _NonAppCheckUnload(void);
|
||||
|
||||
EXPORT BOOL CMRDNSInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
|
||||
EXPORT BOOL RDNSShutdown(void);
|
||||
EXPORT int RDNSVerify(ConnMgrCommand *command, ConnMgrResult *result);
|
||||
|
||||
/* Config Prefixes */
|
||||
#define BLOCK_TIMEOUT_PREFIX "RDNSBlockTimeout:"
|
||||
#define ALLOW_TIMEOUT_PREFIX "RDNSAllowTimeout:"
|
||||
|
||||
/* SQL */
|
||||
#define SQL_CREATE "BEGIN TRANSACTION;" \
|
||||
"CREATE TABLE cache (" \
|
||||
"ip INTEGER PRIMARY KEY NOT NULL," \
|
||||
"timeout DATETIME," \
|
||||
"block BOOL" \
|
||||
");" \
|
||||
"CREATE INDEX timeout_idx ON cache (timeout);" \
|
||||
"END TRANSACTION;"
|
||||
|
||||
#define SQL_ROLLBACK "ROLLBACK;"
|
||||
|
||||
#define SQL_ADD "INSERT OR REPLACE INTO cache (ip, timeout, block) VALUES (?, DATETIME('now', ?), ?);"
|
||||
#define SQL_GET "SELECT block FROM cache WHERE ip=? AND julianday('now') < julianday(timeout);"
|
||||
#define SQL_CLEAN "DELETE FROM cache WHERE julianday('now') >= julianday(timeout);"
|
||||
|
||||
#define SQL_BEGIN "BEGIN TRANSACTION;"
|
||||
#define SQL_END "END TRANSACTION;"
|
||||
#define SQL_SAVE SQL_CLEAN SQL_END SQL_BEGIN
|
||||
@@ -1,19 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmuser.la
|
||||
|
||||
libcmuser_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/user/cmuser.c \
|
||||
src/agents/connmgr/cmmodules/user/cmuser.h
|
||||
|
||||
libcmuser_la_LDFLAGS := -module -avoid-version
|
||||
libcmuser_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/user/cmuser/all: libcmuser.la
|
||||
src/agents/connmgr/cmmodules/user/cmuser/clean: clean
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -1,293 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <xplresolve.h>
|
||||
#include <mdb.h>
|
||||
#include <msgapi.h>
|
||||
|
||||
#include "cmuser.h"
|
||||
|
||||
/* Globals */
|
||||
BOOL UserUnloadOk = TRUE;
|
||||
UserGlobal User;
|
||||
|
||||
static BOOL ReadConfiguration(void);
|
||||
static void Cleanup(void *param);
|
||||
|
||||
|
||||
EXPORT BOOL UserNotify(ConnMgrCommand *command)
|
||||
{
|
||||
/*
|
||||
CM_EVENT_AUTHENTICATED
|
||||
When receieved, create a file in datadir where the name is the ip address
|
||||
and the conntent is the username.
|
||||
*/
|
||||
|
||||
if (XplStrCaseCmp(command->event, CM_EVENT_AUTHENTICATED) == 0) {
|
||||
unsigned char buffer[XPL_MAX_PATH + 1];
|
||||
FILE *addr;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s/%07lx", User.config.datadir, command->address);
|
||||
addr = fopen(buffer, "w");
|
||||
if (addr) {
|
||||
fwrite(command->detail.authenticated.user, sizeof(unsigned char), strlen(command->detail.authenticated.user), addr);
|
||||
fclose(addr);
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
EXPORT int UserVerify(ConnMgrCommand *command, ConnMgrResult *result)
|
||||
{
|
||||
/*
|
||||
CM_EVENT_RELAY
|
||||
When received, look for a file in datadir with the ip address as the
|
||||
name, and read the user from the content of the file. Check the time
|
||||
of the file to see if it has expired.
|
||||
*/
|
||||
if (XplStrCaseCmp(command->event, CM_EVENT_RELAY) == 0) {
|
||||
unsigned char buffer[XPL_MAX_PATH + 1];
|
||||
struct stat sb;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s/%07lx", User.config.datadir, command->address);
|
||||
if (stat(buffer, &sb) != -1) {
|
||||
if (sb.st_mtime > time(NULL) - (User.config.timeout * 60)) {
|
||||
FILE *addr = fopen(buffer, "r");
|
||||
|
||||
if (addr) {
|
||||
int l = fread(result->detail.user, sizeof(unsigned char), MAXEMAILNAMESIZE, addr);
|
||||
result->detail.user[l] = '\0';
|
||||
|
||||
fclose(addr);
|
||||
return(CM_MODULE_ACCEPT);
|
||||
}
|
||||
} else {
|
||||
unlink(buffer);
|
||||
}
|
||||
}
|
||||
return(CM_MODULE_DENY);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
CMUSERInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
|
||||
{
|
||||
if (UserUnloadOk == TRUE) {
|
||||
XplSafeWrite(User.threadCount, 0);
|
||||
|
||||
User.directoryHandle = (MDBHandle) MsgInit();
|
||||
if (User.directoryHandle) {
|
||||
UserUnloadOk = FALSE;
|
||||
|
||||
User.logHandle = LoggerOpen("cmuser");
|
||||
if (User.logHandle == NULL) {
|
||||
XplConsolePrintf("cmuser: Unable to initialize logging. Logging disabled.\r\n");
|
||||
}
|
||||
|
||||
/* Fill out registration information */
|
||||
registration->priority = 5;
|
||||
registration->Shutdown = UserShutdown;
|
||||
registration->Verify = UserVerify;
|
||||
registration->Notify = UserNotify;
|
||||
|
||||
XplSafeIncrement(User.threadCount);
|
||||
|
||||
strcpy(User.config.datadir, datadir);
|
||||
|
||||
if (ReadConfiguration()) {
|
||||
XplThreadID id;
|
||||
int ccode;
|
||||
|
||||
XplBeginThread(&id, Cleanup, (1024 * 32), NULL, ccode);
|
||||
return(TRUE);
|
||||
}
|
||||
} else {
|
||||
XplConsolePrintf("cmuser: Failed to obtain directory handle\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
UserShutdown(void)
|
||||
{
|
||||
XplSafeDecrement(User.threadCount);
|
||||
|
||||
if (UserUnloadOk == FALSE) {
|
||||
UserUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library users are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(User.threadCount)) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
LoggerClose(User.logHandle);
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(User.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(User.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(User.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ReadConfiguration(void)
|
||||
{
|
||||
MDBValueStruct *config;
|
||||
|
||||
config = MDBCreateValueStruct(User.directoryHandle, MsgGetServerDN(NULL));
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_DISABLED, config)) {
|
||||
if (atol(config->Value[0]) == 1) {
|
||||
MDBDestroyValueStruct(config);
|
||||
UserShutdown();
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_CONFIG_CHANGED, config)) {
|
||||
User.config.last = atol(config->Value[0]);
|
||||
MDBFreeValues(config);
|
||||
} else {
|
||||
User.config.last = 0;
|
||||
}
|
||||
|
||||
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_TIMEOUT, config)) {
|
||||
User.config.timeout = atol(config->Value[0]);
|
||||
} else {
|
||||
User.config.timeout = 15;
|
||||
}
|
||||
|
||||
MDBDestroyValueStruct(config);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
Cleanup(void *param)
|
||||
{
|
||||
while (!UserUnloadOk) {
|
||||
int i;
|
||||
XplDir *dir;
|
||||
XplDir *dirent;
|
||||
struct stat sb;
|
||||
|
||||
if ((dir = XplOpenDir(User.config.datadir)) != NULL) {
|
||||
while ((dirent = XplReadDir(dir)) != NULL) {
|
||||
unsigned char buffer[XPL_MAX_PATH +1 ];
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "%s/%s", User.config.datadir, dirent->d_nameDOS);
|
||||
if ((stat(buffer, &sb) != -1) && (sb.st_mtime < time(NULL) - (User.config.timeout * 60))) {
|
||||
unlink(buffer);
|
||||
}
|
||||
}
|
||||
XplCloseDir(dir);
|
||||
}
|
||||
|
||||
for (i = 0; i < (User.config.timeout * 60) && !UserUnloadOk; i++) {
|
||||
XplDelay(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Below are "stock" functions that are basically infrastructure.
|
||||
However, one might want to add initialization code to main
|
||||
and takedown code to the signal handler
|
||||
*/
|
||||
void
|
||||
UserShutdownSigHandler(int Signal)
|
||||
{
|
||||
int oldtgid = XplSetThreadGroupID(User.tgid);
|
||||
|
||||
if (UserUnloadOk == FALSE) {
|
||||
UserUnloadOk = TRUE;
|
||||
|
||||
/*
|
||||
Make sure the library users are gone before beginning to
|
||||
shutdown.
|
||||
*/
|
||||
while (XplSafeRead(User.threadCount) > 1) {
|
||||
XplDelay(33);
|
||||
}
|
||||
|
||||
/* Do any required cleanup */
|
||||
LoggerClose(User.logHandle);
|
||||
|
||||
#if defined(NETWARE) || defined(LIBC)
|
||||
XplSignalLocalSemaphore(User.shutdownSemaphore); /* The signal will release main() */
|
||||
XplWaitOnLocalSemaphore(User.shutdownSemaphore); /* The wait will wait until main() is gone */
|
||||
|
||||
XplCloseLocalSemaphore(User.shutdownSemaphore);
|
||||
#endif
|
||||
}
|
||||
|
||||
XplSetThreadGroupID(oldtgid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
_NonAppCheckUnload(void)
|
||||
{
|
||||
if (UserUnloadOk == FALSE) {
|
||||
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
|
||||
XplConsolePrintf("\rIt does not allow manual unloading.\n");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* init globals */
|
||||
User.tgid = XplGetThreadGroupID();
|
||||
|
||||
XplRenameThread(GetThreadID(), "Gate Keeper User Module");
|
||||
XplOpenLocalSemaphore(User.shutdownSemaphore, 0);
|
||||
XplSignalHandler(UserShutdownSigHandler);
|
||||
|
||||
/*
|
||||
This will "park" the module 'til we get unloaded;
|
||||
it would not be neccessary to do this on NetWare,
|
||||
but to prevent from automatically exiting on Unix
|
||||
we need to keep main around...
|
||||
*/
|
||||
XplWaitOnLocalSemaphore(User.shutdownSemaphore);
|
||||
XplSignalLocalSemaphore(User.shutdownSemaphore);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <mdb.h>
|
||||
#include <logger.h>
|
||||
|
||||
#include <connmgr.h>
|
||||
|
||||
#define PRODUCT_SHORT_NAME "cmuser.nlm"
|
||||
#define PRODUCT_NAME "Bongo Connection Manager User Authentication Module"
|
||||
|
||||
typedef struct _UserGlobal {
|
||||
/* Handles */
|
||||
void *logHandle;
|
||||
MDBHandle directoryHandle;
|
||||
|
||||
/* Module State */
|
||||
time_t timeStamp;
|
||||
int tgid;
|
||||
BOOL unloadOK;
|
||||
XplSemaphore shutdownSemaphore;
|
||||
XplAtomic threadCount;
|
||||
|
||||
struct {
|
||||
long last;
|
||||
|
||||
long timeout;
|
||||
unsigned char datadir[XPL_MAX_PATH + 1];
|
||||
} config;
|
||||
} UserGlobal;
|
||||
|
||||
extern UserGlobal User;
|
||||
|
||||
/* cmuser.c */
|
||||
void UserShutdownSigHandler(int Signal);
|
||||
int _NonAppCheckUnload(void);
|
||||
|
||||
EXPORT BOOL CMUSERInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
|
||||
EXPORT BOOL UserShutdown(void);
|
||||
EXPORT BOOL UserNotify(ConnMgrCommand *command);
|
||||
EXPORT int UserVerify(ConnMgrCommand *command, ConnMgrResult *result);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,42 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <connmgr.h>
|
||||
|
||||
#define CONNMGR_STACK_SPACE (1024 * 32)
|
||||
#define CONNECTION_TIMEOUT (15 * 60)
|
||||
|
||||
/* modules.c */
|
||||
typedef struct _ModuleStruct {
|
||||
struct _CMModuleRegistrationStruct registration;
|
||||
|
||||
CMInitFunc Init;
|
||||
XplPluginHandle handle;
|
||||
struct _ModuleStruct *next;
|
||||
unsigned char *name;
|
||||
} ModuleStruct;
|
||||
|
||||
|
||||
void ModulesVerify(ModuleStruct *first, ConnMgrCommand *command, ConnMgrResult *result);
|
||||
void ModulesNotify(ModuleStruct *first, ConnMgrCommand *command);
|
||||
ModuleStruct * LoadModules(unsigned char *directory, ModuleStruct *first);
|
||||
void UnloadModules(ModuleStruct *first);
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
|
||||
#include <bongoutil.h>
|
||||
#include <msgapi.h>
|
||||
|
||||
#include "connmgrp.h"
|
||||
|
||||
void
|
||||
ModulesVerify(ModuleStruct *first, ConnMgrCommand *command, ConnMgrResult *result)
|
||||
{
|
||||
ModuleStruct *module = first;
|
||||
result->result = command->detail.policy.default_result;
|
||||
|
||||
while (module) {
|
||||
if (module->registration.Verify) {
|
||||
int rc = module->registration.Verify(command, result);
|
||||
|
||||
if (rc & CM_MODULE_DENY) {
|
||||
if (rc & CM_MODULE_PERMANENT) {
|
||||
result->result = CM_RESULT_DENY_PERMANENT;
|
||||
} else {
|
||||
result->result = CM_RESULT_DENY_TEMPORARY;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc & CM_MODULE_FORCE) {
|
||||
if (rc & CM_MODULE_ACCEPT) {
|
||||
result->result = CM_RESULT_ALLOWED;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
module = module->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ModulesNotify(ModuleStruct *first, ConnMgrCommand *command)
|
||||
{
|
||||
ModuleStruct *module = first;
|
||||
|
||||
while (module) {
|
||||
if (module->registration.Notify) {
|
||||
module->registration.Notify(command);
|
||||
}
|
||||
|
||||
module = module->next;
|
||||
}
|
||||
}
|
||||
|
||||
ModuleStruct *
|
||||
LoadModules(unsigned char *directory, ModuleStruct *first)
|
||||
{
|
||||
XplDir *dir;
|
||||
XplDir *dirent;
|
||||
ModuleStruct *result = first;
|
||||
|
||||
XplMakeDir(XPL_DEFAULT_DBF_DIR "//connmgr");
|
||||
|
||||
if ((dir = XplOpenDir(directory)) != NULL) {
|
||||
while ((dirent = XplReadDir(dir)) != NULL) {
|
||||
unsigned char path[XPL_MAX_PATH +1 ];
|
||||
unsigned char name[XPL_MAX_PATH + 1];
|
||||
unsigned char *modulename = dirent->d_nameDOS;
|
||||
ModuleStruct *new = MemMalloc(sizeof(ModuleStruct));
|
||||
unsigned char datadir[XPL_MAX_PATH + 1];
|
||||
|
||||
memset(new, 0, sizeof(ModuleStruct));
|
||||
|
||||
if (strlen(modulename) > 3) {
|
||||
snprintf(path, sizeof(path), "%s/lib%s", directory, modulename);
|
||||
new->handle = XplLoadDLL(path);
|
||||
|
||||
if (!new->handle) {
|
||||
snprintf(path, sizeof(path), "%s/%s", directory, modulename);
|
||||
new->handle = XplLoadDLL(path);
|
||||
}
|
||||
|
||||
if (new->handle) {
|
||||
unsigned char *ptr;
|
||||
|
||||
/* Initialize the module */
|
||||
if (XplStrNCaseCmp(modulename, "lib", 3) == 0) {
|
||||
BongoStrNCpy(name, modulename + 3, sizeof(name) - strlen("Init"));
|
||||
} else {
|
||||
BongoStrNCpy(name, modulename, sizeof(name) - strlen("Init"));
|
||||
}
|
||||
|
||||
ptr = strrchr(name, '.');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
/* Setup the work directory for the module */
|
||||
ptr = name;
|
||||
while (*ptr) {
|
||||
*ptr = tolower(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
sprintf(datadir, "%s/connmgr/%s", XPL_DEFAULT_DBF_DIR, name);
|
||||
XplMakeDir(datadir);
|
||||
|
||||
ptr = name;
|
||||
while (*ptr) {
|
||||
*ptr = toupper(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
strcat(name, "Init");
|
||||
new->Init = (CMInitFunc)XplGetDLLFunction(modulename, name, new->handle);
|
||||
name[strlen(name) - 4] = '\0';
|
||||
#if 0
|
||||
} else {
|
||||
/* dlerror() is much more useful when dlopen fails than errno is */
|
||||
unsigned char *err = dlerror();
|
||||
if (err) {
|
||||
XplConsolePrintf("connmgr: XplLoadDLL failed: %s\n", err);
|
||||
}
|
||||
XplConsolePrintf("connmgr: could not load module %s/%s, errno: %d %s\n", directory, modulename, errno, strerror(errno));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (new->Init && new->Init(&(new->registration), datadir)) {
|
||||
new->name = MemStrdup(name);
|
||||
|
||||
#if VERBOSE
|
||||
XplConsolePrintf("connmgr: loaded module: %s\n", new->name);
|
||||
#endif
|
||||
|
||||
if (!result) {
|
||||
result = new;
|
||||
} else if (result->registration.priority > new->registration.priority) {
|
||||
new->next = result;
|
||||
result = new;
|
||||
} else {
|
||||
ModuleStruct *n = result;
|
||||
|
||||
/* Find a spot for it */
|
||||
while (n && n->next) {
|
||||
if (n->next->registration.priority > new->registration.priority) {
|
||||
new->next = n->next;
|
||||
n->next = new;
|
||||
n = NULL;
|
||||
}
|
||||
|
||||
if (n) {
|
||||
n = n->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (n) {
|
||||
n->next = new;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MemFree(new);
|
||||
}
|
||||
}
|
||||
|
||||
XplCloseDir(dir);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
void
|
||||
UnloadModules(ModuleStruct *first)
|
||||
{
|
||||
ModuleStruct *module = first;
|
||||
|
||||
while (module) {
|
||||
ModuleStruct *next = module->next;
|
||||
|
||||
if (module->registration.Shutdown) {
|
||||
module->registration.Shutdown();
|
||||
}
|
||||
|
||||
if (module->handle && module->name) {
|
||||
XplUnloadDLL(module->name, module->handle);
|
||||
MemFree(module->name);
|
||||
}
|
||||
|
||||
MemFree(module);
|
||||
module = next;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
lib_LTLIBRARIES += libbongoconnmgr.la
|
||||
|
||||
#libbongonmap_la_LDFLAGS := -static
|
||||
libbongoconnmgr_la_SOURCES := \
|
||||
src/libs/connmgr/connmgr.c \
|
||||
src/libs/connmgr/hashcred.c
|
||||
|
||||
src/libs/connmgr/all: libbongoconnmgr.la
|
||||
src/libs/connmgr/clean: clean
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -1,342 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <bongoutil.h>
|
||||
|
||||
#include <memmgr.h>
|
||||
|
||||
#include <cmlib.h>
|
||||
#include <connmgr.h>
|
||||
#include <msgapi.h>
|
||||
|
||||
struct {
|
||||
unsigned char access[CM_HASH_SIZE];
|
||||
unsigned char pass[XPLHASH_MD5_LENGTH];
|
||||
MDBHandle directoryHandle;
|
||||
|
||||
BOOL debug;
|
||||
unsigned long address;
|
||||
|
||||
XplRWLock lock;
|
||||
unsigned char service[16 + 1];
|
||||
} CMLibrary = {
|
||||
{ '\0' },
|
||||
{ '\0' },
|
||||
NULL,
|
||||
|
||||
FALSE
|
||||
};
|
||||
|
||||
BOOL
|
||||
CMSendCommand(ConnMgrCommand *command, ConnMgrResult *result)
|
||||
{
|
||||
struct sockaddr_in fromSin;
|
||||
struct sockaddr_in toSin;
|
||||
int sock;
|
||||
int tries = 0;
|
||||
|
||||
do {
|
||||
result->result = CM_RESULT_UNKNOWN_ERROR;
|
||||
|
||||
XplRWReadLockAcquire(&CMLibrary.lock);
|
||||
strcpy(command->pass, CMLibrary.pass);
|
||||
XplRWReadLockRelease(&CMLibrary.lock);
|
||||
|
||||
memset(&fromSin, 0, sizeof(struct sockaddr_in));
|
||||
memset(&toSin, 0, sizeof(struct sockaddr_in));
|
||||
sock = IPsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock >= 0) {
|
||||
toSin.sin_family = AF_INET;
|
||||
toSin.sin_addr.s_addr = CMLibrary.address;
|
||||
toSin.sin_port = htons(CM_PORT);
|
||||
|
||||
fromSin.sin_family = AF_INET;
|
||||
fromSin.sin_addr.s_addr = 0;
|
||||
fromSin.sin_port = 0;
|
||||
|
||||
if (IPbind(sock, (struct sockaddr *)&fromSin, sizeof(fromSin)) == 0) {
|
||||
sendto(sock, (unsigned char *)command, sizeof(ConnMgrCommand), 0, (struct sockaddr*)&toSin, sizeof(toSin));
|
||||
XplIPRead(XPL_INT_TO_PTR(sock), (unsigned char *)result, sizeof(ConnMgrResult), 19);
|
||||
}
|
||||
IPclose(sock);
|
||||
}
|
||||
|
||||
if (result->result == CM_RESULT_MUST_AUTH) {
|
||||
xpl_hash_context ctx;
|
||||
|
||||
// Ensure that we don't walk off the edge of the buffer if garbage was sent
|
||||
result->detail.salt[sizeof(result->detail.salt) - 1] = '\0';
|
||||
|
||||
XplHashNew(&ctx, XPLHASH_MD5);
|
||||
XplHashWrite(&ctx, result->detail.salt, strlen(result->detail.salt));
|
||||
XplHashWrite(&ctx, CMLibrary.access, CM_HASH_SIZE);
|
||||
XplHashFinal(&ctx, XPLHASH_LOWERCASE, command->pass, XPLHASH_MD5_LENGTH);
|
||||
|
||||
/* Store the password so we don't have to generate it every time */
|
||||
XplRWWriteLockAcquire(&CMLibrary.lock);
|
||||
strcpy(CMLibrary.pass, command->pass);
|
||||
XplRWWriteLockRelease(&CMLibrary.lock);
|
||||
} else {
|
||||
return(TRUE);
|
||||
}
|
||||
} while (tries++ < 3);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
CMVerifyConnect(unsigned long address, unsigned char *comment, BOOL *requireAuth)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_VERIFY;
|
||||
strcpy(command.event, CM_EVENT_CONNECT);
|
||||
command.address = address;
|
||||
command.detail.policy.default_result = CM_RESULT_ALLOWED;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
|
||||
if (result.comment[0] != '\0') {
|
||||
strncpy(comment, result.comment, sizeof(result.comment));
|
||||
} else {
|
||||
comment[0] = '\0';
|
||||
}
|
||||
|
||||
if (requireAuth) {
|
||||
*requireAuth = result.detail.connect.requireAuth;
|
||||
}
|
||||
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMVerifyRelay(unsigned long address, unsigned char *user)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_VERIFY;
|
||||
strcpy(command.event, CM_EVENT_RELAY);
|
||||
command.address = address;
|
||||
command.detail.policy.default_result = CM_RESULT_MUST_AUTH;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
|
||||
if (result.result == CM_RESULT_ALLOWED && user) {
|
||||
strncpy(user, result.detail.user, MAXEMAILNAMESIZE);
|
||||
} else {
|
||||
user[0] = '\0';
|
||||
}
|
||||
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMDisconnected(unsigned long address)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_DISCONNECTED);
|
||||
command.address = address;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMAuthenticated(unsigned long address, unsigned char *user)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_AUTHENTICATED);
|
||||
command.address = address;
|
||||
|
||||
if (user) {
|
||||
strncpy(command.detail.authenticated.user, user, MAXEMAILNAMESIZE);
|
||||
} else {
|
||||
command.detail.authenticated.user[0] = '\0';
|
||||
}
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMDelivered(unsigned long address, unsigned long recipients)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_DELIVERED);
|
||||
command.address = address;
|
||||
command.detail.delivered.recipients = recipients;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMReceived(unsigned long address, unsigned long local, unsigned long invalid, unsigned long remote)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_RECEIVED);
|
||||
command.address = address;
|
||||
|
||||
command.detail.received.local = local;
|
||||
command.detail.received.invalid = invalid;
|
||||
command.detail.received.remote = remote;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMFoundVirus(unsigned long address, unsigned long recipients, unsigned char *name)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_VIRUS_FOUND);
|
||||
command.address = address;
|
||||
command.detail.virus.recipients = recipients;
|
||||
|
||||
if (name) {
|
||||
strncpy(command.detail.virus.name, name, 256);
|
||||
} else {
|
||||
command.detail.virus.name[0] = '\0';
|
||||
}
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMSpamFound(unsigned long address, unsigned long recipients)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_SPAM_FOUND);
|
||||
command.address = address;
|
||||
command.detail.spam.recipients = recipients;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMDOSDetected(unsigned long address, unsigned char *description)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_DOS_DETECTED);
|
||||
command.address = address;
|
||||
|
||||
if (description) {
|
||||
strncpy(command.detail.dos.description, description, 256);
|
||||
} else {
|
||||
command.detail.dos.description[0] = '\0';
|
||||
}
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
BOOL
|
||||
CMInitialize(MDBHandle directoryHandle, unsigned char *service)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (directoryHandle) {
|
||||
MDBValueStruct *v;
|
||||
|
||||
CMLibrary.directoryHandle = directoryHandle;
|
||||
|
||||
v = MDBCreateValueStruct(CMLibrary.directoryHandle, NULL);
|
||||
if (v) {
|
||||
MDBRead(MSGSRV_ROOT, MSGSRV_A_ACL, v);
|
||||
if (v->Used) {
|
||||
result = HashCredential(MsgGetServerDN(NULL), v->Value[0], CMLibrary.access);
|
||||
}
|
||||
|
||||
MDBFreeValues(v);
|
||||
|
||||
if (MsgReadIP((unsigned char *) MsgGetServerDN(NULL), MSGSRV_A_CONNMGR, v)) {
|
||||
CMLibrary.address = inet_addr(v->Value[0]);
|
||||
}
|
||||
|
||||
MDBDestroyValueStruct(v);
|
||||
}
|
||||
|
||||
XplRWLockInit(&CMLibrary.lock);
|
||||
}
|
||||
|
||||
if (service) {
|
||||
strncpy(CMLibrary.service, service, 16);
|
||||
CMLibrary.service[16] = '\0';
|
||||
} else {
|
||||
CMLibrary.service[0] = '\0';
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of version 2 of the GNU General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, contact Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail, you
|
||||
* may find current contact information at www.novell.com.
|
||||
* </Novell-copyright>
|
||||
****************************************************************************/
|
||||
|
||||
#if 0
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <msgapi.h>
|
||||
#include <gatekeeper.h>
|
||||
#include <gklib.h>
|
||||
|
||||
#define ORGANIZATION_BUFFER_SIZE 100
|
||||
|
||||
#define GK_CRED_STORE_SIZE 4096
|
||||
#define GK_CRED_DIGEST_SIZE 16
|
||||
#define GK_CRED_CHUNK_SIZE (GK_CRED_STORE_SIZE * GK_CRED_DIGEST_SIZE) / GK_HASH_SIZE
|
||||
|
||||
static BOOL
|
||||
GetOrgName(unsigned char *Organization)
|
||||
{
|
||||
unsigned long len;
|
||||
unsigned char *ptr;
|
||||
unsigned char *buffer;
|
||||
|
||||
/* get the treename */
|
||||
buffer = MemStrdup(MsgGetServerDN(NULL));
|
||||
if (buffer) {
|
||||
if (buffer[0] == '\\') {
|
||||
ptr = strchr(buffer + 1, '\\');
|
||||
if (ptr) {
|
||||
len = ptr - (buffer + 1);
|
||||
if (len > 0) {
|
||||
if (len < ORGANIZATION_BUFFER_SIZE) {
|
||||
*ptr = '\0';
|
||||
strcpy(Organization, buffer + 1);
|
||||
*ptr = '\\';
|
||||
} else {
|
||||
memcpy(Organization, buffer + 1, ORGANIZATION_BUFFER_SIZE);
|
||||
Organization[ORGANIZATION_BUFFER_SIZE] = '\0';
|
||||
}
|
||||
MemFree(buffer);
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemFree(buffer);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
BOOL
|
||||
HashCredential(unsigned char *Credential, unsigned char *Hash)
|
||||
{
|
||||
unsigned char organization[ORGANIZATION_BUFFER_SIZE + 1];
|
||||
unsigned char *ptr;
|
||||
unsigned long organizationLen;
|
||||
unsigned long len;
|
||||
|
||||
if (Hash && Credential) {
|
||||
len = strlen(Credential);
|
||||
if (GetOrgName(organization)) {
|
||||
organizationLen = strlen(organization);
|
||||
if (len >= GK_CRED_STORE_SIZE) {
|
||||
unsigned long i;
|
||||
MD5_CTX mdContext;
|
||||
unsigned char digest[GK_CRED_DIGEST_SIZE];
|
||||
unsigned char *srcPtr;
|
||||
unsigned char *dstPtr;
|
||||
unsigned char *dstEnd;
|
||||
|
||||
srcPtr = Credential;
|
||||
dstPtr = Hash;
|
||||
dstEnd = Hash + GK_HASH_SIZE;
|
||||
|
||||
MD5_Init(&mdContext);
|
||||
MD5_Update(&mdContext, srcPtr, GK_CRED_CHUNK_SIZE);
|
||||
MD5_Update(&mdContext, organization, organizationLen);
|
||||
MD5_Final(digest, &mdContext);
|
||||
|
||||
srcPtr += GK_CRED_CHUNK_SIZE;
|
||||
|
||||
for (i = 0; i < GK_CRED_DIGEST_SIZE; i++) {
|
||||
if (dstPtr < dstEnd) {
|
||||
*dstPtr = digest[i];
|
||||
dstPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
MD5_Init(&mdContext);
|
||||
MD5_Update(&mdContext, srcPtr, GK_CRED_CHUNK_SIZE);
|
||||
MD5_Update(&mdContext, Hash, dstPtr - Hash);
|
||||
MD5_Final(digest, &mdContext);
|
||||
|
||||
srcPtr += GK_CRED_CHUNK_SIZE;
|
||||
|
||||
for (i = 0; i < GK_CRED_DIGEST_SIZE; i++) {
|
||||
if (dstPtr < dstEnd) {
|
||||
*dstPtr = digest[i];
|
||||
dstPtr++;
|
||||
}
|
||||
}
|
||||
} while (dstPtr < dstEnd);
|
||||
|
||||
/* Hash now contains a non-terminated 128 byte octet string */
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
XplConsolePrintf("\rGate Keeper credentials are not properly configured!\r\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
XplConsolePrintf("\Bongo can not determine what organization it is running on.\r\n");
|
||||
return(FALSE);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user