Merge remote branch 'origin/master' into qcdm
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -23,6 +23,7 @@ libtool
|
|||||||
*-glue.h
|
*-glue.h
|
||||||
*.tar.bz2
|
*.tar.bz2
|
||||||
org.freedesktop.ModemManager.service
|
org.freedesktop.ModemManager.service
|
||||||
|
org.freedesktop.ModemManager.conf
|
||||||
ModemManager.pc
|
ModemManager.pc
|
||||||
marshallers/mm-marshal.[ch]
|
marshallers/mm-marshal.[ch]
|
||||||
src/modem-manager
|
src/modem-manager
|
||||||
@@ -30,6 +31,7 @@ docs/spec.html
|
|||||||
callouts/mm-modem-probe
|
callouts/mm-modem-probe
|
||||||
test/lsudev
|
test/lsudev
|
||||||
src/tests/test-modem-helpers
|
src/tests/test-modem-helpers
|
||||||
|
policy/org.freedesktop.modem-manager.policy
|
||||||
|
|
||||||
libqcdm/tests/test-qcdm
|
libqcdm/tests/test-qcdm
|
||||||
|
|
||||||
|
19
Makefile.am
19
Makefile.am
@@ -21,9 +21,23 @@ endif
|
|||||||
|
|
||||||
SUBDIRS = marshallers libqcdm src plugins introspection po policy test
|
SUBDIRS = marshallers libqcdm src plugins introspection po policy test
|
||||||
|
|
||||||
|
if WITH_POLKIT
|
||||||
|
SUBDIRS += policy
|
||||||
|
endif
|
||||||
|
|
||||||
dbusservicedir = $(DBUS_SYS_DIR)
|
dbusservicedir = $(DBUS_SYS_DIR)
|
||||||
dbusservice_DATA = org.freedesktop.ModemManager.conf
|
dbusservice_DATA = org.freedesktop.ModemManager.conf
|
||||||
|
|
||||||
|
dbusservice_file_polkit = org.freedesktop.ModemManager.conf.polkit
|
||||||
|
dbusservice_file_nopolkit = org.freedesktop.ModemManager.conf.nopolkit
|
||||||
|
|
||||||
|
org.freedesktop.ModemManager.conf:
|
||||||
|
if WITH_POLKIT
|
||||||
|
cp -f $(top_srcdir)/$(dbusservice_file_polkit) $(dbusservice_DATA)
|
||||||
|
else
|
||||||
|
cp -f $(top_srcdir)/$(dbusservice_file_nopolkit) $(dbusservice_DATA)
|
||||||
|
endif
|
||||||
|
|
||||||
dbusactivationdir = $(datadir)/dbus-1/system-services
|
dbusactivationdir = $(datadir)/dbus-1/system-services
|
||||||
dbusactivation_in_files = org.freedesktop.ModemManager.service.in
|
dbusactivation_in_files = org.freedesktop.ModemManager.service.in
|
||||||
dbusactivation_DATA = $(dbusactivation_in_files:.service.in=.service)
|
dbusactivation_DATA = $(dbusactivation_in_files:.service.in=.service)
|
||||||
@@ -53,8 +67,9 @@ DISTCLEANFILES = \
|
|||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
doc-generator.xsl \
|
doc-generator.xsl \
|
||||||
$(dbusservice_DATA) \
|
|
||||||
$(dbusactivation_in_files) \
|
$(dbusactivation_in_files) \
|
||||||
$(INTLTOOL_FILES)
|
$(INTLTOOL_FILES) \
|
||||||
|
$(dbusservice_file_polkit) \
|
||||||
|
$(dbusservice_file_nopolkit)
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
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`
|
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
|
||||||
AC_SUBST(GLIB_GENMARSHAL)
|
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-gobject-1 >= 0.95)
|
||||||
|
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
|
# PPPD
|
||||||
AC_CHECK_HEADERS(pppd/pppd.h, have_pppd_headers="yes", have_pppd_headers="no")
|
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")
|
AM_CONDITIONAL(HAVE_PPPD_H, test "x$have_pppd_headers" = "xyes")
|
||||||
@@ -119,4 +135,6 @@ echo Building documentation: ${with_docs}
|
|||||||
echo
|
echo
|
||||||
echo Building PPP-enabled tests: ${have_pppd_headers}
|
echo Building PPP-enabled tests: ${have_pppd_headers}
|
||||||
echo
|
echo
|
||||||
|
echo Building with PolicyKit support: ${with_polkit}
|
||||||
|
echo
|
||||||
|
|
||||||
|
@@ -5,4 +5,5 @@ VOID:UINT,BOOLEAN
|
|||||||
VOID:UINT,UINT
|
VOID:UINT,UINT
|
||||||
VOID:UINT,UINT,UINT
|
VOID:UINT,UINT,UINT
|
||||||
VOID:STRING,BOXED
|
VOID:STRING,BOXED
|
||||||
|
VOID:POINTER,UINT
|
||||||
|
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||||
<busconfig>
|
<busconfig>
|
||||||
|
<!-- This config allows anyone to control ModemManager -->
|
||||||
|
|
||||||
<policy context="default">
|
<policy context="default">
|
||||||
<allow send_destination="org.freedesktop.ModemManager"/>
|
<allow send_destination="org.freedesktop.ModemManager"/>
|
||||||
</policy>
|
</policy>
|
||||||
@@ -12,3 +14,4 @@
|
|||||||
|
|
||||||
<limit name="max_replies_per_connection">512</limit>
|
<limit name="max_replies_per_connection">512</limit>
|
||||||
</busconfig>
|
</busconfig>
|
||||||
|
|
154
org.freedesktop.ModemManager.conf.polkit
Normal file
154
org.freedesktop.ModemManager.conf.polkit
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
<!DOCTYPE busconfig PUBLIC
|
||||||
|
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||||
|
<busconfig>
|
||||||
|
<policy context="default">
|
||||||
|
<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"
|
||||||
|
send_member="EnumerateDevices"/>
|
||||||
|
|
||||||
|
<allow send_destination="org.freedesktop.ModemManager"
|
||||||
|
send_interface="org.freedesktop.DBus.Properties"/>
|
||||||
|
|
||||||
|
<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"/>
|
||||||
|
|
||||||
|
<allow send_destination="org.freedesktop.ModemManager"
|
||||||
|
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||||
|
send_member="GetSmsc"/>
|
||||||
|
|
||||||
|
<allow send_destination="org.freedesktop.ModemManager"
|
||||||
|
send_interface="org.freedesktop.ModemManager.Modem.Gsm.SMS"
|
||||||
|
send_member="SetSmsc"/>
|
||||||
|
</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>
|
||||||
|
|
@@ -20,6 +20,10 @@ modem_manager_CPPFLAGS = \
|
|||||||
-I${top_builddir}/marshallers \
|
-I${top_builddir}/marshallers \
|
||||||
-DPLUGINDIR=\"$(pkglibdir)\"
|
-DPLUGINDIR=\"$(pkglibdir)\"
|
||||||
|
|
||||||
|
if WITH_POLKIT
|
||||||
|
modem_manager_CPPFLAGS += $(POLKIT_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
modem_manager_LDADD = \
|
modem_manager_LDADD = \
|
||||||
$(MM_LIBS) \
|
$(MM_LIBS) \
|
||||||
$(GUDEV_LIBS) \
|
$(GUDEV_LIBS) \
|
||||||
@@ -27,10 +31,30 @@ modem_manager_LDADD = \
|
|||||||
$(top_builddir)/libqcdm/src/libqcdm.la \
|
$(top_builddir)/libqcdm/src/libqcdm.la \
|
||||||
$(builddir)/libmodem-helpers.la
|
$(builddir)/libmodem-helpers.la
|
||||||
|
|
||||||
|
if WITH_POLKIT
|
||||||
|
modem_manager_LDADD += $(POLKIT_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
auth_sources = \
|
||||||
|
mm-auth-request.c \
|
||||||
|
mm-auth-request.h \
|
||||||
|
mm-auth-provider.h \
|
||||||
|
mm-auth-provider.c \
|
||||||
|
mm-auth-provider-factory.c
|
||||||
|
|
||||||
|
if WITH_POLKIT
|
||||||
|
auth_sources += \
|
||||||
|
mm-auth-request-polkit.c \
|
||||||
|
mm-auth-request-polkit.h \
|
||||||
|
mm-auth-provider-polkit.c \
|
||||||
|
mm-auth-provider-polkit.h
|
||||||
|
endif
|
||||||
|
|
||||||
modem_manager_SOURCES = \
|
modem_manager_SOURCES = \
|
||||||
main.c \
|
main.c \
|
||||||
mm-callback-info.c \
|
mm-callback-info.c \
|
||||||
mm-callback-info.h \
|
mm-callback-info.h \
|
||||||
|
$(auth_sources) \
|
||||||
mm-manager.c \
|
mm-manager.c \
|
||||||
mm-manager.h \
|
mm-manager.h \
|
||||||
mm-modem.c \
|
mm-modem.c \
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
153
src/mm-auth-provider-polkit.c
Normal file
153
src/mm-auth-provider-polkit.c
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/* -*- 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 <polkit/polkit.h>
|
||||||
|
|
||||||
|
#include "mm-auth-request-polkit.h"
|
||||||
|
#include "mm-auth-provider-polkit.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MMAuthProviderPolkit, mm_auth_provider_polkit, MM_TYPE_AUTH_PROVIDER)
|
||||||
|
|
||||||
|
#define MM_AUTH_PROVIDER_POLKIT_GET_PRIVATE(o) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_AUTH_PROVIDER_POLKIT, MMAuthProviderPolkitPrivate))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PolkitAuthority *authority;
|
||||||
|
guint auth_changed_id;
|
||||||
|
} MMAuthProviderPolkitPrivate;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_NAME = 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
GObject *
|
||||||
|
mm_auth_provider_polkit_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (MM_TYPE_AUTH_PROVIDER_POLKIT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
pk_authority_changed_cb (GObject *object, gpointer user_data)
|
||||||
|
{
|
||||||
|
/* Let clients know they should re-check their authorization */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static MMAuthRequest *
|
||||||
|
real_create_request (MMAuthProvider *provider,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
MMAuthProviderPolkitPrivate *priv = MM_AUTH_PROVIDER_POLKIT_GET_PRIVATE (provider);
|
||||||
|
|
||||||
|
return (MMAuthRequest *) mm_auth_request_polkit_new (priv->authority,
|
||||||
|
authorization,
|
||||||
|
owner,
|
||||||
|
context,
|
||||||
|
callback,
|
||||||
|
callback_data,
|
||||||
|
notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_auth_provider_polkit_init (MMAuthProviderPolkit *self)
|
||||||
|
{
|
||||||
|
MMAuthProviderPolkitPrivate *priv = MM_AUTH_PROVIDER_POLKIT_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
priv->authority = polkit_authority_get ();
|
||||||
|
if (priv->authority) {
|
||||||
|
priv->auth_changed_id = g_signal_connect (priv->authority,
|
||||||
|
"changed",
|
||||||
|
G_CALLBACK (pk_authority_changed_cb),
|
||||||
|
self);
|
||||||
|
} else
|
||||||
|
g_warning ("%s: failed to create PolicyKit authority.", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_NAME:
|
||||||
|
g_value_set_string (value, "polkit");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dispose (GObject *object)
|
||||||
|
{
|
||||||
|
MMAuthProviderPolkit *self = MM_AUTH_PROVIDER_POLKIT (object);
|
||||||
|
MMAuthProviderPolkitPrivate *priv = MM_AUTH_PROVIDER_POLKIT_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
if (priv->auth_changed_id) {
|
||||||
|
g_signal_handler_disconnect (priv->authority, priv->auth_changed_id);
|
||||||
|
priv->auth_changed_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (mm_auth_provider_polkit_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_auth_provider_polkit_class_init (MMAuthProviderPolkitClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
MMAuthProviderClass *ap_class = MM_AUTH_PROVIDER_CLASS (class);
|
||||||
|
|
||||||
|
mm_auth_provider_polkit_parent_class = g_type_class_peek_parent (class);
|
||||||
|
g_type_class_add_private (class, sizeof (MMAuthProviderPolkitPrivate));
|
||||||
|
|
||||||
|
/* Virtual methods */
|
||||||
|
object_class->set_property = set_property;
|
||||||
|
object_class->get_property = get_property;
|
||||||
|
object_class->dispose = dispose;
|
||||||
|
ap_class->create_request = real_create_request;
|
||||||
|
|
||||||
|
/* Properties */
|
||||||
|
g_object_class_override_property (object_class, PROP_NAME, MM_AUTH_PROVIDER_NAME);
|
||||||
|
}
|
||||||
|
|
43
src/mm-auth-provider-polkit.h
Normal file
43
src/mm-auth-provider-polkit.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* -*- 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_POLKIT_H
|
||||||
|
#define MM_AUTH_PROVIDER_POLKIT_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "mm-auth-provider.h"
|
||||||
|
|
||||||
|
#define MM_TYPE_AUTH_PROVIDER_POLKIT (mm_auth_provider_polkit_get_type ())
|
||||||
|
#define MM_AUTH_PROVIDER_POLKIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_AUTH_PROVIDER_POLKIT, MMAuthProviderPolkit))
|
||||||
|
#define MM_AUTH_PROVIDER_POLKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_AUTH_PROVIDER_POLKIT, MMAuthProviderPolkitClass))
|
||||||
|
#define MM_IS_AUTH_PROVIDER_POLKIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_AUTH_PROVIDER_POLKIT))
|
||||||
|
#define MM_IS_AUTH_PROVIDER_POLKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_AUTH_PROVIDER_POLKIT))
|
||||||
|
#define MM_AUTH_PROVIDER_POLKIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_AUTH_PROVIDER_POLKIT, MMAuthProviderPolkitClass))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMAuthProvider parent;
|
||||||
|
} MMAuthProviderPolkit;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMAuthProviderClass parent;
|
||||||
|
} MMAuthProviderPolkitClass;
|
||||||
|
|
||||||
|
GType mm_auth_provider_polkit_get_type (void);
|
||||||
|
|
||||||
|
GObject *mm_auth_provider_polkit_new (void);
|
||||||
|
|
||||||
|
#endif /* MM_AUTH_PROVIDER_POLKIT_H */
|
||||||
|
|
300
src/mm-auth-provider.c
Normal file
300
src/mm-auth-provider.c
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
/* -*- 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
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
GObject *
|
||||||
|
mm_auth_provider_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (MM_TYPE_AUTH_PROVIDER, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_requests (MMAuthProvider *self, GSList *remove)
|
||||||
|
{
|
||||||
|
MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self);
|
||||||
|
MMAuthRequest *req;
|
||||||
|
|
||||||
|
while (remove) {
|
||||||
|
req = MM_AUTH_REQUEST (remove->data);
|
||||||
|
g_hash_table_remove (priv->requests, req);
|
||||||
|
remove = g_slist_remove (remove, req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_auth_provider_cancel_request (MMAuthProvider *provider, MMAuthRequest *req)
|
||||||
|
{
|
||||||
|
MMAuthProviderPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (provider != NULL);
|
||||||
|
g_return_if_fail (MM_IS_AUTH_PROVIDER (provider));
|
||||||
|
g_return_if_fail (req != NULL);
|
||||||
|
|
||||||
|
priv = MM_AUTH_PROVIDER_GET_PRIVATE (provider);
|
||||||
|
|
||||||
|
g_return_if_fail (g_hash_table_lookup (priv->requests, req) != NULL);
|
||||||
|
g_hash_table_remove (priv->requests, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_auth_provider_cancel_for_owner (MMAuthProvider *self, GObject *owner)
|
||||||
|
{
|
||||||
|
MMAuthProviderPrivate *priv;
|
||||||
|
GHashTableIter iter;
|
||||||
|
MMAuthRequest *req;
|
||||||
|
gpointer value;
|
||||||
|
GSList *remove = NULL;
|
||||||
|
|
||||||
|
g_return_if_fail (self != NULL);
|
||||||
|
g_return_if_fail (MM_IS_AUTH_PROVIDER (self));
|
||||||
|
|
||||||
|
/* Find all requests from this owner */
|
||||||
|
priv = MM_AUTH_PROVIDER_GET_PRIVATE (self);
|
||||||
|
g_hash_table_iter_init (&iter, priv->requests);
|
||||||
|
while (g_hash_table_iter_next (&iter, NULL, &value)) {
|
||||||
|
req = MM_AUTH_REQUEST (value);
|
||||||
|
if (mm_auth_request_get_owner (req) == owner)
|
||||||
|
remove = g_slist_prepend (remove, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And cancel/remove them */
|
||||||
|
remove_requests (self, remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
static MMAuthRequest *
|
||||||
|
real_create_request (MMAuthProvider *provider,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
return (MMAuthRequest *) mm_auth_request_new (0,
|
||||||
|
authorization,
|
||||||
|
owner,
|
||||||
|
context,
|
||||||
|
callback,
|
||||||
|
callback_data,
|
||||||
|
notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = MM_AUTH_REQUEST (value);
|
||||||
|
|
||||||
|
if (mm_auth_request_get_authorization (req) != MM_AUTH_RESULT_UNKNOWN) {
|
||||||
|
mm_auth_request_callback (req);
|
||||||
|
remove = g_slist_prepend (remove, req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And remove those requests from our pending request list */
|
||||||
|
remove_requests (self, remove);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
auth_result_cb (MMAuthRequest *req, gpointer user_data)
|
||||||
|
{
|
||||||
|
MMAuthProvider *self = MM_AUTH_PROVIDER (user_data);
|
||||||
|
MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
/* Process results from an idle handler */
|
||||||
|
if (priv->process_id == 0)
|
||||||
|
priv->process_id = g_idle_add (process_complete_requests, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RESULT_SIGID_TAG "result-sigid"
|
||||||
|
|
||||||
|
MMAuthRequest *
|
||||||
|
mm_auth_provider_request_auth (MMAuthProvider *self,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MMAuthProviderPrivate *priv;
|
||||||
|
MMAuthRequest *req;
|
||||||
|
guint32 sigid;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self != NULL, 0);
|
||||||
|
g_return_val_if_fail (MM_IS_AUTH_PROVIDER (self), 0);
|
||||||
|
g_return_val_if_fail (authorization != NULL, 0);
|
||||||
|
g_return_val_if_fail (callback != NULL, 0);
|
||||||
|
|
||||||
|
priv = MM_AUTH_PROVIDER_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
req = MM_AUTH_PROVIDER_GET_CLASS (self)->create_request (self,
|
||||||
|
authorization,
|
||||||
|
owner,
|
||||||
|
context,
|
||||||
|
callback,
|
||||||
|
callback_data,
|
||||||
|
notify);
|
||||||
|
g_assert (req);
|
||||||
|
|
||||||
|
sigid = g_signal_connect (req, "result", G_CALLBACK (auth_result_cb), self);
|
||||||
|
g_object_set_data (G_OBJECT (req), RESULT_SIGID_TAG, GUINT_TO_POINTER (sigid));
|
||||||
|
|
||||||
|
g_hash_table_insert (priv->requests, req, req);
|
||||||
|
if (!mm_auth_request_authenticate (req, error)) {
|
||||||
|
/* Error */
|
||||||
|
g_hash_table_remove (priv->requests, req);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
dispose_auth_request (gpointer data)
|
||||||
|
{
|
||||||
|
MMAuthRequest *req = MM_AUTH_REQUEST (data);
|
||||||
|
guint sigid;
|
||||||
|
|
||||||
|
sigid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), RESULT_SIGID_TAG));
|
||||||
|
if (sigid)
|
||||||
|
g_signal_handler_disconnect (req, sigid);
|
||||||
|
mm_auth_request_dispose (req);
|
||||||
|
g_object_unref (req);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
dispose_auth_request);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
dispose (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)->dispose (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->dispose = dispose;
|
||||||
|
class->create_request = real_create_request;
|
||||||
|
|
||||||
|
/* 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));
|
||||||
|
}
|
||||||
|
|
84
src/mm-auth-provider.h
Normal file
84
src/mm-auth-provider.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/* -*- 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>
|
||||||
|
#include <dbus/dbus-glib-lowlevel.h>
|
||||||
|
|
||||||
|
#include "mm-auth-request.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 struct {
|
||||||
|
GObject parent;
|
||||||
|
} MMAuthProvider;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GObjectClass parent;
|
||||||
|
|
||||||
|
MMAuthRequest * (*create_request) (MMAuthProvider *provider,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
} MMAuthProviderClass;
|
||||||
|
|
||||||
|
GType mm_auth_provider_get_type (void);
|
||||||
|
|
||||||
|
/* Don't do anything clever from the notify callback... */
|
||||||
|
MMAuthRequest *mm_auth_provider_request_auth (MMAuthProvider *provider,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
void mm_auth_provider_cancel_for_owner (MMAuthProvider *provider,
|
||||||
|
GObject *owner);
|
||||||
|
|
||||||
|
/* Subclass API */
|
||||||
|
|
||||||
|
/* To get an auth provider instance, implemented in mm-auth-provider-factory.c */
|
||||||
|
MMAuthProvider *mm_auth_provider_get (void);
|
||||||
|
|
||||||
|
/* schedules the request's completion */
|
||||||
|
void mm_auth_provider_finish_request (MMAuthProvider *provider,
|
||||||
|
MMAuthRequest *req,
|
||||||
|
MMAuthResult result);
|
||||||
|
|
||||||
|
void mm_auth_provider_cancel_request (MMAuthProvider *provider, MMAuthRequest *req);
|
||||||
|
|
||||||
|
#endif /* MM_AUTH_PROVIDER_H */
|
||||||
|
|
175
src/mm-auth-request-polkit.c
Normal file
175
src/mm-auth-request-polkit.c
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/* -*- 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 <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "mm-auth-request-polkit.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MMAuthRequestPolkit, mm_auth_request_polkit, MM_TYPE_AUTH_REQUEST)
|
||||||
|
|
||||||
|
#define MM_AUTH_REQUEST_POLKIT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_AUTH_REQUEST_POLKIT, MMAuthRequestPolkitPrivate))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PolkitAuthority *authority;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
PolkitSubject *subject;
|
||||||
|
} MMAuthRequestPolkitPrivate;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
GObject *
|
||||||
|
mm_auth_request_polkit_new (PolkitAuthority *authority,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GObject *obj;
|
||||||
|
MMAuthRequestPolkitPrivate *priv;
|
||||||
|
char *sender;
|
||||||
|
|
||||||
|
g_return_val_if_fail (authorization != NULL, NULL);
|
||||||
|
g_return_val_if_fail (owner != NULL, NULL);
|
||||||
|
g_return_val_if_fail (callback != NULL, NULL);
|
||||||
|
g_return_val_if_fail (context != NULL, NULL);
|
||||||
|
|
||||||
|
obj = mm_auth_request_new (MM_TYPE_AUTH_REQUEST_POLKIT,
|
||||||
|
authorization,
|
||||||
|
owner,
|
||||||
|
context,
|
||||||
|
callback,
|
||||||
|
callback_data,
|
||||||
|
notify);
|
||||||
|
if (obj) {
|
||||||
|
priv = MM_AUTH_REQUEST_POLKIT_GET_PRIVATE (obj);
|
||||||
|
priv->authority = authority;
|
||||||
|
priv->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
|
sender = dbus_g_method_get_sender (context);
|
||||||
|
priv->subject = polkit_system_bus_name_new (sender);
|
||||||
|
g_free (sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
pk_auth_cb (GObject *object, GAsyncResult *result, gpointer user_data)
|
||||||
|
{
|
||||||
|
MMAuthRequestPolkit *self = user_data;
|
||||||
|
MMAuthRequestPolkitPrivate *priv;
|
||||||
|
PolkitAuthorizationResult *pk_result;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_return_if_fail (self != NULL);
|
||||||
|
g_return_if_fail (MM_IS_AUTH_REQUEST_POLKIT (self));
|
||||||
|
|
||||||
|
priv = MM_AUTH_REQUEST_POLKIT_GET_PRIVATE (self);
|
||||||
|
if (!g_cancellable_is_cancelled (priv->cancellable)) {
|
||||||
|
pk_result = polkit_authority_check_authorization_finish (priv->authority,
|
||||||
|
result,
|
||||||
|
&error);
|
||||||
|
if (error) {
|
||||||
|
mm_auth_request_set_result (MM_AUTH_REQUEST (self), MM_AUTH_RESULT_INTERNAL_FAILURE);
|
||||||
|
g_warning ("%s: PolicyKit authentication error: (%d) %s",
|
||||||
|
__func__,
|
||||||
|
error ? error->code : -1,
|
||||||
|
error && error->message ? error->message : "(unknown)");
|
||||||
|
} else if (polkit_authorization_result_get_is_authorized (pk_result))
|
||||||
|
mm_auth_request_set_result (MM_AUTH_REQUEST (self), MM_AUTH_RESULT_AUTHORIZED);
|
||||||
|
else if (polkit_authorization_result_get_is_challenge (pk_result))
|
||||||
|
mm_auth_request_set_result (MM_AUTH_REQUEST (self), MM_AUTH_RESULT_CHALLENGE);
|
||||||
|
else
|
||||||
|
mm_auth_request_set_result (MM_AUTH_REQUEST (self), MM_AUTH_RESULT_NOT_AUTHORIZED);
|
||||||
|
|
||||||
|
g_signal_emit_by_name (self, "result");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
real_authenticate (MMAuthRequest *self, GError **error)
|
||||||
|
{
|
||||||
|
MMAuthRequestPolkitPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (MM_IS_AUTH_REQUEST_POLKIT (self), FALSE);
|
||||||
|
|
||||||
|
/* We ref ourselves across the polkit call, because we can't get
|
||||||
|
* disposed of while the call is still in-progress, and even if we
|
||||||
|
* cancel ourselves we'll still get the callback.
|
||||||
|
*/
|
||||||
|
g_object_ref (self);
|
||||||
|
|
||||||
|
priv = MM_AUTH_REQUEST_POLKIT_GET_PRIVATE (self);
|
||||||
|
polkit_authority_check_authorization (priv->authority,
|
||||||
|
priv->subject,
|
||||||
|
mm_auth_request_get_authorization (MM_AUTH_REQUEST (self)),
|
||||||
|
NULL,
|
||||||
|
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
|
||||||
|
priv->cancellable,
|
||||||
|
pk_auth_cb,
|
||||||
|
self);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
real_dispose (MMAuthRequest *req)
|
||||||
|
{
|
||||||
|
g_return_if_fail (req != NULL);
|
||||||
|
g_return_if_fail (MM_IS_AUTH_REQUEST_POLKIT (req));
|
||||||
|
|
||||||
|
g_cancellable_cancel (MM_AUTH_REQUEST_POLKIT_GET_PRIVATE (req)->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_auth_request_polkit_init (MMAuthRequestPolkit *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dispose (GObject *object)
|
||||||
|
{
|
||||||
|
MMAuthRequestPolkitPrivate *priv = MM_AUTH_REQUEST_POLKIT_GET_PRIVATE (object);
|
||||||
|
|
||||||
|
g_object_unref (priv->cancellable);
|
||||||
|
g_object_unref (priv->subject);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (mm_auth_request_polkit_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_auth_request_polkit_class_init (MMAuthRequestPolkitClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
MMAuthRequestClass *ar_class = MM_AUTH_REQUEST_CLASS (class);
|
||||||
|
|
||||||
|
mm_auth_request_polkit_parent_class = g_type_class_peek_parent (class);
|
||||||
|
g_type_class_add_private (class, sizeof (MMAuthRequestPolkitPrivate));
|
||||||
|
|
||||||
|
/* Virtual methods */
|
||||||
|
object_class->dispose = dispose;
|
||||||
|
ar_class->authenticate = real_authenticate;
|
||||||
|
ar_class->dispose = real_dispose;
|
||||||
|
}
|
||||||
|
|
53
src/mm-auth-request-polkit.h
Normal file
53
src/mm-auth-request-polkit.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* -*- 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_REQUEST_POLKIT_H
|
||||||
|
#define MM_AUTH_REQUEST_POLKIT_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <polkit/polkit.h>
|
||||||
|
#include <dbus/dbus-glib-lowlevel.h>
|
||||||
|
|
||||||
|
#include "mm-auth-request.h"
|
||||||
|
|
||||||
|
#define MM_TYPE_AUTH_REQUEST_POLKIT (mm_auth_request_polkit_get_type ())
|
||||||
|
#define MM_AUTH_REQUEST_POLKIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_AUTH_REQUEST_POLKIT, MMAuthRequestPolkit))
|
||||||
|
#define MM_AUTH_REQUEST_POLKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_AUTH_REQUEST_POLKIT, MMAuthRequestPolkitClass))
|
||||||
|
#define MM_IS_AUTH_REQUEST_POLKIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_AUTH_REQUEST_POLKIT))
|
||||||
|
#define MM_IS_AUTH_REQUEST_POLKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_AUTH_REQUEST_POLKIT))
|
||||||
|
#define MM_AUTH_REQUEST_POLKIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_AUTH_REQUEST_POLKIT, MMAuthRequestPolkitClass))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMAuthRequest parent;
|
||||||
|
} MMAuthRequestPolkit;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MMAuthRequestClass parent;
|
||||||
|
} MMAuthRequestPolkitClass;
|
||||||
|
|
||||||
|
GType mm_auth_request_polkit_get_type (void);
|
||||||
|
|
||||||
|
GObject *mm_auth_request_polkit_new (PolkitAuthority *authority,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
|
||||||
|
void mm_auth_request_polkit_cancel (MMAuthRequestPolkit *self);
|
||||||
|
|
||||||
|
#endif /* MM_AUTH_REQUEST_POLKIT_H */
|
||||||
|
|
182
src/mm-auth-request.c
Normal file
182
src/mm-auth-request.c
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/* -*- 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 "mm-auth-request.h"
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (MMAuthRequest, mm_auth_request, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
#define MM_AUTH_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_AUTH_REQUEST, MMAuthRequestPrivate))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GObject *owner;
|
||||||
|
char *auth;
|
||||||
|
DBusGMethodInvocation *context;
|
||||||
|
MMAuthRequestCb callback;
|
||||||
|
gpointer callback_data;
|
||||||
|
|
||||||
|
MMAuthResult result;
|
||||||
|
} MMAuthRequestPrivate;
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
GObject *
|
||||||
|
mm_auth_request_new (GType atype,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GObject *obj;
|
||||||
|
MMAuthRequestPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (authorization != NULL, NULL);
|
||||||
|
g_return_val_if_fail (owner != NULL, NULL);
|
||||||
|
g_return_val_if_fail (callback != NULL, NULL);
|
||||||
|
|
||||||
|
obj = g_object_new (atype ? atype : MM_TYPE_AUTH_REQUEST, NULL);
|
||||||
|
if (obj) {
|
||||||
|
priv = MM_AUTH_REQUEST_GET_PRIVATE (obj);
|
||||||
|
priv->owner = owner; /* not reffed */
|
||||||
|
priv->context = context;
|
||||||
|
priv->auth = g_strdup (authorization);
|
||||||
|
priv->callback = callback;
|
||||||
|
priv->callback_data = callback_data;
|
||||||
|
|
||||||
|
g_object_set_data_full (obj, "caller-data", callback_data, notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
const char *
|
||||||
|
mm_auth_request_get_authorization (MMAuthRequest *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self != NULL, NULL);
|
||||||
|
g_return_val_if_fail (MM_IS_AUTH_REQUEST (self), NULL);
|
||||||
|
|
||||||
|
return MM_AUTH_REQUEST_GET_PRIVATE (self)->auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
GObject *
|
||||||
|
mm_auth_request_get_owner (MMAuthRequest *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self != NULL, NULL);
|
||||||
|
g_return_val_if_fail (MM_IS_AUTH_REQUEST (self), NULL);
|
||||||
|
|
||||||
|
return MM_AUTH_REQUEST_GET_PRIVATE (self)->owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
MMAuthResult
|
||||||
|
mm_auth_request_get_result (MMAuthRequest *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self != NULL, MM_AUTH_RESULT_UNKNOWN);
|
||||||
|
g_return_val_if_fail (MM_IS_AUTH_REQUEST (self), MM_AUTH_RESULT_UNKNOWN);
|
||||||
|
|
||||||
|
return MM_AUTH_REQUEST_GET_PRIVATE (self)->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_auth_request_set_result (MMAuthRequest *self, MMAuthResult result)
|
||||||
|
{
|
||||||
|
g_return_if_fail (self != NULL);
|
||||||
|
g_return_if_fail (MM_IS_AUTH_REQUEST (self));
|
||||||
|
g_return_if_fail (result != MM_AUTH_RESULT_UNKNOWN);
|
||||||
|
|
||||||
|
MM_AUTH_REQUEST_GET_PRIVATE (self)->result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_auth_request_authenticate (MMAuthRequest *self, GError **error)
|
||||||
|
{
|
||||||
|
return MM_AUTH_REQUEST_GET_CLASS (self)->authenticate (self, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_auth_request_callback (MMAuthRequest *self)
|
||||||
|
{
|
||||||
|
MMAuthRequestPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (self != NULL);
|
||||||
|
g_return_if_fail (MM_IS_AUTH_REQUEST (self));
|
||||||
|
|
||||||
|
priv = MM_AUTH_REQUEST_GET_PRIVATE (self);
|
||||||
|
g_warn_if_fail (priv->result != MM_AUTH_RESULT_UNKNOWN);
|
||||||
|
|
||||||
|
if (priv->callback)
|
||||||
|
priv->callback (self, priv->owner, priv->context, priv->callback_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_auth_request_dispose (MMAuthRequest *self)
|
||||||
|
{
|
||||||
|
g_return_if_fail (self != NULL);
|
||||||
|
g_return_if_fail (MM_IS_AUTH_REQUEST (self));
|
||||||
|
|
||||||
|
if (MM_AUTH_REQUEST_GET_CLASS (self)->dispose)
|
||||||
|
MM_AUTH_REQUEST_GET_CLASS (self)->dispose (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
real_authenticate (MMAuthRequest *self, GError **error)
|
||||||
|
{
|
||||||
|
/* Null auth; everything passes */
|
||||||
|
mm_auth_request_set_result (self, MM_AUTH_RESULT_AUTHORIZED);
|
||||||
|
g_signal_emit_by_name (self, "result");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_auth_request_init (MMAuthRequest *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dispose (GObject *object)
|
||||||
|
{
|
||||||
|
MMAuthRequestPrivate *priv = MM_AUTH_REQUEST_GET_PRIVATE (object);
|
||||||
|
|
||||||
|
g_free (priv->auth);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (mm_auth_request_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mm_auth_request_class_init (MMAuthRequestClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
|
||||||
|
mm_auth_request_parent_class = g_type_class_peek_parent (class);
|
||||||
|
g_type_class_add_private (class, sizeof (MMAuthRequestPrivate));
|
||||||
|
|
||||||
|
/* Virtual methods */
|
||||||
|
object_class->dispose = dispose;
|
||||||
|
class->authenticate = real_authenticate;
|
||||||
|
|
||||||
|
g_signal_new ("result",
|
||||||
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
G_SIGNAL_RUN_FIRST,
|
||||||
|
0, NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0, G_TYPE_NONE);
|
||||||
|
}
|
||||||
|
|
72
src/mm-auth-request.h
Normal file
72
src/mm-auth-request.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/* -*- 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_REQUEST_H
|
||||||
|
#define MM_AUTH_REQUEST_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <dbus/dbus-glib-lowlevel.h>
|
||||||
|
|
||||||
|
#define MM_TYPE_AUTH_REQUEST (mm_auth_request_get_type ())
|
||||||
|
#define MM_AUTH_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_AUTH_REQUEST, MMAuthRequest))
|
||||||
|
#define MM_AUTH_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_AUTH_REQUEST, MMAuthRequestClass))
|
||||||
|
#define MM_IS_AUTH_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_AUTH_REQUEST))
|
||||||
|
#define MM_IS_AUTH_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_AUTH_REQUEST))
|
||||||
|
#define MM_AUTH_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_AUTH_REQUEST, MMAuthRequestClass))
|
||||||
|
|
||||||
|
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 {
|
||||||
|
GObject parent;
|
||||||
|
} MMAuthRequest;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GObjectClass parent;
|
||||||
|
|
||||||
|
gboolean (*authenticate) (MMAuthRequest *self, GError **error);
|
||||||
|
void (*dispose) (MMAuthRequest *self);
|
||||||
|
} MMAuthRequestClass;
|
||||||
|
|
||||||
|
GType mm_auth_request_get_type (void);
|
||||||
|
|
||||||
|
typedef void (*MMAuthRequestCb) (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
GObject *mm_auth_request_new (GType atype,
|
||||||
|
const char *authorization,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
|
||||||
|
const char * mm_auth_request_get_authorization (MMAuthRequest *req);
|
||||||
|
GObject * mm_auth_request_get_owner (MMAuthRequest *req);
|
||||||
|
MMAuthResult mm_auth_request_get_result (MMAuthRequest *req);
|
||||||
|
void mm_auth_request_set_result (MMAuthRequest *req, MMAuthResult result);
|
||||||
|
gboolean mm_auth_request_authenticate (MMAuthRequest *req, GError **error);
|
||||||
|
void mm_auth_request_callback (MMAuthRequest *req);
|
||||||
|
void mm_auth_request_dispose (MMAuthRequest *req);
|
||||||
|
|
||||||
|
#endif /* MM_AUTH_REQUEST_H */
|
||||||
|
|
@@ -76,6 +76,7 @@ mm_modem_error_get_type (void)
|
|||||||
ENUM_ENTRY (MM_MODEM_ERROR_DISCONNECTED, "Disconnected"),
|
ENUM_ENTRY (MM_MODEM_ERROR_DISCONNECTED, "Disconnected"),
|
||||||
ENUM_ENTRY (MM_MODEM_ERROR_OPERATION_IN_PROGRESS, "OperationInProgress"),
|
ENUM_ENTRY (MM_MODEM_ERROR_OPERATION_IN_PROGRESS, "OperationInProgress"),
|
||||||
ENUM_ENTRY (MM_MODEM_ERROR_REMOVED, "Removed"),
|
ENUM_ENTRY (MM_MODEM_ERROR_REMOVED, "Removed"),
|
||||||
|
ENUM_ENTRY (MM_MODEM_ERROR_AUTHORIZATION_REQUIRED, "AuthorizationRequired"),
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -39,7 +39,8 @@ enum {
|
|||||||
MM_MODEM_ERROR_CONNECTED = 2,
|
MM_MODEM_ERROR_CONNECTED = 2,
|
||||||
MM_MODEM_ERROR_DISCONNECTED = 3,
|
MM_MODEM_ERROR_DISCONNECTED = 3,
|
||||||
MM_MODEM_ERROR_OPERATION_IN_PROGRESS = 4,
|
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 ())
|
#define MM_MODEM_ERROR (mm_modem_error_quark ())
|
||||||
|
@@ -136,39 +136,6 @@ got_signal_quality (MMModem *modem,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
mm_generic_gsm_set_reg_status (MMGenericGsm *modem,
|
|
||||||
MMModemGsmNetworkRegStatus status)
|
|
||||||
{
|
|
||||||
MMGenericGsmPrivate *priv;
|
|
||||||
|
|
||||||
g_return_if_fail (MM_IS_GENERIC_GSM (modem));
|
|
||||||
|
|
||||||
priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
|
|
||||||
|
|
||||||
if (priv->reg_status != status) {
|
|
||||||
priv->reg_status = status;
|
|
||||||
|
|
||||||
g_debug ("Registration state changed: %d", status);
|
|
||||||
|
|
||||||
if (status == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME ||
|
|
||||||
status == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
|
|
||||||
mm_at_serial_port_queue_command (priv->primary, "+COPS=3,2;+COPS?", 3, read_operator_code_done, modem);
|
|
||||||
mm_at_serial_port_queue_command (priv->primary, "+COPS=3,0;+COPS?", 3, read_operator_name_done, modem);
|
|
||||||
mm_modem_gsm_network_get_signal_quality (MM_MODEM_GSM_NETWORK (modem), got_signal_quality, NULL);
|
|
||||||
} else {
|
|
||||||
g_free (priv->oper_code);
|
|
||||||
g_free (priv->oper_name);
|
|
||||||
priv->oper_code = priv->oper_name = NULL;
|
|
||||||
|
|
||||||
mm_modem_gsm_network_registration_info (MM_MODEM_GSM_NETWORK (modem), priv->reg_status,
|
|
||||||
priv->oper_code, priv->oper_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
mm_generic_gsm_update_enabled_state (modem, TRUE, MM_MODEM_STATE_REASON_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *result;
|
const char *result;
|
||||||
const char *normalized;
|
const char *normalized;
|
||||||
@@ -1130,6 +1097,40 @@ mm_generic_gsm_pending_registration_stop (MMGenericGsm *modem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mm_generic_gsm_set_reg_status (MMGenericGsm *modem,
|
||||||
|
MMModemGsmNetworkRegStatus status)
|
||||||
|
{
|
||||||
|
MMGenericGsmPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (MM_IS_GENERIC_GSM (modem));
|
||||||
|
|
||||||
|
priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
|
||||||
|
|
||||||
|
if (priv->reg_status != status) {
|
||||||
|
priv->reg_status = status;
|
||||||
|
|
||||||
|
g_debug ("Registration state changed: %d", status);
|
||||||
|
|
||||||
|
if (status == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME ||
|
||||||
|
status == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
|
||||||
|
mm_at_serial_port_queue_command (priv->primary, "+COPS=3,2;+COPS?", 3, read_operator_code_done, modem);
|
||||||
|
mm_at_serial_port_queue_command (priv->primary, "+COPS=3,0;+COPS?", 3, read_operator_name_done, modem);
|
||||||
|
mm_modem_gsm_network_get_signal_quality (MM_MODEM_GSM_NETWORK (modem), got_signal_quality, NULL);
|
||||||
|
} else {
|
||||||
|
g_free (priv->oper_code);
|
||||||
|
g_free (priv->oper_name);
|
||||||
|
priv->oper_code = priv->oper_name = NULL;
|
||||||
|
|
||||||
|
mm_modem_gsm_network_registration_info (MM_MODEM_GSM_NETWORK (modem), priv->reg_status,
|
||||||
|
priv->oper_code, priv->oper_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_generic_gsm_update_enabled_state (modem, TRUE, MM_MODEM_STATE_REASON_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns TRUE if the modem is "done", ie has registered or been denied */
|
||||||
static gboolean
|
static gboolean
|
||||||
reg_status_updated (MMGenericGsm *self, int new_value, GError **error)
|
reg_status_updated (MMGenericGsm *self, int new_value, GError **error)
|
||||||
{
|
{
|
||||||
@@ -1255,8 +1256,7 @@ get_reg_status_done (MMAtSerialPort *port,
|
|||||||
GMatchInfo *match_info;
|
GMatchInfo *match_info;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
guint id;
|
guint id;
|
||||||
|
gboolean status_done;
|
||||||
g_warn_if_fail (info == priv->pending_reg_info);
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
info->error = g_error_copy (error);
|
info->error = g_error_copy (error);
|
||||||
@@ -1290,31 +1290,38 @@ get_reg_status_done (MMAtSerialPort *port,
|
|||||||
g_regex_unref (r);
|
g_regex_unref (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( reg_status >= 0
|
if (reg_status >= 0) {
|
||||||
&& !reg_status_updated (self, reg_status, &info->error)
|
/* Update cached registration status */
|
||||||
&& priv->pending_reg_info) {
|
status_done = reg_status_updated (self, reg_status, &info->error);
|
||||||
g_clear_error (&info->error);
|
|
||||||
|
|
||||||
/* Not registered yet; poll registration status again */
|
/* If we're waiting for automatic registration to complete and it's
|
||||||
id = g_timeout_add_seconds (1, reg_status_again, info);
|
* not done yet, check again in a few seconds.
|
||||||
mm_callback_info_set_data (info, REG_STATUS_AGAIN_TAG,
|
*/
|
||||||
GUINT_TO_POINTER (id),
|
if ((info == priv->pending_reg_info) && !status_done) {
|
||||||
reg_status_again_remove);
|
g_clear_error (&info->error);
|
||||||
return;
|
|
||||||
|
/* Not registered yet; poll registration status again */
|
||||||
|
id = g_timeout_add_seconds (1, reg_status_again, info);
|
||||||
|
mm_callback_info_set_data (info, REG_STATUS_AGAIN_TAG,
|
||||||
|
GUINT_TO_POINTER (id),
|
||||||
|
reg_status_again_remove);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_done:
|
reg_done:
|
||||||
/* This will schedule the callback for us */
|
if (info == priv->pending_reg_info) {
|
||||||
mm_generic_gsm_pending_registration_stop (self);
|
/* For pending registration, this will schedule the callback for us */
|
||||||
|
mm_generic_gsm_pending_registration_stop (self);
|
||||||
|
} else {
|
||||||
|
/* Otherwise for a direct registration request, schedule the callback now */
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_registration_status (MMAtSerialPort *port, MMCallbackInfo *info)
|
get_registration_status (MMAtSerialPort *port, MMCallbackInfo *info)
|
||||||
{
|
{
|
||||||
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
|
|
||||||
|
|
||||||
g_warn_if_fail (info == priv->pending_reg_info);
|
|
||||||
|
|
||||||
mm_at_serial_port_queue_command (port, "+CREG?", 10, get_reg_status_done, info);
|
mm_at_serial_port_queue_command (port, "+CREG?", 10, get_reg_status_done, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1423,14 +1430,28 @@ get_registration_info (MMModemGsmNetwork *self,
|
|||||||
MMModemGsmNetworkRegInfoFn callback,
|
MMModemGsmNetworkRegInfoFn callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
|
||||||
MMCallbackInfo *info;
|
MMCallbackInfo *info;
|
||||||
|
MMSerialPort *port = priv->primary;
|
||||||
|
|
||||||
info = mm_callback_info_new_full (MM_MODEM (self),
|
info = mm_callback_info_new_full (MM_MODEM (self),
|
||||||
gsm_network_reg_info_invoke,
|
gsm_network_reg_info_invoke,
|
||||||
G_CALLBACK (callback),
|
G_CALLBACK (callback),
|
||||||
user_data);
|
user_data);
|
||||||
|
|
||||||
mm_callback_info_schedule (info);
|
if (mm_port_get_connected (MM_PORT (priv->primary))) {
|
||||||
|
if (!priv->secondary) {
|
||||||
|
info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
|
||||||
|
"Cannot get registration info while connected");
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use secondary port if primary is connected */
|
||||||
|
port = priv->secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_registration_status (port, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -44,6 +44,8 @@ typedef struct {
|
|||||||
gboolean valid;
|
gboolean valid;
|
||||||
MMModemState state;
|
MMModemState state;
|
||||||
|
|
||||||
|
MMAuthProvider *authp;
|
||||||
|
|
||||||
GHashTable *ports;
|
GHashTable *ports;
|
||||||
} MMModemBasePrivate;
|
} MMModemBasePrivate;
|
||||||
|
|
||||||
@@ -213,11 +215,51 @@ mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_require
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
modem_auth_request (MMModem *modem,
|
||||||
|
const char *authorization,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
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),
|
||||||
|
context,
|
||||||
|
callback,
|
||||||
|
callback_data,
|
||||||
|
notify,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
modem_auth_finish (MMModem *modem, MMAuthRequest *req, GError **error)
|
||||||
|
{
|
||||||
|
if (mm_auth_request_get_result (req) != MM_AUTH_RESULT_AUTHORIZED) {
|
||||||
|
g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_AUTHORIZATION_REQUIRED,
|
||||||
|
"This request requires the '%s' authorization",
|
||||||
|
mm_auth_request_get_authorization (req));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mm_modem_base_init (MMModemBase *self)
|
mm_modem_base_init (MMModemBase *self)
|
||||||
{
|
{
|
||||||
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
priv->authp = mm_auth_provider_get ();
|
||||||
|
|
||||||
priv->ports = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
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),
|
mm_properties_changed_signal_register_property (G_OBJECT (self),
|
||||||
@@ -228,6 +270,8 @@ mm_modem_base_init (MMModemBase *self)
|
|||||||
static void
|
static void
|
||||||
modem_init (MMModem *modem_class)
|
modem_init (MMModem *modem_class)
|
||||||
{
|
{
|
||||||
|
modem_class->auth_request = modem_auth_request;
|
||||||
|
modem_class->auth_finish = modem_auth_finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -326,6 +370,8 @@ finalize (GObject *object)
|
|||||||
MMModemBase *self = MM_MODEM_BASE (object);
|
MMModemBase *self = MM_MODEM_BASE (object);
|
||||||
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
|
||||||
|
|
||||||
|
mm_auth_provider_cancel_for_owner (priv->authp, object);
|
||||||
|
|
||||||
g_hash_table_destroy (priv->ports);
|
g_hash_table_destroy (priv->ports);
|
||||||
g_free (priv->driver);
|
g_free (priv->driver);
|
||||||
g_free (priv->plugin);
|
g_free (priv->plugin);
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "mm-errors.h"
|
#include "mm-errors.h"
|
||||||
#include "mm-callback-info.h"
|
#include "mm-callback-info.h"
|
||||||
#include "mm-marshal.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_signal_quality (MMModemCdma *modem, DBusGMethodInvocation *context);
|
||||||
static void impl_modem_cdma_get_esn (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
|
static void
|
||||||
impl_modem_cdma_get_esn (MMModemCdma *modem,
|
esn_auth_cb (MMAuthRequest *req,
|
||||||
DBusGMethodInvocation *context)
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
mm_modem_cdma_get_esn (modem, str_call_done, context);
|
MMModemCdma *self = MM_MODEM_CDMA (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise get the ESN */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &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,
|
||||||
|
context,
|
||||||
|
esn_auth_cb,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dbus/dbus-glib.h>
|
#include <dbus/dbus-glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "mm-modem-gsm-card.h"
|
#include "mm-modem-gsm-card.h"
|
||||||
#include "mm-errors.h"
|
#include "mm-errors.h"
|
||||||
@@ -201,26 +202,176 @@ mm_modem_gsm_card_change_pin (MMModemGsmCard *self,
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
impl_gsm_modem_get_imei (MMModemGsmCard *modem,
|
imei_auth_cb (MMAuthRequest *req,
|
||||||
DBusGMethodInvocation *context)
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
mm_modem_gsm_card_get_imei (modem, str_call_done, context);
|
MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise get the IMEI */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &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
|
static void
|
||||||
impl_gsm_modem_get_imsi (MMModemGsmCard *modem,
|
impl_gsm_modem_get_imei (MMModemGsmCard *modem, DBusGMethodInvocation *context)
|
||||||
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,
|
||||||
|
context,
|
||||||
|
imei_auth_cb,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
imsi_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise get the IMSI */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &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
|
static void
|
||||||
impl_gsm_modem_send_puk (MMModemGsmCard *modem,
|
impl_gsm_modem_get_imsi (MMModemGsmCard *modem, DBusGMethodInvocation *context)
|
||||||
const char *puk,
|
|
||||||
const char *pin,
|
|
||||||
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,
|
||||||
|
context,
|
||||||
|
imsi_auth_cb,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *puk;
|
||||||
|
char *pin;
|
||||||
|
char *pin2;
|
||||||
|
gboolean enabled;
|
||||||
|
} 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_puk_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
|
||||||
|
SendPinPukInfo *info = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise send the PUK */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
mm_modem_gsm_card_send_puk (self, info->puk, info->pin, async_call_done, 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);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to send the PUK */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_DEVICE,
|
||||||
|
context,
|
||||||
|
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 (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
|
||||||
|
SendPinPukInfo *info = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise unlock the modem */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
mm_modem_gsm_card_send_pin (self, info->pin, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -228,7 +379,42 @@ impl_gsm_modem_send_pin (MMModemGsmCard *modem,
|
|||||||
const char *pin,
|
const char *pin,
|
||||||
DBusGMethodInvocation *context)
|
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);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to unlock the modem */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_DEVICE,
|
||||||
|
context,
|
||||||
|
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 (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
|
||||||
|
SendPinPukInfo *info = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise enable the PIN */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
mm_modem_gsm_card_enable_pin (self, info->pin, info->enabled, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -237,7 +423,42 @@ impl_gsm_modem_enable_pin (MMModemGsmCard *modem,
|
|||||||
gboolean enabled,
|
gboolean enabled,
|
||||||
DBusGMethodInvocation *context)
|
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);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to enable a PIN */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_DEVICE,
|
||||||
|
context,
|
||||||
|
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 (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
|
||||||
|
SendPinPukInfo *info = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise change the PIN */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
mm_modem_gsm_card_change_pin (self, info->pin, info->pin2, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -246,7 +467,22 @@ impl_gsm_modem_change_pin (MMModemGsmCard *modem,
|
|||||||
const char *new_pin,
|
const char *new_pin,
|
||||||
DBusGMethodInvocation *context)
|
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);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to change the PIN */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_DEVICE,
|
||||||
|
context,
|
||||||
|
change_pin_auth_cb,
|
||||||
|
info,
|
||||||
|
send_pin_puk_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -305,6 +541,7 @@ mm_modem_gsm_card_get_type (void)
|
|||||||
&card_info, 0);
|
&card_info, 0);
|
||||||
|
|
||||||
g_type_interface_add_prerequisite (card_type, G_TYPE_OBJECT);
|
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);
|
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);
|
mm_modem_gsm_network_register (modem, id, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scan_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmNetwork *self = MM_MODEM_GSM_NETWORK (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise get the IMEI */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &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
|
static void
|
||||||
impl_gsm_modem_scan (MMModemGsmNetwork *modem,
|
impl_gsm_modem_scan (MMModemGsmNetwork *modem,
|
||||||
DBusGMethodInvocation *context)
|
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,
|
||||||
|
context,
|
||||||
|
scan_auth_cb,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -562,6 +591,7 @@ mm_modem_gsm_network_get_type (void)
|
|||||||
&network_info, 0);
|
&network_info, 0);
|
||||||
|
|
||||||
g_type_interface_add_prerequisite (network_type, G_TYPE_OBJECT);
|
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);
|
dbus_g_object_type_install_info (network_type, &dbus_glib_mm_modem_gsm_network_object_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -129,12 +129,137 @@ mm_modem_gsm_sms_send (MMModemGsmSms *self,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
guint num1;
|
||||||
|
guint num2;
|
||||||
|
guint num3;
|
||||||
|
guint num4;
|
||||||
|
guint num5;
|
||||||
|
char *str;
|
||||||
|
GHashTable *hash;
|
||||||
|
} SmsAuthInfo;
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_auth_info_destroy (gpointer data)
|
||||||
|
{
|
||||||
|
SmsAuthInfo *info = data;
|
||||||
|
|
||||||
|
g_hash_table_destroy (info->hash);
|
||||||
|
g_free (info->str);
|
||||||
|
memset (info, 0, sizeof (SmsAuthInfo));
|
||||||
|
g_free (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_gvalue (gpointer data)
|
||||||
|
{
|
||||||
|
GValue *value = (GValue *) data;
|
||||||
|
|
||||||
|
g_value_unset (value);
|
||||||
|
g_slice_free (GValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SmsAuthInfo *
|
||||||
|
sms_auth_info_new (guint num1,
|
||||||
|
guint num2,
|
||||||
|
guint num3,
|
||||||
|
guint num4,
|
||||||
|
guint num5,
|
||||||
|
const char *str,
|
||||||
|
GHashTable *hash)
|
||||||
|
{
|
||||||
|
SmsAuthInfo *info;
|
||||||
|
|
||||||
|
info = g_malloc0 (sizeof (SmsAuthInfo));
|
||||||
|
info->num1 = num1;
|
||||||
|
info->num2 = num2;
|
||||||
|
info->num3 = num3;
|
||||||
|
info->num4 = num4;
|
||||||
|
info->num5 = num5;
|
||||||
|
info->str = g_strdup (str);
|
||||||
|
|
||||||
|
/* Copy the hash table if we're given one */
|
||||||
|
if (hash) {
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
info->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free, destroy_gvalue);
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, hash);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
|
const char *str_key = (const char *) key;
|
||||||
|
GValue *src = (GValue *) value;
|
||||||
|
GValue *dst;
|
||||||
|
|
||||||
|
dst = g_slice_new0 (GValue);
|
||||||
|
g_value_init (dst, G_VALUE_TYPE (src));
|
||||||
|
g_hash_table_insert (info->hash, g_strdup (str_key), dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_delete_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise delete the SMS */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
async_call_not_supported (self, async_call_done, context);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
impl_gsm_modem_sms_delete (MMModemGsmSms *modem,
|
impl_gsm_modem_sms_delete (MMModemGsmSms *modem,
|
||||||
guint idx,
|
guint idx,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
async_call_not_supported (modem, async_call_done, context);
|
GError *error = NULL;
|
||||||
|
SmsAuthInfo *info;
|
||||||
|
|
||||||
|
info = sms_auth_info_new (idx, 0, 0, 0, 0, NULL, NULL);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to delete an SMS */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_delete_auth_cb,
|
||||||
|
info,
|
||||||
|
sms_auth_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_get_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise get the SMS */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
async_call_not_supported (self, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -142,9 +267,26 @@ impl_gsm_modem_sms_get (MMModemGsmSms *modem,
|
|||||||
guint idx,
|
guint idx,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
async_call_not_supported (modem, async_call_done, context);
|
GError *error = NULL;
|
||||||
|
SmsAuthInfo *info;
|
||||||
|
|
||||||
|
info = sms_auth_info_new (idx, 0, 0, 0, 0, NULL, NULL);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to get an SMS */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_get_auth_cb,
|
||||||
|
info,
|
||||||
|
sms_auth_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
impl_gsm_modem_sms_get_format (MMModemGsmSms *modem,
|
impl_gsm_modem_sms_get_format (MMModemGsmSms *modem,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
@@ -167,19 +309,103 @@ impl_gsm_modem_sms_get_smsc (MMModemGsmSms *modem,
|
|||||||
async_call_not_supported (modem, async_call_done, context);
|
async_call_not_supported (modem, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_set_smsc_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise set the SMS service center */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
async_call_not_supported (self, async_call_done, context);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
impl_gsm_modem_sms_set_smsc (MMModemGsmSms *modem,
|
impl_gsm_modem_sms_set_smsc (MMModemGsmSms *modem,
|
||||||
const char *smsc,
|
const char *smsc,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
async_call_not_supported (modem, async_call_done, context);
|
GError *error = NULL;
|
||||||
|
SmsAuthInfo *info;
|
||||||
|
|
||||||
|
info = sms_auth_info_new (0, 0, 0, 0, 0, smsc, NULL);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to set the SMS service center */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_set_smsc_auth_cb,
|
||||||
|
info,
|
||||||
|
sms_auth_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_list_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise list SMSs */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
async_call_not_supported (self, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
impl_gsm_modem_sms_list (MMModemGsmSms *modem,
|
impl_gsm_modem_sms_list (MMModemGsmSms *modem,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
async_call_not_supported (modem, async_call_done, context);
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to list SMSs */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_list_auth_cb,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_save_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise save the SMS */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
async_call_not_supported (self, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -187,7 +413,80 @@ impl_gsm_modem_sms_save (MMModemGsmSms *modem,
|
|||||||
GHashTable *properties,
|
GHashTable *properties,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
async_call_not_supported (modem, async_call_done, context);
|
GError *error = NULL;
|
||||||
|
SmsAuthInfo *info;
|
||||||
|
|
||||||
|
info = sms_auth_info_new (0, 0, 0, 0, 0, NULL, properties);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to save the SMS */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_save_auth_cb,
|
||||||
|
info,
|
||||||
|
sms_auth_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_send_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
SmsAuthInfo *info = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
GValue *value;
|
||||||
|
const char *number = NULL;
|
||||||
|
const char *text = NULL ;
|
||||||
|
const char *smsc = NULL;
|
||||||
|
guint validity = 0;
|
||||||
|
guint class = 0;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise delete the SMS */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
value = (GValue *) g_hash_table_lookup (info->hash, "number");
|
||||||
|
if (value)
|
||||||
|
number = g_value_get_string (value);
|
||||||
|
|
||||||
|
value = (GValue *) g_hash_table_lookup (info->hash, "text");
|
||||||
|
if (value)
|
||||||
|
text = g_value_get_string (value);
|
||||||
|
|
||||||
|
value = (GValue *) g_hash_table_lookup (info->hash, "smsc");
|
||||||
|
if (value)
|
||||||
|
smsc = g_value_get_string (value);
|
||||||
|
|
||||||
|
value = (GValue *) g_hash_table_lookup (info->hash, "validity");
|
||||||
|
if (value)
|
||||||
|
validity = g_value_get_uint (value);
|
||||||
|
|
||||||
|
value = (GValue *) g_hash_table_lookup (info->hash, "class");
|
||||||
|
if (value)
|
||||||
|
class = g_value_get_uint (value);
|
||||||
|
|
||||||
|
if (!number) {
|
||||||
|
error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Missing number");
|
||||||
|
} else if (!text) {
|
||||||
|
error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Missing message text");
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (error) {
|
||||||
|
async_call_done (MM_MODEM (self), error, context);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
mm_modem_gsm_sms_send (self, number, text, smsc, validity, class, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -195,46 +494,41 @@ impl_gsm_modem_sms_send (MMModemGsmSms *modem,
|
|||||||
GHashTable *properties,
|
GHashTable *properties,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
GValue *value;
|
|
||||||
const char *number = NULL;
|
|
||||||
const char *text = NULL ;
|
|
||||||
const char *smsc = NULL;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
guint validity = 0;
|
SmsAuthInfo *info;
|
||||||
guint class = 0;
|
|
||||||
|
|
||||||
value = (GValue *) g_hash_table_lookup (properties, "number");
|
info = sms_auth_info_new (0, 0, 0, 0, 0, NULL, properties);
|
||||||
if (value)
|
|
||||||
number = g_value_get_string (value);
|
|
||||||
|
|
||||||
value = (GValue *) g_hash_table_lookup (properties, "text");
|
/* Make sure the caller is authorized to send the PUK */
|
||||||
if (value)
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
text = g_value_get_string (value);
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_send_auth_cb,
|
||||||
|
info,
|
||||||
|
sms_auth_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
value = (GValue *) g_hash_table_lookup (properties, "smsc");
|
/*****************************************************************************/
|
||||||
if (value)
|
|
||||||
smsc = g_value_get_string (value);
|
|
||||||
|
|
||||||
value = (GValue *) g_hash_table_lookup (properties, "validity");
|
static void
|
||||||
if (value)
|
sms_send_from_storage_auth_cb (MMAuthRequest *req,
|
||||||
validity = g_value_get_uint (value);
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
value = (GValue *) g_hash_table_lookup (properties, "class");
|
/* Return any authorization error, otherwise delete the SMS */
|
||||||
if (value)
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
class = g_value_get_uint (value);
|
dbus_g_method_return_error (context, error);
|
||||||
|
|
||||||
if (!number)
|
|
||||||
error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
|
||||||
"Missing number");
|
|
||||||
else if (!text)
|
|
||||||
error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
|
|
||||||
"Missing message text");
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
async_call_done (MM_MODEM (modem), error, context);
|
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
} else
|
} else
|
||||||
mm_modem_gsm_sms_send (modem, number, text, smsc, validity, class, async_call_done, context);
|
async_call_not_supported (self, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -242,7 +536,41 @@ impl_gsm_modem_sms_send_from_storage (MMModemGsmSms *modem,
|
|||||||
guint idx,
|
guint idx,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
async_call_not_supported (modem, async_call_done, context);
|
GError *error = NULL;
|
||||||
|
SmsAuthInfo *info;
|
||||||
|
|
||||||
|
info = sms_auth_info_new (idx, 0, 0, 0, 0, NULL, NULL);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to send the PUK */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_send_from_storage_auth_cb,
|
||||||
|
info,
|
||||||
|
sms_auth_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
sms_set_indication_auth_cb (MMAuthRequest *req,
|
||||||
|
GObject *owner,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
/* Return any authorization error, otherwise delete the SMS */
|
||||||
|
if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
} else
|
||||||
|
async_call_not_supported (self, async_call_done, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -254,7 +582,22 @@ impl_gsm_modem_sms_set_indication (MMModemGsmSms *modem,
|
|||||||
guint bfr,
|
guint bfr,
|
||||||
DBusGMethodInvocation *context)
|
DBusGMethodInvocation *context)
|
||||||
{
|
{
|
||||||
async_call_not_supported (modem, async_call_done, context);
|
GError *error = NULL;
|
||||||
|
SmsAuthInfo *info;
|
||||||
|
|
||||||
|
info = sms_auth_info_new (mode, mt, bm, ds, bfr, NULL, NULL);
|
||||||
|
|
||||||
|
/* Make sure the caller is authorized to send the PUK */
|
||||||
|
if (!mm_modem_auth_request (MM_MODEM (modem),
|
||||||
|
MM_AUTHORIZATION_SMS,
|
||||||
|
context,
|
||||||
|
sms_set_indication_auth_cb,
|
||||||
|
info,
|
||||||
|
sms_auth_info_destroy,
|
||||||
|
&error)) {
|
||||||
|
dbus_g_method_return_error (context, error);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@@ -608,6 +608,54 @@ mm_modem_set_state (MMModem *self,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_modem_auth_request (MMModem *self,
|
||||||
|
const char *authorization,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
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 (context != 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,
|
||||||
|
context,
|
||||||
|
callback,
|
||||||
|
callback_data,
|
||||||
|
notify,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mm_modem_auth_finish (MMModem *self,
|
||||||
|
MMAuthRequest *req,
|
||||||
|
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 (req != NULL, FALSE);
|
||||||
|
|
||||||
|
g_return_val_if_fail (MM_MODEM_GET_INTERFACE (self)->auth_finish, FALSE);
|
||||||
|
success = MM_MODEM_GET_INTERFACE (self)->auth_finish (self, req, error);
|
||||||
|
|
||||||
|
/* If the request failed, the implementor *should* return an error */
|
||||||
|
if (!success && error)
|
||||||
|
g_warn_if_fail (*error != NULL);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mm_modem_init (gpointer g_iface)
|
mm_modem_init (gpointer g_iface)
|
||||||
{
|
{
|
||||||
|
@@ -18,8 +18,10 @@
|
|||||||
#define MM_MODEM_H
|
#define MM_MODEM_H
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
#include <dbus/dbus-glib-lowlevel.h>
|
||||||
|
|
||||||
#include "mm-port.h"
|
#include "mm-port.h"
|
||||||
|
#include "mm-auth-provider.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MM_MODEM_STATE_UNKNOWN = 0,
|
MM_MODEM_STATE_UNKNOWN = 0,
|
||||||
@@ -156,6 +158,21 @@ struct _MMModem {
|
|||||||
MMModemInfoFn callback,
|
MMModemInfoFn callback,
|
||||||
gpointer user_data);
|
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,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean (*auth_finish) (MMModem *self,
|
||||||
|
MMAuthRequest *req,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
/* Signals */
|
/* Signals */
|
||||||
void (*state_changed) (MMModem *self,
|
void (*state_changed) (MMModem *self,
|
||||||
MMModemState new_state,
|
MMModemState new_state,
|
||||||
@@ -217,5 +234,21 @@ void mm_modem_set_state (MMModem *self,
|
|||||||
|
|
||||||
GError *mm_modem_check_removed (MMModem *self, const GError *error);
|
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,
|
||||||
|
DBusGMethodInvocation *context,
|
||||||
|
MMAuthRequestCb callback,
|
||||||
|
gpointer callback_data,
|
||||||
|
GDestroyNotify notify,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean mm_modem_auth_finish (MMModem *self,
|
||||||
|
MMAuthRequest *req,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
#endif /* MM_MODEM_H */
|
#endif /* MM_MODEM_H */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user