summaryrefslogtreecommitdiffstats
path: root/hcid/passkey-agent.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-03-13 18:33:34 +0000
committerMarcel Holtmann <marcel@holtmann.org>2006-03-13 18:33:34 +0000
commit66c7a54e436948b18044dd9256a8ad24f34b1f72 (patch)
tree9198ccfd88ebaa81ed0fc697dcfae287a57e0097 /hcid/passkey-agent.c
parentbf8b147f99d4c7be3d03a55c4889e7b5970c94e6 (diff)
Support specific passkey agents and check for service termination
Diffstat (limited to 'hcid/passkey-agent.c')
-rw-r--r--hcid/passkey-agent.c247
1 files changed, 201 insertions, 46 deletions
diff --git a/hcid/passkey-agent.c b/hcid/passkey-agent.c
index b3ba2e3b..423a72f2 100644
--- a/hcid/passkey-agent.c
+++ b/hcid/passkey-agent.c
@@ -27,37 +27,74 @@
#include <stdio.h>
#include <errno.h>
+#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
+#include <getopt.h>
#include <string.h>
#include <dbus/dbus.h>
-static const char *agent_path = "/org/bluez/passkey_agent";
+#define INTERFACE "org.bluez.Security"
-static char *passkey = "0000";
+static char *passkey = NULL;
+static char *address = NULL;
static volatile sig_atomic_t __io_canceled = 0;
+static volatile sig_atomic_t __io_terminated = 0;
static void sig_term(int sig)
{
__io_canceled = 1;
}
-DBusHandlerResult agent_message(DBusConnection *conn, DBusMessage *msg, void *data)
+static DBusHandlerResult agent_filter(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ const char *name, *old, *new;
+
+ if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old,
+ DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "Invalid arguments for NameOwnerChanged signal");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (!strcmp(name, "org.bluez") && *new == '\0') {
+ fprintf(stderr, "Passkey service has been terminated\n");
+ __io_terminated = 1;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult agent_message(DBusConnection *conn, DBusMessage *msg, void *data)
{
DBusMessage *reply;
- DBusMessageIter iter;
- char *path, *address;
+ const char *path, *address;
- dbus_message_iter_init(msg, &iter);
- dbus_message_iter_get_basic(&iter, &path);
- dbus_message_iter_get_basic(&iter, &address);
+ if (!dbus_message_is_method_call(msg, INTERFACE, "Request"))
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (!passkey)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path,
+ DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "Invalid arguments for passkey Request method");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
reply = dbus_message_new_method_return(msg);
+ if (!reply) {
+ fprintf(stderr, "Can't create reply message\n");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &passkey);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &passkey,
+ DBUS_TYPE_INVALID);
dbus_connection_send(conn, reply, NULL);
@@ -72,78 +109,196 @@ static const DBusObjectPathVTable agent_table = {
.message_function = agent_message,
};
-int main(int argc, char **argv)
+static int register_agent(DBusConnection *conn, const char *agent_path,
+ const char *address, int use_default)
{
- struct sigaction sa;
- DBusConnection* conn;
DBusMessage *msg, *reply;
- DBusMessageIter iter;
- DBusError err;
+ const char *path, *method;
- dbus_error_init(&err);
+ if (!dbus_connection_register_object_path(conn, agent_path,
+ &agent_table, NULL)) {
+ fprintf(stderr, "Can't register path object path for agent\n");
+ return -1;
+ }
- conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ if (use_default) {
+ path = "/org/bluez/Manager";
+ method = "RegisterDefaultPasskeyAgent";
+ } else {
+ path = "/org/bluez/Adapter/hci0";
+ method = "RegisterPasskeyAgent";
+ }
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Can't get on system bus");
- dbus_error_free(&err);
- exit(1);
+ msg = dbus_message_new_method_call("org.bluez", path, INTERFACE, method);
+ if (!msg) {
+ fprintf(stderr, "Can't allocate new method call\n");
+ return -1;
}
- dbus_connection_register_object_path(conn, agent_path,
- &agent_table, NULL);
+ if (use_default)
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path,
+ DBUS_TYPE_INVALID);
+ else
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path,
+ DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID);
+
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, NULL);
+
+ dbus_message_unref(msg);
- msg = dbus_message_new_method_call("org.bluez", "/org/bluez/Manager",
- "org.bluez.Security", "RegisterDefaultPasskeyAgent");
+ if (!reply) {
+ fprintf(stderr, "Can't register passkey agent\n");
+ return -1;
+ }
+
+ dbus_message_unref(reply);
+
+ dbus_connection_flush(conn);
+ return 0;
+}
+
+static int unregister_agent(DBusConnection *conn, const char *agent_path,
+ const char *address, int use_default)
+{
+ DBusMessage *msg, *reply;
+ const char *path, *method;
+
+ if (use_default) {
+ path = "/org/bluez/Manager";
+ method = "UnregisterDefaultPasskeyAgent";
+ } else {
+ path = "/org/bluez/Adapter/hci0";
+ method = "UnregisterPasskeyAgent";
+ }
+
+ msg = dbus_message_new_method_call("org.bluez", path, INTERFACE, method);
if (!msg) {
fprintf(stderr, "Can't allocate new method call\n");
+ dbus_connection_close(conn);
exit(1);
}
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &agent_path);
+ if (use_default)
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path,
+ DBUS_TYPE_INVALID);
+ else
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &agent_path,
+ DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID);
- reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, NULL);
dbus_message_unref(msg);
if (!reply) {
- fprintf(stderr, "Can't register passkey agent\n");
- exit(1);
+ fprintf(stderr, "Can't unregister passkey agent\n");
+ return -1;
}
dbus_message_unref(reply);
dbus_connection_flush(conn);
+ return 0;
+}
+
+static void usage(void)
+{
+ printf("Bluetooth passkey agent ver %s\n\n", VERSION);
+
+ printf("Usage:\n"
+ "\tpasskey-agent [--default] [--path agent-path] <passkey> [address]\n"
+ "\n");
+}
+
+static struct option main_options[] = {
+ { "default", 0, 0, 'd' },
+ { "path", 0, 0, 'p' },
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+int main(int argc, char **argv)
+{
+ struct sigaction sa;
+ DBusConnection *conn;
+ char match_string[128], default_path[128], *agent_path = NULL;
+ int opt, use_default = 0;
+
+ snprintf(default_path, sizeof(default_path),
+ "/org/bluez/passkey-agent-%d", getpid());
+
+ while ((opt = getopt_long(argc, argv, "+dp:h", main_options, NULL)) != EOF) {
+ switch(opt) {
+ case 'd':
+ use_default = 1;
+ break;
+ case 'p':
+ if (optarg[0] != '/') {
+ fprintf(stderr, "Invalid path\n");
+ exit(1);
+ }
+ agent_path = strdup(optarg);
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ default:
+ exit(1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ optind = 0;
+
+ if (argc < 1) {
+ usage();
+ exit(1);
+ }
+
+ passkey = strdup(argv[0]);
+ address = (argc > 1) ? strdup(argv[1]) : NULL;
+
+ if (!agent_path)
+ agent_path = strdup(default_path);
+
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ if (!conn) {
+ fprintf(stderr, "Can't get on system bus");
+ exit(1);
+ }
+
+ if (register_agent(conn, agent_path, address, use_default) < 0) {
+ dbus_connection_close(conn);
+ exit(1);
+ }
+
+ if (!dbus_connection_add_filter(conn, agent_filter, NULL, NULL))
+ fprintf(stderr, "Can't add signal filter");
+
+ snprintf(match_string, sizeof(match_string),
+ "interface=%s,member=NameOwnerChanged,arg0=%s",
+ DBUS_INTERFACE_DBUS, "org.bluez");
+
+ dbus_bus_add_match(conn, match_string, NULL);
+
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_NOCLDSTOP;
sa.sa_handler = sig_term;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
- while (!__io_canceled) {
+ while (!__io_canceled && !__io_terminated) {
if (dbus_connection_read_write_dispatch(conn, 100) != TRUE)
break;
}
-#if 0
- msg = dbus_message_new_method_call("org.bluez", "/org/bluez/Manager",
- "org.bluez.Security", "UnregisterDefaultPasskeyAgent");
-
- if (!msg) {
- fprintf(stderr, "Can't allocate new method call\n");
- exit(1);
- }
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &agent_path);
-
- reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ if (!__io_terminated)
+ unregister_agent(conn, agent_path, address, use_default);
- dbus_message_unref(msg);
-#endif
+ if (passkey)
+ free(passkey);
dbus_connection_close(conn);