/* * ---------------------------------------------------------------- * Night Light IRC Proxy - Ident Daemon - Configuration Functions * ---------------------------------------------------------------- * Copyright (C) 1997-2007 Jonas Kvinge * 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); }