core: add authorization providers and optional PolicyKit support
When the support is complete, use --with-polkit to enable PolicyKit support. It's not there yet, but this commit adds an authorization provider framework which will be extended to allow hooking into PolicyKit.
This commit is contained in:
@@ -19,7 +19,11 @@ all: $(GENERATED_FILES)
|
||||
CLEANFILES = $(GENERATED_FILES)
|
||||
endif
|
||||
|
||||
SUBDIRS = marshallers src plugins introspection po policy test
|
||||
SUBDIRS = marshallers src plugins introspection po test
|
||||
|
||||
if WITH_POLKIT
|
||||
SUBDIRS += policy
|
||||
endif
|
||||
|
||||
dbusservicedir = $(DBUS_SYS_DIR)
|
||||
dbusservice_DATA = org.freedesktop.ModemManager.conf
|
||||
|
18
configure.ac
18
configure.ac
@@ -50,6 +50,22 @@ AC_SUBST(UDEV_BASE_DIR)
|
||||
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
|
||||
AC_SUBST(GLIB_GENMARSHAL)
|
||||
|
||||
# PolicyKit
|
||||
AC_ARG_WITH(polkit, AS_HELP_STRING([--with-polkit], [Build with PolicyKit support]))
|
||||
AM_CONDITIONAL(WITH_POLKIT, test "x$with_polkit" = "xyes")
|
||||
case $with_polkit in
|
||||
yes)
|
||||
with_polkit=yes
|
||||
PKG_CHECK_MODULES(POLKIT, polkit >= 0.95 polkit-gobject-1)
|
||||
AC_DEFINE(WITH_POLKIT, 1, [Define if you want to use PolicyKit])
|
||||
AC_SUBST(POLKIT_CFLAGS)
|
||||
AC_SUBST(POLKIT_LIBS)
|
||||
;;
|
||||
*)
|
||||
with_polkit=no
|
||||
;;
|
||||
esac
|
||||
|
||||
# PPPD
|
||||
AC_CHECK_HEADERS(pppd/pppd.h, have_pppd_headers="yes", have_pppd_headers="no")
|
||||
AM_CONDITIONAL(HAVE_PPPD_H, test "x$have_pppd_headers" = "xyes")
|
||||
@@ -116,4 +132,6 @@ echo Building documentation: ${with_docs}
|
||||
echo
|
||||
echo Building PPP-enabled tests: ${have_pppd_headers}
|
||||
echo
|
||||
echo Building with PolicyKit support: ${with_polkit}
|
||||
echo
|
||||
|
||||
|
@@ -5,4 +5,5 @@ VOID:UINT,BOOLEAN
|
||||
VOID:UINT,UINT
|
||||
VOID:UINT,UINT,UINT
|
||||
VOID:STRING,BOXED
|
||||
VOID:POINTER,UINT
|
||||
|
||||
|
@@ -3,12 +3,137 @@
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<policy context="default">
|
||||
<allow send_destination="org.freedesktop.ModemManager"/>
|
||||
<deny send_destination="org.freedesktop.ModemManager"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.DBus.Introspectable"/>
|
||||
|
||||
<!-- Methods listed here are explicitly allowed or PolicyKit protected.
|
||||
The rest are restricted to root for security.
|
||||
-->
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem"
|
||||
send_member="GetInfo"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Cdma"
|
||||
send_member="GetSignalQuality"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Cdma"
|
||||
send_member="GetServingSystem"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Cdma"
|
||||
send_member="GetRegistrationState"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Cdma"
|
||||
send_member="GetEsn"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Network"
|
||||
send_member="GetSignalQuality"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Network"
|
||||
send_member="GetBand"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Network"
|
||||
send_member="GetNetworkMode"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Network"
|
||||
send_member="GetRegistrationInfo"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Network"
|
||||
send_member="Scan"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Card"
|
||||
send_member="GetImei"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Card"
|
||||
send_member="GetImsi"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Card"
|
||||
send_member="SendPuk"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Card"
|
||||
send_member="SendPin"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Card"
|
||||
send_member="EnablePin"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Card"
|
||||
send_member="ChangePin"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Contacts"
|
||||
send_member="Add"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Contacts"
|
||||
send_member="Delete"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Contacts"
|
||||
send_member="Get"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Contacts"
|
||||
send_member="List"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Contacts"
|
||||
send_member="Find"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.Contacts"
|
||||
send_member="GetCount"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||
send_member="Delete"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||
send_member="Get"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||
send_member="List"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||
send_member="Save"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||
send_member="Send"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||
send_member="SendFromStorage"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.ModemManager"
|
||||
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||
send_member="SetIndication"/>
|
||||
</policy>
|
||||
|
||||
<policy user="root">
|
||||
<allow own="org.freedesktop.ModemManager"/>
|
||||
<allow send_destination="org.freedesktop.ModemManager"/>
|
||||
</policy>
|
||||
|
||||
<limit name="max_replies_per_connection">512</limit>
|
||||
</busconfig>
|
||||
|
||||
|
@@ -19,12 +19,20 @@ modem_manager_CPPFLAGS = \
|
||||
-I${top_builddir}/marshallers \
|
||||
-DPLUGINDIR=\"$(pkglibdir)\"
|
||||
|
||||
if WITH_POLKIT
|
||||
modem_manager_CPPFLAGS += $(POLKIT_CFLAGS)
|
||||
endif
|
||||
|
||||
modem_manager_LDADD = \
|
||||
$(MM_LIBS) \
|
||||
$(GUDEV_LIBS) \
|
||||
$(top_builddir)/marshallers/libmarshallers.la \
|
||||
$(builddir)/libmodem-helpers.la
|
||||
|
||||
if WITH_POLKIT
|
||||
modem_manager_LDADD += $(POLKIT_LIBS)
|
||||
endif
|
||||
|
||||
modem_manager_SOURCES = \
|
||||
main.c \
|
||||
mm-callback-info.c \
|
||||
@@ -63,7 +71,16 @@ modem_manager_SOURCES = \
|
||||
mm-plugin-base.c \
|
||||
mm-plugin-base.h \
|
||||
mm-properties-changed-signal.c \
|
||||
mm-properties-changed-signal.h
|
||||
mm-properties-changed-signal.h \
|
||||
mm-auth-provider.h \
|
||||
mm-auth-provider.c \
|
||||
mm-auth-provider-factory.c
|
||||
|
||||
if WITH_POLKIT
|
||||
modem_manager_SOURCES += \
|
||||
mm-auth-provider-polkit.c \
|
||||
mm-auth-provider-polkit.h
|
||||
endif
|
||||
|
||||
mm-manager-glue.h: $(top_srcdir)/introspection/mm-manager.xml
|
||||
dbus-binding-tool --prefix=mm_manager --mode=glib-server --output=$@ $<
|
||||
|
45
src/mm-auth-provider-factory.c
Normal file
45
src/mm-auth-provider-factory.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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:
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "mm-auth-provider.h"
|
||||
|
||||
GObject *mm_auth_provider_new (void);
|
||||
|
||||
#ifdef WITH_POLKIT
|
||||
#define IN_AUTH_PROVIDER_FACTORY_C
|
||||
#include "mm-auth-provider-polkit.h"
|
||||
#undef IN_AUTH_PROVIDER_FACTORY_C
|
||||
#endif
|
||||
|
||||
MMAuthProvider *
|
||||
mm_auth_provider_get (void)
|
||||
{
|
||||
static MMAuthProvider *singleton;
|
||||
|
||||
if (!singleton) {
|
||||
#if WITH_POLKIT
|
||||
singleton = (MMAuthProvider *) mm_auth_provider_polkit_new ();
|
||||
#else
|
||||
singleton = (MMAuthProvider *) mm_auth_provider_new ();
|
||||
#endif
|
||||
}
|
||||
|
||||
g_assert (singleton);
|
||||
return singleton;
|
||||
}
|
||||
|
405
src/mm-auth-provider.c
Normal file
405
src/mm-auth-provider.c
Normal file
@@ -0,0 +1,405 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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:
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mm-marshal.h"
|
||||
#include "mm-auth-provider.h"
|
||||
|
||||
GObject *mm_auth_provider_new (void);
|
||||
|
||||
G_DEFINE_TYPE (MMAuthProvider, mm_auth_provider, G_TYPE_OBJECT)
|
||||
|
||||
#define MM_AUTH_PROVIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_AUTH_PROVIDER, MMAuthProviderPrivate))
|
||||
|
||||
typedef struct {
|
||||
GHashTable *requests;
|
||||
guint process_id;
|
||||
} MMAuthProviderPrivate;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
enum {
|
||||
REQUEST_ADDED,
|
||||
REQUEST_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
GObject *
|
||||
mm_auth_provider_new (void)
|
||||
{
|
||||
return g_object_new (MM_TYPE_AUTH_PROVIDER, NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct MMAuthRequest {
|
||||
guint32 refcount;
|
||||
guint32 id;
|
||||
char *auth;
|
||||
GObject *instance;
|
||||
|
||||
MMAuthResult result;
|
||||
|
||||
MMAuthRequestCb callback;
|
||||
gpointer callback_data;
|
||||
GDestroyNotify notify;
|
||||
};
|
||||
|
||||
static MMAuthRequest *
|
||||
mm_auth_request_new (const char *authorization,
|
||||
GObject *instance,
|
||||
MMAuthRequestCb callback,
|
||||
gpointer callback_data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
static guint32 id = 1;
|
||||
MMAuthRequest *req;
|
||||
|
||||
g_return_val_if_fail (authorization != NULL, NULL);
|
||||
g_return_val_if_fail (callback != NULL, NULL);
|
||||
|
||||
req = g_malloc0 (sizeof (MMAuthRequest));
|
||||
req->id = id++;
|
||||
req->refcount = 1;
|
||||
req->auth = g_strdup (authorization);
|
||||
req->instance = instance;
|
||||
req->callback = callback;
|
||||
req->callback_data = callback_data;
|
||||
req->notify = notify;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
MMAuthRequest *
|
||||
mm_auth_request_ref (MMAuthRequest *req)
|
||||
{
|
||||
g_return_val_if_fail (req != NULL, NULL);
|
||||
g_return_val_if_fail (req->refcount > 0, NULL);
|
||||
|
||||
req->refcount++;
|
||||
return req;
|
||||
}
|
||||
|
||||
void
|
||||
mm_auth_request_unref (MMAuthRequest *req)
|
||||
{
|
||||
g_return_if_fail (req != NULL);
|
||||
g_return_if_fail (req->refcount > 0);
|
||||
|
||||
req->refcount--;
|
||||
if (req->refcount == 0) {
|
||||
g_free (req->auth);
|
||||
memset (req, 0, sizeof (MMAuthRequest));
|
||||
g_free (req);
|
||||
}
|
||||
}
|
||||
|
||||
guint32
|
||||
mm_auth_request_get_id (MMAuthRequest *req)
|
||||
{
|
||||
g_return_val_if_fail (req != NULL, 0);
|
||||
g_return_val_if_fail (req->refcount > 0, 0);
|
||||
|
||||
return req->id;
|
||||
}
|
||||
|
||||
const char *
|
||||
mm_auth_request_get_authorization (MMAuthRequest *req)
|
||||
{
|
||||
g_return_val_if_fail (req != NULL, 0);
|
||||
g_return_val_if_fail (req->refcount > 0, 0);
|
||||
|
||||
return req->auth;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
MMAuthRequest *
|
||||
mm_auth_provider_get_request (MMAuthProvider *provider, guint32 reqid)
|
||||
{
|
||||
MMAuthProviderPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (provider != NULL, NULL);
|
||||
g_return_val_if_fail (MM_IS_AUTH_PROVIDER (provider), NULL);
|
||||
g_return_val_if_fail (reqid > 0, NULL);
|
||||
|
||||
priv = MM_AUTH_PROVIDER_GET_PRIVATE (provider);
|
||||
return (MMAuthRequest *) g_hash_table_lookup (priv->requests, GUINT_TO_POINTER (reqid));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_complete_requests (gpointer user_data)
|
||||
{
|
||||
MMAuthProvider *self = MM_AUTH_PROVIDER (user_data);
|
||||
MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self);
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
GSList *remove = NULL;
|
||||
MMAuthRequest *req;
|
||||
|
||||
priv->process_id = 0;
|
||||
|
||||
/* Call finished request's callbacks */
|
||||
g_hash_table_iter_init (&iter, priv->requests);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value)) {
|
||||
req = (MMAuthRequest *) value;
|
||||
if (req->result != MM_AUTH_RESULT_UNKNOWN) {
|
||||
req->callback (req->instance, req->id, req->result, req->callback_data);
|
||||
|
||||
/* Let the caller clean up the request's callback data */
|
||||
if (req->notify)
|
||||
req->notify (req->callback_data);
|
||||
|
||||
remove = g_slist_prepend (remove, req);
|
||||
}
|
||||
}
|
||||
|
||||
/* And remove those requests from our pending request list */
|
||||
while (remove) {
|
||||
req = (MMAuthRequest *) remove->data;
|
||||
g_signal_emit (self, signals[REQUEST_REMOVED], 0, req->instance, req->id);
|
||||
g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->id));
|
||||
remove = g_slist_remove (remove, req);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
mm_auth_provider_finish_request (MMAuthProvider *provider,
|
||||
guint32 reqid,
|
||||
MMAuthResult result)
|
||||
{
|
||||
MMAuthProviderPrivate *priv;
|
||||
MMAuthRequest *req;
|
||||
|
||||
g_return_if_fail (provider != NULL);
|
||||
g_return_if_fail (MM_IS_AUTH_PROVIDER (provider));
|
||||
g_return_if_fail (reqid > 0);
|
||||
g_return_if_fail (result != MM_AUTH_RESULT_UNKNOWN);
|
||||
|
||||
priv = MM_AUTH_PROVIDER_GET_PRIVATE (provider);
|
||||
req = (MMAuthRequest *) g_hash_table_lookup (priv->requests, GUINT_TO_POINTER (reqid));
|
||||
g_return_if_fail (req != NULL);
|
||||
|
||||
req->result = result;
|
||||
|
||||
if (priv->process_id == 0)
|
||||
priv->process_id = g_idle_add (process_complete_requests, provider);
|
||||
}
|
||||
|
||||
void
|
||||
mm_auth_provider_cancel_request (MMAuthProvider *provider, guint32 reqid)
|
||||
{
|
||||
MMAuthProviderPrivate *priv;
|
||||
MMAuthRequest *req;
|
||||
|
||||
g_return_if_fail (provider != NULL);
|
||||
g_return_if_fail (MM_IS_AUTH_PROVIDER (provider));
|
||||
g_return_if_fail (reqid > 0);
|
||||
|
||||
priv = MM_AUTH_PROVIDER_GET_PRIVATE (provider);
|
||||
|
||||
req = (MMAuthRequest *) g_hash_table_lookup (priv->requests, GUINT_TO_POINTER (reqid));
|
||||
g_return_if_fail (req != NULL);
|
||||
|
||||
/* Let the caller clean up the request's callback data */
|
||||
if (req->notify)
|
||||
req->notify (req->callback_data);
|
||||
|
||||
/* We don't signal removal here as it's assumed the caller
|
||||
* handles that itself instead of by the signal.
|
||||
*/
|
||||
g_hash_table_remove (priv->requests, GUINT_TO_POINTER (reqid));
|
||||
}
|
||||
|
||||
const char *
|
||||
mm_auth_provider_get_authorization_for_id (MMAuthProvider *provider, guint32 reqid)
|
||||
{
|
||||
MMAuthProviderPrivate *priv;
|
||||
MMAuthRequest *req;
|
||||
|
||||
g_return_val_if_fail (provider != NULL, NULL);
|
||||
g_return_val_if_fail (MM_IS_AUTH_PROVIDER (provider), NULL);
|
||||
g_return_val_if_fail (reqid > 0, NULL);
|
||||
|
||||
priv = MM_AUTH_PROVIDER_GET_PRIVATE (provider);
|
||||
req = (MMAuthRequest *) g_hash_table_lookup (priv->requests, GUINT_TO_POINTER (reqid));
|
||||
g_return_val_if_fail (req != NULL, NULL);
|
||||
|
||||
return mm_auth_request_get_authorization (req);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
real_request_auth (MMAuthProvider *provider,
|
||||
MMAuthRequest *req,
|
||||
GError **error)
|
||||
{
|
||||
/* This class provides null authentication; all requests pass */
|
||||
mm_auth_provider_finish_request (provider,
|
||||
mm_auth_request_get_id (req),
|
||||
MM_AUTH_RESULT_AUTHORIZED);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
guint32
|
||||
mm_auth_provider_request_auth (MMAuthProvider *provider,
|
||||
const char *authorization,
|
||||
GObject *instance,
|
||||
MMAuthRequestCb callback,
|
||||
gpointer callback_data,
|
||||
GDestroyNotify notify,
|
||||
GError **error)
|
||||
{
|
||||
MMAuthProviderPrivate *priv;
|
||||
MMAuthRequest *req;
|
||||
|
||||
g_return_val_if_fail (provider != NULL, 0);
|
||||
g_return_val_if_fail (MM_IS_AUTH_PROVIDER (provider), 0);
|
||||
g_return_val_if_fail (authorization != NULL, 0);
|
||||
g_return_val_if_fail (callback != NULL, 0);
|
||||
|
||||
priv = MM_AUTH_PROVIDER_GET_PRIVATE (provider);
|
||||
|
||||
req = mm_auth_request_new (authorization, instance, callback, callback_data, notify);
|
||||
g_assert (req);
|
||||
|
||||
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->id), req);
|
||||
g_signal_emit (provider, signals[REQUEST_ADDED], 0, instance, req->id);
|
||||
|
||||
if (!MM_AUTH_PROVIDER_GET_CLASS (provider)->request_auth (provider, req, error)) {
|
||||
/* Error */
|
||||
g_signal_emit (provider, signals[REQUEST_REMOVED], 0, instance, req->id);
|
||||
|
||||
/* Let the caller clean up the request's callback data */
|
||||
if (req->notify)
|
||||
req->notify (req->callback_data);
|
||||
|
||||
g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return req->id;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
mm_auth_provider_init (MMAuthProvider *self)
|
||||
{
|
||||
MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self);
|
||||
|
||||
priv->requests = g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) mm_auth_request_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define NULL_PROVIDER "open"
|
||||
|
||||
static void
|
||||
get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, NULL_PROVIDER);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (object);
|
||||
|
||||
if (priv->process_id)
|
||||
g_source_remove (priv->process_id);
|
||||
g_hash_table_destroy (priv->requests);
|
||||
|
||||
G_OBJECT_CLASS (mm_auth_provider_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_auth_provider_class_init (MMAuthProviderClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
mm_auth_provider_parent_class = g_type_class_peek_parent (class);
|
||||
g_type_class_add_private (class, sizeof (MMAuthProviderPrivate));
|
||||
|
||||
/* Virtual methods */
|
||||
object_class->set_property = set_property;
|
||||
object_class->get_property = get_property;
|
||||
object_class->finalize = finalize;
|
||||
class->request_auth = real_request_auth;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property (object_class, PROP_NAME,
|
||||
g_param_spec_string (MM_AUTH_PROVIDER_NAME,
|
||||
"Name",
|
||||
"Provider name",
|
||||
NULL_PROVIDER,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
/* Signals */
|
||||
signals[REQUEST_ADDED] =
|
||||
g_signal_new ("request-added",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
mm_marshal_VOID__POINTER_UINT,
|
||||
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
|
||||
|
||||
signals[REQUEST_REMOVED] =
|
||||
g_signal_new ("request-removed",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
mm_marshal_VOID__POINTER_UINT,
|
||||
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
|
||||
}
|
||||
|
99
src/mm-auth-provider.h
Normal file
99
src/mm-auth-provider.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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:
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef MM_AUTH_PROVIDER_H
|
||||
#define MM_AUTH_PROVIDER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
/* Authorizations */
|
||||
#define MM_AUTHORIZATION_DEVICE "org.freedesktop.ModemManager.Device"
|
||||
#define MM_AUTHORIZATION_CONTACTS "org.freedesktop.ModemManager.Contacts"
|
||||
#define MM_AUTHORIZATION_SMS "org.freedesktop.ModemManager.SMS"
|
||||
/******************/
|
||||
|
||||
|
||||
#define MM_TYPE_AUTH_PROVIDER (mm_auth_provider_get_type ())
|
||||
#define MM_AUTH_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_AUTH_PROVIDER, MMAuthProvider))
|
||||
#define MM_AUTH_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_AUTH_PROVIDER, MMAuthProviderClass))
|
||||
#define MM_IS_AUTH_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_AUTH_PROVIDER))
|
||||
#define MM_IS_AUTH_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_AUTH_PROVIDER))
|
||||
#define MM_AUTH_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_AUTH_PROVIDER, MMAuthProviderClass))
|
||||
|
||||
#define MM_AUTH_PROVIDER_NAME "name"
|
||||
|
||||
typedef enum MMAuthResult {
|
||||
MM_AUTH_RESULT_UNKNOWN = 0,
|
||||
MM_AUTH_RESULT_INTERNAL_FAILURE,
|
||||
MM_AUTH_RESULT_NOT_AUTHORIZED,
|
||||
MM_AUTH_RESULT_CHALLENGE,
|
||||
MM_AUTH_RESULT_AUTHORIZED
|
||||
} MMAuthResult;
|
||||
|
||||
typedef struct MMAuthRequest MMAuthRequest;
|
||||
typedef struct _MMAuthProvider MMAuthProvider;
|
||||
typedef struct _MMAuthProviderClass MMAuthProviderClass;
|
||||
|
||||
typedef void (*MMAuthRequestCb) (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data);
|
||||
|
||||
struct _MMAuthProvider {
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _MMAuthProviderClass {
|
||||
GObjectClass parent;
|
||||
|
||||
gboolean (*request_auth) (MMAuthProvider *provider,
|
||||
MMAuthRequest *req,
|
||||
GError **error);
|
||||
};
|
||||
|
||||
GType mm_auth_provider_get_type (void);
|
||||
|
||||
guint32 mm_auth_provider_request_auth (MMAuthProvider *provider,
|
||||
const char *authorization,
|
||||
GObject *instance,
|
||||
MMAuthRequestCb callback,
|
||||
gpointer callback_data,
|
||||
GDestroyNotify notify,
|
||||
GError **error);
|
||||
|
||||
/* To get an auth provider instance, implemented in mm-auth-provider-factory.c */
|
||||
MMAuthProvider *mm_auth_provider_get (void);
|
||||
|
||||
/* For subclasses only */
|
||||
MMAuthRequest *mm_auth_provider_get_request (MMAuthProvider *provider, guint32 reqid);
|
||||
MMAuthRequest *mm_auth_request_ref (MMAuthRequest *req);
|
||||
void mm_auth_request_unref (MMAuthRequest *req);
|
||||
guint32 mm_auth_request_get_id (MMAuthRequest *req);
|
||||
const char * mm_auth_request_get_authorization (MMAuthRequest *req);
|
||||
|
||||
/* Normal API */
|
||||
|
||||
/* schedules the request's completion */
|
||||
void mm_auth_provider_finish_request (MMAuthProvider *provider,
|
||||
guint32 reqid,
|
||||
MMAuthResult result);
|
||||
|
||||
void mm_auth_provider_cancel_request (MMAuthProvider *provider, guint32 reqid);
|
||||
|
||||
const char *mm_auth_provider_get_authorization_for_id (MMAuthProvider *provider,
|
||||
guint32 reqid);
|
||||
|
||||
#endif /* MM_AUTH_PROVIDER_H */
|
||||
|
@@ -76,6 +76,7 @@ mm_modem_error_get_type (void)
|
||||
ENUM_ENTRY (MM_MODEM_ERROR_DISCONNECTED, "Disconnected"),
|
||||
ENUM_ENTRY (MM_MODEM_ERROR_OPERATION_IN_PROGRESS, "OperationInProgress"),
|
||||
ENUM_ENTRY (MM_MODEM_ERROR_REMOVED, "Removed"),
|
||||
ENUM_ENTRY (MM_MODEM_ERROR_AUTHORIZATION_REQUIRED, "AuthorizationRequired"),
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@@ -39,7 +39,8 @@ enum {
|
||||
MM_MODEM_ERROR_CONNECTED = 2,
|
||||
MM_MODEM_ERROR_DISCONNECTED = 3,
|
||||
MM_MODEM_ERROR_OPERATION_IN_PROGRESS = 4,
|
||||
MM_MODEM_ERROR_REMOVED = 5
|
||||
MM_MODEM_ERROR_REMOVED = 5,
|
||||
MM_MODEM_ERROR_AUTHORIZATION_REQUIRED = 6
|
||||
};
|
||||
|
||||
#define MM_MODEM_ERROR (mm_modem_error_quark ())
|
||||
|
@@ -44,6 +44,11 @@ typedef struct {
|
||||
gboolean valid;
|
||||
MMModemState state;
|
||||
|
||||
MMAuthProvider *authp;
|
||||
guint authp_added_id;
|
||||
guint authp_removed_id;
|
||||
GSList *auth_reqs;
|
||||
|
||||
GHashTable *ports;
|
||||
} MMModemBasePrivate;
|
||||
|
||||
@@ -213,11 +218,104 @@ mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_require
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
modem_auth_request (MMModem *modem,
|
||||
const char *authorization,
|
||||
MMAuthRequestCb callback,
|
||||
gpointer callback_data,
|
||||
GDestroyNotify notify,
|
||||
GError **error)
|
||||
{
|
||||
MMModemBase *self = MM_MODEM_BASE (modem);
|
||||
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||
|
||||
g_assert (priv->authp);
|
||||
return !!mm_auth_provider_request_auth (priv->authp,
|
||||
authorization,
|
||||
G_OBJECT (self),
|
||||
callback,
|
||||
callback_data,
|
||||
notify,
|
||||
error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
modem_auth_finish (MMModem *modem,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
GError **error)
|
||||
{
|
||||
MMModemBase *self = MM_MODEM_BASE (modem);
|
||||
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||
|
||||
if (result != MM_AUTH_RESULT_AUTHORIZED) {
|
||||
const char *auth;
|
||||
|
||||
auth = mm_auth_provider_get_authorization_for_id (priv->authp, reqid);
|
||||
g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_AUTHORIZATION_REQUIRED,
|
||||
"This request requires the '%s' authorization",
|
||||
auth ? auth : "(unknown)");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
authp_request_added (MMAuthProvider *provider,
|
||||
gpointer parent,
|
||||
guint32 reqid,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemBase *self;
|
||||
MMModemBasePrivate *priv;
|
||||
|
||||
/* Make sure it's our auth request */
|
||||
if (parent != user_data)
|
||||
return;
|
||||
|
||||
self = MM_MODEM_BASE (user_data);
|
||||
priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||
|
||||
/* Add this request to our table so we can cancel it when we die */
|
||||
priv->auth_reqs = g_slist_prepend (priv->auth_reqs, GUINT_TO_POINTER (reqid));
|
||||
}
|
||||
|
||||
static void
|
||||
authp_request_removed (MMAuthProvider *provider,
|
||||
gpointer parent,
|
||||
guint32 reqid,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemBase *self;
|
||||
MMModemBasePrivate *priv;
|
||||
|
||||
/* Make sure it's our auth request */
|
||||
if (parent != user_data)
|
||||
return;
|
||||
|
||||
self = MM_MODEM_BASE (user_data);
|
||||
priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||
|
||||
/* Request finished; remove cleanly */
|
||||
priv->auth_reqs = g_slist_remove (priv->auth_reqs, GUINT_TO_POINTER (reqid));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
mm_modem_base_init (MMModemBase *self)
|
||||
{
|
||||
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||
|
||||
priv->authp = mm_auth_provider_get ();
|
||||
priv->authp_added_id = g_signal_connect (priv->authp, "request-added",
|
||||
(GCallback) authp_request_added,
|
||||
self);
|
||||
priv->authp_removed_id = g_signal_connect (priv->authp, "request-removed",
|
||||
(GCallback) authp_request_removed,
|
||||
self);
|
||||
|
||||
priv->ports = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
|
||||
mm_properties_changed_signal_register_property (G_OBJECT (self),
|
||||
@@ -228,6 +326,8 @@ mm_modem_base_init (MMModemBase *self)
|
||||
static void
|
||||
modem_init (MMModem *modem_class)
|
||||
{
|
||||
modem_class->auth_request = modem_auth_request;
|
||||
modem_class->auth_finish = modem_auth_finish;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -325,6 +425,14 @@ finalize (GObject *object)
|
||||
{
|
||||
MMModemBase *self = MM_MODEM_BASE (object);
|
||||
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
|
||||
g_signal_handler_disconnect (priv->authp, priv->authp_added_id);
|
||||
g_signal_handler_disconnect (priv->authp, priv->authp_removed_id);
|
||||
|
||||
for (iter = priv->auth_reqs; iter; iter = g_slist_next (iter))
|
||||
mm_auth_provider_cancel_request (priv->authp, GPOINTER_TO_UINT (iter->data));
|
||||
g_slist_free (priv->auth_reqs);
|
||||
|
||||
g_hash_table_destroy (priv->ports);
|
||||
g_free (priv->driver);
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "mm-errors.h"
|
||||
#include "mm-callback-info.h"
|
||||
#include "mm-marshal.h"
|
||||
#include "mm-auth-provider.h"
|
||||
|
||||
static void impl_modem_cdma_get_signal_quality (MMModemCdma *modem, DBusGMethodInvocation *context);
|
||||
static void impl_modem_cdma_get_esn (MMModemCdma *modem, DBusGMethodInvocation *context);
|
||||
@@ -188,10 +189,38 @@ mm_modem_cdma_get_esn (MMModemCdma *self,
|
||||
}
|
||||
|
||||
static void
|
||||
impl_modem_cdma_get_esn (MMModemCdma *modem,
|
||||
DBusGMethodInvocation *context)
|
||||
esn_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
mm_modem_cdma_get_esn (modem, str_call_done, context);
|
||||
MMModemCdma *self = MM_MODEM_CDMA (instance);
|
||||
DBusGMethodInvocation *context = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise get the ESN */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_cdma_get_esn (self, str_call_done, context);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_modem_cdma_get_esn (MMModemCdma *self, DBusGMethodInvocation *context)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
/* Make sure the caller is authorized to get the ESN */
|
||||
if (!mm_modem_auth_request (MM_MODEM (self),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
esn_auth_cb,
|
||||
context,
|
||||
NULL,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mm-modem-gsm-card.h"
|
||||
#include "mm-errors.h"
|
||||
@@ -201,26 +202,178 @@ mm_modem_gsm_card_change_pin (MMModemGsmCard *self,
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
impl_gsm_modem_get_imei (MMModemGsmCard *modem,
|
||||
DBusGMethodInvocation *context)
|
||||
imei_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
mm_modem_gsm_card_get_imei (modem, str_call_done, context);
|
||||
MMModemGsmCard *self = MM_MODEM_GSM_CARD (instance);
|
||||
DBusGMethodInvocation *context = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise get the IMEI */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_gsm_card_get_imei (self, str_call_done, context);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_gsm_modem_get_imsi (MMModemGsmCard *modem,
|
||||
DBusGMethodInvocation *context)
|
||||
impl_gsm_modem_get_imei (MMModemGsmCard *modem, DBusGMethodInvocation *context)
|
||||
{
|
||||
mm_modem_gsm_card_get_imsi (modem, str_call_done, context);
|
||||
GError *error = NULL;
|
||||
|
||||
/* Make sure the caller is authorized to get the IMEI */
|
||||
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
imei_auth_cb,
|
||||
context,
|
||||
NULL,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
imsi_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemGsmCard *self = MM_MODEM_GSM_CARD (instance);
|
||||
DBusGMethodInvocation *context = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise get the IMSI */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_gsm_card_get_imsi (self, str_call_done, context);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_gsm_modem_send_puk (MMModemGsmCard *modem,
|
||||
const char *puk,
|
||||
const char *pin,
|
||||
DBusGMethodInvocation *context)
|
||||
impl_gsm_modem_get_imsi (MMModemGsmCard *modem, DBusGMethodInvocation *context)
|
||||
{
|
||||
mm_modem_gsm_card_send_puk (modem, puk, pin, async_call_done, context);
|
||||
GError *error = NULL;
|
||||
|
||||
/* Make sure the caller is authorized to get the IMSI */
|
||||
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
imsi_auth_cb,
|
||||
context,
|
||||
NULL,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
char *puk;
|
||||
char *pin;
|
||||
char *pin2;
|
||||
gboolean enabled;
|
||||
DBusGMethodInvocation *context;
|
||||
} SendPinPukInfo;
|
||||
|
||||
static void
|
||||
send_pin_puk_info_destroy (gpointer data)
|
||||
{
|
||||
SendPinPukInfo *info = data;
|
||||
|
||||
g_free (info->puk);
|
||||
g_free (info->pin);
|
||||
g_free (info->pin2);
|
||||
memset (info, 0, sizeof (SendPinPukInfo));
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static SendPinPukInfo *
|
||||
send_pin_puk_info_new (const char *puk,
|
||||
const char *pin,
|
||||
const char *pin2,
|
||||
gboolean enabled,
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
SendPinPukInfo *info;
|
||||
|
||||
info = g_malloc0 (sizeof (SendPinPukInfo));
|
||||
info->puk = g_strdup (puk);
|
||||
info->pin = g_strdup (pin);
|
||||
info->pin2 = g_strdup (pin2);
|
||||
info->enabled = enabled;
|
||||
info->context = context;
|
||||
return info;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
send_puk_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemGsmCard *self = MM_MODEM_GSM_CARD (instance);
|
||||
SendPinPukInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise send the PUK */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (info->context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_gsm_card_send_puk (self, info->puk, info->pin, async_call_done, info->context);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_gsm_modem_send_puk (MMModemGsmCard *modem,
|
||||
const char *puk,
|
||||
const char *pin,
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
GError *error = NULL;
|
||||
SendPinPukInfo *info;
|
||||
|
||||
info = send_pin_puk_info_new (puk, pin, NULL, FALSE, context);
|
||||
|
||||
/* Make sure the caller is authorized to send the PUK */
|
||||
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
send_puk_auth_cb,
|
||||
info,
|
||||
send_pin_puk_info_destroy,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
send_pin_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemGsmCard *self = MM_MODEM_GSM_CARD (instance);
|
||||
SendPinPukInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise unlock the modem */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (info->context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_gsm_card_send_pin (self, info->pin, async_call_done, info->context);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -228,7 +381,41 @@ impl_gsm_modem_send_pin (MMModemGsmCard *modem,
|
||||
const char *pin,
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
mm_modem_gsm_card_send_pin (modem, pin, async_call_done, context);
|
||||
GError *error = NULL;
|
||||
SendPinPukInfo *info;
|
||||
|
||||
info = send_pin_puk_info_new (NULL, pin, NULL, FALSE, context);
|
||||
|
||||
/* Make sure the caller is authorized to unlock the modem */
|
||||
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
send_pin_auth_cb,
|
||||
info,
|
||||
send_pin_puk_info_destroy,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
enable_pin_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemGsmCard *self = MM_MODEM_GSM_CARD (instance);
|
||||
SendPinPukInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise enable the PIN */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (info->context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_gsm_card_enable_pin (self, info->pin, info->enabled, async_call_done, info->context);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -237,7 +424,41 @@ impl_gsm_modem_enable_pin (MMModemGsmCard *modem,
|
||||
gboolean enabled,
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
mm_modem_gsm_card_enable_pin (modem, pin, enabled, async_call_done, context);
|
||||
GError *error = NULL;
|
||||
SendPinPukInfo *info;
|
||||
|
||||
info = send_pin_puk_info_new (NULL, pin, NULL, enabled, context);
|
||||
|
||||
/* Make sure the caller is authorized to enable a PIN */
|
||||
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
enable_pin_auth_cb,
|
||||
info,
|
||||
send_pin_puk_info_destroy,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
change_pin_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemGsmCard *self = MM_MODEM_GSM_CARD (instance);
|
||||
SendPinPukInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise change the PIN */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (info->context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_gsm_card_change_pin (self, info->pin, info->pin2, async_call_done, info->context);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -246,7 +467,21 @@ impl_gsm_modem_change_pin (MMModemGsmCard *modem,
|
||||
const char *new_pin,
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
mm_modem_gsm_card_change_pin (modem, old_pin, new_pin, async_call_done, context);
|
||||
GError *error = NULL;
|
||||
SendPinPukInfo *info;
|
||||
|
||||
info = send_pin_puk_info_new (NULL, old_pin, new_pin, FALSE, context);
|
||||
|
||||
/* Make sure the caller is authorized to change the PIN */
|
||||
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
change_pin_auth_cb,
|
||||
info,
|
||||
send_pin_puk_info_destroy,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -305,6 +540,7 @@ mm_modem_gsm_card_get_type (void)
|
||||
&card_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (card_type, G_TYPE_OBJECT);
|
||||
g_type_interface_add_prerequisite (card_type, MM_TYPE_MODEM);
|
||||
dbus_g_object_type_install_info (card_type, &dbus_glib_mm_modem_gsm_card_object_info);
|
||||
}
|
||||
|
||||
|
@@ -397,11 +397,40 @@ impl_gsm_modem_register (MMModemGsmNetwork *modem,
|
||||
mm_modem_gsm_network_register (modem, id, async_call_done, context);
|
||||
}
|
||||
|
||||
static void
|
||||
scan_auth_cb (GObject *instance,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMModemGsmNetwork *self = MM_MODEM_GSM_NETWORK (instance);
|
||||
DBusGMethodInvocation *context = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Return any authorization error, otherwise get the IMEI */
|
||||
if (!mm_modem_auth_finish (MM_MODEM (self), reqid, result, &error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
} else
|
||||
mm_modem_gsm_network_scan (self, scan_call_done, context);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_gsm_modem_scan (MMModemGsmNetwork *modem,
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
mm_modem_gsm_network_scan (modem, scan_call_done, context);
|
||||
GError *error = NULL;
|
||||
|
||||
/* Make sure the caller is authorized to request a scan */
|
||||
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||
MM_AUTHORIZATION_DEVICE,
|
||||
scan_auth_cb,
|
||||
context,
|
||||
NULL,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -562,6 +591,7 @@ mm_modem_gsm_network_get_type (void)
|
||||
&network_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (network_type, G_TYPE_OBJECT);
|
||||
g_type_interface_add_prerequisite (network_type, MM_TYPE_MODEM);
|
||||
dbus_g_object_type_install_info (network_type, &dbus_glib_mm_modem_gsm_network_object_info);
|
||||
}
|
||||
|
||||
|
@@ -608,6 +608,52 @@ mm_modem_set_state (MMModem *self,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
mm_modem_auth_request (MMModem *self,
|
||||
const char *authorization,
|
||||
MMAuthRequestCb callback,
|
||||
gpointer callback_data,
|
||||
GDestroyNotify notify,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
|
||||
g_return_val_if_fail (authorization != NULL, FALSE);
|
||||
g_return_val_if_fail (callback != NULL, FALSE);
|
||||
|
||||
g_return_val_if_fail (MM_MODEM_GET_INTERFACE (self)->auth_request, FALSE);
|
||||
return MM_MODEM_GET_INTERFACE (self)->auth_request (self,
|
||||
authorization,
|
||||
callback,
|
||||
callback_data,
|
||||
notify,
|
||||
error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_modem_auth_finish (MMModem *self,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
|
||||
g_return_val_if_fail (reqid > 0, FALSE);
|
||||
|
||||
g_return_val_if_fail (MM_MODEM_GET_INTERFACE (self)->auth_finish, FALSE);
|
||||
success = MM_MODEM_GET_INTERFACE (self)->auth_finish (self, reqid, result, error);
|
||||
|
||||
/* If the request failed, the implementor *should* return an error */
|
||||
if (!success && error)
|
||||
g_warn_if_fail (*error != NULL);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
mm_modem_init (gpointer g_iface)
|
||||
{
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "mm-port.h"
|
||||
#include "mm-auth-provider.h"
|
||||
|
||||
typedef enum {
|
||||
MM_MODEM_STATE_UNKNOWN = 0,
|
||||
@@ -156,6 +157,21 @@ struct _MMModem {
|
||||
MMModemInfoFn callback,
|
||||
gpointer user_data);
|
||||
|
||||
/* Normally implemented by the modem base class; plugins should
|
||||
* never need to implement this.
|
||||
*/
|
||||
gboolean (*auth_request) (MMModem *self,
|
||||
const char *authorization,
|
||||
MMAuthRequestCb callback,
|
||||
gpointer callback_data,
|
||||
GDestroyNotify notify,
|
||||
GError **error);
|
||||
|
||||
gboolean (*auth_finish) (MMModem *self,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
GError **error);
|
||||
|
||||
/* Signals */
|
||||
void (*state_changed) (MMModem *self,
|
||||
MMModemState new_state,
|
||||
@@ -217,5 +233,21 @@ void mm_modem_set_state (MMModem *self,
|
||||
|
||||
GError *mm_modem_check_removed (MMModem *self, const GError *error);
|
||||
|
||||
/* Request authorization to perform an action. Used by D-Bus method
|
||||
* handlers to ensure that the incoming request is authorized to perform
|
||||
* the action it's requesting.
|
||||
*/
|
||||
gboolean mm_modem_auth_request (MMModem *self,
|
||||
const char *authorization,
|
||||
MMAuthRequestCb callback,
|
||||
gpointer callback_data,
|
||||
GDestroyNotify notify,
|
||||
GError **error);
|
||||
|
||||
gboolean mm_modem_auth_finish (MMModem *self,
|
||||
guint32 reqid,
|
||||
MMAuthResult result,
|
||||
GError **error);
|
||||
|
||||
#endif /* MM_MODEM_H */
|
||||
|
||||
|
Reference in New Issue
Block a user