From 221d5a935e2e876c7c6b99815592f4ef7a7f4753 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Thu, 20 Sep 2001 04:17:10 +0000 Subject: [PATCH] * Inbound network authentication working. Fixed a bug in the split-horizon algorithm. Still need to move the 'netpoll' command into the server. --- citadel/ChangeLog | 5 +- citadel/citserver.c | 4 - citadel/file_ops.c | 574 ++++++++++++++++++++++------------------- citadel/file_ops.h | 1 - citadel/serv_network.c | 52 +++- citadel/tools.c | 1 + 6 files changed, 357 insertions(+), 280 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index f83a5c558..cc2db12e8 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,8 @@ $Log$ + Revision 580.45 2001/09/20 04:17:10 ajc + * Inbound network authentication working. Fixed a bug in the split-horizon + algorithm. Still need to move the 'netpoll' command into the server. + Revision 580.44 2001/09/18 04:05:04 ajc * Added host/IP and port to node config (client side only) @@ -2751,4 +2755,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/citserver.c b/citadel/citserver.c index 8bbd76d24..00d086956 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -1125,10 +1125,6 @@ void do_command_loop(void) { cmd_more(); } - else if (!strncasecmp(cmdbuf,"NETP",4)) { - cmd_netp(&cmdbuf[5]); - } - else if (!strncasecmp(cmdbuf,"NDOP",4)) { cmd_ndop(&cmdbuf[5]); } diff --git a/citadel/file_ops.c b/citadel/file_ops.c index 9a6989301..d701a443c 100644 --- a/citadel/file_ops.c +++ b/citadel/file_ops.c @@ -44,31 +44,45 @@ #include "tools.h" #include "citserver.h" + +/* + * Server command to delete a file from a room's directory + */ void cmd_delf(char *filename) { char pathname[64]; int a; - if (CtdlAccessCheck(ac_room_aide)) return; + if (CtdlAccessCheck(ac_room_aide)) + return; if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) { - cprintf("%d No directory in this room.\n",ERROR+NOT_HERE); + cprintf("%d No directory in this room.\n", + ERROR + NOT_HERE); return; - } + } - if (strlen(filename)==0) { + if (strlen(filename) == 0) { cprintf("%d You must specify a file name.\n", - ERROR+FILE_NOT_FOUND); + ERROR + FILE_NOT_FOUND); return; + } + for (a = 0; a < strlen(filename); ++a) { + if (filename[a] == '/') { + filename[a] = '_'; } - for (a=0; aquickroom.QRdirname,filename); - a=unlink(pathname); - if (a==0) cprintf("%d File '%s' deleted.\n",OK,pathname); - else cprintf("%d File '%s' not found.\n",ERROR+FILE_NOT_FOUND,pathname); } + snprintf(pathname, sizeof pathname, "./files/%s/%s", + CC->quickroom.QRdirname, filename); + a = unlink(pathname); + if (a == 0) { + cprintf("%d File '%s' deleted.\n", OK, pathname); + } + else { + cprintf("%d File '%s' not found.\n", + ERROR + FILE_NOT_FOUND, pathname); + } +} @@ -86,59 +100,61 @@ void cmd_movf(char *cmdbuf) int a; struct quickroom qrbuf; - extract(filename,cmdbuf,0); - extract(newroom,cmdbuf,1); + extract(filename, cmdbuf, 0); + extract(newroom, cmdbuf, 1); if (CtdlAccessCheck(ac_room_aide)) return; if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) { - cprintf("%d No directory in this room.\n",ERROR+NOT_HERE); + cprintf("%d No directory in this room.\n", + ERROR + NOT_HERE); return; - } + } - if (strlen(filename)==0) { + if (strlen(filename) == 0) { cprintf("%d You must specify a file name.\n", - ERROR+FILE_NOT_FOUND); + ERROR + FILE_NOT_FOUND); return; - } + } - for (a=0; aquickroom.QRdirname,filename); - if (access(pathname,0)!=0) { + for (a = 0; a < strlen(filename); ++a) { + if (filename[a] == '/') { + filename[a] = '_'; + } + } + snprintf(pathname, sizeof pathname, "./files/%s/%s", + CC->quickroom.QRdirname, filename); + if (access(pathname, 0) != 0) { cprintf("%d File '%s' not found.\n", - ERROR+FILE_NOT_FOUND,pathname); + ERROR + FILE_NOT_FOUND, pathname); return; - } + } - if (getroom(&qrbuf, newroom)!=0) { - cprintf("%d '%s' does not exist.\n", - ERROR, newroom); + if (getroom(&qrbuf, newroom) != 0) { + cprintf("%d '%s' does not exist.\n", ERROR, newroom); return; - } + } if ((qrbuf.QRflags & QR_DIRECTORY) == 0) { cprintf("%d '%s' is not a directory room.\n", - ERROR+NOT_HERE,qrbuf.QRname); + ERROR + NOT_HERE, qrbuf.QRname); return; - } - snprintf(newpath,sizeof newpath,"./files/%s/%s",qrbuf.QRdirname, + } + snprintf(newpath, sizeof newpath, "./files/%s/%s", qrbuf.QRdirname, filename); - if (link(pathname,newpath)!=0) { - cprintf("%d Couldn't move file: %s\n",ERROR,strerror(errno)); + if (link(pathname, newpath) != 0) { + cprintf("%d Couldn't move file: %s\n", ERROR, + strerror(errno)); return; - } + } unlink(pathname); /* this is a crude method of copying the file description */ snprintf(buf, sizeof buf, - "cat ./files/%s/filedir |grep %s >>./files/%s/filedir", - CC->quickroom.QRdirname, - filename, - qrbuf.QRdirname); + "cat ./files/%s/filedir |grep %s >>./files/%s/filedir", + CC->quickroom.QRdirname, filename, qrbuf.QRdirname); system(buf); - cprintf("%d File '%s' has been moved.\n",OK,filename); - } + cprintf("%d File '%s' has been moved.\n", OK, filename); +} /* @@ -146,87 +162,103 @@ void cmd_movf(char *cmdbuf) */ void cmd_netf(char *cmdbuf) { - char pathname[SIZ],filename[SIZ],destsys[SIZ],buf[SIZ],outfile[SIZ]; - int a,e; + char pathname[SIZ], filename[SIZ], destsys[SIZ], buf[SIZ]; + char outfile[SIZ]; + int a, e; time_t now; FILE *ofp; static int seq = 1; - extract(filename,cmdbuf,0); - extract(destsys,cmdbuf,1); + extract(filename, cmdbuf, 0); + extract(destsys, cmdbuf, 1); if (CtdlAccessCheck(ac_room_aide)) return; if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) { - cprintf("%d No directory in this room.\n",ERROR+NOT_HERE); + cprintf("%d No directory in this room.\n", + ERROR + NOT_HERE); return; - } + } - if (strlen(filename)==0) { + if (strlen(filename) == 0) { cprintf("%d You must specify a file name.\n", - ERROR+FILE_NOT_FOUND); + ERROR + FILE_NOT_FOUND); return; - } + } - for (a=0; aquickroom.QRdirname,filename); - if (access(pathname,0)!=0) { + for (a = 0; a < strlen(filename); ++a) { + if (filename[a] == '/') { + filename[a] = '_'; + } + } + snprintf(pathname, sizeof pathname, "./files/%s/%s", + CC->quickroom.QRdirname, filename); + if (access(pathname, 0) != 0) { cprintf("%d File '%s' not found.\n", - ERROR+FILE_NOT_FOUND,pathname); + ERROR + FILE_NOT_FOUND, pathname); return; - } - snprintf(buf,sizeof buf,"sysop@%s",destsys); - e=alias(buf); - if (e!=MES_BINARY) { + } + snprintf(buf, sizeof buf, "sysop@%s", destsys); + e = alias(buf); + if (e != MES_BINARY) { cprintf("%d No such system: '%s'\n", - ERROR+NO_SUCH_SYSTEM,destsys); + ERROR + NO_SUCH_SYSTEM, destsys); return; - } + } snprintf(outfile, sizeof outfile, - "%s/network/spoolin/nsf.%04x.%04x", - BBSDIR, getpid(), ++seq); - ofp=fopen(outfile,"a"); - if (ofp==NULL) { - cprintf("%d internal error\n",ERROR); + "%s/network/spoolin/nsf.%04x.%04x", + BBSDIR, getpid(), ++seq); + ofp = fopen(outfile, "a"); + if (ofp == NULL) { + cprintf("%d internal error\n", ERROR); return; - } + } - putc(255,ofp); - putc(MES_NORMAL,ofp); - putc(0,ofp); - fprintf(ofp,"Pcit%ld",CC->usersupp.usernum); putc(0,ofp); + putc(255, ofp); + putc(MES_NORMAL, ofp); + putc(0, ofp); + fprintf(ofp, "Pcit%ld", CC->usersupp.usernum); + putc(0, ofp); time(&now); - fprintf(ofp,"T%ld",(long)now); putc(0,ofp); - fprintf(ofp,"A%s",CC->usersupp.fullname); putc(0,ofp); - fprintf(ofp,"O%s",CC->quickroom.QRname); putc(0,ofp); - fprintf(ofp,"N%s",NODENAME); putc(0,ofp); - fprintf(ofp,"D%s",destsys); putc(0,ofp); - fprintf(ofp,"SFILE"); putc(0,ofp); - putc('M',ofp); + fprintf(ofp, "T%ld", (long) now); + putc(0, ofp); + fprintf(ofp, "A%s", CC->usersupp.fullname); + putc(0, ofp); + fprintf(ofp, "O%s", CC->quickroom.QRname); + putc(0, ofp); + fprintf(ofp, "N%s", NODENAME); + putc(0, ofp); + fprintf(ofp, "D%s", destsys); + putc(0, ofp); + fprintf(ofp, "SFILE"); + putc(0, ofp); + putc('M', ofp); fclose(ofp); - snprintf(buf,sizeof buf, - "cd ./files/%s; uuencode %s <%s 2>/dev/null >>%s", - CC->quickroom.QRdirname,filename,filename,outfile); + snprintf(buf, sizeof buf, + "cd ./files/%s; uuencode %s <%s 2>/dev/null >>%s", + CC->quickroom.QRdirname, filename, filename, outfile); system(buf); - ofp = fopen(outfile,"a"); - putc(0,ofp); + ofp = fopen(outfile, "a"); + putc(0, ofp); fclose(ofp); - cprintf("%d File '%s' has been sent to %s.\n",OK,filename,destsys); + cprintf("%d File '%s' has been sent to %s.\n", OK, filename, + destsys); system("nohup ./netproc -i >/dev/null 2>&1 &"); return; - } +} /* - * This code is common to all commands which open a file for downloading. + * This code is common to all commands which open a file for downloading, + * regardless of whether it's a file from the directory, an image, a network + * spool file, a MIME attachment, etc. * It examines the file and displays the OK result code and some information * about the file. NOTE: this stuff is Unix dependent. */ -void OpenCmdResult(char *filename, char *mime_type) { +void OpenCmdResult(char *filename, char *mime_type) +{ struct stat statbuf; time_t modtime; long filesize; @@ -249,41 +281,46 @@ void cmd_open(char *cmdbuf) char pathname[SIZ]; int a; - extract(filename,cmdbuf,0); + extract(filename, cmdbuf, 0); if (CtdlAccessCheck(ac_logged_in)) return; if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) { - cprintf("%d No directory in this room.\n",ERROR+NOT_HERE); + cprintf("%d No directory in this room.\n", + ERROR + NOT_HERE); return; - } + } - if (strlen(filename)==0) { + if (strlen(filename) == 0) { cprintf("%d You must specify a file name.\n", - ERROR+FILE_NOT_FOUND); + ERROR + FILE_NOT_FOUND); return; - } + } if (CC->download_fp != NULL) { - cprintf("%d You already have a download file open.\n",ERROR); + cprintf("%d You already have a download file open.\n", + ERROR); return; - } + } - for (a=0; aquickroom.QRdirname,filename); - CC->download_fp = fopen(pathname,"r"); + snprintf(pathname, sizeof pathname, + "./files/%s/%s", CC->quickroom.QRdirname, filename); + CC->download_fp = fopen(pathname, "r"); - if (CC->download_fp==NULL) { + if (CC->download_fp == NULL) { cprintf("%d cannot open %s: %s\n", - ERROR,pathname,strerror(errno)); + ERROR, pathname, strerror(errno)); return; - } + } OpenCmdResult(filename, "application/octet-stream"); - } +} /* * open an image file @@ -297,54 +334,56 @@ void cmd_oimg(char *cmdbuf) int which_floor; int a; - extract(filename,cmdbuf,0); + extract(filename, cmdbuf, 0); - if (strlen(filename)==0) { + if (strlen(filename) == 0) { cprintf("%d You must specify a file name.\n", - ERROR+FILE_NOT_FOUND); + ERROR + FILE_NOT_FOUND); return; - } + } if (CC->download_fp != NULL) { - cprintf("%d You already have a download file open.\n",ERROR); + cprintf("%d You already have a download file open.\n", + ERROR); return; - } + } if (!strcasecmp(filename, "_userpic_")) { extract(which_user, cmdbuf, 1); if (getuser(&usbuf, which_user) != 0) { - cprintf("%d No such user.\n", ERROR+NO_SUCH_USER); + cprintf("%d No such user.\n", + ERROR + NO_SUCH_USER); return; - } + } snprintf(pathname, sizeof pathname, "./userpics/%ld.gif", usbuf.usernum); - } - else if (!strcasecmp(filename, "_floorpic_")) { + } else if (!strcasecmp(filename, "_floorpic_")) { which_floor = extract_int(cmdbuf, 1); - snprintf(pathname, sizeof pathname, "./images/floor.%d.gif", - which_floor); - } - else if (!strcasecmp(filename, "_roompic_")) { + snprintf(pathname, sizeof pathname, + "./images/floor.%d.gif", which_floor); + } else if (!strcasecmp(filename, "_roompic_")) { assoc_file_name(pathname, &CC->quickroom, "images"); - } - else { - for (a=0; adownload_fp = fopen(pathname,"r"); + snprintf(pathname, sizeof pathname, "./images/%s.gif", + filename); + } + + CC->download_fp = fopen(pathname, "rb"); if (CC->download_fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR+FILE_NOT_FOUND,pathname,strerror(errno)); + ERROR + FILE_NOT_FOUND, pathname, strerror(errno)); return; - } - - OpenCmdResult(pathname, "image/gif"); } + OpenCmdResult(pathname, "image/gif"); +} + /* * open a file for uploading */ @@ -352,51 +391,56 @@ void cmd_uopn(char *cmdbuf) { int a; - extract(CC->upl_file,cmdbuf,0); - extract(CC->upl_comment,cmdbuf,1); + extract(CC->upl_file, cmdbuf, 0); + extract(CC->upl_comment, cmdbuf, 1); if (CtdlAccessCheck(ac_logged_in)) return; if ((CC->quickroom.QRflags & QR_DIRECTORY) == 0) { - cprintf("%d No directory in this room.\n",ERROR+NOT_HERE); + cprintf("%d No directory in this room.\n", + ERROR + NOT_HERE); return; - } + } - if (strlen(CC->upl_file)==0) { + if (strlen(CC->upl_file) == 0) { cprintf("%d You must specify a file name.\n", - ERROR+FILE_NOT_FOUND); + ERROR + FILE_NOT_FOUND); return; - } + } if (CC->upload_fp != NULL) { - cprintf("%d You already have a upload file open.\n",ERROR); + cprintf("%d You already have a upload file open.\n", + ERROR); return; + } + + for (a = 0; a < strlen(CC->upl_file); ++a) { + if (CC->upl_file[a] == '/') { + CC->upl_file[a] = '_'; } + } + snprintf(CC->upl_path, sizeof CC->upl_path, "./files/%s/%s", + CC->quickroom.QRdirname, CC->upl_file); + snprintf(CC->upl_filedir, sizeof CC->upl_filedir, + "./files/%s/filedir", CC->quickroom.QRdirname); - for (a=0; aupl_file); ++a) - if (CC->upl_file[a]=='/') CC->upl_file[a] = '_'; - snprintf(CC->upl_path,sizeof CC->upl_path,"./files/%s/%s", - CC->quickroom.QRdirname,CC->upl_file); - snprintf(CC->upl_filedir,sizeof CC->upl_filedir,"./files/%s/filedir", - CC->quickroom.QRdirname); - - CC->upload_fp = fopen(CC->upl_path,"r"); + CC->upload_fp = fopen(CC->upl_path, "r"); if (CC->upload_fp != NULL) { fclose(CC->upload_fp); CC->upload_fp = NULL; cprintf("%d '%s' already exists\n", - ERROR+ALREADY_EXISTS,CC->upl_path); + ERROR + ALREADY_EXISTS, CC->upl_path); return; - } + } - CC->upload_fp = fopen(CC->upl_path,"wb"); + CC->upload_fp = fopen(CC->upl_path, "wb"); if (CC->upload_fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR,CC->upl_path,strerror(errno)); + ERROR, CC->upl_path, strerror(errno)); return; - } - cprintf("%d Ok\n",OK); } + cprintf("%d Ok\n", OK); +} @@ -413,91 +457,97 @@ void cmd_uimg(char *cmdbuf) if (num_parms(cmdbuf) < 2) { cprintf("%d Usage error.\n", ERROR); return; - } + } - is_this_for_real = extract_int(cmdbuf,0); + is_this_for_real = extract_int(cmdbuf, 0); extract(basenm, cmdbuf, 1); if (CC->upload_fp != NULL) { - cprintf("%d You already have an upload file open.\n", ERROR); + cprintf("%d You already have an upload file open.\n", + ERROR); return; - } + } strcpy(CC->upl_path, ""); - for (a=0; ausersupp.axlevel >= 6) { snprintf(CC->upl_path, sizeof CC->upl_path, "./images/%s", basenm); - } + } if (!strcasecmp(basenm, "_userpic_")) { snprintf(CC->upl_path, sizeof CC->upl_path, "./userpics/%ld.gif", CC->usersupp.usernum); - } + } - if ( (!strcasecmp(basenm, "_floorpic_")) && (CC->usersupp.axlevel >= 6) ) { + if ((!strcasecmp(basenm, "_floorpic_")) + && (CC->usersupp.axlevel >= 6)) { which_floor = extract_int(cmdbuf, 2); snprintf(CC->upl_path, sizeof CC->upl_path, "./images/floor.%d.gif", which_floor); - } + } - if ( (!strcasecmp(basenm, "_roompic_")) && (is_room_aide()) ) { + if ((!strcasecmp(basenm, "_roompic_")) && (is_room_aide())) { assoc_file_name(CC->upl_path, &CC->quickroom, "images"); - } + } if (strlen(CC->upl_path) == 0) { cprintf("%d Higher access required.\n", - ERROR+HIGHER_ACCESS_REQUIRED); + ERROR + HIGHER_ACCESS_REQUIRED); return; - } + } if (is_this_for_real == 0) { cprintf("%d Ok to send image\n", OK); return; - } + } - CC->upload_fp = fopen(CC->upl_path,"wb"); + CC->upload_fp = fopen(CC->upl_path, "wb"); if (CC->upload_fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR,CC->upl_path,strerror(errno)); + ERROR, CC->upl_path, strerror(errno)); return; - } - cprintf("%d Ok\n",OK); - CC->upload_type = UPL_IMAGE; } + cprintf("%d Ok\n", OK); + CC->upload_type = UPL_IMAGE; +} /* * close the download file */ -void cmd_clos(void) { +void cmd_clos(void) +{ char buf[SIZ]; - + if (CC->download_fp == NULL) { - cprintf("%d You don't have a download file open.\n",ERROR); + cprintf("%d You don't have a download file open.\n", + ERROR); return; - } + } fclose(CC->download_fp); CC->download_fp = NULL; if (CC->dl_is_net == 1) { CC->dl_is_net = 0; - snprintf(buf,sizeof buf,"%s/network/spoolout/%s",BBSDIR, + snprintf(buf, sizeof buf, "%s/network/spoolout/%s", BBSDIR, CC->net_node); unlink(buf); - } - - cprintf("%d Ok\n",OK); } + cprintf("%d Ok\n", OK); +} + /* - * abort and upload + * abort an upload */ void abort_upl(struct CitContext *who) { @@ -505,8 +555,8 @@ void abort_upl(struct CitContext *who) fclose(who->upload_fp); who->upload_fp = NULL; unlink(CC->upl_path); - } } +} @@ -517,48 +567,45 @@ void cmd_ucls(char *cmd) { FILE *fp; char upload_notice[512]; - + if (CC->upload_fp == NULL) { - cprintf("%d You don't have an upload file open.\n",ERROR); + cprintf("%d You don't have an upload file open.\n", ERROR); return; } fclose(CC->upload_fp); CC->upload_fp = NULL; - if ((!strcasecmp(cmd,"1")) && (CC->upload_type != UPL_FILE)) { + if ((!strcasecmp(cmd, "1")) && (CC->upload_type != UPL_FILE)) { CC->upload_type = UPL_FILE; cprintf("%d Upload completed.\n", OK); - if (CC->upload_type == UPL_NET) { - if (fork()==0) { - execlp("./netproc", "netproc", "-i", NULL); - exit(errno); - } - } + /* FIXME ... here we need to trigger a network run */ return; } - if (!strcasecmp(cmd,"1")) { - cprintf("%d File '%s' saved.\n",OK,CC->upl_path); - fp = fopen(CC->upl_filedir,"a"); - if (fp==NULL) fp=fopen(CC->upl_filedir,"w"); - if (fp!=NULL) { - fprintf(fp,"%s %s\n",CC->upl_file,CC->upl_comment); + if (!strcasecmp(cmd, "1")) { + cprintf("%d File '%s' saved.\n", OK, CC->upl_path); + fp = fopen(CC->upl_filedir, "a"); + if (fp == NULL) { + fp = fopen(CC->upl_filedir, "w"); + } + if (fp != NULL) { + fprintf(fp, "%s %s\n", CC->upl_file, + CC->upl_comment); fclose(fp); } /* put together an upload notice */ sprintf(upload_notice, "NEW UPLOAD: '%s'\n %s\n", - CC->upl_file,CC->upl_comment); + CC->upl_file, CC->upl_comment); quickie_message(CC->curr_user, NULL, CC->quickroom.QRname, upload_notice); - } - else { + } else { abort_upl(CC); - cprintf("%d File '%s' aborted.\n",OK,CC->upl_path); + cprintf("%d File '%s' aborted.\n", OK, CC->upl_path); } } @@ -573,24 +620,26 @@ void cmd_read(char *cmdbuf) int bytes; char buf[4096]; - start_pos = extract_long(cmdbuf,0); - bytes = extract_int(cmdbuf,1); - + start_pos = extract_long(cmdbuf, 0); + bytes = extract_int(cmdbuf, 1); + if (CC->download_fp == NULL) { - cprintf("%d You don't have a download file open.\n",ERROR); + cprintf("%d You don't have a download file open.\n", + ERROR); return; - } + } if (bytes > 4096) { - cprintf("%d You may not read more than 4096 bytes.\n",ERROR); + cprintf("%d You may not read more than 4096 bytes.\n", + ERROR); return; - } + } - fseek(CC->download_fp,start_pos,0); - fread(buf,bytes,1,CC->download_fp); - cprintf("%d %d\n",BINARY_FOLLOWS,bytes); + fseek(CC->download_fp, start_pos, 0); + fread(buf, bytes, 1, CC->download_fp); + cprintf("%d %d\n", BINARY_FOLLOWS, bytes); client_write(buf, bytes); - } +} @@ -602,40 +651,26 @@ void cmd_writ(char *cmdbuf) int bytes; char buf[4096]; - bytes = extract_int(cmdbuf,0); - + bytes = extract_int(cmdbuf, 0); + if (CC->upload_fp == NULL) { - cprintf("%d You don't have an upload file open.\n",ERROR); + cprintf("%d You don't have an upload file open.\n", ERROR); return; - } + } if (bytes > 4096) { - cprintf("%d You may not write more than 4096 bytes.\n",ERROR); + cprintf("%d You may not write more than 4096 bytes.\n", + ERROR); return; - } + } - cprintf("%d %d\n",SEND_BINARY,bytes); + cprintf("%d %d\n", SEND_BINARY, bytes); client_read(buf, bytes); - fwrite(buf,bytes,1,CC->upload_fp); - } + fwrite(buf, bytes, 1, CC->upload_fp); +} -/* - * cmd_netp() - identify as network poll session - */ -void cmd_netp(char *cmdbuf) -{ - char buf[SIZ]; - - extract(buf,cmdbuf,1); - if (strcasecmp(buf,config.c_net_password)) { - cprintf("%d authentication failed\n",ERROR); - return; - } - extract(CC->net_node,cmdbuf,0); - cprintf("%d authenticated as network node '%s'\n",OK,CC->net_node); - } /* * cmd_ndop() - open a network spool file for downloading @@ -645,33 +680,35 @@ void cmd_ndop(char *cmdbuf) char pathname[SIZ]; struct stat statbuf; - if (strlen(CC->net_node)==0) { + if (strlen(CC->net_node) == 0) { cprintf("%d Not authenticated as a network node.\n", - ERROR+NOT_LOGGED_IN); + ERROR + NOT_LOGGED_IN); return; - } + } if (CC->download_fp != NULL) { - cprintf("%d You already have a download file open.\n",ERROR); + cprintf("%d You already have a download file open.\n", + ERROR); return; - } + } - snprintf(pathname,sizeof pathname,"%s/network/spoolout/%s",BBSDIR, - CC->net_node); + snprintf(pathname, sizeof pathname, "%s/network/spoolout/%s", + BBSDIR, CC->net_node); /* first open the file in append mode in order to create a * zero-length file if it doesn't already exist */ - CC->download_fp = fopen(pathname,"a"); - if (CC->download_fp != NULL) fclose(CC->download_fp); + CC->download_fp = fopen(pathname, "a"); + if (CC->download_fp != NULL) + fclose(CC->download_fp); /* now open it */ - CC->download_fp = fopen(pathname,"r"); - if (CC->download_fp==NULL) { + CC->download_fp = fopen(pathname, "r"); + if (CC->download_fp == NULL) { cprintf("%d cannot open %s: %s\n", - ERROR,pathname,strerror(errno)); + ERROR, pathname, strerror(errno)); return; - } + } /* set this flag so other routines know that the download file @@ -679,9 +716,9 @@ void cmd_ndop(char *cmdbuf) */ CC->dl_is_net = 1; - stat(pathname,&statbuf); - cprintf("%d %ld\n",OK,statbuf.st_size); - } + stat(pathname, &statbuf); + cprintf("%d %ld\n", OK, statbuf.st_size); +} /* * cmd_nuop() - open a network spool file for uploading @@ -690,37 +727,38 @@ void cmd_nuop(char *cmdbuf) { static int seq = 1; - if (strlen(CC->net_node)==0) { + if (strlen(CC->net_node) == 0) { cprintf("%d Not authenticated as a network node.\n", - ERROR+NOT_LOGGED_IN); + ERROR + NOT_LOGGED_IN); return; - } + } if (CC->upload_fp != NULL) { - cprintf("%d You already have an upload file open.\n",ERROR); + cprintf("%d You already have an upload file open.\n", + ERROR); return; - } + } snprintf(CC->upl_path, sizeof CC->upl_path, - "%s/network/spoolin/%s.%04x.%04x", - BBSDIR, CC->net_node, getpid(), ++seq); + "%s/network/spoolin/%s.%04x.%04x", + BBSDIR, CC->net_node, getpid(), ++seq); - CC->upload_fp = fopen(CC->upl_path,"r"); + CC->upload_fp = fopen(CC->upl_path, "r"); if (CC->upload_fp != NULL) { fclose(CC->upload_fp); CC->upload_fp = NULL; cprintf("%d '%s' already exists\n", - ERROR+ALREADY_EXISTS,CC->upl_path); + ERROR + ALREADY_EXISTS, CC->upl_path); return; - } + } - CC->upload_fp = fopen(CC->upl_path,"w"); + CC->upload_fp = fopen(CC->upl_path, "w"); if (CC->upload_fp == NULL) { cprintf("%d Cannot open %s: %s\n", - ERROR,CC->upl_path,strerror(errno)); + ERROR, CC->upl_path, strerror(errno)); return; - } + } CC->upload_type = UPL_NET; - cprintf("%d Ok\n",OK); - } + cprintf("%d Ok\n", OK); +} diff --git a/citadel/file_ops.h b/citadel/file_ops.h index 014ae556b..f6c9c9d55 100644 --- a/citadel/file_ops.h +++ b/citadel/file_ops.h @@ -12,6 +12,5 @@ void abort_upl (struct CitContext *who); void cmd_ucls (char *cmd); void cmd_read (char *cmdbuf); void cmd_writ (char *cmdbuf); -void cmd_netp (char *cmdbuf); void cmd_ndop (char *cmdbuf); void cmd_nuop (char *cmdbuf); diff --git a/citadel/serv_network.c b/citadel/serv_network.c index 30dc7fe37..bcadcd917 100644 --- a/citadel/serv_network.c +++ b/citadel/serv_network.c @@ -144,9 +144,10 @@ void write_network_map(void) { /* * 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. + * which is the next hop. If it *is* a neighbor node, we also fill in the + * shared secret. */ -int is_valid_node(char *nexthop, char *node) { +int is_valid_node(char *nexthop, char *secret, char *node) { char *ignetcfg = NULL; int i; char linebuf[SIZ]; @@ -182,6 +183,9 @@ int is_valid_node(char *nexthop, char *node) { if (nexthop != NULL) { strcpy(nexthop, ""); } + if (secret != NULL) { + extract(secret, linebuf, 1); + } retval = 0; } } @@ -286,7 +290,7 @@ void network_spool_msg(long msgnum, void *userdata) { char *instr = NULL; char *newpath = NULL; size_t instr_len = SIZ; - struct CtdlMessage *msg; + struct CtdlMessage *msg = NULL; struct CtdlMessage *imsg; struct ser_ret sermsg; FILE *fp; @@ -396,7 +400,6 @@ void network_spool_msg(long msgnum, void *userdata) { * Now serialize it for transmission */ serialize_message(&sermsg, msg); - CtdlFreeMessage(msg); /* Now send it to every node */ for (nptr = sc->ignet_push_shares; nptr != NULL; @@ -405,13 +408,14 @@ void network_spool_msg(long msgnum, void *userdata) { send = 1; /* Check for valid node name */ - if (is_valid_node(NULL, nptr->name) != 0) { + if (is_valid_node(NULL,NULL,nptr->name) != 0) { lprintf(3, "Invalid node <%s>\n", nptr->name); send = 0; } /* Check for split horizon */ + lprintf(9, "Path is %s\n", msg->cm_fields['P']); bang = num_tokens(msg->cm_fields['P'], '!'); if (bang > 1) for (i=0; i<(bang-1); ++i) { extract_token(buf, msg->cm_fields['P'], @@ -435,6 +439,7 @@ void network_spool_msg(long msgnum, void *userdata) { } } phree(sermsg.ser); + CtdlFreeMessage(msg); } } @@ -631,7 +636,8 @@ void network_process_buffer(char *buffer, long size) { if (strcasecmp(msg->cm_fields['D'], config.c_nodename)) { /* route the message */ - if (is_valid_node(NULL, msg->cm_fields['D']) == 0) { + if (is_valid_node(NULL, NULL, + msg->cm_fields['D']) == 0) { /* prepend our node to the path */ if (msg->cm_fields['P'] != NULL) { @@ -859,6 +865,39 @@ void network_do_queue(void) { } + +/* + * cmd_netp() - authenticate to the server as another Citadel node polling + * for network traffic + */ +void cmd_netp(char *cmdbuf) +{ + char node[SIZ]; + char pass[SIZ]; + + char secret[SIZ]; + char nexthop[SIZ]; + + extract(node, cmdbuf, 0); + extract(pass, cmdbuf, 1); + + if (is_valid_node(nexthop, secret, node) != 0) { + cprintf("%d authentication failed\n", ERROR); + return; + } + + if (strcasecmp(pass, secret)) { + cprintf("%d authentication failed\n", ERROR); + return; + } + + safestrncpy(CC->net_node, node, sizeof CC->net_node); + cprintf("%d authenticated as network node '%s'\n", OK, + CC->net_node); +} + + + /* * Module entry point */ @@ -866,6 +905,7 @@ char *Dynamic_Module_Init(void) { CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config"); CtdlRegisterProtoHook(cmd_snet, "SNET", "Get network config"); + CtdlRegisterProtoHook(cmd_netp, "NETP", "Identify as network poller"); CtdlRegisterSessionHook(network_do_queue, EVT_TIMER); return "$Id$"; } diff --git a/citadel/tools.c b/citadel/tools.c index 28e5c4789..8ff62786d 100644 --- a/citadel/tools.c +++ b/citadel/tools.c @@ -75,6 +75,7 @@ int num_tokens(char *source, char tok) { int a; int count = 1; + if (source == NULL) return(0); for (a=0; a