blob: 29a3b9641fa6aaacee8a0a764224180aa496baba [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. 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// SSecurityVncAuth
20//
21// XXX not thread-safe, because d3des isn't - do we need to worry about this?
22//
23
24#include <rfb/SSecurityVncAuth.h>
25#include <rdr/RandomStream.h>
26#include <rfb/SConnection.h>
27#include <rfb/Password.h>
28#include <rfb/Configuration.h>
29#include <rfb/LogWriter.h>
30#include <rfb/util.h>
31#include <rfb/Exception.h>
32#include <string.h>
33#include <stdio.h>
34extern "C" {
35#include <rfb/d3des.h>
36}
37
38
39using namespace rfb;
40
41static LogWriter vlog("SVncAuth");
42
43
44SSecurityVncAuth::SSecurityVncAuth(VncAuthPasswdGetter* pg_)
45 : sentChallenge(false), responsePos(0), pg(pg_)
46{
47}
48
49bool SSecurityVncAuth::processMsg(SConnection* sc)
50{
51 rdr::InStream* is = sc->getInStream();
52 rdr::OutStream* os = sc->getOutStream();
53
54 if (!sentChallenge) {
55 rdr::RandomStream rs;
56 rs.readBytes(challenge, vncAuthChallengeSize);
57 os->writeBytes(challenge, vncAuthChallengeSize);
58 os->flush();
59 sentChallenge = true;
60 return false;
61 }
62
63 while (responsePos < vncAuthChallengeSize && is->checkNoWait(1))
64 response[responsePos++] = is->readU8();
65
66 if (responsePos < vncAuthChallengeSize) return false;
67
68 PlainPasswd passwd(pg->getVncAuthPasswd());
69
70 if (!passwd.buf)
71 throw AuthFailureException("No password configured for VNC Auth");
72
73 // Calculate the expected response
74 rdr::U8 key[8];
75 int pwdLen = strlen(passwd.buf);
76 for (int i=0; i<8; i++)
77 key[i] = i<pwdLen ? passwd.buf[i] : 0;
78 deskey(key, EN0);
79 for (int j = 0; j < vncAuthChallengeSize; j += 8)
80 des(challenge+j, challenge+j);
81
82 // Check the actual response
83 if (memcmp(challenge, response, vncAuthChallengeSize) != 0)
84 throw AuthFailureException();
85
86 return true;
87}