* do not add a KStandardAction manually to actionCollection()
[kdenetwork.git] / krfb / connectioncontroller.cpp
blob9724f833cc46e2a0bbaecc0a2a6e7ec550d75c84
1 /* This file is part of the KDE project
2 Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
3 (C) 2001-2003 by Tim Jansen <tim@tjansen.de>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9 */
10 #include "connectioncontroller.h"
11 #include "connectioncontroller.moc"
13 #include <QX11Info>
14 #include <QHostInfo>
15 #include <QApplication>
16 #include <QDesktopWidget>
17 #include <QTcpSocket>
18 #include <QTimer>
20 #include <KConfig>
21 #include <KGlobal>
22 #include <KUser>
23 #include <KNotification>
24 #include <KLocale>
25 #include <KDebug>
28 #include "invitationmanager.h"
29 #include "connectiondialog.h"
30 #include "events.h"
31 #include "krfbserver.h"
33 #include "krfbconfig.h"
35 #include <X11/Xutil.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
41 static QString peerAddress(int sock) {
43 const int ADDR_SIZE = 50;
44 struct sockaddr sa;
45 socklen_t salen = sizeof(struct sockaddr);
46 if (getpeername(sock, &sa, &salen) == 0) {
47 if (sa.sa_family == AF_INET) {
48 struct sockaddr_in *si = (struct sockaddr_in *)&sa;
49 return QString(inet_ntoa(si->sin_addr));
51 if (sa.sa_family == AF_INET6) {
52 char inetbuf[ADDR_SIZE];
53 inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
54 return QString(inetbuf);
56 return QString("not a network address");
58 return QString("unable to determine...");
61 static void clientGoneHook(rfbClientPtr cl)
63 ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
64 cc->handleClientGone();
68 static bool checkPassword(const QString &p, unsigned char *ochallenge, const char *response, int len)
71 if ((len == 0) && (p.length() == 0)) {
72 return true;
75 char passwd[MAXPWLEN];
76 unsigned char challenge[CHALLENGESIZE];
78 memcpy(challenge, ochallenge, CHALLENGESIZE);
79 bzero(passwd, MAXPWLEN);
80 if (!p.isNull()) {
81 strncpy(passwd, p.toLatin1(),
82 (MAXPWLEN <= p.length()) ? MAXPWLEN : p.length());
85 rfbEncryptBytes(challenge, passwd);
86 return memcmp(challenge, response, len) == 0;
90 ConnectionController::ConnectionController(struct _rfbClientRec *_cl, KrfbServer * parent)
91 : QObject(parent), cl(_cl)
93 cl->clientData = (void*)this;
96 ConnectionController::~ConnectionController()
100 enum rfbNewClientAction ConnectionController::handleNewClient()
103 bool askOnConnect = KrfbConfig::askOnConnect();
104 bool allowUninvited = KrfbConfig::allowUninvitedConnections();
106 remoteIp = peerAddress(cl->sock);
108 if (!allowUninvited && InvitationManager::self()->activeInvitations() == 0) {
109 KNotification::event("ConnectionAttempted",
110 i18n("Attepted uninvited connection from %1: connection refused",
111 remoteIp));
112 return RFB_CLIENT_REFUSE;
115 if (!askOnConnect && InvitationManager::self()->activeInvitations() == 0) {
116 KNotification::event("NewConnectionAutoAccepted",
117 i18n("Accepted uninvited connection from %1",
118 remoteIp));
120 emit sessionEstablished(remoteIp);
121 return RFB_CLIENT_ACCEPT;
124 KNotification::event("NewConnectionOnHold",
125 i18n("Received connection from %1, on hold (waiting for confirmation)",
126 remoteIp));
128 cl->clientGoneHook = clientGoneHook;
130 ConnectionDialog *dialog = new ConnectionDialog(0);
131 dialog->setRemoteHost(remoteIp);
132 dialog->setAllowRemoteControl( true );
134 connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
135 connect(dialog, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
137 dialog->show();
139 return RFB_CLIENT_ON_HOLD;
142 bool ConnectionController::handleCheckPassword(rfbClientPtr cl, const char *response, int len)
144 bool allowUninvited = KrfbConfig::allowUninvitedConnections();
145 QString password = KrfbConfig::uninvitedConnectionPassword();
147 bool authd = false;
148 kDebug() << "about to start autentication";
150 if (allowUninvited) {
151 authd = checkPassword(password, cl->authChallenge, response, len);
154 if (!authd) {
155 QList<Invitation> invlist = InvitationManager::self()->invitations();
157 foreach(const Invitation &it, invlist) {
158 kDebug() << "checking password";
159 if (checkPassword(it.password(), cl->authChallenge, response, len) && it.isValid()) {
160 authd = true;
161 InvitationManager::self()->removeInvitation(it);
162 break;
167 if (!authd) {
168 if (InvitationManager::self()->invitations().size() > 0) {
169 KNotification::event("InvalidPasswordInvitations",
170 i18n("Failed login attempt from %1: wrong password",
171 remoteIp));
172 } else {
173 KNotification::event("InvalidPassword",
174 i18n("Failed login attempt from %1: wrong password",
175 remoteIp));
177 return false;
181 return true;
185 void ConnectionController::handleKeyEvent(bool down, rfbKeySym keySym)
187 if (controlEnabled) {
188 KeyboardEvent ev(down, keySym);
189 ev.exec();
193 void ConnectionController::handlePointerEvent(int bm, int x, int y)
195 if (controlEnabled) {
196 PointerEvent ev(bm, x, y);
197 ev.exec();
201 void ConnectionController::handleClientGone()
203 emit clientDisconnected(this);
204 kDebug() << "client gone";
205 deleteLater();
208 void ConnectionController::clipboardToServer(const QString &s)
210 ClipboardEvent ev(this, s);
211 ev.exec();
214 void ConnectionController::dialogAccepted()
216 // rfbStartOnHoldClient(cl);
217 cl->onHold = false;
220 void ConnectionController::dialogRejected()
222 kDebug() << "refused connection";
223 rfbRefuseOnHoldClient(cl);
226 void ConnectionController::setControlEnabled(bool enable)
228 controlEnabled = enable;