/* Copyright (C) 2004 TightVNC Team. All Rights Reserved. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ // -=- RFB Protocol #include <rfb/Exception.h> #include <rfb/LogWriter.h> #include <rfbplayer/RfbProto.h> using namespace rfb; static LogWriter vlog("RfbProto"); // // Constructor // RfbProto::RfbProto(char *fileName) { is = NULL; reader = NULL; newSession(fileName); } // // Destructor // RfbProto::~RfbProto() { if (is) delete is; is = 0; if (reader) delete reader; reader = 0; } void RfbProto::newSession(char *fileName) { // Close the previous session if (is) { delete is; is = NULL; delete reader; reader = NULL; } // Begin the new session if (fileName != NULL) { is = new FbsInputStream(fileName); reader = new CMsgReaderV3(this, is); initialiseProtocol(); } } void RfbProto::initialiseProtocol() { state_ = RFBSTATE_PROTOCOL_VERSION; } void RfbProto::processMsg() { switch (state_) { case RFBSTATE_PROTOCOL_VERSION: processVersionMsg(); break; case RFBSTATE_SECURITY: processSecurityMsg(); break; case RFBSTATE_INITIALISATION: processInitMsg(); break; case RFBSTATE_NORMAL: reader->readMsg(); break; default: throw rfb::Exception("RfbProto::processMsg: invalid state"); } } void RfbProto::processVersionMsg() { vlog.debug("reading protocol version"); memset(&cp, 0, sizeof(cp)); bool done; if (!cp.readVersion(is, &done)) { state_ = RFBSTATE_INVALID; throw rfb::Exception("reading version failed: wrong file format?"); } if (!done) return; // The only official RFB protocol versions are currently 3.3, 3.7 and 3.8 if (!cp.isVersion(3,3) && !cp.isVersion(3,7) && !cp.isVersion(3,8)) { char msg[256]; sprintf(msg,"File have unsupported RFB protocol version %d.%d", cp.majorVersion, cp.minorVersion); state_ = RFBSTATE_INVALID; throw rfb::Exception(msg); } state_ = RFBSTATE_SECURITY; vlog.info("Using RFB protocol version %d.%d", cp.majorVersion, cp.minorVersion); } void RfbProto::processSecurityMsg() { vlog.debug("processing security types message"); int secType = secTypeInvalid; // legacy 3.3 server may only offer "vnc authentication" or "none" secType = is->readU32(); if (secType == secTypeInvalid) { int reasonLen = is->readU32(); char *reason = new char[reasonLen]; is->readBytes(reason, reasonLen); throw rfb::Exception(reason); } if (secType != secTypeNone) { throw rfb::Exception("Wrong authentication type in the session file"); } state_ = RFBSTATE_INITIALISATION; } void RfbProto::processInitMsg() { vlog.debug("reading server initialisation"); reader->readServerInit(); } void RfbProto::serverInit() { state_ = RFBSTATE_NORMAL; vlog.debug("initialisation done"); }