blob: 5a7ff7f9579577500d9d33d5b39c68dcd221c736 [file] [log] [blame]
Constantin Kaplinsky729598c2006-05-25 05:12:25 +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 if (is) delete is;
46 is = 0;
47 if (reader) delete reader;
48 reader = 0;
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 memset(&cp, 0, sizeof(cp));
89 bool done;
90 if (!cp.readVersion(is, &done)) {
91 state_ = RFBSTATE_INVALID;
92 throw rfb::Exception("reading version failed: wrong file format?");
93 }
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;
102 throw rfb::Exception(msg);
103 }
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);
123 throw rfb::Exception(reason);
124 }
125
126 if (secType != secTypeNone) {
127 throw rfb::Exception("Wrong authentication type in the session file");
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}