1
0
mirror of https://github.com/KDE/krfb synced 2026-07-01 07:41:17 -07:00

kinetd running fine, but not executing yet

svn path=/trunk/kdenetwork/krfb/; revision=140268
This commit is contained in:
Tim Jansen
2002-03-02 18:24:40 +00:00
parent 00dce900a9
commit cba2a6bae1
16 changed files with 324 additions and 87 deletions

View File

@@ -1,3 +1,9 @@
2002-02-24 Tim Jansen <tjansen@tjansen.de>
* fixed DCOP port() call
* added DCOP documentation
2002-02-20 Tim Jansen <tjansen@tjansen.de>
* krfb/xupdatescanner.cc: split tiles into left&right half if neccessary.

26
MODES_SECURITY Normal file
View File

@@ -0,0 +1,26 @@
Modes & Security
================
KRfb has 3 different security modes
- stand-alone:
+ traditional mode like in versions < 0.7
+ kinetd always disabled
+ KRfb only accepts connections from the time the user
started it until he quits krfb
+ no security restrictions (password can be empty)
- daemon/invitation only:
+ new default since 0.7
+ kinetd is only enabled after the user invited someone
+ krfb only accepts invited users, all other requests will be
denied
- daemon/open
+ kinetd is always enabled
+ a password must be set (enforced by kcontrol module, so this
can be overidden by editing the configuration)
+ kinetd accepts both invited and other users
- an invitation is a password that expires after a default of 60 min
- because of limitations in the Rfb protocol a connecting client must always
enter a password while invitations are valid, even if it is empty

1
README
View File

@@ -17,5 +17,6 @@ ROADMAP - KRfb roadmap, progress and future features
TODO - unscheduled things to be done
NOTES - reasons for various decisions
DCOP-INTERFACE - short documentation of the DCOP interface
MODES_SECURITY - modes & security settings
ChangeLog - more detailed changes with dates

View File

@@ -8,8 +8,8 @@ Version 0.6 (2002/02/18): Improved RFB backend
- knotify
Version 0.7: Better integration with KDE, improved GUI
- i18n
- kded module 'kinetd' that listens on the Rfb port and starts KRfb
- invitation support
- kcontrol module
- on startup a dialog appears that allows the user to invite somebody
using email (and later other mechanisms). Dialog can be turned off forever,
@@ -17,5 +17,6 @@ Version 0.7: Better integration with KDE, improved GUI
- remove STDOUT/STDERR logging
Version 0.8:
- i18n
- docs

View File

@@ -1,6 +1,6 @@
#MIN_CONFIG
AM_INIT_AUTOMAKE(krfb,0.6)
AM_INIT_AUTOMAKE(krfb,0.7)
AC_CHECK_HEADER(X11/extensions/XTest.h,
[],

View File

@@ -3,7 +3,7 @@ METASOURCES = AUTO
# Code
lib_LTLIBRARIES = libkded_kinetd.la
libkded_kinetd_la_SOURCES = kinetd.cpp kinetd.h
libkded_kinetd_la_SOURCES = kinetd.cpp kinetd.h kinetd.skel
libkded_kinetd_la_LIBADD = $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI)
# Services

View File

@@ -17,38 +17,73 @@
***************************************************************************/
/*
* TODOs:
* - setup servicetype
* - override configuration in KDEHOME with a KConfig
* - set listening ip address
* - implement autoPortRange
* TODOs:
* - get notified of changes in services
*/
#include "kinetd.h"
#include <kservicetype.h>
#include <kservice.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include <kconfig.h>
PortListener::PortListener(KService::Ptr s) :
valid(true),
autoPortRange(0),
multiInstance(false),
enabled(true)
PortListener::PortListener(KService::Ptr s)
{
loadConfig(s);
process.setExecutable(execPath);
port = portBase;
socket = new KServerSocket(port, false);
while (!socket->bindAndListen()) {
port++;
if (port >= (portBase+autoPortRange)) {
kdDebug() << "Kinetd cannot load service "<<serviceName
<<": unable to get port" << endl;
valid = false;
return;
}
delete socket;
socket = new KServerSocket(port, false);
}
connect(socket, SIGNAL(accepted(KSocket*)),
SLOT(accepted(KSocket*)));
}
void PortListener::loadConfig(KService::Ptr s) {
valid = true;
autoPortRange = 0;
enabled = true;
argument = QString::null;
multiInstance = false;
QVariant vid, vport, vautoport, venabled, vargument, vmultiInstance;
QVariant vport, vautoport, venabled, vargument, vmultiInstance;
serviceName = s->name();
execPath = s->exec();
vid = s->property("X-KDE-KINETD-id");
vport = s->property("X-KDE-KINETD-port");
vautoport = s->property("X-KDE-KINETD-autoPortRange");
venabled = s->property("X-KDE-KINETD-enabled");
vargument = s->property("X-KDE-KINETD-argument");
vmultiInstance = s->property("X-KDE-KINETD-multiInstance");
if (!vport.isValid())
vargument = s->property("X-KDE-KINETD-argument");
vmultiInstance = s->property("X-KDE-KINETD-multiInstance");
if (!vid.isValid()) {
kdDebug() << "Kinetd cannot load service "<<serviceName
<<": no id set" << endl;
valid = false;
else
port = vport.toInt();
return;
}
if (!vport.isValid()) {
kdDebug() << "Kinetd cannot load service "<<serviceName
<<": invalid port" << endl;
valid = false;
return;
}
serviceName = vid.toString();
portBase = vport.toInt();
if (vautoport.isValid())
autoPortRange = vautoport.toInt();
if (venabled.isValid())
@@ -58,23 +93,29 @@ PortListener::PortListener(KService::Ptr s) :
if (vmultiInstance.isValid())
multiInstance = vmultiInstance.toBool();
socket = new KServerSocket(port, false);
connect(socket, SIGNAL(accepted(KSocket*)),
SLOT(accepted(KSocket*)));
process.setExecutable(execPath);
if (!socket->bindAndListen()) {
// TODO: do something, implement autoport
kdDebug() << "bind failed" <<endl;
KStandardDirs ksd;
QString configName = ksd.findResource("config", "kinetdrc");
if (configName.isNull()) {
QString d = ksd.saveLocation("config");
if (!d.isNull())
configName = d + "/kinetdrc";
else {
valid = false;
kdDebug() << "Unable to create configuration" << endl;
return;
}
}
config = new KConfig(configName);
config->setGroup("ListenerConfig");
enabled = config->readBoolEntry("enabled_" + serviceName, enabled);
}
void PortListener::accepted(KSocket *sock) {
kdDebug() << "got connection" << endl;
if ((!enabled) ||
((!multiInstance) && process.isRunning())) {
if ((!enabled) ||
((!multiInstance) && process.isRunning())) {
delete sock;
return;
}
@@ -90,9 +131,30 @@ bool PortListener::isValid() {
return valid;
}
bool PortListener::isEnabled() {
return enabled;
}
void PortListener::setEnabled(bool e) {
if (e == enabled)
return;
enabled = e;
if (!config)
return;
config->setGroup("ListenerConfig");
config->writeEntry("enabled_" + serviceName, enabled);
config->sync();
}
QString PortListener::name() {
return serviceName;
}
PortListener::~PortListener() {
if (socket)
delete socket;
if (config)
delete config;
}
@@ -103,20 +165,62 @@ KInetD::KInetD(QCString &n) :
loadServiceList();
}
void KInetD::loadServiceList()
void KInetD::loadServiceList()
{
portListeners.clear();
KService::List kinetdModules =
KService::List kinetdModules =
KServiceType::offers("KInetDModule");
for(KService::List::ConstIterator it = kinetdModules.begin();
it != kinetdModules.end();
it++) {
for(KService::List::ConstIterator it = kinetdModules.begin();
it != kinetdModules.end();
it++) {
KService::Ptr s = *it;
portListeners.append(new PortListener(s));
PortListener *pl = new PortListener(s);
if (pl->isValid())
portListeners.append(pl);
}
}
PortListener *KInetD::getListenerByName(QString name)
{
PortListener *pl = portListeners.first();
while (pl) {
if (pl->name() == name)
return pl;
pl = portListeners.next();
}
return pl;
}
QStringList KInetD::services()
{
QStringList list;
PortListener *pl = portListeners.first();
while (pl) {
list.append(pl->name());
pl = portListeners.next();
}
return list;
}
bool KInetD::isEnabled(QString service)
{
PortListener *pl = getListenerByName(service);
if (!pl)
return false;
return pl->isEnabled();
}
void KInetD::setEnabled(QString service, bool enable)
{
PortListener *pl = getListenerByName(service);
if (!pl)
return;
pl->setEnabled(enable);
}
extern "C" {
KDEDModule *create_kinetd(QCString &name)

View File

@@ -23,13 +23,15 @@
#include <kservice.h>
#include <ksock.h>
#include <kprocess.h>
#include <qstringlist.h>
#include <qstring.h>
class PortListener : public QObject {
Q_OBJECT
private:
bool valid;
QString serviceName;
int port, autoPortRange;
int port, portBase, autoPortRange;
bool multiInstance;
QCString execPath;
QString argument;
@@ -37,11 +39,18 @@ private:
KServerSocket *socket;
KProcess process;
KConfig *config;
void loadConfig(KService::Ptr s);
public:
PortListener(KService::Ptr s);
~PortListener();
bool isValid();
QString name();
void setEnabled(bool enabled);
bool isEnabled();
private slots:
void accepted(KSocket*);
@@ -49,17 +58,40 @@ private slots:
class KInetD : public KDEDModule {
Q_OBJECT
K_DCOP
k_dcop:
/**
* Returns a list of all registered services in KInetd.
* To add a service you need to add a .desktop file with
* the servicetype "KInetDModule" into the services director
* (see kinetdmodule.desktop in servicetypes dir).
* @return a list with the names of all services
*/
QStringList services();
/**
* Returns true if the service exists and is available.
* @param service name of a service as specified in its .desktop file
* @return true if a service with the given name exists and is enabled
*/
bool isEnabled(QString service);
/**
* Enables or disabled the given service. Ignored if the given service
* does not exist.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setEnabled(QString service, bool enable);
private:
QPtrList<PortListener> portListeners;
public:
KInetD(QCString &n);
void loadServiceList();
// DCOP functions
void reloadPortListenerList();
PortListener *getListenerByName(QString name);
};

View File

@@ -1,22 +1,34 @@
# describes the servicetype that you need to implement in order to use
# kinetd.
[Desktop Entry]
Type=ServiceType
X-KDE-ServiceType=KInetDModule
Name=KInetD Module Type
[PropertyDef::X-KDE-Kinetd-port]
Type=int
[PropertyDef::X-KDE-Kinetd-autoPortRange]
Type=int
[PropertyDef::X-KDE-Kinetd-enabled]
Type=bool
[PropertyDef::X-KDE-Kinetd-argument]
# id to manipulate the service
[PropertyDef::X-KDE-KINETD-id]
Type=QString
[PropertyDef::X-KDE-Kinetd-multiInstance]
# describes the TCP port kinetd should listen to
[PropertyDef::X-KDE-KINETD-port]
Type=int
# if set and >0 the number of ports kinetd should probe if the port is in use
[PropertyDef::X-KDE-KINETD-autoPortRange]
Type=int
# if enabled kinetd will listen on the port. Can be overridden using the
# dcop interface.
[PropertyDef::X-KDE-KINETD-enabled]
Type=bool
# if set this argument if given to the app to start, followed by the number
# of the socket's fd
[PropertyDef::X-KDE-KINETD-argument]
Type=QString
# if true kinetd can accepts several connections at the same time. Otherwise
# it will block the port when a connection has been established.
[PropertyDef::X-KDE-KINETD-multiInstance]
Type=bool

View File

@@ -1,6 +1,6 @@
Begin3
Title: KDE Desktop Sharing (KRfb)
Version: 0.6
Version: 0.7
Entered-date:
Description: KRfb is a RFB (VNC) server that allows sharing a local
X11 session.

View File

@@ -7,10 +7,12 @@ krfb_SOURCES = rfbcontroller.cc configuration.cc trayicon.cpp \
krfb_LDADD = ../libvncserver/libvncserver.a -lz -lpthread -ljpeg -lXtst \
$(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) $(LIBSOCKET)
EXTRA_DIST = $(krfb_SOURCES) krfb.desktop lo32-app-krfb.png \
lo16-app-krfb.png rfbcontroller.h eyes-closed24.png eyes-open24.png \
xupdatescanner.h trayicon.h configuration.h krfbiface.h krfbiface.kidl \
eventsrc
kde_services_DATA = kinetd_krfb.desktop
EXTRA_DIST = $(krfb_SOURCES) $(kde_services_DATA) krfb.desktop \
lo32-app-krfb.png lo16-app-krfb.png rfbcontroller.h \
eyes-closed24.png eyes-open24.png xupdatescanner.h trayicon.h \
configuration.h krfbiface.h krfbiface.kidl eventsrc
install-data-local:
$(mkinstalldirs) $(kde_appsdir)/Applications/

View File

@@ -2,14 +2,15 @@
Encoding=UTF-8
Type=Service
ServiceTypes=KDEDModule
ServiceTypes=KInetDModule
Exec=krfb
X-KDE-FactoryName=kinetd
X-KDE-Kinetd-port=5900
X-KDE-Kinetd-autoPortRange=100
X-KDE-Kinetd-enabled=true
X-KDE-Kinetd-argument=--kinetd
X-KDE-Kinetd-multiInstance=false
X-KDE-KINETD-id=krfb
X-KDE-KINETD-port=5900
X-KDE-KINETD-autoPortRange=100
X-KDE-KINETD-enabled=true
X-KDE-KINETD-argument=--kinetd
X-KDE-KINETD-multiInstance=false
Name=KRfb Desktop Sharing
Comment=A daemon that allows you to share your desktop

View File

@@ -7,17 +7,69 @@ class krfbIface : virtual public DCOPObject
{
K_DCOP
k_dcop:
/**
* If a client is connected it will be disconnected.
*/
virtual void disconnect() = 0;
// virtual void setWindowID(int) = 0;
/**
* Quites krfb, connected clients will be disconnected.
*/
virtual void exit() = 0;
/**
* If true krfb will disconnect after a client disconnected.
* @return true if oneConnection feature is turned on
*/
virtual bool oneConnection() = 0;
virtual void setOneConnection(bool) = 0;
/**
* If set to true krfb will disconnect after a client disconnected.
* @param o true to turn oneConnection feature on.
*/
virtual void setOneConnection(bool o) = 0;
/**
* If this feature is activated krfb will ask the user before an incomning
* connection will be accepted.
* @return true if askOnConnect is activated
*/
virtual bool askOnConnect() = 0;
virtual void setAskOnConnect(bool) = 0;
/**
* If this feature is activated krfb will ask the user before an incomning
* connection will be accepted.
* @param a true to turn the askOnConnect feature on.
*/
virtual void setAskOnConnect(bool a) = 0;
/**
* If this feature is activated krfb allows the connecting client to
* control the desktop (pointer & keyboard).
* @return true if desktop control is activated
*/
virtual bool allowDesktopControl() = 0;
virtual void setAllowDesktopControl(bool) = 0;
virtual void setPassword(QString) = 0;
/**
* If this feature is activated krfb allows the connecting client to
* control the desktop (pointer & keyboard).
* @return a true to activate desktop control
*/
virtual void setAllowDesktopControl(bool a) = 0;
/**
* Sets the default password. An empty password can be used to deactivate
* the password authentication, but only if krfb is in stand-alone mode.
* @param p the password to set
*/
virtual void setPassword(QString p) = 0;
/**
* Returns the port the server is listening on.
* @return the tcp port of the server
*/
virtual int port() = 0;
};
#endif

View File

@@ -157,6 +157,8 @@ int main(int argc, char *argv[])
sigemptyset(&sigs);
sigaddset(&sigs, SIGPIPE);
sigprocmask(SIG_BLOCK, &sigs, 0);
controller.startServer();
return app.exec();
}

View File

@@ -249,8 +249,6 @@ RFBController::RFBController(Configuration *c) :
asyncQueue.setAutoDelete(true);
KeyboardEvent::initKeycodes();
startServer();
}
RFBController::~RFBController()
@@ -314,7 +312,7 @@ void RFBController::startServer(bool xtestGrab)
server->frameBuffer = fb;
server->autoPort = TRUE;
server->kbdAddEvent = keyboardHook;
server->ptrAddEvent = pointerHook;
server->newClientHook = newClientHook;
@@ -322,9 +320,9 @@ void RFBController::startServer(bool xtestGrab)
passwordChanged();
scanner = new XUpdateScanner(qt_xdisplay(),
QApplication::desktop()->winId(),
(unsigned char*)fb, w, h,
scanner = new XUpdateScanner(qt_xdisplay(),
QApplication::desktop()->winId(),
(unsigned char*)fb, w, h,
server->rfbServerFormat.bitsPerPixel,
server->paddedWidthInBytes);

View File

@@ -99,13 +99,13 @@ public:
* dialog.
* The controller has three states: 'waiting for connection',
* 'waiting for confirmation' and 'connected'. In the first state socket and
* connection are null, in the second socket is set and in the last both are
* connection are null, in the second socket is set and in the last both are
* set.
* @author Tim Jansen
*/
class RFBController : public QObject {
Q_OBJECT
public:
public:
RFBController(Configuration *c);
virtual ~RFBController();
@@ -121,22 +121,22 @@ public:
enum rfbNewClientAction handleNewClient(rfbClientPtr cl);
void handleClientGone();
int getPort();
void startServer(bool xtestGrab = true);
static bool checkX11Capabilities();
public slots:
public slots:
void rebind();
void passwordChanged();
void closeConnection();
signals:
void sessionEstablished();
void sessionFinished();
void sessionFinished();
void sessionRefused();
void portProbed(int);
private:
void startServer(bool xtestGrab = true);
private:
void stopServer(bool xtestUngrab = true);
bool checkAsyncEvents();
void sendDelayedKNotifyEvent(QString name, QString desc);