summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2011-04-27 10:10:00 (UTC)
committer Michael Krelin <hacker@klever.net>2011-04-27 10:10:00 (UTC)
commitd097b824b7fcad001c9581fb2e322bf3e3e5961d (patch) (side-by-side diff)
tree5a1c55e82c4b0ff4acca276b8e1122547530cc0b
parent65981784977659461f08b48f537be9f9f77a2112 (diff)
downloadpumpkin-d097b824b7fcad001c9581fb2e322bf3e3e5961d.zip
pumpkin-d097b824b7fcad001c9581fb2e322bf3e3e5961d.tar.gz
pumpkin-d097b824b7fcad001c9581fb2e322bf3e3e5961d.tar.bz2
fix for misleading error message about unexpected source
along with a double-freeing offense. When I fail to receive packet not only I diagnose this unfortunate development, but also start talking about packet from unexpected source which is kinda weird considering there's no packet at all. Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (show whitespace changes)
-rwxr-xr-x[-rw-r--r--]PumpKINDlg.cpp1
1 files changed, 1 insertions, 0 deletions
diff --git a/PumpKINDlg.cpp b/PumpKINDlg.cpp
index f41b69f..3ff1500 100644..100755
--- a/PumpKINDlg.cpp
+++ b/PumpKINDlg.cpp
@@ -476,256 +476,257 @@ int saddrLen = sizeof(SOCKADDR_IN);
UINT tftp::Opcode()
{
return REVERSEBYTES(opcode);
}
CString tftp::rqFileName()
{
ASSERT(length);
ASSERT(Opcode()==opRRQ || Opcode()==opWRQ);
CString rv;
if(memchr(&data.m_RQ.data,0,length-sizeof(opcode)))
rv = (LPCTSTR)data.m_RQ.data;
return rv;
}
CString tftp::rqType()
{
ASSERT(length);
ASSERT(Opcode()==opRRQ || Opcode()==opWRQ);
CString rv;
char *tmp = (char*)memchr(&data.m_RQ.data,0,length-sizeof(opcode));
if(tmp++)
rv = (LPCTSTR)tmp;
return rv;
}
UINT tftp::GetOptions(tftp::tftpOptions* ops)
{
ASSERT(length);
ASSERT(Opcode()==opRRQ || Opcode()==opWRQ || Opcode()==opOACK);
ASSERT(ops);
tftpOptions& o = *ops;
LPSTR base = (LPSTR)&data.m_RQ.data;
UINT basePtr = 0;
if(Opcode()==opRRQ || Opcode()==opWRQ){
base = (LPSTR)memchr(&data.m_RQ.data,0,length-sizeof(opcode));
if(!base)
return 0;
base++;
basePtr = (base-(LPSTR)&data.m_RQ.data);
base = (LPSTR)memchr(base,0,length-basePtr);
if(!base)
return 0;
base++;
basePtr = (base-(LPSTR)&data.m_RQ.data);
}
ops->RemoveAll();
UINT rv = 0;
while(basePtr<(length-sizeof(opcode))){
CString onam = (LPSTR)&data.m_RQ.data[basePtr];
basePtr+=onam.GetLength()+1;
CString oval = (LPSTR)&data.m_RQ.data[basePtr];
basePtr+=oval.GetLength()+1;
onam.MakeLower();
o[onam]=oval;
rv++;
}
return rv;
}
tftp::tftp()
{
length=0;
}
void CXferSocket::OnSend(int nErrorCode)
{
if(nErrorCode){
ASSERT(m_Daddy);
m_Daddy->LogLine(IDS_LOG_XFERSEND);
return;
}
if(!m_Queue.IsEmpty()){
tftp *p = m_Queue.GetHead();
ASSERT(p);
m_Queue.RemoveHead();
if(!p->Send(this,&m_Peer)){
ASSERT(m_Daddy);
m_Daddy->LogLine(IDS_LOG_XFERUDPSEND);
}
delete p;
}
DoSelect();
if(m_Queue.IsEmpty()){
switch(state){
case stateDeny:
Destroy(FALSE);
break;
case stateFinish:
Destroy(TRUE);
break;
}
}
}
BOOL tftp::Send(CAsyncSocket *socket,SOCKADDR_IN* saddr)
{
ASSERT(socket);
int rv = socket->SendTo(udpBase(),length,(SOCKADDR*)saddr,sizeof(SOCKADDR_IN));
if(rv!=length)
return FALSE;
return TRUE;
}
void CXferSocket::DoSelect(BOOL do_select)
{
if(m_Peer.sin_addr.s_addr!=INADDR_NONE)
AsyncSelect(FD_CLOSE|FD_READ|((m_Queue.IsEmpty()&&!do_select)?0:FD_WRITE));
}
void CXferSocket::OnReceive(int nErrorCode)
{
if(nErrorCode){
ASSERT(m_Daddy);
m_Daddy->LogLine(IDS_LOG_XFERRECEIVE);
return;
}
ASSERT(m_Daddy);
DWORD fionread = 0;
VERIFY(IOCtl(FIONREAD,&fionread));
tftp *p = tftp::Allocate(fionread);
ASSERT(p);
SOCKADDR_IN sin;
if(!p->Receive(this,fionread,&sin)){
m_Daddy->LogLine(IDS_LOG_XFERUDPRECEIVE);
delete p;
+ return;
}else
if(m_Peer.sin_addr.s_addr==INADDR_NONE){
m_Peer.sin_addr=sin.sin_addr;
m_Peer.sin_port=sin.sin_port;
}
BOOL alive = TRUE;
if(state==stateInit){
state=stateXfer;
m_Peer.sin_port=sin.sin_port;
UpdateList();
}
if(sin.sin_addr.s_addr!=m_Peer.sin_addr.s_addr || sin.sin_port!=m_Peer.sin_port){
m_Daddy->LogLine(IDS_LOG_XFERSOURCETID);
// *** Bounce it!
}else{
alive = OnTFTP(p);
}
delete p;
if(alive){
DoSelect();
ResetTimeout();
}
}
void CXferSocket::SetPeer(SOCKADDR_IN *sin)
{
ASSERT(sin);
memmove(&m_Peer,sin,sizeof(m_Peer));
}
void CXferSocket::UpdateList()
{
ASSERT(m_Daddy);
LV_FINDINFO lvf;
memset(&lvf,0,sizeof(lvf));
lvf.flags=LVFI_PARAM;
lvf.lParam=(LPARAM)this;
int i = m_Daddy->m_List.FindItem(&lvf);
if(i<0){
ASSERT(IsKindOf(RUNTIME_CLASS(CRRQSocket)) || IsKindOf(RUNTIME_CLASS(CWRQSocket)));
i=m_Daddy->m_List.InsertItem(0,m_FileName,IsKindOf(RUNTIME_CLASS(CRRQSocket))?m_Daddy->m_iRRQ:m_Daddy->m_iWRQ);
ASSERT(!(i<0));
m_Daddy->m_List.SetItemData(i,(DWORD)this);
}
m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemFile,m_FileName);
m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemType,m_Type);
m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemPeer,inet_ntoa(m_Peer.sin_addr));
CString tmp;
tmp.Format(IDS_FMT_BYTES,GetACK());
m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemBytes,tmp);
if(m_xferSize>=0){
tmp.Format(IDS_FMT_BYTES,m_xferSize);
m_Daddy->m_List.SetItemText(i,CPumpKINDlg::subitemTSize,tmp);
}
}
CXferSocket::CXferSocket()
: m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE),
m_blkSize(512), m_timeOut(30), m_xferSize(-1),
m__blkSize(512), m__timeOut(30)
{
m_Daddy=NULL;
m_Peer.sin_addr.s_addr=INADDR_NONE;
m_Peer.sin_family=AF_INET;
state=stateNone;
}
ULONG CXferSocket::GetACK()
{
return 0;
}
CXferSocket::CXferSocket(CPumpKINDlg *daddy,LPCTSTR fileName,LPCTSTR type,SOCKADDR_IN* sin)
: m_wndResolver(NULL), m_Retry(NULL), m_bRetry(FALSE),
m_blkSize(512), m_timeOut(30), m_xferSize(-1),
m__blkSize(512), m__timeOut(30)
{
m_Peer.sin_family=AF_INET;
state=stateNone;
ASSERT(daddy);
m_Daddy=daddy;
m_timeOut=m__timeOut=m_Daddy->m_TFTPTimeOut.GetTotalSeconds();
if(sin){
m_Peer.sin_addr.s_addr=sin->sin_addr.s_addr;
m_Peer.sin_port=sin->sin_port;
}else
m_Peer.sin_addr.s_addr=INADDR_NONE;
m_FileName=fileName;
m_Type=type;
}
BOOL CRRQSocket::Create(LPCTSTR localFile,LPCTSTR hostName)
{
if(!CAsyncSocket::Create(0,SOCK_DGRAM))
return FALSE;
ASSERT(m_Daddy);
ASSERT(m_Peer.sin_addr.s_addr!=INADDR_NONE || hostName);
m_Daddy->m_Xfers[m_hSocket]=this;
CString lFile = localFile?localFile:m_FileName;
TurnSlashes(lFile,TRUE);
UpdateList();
if(!localFile){ // Check only for incoming requests
if(CheckBadRelativeness(m_FileName)){
Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
return TRUE;
}
int atar=m_Daddy->m_aclRules.FindTarget(acl_rule::opRRQ,m_Peer.sin_addr.s_addr);
if(atar<0)
atar = m_Daddy->m_RRQMode;
switch(atar){
case CPumpKINDlg::rrqGiveAll:
break;
case CPumpKINDlg::rrqAlwaysConfirm:
if(ConfirmRequest())
break;
default:
TRACE1("Unexpected access target: %d\n",atar);
case CPumpKINDlg::rrqDenyAll:
Deny(tftp::errAccessViolation,IDS_TFTP_ERROR_ACCESS);
return TRUE;
}
}
CString fn = localFile?ApplyRootGently(lFile):ApplyRoot(lFile);
CFileException e;
if(!m_File.Open(fn,CFile::modeRead|CFile::shareDenyWrite,&e)){
if(localFile){
CString tmp;
tmp.Format(IDS_LOG_FAILEDLOCALFILE,fn);