From c6ee92855d32a61a0b0e8aa399b822faaa7bcac7 Mon Sep 17 00:00:00 2001 From: Luiz Augusto Von Dentz Date: Mon, 7 Dec 2009 14:57:57 +0200 Subject: [PATCH] obexd: Fix pcsuite service driver matching Pcsuite is not a target but a client thus its .target should not be used with target header. This patch fixes it by using WHO header to search for a proper service as indicated by the spec: "Who is a length prefixed byte sequence used so that peer applications may identify each other, typically to allow special additional capabilities unique to that application or class of device to come into play." --- obexd/plugins/ftp.c | 6 ++++++ obexd/src/obex.c | 27 +++++++++++++++++++-------- obexd/src/service.c | 9 ++++++++- obexd/src/service.h | 5 ++++- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/obexd/plugins/ftp.c b/obexd/plugins/ftp.c index 5a1cc32d4..7174a6471 100644 --- a/obexd/plugins/ftp.c +++ b/obexd/plugins/ftp.c @@ -141,6 +141,10 @@ static const guint8 FTP_TARGET[TARGET_SIZE] = { 0xF9, 0xEC, 0x7B, 0xC4, 0x95, 0x3C, 0x11, 0xD2, 0x98, 0x4E, 0x52, 0x54, 0x00, 0xDC, 0x9E, 0x09 }; +static const guint8 PCSUITE_TARGET[TARGET_SIZE] = { + 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + static gint get_by_type(struct obex_session *os, gchar *type, size_t *size) { if (type == NULL) @@ -461,6 +465,8 @@ struct obex_service_driver pcsuite = { .record = PCSUITE_RECORD, .target = FTP_TARGET, .target_size = TARGET_SIZE, + .who = PCSUITE_TARGET, + .who_size = TARGET_SIZE, .connect = ftp_connect, .get = ftp_get, .put = ftp_put, diff --git a/obexd/src/obex.c b/obexd/src/obex.c index f75f02145..192b3dd98 100644 --- a/obexd/src/obex.c +++ b/obexd/src/obex.c @@ -178,6 +178,8 @@ static void cmd_connect(struct obex_session *os, guint hlen, newsize; guint16 mtu; guint8 hi; + const guint8 *target = NULL, *who = NULL; + guint target_size = 0, who_size = 0; if (OBEX_ObjectGetNonHdrData(obj, &buffer) != sizeof(*nonhdr)) { OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN); @@ -200,14 +202,21 @@ static void cmd_connect(struct obex_session *os, os->cid = ++cid; while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) { - if (hi != OBEX_HDR_TARGET) - continue; - - os->service = obex_service_driver_find(os->server->drivers, - hd.bs, hlen); - break; + switch (hi) { + case OBEX_HDR_WHO: + who = hd.bs; + who_size = hlen; + break; + case OBEX_HDR_TARGET: + target = hd.bs; + target_size = hlen; + break; + } } + os->service = obex_service_driver_find(os->server->drivers, + target, target_size, + who, who_size); if (os->service == NULL) { error("Connect attempt to a non-supported target"); OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN); @@ -215,6 +224,8 @@ static void cmd_connect(struct obex_session *os, return; } + debug("Selected driver: %s", os->service->name); + if (os->service->connect) os->service->connect(obex, obj); } @@ -892,8 +903,8 @@ gint obex_session_start(GIOChannel *io, struct server *server) os = g_new0(struct obex_session, 1); - os->service = obex_service_driver_find(server->drivers, NULL, 0); - + os->service = obex_service_driver_find(server->drivers, NULL, 0, + NULL, 0); os->current_folder = g_strdup(server->folder); os->server = server; os->rx_mtu = server->rx_mtu ? server->rx_mtu : DEFAULT_RX_MTU; diff --git a/obexd/src/service.c b/obexd/src/service.c index 3020acc36..06582fd89 100644 --- a/obexd/src/service.c +++ b/obexd/src/service.c @@ -39,13 +39,20 @@ static GSList *drivers = NULL; struct obex_service_driver *obex_service_driver_find(GSList *list, - const guint8 *target, guint target_size) + const guint8 *target, guint target_size, + const guint8 *who, guint who_size) + { GSList *l; for (l = list; l; l = l->next) { struct obex_service_driver *driver = l->data; + if (driver->who && who && + driver->who_size == who_size && + memcmp(driver->who, who, who_size) != 0) + continue; + if (driver->target == NULL && target == NULL) return driver; diff --git a/obexd/src/service.h b/obexd/src/service.h index df12e91c9..84a46753b 100644 --- a/obexd/src/service.h +++ b/obexd/src/service.h @@ -27,6 +27,8 @@ struct obex_service_driver { guint8 channel; const guint8 *target; guint target_size; + const guint8 *who; + guint who_size; const gchar *record; void (*connect) (obex_t *obex, obex_object_t *obj); void (*progress) (obex_t *obex, obex_object_t *obj); @@ -42,4 +44,5 @@ int obex_service_driver_register(struct obex_service_driver *driver); void obex_service_driver_unregister(struct obex_service_driver *driver); GSList *obex_service_driver_list(guint16 services); struct obex_service_driver *obex_service_driver_find(GSList *drivers, - const guint8 *target, guint target_size); + const guint8 *target, guint target_size, + const guint8 *who, guint who_size); -- 2.47.3