Linux 版 (精华区)
发信人: tcpip (干打雷,不下雨), 信区: Linux
标 题: 对bbs2www1.23中两个BUG的修改(转寄)
发信站: 哈工大紫丁香 (Mon Aug 9 18:43:54 1999), 转信
发信人: Keyboy (峰清扬), 信区: BBSMan_Dev
标 题: 对bbs2www 1.23中两个BUG的修改
发信站: BBS 水木清华站 (Wed Aug 4 21:37:50 1999)
我刚刚试用了7月28日发布的BBS2WWW 1.23, 感觉相当不错, 不过有两个一直存
在的BUG还是没解决:
1. 在某个版被封了POST的ID仍可以通过WWW-POST在该版发表文章;
2. 普通的TELNET登录者在匿名版发表文章时, 发表者的ID和昵称分别是该版英
文版名和"我是匿名天使", 文章来源是"匿名天使之家"; 但BBS2WWW在WWW方
式发表文章时未区分匿名版.
我针对上述的BUG对bbssnd.c作了一点修改, 下面贴出完整的源代码, 程序中由
"Modification by Rick" 标记我添加或修改代码. 检查ID在某版的POST权限是
通过检查对应 board 目录下的 deny_users 文件实现的. FFireBird本身的源代
码中还对ID是否具有SYSOP权限进行了检查, 如果是ID具有O权限,则不受封POST
的限制, 在我作的修改中也加入了这一部分检查. 检查某版是否为匿名版则是
通过 header.flag & ANONY_FLAG 来实现的.
示范站点是: http://www2.cs.uestc.edu.cn/cgi-bin/bbssec
下面是 bbssnd.c, 略去了开头的注释:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#define _XOPEN_SOURCE
#include <unistd.h>
#include "bbs2www.h"
#define PERM_POST 000010
#define PERM(x) ((x)?record.userlevel&(x):1)
char *crypt();
void plustospace(char *str)
{
register int x;
for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' ';
}
char x2c(char *what) {
register char digit;
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')
); digit *= 16;
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'
)); return(digit);
}
void unescape_url(char *url) {
register int x,y;
for(x=0,y=0;url[y];++x,++y) {
if((url[x] = url[y]) == '%') {
url[x] = x2c(&url[y+1]);
y+=2;
}
}
url[x] = '\0';
}
char *read_form(char *buf, char *str, char *match, int length)
{
int i;
buf = strstr(buf, match);
if(buf != NULL)
buf += strlen(match);
else
{
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf("Error input! \n");
exit(1);
}
for(i = 0; buf[i] != '&'; i++)
{
if(i == length -1)
break;
str[i] = buf[i];
}
str[i] = '\0';
plustospace(str);
unescape_url(str);
}
void main (int argc, char *argv[])
{
FILE *fout, *fidx;
char *buf, *ptr, *ptr1, *pw, article[256], board[15], buf1[256],
filename[STRLEN],passwd[20], title[100], username[20];
int i, color, length, exchange = 1, fh, found = 0;
struct boardheader brdhdr;
struct fileheader header;
struct userec record;
time_t now;
length = atoi(getenv("CONTENT_LENGTH"));
ptr = buf = (char *)malloc(length + 1);
buf[length] = '\0';
fread(buf, sizeof(char), length, stdin);
read_form(buf, board, "board=", 15);
if(strstr(buf, "exchange=N") != NULL)
exchange = 0;
read_form(buf, title, "title=", 100);
read_form(buf, username, "username=", 20);
read_form(buf, passwd, "passwd=", 20);
if((buf = strstr(buf, "text=")) == NULL)
{
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf("input error!\n");
exit(1);
}
else
buf += 5;
plustospace(buf);
unescape_url(buf);
if (username[0] != '\0' && passwd[0] != '\0')
{
now = time(NULL);
sprintf(filename, "%sboards/%s/.DIR", BBSHOME, board);
if( (fidx = fopen(filename, "r+" )) == NULL ) {
if( (fidx = fopen(filename, "w+" )) == NULL ) {
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf( ":err: unable to post in %s board.\n", board);
exit(1);
}
}
sprintf(filename, "%s.PASSWDS", BBSHOME);
if( (fh = open(filename, O_RDWR)) == -1 ) {
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf( ":err: unable to open .PASSWDS file.\n" );
exit( 0 );
}
while( read( fh, &record, sizeof(record) ) > 0 ) {
if( strcasecmp( username, record.userid ) == 0 ) {
strcpy( username, record.userid );
pw = crypt( passwd, record.passwd );
if( strcmp( pw, record.passwd ) != 0 ) {
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf( ":err: user '%s' password incorrect!!\n",
record.userid );
exit(0);
}
if (!strstr(board, "test"))
record.numposts++;
record.lastlogin = now;
lseek( fh, -1 * sizeof(record), SEEK_CUR);
write( fh, &record, sizeof(record) );
found = 1;
break;
}
}
close(fh);
if (!found)
{
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf( ":err: unknown userid %s\n", username );
exit( 0 );
}
found = 0;
sprintf(filename, "%s.BOARDS", BBSHOME);
if((fh = open(filename, O_RDONLY, 0)) == -1)
{
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf( ":err: unable to open .BOARDS file.\n" );
exit( 0 );
}
while (read(fh, &brdhdr, sizeof(brdhdr)) == sizeof(brdhdr))
if (strcasecmp(brdhdr.filename, board) == 0)
{
found = 1;
break;
}
close(fh);
if (!found)
{
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf( ":err: unknown board %s\n", board);
exit( 0 );
}
/* Added by Rick (rick@88998.com) . 1999.8.4.
** Check whether the user is denied for this board or not
*/
if (!PERM(PERM_SYSOP)) {
sprintf(filename, "%sboards/%s/deny_users", BBSHOME, board);
if ((fout = fopen(filename, "r")) != NULL) {
while (fgets(buf1, sizeof(buf1) - 1, fout)) {
if (strncasecmp(buf1, username, strlen(username)) == 0) {
printf ("Content-type: text/html; charset=gb2312\n\n\n");
printf (":err: Your post right for %s board has been stopped
by the board master.<br>", board); fclose (fout);
exit(1);
}
}
fclose(fout);
}
}
/* end here */
if (!PERM(PERM_POST) || !PERM(brdhdr.level))
{
printf("Content-type: text/html; charset=gb2312\n\n\n");
printf(":err: user %s have no right to post at %s board.",
username, board);
exit(0);
}
sprintf(filename, "M.%d.A", now);
ptr1 = strrchr(filename, 'A' );
while( 1 ) {
sprintf( article, "%sboards/%s/%s", BBSHOME, board, filename );
fh = open( article, O_CREAT | O_EXCL | O_WRONLY, 0644 );
if( fh != -1 ) break;
if( *ptr1 < 'z' ) (*ptr1)++;
else ptr1++, *ptr1 = 'a', ptr1[1] = '\0';
}
color=(record.numlogins%7)+31;
/* Modified by Rick (rick@88998.com) . 1999.8.3 */
sprintf(buf1, "发信人: %s (%s), 信区: %s\n标 题: %s\n发信站: %s (%.2
4s) , %s\n\n", (brdhdr.flag & ANONY_FLAG)?board:record.userid,
(brdhdr.flag & ANONY_FLAG)?"我是匿名天使":record.username,
brdhdr.filename, title, BBSNAME, ctime(&now), exchange?"转信":"站内
信件"); write(fh, buf1, strlen(buf1));
write(fh, buf, strlen(buf));
#ifdef HIDE_IP
sprintf(buf1,"\n--\n%c[1;%2dm※ 来源: %s %s. [FROM: WWW] %c[m\n",
27, color, BBSNAME, BBSDOMAIN, 27);
#else
sprintf(buf1,"\n--\n%c[1;%2dm※ 来源: %s WWW %s. [FROM: %.20s] %c[m\
n", 27, color, BBSNAME, BBSDOMAIN,
(brdhdr.flag & ANONY_FLAG)?"匿名天使的家":getenv("R
EMOTE_ADDR"), 27); #endif
/* Modification end here */
write(fh, buf1, strlen(buf1));
close(fh);
}
bzero( (void *)&header, sizeof( header ) );
strcpy( header.filename, filename);
/* Modified by Rick(rick@88998.com). 1999.8.4 */
strncpy( header.owner, (brdhdr.flag & ANONY_FLAG)?board:record.userid, I
DLEN ); /* Modification end. */
strncpy( header.title, title, STRLEN );
fseek(fidx, 0, SEEK_END);
fwrite(&header, sizeof(header), 1, fidx);
fclose(fidx);
free(ptr);
printf("Location: %s/bbsdoc?N%s\n\n", BBSCGI, board);
}
--
We were moving mountains long before we know we could.
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.115.16
.15]
--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: bin@mtlab.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:205.121毫秒