From 6161bef145b9d25ab87a3184035802da0fefe712 Mon Sep 17 00:00:00 2001 From: Amarnath Valluri Date: Tue, 15 Oct 2013 15:26:30 +0300 Subject: [PATCH] certifiacte validation code added --- common/dbus-error.h | 3 +++ configure.ac | 13 +++++++++++++ daemon/Makefile.am | 4 ++-- daemon/dbus-manager.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++----- daemon/dbus-manager.h | 4 ++++ daemon/dbus-service.c | 6 ++++++ daemon/manager.c | 4 ++++ examples/test-app.c | 6 +++--- lib/message-port.c | 2 +- lib/msgport-manager.c | 5 +++-- lib/msgport-service.c | 28 +-------------------------- 11 files changed, 88 insertions(+), 40 deletions(-) diff --git a/common/dbus-error.h b/common/dbus-error.h index 81789fd..fb7a080 100644 --- a/common/dbus-error.h +++ b/common/dbus-error.h @@ -38,6 +38,9 @@ msgport_error_quark (); #define msgport_error_port_id_not_found_new(service_id) \ msgport_error_new (MSGPORT_ERROR_NOT_FOUND, "no port found with id '%d'", service_id); +#define msgport_error_certificate_mismatch_new() \ + msgport_error_new (MSGPORT_ERROR_CERTIFICATE_MISMATCH, "cerficates not matched"); + #define msgport_error_unknown_new() \ msgport_error_new (MSGPORT_ERROR_UNKNOWN, "unknown"); diff --git a/configure.ac b/configure.ac index d334bd6..1529fb0 100644 --- a/configure.ac +++ b/configure.ac @@ -31,6 +31,10 @@ AC_SUBST(GIOUINX_LIBS) AC_SUBST(AUL_CFLAGS) AC_SUBST(AUL_LIBS) +#PKG_CHECK_MODULES([PKGMGRINFO], [pkgmgr-info]) +AC_SUBST(PKGMGRINFO_CFLAGS) +AC_SUBST(PKGMGRINFO_LIBS) + PKG_CHECK_MODULES([BUNDLE], [bundle]) AC_SUBST(BUNDLE_CFLAGS) AC_SUBST(BUNDLE_LIBS) @@ -39,6 +43,15 @@ AC_DEFINE(MESSAGEPORT_BUS_ADDRESS, ["unix:path=%s/.message-port", g_get_user_runtime_dir()], [messageport daemon server socket address]) +# Enable Debug +AC_ARG_ENABLE(debug, + [--enable-debug Eenable debug features], + [enable_debug=$enableval], [enable_debug=no]) +if test "x$enable_debug" = "xyes" ; then + AC_DEFINE(ENABLE_DEBUG, [1], [Enable debug features]) +fi + + # Checks for header files. AC_CHECK_HEADERS([string.h]) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index f2c4e60..1cb6548 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -15,12 +15,12 @@ messageportd_SOURCES = \ messageportd_CPPFLAGS = \ -I$(top_builddir) \ - $(GLIB_CLFAGS) $(GIO_CFLAGS) $(AUL_CFLAGS) \ + $(GLIB_CLFAGS) $(GIO_CFLAGS) $(AUL_CFLAGS) $(PKGMGRINFO_CFLAGS)\ $(NULL) messageportd_LDADD = \ ../common/libmessageport-dbus-glue.la \ - $(GLIB_LIBS) $(GIO_LIBS) $(AUL_LIBS) \ + $(GLIB_LIBS) $(GIO_LIBS) $(AUL_LIBS) $(PKGMGRINFO_LIBS) \ $(NULL) CLEANFILES = diff --git a/daemon/dbus-manager.c b/daemon/dbus-manager.c index 6d8ab64..7603309 100644 --- a/daemon/dbus-manager.c +++ b/daemon/dbus-manager.c @@ -42,6 +42,8 @@ struct _MsgPortDbusManagerPrivate { MsgPortManager *manager; MsgPortDbusServer *server; gchar *app_id; + gboolean is_null_cert; + GHashTable *peer_certs; }; @@ -72,6 +74,11 @@ _dbus_manager_dispose (GObject *self) g_clear_object (&dbus_mgr->priv->manager); + if (dbus_mgr->priv->peer_certs) { + g_hash_table_unref (dbus_mgr->priv->peer_certs); + dbus_mgr->priv->peer_certs = NULL; + } + G_OBJECT_CLASS (msgport_dbus_manager_parent_class)->dispose (self); } @@ -122,7 +129,8 @@ _dbus_manager_handle_check_for_remote_service ( msgport_return_val_if_fail (dbus_mgr && MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE); - DBG ("check remote service request from %p for %s %s", dbus_mgr, remote_app_id, remote_port_name); + DBG ("check remote service request from %p for %s %s %d", + dbus_mgr, remote_app_id, remote_port_name, is_trusted); remote_dbus_manager = msgport_dbus_server_get_dbus_manager_by_app_id ( dbus_mgr->priv->server, remote_app_id); @@ -154,17 +162,17 @@ _dbus_manager_handle_send_message ( gpointer userdata) { GError *error = NULL; - MsgPortDbusService *dbus_service = 0; + MsgPortDbusService *peer_dbus_service = 0; msgport_return_val_if_fail (dbus_mgr && MSGPORT_IS_DBUS_MANAGER (dbus_mgr), FALSE); DBG ("send_message from %p : %d ", dbus_mgr, service_id); - dbus_service = msgport_manager_get_service_by_id ( + peer_dbus_service = msgport_manager_get_service_by_id ( dbus_mgr->priv->manager, service_id, &error); - if (dbus_service){ - if (msgport_dbus_service_send_message (dbus_service, data, "", "", FALSE, &error)) { + if (peer_dbus_service) { + if (msgport_dbus_service_send_message (peer_dbus_service, data, dbus_mgr->priv->app_id, "", FALSE, &error)) { msgport_dbus_glue_manager_complete_send_message ( dbus_mgr->priv->dbus_skeleton, invocation); return TRUE; @@ -195,6 +203,8 @@ msgport_dbus_manager_init (MsgPortDbusManager *self) priv->dbus_skeleton = msgport_dbus_glue_manager_skeleton_new (); priv->manager = msgport_manager_new (); + priv->is_null_cert = FALSE; + priv->peer_certs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_signal_connect_swapped (priv->dbus_skeleton, "handle-register-service", G_CALLBACK (_dbus_manager_handle_register_service), (gpointer)self); @@ -294,3 +304,36 @@ msgport_dbus_manager_get_app_id (MsgPortDbusManager *dbus_manager) return (const gchar *)dbus_manager->priv->app_id; } +gboolean +msgport_dbus_manager_validate_peer_certificate (MsgPortDbusManager *dbus_manager, const gchar *peer_app_id) +{ + //int res ; + //pkgmgrinfo_cert_compare_result_type_e compare_result; + gboolean is_valid_cert = FALSE; + + /* check if the source application has no certificate info */ + if (dbus_manager->priv->is_null_cert) + return TRUE; /* allow all peers to connect */ + + /* check if we have cached status */ + if (g_hash_table_contains (dbus_manager->priv->peer_certs, peer_app_id)) + return (gboolean) g_hash_table_lookup (dbus_manager->priv->peer_certs, peer_app_id); +#if 0 + if ((res = pkgmgrinfo_pkginfo_compare_app_cert_info (dbus_manager->priv->app_id, + peer_app_id, &compare_result)) != PACKAGE_MANAGER_ERROR_NONE) { + WARN ("Fail to compare certificates of applications('%s', '%s') : error %d", + dbus_manager->priv->app_id, peer_app_id, res); + return FALSE; + } + if (compare_result == PMINFO_CERT_COMPARE_LHS_NO_CERT) { + dbus_manager->priv->is_null_cert = TRUE; + return TRUE; + } + + is_valid_cert = (compare_result == PMINFO_CERT_COMPARE_MATCH) ; + g_hash_table_insert (dbus_manager->priv->peer_certs, g_strdup (peer_app_id), (gpointer)is_valid_cert); +#endif + + return is_valid_cert; +} + diff --git a/daemon/dbus-manager.h b/daemon/dbus-manager.h index 3e325f0..8bfdad7 100644 --- a/daemon/dbus-manager.h +++ b/daemon/dbus-manager.h @@ -73,6 +73,10 @@ msgport_dbus_manager_get_connection (MsgPortDbusManager *dbus_manager); const gchar * msgport_dbus_manager_get_app_id (MsgPortDbusManager *dbus_manager); +gboolean +msgport_dbus_manager_validate_peer_certificate (MsgPortDbusManager *dbus_manager, + const gchar *peer_app_id); + G_END_DECLS #endif /* _MSGPORT_DBUS_MANAER_H */ diff --git a/daemon/dbus-service.c b/daemon/dbus-service.c index 8b20048..d6d9727 100644 --- a/daemon/dbus-service.c +++ b/daemon/dbus-service.c @@ -262,6 +262,12 @@ msgport_dbus_service_send_message ( { msgport_return_val_if_fail_with_error (dbus_service && MSGPORT_IS_DBUS_SERVICE (dbus_service), FALSE, error); + if (dbus_service->priv->is_trusted && + !msgport_dbus_manager_validate_peer_certificate (dbus_service->priv->owner, r_app_id)) { + if (error) *error = msgport_error_certificate_mismatch_new (); + return FALSE; + } + DBG ("Sending message to %p from '%s:%s'", dbus_service, r_app_id, r_port); msgport_dbus_glue_service_emit_on_message (dbus_service->priv->dbus_skeleton, data, r_app_id, r_port, r_is_trusted); diff --git a/daemon/manager.c b/daemon/manager.c index f85e054..30f7f97 100644 --- a/daemon/manager.c +++ b/daemon/manager.c @@ -181,6 +181,10 @@ msgport_manager_get_service ( while (service_list != NULL) { MsgPortDbusService *dbus_service = MSGPORT_DBUS_SERVICE (service_list->data); + DBG ("Owner : %p - Port : %s, Is_trusted : %d", owner, + msgport_dbus_service_get_port_name (dbus_service), + msgport_dbus_service_get_is_trusted (dbus_service)); + if ( !g_strcmp0 (remote_port_name, msgport_dbus_service_get_port_name (dbus_service)) && is_trusted == msgport_dbus_service_get_is_trusted (dbus_service)) { return dbus_service ; diff --git a/examples/test-app.c b/examples/test-app.c index 44d9498..08a8b92 100644 --- a/examples/test-app.c +++ b/examples/test-app.c @@ -68,7 +68,7 @@ void (_on_parent_got_message)(int port_id, const char* remote_app_id, const char int _register_test_port (const gchar *port_name, messageport_message_cb cb) { - int port_id = messageport_register_local_port (port_name, cb); + int port_id = messageport_register_trusted_local_port (port_name, cb); if (port_id > MESSAGEPORT_ERROR_NONE) { gchar *name = NULL; @@ -105,7 +105,7 @@ int main (int argc, char *argv[]) sleep (5); gchar *parent_app_id = g_strdup_printf ("%d", getppid()); gboolean found; - messageport_error_e res = messageport_check_remote_port (parent_app_id, "test_parent_port", &found); + messageport_error_e res = messageport_check_trusted_remote_port (parent_app_id, "test_parent_port", &found); if (!found) { DBG ("CHILD : Could not found remote port (%d)", res); @@ -118,7 +118,7 @@ int main (int argc, char *argv[]) bundle_add (b, "Name", "Amarnath"); bundle_add (b, "Email", "amarnath.valluri@intel.com"); - res = messageport_send_bidirectional_message(port_id, parent_app_id, "test_parent_port", b); + res = messageport_send_bidirectional_trusted_message(port_id, parent_app_id, "test_parent_port", b); bundle_free (b); if (res != MESSAGEPORT_ERROR_NONE) { diff --git a/lib/message-port.c b/lib/message-port.c index 32f1496..a5d1744 100644 --- a/lib/message-port.c +++ b/lib/message-port.c @@ -24,7 +24,7 @@ _messageport_check_remote_port (const char *app_id, const char *port, gboolean i messageport_error_e res; MsgPortManager *manager = msgport_get_manager (); - res = msgport_manager_check_remote_service (manager, app_id, port, FALSE, NULL); + res = msgport_manager_check_remote_service (manager, app_id, port, is_trusted, NULL); if (exists) *exists = (res == MESSAGEPORT_ERROR_NONE); diff --git a/lib/msgport-manager.c b/lib/msgport-manager.c index bc4a0c2..28f0699 100644 --- a/lib/msgport-manager.c +++ b/lib/msgport-manager.c @@ -218,7 +218,8 @@ msgport_manager_check_remote_service (MsgPortManager *manager, const gchar *app_ app_id, port, is_trusted, &remote_service_id, NULL, &error); if (error) { - WARN ("No service found for app_id %s, port name %s: %s", app_id, port, error->message); + WARN ("No %sservice found for app_id %s, port name %s: %s", + is_trusted ? "trusted " : "", app_id, port, error->message); g_error_free (error); return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; } @@ -290,7 +291,7 @@ msgport_manager_send_bidirectional_message (MsgPortManager *manager, int local_p return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; } if ( (res = msgport_manager_check_remote_service (manager, remote_app_id, remote_port, is_trusted, &remote_service_id) != MESSAGEPORT_ERROR_NONE)) { - WARN ("No remote port informatuon for %s:%s, error : %d", remote_app_id, remote_port, res); + WARN ("No remote %sport informatuon for %s:%s, error : %d", is_trusted ? "trusted " : "", remote_app_id, remote_port, res); return MESSAGEPORT_ERROR_MESSAGEPORT_NOT_FOUND; } diff --git a/lib/msgport-service.c b/lib/msgport-service.c index db698b3..c65cb77 100644 --- a/lib/msgport-service.c +++ b/lib/msgport-service.c @@ -60,7 +60,6 @@ _on_got_message (MsgPortService *service, GVariant *data, const gchar *remote_ap MsgPortService * msgport_service_new (GDBusConnection *connection, const gchar *path, messageport_message_cb message_cb) { - //GVariant *v_prop = NULL; GError *error = NULL; MsgPortService *service = g_object_new (MSGPORT_TYPE_SERVICE, NULL); @@ -72,36 +71,11 @@ msgport_service_new (GDBusConnection *connection, const gchar *path, messageport G_DBUS_PROXY_FLAGS_NONE, NULL, path, NULL, &error); if (!service->proxy) { g_object_unref (service); - WARN ("failed create servie proxy for path '%s' : %s", path, - error->message); + WARN ("failed create servie proxy for path '%s' : %s", path, error->message); g_error_free (error); return NULL; } -#if 0 - v_prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (service->proxy), "Id"); - if (v_prop) { - service->id = g_variant_get_uint32 (v_prop); - g_variant_unref (v_prop); - } else { - WARN ("Could not load property name 'Id' of service '%s'", path); - } - - v_prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (service->proxy), "PortName"); - if (v_prop) { - service->name = g_strdup (g_variant_get_string (v_prop, NULL)); - g_variant_unref (v_prop); - } else { - WARN ("Could not load property name 'PortName' of service '%s'", path); - } - v_prop = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (service->proxy), "IsTrusted"); - if (v_prop) { - service->is_trusted = g_variant_get_boolean (v_prop); - g_object_unref (v_prop); - } else { - WARN ("Could not load property name 'IsTrusted' of service '%s'", path); - } -#endif service->client_cb = message_cb; service->on_messge_signal_id = g_signal_connect_swapped (service->proxy, "on-message", G_CALLBACK (_on_got_message), service); -- 2.7.4