"Fossies" - the Fresh Open Source Software Archive

Member "tvnserver-2.0.4/rfb/HostPath.cpp" (3 Aug 2011, 6325 Bytes) of archive /windows/misc/tvnserver-2.0.4-src.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "HostPath.cpp" see the Fossies "Dox" file reference documentation.

    1 // Copyright (C) 2008, 2009, 2010 GlavSoft LLC.
    2 // All rights reserved.
    3 //
    4 //-------------------------------------------------------------------------
    5 // This file is part of the TightVNC software.  Please visit our Web site:
    6 //
    7 //                       http://www.tightvnc.com/
    8 //
    9 // This program is free software; you can redistribute it and/or modify
   10 // it under the terms of the GNU General Public License as published by
   11 // the Free Software Foundation; either version 2 of the License, or
   12 // (at your option) any later version.
   13 //
   14 // This program is distributed in the hope that it will be useful,
   15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17 // GNU General Public License for more details.
   18 //
   19 // You should have received a copy of the GNU General Public License along
   20 // with this program; if not, write to the Free Software Foundation, Inc.,
   21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   22 //-------------------------------------------------------------------------
   23 //
   24 
   25 #include <string.h>
   26 #include <stdlib.h>
   27 #include "HostPath.h"
   28 
   29 const size_t HostPath::m_SSH_USER_MAX_CHARS = 32;
   30 const size_t HostPath::m_SSH_HOST_MAX_CHARS = 255;
   31 const size_t HostPath::m_SSH_PORT_MAX_CHARS = 5;
   32 const size_t HostPath::m_VNC_HOST_MAX_CHARS = 255;
   33 const size_t HostPath::m_VNC_PORT_MAX_CHARS = 5;
   34 
   35 HostPath::HostPath()
   36   : m_path(0),
   37     m_sshHost(0),
   38     m_sshPort(0),
   39     m_vncHost(0),
   40     m_vncPort(0),
   41     m_defaultPort(5900)
   42 {
   43 }
   44 
   45 HostPath::HostPath(const char *path, int defaultPort)
   46   : m_path(0),
   47     m_sshHost(0),
   48     m_sshPort(0),
   49     m_vncHost(0),
   50     m_vncPort(0),
   51     m_defaultPort(defaultPort)
   52 {
   53   set(path);
   54 }
   55 
   56 HostPath::~HostPath()
   57 {
   58   clear();
   59 }
   60 
   61 bool
   62 HostPath::set(const char *path)
   63 {
   64   clear();
   65 
   66   const size_t MAX_PATH_LEN =
   67     (m_SSH_USER_MAX_CHARS + m_SSH_HOST_MAX_CHARS + m_SSH_PORT_MAX_CHARS +
   68      m_VNC_HOST_MAX_CHARS + m_VNC_PORT_MAX_CHARS + 5);
   69 
   70   if (path == 0) {
   71     return false;
   72   }
   73   size_t pathLen = strlen(path);
   74   if (pathLen < 1 || pathLen > MAX_PATH_LEN) {
   75     return false;
   76   }
   77   m_path = new char[pathLen + 1];
   78   memcpy(m_path, path, pathLen);
   79   m_path[pathLen] = '\0';
   80 
   81   size_t tokens[4];
   82   parsePath(tokens);
   83   if ( tokens[0] + tokens[2] + tokens[3] == 0 ||
   84        (tokens[1] != 0 && tokens[0] == 0) ) {
   85     clear();
   86     return false;
   87   }
   88   const char *tokenStart = m_path;
   89 
   90   if (tokens[0] != 0) {
   91     size_t hostLen = tokens[0];
   92     if (hostLen > m_SSH_HOST_MAX_CHARS) {
   93       clear();
   94       return false;
   95     }
   96     m_sshHost = new char[hostLen + 1];
   97     memcpy(m_sshHost, tokenStart, hostLen);
   98     m_sshHost[hostLen] = '\0';
   99     m_sshPort = 22;
  100     tokenStart += tokens[0];
  101 
  102     if (tokens[1] != 0) {
  103       size_t portLen = tokens[1] - 1;
  104       if (portLen < 1 ||
  105           portLen > m_SSH_PORT_MAX_CHARS ||
  106           *tokenStart != ':' ||
  107           strspn(tokenStart + 1, "0123456789") != portLen) {
  108         clear();
  109         return false;
  110       }
  111       m_sshPort = atoi(tokenStart + 1);
  112       tokenStart += tokens[1];
  113     }
  114 
  115     tokenStart++; 
  116   }
  117 
  118   const char* hostStart = tokenStart;
  119   size_t hostLen = tokens[2];
  120   if (tokens[2] == 0) {
  121     hostStart = "localhost";
  122     hostLen = 9; 
  123   } else {
  124     if (hostLen > m_VNC_HOST_MAX_CHARS) {
  125       clear();
  126       return false;
  127     }
  128   }
  129   m_vncHost = new char[hostLen + 1];
  130   memcpy(m_vncHost, hostStart, hostLen);
  131   m_vncHost[hostLen] = '\0';
  132   tokenStart += tokens[2];
  133 
  134   if (tokens[3] == 0) {
  135     m_vncPort = m_defaultPort;
  136   } else {
  137     size_t portLen = tokens[3] - 1;
  138     if (portLen < 1 || *tokenStart != ':') {
  139       clear();
  140       return false;
  141     }
  142     const char* portStart = tokenStart + 1;
  143     bool twoColons = (*portStart == ':');
  144     if (twoColons) {
  145       portStart++;
  146       portLen--;
  147     }
  148     if (portLen < 1 ||
  149         portLen > m_VNC_PORT_MAX_CHARS ||
  150         strspn(portStart, "0123456789") != portLen) {
  151       clear();
  152       return false;
  153     }
  154     m_vncPort = atoi(portStart);
  155     if (!twoColons && m_vncPort >= 0 && m_vncPort <= 99) {
  156       m_vncPort += m_defaultPort;
  157     }
  158   }
  159 
  160   if (!validateHostNames()) {
  161     clear();
  162     return false;
  163   }
  164 
  165   return true;
  166 }
  167 
  168 void
  169 HostPath::clear()
  170 {
  171   if (m_path != 0) {
  172     delete[] m_path;
  173     m_path = 0;
  174   }
  175   if (m_sshHost != 0) {
  176     delete[] m_sshHost;
  177     m_sshHost = 0;
  178   }
  179   if (m_vncHost != 0) {
  180     delete[] m_vncHost;
  181     m_vncHost = 0;
  182   }
  183   m_sshPort = 0;
  184   m_vncPort = 0;
  185 }
  186 
  187 void
  188 HostPath::parsePath(size_t results[]) const
  189 {
  190   memset(results, 0, 4 * sizeof(size_t));
  191 
  192   if (m_path == 0)
  193     return;
  194 
  195   const char* vncHostStart = m_path;
  196 
  197   const char* slashPtr = strchr(m_path, '/');
  198   if (slashPtr != 0) {
  199     results[0] = strcspn(m_path, ":/");
  200     results[1] = (slashPtr - m_path) - results[0];
  201     vncHostStart = slashPtr + 1;
  202   }
  203 
  204   const char *colonPtr = strchr(vncHostStart, ':');
  205   if (colonPtr != 0) {
  206     results[2] = colonPtr - vncHostStart;
  207     results[3] = strlen(colonPtr);
  208   } else {
  209     results[2] = strlen(vncHostStart);
  210   }
  211 }
  212 
  213 bool
  214 HostPath::validateHostNames() const
  215 {
  216   const char* acceptChars =
  217     ".-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890";
  218 
  219   if (m_sshHost != 0) {
  220     const char* sshHostPtr = m_sshHost;
  221     size_t sshHostLen = strlen(m_sshHost);
  222 
  223     const char *sobakaPtr = strchr(m_sshHost, '@');
  224     if (sobakaPtr != 0) {
  225       const char* sshUserPtr = m_sshHost;
  226       size_t sshUserLen = sobakaPtr - m_sshHost;
  227       sshHostPtr = sobakaPtr + 1;
  228       sshHostLen = sshHostLen - sshUserLen - 1;
  229 
  230       if (sshUserLen < 1 || sshUserLen > m_SSH_USER_MAX_CHARS ||
  231           strspn(sshUserPtr, acceptChars) != sshUserLen) {
  232         return false;
  233       }
  234     }
  235 
  236     if (sshHostLen < 1 || sshHostLen > m_SSH_HOST_MAX_CHARS ||
  237         strspn(sshHostPtr, acceptChars) != sshHostLen) {
  238       return false;
  239     }
  240   }
  241 
  242   if (m_vncHost == 0)
  243     return false;
  244 
  245   size_t vncHostLen = strlen(m_vncHost);
  246   if (vncHostLen < 1 || vncHostLen > m_VNC_HOST_MAX_CHARS ||
  247       strspn(m_vncHost, acceptChars) != vncHostLen) {
  248     return false;
  249   }
  250 
  251   return true;
  252 }