home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 217 / DPCS0306DVD.ISO / Toolkit / Internet / FileZilla / Server / FileZilla_Server-0.9.11.exe / source / interface / AdminSocket.cpp next >
Encoding:
C/C++ Source or Header  |  2005-01-21  |  11.7 KB  |  486 lines

  1. // FileZilla Server - a Windows ftp server
  2.  
  3. // Copyright (C) 2002-2004 - Tim Kosse <tim.kosse@gmx.de>
  4.  
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9.  
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. // AdminSocket.cpp: Implementierung der Klasse CAdminSocket.
  20. //
  21. //////////////////////////////////////////////////////////////////////
  22.  
  23. #include "stdafx.h"
  24. #include "AdminSocket.h"
  25. #include "MainFrm.h"
  26. #include "..\OptionTypes.h"
  27. #include "..\platform.h"
  28. #include "misc\md5.h"
  29.  
  30. //////////////////////////////////////////////////////////////////////
  31. // Konstruktion/Destruktion
  32. //////////////////////////////////////////////////////////////////////
  33.  
  34. #define BUFSIZE 4096
  35.  
  36. CAdminSocket::CAdminSocket(CMainFrame *pMainFrame)
  37. {
  38.     ASSERT(pMainFrame);
  39.     m_pMainFrame = pMainFrame;
  40.     m_pRecvBuffer = new unsigned char[BUFSIZE];
  41.     m_nRecvBufferLen = BUFSIZE;
  42.     m_nRecvBufferPos = 0;
  43.     m_nConnectionState = 0;
  44.     m_bClosed = FALSE;
  45. }
  46.  
  47. CAdminSocket::~CAdminSocket()
  48. {
  49.     delete [] m_pRecvBuffer;
  50.     
  51.     for (std::list<t_data>::iterator iter=m_SendBuffer.begin(); iter!=m_SendBuffer.end(); iter++)
  52.         delete [] iter->pData;
  53. }
  54.  
  55. void CAdminSocket::OnConnect(int nErrorCode)
  56. {
  57.     if (!nErrorCode)
  58.     {
  59.         if (!m_nConnectionState)
  60.         {
  61.             m_pMainFrame->ShowStatus(_T("Connected, waiting for authentication"), 0);
  62.             m_nConnectionState = 1;
  63.         }
  64.         m_pMainFrame->OnAdminInterfaceConnected();
  65.     }
  66.     else
  67.     {
  68.         m_pMainFrame->ShowStatus(_T("Error, could not connect to server"), 1);
  69.         Close();
  70.     }
  71. }
  72.  
  73. void CAdminSocket::OnReceive(int nErrorCode)
  74. {
  75.     if (nErrorCode)
  76.     {
  77.         m_pMainFrame->ShowStatus(_T("OnReceive failed, closing connection"), 1);
  78.         Close();
  79.         return;
  80.     }
  81.     
  82.     if (!m_nConnectionState)
  83.     {
  84.         m_pMainFrame->ShowStatus(_T("Connected, waiting for authentication"), 0);
  85.         m_nConnectionState = 1;
  86.     }
  87.  
  88.     int numread = Receive(m_pRecvBuffer + m_nRecvBufferPos, m_nRecvBufferLen - m_nRecvBufferPos);
  89.     if (numread > 0)
  90.     {
  91.         m_nRecvBufferPos += numread;
  92.         if (m_nRecvBufferLen-m_nRecvBufferPos < (BUFSIZE/4))
  93.         {
  94.             unsigned char *tmp = m_pRecvBuffer;
  95.             m_nRecvBufferLen += BUFSIZE;
  96.             m_pRecvBuffer = new unsigned char[m_nRecvBufferLen];
  97.             memcpy(m_pRecvBuffer, tmp, m_nRecvBufferPos);
  98.             delete [] tmp;
  99.         }
  100.     }
  101.     if (!numread)
  102.     {
  103.         Close();
  104.         return;
  105.     }
  106.     else if (numread == SOCKET_ERROR)
  107.     {
  108.         if (WSAGetLastError() != WSAEWOULDBLOCK)
  109.         {
  110.             Close();
  111.             return;
  112.         }
  113.     }
  114.     while (ParseRecvBuffer());
  115. }
  116.  
  117. void CAdminSocket::OnSend(int nErrorCode)
  118. {
  119.     if (nErrorCode)
  120.     {
  121.         Close();
  122.         return;
  123.     }
  124.     if (!m_nConnectionState)
  125.         return;
  126.  
  127.     while (!m_SendBuffer.empty())
  128.     {
  129.         t_data data=m_SendBuffer.front();
  130.         int nSent = Send(data.pData+data.dwOffset, data.dwLength-data.dwOffset);
  131.         if (!nSent)
  132.         {
  133.             Close();
  134.             return;
  135.         }
  136.         if (nSent == SOCKET_ERROR)
  137.         {
  138.             if (WSAGetLastError()!=WSAEWOULDBLOCK)
  139.                 Close();
  140.             return;
  141.         }
  142.         
  143.         if ((DWORD)nSent < (data.dwLength-data.dwOffset))
  144.             data.dwOffset+=nSent;
  145.         else
  146.         {
  147.             m_SendBuffer.pop_front();
  148.             delete [] data.pData;
  149.         }
  150.     }
  151. }
  152.  
  153. void CAdminSocket::Close()
  154. {
  155.     if (m_nConnectionState)
  156.         m_pMainFrame->ShowStatus(_T("Connection to server closed."), 1);
  157.     m_nConnectionState = 0;
  158.     if (!m_bClosed)
  159.     {
  160.         m_bClosed = TRUE;
  161.         m_pMainFrame->PostMessage(WM_APP + 1, 0, 0);
  162.     }
  163. }
  164.  
  165. BOOL CAdminSocket::ParseRecvBuffer()
  166. {
  167.     DWORD len;
  168.     switch (m_nConnectionState)
  169.     {
  170.     case 1:
  171.         {
  172.             if (m_nRecvBufferPos<3)
  173.                 return FALSE;
  174.             if (m_pRecvBuffer[0]!='F' || m_pRecvBuffer[1]!='Z' || m_pRecvBuffer[2]!='S')
  175.             {
  176.                 CString str;
  177.                 str.Format(_T("Protocol error: Unknown protocol identifier (0x%d 0x%d 0x%d)."), (int)m_pRecvBuffer[0], (int)m_pRecvBuffer[1], (int)m_pRecvBuffer[2]);
  178.                 m_pMainFrame->ShowStatus(str, 1);
  179.                 Close();
  180.                 return FALSE;
  181.             }
  182.             if (m_nRecvBufferPos<5)
  183.                 return FALSE;
  184.             int len = m_pRecvBuffer[3]*256 + m_pRecvBuffer[4];
  185.             if (len != 4)
  186.             {
  187.                 CString str;
  188.                 str.Format(_T("Protocol error: Invalid server version length (%d)."), len);
  189.                 m_pMainFrame->ShowStatus(str, 1);
  190.                 Close();
  191.                 return FALSE;
  192.             }
  193.             if (m_nRecvBufferPos<9)
  194.                 return FALSE;
  195.             
  196.             int version = (int)GET32(m_pRecvBuffer + 5);
  197.             if (version != SERVER_VERSION)
  198.             {
  199.                 CString str;
  200.                 str.Format(_T("Protocol warning: Server version mismatch: Server version is %d.%d.%d.%d, interface version is %d.%d.%d.%d"),
  201.                            (version >> 24) & 0xFF,
  202.                            (version >> 16) & 0xFF,
  203.                            (version >>  8) & 0xFF,
  204.                            (version >>  0) & 0xFF,
  205.                            (SERVER_VERSION >> 24) & 0xFF,
  206.                            (SERVER_VERSION >> 16) & 0xFF,
  207.                            (SERVER_VERSION >>  8) & 0xFF,
  208.                            (SERVER_VERSION >>  0) & 0xFF);
  209.                 m_pMainFrame->ShowStatus(str, 1);
  210.             }
  211.  
  212.             if (m_nRecvBufferPos<11)
  213.                 return FALSE;
  214.             len = m_pRecvBuffer[9]*256 + m_pRecvBuffer[10];
  215.             if (len != 4)
  216.             {
  217.                 CString str;
  218.                 str.Format(_T("Protocol error: Invalid protocol version length (%d)."), len);
  219.                 m_pMainFrame->ShowStatus(str, 1);
  220.                 Close();
  221.                 return FALSE;
  222.             }
  223.             if (m_nRecvBufferPos<15)
  224.                 return FALSE;
  225.             version = (int)GET32(m_pRecvBuffer + 11);
  226.             if (version != PROTOCOL_VERSION)
  227.             {
  228.                 CString str;
  229.                 str.Format(_T("Protocol error: Protocol version mismatch: Server protocol version is %d.%d.%d.%d, interface protocol version is %d.%d.%d.%d"),
  230.                            (version >> 24) & 0xFF,
  231.                            (version >> 16) & 0xFF,
  232.                            (version >>  8) & 0xFF,
  233.                            (version >>  0) & 0xFF,
  234.                            (PROTOCOL_VERSION >> 24) & 0xFF,
  235.                            (PROTOCOL_VERSION >> 16) & 0xFF,
  236.                            (PROTOCOL_VERSION >>  8) & 0xFF,
  237.                            (PROTOCOL_VERSION >>  0) & 0xFF);
  238.                 m_pMainFrame->ShowStatus(str, 1);
  239.                 Close();
  240.                 return FALSE;
  241.             }
  242.  
  243.             memmove(m_pRecvBuffer, m_pRecvBuffer+15, m_nRecvBufferPos-15);
  244.             m_nRecvBufferPos-=15;
  245.             m_nConnectionState = 2;
  246.         }
  247.         break;
  248.     case 2:
  249.         if (m_nRecvBufferPos<5)
  250.             return FALSE;
  251.         if ((m_pRecvBuffer[0]&0x03) > 2)
  252.         {
  253.             CString str;
  254.             str.Format(_T("Protocol error: Unknown command type (%d), closing connection."), (int)(m_pRecvBuffer[0]&0x03));
  255.             m_pMainFrame->ShowStatus(str, 1);
  256.             Close();
  257.             return FALSE;
  258.         }
  259.         len = (int)GET32(m_pRecvBuffer + 1);
  260.         if (len + 5 <= m_nRecvBufferPos)
  261.         {
  262.             if ((m_pRecvBuffer[0]&0x03) == 0  &&  (m_pRecvBuffer[0]&0x7C)>>2 == 0)
  263.             {
  264.                 if (len<4)
  265.                 {
  266.                     m_pMainFrame->ShowStatus(_T("Invalid auth data"), 1);
  267.                     Close();
  268.                     return FALSE;
  269.                 }
  270.                 unsigned char *p = m_pRecvBuffer + 5;
  271.                 
  272.                 unsigned int noncelen1 = *p*256 + p[1];
  273.                 if ((noncelen1+2) > (len-2))
  274.                 {
  275.                     m_pMainFrame->ShowStatus(_T("Invalid auth data"), 1);
  276.                     Close();
  277.                     return FALSE;
  278.                 }
  279.                 
  280.                 unsigned int noncelen2 = p[2 + noncelen1]*256 + p[2 + noncelen1 +1];
  281.                 if ((noncelen1+noncelen2+4) > len)
  282.                 {
  283.                     m_pMainFrame->ShowStatus(_T("Invalid auth data"), 1);
  284.                     Close();
  285.                     return FALSE;
  286.                 }
  287.                 
  288.                 MD5 md5;
  289.                 if (noncelen1)
  290.                     md5.update(p+2, noncelen1);
  291.                 md5.update((const unsigned char *)(const char *)m_Password, m_Password.GetLength());
  292.                 if (noncelen2)
  293.                     md5.update(p+noncelen1+4, noncelen2);
  294.                 md5.finalize();
  295.                 
  296.                 memmove(m_pRecvBuffer, m_pRecvBuffer+len+5, m_nRecvBufferPos-len-5);
  297.                 m_nRecvBufferPos-=len+5;
  298.                 
  299.                 unsigned char *digest = md5.raw_digest();
  300.                 SendCommand(0, digest, 16);
  301.                 delete [] digest;
  302.                 m_nConnectionState=3;
  303.                 return TRUE;
  304.             }
  305.             else if ((m_pRecvBuffer[0]&0x03) == 1  &&  (m_pRecvBuffer[0]&0x7C)>>2 == 0)
  306.             {
  307.                 m_nConnectionState=3;
  308.                 m_pMainFrame->ParseReply((m_pRecvBuffer[0]&0x7C)>>2, m_pRecvBuffer+5, len);
  309.             }
  310.             else
  311.             {
  312.                 CString str;
  313.                 str.Format(_T("Protocol error: Unknown command ID (%d), closing connection."), (int)(m_pRecvBuffer[0]&0x7C)>>2);
  314.                 m_pMainFrame->ShowStatus(str, 1);
  315.                 Close();
  316.                 return FALSE;
  317.             }
  318.             memmove(m_pRecvBuffer, m_pRecvBuffer+len+5, m_nRecvBufferPos-len-5);
  319.             m_nRecvBufferPos-=len+5;
  320.         }
  321.         break;
  322.     case 3:
  323.         if (m_nRecvBufferPos < 5)
  324.             return FALSE;
  325.         int nType = *m_pRecvBuffer & 0x03;
  326.         int nID = (*m_pRecvBuffer & 0x7C) >> 2;
  327.         if (nType > 2 || nType < 1)
  328.         {
  329.             CString str;
  330.             str.Format(_T("Protocol error: Unknown command type (%d), closing connection."), nType);
  331.             m_pMainFrame->ShowStatus(str, 1);
  332.             Close();
  333.             return FALSE;
  334.         }
  335.         else
  336.         {
  337.             len = (unsigned int)GET32(m_pRecvBuffer + 1);
  338.             if (len > 0xFFFFFF)
  339.             {
  340.                 CString str;
  341.                 str.Format(_T("Protocol error: Invalid data length (%u) for command (%d:%d)"), len, nType, nID);
  342.                 m_pMainFrame->ShowStatus(str, 1);
  343.                 Close();
  344.                 return FALSE;
  345.             }                
  346.             if (m_nRecvBufferPos < len+5)
  347.                 return FALSE;
  348.             else
  349.             {
  350.                 if (nType == 1)
  351.                     m_pMainFrame->ParseReply(nID, m_pRecvBuffer + 5, len);
  352.                 else if (nType == 2)
  353.                     m_pMainFrame->ParseStatus(nID, m_pRecvBuffer + 5, len);
  354.                 else
  355.                 {
  356.                     CString str;
  357.                     str.Format(_T("Protocol warning: Command type %d not implemented."), nType);
  358.                     m_pMainFrame->ShowStatus(str, 1);
  359.                 }
  360.                 
  361.                 memmove(m_pRecvBuffer, m_pRecvBuffer+len+5, m_nRecvBufferPos-len-5);
  362.                 m_nRecvBufferPos-=len+5;
  363.             }
  364.         }
  365.         break;
  366.     }
  367.     return TRUE;
  368. }
  369.  
  370. BOOL CAdminSocket::SendCommand(int nType)
  371. {
  372.     t_data data;
  373.     data.pData = new unsigned char[5];
  374.     data.pData[0] = nType << 2;
  375.     data.dwOffset = 0;
  376.     DWORD dwDataLength = 0;
  377.     memcpy(data.pData + 1, &dwDataLength, 4);
  378.  
  379.     data.dwLength = 5;
  380.  
  381.     m_SendBuffer.push_back(data);
  382.     
  383.     do 
  384.     {
  385.         data=m_SendBuffer.front();
  386.         int nSent = Send(data.pData+data.dwOffset, data.dwLength-data.dwOffset);
  387.         if (!nSent)
  388.         {
  389.             Close();
  390.             return FALSE;
  391.         }
  392.         if (nSent == SOCKET_ERROR)
  393.         {
  394.             if (WSAGetLastError()!=WSAEWOULDBLOCK)
  395.             {
  396.                 Close();
  397.                 return FALSE;
  398.             }
  399.             return TRUE;
  400.         }
  401.         
  402.         if ((DWORD)nSent < (data.dwLength-data.dwOffset))
  403.             data.dwOffset+=nSent;
  404.         else
  405.         {
  406.             m_SendBuffer.pop_front();
  407.             delete [] data.pData;
  408.         }
  409.     } while (!m_SendBuffer.empty());
  410.  
  411.     return TRUE;
  412. }
  413.  
  414. BOOL CAdminSocket::SendCommand(int nType, void *pData, int nDataLength)
  415. {
  416.     ASSERT((pData && nDataLength) || (!pData && !nDataLength));
  417.     
  418.     t_data data;
  419.     data.pData = new unsigned char[nDataLength+5];
  420.     data.pData[0] = nType << 2;
  421.     data.dwOffset = 0;
  422.     memcpy(data.pData + 1, &nDataLength, 4);
  423.     if (pData)
  424.         memcpy(data.pData+5, pData, nDataLength);
  425.  
  426.     data.dwLength = nDataLength + 5;
  427.  
  428.     m_SendBuffer.push_back(data);
  429.     
  430.     do 
  431.     {
  432.         data=m_SendBuffer.front();
  433.         int nSent = Send(data.pData+data.dwOffset, data.dwLength-data.dwOffset);
  434.         if (!nSent)
  435.         {
  436.             Close();
  437.             return FALSE;
  438.         }
  439.         if (nSent == SOCKET_ERROR)
  440.         {
  441.             if (WSAGetLastError()!=WSAEWOULDBLOCK)
  442.             {
  443.                 Close();
  444.                 return FALSE;
  445.             }
  446.             return TRUE;
  447.         }
  448.         
  449.         if ((DWORD)nSent < (data.dwLength-data.dwOffset))
  450.             data.dwOffset += nSent;
  451.         else
  452.         {
  453.             m_SendBuffer.pop_front();
  454.             delete [] data.pData;
  455.         }
  456.     } while (!m_SendBuffer.empty());
  457.  
  458.     return TRUE;
  459. }
  460.  
  461. BOOL CAdminSocket::IsConnected()
  462. {
  463.     return m_nConnectionState == 3;
  464. }
  465.  
  466. void CAdminSocket::OnClose(int nErrorCode)
  467. {
  468.     Close();
  469. }
  470.  
  471. void CAdminSocket::DoClose()
  472. {
  473.     m_bClosed = true;
  474.     Close();
  475. }
  476.  
  477. bool CAdminSocket::IsLocal()
  478. {
  479.     CString ip;
  480.     UINT port;
  481.     if (!GetPeerName(ip, port))
  482.         return false;
  483.  
  484.     return ip == "127.0.0.1";
  485. }
  486.