Commit d51367d8 authored by rswindell's avatar rswindell
Browse files

Added buffer (filename) overflow protection to smb_getattachment().

parent 5e21f113
......@@ -57,7 +57,7 @@ int sbbs_t::loadmsg(smbmsg_t *msg, ulong number)
if((i=smb_lockmsghdr(&smb,msg)) != SMB_SUCCESS) {
errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
return i;
return i;
}
i=smb_getmsghdr(&smb,msg);
......@@ -68,7 +68,7 @@ int sbbs_t::loadmsg(smbmsg_t *msg, ulong number)
smb_freemsgmem(msg);
}
smb_unlockmsghdr(&smb,msg);
smb_unlockmsghdr(&smb,msg);
}
msg->hdr.number=number;
......@@ -155,7 +155,7 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg)
if(msg->from_ext)
bprintf(text[MsgFromExt],msg->from_ext);
if(msg->from_net.addr!=NULL && strchr(msg->from,'@')==NULL)
bprintf(text[MsgFromNet],smb_netaddrstr(&msg->from_net,str));
bprintf(text[MsgFromNet],smb_netaddrstr(&msg->from_net,str));
}
if(!(msg->hdr.attr&MSG_POLL) && (msg->upvotes || msg->downvotes))
bprintf(text[MsgVotes]
......@@ -173,7 +173,7 @@ void sbbs_t::show_msghdr(smb_t* smb, smbmsg_t* msg)
sender=(char *)msg->hfield_dat[i];
if(msg->hfield[i].type==FORWARDED && sender)
bprintf(text[ForwardedFrom],sender
,timestr(*(time32_t *)msg->hfield_dat[i]));
,timestr(*(time32_t *)msg->hfield_dat[i]));
}
this->smb = saved_smb;
}
......@@ -228,7 +228,7 @@ bool sbbs_t::show_msg(smb_t* smb, smbmsg_t* msg, long p_mode, post_t* post)
bool results_visible = false;
if((msg->hdr.auxattr&POLL_RESULTS_MASK) == POLL_RESULTS_OPEN)
results_visible = true;
else if((msg->from_net.type == NET_NONE && sub_op(smb->subnum))
else if((msg->from_net.type == NET_NONE && sub_op(smb->subnum))
|| smb_msg_is_from(msg, cfg.sub[smb->subnum]->misc&SUB_NAME ? useron.name : useron.alias, NET_NONE, NULL))
results_visible = true;
else if((msg->hdr.auxattr&POLL_RESULTS_MASK) == POLL_RESULTS_CLOSED)
......@@ -288,7 +288,7 @@ void sbbs_t::download_msg_attachments(smb_t* smb, smbmsg_t* msg, bool del)
char filename[MAX_PATH+1] = {0};
uint32_t filelen = 0;
uint8_t* filedata;
if((filedata = smb_getattachment(msg, txt, filename, &filelen, attachment_index++)) != NULL
if((filedata = smb_getattachment(msg, txt, filename, sizeof(filename), &filelen, attachment_index++)) != NULL
&& filename[0] != 0 && filelen > 0) {
char tmp[32];
SAFEPRINTF2(str, text[DownloadAttachedFileQ], filename, ultoac(filelen,tmp));
......@@ -350,7 +350,7 @@ void sbbs_t::download_msg_attachments(smb_t* smb, smbmsg_t* msg, bool del)
if(cfg.prot[i]->dlcmd[0]
&& chk_ar(cfg.prot[i]->ar,&useron,&client)) {
sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
strcat(str,tmp);
strcat(str,tmp);
}
ch=(char)getkeys(str,0);
for(i=0;i<cfg.total_prots;i++)
......@@ -373,21 +373,21 @@ void sbbs_t::download_msg_attachments(smb_t* smb, smbmsg_t* msg, bool del)
SAFEPRINTF(str
,"downloaded attached file: %s"
,fd.name);
logline("D-",str);
logline("D-",str);
}
autohangup();
}
}
}
autohangup();
}
}
}
}
if(!p)
break;
tp=p+1;
while(*tp==' ') tp++;
while(*tp==' ') tp++;
}
// Remove the *.in directory, only if its empty
SAFEPRINTF2(fpath, "%sfile/%04u.in", cfg.data_dir, msg->idx.to);
rmdir(fpath);
rmdir(fpath);
}
}
......@@ -403,7 +403,7 @@ bool sbbs_t::msgtotxt(smb_t* smb, smbmsg_t* msg, const char *fname, bool header,
if((out=fnopen(&i,fname,O_WRONLY|O_CREAT|O_APPEND))==NULL) {
errormsg(WHERE,ERR_OPEN,fname,0);
return false;
return false;
}
if(header) {
fprintf(out,"\r\n");
......@@ -421,7 +421,7 @@ bool sbbs_t::msgtotxt(smb_t* smb, smbmsg_t* msg, const char *fname, bool header,
fprintf(out,"\r\nDate : %.24s %s"
,timestr(msg->hdr.when_written.time)
,smb_zonestr(msg->hdr.when_written.zone,NULL));
fprintf(out,"\r\n\r\n");
fprintf(out,"\r\n\r\n");
}
bool result = false;
......@@ -429,7 +429,7 @@ bool sbbs_t::msgtotxt(smb_t* smb, smbmsg_t* msg, const char *fname, bool header,
if(buf!=NULL) {
strip_invalid_attr(buf);
fputs(buf,out);
smb_freemsgtxt(buf);
smb_freemsgtxt(buf);
result = true;
} else if(smb_getmsgdatlen(msg)>2)
errormsg(WHERE,ERR_READ,smb->file,smb_getmsgdatlen(msg));
......@@ -455,7 +455,7 @@ ulong sbbs_t::getmsgnum(uint subnum, time_t t)
smb.subnum=subnum;
if((i=smb_open_index(&smb)) != SMB_SUCCESS) {
errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
return 0;
return 0;
}
int result = smb_getmsgidx_by_time(&smb, &idx, t);
smb_close(&smb);
......@@ -480,17 +480,17 @@ time_t sbbs_t::getmsgtime(uint subnum, ulong ptr)
smb.subnum=subnum;
if((i=smb_open(&smb))!=0) {
errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
return(0);
return(0);
}
if(!filelength(fileno(smb.sid_fp))) { /* Empty base */
smb_close(&smb);
return(0);
return(0);
}
msg.offset=0;
msg.hdr.number=0;
if(smb_getmsgidx(&smb,&msg)) { /* Get first message index */
smb_close(&smb);
return(0);
return(0);
}
if(!ptr || msg.idx.number>=ptr) { /* ptr is before first message */
smb_close(&smb);
......@@ -499,7 +499,7 @@ time_t sbbs_t::getmsgtime(uint subnum, ulong ptr)
if(smb_getlastidx(&smb,&lastidx)) { /* Get last message index */
smb_close(&smb);
return(0);
return(0);
}
if(lastidx.number<ptr) { /* ptr is after last message */
smb_close(&smb);
......@@ -510,7 +510,7 @@ time_t sbbs_t::getmsgtime(uint subnum, ulong ptr)
msg.hdr.number=ptr;
if(!smb_getmsgidx(&smb,&msg)) {
smb_close(&smb);
return(msg.idx.time);
return(msg.idx.time);
}
if(ptr-msg.idx.number < lastidx.number-ptr) {
......@@ -520,10 +520,10 @@ time_t sbbs_t::getmsgtime(uint subnum, ulong ptr)
msg.hdr.number=0;
if(smb_getmsgidx(&smb,&msg) || msg.idx.number>=ptr)
break;
msg.offset++;
msg.offset++;
}
smb_close(&smb);
return(msg.idx.time);
return(msg.idx.time);
}
ptr--;
......@@ -531,7 +531,7 @@ time_t sbbs_t::getmsgtime(uint subnum, ulong ptr)
msg.hdr.number=ptr;
if(!smb_getmsgidx(&smb,&msg))
break;
ptr--;
ptr--;
}
smb_close(&smb);
return(msg.idx.time);
......@@ -562,22 +562,22 @@ ulong sbbs_t::getlastmsg(uint subnum, uint32_t *ptr, time_t *t)
smb.subnum=subnum;
if((i=smb_open(&smb))!=0) {
errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
return(0);
return(0);
}
if(!filelength(fileno(smb.sid_fp))) { /* Empty base */
smb_close(&smb);
return(0);
return(0);
}
if((i=smb_locksmbhdr(&smb))!=0) {
smb_close(&smb);
errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
return(0);
return(0);
}
if((i=smb_getlastidx(&smb,&idx))!=0) {
smb_close(&smb);
errormsg(WHERE,ERR_READ,smb.file,i,smb.last_error);
return(0);
return(0);
}
total=(long)filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
smb_unlocksmbhdr(&smb);
......
......@@ -4377,7 +4377,7 @@ int import_netmail(const char* path, fmsghdr_t hdr, FILE* fp, const char* inboun
}
}
if(stricmp(hdr.to, FIDO_AREAMGR_NAME) == 0
if(stricmp(hdr.to, FIDO_AREAMGR_NAME) == 0
|| stricmp(hdr.to, "SBBSecho") == 0
|| stricmp(hdr.to, FIDO_PING_NAME) == 0) {
fmsgbuf=getfmsg(fp,NULL);
......@@ -5170,7 +5170,7 @@ int export_netmail(void)
char filename[MAX_PATH+1] = {0};
uint32_t filelen = 0;
uint8_t* filedata;
if((filedata = smb_getattachment(&msg, txt, filename, &filelen, /* attachment_index */0)) != NULL
if((filedata = smb_getattachment(&msg, txt, filename, sizeof(filename), &filelen, /* attachment_index */0)) != NULL
&& filename[0] != 0 && filelen > 0) {
lprintf(LOG_DEBUG, "MIME attachment decoded: %s (%lu bytes)", filename, (ulong)filelen);
char outdir[MAX_PATH+1];
......
......@@ -268,7 +268,7 @@ SMBEXPORT void SMBCALL smb_dump_msghdr(FILE* fp, smbmsg_t* msg);
/* smbtxt.c */
SMBEXPORT char* SMBCALL smb_getmsgtxt(smb_t* smb, smbmsg_t* msg, ulong mode);
SMBEXPORT char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf);
SMBEXPORT uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, uint32_t* filelen, int index);
SMBEXPORT uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, size_t filename_len, uint32_t* filelen, int index);
/* smbfile.c */
SMBEXPORT int SMBCALL smb_feof(FILE* fp);
......@@ -286,7 +286,7 @@ SMBEXPORT void SMBCALL smb_rewind(FILE* fp);
SMBEXPORT void SMBCALL smb_clearerr(FILE* fp);
SMBEXPORT int SMBCALL smb_open_fp(smb_t* smb, FILE**, int share);
SMBEXPORT void SMBCALL smb_close_fp(FILE**);
#ifdef __cplusplus
}
#endif
......
......@@ -162,12 +162,12 @@ char* SMBCALL smb_getmsgtxt(smb_t* smb, smbmsg_t* msg, ulong mode)
, __FUNCTION__, l+lzhlen+3L);
free(lzhbuf);
free(buf);
return(NULL);
return(NULL);
}
buf=p;
lzh_decode((uint8_t *)lzhbuf,length,(uint8_t *)buf+l);
free(lzhbuf);
l+=lzhlen;
l+=lzhlen;
}
else {
if((p=(char*)realloc(buf,l+length+3L))==NULL) {
......@@ -190,7 +190,7 @@ char* SMBCALL smb_getmsgtxt(smb_t* smb, smbmsg_t* msg, ulong mode)
l++;
*(buf+l)='\n'; /* LF */
l++;
*(buf+l)=0;
*(buf+l)=0;
}
if(mode&GETMSGTXT_PLAIN) {
......@@ -276,7 +276,7 @@ static enum content_transfer_encoding mime_getxferencoding(char* beg, char* end)
}
/* ToDo: parse and return the "modification-date" value */
static BOOL mime_getattachment(char* beg, char* end, char* attachment)
static BOOL mime_getattachment(char* beg, char* end, char* attachment, size_t attachment_len)
{
char fname[MAX_PATH+1];
char* p = beg;
......@@ -316,7 +316,10 @@ static BOOL mime_getattachment(char* beg, char* end, char* attachment)
term = fname;
FIND_WHITESPACE(term);
*term = 0;
strcpy(attachment, getfname(fname));
if(attachment != NULL && attachment_len > 0) {
strncpy(attachment, getfname(fname), attachment_len);
attachment[attachment_len] = '\0';
}
return TRUE;
}
return FALSE;
......@@ -324,7 +327,7 @@ static BOOL mime_getattachment(char* beg, char* end, char* attachment)
/* Find the specified content-type in a MIME-encoded message body, recursively */
static char* mime_getcontent(char* buf, const char* content_type, const char* content_match
,int depth, enum content_transfer_encoding* encoding, char* attachment, int index)
,int depth, enum content_transfer_encoding* encoding, char* attachment, size_t attachment_len, int index)
{
char* txt;
char* p;
......@@ -333,7 +336,7 @@ static char* mime_getcontent(char* buf, const char* content_type, const char* co
char match2[128];
int match_len = 0;
int found = 0;
if(content_match != NULL) {
match_len = sprintf(match1, "Content-Type: %s;", content_match);
sprintf(match2, "Content-Type: %s\r", content_match);
......@@ -376,13 +379,13 @@ static char* mime_getcontent(char* buf, const char* content_type, const char* co
if(content_type >= p)
continue;
if((match_len && strnicmp(content_type, match1, match_len) && strnicmp(content_type, match2, match_len))
|| (attachment != NULL && !mime_getattachment(txt, p, attachment))) {
if((p = mime_getcontent(p, content_type, content_match, depth + 1, encoding, attachment, index)) != NULL)
|| (attachment != NULL && !mime_getattachment(txt, p, attachment, attachment_len))) {
if((p = mime_getcontent(p, content_type, content_match, depth + 1, encoding, attachment, attachment_len, index)) != NULL)
return p;
continue;
}
if(found++ != index) {
if((p = mime_getcontent(p, content_type, content_match, depth + 1, encoding, attachment, index)) != NULL)
if((p = mime_getcontent(p, content_type, content_match, depth + 1, encoding, attachment, attachment_len, index)) != NULL)
return p;
continue;
}
......@@ -406,8 +409,8 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf)
char* content_type = NULL;
enum content_transfer_encoding xfer_encoding = CONTENT_TRANFER_ENCODING_NONE;
for(i=0;i<msg->total_hfields;i++) {
if(msg->hfield[i].type==RFC822HEADER) {
for(i=0;i<msg->total_hfields;i++) {
if(msg->hfield[i].type==RFC822HEADER) {
if(strnicmp((char*)msg->hfield_dat[i],"Content-Type:",13)==0) {
content_type=msg->hfield_dat[i];
break;
......@@ -417,7 +420,7 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf)
if(content_type == NULL) /* not MIME */
return NULL;
txt = mime_getcontent(buf, content_type, "text/plain", 0, &xfer_encoding
,/* attachment: */NULL, /* index: */0);
,/* attachment: */NULL, /* attachment_len: */0, /* index: */0);
if(txt == NULL)
return NULL;
......@@ -439,15 +442,15 @@ char* SMBCALL smb_getplaintext(smbmsg_t* msg, char* buf)
}
/* Get just an attachment (just one) from MIME-encoded message body */
uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, uint32_t* filelen, int index)
uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, size_t filename_len, uint32_t* filelen, int index)
{
int i;
char* txt;
char* content_type = NULL;
enum content_transfer_encoding xfer_encoding = CONTENT_TRANFER_ENCODING_NONE;
for(i=0;i<msg->total_hfields;i++) {
if(msg->hfield[i].type==RFC822HEADER) {
for(i=0;i<msg->total_hfields;i++) {
if(msg->hfield[i].type==RFC822HEADER) {
if(strnicmp((char*)msg->hfield_dat[i],"Content-Type:",13)==0) {
content_type=msg->hfield_dat[i];
break;
......@@ -457,7 +460,7 @@ uint8_t* SMBCALL smb_getattachment(smbmsg_t* msg, char* buf, char* filename, uin
if(content_type == NULL) /* not MIME */
return NULL;
txt = mime_getcontent(buf, content_type, /* match-type: */NULL, 0, &xfer_encoding
,/* attachment: */filename, index);
,/* attachment: */filename, filename_len, index);
if(txt != NULL && xfer_encoding == CONTENT_TRANFER_ENCODING_BASE64) {
memmove(buf, txt, strlen(txt)+1);
int result = b64_decode(buf, strlen(buf), buf, strlen(buf));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment