--- kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/Makefile.am +++ kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/Makefile.am @@ -4,10 +4,10 @@ # Code bin_PROGRAMS = kbluetoothd -kbluetoothd_SOURCES = rfcommportlistener.cpp sdprecord.cpp confirmationdlgbase.ui confirmation.cpp devicenamecache.cpp devicenamecache.skel metaserver.skel hcidevmonitor.cpp trayicon.cpp main.cpp application.cpp conmainwidget.ui condetailswidget.ui metaserver.cpp connectiondlg.cpp devicescanner.skel devicescanner.cpp pinserver.cpp pinserver.skel pingendialog.ui pindefdialog.ui pindialog.cpp procinheritsock.cpp mostrecentlyused.skel mostrecentlyused.cpp hcilistener.cpp neighbourmonitor.cpp portlistener.cpp +kbluetoothd_SOURCES = rfcommportlistener.cpp sdprecord.cpp confirmationdlgbase.ui confirmation.cpp devicenamecache.cpp devicenamecache.skel metaserver.skel hcidevmonitor.cpp trayicon.cpp main.cpp application.cpp conmainwidget.ui condetailswidget.ui metaserver.cpp connectiondlg.cpp devicescanner.skel devicescanner.cpp pinserver.cpp pinserver.skel pingendialog.ui pindefdialog.ui pindialog.cpp procinheritsock.cpp mostrecentlyused.skel mostrecentlyused.cpp hcilistener.cpp neighbourmonitor.cpp portlistener.cpp dbuspasskeyagent.cpp kbluetoothd_LDFLAGS = $(KDE_RPATH) $(all_libraries) -kbluetoothd_LDADD = ../../libkbluetooth/libkbluetooth.la ../libkbluetoothd/libkbluetoothd.la $(LIB_KIO) $(LIB_KDEUI) +kbluetoothd_LDADD = ../../libkbluetooth/libkbluetooth.la ../libkbluetoothd/libkbluetoothd.la $(LIB_KIO) $(LIB_KDEUI) $(DBUS_LIBS) -ldbus-qt-1 # Services kde_servicetypes_DATA = kbluetoothdmodule.desktop @@ -31,6 +31,6 @@ $(INSTALL_DATA) $(srcdir)/eventsrc $(DESTDIR)$(kde_datadir)/kbluetoothd/eventsrc # set the include path for X, qt and KDE -INCLUDES = -I$(top_srcdir)/kdebluetooth $(all_includes) $(BLUETOOTH_CFLAGS) +INCLUDES = -I$(top_srcdir)/kdebluetooth $(all_includes) $(BLUETOOTH_CFLAGS) $(DBUS_CFLAGS) -noinst_HEADERS = procinheritsock.h mostrecentlyused.h hcilistener.h neighbourmonitor.h +noinst_HEADERS = procinheritsock.h mostrecentlyused.h hcilistener.h neighbourmonitor.h dbuspasskeyagent.h --- ./kdebluetooth/kbluetoothd/kbluetoothd/application.cpp.orig 2006-10-16 14:23:56.000000000 +0400 +++ ./kdebluetooth/kbluetoothd/kbluetoothd/application.cpp 2007-03-30 23:34:21.792836593 +0400 @@ -26,6 +26,8 @@ #include #include +#include "dbuspasskeyagent.h" + using namespace KBluetooth; using namespace std; @@ -57,6 +59,8 @@ hciListener->start(); bFirstNewInstance = true; trayIcon->slotMruMenuUpdate(); + + agent = new DBusPasskeyAgent(this); // Warn the user if the location of kbluepin has changed // Don't show if bluez-libs is 3.x @@ -74,6 +78,7 @@ mru->writeConfig(); delete m_config; delete trayIcon; + delete agent; } int KBluetoothdApp::newInstance() --- kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/application.h +++ kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/application.h @@ -29,6 +29,7 @@ class MostRecentlyUsed; class HciListener; class HciDevMonitor; +class DBusPasskeyAgent; class KBluetoothdApp: public KUniqueApplication { @@ -52,6 +53,7 @@ void slotHciDeviceLost(); void configUpdate(); private: + DBusPasskeyAgent *agent; void startServices(); void endServices(); KConfig* m_config; --- kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/configure.in.in +++ kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/configure.in.in @@ -7,3 +7,18 @@ KDE_EXPAND_MAKEVAR(KBLUETOOTHDJOBTEMPLATEDIR, KBLUETOOTHDJOBTEMPLATEDIR) AC_SUBST(KBLUETOOTHDJOBTEMPLATEDIR) AC_DEFINE_UNQUOTED(KBLUETOOTHDJOBTEMPLATEDIR, "$KBLUETOOTHDJOBTEMPLATEDIR", [job templates for kbluetoothd]) + +# DBUS +PKG_CHECK_MODULES(DBUS, "dbus-1") + +AC_SUBST(DBUS_CFLAGS) +AC_SUBST(DBUS_LIBS) + +# DBUS QT BINDING ### stolen from kpowersave and knetworkmanager ;) # +CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS $all_includes -DDBUS_API_SUBJECT_TO_CHANGE" +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +AC_CHECK_HEADER([dbus/connection.h],,[AC_MSG_ERROR([You need D-BUS/Qt3 bindings])]) +AC_CHECK_HEADER([dbus/message.h],,[AC_MSG_ERROR([You need D-BUS/Qt3 bindings])]) +#CPPFLAGS=$safe_CPPFLAGS +AC_LANG_RESTORE --- kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/dbuspasskeyagent.cpp +++ kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/dbuspasskeyagent.cpp @@ -0,0 +1,296 @@ +/* + * + * BlueZ Passkey Agent Interface for kbluetoothd + * + * Copyright (C) 2006 Daniel Gollub + * + * + * This file is part of kbluetoothd. + * + * kbluetooth is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * libkbluetooth is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libkbluetooth; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include "dbuspasskeyagent.h" + +#define KBLUETOOTH_DBUS_PATH "/org/bluez/kbluetoothd_" + +DBusMessage* DBusPasskeyAgent::_msg = NULL; +KBluetoothdApp *DBusPasskeyAgent::_app = NULL; +PinDialog* DBusPasskeyAgent::_pinDialog = NULL; +DBusPasskeyAgent *DBusPasskeyAgent::_ctx = NULL; + +DBusPasskeyAgent::DBusPasskeyAgent(KBluetoothdApp *app) : QObject() +{ + this->_app = app; + this->_ctx = this; + this->agentpath = QString(KBLUETOOTH_DBUS_PATH "%1").arg(getpid()); + dbusInit(); + addHandler(); + registerDefaultPasskeyAgent(); +} + +DBusPasskeyAgent::~DBusPasskeyAgent() +{ + kdDebug() << __func__ << endl; + unregisterDefaultPasskeyAgent(); +} + +bool DBusPasskeyAgent::dbusInit() +{ + kdDebug() << "<<<<< " << __func__ << endl; + + kdDebug() << __func__ << "()" << endl; + + DBusError error; + dbus_error_init(&error); + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + + if (!conn) { + kdDebug() << "dbus_bus_get() failed...." << endl; + if (dbus_error_is_set(&error)) { + kdDebug() << error.message << endl; + dbus_error_free(&error); + return false; + } + } + + _dbusConnection = new DBusQt::Connection(this); + if (!_dbusConnection) { + kdDebug() << __func__ << " DBusQt::Connection() failed." << endl; + return false; + } + + _dbusConnection->dbus_connection_setup_with_qt_main(conn); + + return true; +} + +bool DBusPasskeyAgent::registerDefaultPasskeyAgent() +{ + kdDebug() << "<<<<< " << __func__ << endl; + + kdDebug() << __func__ << "()" << endl; + + DBusMessage *reply = NULL; + DBusError error; + + dbus_error_init(&error); + + DBusMessage *msg = NULL; + msg = dbus_message_new_method_call(INTERFACE_BLUEZ, BLUEZ_PATH, INTERFACE_SECURITY, "RegisterDefaultPasskeyAgent"); + if (!msg) { + kdDebug() << "kbluetoothd (Default Passkey Agent): Can't allocate new method call" << endl; + return false; + } + + const char *path = agentpath.latin1(); + dbus_message_append_args(msg, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error); + if (!reply) { + if (dbus_error_is_set(&error)) { + kdDebug() << "kbluetoothd (Default Passkey Agent): " << __func__ << "(): " << error.message << endl; + dbus_error_free(&error); + return false; + } + } + + return true; +} + +bool DBusPasskeyAgent::unregisterDefaultPasskeyAgent() +{ + kdDebug() << "<<<<< " << __func__ << endl; + + DBusMessage *reply = NULL; + DBusError error; + + dbus_error_init(&error); + + DBusMessage *msg = NULL; + msg = dbus_message_new_method_call(INTERFACE_BLUEZ, BLUEZ_PATH, INTERFACE_SECURITY, "UnregisterDefaultPasskeyAgent"); + if (!msg) { + kdDebug() << "kbluetoothd (Unregister Default Passkey Agent): Can't allocate new method call" << endl; + return false; + } + + const char *path = agentpath.latin1(); + dbus_message_append_args(msg, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error); + if (!reply) { + if (dbus_error_is_set(&error)) { + kdDebug() << "kbluetoothd (Default Passkey Agent): " << __func__ << "(): " << error.message << endl; + dbus_error_free(&error); + return false; + } + } + + return true; +} + +bool DBusPasskeyAgent::addHandler() +{ + kdDebug() << "<<<<< " << __func__ << endl; + + DBusError error; + DBusHandleMessageFunction filter = filterFunction; + + dbus_error_init(&error); + + if (!dbus_connection_add_filter(conn, filter, NULL, NULL)) { + return false; + } + + // TODO ... error handler + dbus_bus_add_match(conn, "interface=" DBUS_INTERFACE_DBUS "," + "member=NameOwnerChanged, arg0=" INTERFACE_BLUEZ, &error); + dbus_bus_add_match(conn, "type='signal',interface='" INTERFACE_SECURITY "'," + "path='" BLUEZ_PATH "',sender='" INTERFACE_BLUEZ "'", &error); + dbus_bus_add_match(conn, "type='signal',interface='" INTERFACE_MANAGER "'," + "path='" BLUEZ_PATH "',sender='" INTERFACE_BLUEZ "'", &error); + + + return true; +} + +DBusHandlerResult DBusPasskeyAgent::filterFunction(DBusConnection * /*conn*/, DBusMessage *msg, void * /*data*/) +{ + kdDebug() << __func__ << "()....................." << endl; + const char *member = dbus_message_get_member(msg); + + if (!member) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + kdDebug() << __func__ << "(): " << member << endl; + + if (!strcmp("Request", member)) { + return _ctx->requestMessage(msg); + } else if (!strcmp("NameOwnerChanged", member)) { + return _ctx->ownerChanged(msg); + } else if (!strcmp("AdapterAdded", member)) { + _ctx->registerDefaultPasskeyAgent(); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +QString DBusPasskeyAgent::getRemoteName(const char *path, const char *address) +{ + + const char *remotename; + DBusError error; + dbus_error_init(&error); + + DBusMessage *msg = NULL; + msg = dbus_message_new_method_call(INTERFACE_BLUEZ, path, "org.bluez.Adapter", "GetRemoteName"); + if (!msg) { + kdDebug() << "kbluetoothd (Default Passkey Agent) " << __func__ << "(): Can't allocate new method call" << endl; + return false; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID); + DBusMessage *reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &error); + if (!reply) { + if (dbus_error_is_set(&error)) { + kdDebug() << "kbluetoothd (Default Passkey Agent): " << __func__ << "(): " << error.message << endl; + dbus_error_free(&error); + return QString::null; + } + } + + dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &remotename, DBUS_TYPE_INVALID); + dbus_message_unref(reply); + + return QString::fromUtf8(remotename); +} + +DBusHandlerResult DBusPasskeyAgent::requestMessage(DBusMessage *msg) { + + const char *path, *address; + QString remotename = QString::null; + + _msg = msg; + + dbus_message_ref(_msg); + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, + DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID)) { + kdDebug() << "DBusPasskeyAgent: Invalid argumentes for Passkey Request method." << endl; + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + /* get address and remote name */ + + remotename = _ctx->getRemoteName(path, address); + + + if (remotename == QString::null) + remotename = QString("n/a"); + + _pinDialog = new PinDialog(NULL, true, false, QString(address), remotename, _ctx); + _pinDialog->show(); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +DBusHandlerResult DBusPasskeyAgent::ownerChanged(DBusMessage *msg) { + kdDebug() << __func__ << "()" << endl; + + char *service, *old_owner, *new_owner; + + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &service, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, + DBUS_TYPE_INVALID)) { + + if (!strcmp(service, INTERFACE_BLUEZ)) { + if (new_owner && (strlen(new_owner) > 0)) { + kdDebug() << __func__ << "(): rerun default passkey agent." << endl; + _ctx->registerDefaultPasskeyAgent(); + } + } + } + + + return DBUS_HANDLER_RESULT_HANDLED; +} + +void DBusPasskeyAgent::sendPin() { + kdDebug() << __func__ << "()" << endl; + + QString qpasskey = _pinDialog->getPin(); + const char *passkey = qpasskey.ascii(); + + DBusMessage *reply = dbus_message_new_method_return(_msg); + if (!reply) { + kdDebug() << __func__ <<" (): Reply failed." << endl; + goto error_free; + } + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &passkey, DBUS_TYPE_INVALID); + + dbus_connection_send(conn, reply, NULL); + dbus_message_unref(reply); + + kdDebug() << __func__ << "(): send." << endl; + +error_free: + dbus_message_unref(_msg); +} + +#include "dbuspasskeyagent.moc" --- kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/dbuspasskeyagent.h +++ kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/dbuspasskeyagent.h @@ -0,0 +1,91 @@ +/* + * + * BlueZ Passkey Agent Interface for kbluetoothd + * + * Copyright (C) 2006 Daniel Gollub + * + * + * This file is part of kbluetoothd. + * + * kbluetooth is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * libkbluetooth is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libkbluetooth; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +#ifndef DBUSPASSKEYAGENT_H +#define DBUSPASSKEYAGENT_H + +#ifndef DBUS_API_SUBJECT_TO_CHANGE +#define DBUS_API_SUBJECT_TO_CHANGE +#endif + +#include + +#include +#include + +#include "application.h" +#include "pindialog.h" + +#define BLUEZ_PATH "/org/bluez" +#define INTERFACE_BLUEZ "org.bluez" +#define INTERFACE_MANAGER "org.bluez.Manager" +#define INTERFACE_SECURITY "org.bluez.Security" +#define INTERFACE_PASSKEYAGENT "org.bluez.PasskeyAgent" + +class PinDialog; + +class DBusPasskeyAgent : public QObject +{ + + Q_OBJECT + + public: + DBusPasskeyAgent(KBluetoothdApp *app); + ~DBusPasskeyAgent(); + + public slots: + void sendPin(); + + private: + + bool dbusInit(); + + bool registerDefaultPasskeyAgent(); + bool unregisterDefaultPasskeyAgent(); + + bool addHandler(); + + QString getRemoteName(const char *path, const char *address); + + static DBusHandlerResult filterFunction(DBusConnection *conn, DBusMessage *msg, void *data); + static DBusHandlerResult requestMessage(DBusMessage *msg); + static DBusHandlerResult ownerChanged(DBusMessage *msg); + + + + static KBluetoothdApp *_app; + static DBusPasskeyAgent *_ctx; + static DBusMessage *_msg; + static PinDialog *_pinDialog; + + + QString agentpath; + DBusConnection *conn; + DBusQt::Connection *_dbusConnection; + +}; + +#endif // DBUSPASSKEYAGENT_H --- kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/pindialog.cpp +++ kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/pindialog.cpp @@ -30,7 +30,7 @@ #include PinDialog::PinDialog(QWidget* owner, bool /*bIncoming*/, - bool ownAuth, QString addr, QString devName) : + bool ownAuth, QString addr, QString devName, DBusPasskeyAgent *agent) : KDialogBase(owner, "pinrequest", ownAuth, "Pin Request", ownAuth?(Close):(Ok|Cancel)) { @@ -63,6 +63,8 @@ pinDlg->pinEdit->setFocus(); } + connect(this, SIGNAL (okClicked()), agent, SLOT (sendPin())); + if (ownAuth) { setMainWidget(pinGenDlg); pinGenDlg->goButton->setFocus(); @@ -76,9 +78,14 @@ { } +QString PinDialog::getPin() +{ + return pinDlg->pinEdit->text(); +} + QString PinDialog::getPin(bool bIn, bool ownAuth, QString addr, QString name) { - QGuardedPtr dlg = new PinDialog(NULL, bIn, ownAuth, addr, name); + QGuardedPtr dlg = new PinDialog(NULL, bIn, ownAuth, addr, name, NULL); if (ownAuth == true) { if (!dlg->pinGenDlg) return QString::null; dlg->show(); --- kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/pindialog.h +++ kdebluetooth/kdebluetooth/kbluetoothd/kbluetoothd/pindialog.h @@ -15,8 +15,11 @@ #include #include +#include "dbuspasskeyagent.h" +#include "pindefdialog.h" + class PinGenerateDialog; -class PinDefaultDialog; +//class PinDefaultDialog; class QWidget; namespace KBluetooth { class HciSocket; @@ -29,11 +32,13 @@ { Q_OBJECT public: - PinDialog(QWidget* owner, bool bIn, bool ownAuth, QString addr, QString name); + PinDialog(QWidget* owner, bool bIn, bool ownAuth, QString addr, QString name, DBusPasskeyAgent *agent); ~PinDialog(); + QString getPin(); static QString getPin(bool bIn, bool ownAuth, QString addr, QString name); + PinDefaultDialog *pinDlg; protected: - QGuardedPtr pinDlg; +// QGuardedPtr pinDlg; QGuardedPtr pinGenDlg; QString addr; KBluetooth::HciSocket *hciSocket;