blob: 5a7ff7f9579577500d9d33d5b39c68dcd221c736 [file] [log] [blame]
Constantin Kaplinskyfbfbb922004-11-14 18:28:51 +00001/* Copyright (C) 2004 TightVNC Team. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19// -=- RFB Protocol
20
21#include <rfb/Exception.h>
22#include <rfb/LogWriter.h>
23
24#include <rfbplayer/RfbProto.h>
25
26using namespace rfb;
27
28static LogWriter vlog("RfbProto");
29
30//
31// Constructor
32//
33
34RfbProto::RfbProto(char *fileName) {
35 is = NULL;
36 reader = NULL;
37 newSession(fileName);
38}
39
40//
41// Destructor
42//
43
44RfbProto::~RfbProto() {
george825beb62a2005-02-09 13:04:32 +000045 if (is) delete is;
46 is = 0;
47 if (reader) delete reader;
48 reader = 0;
Constantin Kaplinskyfbfbb922004-11-14 18:28:51 +000049}
50
51void RfbProto::newSession(char *fileName) {
52 // Close the previous session
53 if (is) {
54 delete is;
55 is = NULL;
56 delete reader;
57 reader = NULL;
58 }
59
60 // Begin the new session
61 if (fileName != NULL) {
62 is = new FbsInputStream(fileName);
63 reader = new CMsgReaderV3(this, is);
64 initialiseProtocol();
65 }
66}
67
68void RfbProto::initialiseProtocol() {
69 state_ = RFBSTATE_PROTOCOL_VERSION;
70}
71
72void RfbProto::processMsg()
73{
74 switch (state_) {
75
76 case RFBSTATE_PROTOCOL_VERSION: processVersionMsg(); break;
77 case RFBSTATE_SECURITY: processSecurityMsg(); break;
78 case RFBSTATE_INITIALISATION: processInitMsg(); break;
79 case RFBSTATE_NORMAL: reader->readMsg(); break;
80 default:
81 throw rfb::Exception("RfbProto::processMsg: invalid state");
82 }
83}
84
85void RfbProto::processVersionMsg()
86{
87 vlog.debug("reading protocol version");
george824f7d1d32005-02-03 14:25:00 +000088 memset(&cp, 0, sizeof(cp));
Constantin Kaplinskyfbfbb922004-11-14 18:28:51 +000089 bool done;
90 if (!cp.readVersion(is, &done)) {
91 state_ = RFBSTATE_INVALID;
Constantin Kaplinsky4aaf63b2005-09-28 16:49:36 +000092 throw rfb::Exception("reading version failed: wrong file format?");
Constantin Kaplinskyfbfbb922004-11-14 18:28:51 +000093 }
94 if (!done) return;
95
96 // The only official RFB protocol versions are currently 3.3, 3.7 and 3.8
97 if (!cp.isVersion(3,3) && !cp.isVersion(3,7) && !cp.isVersion(3,8)) {
98 char msg[256];
99 sprintf(msg,"File have unsupported RFB protocol version %d.%d",
100 cp.majorVersion, cp.minorVersion);
101 state_ = RFBSTATE_INVALID;
Constantin Kaplinsky4aaf63b2005-09-28 16:49:36 +0000102 throw rfb::Exception(msg);
Constantin Kaplinskyfbfbb922004-11-14 18:28:51 +0000103 }
104
105 state_ = RFBSTATE_SECURITY;
106
107 vlog.info("Using RFB protocol version %d.%d",
108 cp.majorVersion, cp.minorVersion);
109}
110
111void RfbProto::processSecurityMsg()
112{
113 vlog.debug("processing security types message");
114
115 int secType = secTypeInvalid;
116
117 // legacy 3.3 server may only offer "vnc authentication" or "none"
118 secType = is->readU32();
119 if (secType == secTypeInvalid) {
120 int reasonLen = is->readU32();
121 char *reason = new char[reasonLen];
122 is->readBytes(reason, reasonLen);
Constantin Kaplinsky4aaf63b2005-09-28 16:49:36 +0000123 throw rfb::Exception(reason);
Constantin Kaplinskyfbfbb922004-11-14 18:28:51 +0000124 }
125
126 if (secType != secTypeNone) {
Constantin Kaplinsky4aaf63b2005-09-28 16:49:36 +0000127 throw rfb::Exception("Wrong authentication type in the session file");
Constantin Kaplinskyfbfbb922004-11-14 18:28:51 +0000128 }
129
130 state_ = RFBSTATE_INITIALISATION;
131}
132
133void RfbProto::processInitMsg() {
134 vlog.debug("reading server initialisation");
135 reader->readServerInit();
136}
137
138void RfbProto::serverInit()
139{
140 state_ = RFBSTATE_NORMAL;
141 vlog.debug("initialisation done");
142}