summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/comm/keypebble/krfblogin.cpp1
1 files changed, 1 insertions, 0 deletions
diff --git a/noncore/comm/keypebble/krfblogin.cpp b/noncore/comm/keypebble/krfblogin.cpp
index 073ba0e..cc3a8fa 100644
--- a/noncore/comm/keypebble/krfblogin.cpp
+++ b/noncore/comm/keypebble/krfblogin.cpp
@@ -1,255 +1,256 @@
1#include <assert.h> 1#include <assert.h>
2 2
3 3
4extern "C" { 4extern "C" {
5#include "vncauth.h" 5#include "vncauth.h"
6} 6}
7 7
8#include "krfblogin.h" 8#include "krfblogin.h"
9#include "krfbconnection.h" 9#include "krfbconnection.h"
10#include <qtimer.h> 10#include <qtimer.h>
11#include <qregexp.h>
11 12
12// The length of the various messages (used to decide how many bytes to 13// The length of the various messages (used to decide how many bytes to
13// wait for). 14// wait for).
14const int ServerVersionLength = 12; 15const int ServerVersionLength = 12;
15const int ClientVersionLength = 12; 16const int ClientVersionLength = 12;
16const int AuthSchemeLength = 4; 17const int AuthSchemeLength = 4;
17const int FailureReasonSizeLength = 4; 18const int FailureReasonSizeLength = 4;
18const int ChallengeLength = 16; 19const int ChallengeLength = 16;
19const int AuthResultLength = 4; 20const int AuthResultLength = 4;
20 21
21// Authentication results 22// Authentication results
22enum AuthResult { 23enum AuthResult {
23 AuthOk, 24 AuthOk,
24 AuthFailed, 25 AuthFailed,
25 AuthTooMany 26 AuthTooMany
26}; 27};
27 28
28typedef unsigned char CARD8; 29typedef unsigned char CARD8;
29typedef unsigned short CARD16; 30typedef unsigned short CARD16;
30typedef unsigned long CARD32; 31typedef unsigned long CARD32;
31 32
32const int endianTest = 1; 33const int endianTest = 1;
33 34
34// Endian stuff 35// Endian stuff
35#define Swap16IfLE(s) \ 36#define Swap16IfLE(s) \
36 (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s)) 37 (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
37 38
38#define Swap32IfLE(l) \ 39#define Swap32IfLE(l) \
39 (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \ 40 (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \
40 (((l) & 0x00ff0000) >> 8) | \ 41 (((l) & 0x00ff0000) >> 8) | \
41 (((l) & 0x0000ff00) << 8) | \ 42 (((l) & 0x0000ff00) << 8) | \
42 (((l) & 0x000000ff) << 24)) : (l)) 43 (((l) & 0x000000ff) << 24)) : (l))
43 44
44KRFBLogin::KRFBLogin( KRFBConnection *con ) 45KRFBLogin::KRFBLogin( KRFBConnection *con )
45 : QObject( con, "RFB login manager" ) 46 : QObject( con, "RFB login manager" )
46{ 47{
47 assert( con ); 48 assert( con );
48 this->con = con; 49 this->con = con;
49 currentState = AwaitingServerVersion; 50 currentState = AwaitingServerVersion;
50 51
51 connect( this, SIGNAL( error( const QString & ) ), 52 connect( this, SIGNAL( error( const QString & ) ),
52 con, SIGNAL( error( const QString & ) ) ); 53 con, SIGNAL( error( const QString & ) ) );
53 54
54 connect( this, SIGNAL( passwordRequired( KRFBConnection * ) ), 55 connect( this, SIGNAL( passwordRequired( KRFBConnection * ) ),
55 con, SIGNAL( passwordRequired( KRFBConnection * ) ) ); 56 con, SIGNAL( passwordRequired( KRFBConnection * ) ) );
56 57
57 qWarning( "Waiting for server version..." ); 58 qWarning( "Waiting for server version..." );
58 59
59 static QString statusMsg = tr( "Waiting for server version..." ); 60 static QString statusMsg = tr( "Waiting for server version..." );
60 emit status( statusMsg ); 61 emit status( statusMsg );
61 62
62 // Kick off the state machine 63 // Kick off the state machine
63 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerVersion() ) ); 64 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerVersion() ) );
64 con->waitForData( ServerVersionLength ); 65 con->waitForData( ServerVersionLength );
65} 66}
66 67
67KRFBLogin::~KRFBLogin() 68KRFBLogin::~KRFBLogin()
68{ 69{
69 70
70} 71}
71 72
72KRFBLogin::State KRFBLogin::state() const 73KRFBLogin::State KRFBLogin::state() const
73{ 74{
74 return currentState; 75 return currentState;
75} 76}
76 77
77void KRFBLogin::gotServerVersion() 78void KRFBLogin::gotServerVersion()
78{ 79{
79 qWarning( "Got server version" ); 80 qWarning( "Got server version" );
80 81
81 disconnect( con, SIGNAL( gotEnoughData() ), 82 disconnect( con, SIGNAL( gotEnoughData() ),
82 this, SLOT( gotServerVersion() ) ); 83 this, SLOT( gotServerVersion() ) );
83 84
84 // Read the server's version message 85 // Read the server's version message
85 char serverVersion[ ServerVersionLength + 1 ]; 86 char serverVersion[ ServerVersionLength + 1 ];
86 con->read( serverVersion, ServerVersionLength ); 87 con->read( serverVersion, ServerVersionLength );
87 serverVersion[ ServerVersionLength ] = '\0'; 88 serverVersion[ ServerVersionLength ] = '\0';
88 89
89 QCString rfbString( serverVersion, ServerVersionLength + 1 ); 90 QCString rfbString( serverVersion, ServerVersionLength + 1 );
90 versionString = rfbString; 91 versionString = rfbString;
91 92
92 QRegExp regexp( "RFB [0-9][0-9][0-9]\\.[0-9][0-9][0-9]\n" ); 93 QRegExp regexp( "RFB [0-9][0-9][0-9]\\.[0-9][0-9][0-9]\n" );
93 94
94 if ( rfbString.find( regexp ) == -1 ) { 95 if ( rfbString.find( regexp ) == -1 ) {
95 static QString msg = tr( "Error: Invalid server version, %1" ).arg( rfbString ); 96 static QString msg = tr( "Error: Invalid server version, %1" ).arg( rfbString );
96 97
97 qWarning( msg ); 98 qWarning( msg );
98 emit error( msg ); 99 emit error( msg );
99 currentState = Error; 100 currentState = Error;
100 return; 101 return;
101 } 102 }
102 103
103 // Calculate the actual version number 104 // Calculate the actual version number
104 serverMajor = (serverVersion[4] - '0') * 100 105 serverMajor = (serverVersion[4] - '0') * 100
105 + (serverVersion[5] - '0') * 10 106 + (serverVersion[5] - '0') * 10
106 + (serverVersion[6] - '0'); 107 + (serverVersion[6] - '0');
107 serverMinor = (serverVersion[8] - '0') * 100 108 serverMinor = (serverVersion[8] - '0') * 100
108 + (serverVersion[9] - '0') * 10 109 + (serverVersion[9] - '0') * 10
109 + (serverVersion[10] - '0'); 110 + (serverVersion[10] - '0');
110 111
111 qWarning("Server Version: %03d.%03d", serverMajor, serverMinor ); 112 qWarning("Server Version: %03d.%03d", serverMajor, serverMinor );
112 113
113 if ( serverMajor != 3 ) { 114 if ( serverMajor != 3 ) {
114 QString msg = tr( "Error: Unsupported server version, %1" ) 115 QString msg = tr( "Error: Unsupported server version, %1" )
115 .arg( rfbString ); 116 .arg( rfbString );
116 117
117 qWarning( msg ); 118 qWarning( msg );
118 emit error( msg ); 119 emit error( msg );
119 currentState = Error; 120 currentState = Error;
120 return; 121 return;
121 } 122 }
122 123
123 if ( serverMinor != 3 ) { 124 if ( serverMinor != 3 ) {
124 qWarning( "Minor version mismatch: %d", serverMinor ); 125 qWarning( "Minor version mismatch: %d", serverMinor );
125 } 126 }
126 127
127 // Setup for the next state 128 // Setup for the next state
128 sendClientVersion(); 129 sendClientVersion();
129 130
130 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotAuthScheme() ) ); 131 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotAuthScheme() ) );
131 con->waitForData( AuthSchemeLength ); 132 con->waitForData( AuthSchemeLength );
132} 133}
133 134
134void KRFBLogin::gotAuthScheme() 135void KRFBLogin::gotAuthScheme()
135{ 136{
136 disconnect( con, SIGNAL( gotEnoughData() ), 137 disconnect( con, SIGNAL( gotEnoughData() ),
137 this, SLOT( gotAuthScheme() ) ); 138 this, SLOT( gotAuthScheme() ) );
138 139
139 // Got data 140 // Got data
140 CARD32 scheme; 141 CARD32 scheme;
141 con->read( &scheme, AuthSchemeLength ); 142 con->read( &scheme, AuthSchemeLength );
142 scheme = Swap32IfLE( scheme ); 143 scheme = Swap32IfLE( scheme );
143 144
144 static QString statusMsgOk = tr( "Logged in" ); 145 static QString statusMsgOk = tr( "Logged in" );
145 146
146 switch ( scheme ) { 147 switch ( scheme ) {
147 case 0: 148 case 0:
148 qWarning( "Failed" ); 149 qWarning( "Failed" );
149 // Handle failure 150 // Handle failure
150 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotFailureReasonSize() ) ); 151 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotFailureReasonSize() ) );
151 con->waitForData( FailureReasonSizeLength ); 152 con->waitForData( FailureReasonSizeLength );
152 break; 153 break;
153 case 1: 154 case 1:
154 // Handle no auth 155 // Handle no auth
155 emit status( statusMsgOk ); 156 emit status( statusMsgOk );
156 con->gotRFBConnection(); 157 con->gotRFBConnection();
157 break; 158 break;
158 case 2: 159 case 2:
159 // Handle VNC auth 160 // Handle VNC auth
160 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotChallenge() ) ); 161 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotChallenge() ) );
161 con->waitForData( ChallengeLength ); 162 con->waitForData( ChallengeLength );
162 break; 163 break;
163 default: 164 default:
164 qWarning( "Unknown authentication scheme, 0x%08lx", scheme ); 165 qWarning( "Unknown authentication scheme, 0x%08lx", scheme );
165 currentState = Error; 166 currentState = Error;
166 break; 167 break;
167 }; 168 };
168} 169}
169 170
170void KRFBLogin::gotChallenge() 171void KRFBLogin::gotChallenge()
171{ 172{
172 disconnect( con, SIGNAL( gotEnoughData() ), 173 disconnect( con, SIGNAL( gotEnoughData() ),
173 this, SLOT( gotChallenge() ) ); 174 this, SLOT( gotChallenge() ) );
174 175
175 QTimer::singleShot( 0, this, SLOT(getPassword()) ); 176 QTimer::singleShot( 0, this, SLOT(getPassword()) );
176} 177}
177 178
178void KRFBLogin::getPassword() 179void KRFBLogin::getPassword()
179{ 180{
180 // Got data 181 // Got data
181 CARD8 challenge[ ChallengeLength ]; 182 CARD8 challenge[ ChallengeLength ];
182 con->read( challenge, ChallengeLength ); 183 con->read( challenge, ChallengeLength );
183 184
184 // Last chance to enter a password 185 // Last chance to enter a password
185 if ( con->pass_.isNull() ) { 186 if ( con->pass_.isNull() ) {
186 qWarning( "krfblogin needs a password" ); 187 qWarning( "krfblogin needs a password" );
187 emit passwordRequired( con ); 188 emit passwordRequired( con );
188 } 189 }
189 190
190 if ( con->pass_.isNull() ) { 191 if ( con->pass_.isNull() ) {
191 QString msg = tr( "Error: This server requires a password, but none " 192 QString msg = tr( "Error: This server requires a password, but none "
192 "has been specified.\n" ); 193 "has been specified.\n" );
193 194
194 emit error( msg ); 195 emit error( msg );
195 return; 196 return;
196 } 197 }
197 198
198 vncEncryptBytes( (unsigned char *) challenge, con->pass_.data() ); 199 vncEncryptBytes( (unsigned char *) challenge, con->pass_.data() );
199 con->write( challenge, ChallengeLength ); 200 con->write( challenge, ChallengeLength );
200 201
201 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotAuthResult() ) ); 202 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotAuthResult() ) );
202 con->waitForData( AuthResultLength ); 203 con->waitForData( AuthResultLength );
203} 204}
204 205
205void KRFBLogin::gotFailureReasonSize() 206void KRFBLogin::gotFailureReasonSize()
206{ 207{
207 disconnect( con, SIGNAL( gotEnoughData() ), this, 208 disconnect( con, SIGNAL( gotEnoughData() ), this,
208 SLOT( gotFailureReasonSize() ) ); 209 SLOT( gotFailureReasonSize() ) );
209} 210}
210 211
211void KRFBLogin::gotAuthResult() 212void KRFBLogin::gotAuthResult()
212{ 213{
213 // Got data 214 // Got data
214 disconnect( con, SIGNAL( gotEnoughData() ), this, 215 disconnect( con, SIGNAL( gotEnoughData() ), this,
215 SLOT( gotAuthResult() ) ); 216 SLOT( gotAuthResult() ) );
216 217
217 long result; 218 long result;
218 con->read( &result, AuthResultLength ); 219 con->read( &result, AuthResultLength );
219 result = Swap32IfLE( result ); 220 result = Swap32IfLE( result );
220 221
221 qWarning( "Authentication Result is 0x%08lx", result ); 222 qWarning( "Authentication Result is 0x%08lx", result );
222 223
223 static QString failed = tr( "Error: The password you specified was incorrect." ); 224 static QString failed = tr( "Error: The password you specified was incorrect." );
224 static QString tooMany = tr( "Error: Too many invalid login attempts have been made\n" 225 static QString tooMany = tr( "Error: Too many invalid login attempts have been made\n"
225 "to this account, please try later." ); 226 "to this account, please try later." );
226 227
227 static QString statusMsgOk = tr( "Logged in" ); 228 static QString statusMsgOk = tr( "Logged in" );
228 static QString statusMsgFailed = tr( "Login Failed" ); 229 static QString statusMsgFailed = tr( "Login Failed" );
229 static QString statusMsgTooMany = tr( "Too many failures" ); 230 static QString statusMsgTooMany = tr( "Too many failures" );
230 231
231 switch( result ) { 232 switch( result ) {
232 case AuthOk: 233 case AuthOk:
233 emit status( statusMsgOk ); 234 emit status( statusMsgOk );
234 con->gotRFBConnection(); 235 con->gotRFBConnection();
235 break; 236 break;
236 case AuthFailed: 237 case AuthFailed:
237 qWarning( "Dammit" ); 238 qWarning( "Dammit" );
238 emit status( statusMsgFailed ); 239 emit status( statusMsgFailed );
239 emit error( failed ); 240 emit error( failed );
240 break; 241 break;
241 case AuthTooMany: 242 case AuthTooMany:
242 emit status( statusMsgTooMany ); 243 emit status( statusMsgTooMany );
243 emit error( tooMany ); 244 emit error( tooMany );
244 break; 245 break;
245 default: 246 default:
246 qWarning( "Invalid authentication result, %lx", result ); 247 qWarning( "Invalid authentication result, %lx", result );
247 break; 248 break;
248 } 249 }
249} 250}
250 251
251void KRFBLogin::sendClientVersion() 252void KRFBLogin::sendClientVersion()
252{ 253{
253 qWarning( "Sending client version" ); 254 qWarning( "Sending client version" );
254 con->write( (void*)"RFB 003.003\n", ClientVersionLength ); 255 con->write( (void*)"RFB 003.003\n", ClientVersionLength );
255} 256}