00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "connectioncontroller.h"
00011 #include "connectioncontroller.moc"
00012
00013 #include <QX11Info>
00014 #include <QHostInfo>
00015 #include <QApplication>
00016 #include <QDesktopWidget>
00017 #include <QTcpSocket>
00018 #include <QTimer>
00019
00020 #include <KConfig>
00021 #include <KGlobal>
00022 #include <KUser>
00023 #include <KNotification>
00024 #include <KLocale>
00025 #include <KDebug>
00026
00027
00028 #include "invitationmanager.h"
00029 #include "connectiondialog.h"
00030 #include "events.h"
00031 #include "krfbserver.h"
00032
00033 #include "krfbconfig.h"
00034
00035 #include <X11/Xutil.h>
00036 #include <sys/socket.h>
00037 #include <netinet/in.h>
00038 #include <arpa/inet.h>
00039
00040
00041 static QString peerAddress(int sock) {
00042
00043 const int ADDR_SIZE = 50;
00044 struct sockaddr sa;
00045 socklen_t salen = sizeof(struct sockaddr);
00046 if (getpeername(sock, &sa, &salen) == 0) {
00047 if (sa.sa_family == AF_INET) {
00048 struct sockaddr_in *si = (struct sockaddr_in *)&sa;
00049 return QString(inet_ntoa(si->sin_addr));
00050 }
00051 if (sa.sa_family == AF_INET6) {
00052 char inetbuf[ADDR_SIZE];
00053 inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
00054 return QString(inetbuf);
00055 }
00056 return QString("not a network address");
00057 }
00058 return QString("unable to determine...");
00059 }
00060
00061 static void clientGoneHook(rfbClientPtr cl)
00062 {
00063 ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
00064 cc->handleClientGone();
00065 }
00066
00067
00068 static bool checkPassword(const QString &p, unsigned char *ochallenge, const char *response, int len)
00069 {
00070
00071 if ((len == 0) && (p.length() == 0)) {
00072 return true;
00073 }
00074
00075 char passwd[MAXPWLEN];
00076 unsigned char challenge[CHALLENGESIZE];
00077
00078 memcpy(challenge, ochallenge, CHALLENGESIZE);
00079 bzero(passwd, MAXPWLEN);
00080 if (!p.isNull()) {
00081 strncpy(passwd, p.toLatin1(),
00082 (MAXPWLEN <= p.length()) ? MAXPWLEN : p.length());
00083 }
00084
00085 rfbEncryptBytes(challenge, passwd);
00086 return memcmp(challenge, response, len) == 0;
00087 }
00088
00089
00090 ConnectionController::ConnectionController(struct _rfbClientRec *_cl, KrfbServer * parent)
00091 : QObject(parent), cl(_cl)
00092 {
00093 cl->clientData = (void*)this;
00094 }
00095
00096 ConnectionController::~ConnectionController()
00097 {
00098 }
00099
00100 enum rfbNewClientAction ConnectionController::handleNewClient()
00101 {
00102
00103 bool askOnConnect = KrfbConfig::askOnConnect();
00104 bool allowUninvited = KrfbConfig::allowUninvitedConnections();
00105
00106 remoteIp = peerAddress(cl->sock);
00107
00108 if (!allowUninvited && InvitationManager::self()->activeInvitations() == 0) {
00109 KNotification::event("ConnectionAttempted",
00110 i18n("Attepted uninvited connection from %1: connection refused",
00111 remoteIp));
00112 return RFB_CLIENT_REFUSE;
00113 }
00114
00115 if (!askOnConnect && InvitationManager::self()->activeInvitations() == 0) {
00116 KNotification::event("NewConnectionAutoAccepted",
00117 i18n("Accepted uninvited connection from %1",
00118 remoteIp));
00119
00120 emit sessionEstablished(remoteIp);
00121 return RFB_CLIENT_ACCEPT;
00122 }
00123
00124 KNotification::event("NewConnectionOnHold",
00125 i18n("Received connection from %1, on hold (waiting for confirmation)",
00126 remoteIp));
00127
00128 cl->clientGoneHook = clientGoneHook;
00129
00130 ConnectionDialog *dialog = new ConnectionDialog(0);
00131 dialog->setRemoteHost(remoteIp);
00132 dialog->setAllowRemoteControl( true );
00133
00134 connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
00135 connect(dialog, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
00136
00137 dialog->show();
00138
00139 return RFB_CLIENT_ON_HOLD;
00140 }
00141
00142 bool ConnectionController::handleCheckPassword(rfbClientPtr cl, const char *response, int len)
00143 {
00144 bool allowUninvited = KrfbConfig::allowUninvitedConnections();
00145 QString password = KrfbConfig::uninvitedConnectionPassword();
00146
00147 bool authd = false;
00148 kDebug() << "about to start autentication";
00149
00150 if (allowUninvited) {
00151 authd = checkPassword(password, cl->authChallenge, response, len);
00152 }
00153
00154 if (!authd) {
00155 QList<Invitation> invlist = InvitationManager::self()->invitations();
00156
00157 foreach(Invitation it, invlist) {
00158 kDebug() << "checking password";
00159 if (checkPassword(it.password(), cl->authChallenge, response, len) && it.isValid()) {
00160 authd = true;
00161 InvitationManager::self()->removeInvitation(it);
00162 break;
00163 }
00164 }
00165 }
00166
00167 if (!authd) {
00168 if (InvitationManager::self()->invitations().size() > 0) {
00169 KNotification::event("InvalidPasswordInvitations",
00170 i18n("Failed login attempt from %1: wrong password",
00171 remoteIp));
00172 } else {
00173 KNotification::event("InvalidPassword",
00174 i18n("Failed login attempt from %1: wrong password",
00175 remoteIp));
00176 }
00177 return false;
00178 }
00179
00180
00181 return true;
00182 }
00183
00184
00185 void ConnectionController::handleKeyEvent(bool down, rfbKeySym keySym)
00186 {
00187 if (controlEnabled) {
00188 KeyboardEvent ev(down, keySym);
00189 ev.exec();
00190 }
00191 }
00192
00193 void ConnectionController::handlePointerEvent(int bm, int x, int y)
00194 {
00195 if (controlEnabled) {
00196 PointerEvent ev(bm, x, y);
00197 ev.exec();
00198 }
00199 }
00200
00201 void ConnectionController::handleClientGone()
00202 {
00203 emit clientDisconnected(this);
00204 kDebug() << "client gone";
00205 deleteLater();
00206 }
00207
00208 void ConnectionController::clipboardToServer(const QString &s)
00209 {
00210 ClipboardEvent ev(this, s);
00211 ev.exec();
00212 }
00213
00214 void ConnectionController::dialogAccepted()
00215 {
00216
00217 cl->onHold = false;
00218 }
00219
00220 void ConnectionController::dialogRejected()
00221 {
00222 kDebug() << "refused connection";
00223 rfbRefuseOnHoldClient(cl);
00224 }
00225
00226 void ConnectionController::setControlEnabled(bool enable)
00227 {
00228 controlEnabled = enable;
00229 }
00230
00231