/*
* ----------------------------------------------------------------
* Night Light IRC Proxy - Ident Daemon - Configuration Functions
* ----------------------------------------------------------------
* Copyright (C) 1997-2007 Jonas Kvinge <jonas@night-light.net>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Last modified by:
* Jonas Kvinge (25.11.2007)
*
*/
#define IDENT_CONF_C
#define NEED_SYS_TYPES_H 1 /* Extra types */
#define NEED_SYS_PARAM_H 1 /* Some systems need this */
#define NEED_LIMITS_H 0 /* Kernel limits */
#define NEED_STDARG_H 1 /* va_list, etc */
#define NEED_ERRNO_H 1 /* errno */
#define NEED_CTYPE_H 1 /* isdigit(), etc */
#define NEED_NETINET_IN_H 1 /* in_addr, sockaddr_in, etc */
#define NEED_ARPA_INET_H 0 /* inet_ntoa(), inet_aton(), etc */
#define NEED_STDIO_H 1 /* Standard C UNIX functions */
#define NEED_STDLIB_H 1 /* malloc(), exit(), atoi(), etc */
#define NEED_TIME_H 1 /* time(), etc */
#define NEED_SYSCTL_H 0 /* sysctl(), etc */
#define NEED_SYS_STAT_H 0 /* chmod(), mkdir(), etc */
#define NEED_SYS_UIO_H 0 /* iovec, etc */
#define NEED_FCNTL_H 1 /* open(), creat(), fcntl(), etc */
#define NEED_SYS_IOCTL_H 0 /* ioctl(), etc */
#define NEED_SYS_FILIO_H 0 /* Solaris need this for ioctl(), etc */
#define NEED_UNISTD_H 1 /* Unix standard functions */
#define NEED_STRING_H 1 /* C string functions */
#define NEED_SIGNAL_H 0 /* Signal functions */
#define NEED_SYS_SOCKET_H 0 /* Socket functions */
#define NEED_NETDB_H 0 /* Network database functions */
#define NEED_ARPA_NAMESER_H 0 /* Nameserver definitions */
#define NEED_GETUSERPW_HEADERS 0 /* Functions to retrive system passwords */
#define NEED_ARES 0 /* Functions needed for ares */
#define NEED_SSL 0 /* Needed for SSL support */
#include "includes.h"
#include "conf.h"
#include "ident_conf.h"
#include "ident_listen.h"
/* VARIABLES - JONAS (03.07.2003) */
struct IdentConf_Struct *IdentConf_Head = NULL;
struct IdentConf_Struct *IdentConf_Tail = NULL;
unsigned long int G_IdentConfs = 0;
char *Ident_Conf_DefaultUser = NULL;
extern struct Conf_Struct ConfS;
/* IDENT_CONF_READ FUNCTION - JONAS (03.07.2003) */
signed long int ident_conf_read(void) {
char File[FILELEN+1] = "";
FILE *FilePT = NULL;
char *TempPT = NULL;
char Line[LINELEN+1] = "";
char *LinePT = NULL;
unsigned short int Count = 0;
char *EntryPT = NULL;
char *DataPT = NULL;
unsigned short int Skip = 0;
DEBUGPRINT(BITMASK_DEBUG_CONF, "Reading ident configuration file.");
if (ConfS.IdentConfFile[0] != '/') {
strncat(File, ConfS.DataPath, FILELEN);
if (ConfS.DataPath[strlen(ConfS.DataPath)] != '/') { strncat(File, "/", (FILELEN - strlen(File))); }
}
strncat(File, ConfS.IdentConfFile, (FILELEN - strlen(File)));
FilePT = fopen(File, "r");
if (FilePT == NULL) {
sysprint(BITMASK_ERROR, "Unable to open ident configuration file %s: [%d] %s", File, errno, strerror(errno));
return(ERROR);
}
ident_conf_destroy();
FOREVERLOOP {
memset(&Line, 0, LINELEN+1);
TempPT = fgets(Line, LINELEN, FilePT);
if (TempPT == NULL) { break; }
++Count;
LinePT = Line;
while ((TempPT = strchr(LinePT, '\r')) != NULL) { *TempPT = '\0'; }
while ((TempPT = strchr(LinePT, '\n')) != NULL) { *TempPT = '\0'; }
while ((TempPT = strchr(LinePT, '\t')) != NULL) { *TempPT = ' '; }
while ((LinePT[0] == ' ') || (LinePT[0] == '\t')) { ++LinePT; }
if ((LinePT[0] == '#') || (LinePT[0] == ';') || (LinePT[0] == '\0')) { continue; }
EntryPT = LinePT;
StrMovePastToken(LinePT, ' ');
if (strcasecmp(EntryPT, "CONNECTION") == FALSE) { Skip = TRUE; continue; }
if (EntryPT[0] == '}') { Skip = FALSE; continue; }
if (Skip == TRUE) { continue; }
if (strcasecmp(EntryPT, "IDENTUNKNOWN") == FALSE) {
if (LinePT == NULL) {
sysprint(BITMASK_ERROR, "Ident configuration error, file %s line %d: Expecting \"USERNAME\" for DEFAULTUSER definition.", File, Count);
continue;
}
DataPT = LinePT;
StrMovePastToken(LinePT, ' ');
Ident_Conf_DefaultUser = strrealloc(Ident_Conf_DefaultUser, DataPT);
continue;
}
else if ((strcasecmp(EntryPT, "IDENT") == FALSE) || (strcasecmp(EntryPT, "IDENTIPV6") == FALSE)) {
char *HostPT = NULL;
char *PortPT = NULL;
unsigned long int Port = 0;
if (LinePT == NULL) {
sysprint(BITMASK_ERROR, "Ident configuration error, file %s line %d: Expecting \"HOST:PORT\" in LISTEN definition.", File, Count);
continue;
}
HostPT = LinePT;
StrMovePastToken(LinePT, ':');
PortPT = LinePT;
if (LinePT == NULL) {
sysprint(BITMASK_ERROR, "Ident configuration error, file %s line %d: Expecting \"HOST:PORT\" in LISTEN definition.", File, Count);
continue;
}
StrMovePastToken(LinePT, ':');
Port = strtoul(PortPT, NULL, 0);
if (strcasecmp(EntryPT, "IDENTIPV6") == FALSE) { ident_conf_add(HostPT, Port, TRUE); }
else { ident_conf_add(HostPT, Port, FALSE); }
continue;
}
/*sysprint(BITMASK_ERROR, "Ident configuration error, file %s line %d: Unknown entry \"%s\".", File, Count, EntryPT);*/
}
fclose(FilePT);
return(G_IdentConfs);
}
/* IDENT_CONF_ADD FUNCTION - JONAS (03.07.2003) */
struct IdentConf_Struct *ident_conf_add(const char *const HostPT, const unsigned long int Port, unsigned short int IPv6) {
struct IdentConf_Struct *IdentConf = NULL;
struct IdentConf_Struct *IdentConf_NEW = NULL;
assert(HostPT != NULL);
DEBUGPRINT(BITMASK_DEBUG_CONF, "Adding ident address: Host: %s - Port: %ld.", HostPT, Port);
IdentConf = ident_conf_get(HostPT, Port);
if (IdentConf != NULL) {
aerrno = AEEXISTS;
return(IdentConf);
}
IdentConf_NEW = malloc(sizeof(struct IdentConf_Struct));
if (IdentConf_NEW == NULL) {
aerrno = AEMALLOC;
return(NULL);
}
memset(IdentConf_NEW, 0, sizeof(struct IdentConf_Struct));
IdentConf_NEW->Host = strdup(HostPT);
if (IdentConf_NEW->Host == NULL) {
free(IdentConf_NEW);
aerrno = AEMALLOC;
return(NULL);
}
IdentConf_NEW->Port = Port;
IdentConf_NEW->IPv6 = IPv6;
if (IdentConf_Head == NULL) {
IdentConf_Head = IdentConf_NEW;
IdentConf_Tail = IdentConf_NEW;
}
else {
IdentConf = IdentConf_Tail;
IdentConf->Next = IdentConf_NEW;
IdentConf_NEW->Prev = IdentConf;
IdentConf_Tail = IdentConf_NEW;
}
G_IdentConfs++;
ident_listen_add(HostPT, Port);
aerrno = AESUCCESS;
return(IdentConf_NEW);
}
/* IDENT_CONF_REM - JONAS (03.07.2003) */
void ident_conf_rem(struct IdentConf_Struct *IdentConf) {
assert(IdentConf != NULL);
if (IdentConf->Prev == NULL) { IdentConf_Head = IdentConf->Next; }
else { IdentConf->Prev->Next = IdentConf->Next; }
if (IdentConf->Next == NULL) { IdentConf_Tail = IdentConf->Prev; }
else { IdentConf->Next->Prev = IdentConf->Prev; }
free(IdentConf->Host);
free(IdentConf);
G_IdentConfs--;
}
/* IDENT_CONF_GET - JONAS (03.07.2003) */
struct IdentConf_Struct *ident_conf_get(const char *const HostPT, const unsigned long int Port) {
struct IdentConf_Struct *IdentConf = NULL;
assert(HostPT != NULL);
for (IdentConf = IdentConf_Head ; IdentConf != NULL ; IdentConf = IdentConf->Next) {
if ((strcasecmp(IdentConf->Host, HostPT) == FALSE) && (IdentConf->Port == Port)) {
aerrno = AESUCCESS;
return(IdentConf);
}
}
aerrno = AENOMATCH;
return(NULL);
}
/* IDENT_CONF_DESTROY FUNCTION - JONAS (03.07.2003) */
void ident_conf_destroy(void) {
while (IdentConf_Head != NULL) { ident_conf_rem(IdentConf_Head); }
FREE(Ident_Conf_DefaultUser);
}
syntax highlighted by Code2HTML, v. 0.9.1