X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fnetconfig.c;h=de180074baf612300e8e58d3306b6c47c848e5b6;hb=7a65130ea2a5be56603233ba7b8d230691f604a0;hp=94b638bcb267179dc4bc527250bc31f7118c343a;hpb=264eb14f837d13affc78b1665cc3ff567aa13d10;p=citadel.git diff --git a/citadel/netconfig.c b/citadel/netconfig.c index 94b638bcb..de180074b 100644 --- a/citadel/netconfig.c +++ b/citadel/netconfig.c @@ -1,8 +1,7 @@ /* - * This module handles shared rooms, inter-Citadel mail, and outbound - * mailing list processing. + * This module handles loading, saving, and parsing of room network configurations. * - * Copyright (c) 2000-2016 by the citadel.org team + * Copyright (c) 2000-2021 by the citadel.org team * * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 3. @@ -31,7 +30,7 @@ #include -#include "include/ctdl_module.h" +#include "ctdl_module.h" #include "serv_extensions.h" #include "config.h" @@ -79,6 +78,7 @@ const CfgLineType *GetCfgTypeByStr(const char *Key, long len) } } + const CfgLineType *GetCfgTypeByEnum(RoomNetCfg eCfg, HashPos *It) { const char *Key; @@ -96,6 +96,7 @@ const CfgLineType *GetCfgTypeByEnum(RoomNetCfg eCfg, HashPos *It) return NULL; } + void ParseGeneric(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRoomNetCfg *OneRNCfg) { RoomNetCfgLine *nptr; @@ -122,6 +123,7 @@ void ParseGeneric(const CfgLineType *ThisOne, StrBuf *Line, const char *LinePos, OneRNCfg->NetConfigs[ThisOne->C] = nptr; } + void SerializeGeneric(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomNetCfg *OneRNCfg, RoomNetCfgLine *data) { int i; @@ -137,6 +139,7 @@ void SerializeGeneric(const CfgLineType *ThisOne, StrBuf *OutputBuffer, OneRoomN StrBufAppendBufPlain(OutputBuffer, HKEY("\n"), 0); } + void DeleteGenericCfgLine(const CfgLineType *ThisOne, RoomNetCfgLine **data) { int i; @@ -153,6 +156,7 @@ void DeleteGenericCfgLine(const CfgLineType *ThisOne, RoomNetCfgLine **data) *data = NULL; } + RoomNetCfgLine *DuplicateOneGenericCfgLine(const RoomNetCfgLine *data) { int i; @@ -182,7 +186,6 @@ void netcfg_keyname(char *keybuf, long roomnum) } - /* * Given a room number and a textual netconfig, convert to base64 and write to the configdb */ @@ -202,14 +205,13 @@ void write_netconfig_to_configdb(long roomnum, const char *raw_netconfig) if ((enc_len > 1) && (enc[enc_len-2] == 13)) enc[enc_len-2] = 0; if ((enc_len > 0) && (enc[enc_len-1] == 10)) enc[enc_len-1] = 0; enc[enc_len] = 0; - syslog(LOG_DEBUG, "Writing key '%s' (length=%d)", keyname, enc_len); + syslog(LOG_DEBUG, "netconfig: writing key '%s' (length=%d)", keyname, enc_len); CtdlSetConfigStr(keyname, enc); free(enc); } } - /* * Given a room number, attempt to load the netconfig configdb entry for that room. * If it returns NULL, there is no netconfig. @@ -301,20 +303,21 @@ void SaveRoomNetConfigFile(OneRoomNetCfg *OneRNCfg, long roomnum) { const CfgLineType *pCfg; pCfg = GetCfgTypeByEnum(eCfg, CfgIt); - if (pCfg->IsSingleLine) + if (pCfg) { - pCfg->Serializer(pCfg, OutBuffer, OneRNCfg, NULL); - } - else - { - RoomNetCfgLine *pName = OneRNCfg->NetConfigs[pCfg->C]; - while (pName != NULL) + if (pCfg->IsSingleLine) { - pCfg->Serializer(pCfg, OutBuffer, OneRNCfg, pName); - pName = pName->next; + pCfg->Serializer(pCfg, OutBuffer, OneRNCfg, NULL); + } + else + { + RoomNetCfgLine *pName = OneRNCfg->NetConfigs[pCfg->C]; + while (pName != NULL) + { + pCfg->Serializer(pCfg, OutBuffer, OneRNCfg, pName); + pName = pName->next; + } } - - } } @@ -331,7 +334,6 @@ void SaveRoomNetConfigFile(OneRoomNetCfg *OneRNCfg, long roomnum) } - void AddRoomCfgLine(OneRoomNetCfg *OneRNCfg, struct ctdlroom *qrbuf, RoomNetCfg LineType, RoomNetCfgLine *Line) { RoomNetCfgLine **pLine; @@ -433,7 +435,11 @@ void cmd_gnet(char *argbuf) char *c = LoadRoomNetConfigFile(CC->room.QRnumber); if (c) { - cprintf("%s\n", c); + int len = strlen(c); + client_write(c, len); // Can't use cprintf() here, it has a limit of 1024 bytes + if (c[len] != '\n') { + client_write(HKEY("\n")); + } free(c); } cprintf("000\n"); @@ -480,6 +486,7 @@ void DeleteCtdlNodeConf(void *vNode) free(Node); } + CtdlNodeConf *NewNode(StrBuf *SerializedNode) { const char *Pos = NULL; @@ -580,11 +587,7 @@ int is_recipient(OneRoomNetCfg *RNCfg, const char *Name) } - -int CtdlNetconfigCheckRoomaccess( - char *errmsgbuf, - size_t n, - const char* RemoteIdentifier) +int CtdlNetconfigCheckRoomaccess(char *errmsgbuf, size_t n, const char* RemoteIdentifier) { OneRoomNetCfg *RNCfg; int found; @@ -619,105 +622,6 @@ int CtdlNetconfigCheckRoomaccess( } - -/* - * cmd_netp() - authenticate to the server as another Citadel node polling - * for network traffic - */ -void cmd_netp(char *cmdbuf) -{ - struct CitContext *CCC = CC; - HashList *working_ignetcfg; - char *node; - StrBuf *NodeStr; - long nodelen; - int v; - long lens[2]; - const char *strs[2]; - - const StrBuf *secret = NULL; - const StrBuf *nexthop = NULL; - char err_buf[SIZ] = ""; - - /* Authenticate */ - node = CCC->curr_user; - nodelen = extract_token(CCC->curr_user, cmdbuf, 0, '|', sizeof CCC->curr_user); - NodeStr = NewStrBufPlain(node, nodelen); - /* load the IGnet Configuration to check node validity */ - working_ignetcfg = CtdlLoadIgNetCfg(); - v = CtdlIsValidNode(&nexthop, &secret, NodeStr, working_ignetcfg, NULL); - if (v != 0) { - snprintf(err_buf, sizeof err_buf, - "An unknown Citadel server called \"%s\" attempted to connect from %s [%s].\n", - node, CCC->cs_host, CCC->cs_addr - ); - syslog(LOG_WARNING, "%s", err_buf); - cprintf("%d authentication failed\n", ERROR + PASSWORD_REQUIRED); - - strs[0] = CCC->cs_addr; - lens[0] = strlen(CCC->cs_addr); - - strs[1] = "SRV_UNKNOWN"; - lens[1] = sizeof("SRV_UNKNOWN") - 1; - - CtdlAideFPMessage( - err_buf, - "IGNet Networking.", - 2, strs, (long*) &lens, - CCC->cs_pid, 0, - time(NULL)); - - DeleteHash(&working_ignetcfg); - FreeStrBuf(&NodeStr); - return; - } - - extract_token(CCC->user.password, cmdbuf, 1, '|', sizeof CCC->user.password); - if (strcasecmp(CCC->user.password, ChrPtr(secret))) { - snprintf(err_buf, sizeof err_buf, - "A Citadel server at %s [%s] failed to authenticate as network node \"%s\".\n", - CCC->cs_host, CCC->cs_addr, node - ); - syslog(LOG_WARNING, "%s", err_buf); - cprintf("%d authentication failed\n", ERROR + PASSWORD_REQUIRED); - - strs[0] = CCC->cs_addr; - lens[0] = strlen(CCC->cs_addr); - - strs[1] = "SRV_PW"; - lens[1] = sizeof("SRV_PW") - 1; - - CtdlAideFPMessage( - err_buf, - "IGNet Networking.", - 2, strs, - (long*) &lens, - CCC->cs_pid, 0, - time(NULL)); - - DeleteHash(&working_ignetcfg); - FreeStrBuf(&NodeStr); - return; - } - - if (CtdlNetworkTalkingTo(node, nodelen, NTT_CHECK)) { - syslog(LOG_WARNING, "Duplicate session for network node <%s>", node); - cprintf("%d Already talking to %s right now\n", ERROR + RESOURCE_BUSY, node); - DeleteHash(&working_ignetcfg); - FreeStrBuf(&NodeStr); - return; - } - nodelen = safestrncpy(CCC->net_node, node, sizeof CCC->net_node); - CtdlNetworkTalkingTo(CCC->net_node, nodelen, NTT_ADD); - syslog(LOG_NOTICE, "Network node <%s> logged in from %s [%s]", - CCC->net_node, CCC->cs_host, CCC->cs_addr - ); - cprintf("%d authenticated as network node '%s'\n", CIT_OK, CCC->net_node); - DeleteHash(&working_ignetcfg); - FreeStrBuf(&NodeStr); -} - - /*-----------------------------------------------------------------------------* * Network maps: evaluate other nodes * *-----------------------------------------------------------------------------*/ @@ -730,6 +634,7 @@ void DeleteNetMap(void *vNetMap) free(TheNetMap); } + CtdlNetMap *NewNetMap(StrBuf *SerializedNetMap) { const char *Pos = NULL; @@ -751,6 +656,7 @@ CtdlNetMap *NewNetMap(StrBuf *SerializedNetMap) return NM; } + HashList* CtdlReadNetworkMap(void) { const char *LinePos; @@ -784,6 +690,7 @@ HashList* CtdlReadNetworkMap(void) return Hash; } + StrBuf *CtdlSerializeNetworkMap(HashList *Map) { void *vMap; @@ -809,102 +716,6 @@ StrBuf *CtdlSerializeNetworkMap(HashList *Map) } -/* - * Learn topology from path fields - */ -void NetworkLearnTopology(char *node, char *path, HashList *the_netmap, int *netmap_changed) -{ - CtdlNetMap *pNM = NULL; - void *vptr; - char nexthop[256]; - CtdlNetMap *nmptr; - - if (GetHash(the_netmap, node, strlen(node), &vptr) && - (vptr != NULL))/* TODO: is the NodeName Uniq? */ - { - pNM = (CtdlNetMap*)vptr; - extract_token(nexthop, path, 0, '!', sizeof nexthop); - if (!strcmp(nexthop, ChrPtr(pNM->NextHop))) { - pNM->lastcontact = time(NULL); - (*netmap_changed) ++; - return; - } - } - - /* If we got here then it's not in the map, so add it. */ - nmptr = (CtdlNetMap *) malloc(sizeof (CtdlNetMap)); - nmptr->NodeName = NewStrBufPlain(node, -1); - nmptr->lastcontact = time(NULL); - nmptr->NextHop = NewStrBuf (); - StrBufExtract_tokenFromStr(nmptr->NextHop, path, strlen(path), 0, '!'); - /* TODO: is the NodeName Uniq? */ - Put(the_netmap, SKEY(nmptr->NodeName), nmptr, DeleteNetMap); - (*netmap_changed) ++; -} - - -/* - * Check the network map and determine whether the supplied node name is - * valid. If it is not a neighbor node, supply the name of a neighbor node - * which is the next hop. If it *is* a neighbor node, we also fill in the - * shared secret. - */ -int CtdlIsValidNode(const StrBuf **nexthop, - const StrBuf **secret, - StrBuf *node, - HashList *IgnetCfg, - HashList *the_netmap) -{ - void *vNetMap; - void *vNodeConf; - CtdlNodeConf *TheNode; - CtdlNetMap *TheNetMap; - - if (StrLength(node) == 0) { - return(-1); - } - - /* - * First try the neighbor nodes - */ - if (GetCount(IgnetCfg) == 0) { - syslog(LOG_INFO, "IgnetCfg is empty!"); - if (nexthop != NULL) { - *nexthop = NULL; - } - return(-1); - } - - /* try to find a neigbour with the name 'node' */ - if (GetHash(IgnetCfg, SKEY(node), &vNodeConf) && - (vNodeConf != NULL)) - { - TheNode = (CtdlNodeConf*)vNodeConf; - if (secret != NULL) - *secret = TheNode->Secret; - return 0; /* yup, it's a direct neighbor */ - } - - /* - * If we get to this point we have to see if we know the next hop - *//* TODO: is the NodeName Uniq? */ - if ((GetCount(the_netmap) > 0) && - (GetHash(the_netmap, SKEY(node), &vNetMap))) - { - TheNetMap = (CtdlNetMap*)vNetMap; - if (nexthop != NULL) - *nexthop = TheNetMap->NextHop; - return(0); - } - - /* - * If we get to this point, the supplied node name is bogus. - */ - syslog(LOG_ERR, "Invalid node name <%s>", ChrPtr(node)); - return(-1); -} - - /* * Convert any legacy configuration files in the "netconfigs" directory */ @@ -921,28 +732,34 @@ void convert_legacy_netcfg_files(void) dh = opendir(ctdl_netcfg_dir); if (!dh) return; - syslog(LOG_INFO, "Legacy netconfig files exist - converting them!"); + syslog(LOG_INFO, "netconfig: legacy netconfig files exist - converting them!"); - while (dit = readdir(dh), dit != NULL) { // yes, we use the non-reentrant version; we're not in threaded mode yet + while (dit = readdir(dh), dit != NULL) // yes, we use the non-reentrant version; we're not in threaded mode yet + { roomnum = atol(dit->d_name); if (roomnum > 0) { snprintf(filename, sizeof filename, "%s/%ld", ctdl_netcfg_dir, roomnum); fp = fopen(filename, "r"); - if (fp) { + if (fp) + { fseek(fp, 0L, SEEK_END); len = ftell(fp); - if (len > 0) { + if (len > 0) + { v = malloc(len); - if (v) { + if (v) + { rewind(fp); - if (fread(v, len, 1, fp)) { + if (fread(v, len, 1, fp)) + { write_netconfig_to_configdb(roomnum, v); unlink(filename); } free(v); } } - else { + else + { unlink(filename); // zero length netconfig, just delete it } fclose(fp); @@ -955,7 +772,6 @@ void convert_legacy_netcfg_files(void) } - /* * Module entry point */ @@ -966,7 +782,6 @@ CTDL_MODULE_INIT(netconfig) convert_legacy_netcfg_files(); CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config"); CtdlRegisterProtoHook(cmd_snet, "SNET", "Set network config"); - CtdlRegisterProtoHook(cmd_netp, "NETP", "Identify as network poller"); } return "netconfig"; }