blob: 68a0f57ef6d52ca37975b02eacabefa503909f64 [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() {
45 delete is;
46 is = NULL;
47 delete reader;
48 reader = NULL;
49}
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");
88 bool done;
89 if (!cp.readVersion(is, &done)) {
90 state_ = RFBSTATE_INVALID;
91 throw rfb::Exception("reading version failed: wrong file format?", "RfbPlayer");
92 }
93 if (!done) return;
94
95 // The only official RFB protocol versions are currently 3.3, 3.7 and 3.8
96 if (!cp.isVersion(3,3) && !cp.isVersion(3,7) && !cp.isVersion(3,8)) {
97 char msg[256];
98 sprintf(msg,"File have unsupported RFB protocol version %d.%d",
99 cp.majorVersion, cp.minorVersion);
100 state_ = RFBSTATE_INVALID;
101 throw rfb::Exception(msg, "RfbPlayer Error");
102 }
103
104 state_ = RFBSTATE_SECURITY;
105
106 vlog.info("Using RFB protocol version %d.%d",
107 cp.majorVersion, cp.minorVersion);
108}
109
110void RfbProto::processSecurityMsg()
111{
112 vlog.debug("processing security types message");
113
114 int secType = secTypeInvalid;
115
116 // legacy 3.3 server may only offer "vnc authentication" or "none"
117 secType = is->readU32();
118 if (secType == secTypeInvalid) {
119 int reasonLen = is->readU32();
120 char *reason = new char[reasonLen];
121 is->readBytes(reason, reasonLen);
122 throw rfb::Exception(reason, "RfbPlayer");
123 }
124
125 if (secType != secTypeNone) {
126 throw rfb::Exception("Wrong authentication type in the session file",
127 "RfbPlayer Error");
128 }
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}