All of lore.kernel.org
 help / color / mirror / Atom feed
* SIM PIN provisioning
@ 2017-02-22 15:30 Christophe Ronco
  2017-03-28 14:56 ` [PATCH 0/2] SIM PIN provisionning Christophe Ronco
  0 siblings, 1 reply; 4+ messages in thread
From: Christophe Ronco @ 2017-02-22 15:30 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1294 bytes --]

Hello,

I would like to be able to provision SIM PINs like what we did for GPRS 
context. In my project, I want a configuration file where SIM PINs will 
be written. When a new SIM appears, Ofono should read this file to get 
SIM PIN if needed.


To be a bit more generic than that, I have written something based on 
provision plugins done for gprs context provisioning.

When Ofono (src/sim.c) discovers that a SIM needs a PIN code, it will 
call all SIM password provision plugins registered to try to get current 
SIM needed password. If it gets a password, it will try to enter it 
without waiting for end-user to call EnterPin method. Of course, this is 
tried only once to avoid blocking SIM cards.

I have also written a SIM password plugin based on a key-value file 
similar to what has been done in file-provision.c plugin. This is what I 
need in my project, others can write other plugins if needed.

Please find attached the patch with these modifications (all of them).

Let me know if you think this feature could be nice for upstream, I'll 
send a broken down version of the patch in this case (I assume, I should 
separate plugin implementation from introduction of this type of plugins 
in Ofono src directory).


Best Regards,


Christophe


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-add-sim-provisioning.patch --]
[-- Type: text/x-patch, Size: 11779 bytes --]

>From 24bb0fe4af1b05251f05a8442361255f7cd9ef03 Mon Sep 17 00:00:00 2001
From: Christophe Ronco <c.ronco@kerlink.fr>
Date: Wed, 22 Feb 2017 14:20:32 +0100
Subject: [PATCH] add sim provisioning

---
 Makefile.am                    |   9 ++-
 include/sim-passwd-provision.h |  41 +++++++++++
 plugins/sim-file-provision.c   | 156 +++++++++++++++++++++++++++++++++++++++++
 src/ofono.h                    |   5 ++
 src/sim-password-provision.c   |  80 +++++++++++++++++++++
 src/sim.c                      |  35 +++++++++
 6 files changed, 324 insertions(+), 2 deletions(-)
 create mode 100644 include/sim-passwd-provision.h
 create mode 100644 plugins/sim-file-provision.c
 create mode 100644 src/sim-password-provision.c

diff --git a/Makefile.am b/Makefile.am
index d9f9b086..fab55226 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,7 +22,8 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
 			include/private-network.h include/cdma-netreg.h \
 			include/cdma-provision.h include/handsfree.h \
 			include/handsfree-audio.h include/siri.h \
-			include/netmon.h include/lte.h
+			include/netmon.h include/lte.h \
+			include/sim-passwd-provision.h
 
 nodist_pkginclude_HEADERS = include/version.h
 
@@ -559,6 +560,10 @@ builtin_sources += plugins/cdma-provision.c
 builtin_modules += file_provision
 builtin_sources += plugins/file-provision.c
 
+builtin_modules += sim_file_provision
+builtin_sources += plugins/sim-file-provision.c
+
+
 endif
 
 if MAINTAINER_MODE
@@ -621,7 +626,7 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
 			src/cdma-provision.c src/handsfree.c \
 			src/handsfree-audio.c src/bluetooth.h \
 			src/hfp.h src/siri.c \
-			src/netmon.c src/lte.c
+			src/netmon.c src/lte.c src/sim-password-provision.c
 
 src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
 			@GLIB_LIBS@ @DBUS_LIBS@ -ldl
diff --git a/include/sim-passwd-provision.h b/include/sim-passwd-provision.h
new file mode 100644
index 00000000..62ceae31
--- /dev/null
+++ b/include/sim-passwd-provision.h
@@ -0,0 +1,41 @@
+/*
+ *
+ *  oFono - Open Telephony stack for Linux
+ *
+ *  Copyright (C) 2017  Kerlink SA.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __OFONO_SIM_PASSWD_PROVISION_H
+#define __OFONO_SIM_PASSWD_PROVISION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ofono_sim_passwd_provision_driver {
+	const char *name;
+	int priority;
+	int (*get_password)(const char *iccid,
+		enum ofono_sim_password_type password_type, char **pin);
+};
+
+int ofono_sim_password_provision_driver_register(
+		const struct ofono_sim_passwd_provision_driver *driver);
+void ofono_sim_password_provision_driver_unregister(
+		const struct ofono_sim_passwd_provision_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OFONO_SIM_PASSWD_PROVISION_H */
diff --git a/plugins/sim-file-provision.c b/plugins/sim-file-provision.c
new file mode 100644
index 00000000..16e63d65
--- /dev/null
+++ b/plugins/sim-file-provision.c
@@ -0,0 +1,156 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2017  Kerlink SA.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <glib.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/modem.h>
+#include <ofono/log.h>
+#include <ofono/plugin.h>
+#include <ofono/sim.h>
+#include <ofono/sim-passwd-provision.h>
+
+#define CONFIG_FILE STORAGEDIR "/provisioning"
+
+struct passwd_type_dict {
+	enum ofono_sim_password_type passwd_enum;
+	const char *passwd_string;
+};
+
+static const struct passwd_type_dict passwd_dictionary[] = {
+	{ OFONO_SIM_PASSWORD_SIM_PIN, "pin" },
+	{ OFONO_SIM_PASSWORD_SIM_PUK, "puk" },
+	{ OFONO_SIM_PASSWORD_PHSIM_PIN, "phone" },
+	{ OFONO_SIM_PASSWORD_PHFSIM_PIN, "firstphone" },
+	{ OFONO_SIM_PASSWORD_PHFSIM_PUK, "firstphonepuk" },
+	{ OFONO_SIM_PASSWORD_PHNET_PIN, "network" },
+	{ OFONO_SIM_PASSWORD_PHNET_PUK, "networkpuk" },
+	{ OFONO_SIM_PASSWORD_PHNETSUB_PIN, "netsub" },
+	{ OFONO_SIM_PASSWORD_PHNETSUB_PUK, "netsubpuk" },
+	{ OFONO_SIM_PASSWORD_PHSP_PIN, "service" },
+	{ OFONO_SIM_PASSWORD_PHSP_PUK, "servicepuk" },
+	{ OFONO_SIM_PASSWORD_PHCORP_PIN, "corp" },
+	{ OFONO_SIM_PASSWORD_PHCORP_PUK, "corppuk" }
+};
+
+static const char *get_passwd_type_name(
+				enum ofono_sim_password_type passwd_enum)
+{
+	int i;
+	int passwd_dict_size;
+
+	passwd_dict_size = sizeof(passwd_dictionary) /
+					sizeof(struct passwd_type_dict);
+
+	for (i = 0; i < passwd_dict_size; i++) {
+		if (passwd_enum == passwd_dictionary[i].passwd_enum)
+			return passwd_dictionary[i].passwd_string;
+	}
+
+	return NULL;
+}
+
+static int get_password(const char *iccid,
+				enum ofono_sim_password_type passwd_type,
+				char **password)
+{
+	int result = -ENOENT;
+	const char *passwd_type_name;
+	GKeyFile *key_file = NULL;
+	char *setting_group = NULL;
+	char *value = NULL;
+
+	passwd_type_name = get_passwd_type_name(passwd_type);
+
+	if (passwd_type_name == NULL) {
+		DBG("unknown type %d", (int)passwd_type);
+		goto end;
+	}
+
+	DBG("Finding password for iccid %s, password type %s",
+						iccid, passwd_type_name);
+	key_file = g_key_file_new();
+
+	if (!g_key_file_load_from_file(key_file, CONFIG_FILE, 0, NULL))
+		goto end;
+
+	setting_group = g_try_malloc(strlen("sim:") + strlen(iccid) + 1);
+	if (setting_group == NULL) {
+		result = -ENOMEM;
+		goto end;
+	}
+
+	/* try with iccid */
+	sprintf(setting_group, "sim:%s", iccid);
+	value = g_key_file_get_string(key_file, setting_group,
+						passwd_type_name, NULL);
+
+	if (value != NULL)
+		goto end;
+
+	/* try default passwd */
+	value = g_key_file_get_string(key_file, "sim",
+						passwd_type_name, NULL);
+
+end:
+	if (key_file != NULL)
+		g_key_file_free(key_file);
+
+	if (setting_group != NULL)
+		g_free(setting_group);
+
+	if (value != NULL) {
+		DBG("Found. Password:%s", value);
+		*password = value;
+		result = 0;
+	} else {
+		DBG("Not found. Result:%d", result);
+	}
+
+	return result;
+}
+
+static struct ofono_sim_passwd_provision_driver provision_driver = {
+	.name		= "PIN provisioning",
+	.priority	= OFONO_PLUGIN_PRIORITY_HIGH,
+	.get_password	= get_password,
+};
+
+static int sim_password_provision_init(void)
+{
+	return ofono_sim_password_provision_driver_register(
+						&provision_driver);
+}
+
+static void sim_password_provision_exit(void)
+{
+	ofono_sim_password_provision_driver_unregister(
+						&provision_driver);
+}
+
+OFONO_PLUGIN_DEFINE(sim_file_provision, "SIM File Provisioning Plugin",
+			VERSION, OFONO_PLUGIN_PRIORITY_HIGH,
+			sim_password_provision_init,
+			sim_password_provision_exit)
diff --git a/src/ofono.h b/src/ofono.h
index a797b7ff..d27fe989 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -506,6 +506,11 @@ void __ofono_gprs_provision_free_settings(
 				struct ofono_gprs_provision_data *settings,
 				int count);
 
+#include <ofono/sim-passwd-provision.h>
+ofono_bool_t __ofono_sim_provision_get_password(const char *iccid,
+				enum ofono_sim_password_type password_type,
+				char **password);
+
 #include <ofono/emulator.h>
 
 enum ofono_emulator_slc_condition {
diff --git a/src/sim-password-provision.c b/src/sim-password-provision.c
new file mode 100644
index 00000000..cd295b1e
--- /dev/null
+++ b/src/sim-password-provision.c
@@ -0,0 +1,80 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 201  Kerlink SA.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include "ofono.h"
+
+static GSList *g_drivers = NULL;
+
+ofono_bool_t __ofono_sim_provision_get_password(const char *iccid,
+				enum ofono_sim_password_type password_type,
+				char **password)
+{
+	GSList *d;
+
+	if (iccid == NULL || strlen(iccid) == 0)
+		return FALSE;
+
+	for (d = g_drivers; d != NULL; d = d->next) {
+		const struct ofono_sim_passwd_provision_driver *driver =
+									d->data;
+
+		if (driver->get_password == NULL)
+			continue;
+
+		DBG("Calling sim password provisioning plugin '%s'",
+								driver->name);
+
+		if (driver->get_password(iccid, password_type, password) < 0)
+			continue;
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gint compare_priority(gconstpointer a, gconstpointer b)
+{
+	const struct ofono_sim_passwd_provision_driver *plugin1 = a;
+	const struct ofono_sim_passwd_provision_driver *plugin2 = b;
+
+	return plugin2->priority - plugin1->priority;
+}
+
+int ofono_sim_password_provision_driver_register(
+		const struct ofono_sim_passwd_provision_driver *driver)
+{
+	DBG("driver: %p name: %s", driver, driver->name);
+
+	g_drivers = g_slist_insert_sorted(g_drivers, (void *) driver,
+							compare_priority);
+	return 0;
+}
+
+void ofono_sim_password_provision_driver_unregister(
+		const struct ofono_sim_passwd_provision_driver *driver)
+{
+	DBG("driver: %p name: %s", driver, driver->name);
+
+	g_drivers = g_slist_remove(g_drivers, driver);
+}
diff --git a/src/sim.c b/src/sim.c
index ac5b6fde..7cb61991 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -61,6 +61,7 @@ struct ofono_sim {
 
 	enum ofono_sim_password_type pin_type;
 	gboolean locked_pins[OFONO_SIM_PASSWORD_SIM_PUK]; /* Number of PINs */
+	gboolean tried_provisionned_pins;
 
 	int pin_retries[OFONO_SIM_PASSWORD_INVALID];
 
@@ -2828,6 +2829,38 @@ ofono_bool_t ofono_sim_remove_spn_watch(struct ofono_sim *sim, unsigned int *id)
 	return ret;
 }
 
+static void sim_auto_enter_pin_cb(const struct ofono_error *error,
+								void *data)
+{
+	struct ofono_sim *sim = data;
+
+	__ofono_sim_recheck_pin(sim);
+}
+
+static void provision_password(struct ofono_sim *sim)
+{
+	char *password;
+
+	if (__ofono_sim_provision_get_password(sim->iccid, sim->pin_type,
+							&password) == FALSE) {
+		DBG("SIM password provisioning failed");
+		return;
+	}
+
+	/* try to enter password */
+	if (password_is_pin(sim->pin_type) == FALSE)
+		goto end;
+
+	if (!__ofono_is_valid_sim_pin(password, sim->pin_type))
+		goto end;
+
+	sim->tried_provisionned_pins = TRUE;
+	sim->driver->send_passwd(sim, password, sim_auto_enter_pin_cb, sim);
+
+end:
+	g_free(password);
+}
+
 static void sim_pin_query_cb(const struct ofono_error *error,
 				enum ofono_sim_password_type pin_type,
 				void *data)
@@ -2908,6 +2941,8 @@ static void sim_pin_query_cb(const struct ofono_error *error,
 		sim_initialize_after_pin(sim);
 		break;
 	default:
+		if (!sim->tried_provisionned_pins)
+			provision_password(sim);
 		break;
 	}
 }
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 0/2] SIM PIN provisionning
  2017-02-22 15:30 SIM PIN provisioning Christophe Ronco
@ 2017-03-28 14:56 ` Christophe Ronco
  2017-03-28 14:56   ` [PATCH 1/2] provision: add " Christophe Ronco
  2017-03-28 14:56   ` [PATCH 2/2] provision: add SIM PIN provisionning plugin Christophe Ronco
  0 siblings, 2 replies; 4+ messages in thread
From: Christophe Ronco @ 2017-03-28 14:56 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1185 bytes --]

The idea is to be able to "automatically" enter SIM PIN.
Automatically means without end-user action on DBUS.

When Ofono (src/sim.c) discovers that a SIM needs a PIN code,
it will call all SIM password provision plugins registered to try
to get current SIM needed password. 
If it gets a password, it will try to enter it without waiting for
end-user to call EnterPin method. Of course, this is tried only once to
avoid blocking SIM cards.

I have also written a SIM password plugin based on a key-value file.

Christophe Ronco (2):
  provision: add SIM PIN provisionning
  provision: add SIM PIN provisionning plugin

 Makefile.am                    |   9 ++-
 include/sim-passwd-provision.h |  41 +++++++++++
 plugins/sim-file-provision.c   | 156 +++++++++++++++++++++++++++++++++++++++++
 src/ofono.h                    |   5 ++
 src/sim-password-provision.c   |  80 +++++++++++++++++++++
 src/sim.c                      |  35 +++++++++
 6 files changed, 324 insertions(+), 2 deletions(-)
 create mode 100644 include/sim-passwd-provision.h
 create mode 100644 plugins/sim-file-provision.c
 create mode 100644 src/sim-password-provision.c

-- 
2.11.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] provision: add SIM PIN provisionning
  2017-03-28 14:56 ` [PATCH 0/2] SIM PIN provisionning Christophe Ronco
@ 2017-03-28 14:56   ` Christophe Ronco
  2017-03-28 14:56   ` [PATCH 2/2] provision: add SIM PIN provisionning plugin Christophe Ronco
  1 sibling, 0 replies; 4+ messages in thread
From: Christophe Ronco @ 2017-03-28 14:56 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 7491 bytes --]

Add framework to be able to have provisoning plugins for SIM codes
(PIN and others).
ICCID is given to provisioning plugin and it should return SIM PIN
if it knows this code.
If a PIN code is returned by a provisionning plugin, it will be tried
(one and only one time) on modem.
---
 Makefile.am                    |  5 +--
 include/sim-passwd-provision.h | 41 ++++++++++++++++++++++
 src/ofono.h                    |  5 +++
 src/sim-password-provision.c   | 80 ++++++++++++++++++++++++++++++++++++++++++
 src/sim.c                      | 35 ++++++++++++++++++
 5 files changed, 164 insertions(+), 2 deletions(-)
 create mode 100644 include/sim-passwd-provision.h
 create mode 100644 src/sim-password-provision.c

diff --git a/Makefile.am b/Makefile.am
index d9f9b086..e68a3323 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,7 +22,8 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
 			include/private-network.h include/cdma-netreg.h \
 			include/cdma-provision.h include/handsfree.h \
 			include/handsfree-audio.h include/siri.h \
-			include/netmon.h include/lte.h
+			include/netmon.h include/lte.h \
+			include/sim-passwd-provision.h
 
 nodist_pkginclude_HEADERS = include/version.h
 
@@ -621,7 +622,7 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
 			src/cdma-provision.c src/handsfree.c \
 			src/handsfree-audio.c src/bluetooth.h \
 			src/hfp.h src/siri.c \
-			src/netmon.c src/lte.c
+			src/netmon.c src/lte.c src/sim-password-provision.c
 
 src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) \
 			@GLIB_LIBS@ @DBUS_LIBS@ -ldl
diff --git a/include/sim-passwd-provision.h b/include/sim-passwd-provision.h
new file mode 100644
index 00000000..62ceae31
--- /dev/null
+++ b/include/sim-passwd-provision.h
@@ -0,0 +1,41 @@
+/*
+ *
+ *  oFono - Open Telephony stack for Linux
+ *
+ *  Copyright (C) 2017  Kerlink SA.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+#ifndef __OFONO_SIM_PASSWD_PROVISION_H
+#define __OFONO_SIM_PASSWD_PROVISION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ofono_sim_passwd_provision_driver {
+	const char *name;
+	int priority;
+	int (*get_password)(const char *iccid,
+		enum ofono_sim_password_type password_type, char **pin);
+};
+
+int ofono_sim_password_provision_driver_register(
+		const struct ofono_sim_passwd_provision_driver *driver);
+void ofono_sim_password_provision_driver_unregister(
+		const struct ofono_sim_passwd_provision_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OFONO_SIM_PASSWD_PROVISION_H */
diff --git a/src/ofono.h b/src/ofono.h
index a797b7ff..d27fe989 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -506,6 +506,11 @@ void __ofono_gprs_provision_free_settings(
 				struct ofono_gprs_provision_data *settings,
 				int count);
 
+#include <ofono/sim-passwd-provision.h>
+ofono_bool_t __ofono_sim_provision_get_password(const char *iccid,
+				enum ofono_sim_password_type password_type,
+				char **password);
+
 #include <ofono/emulator.h>
 
 enum ofono_emulator_slc_condition {
diff --git a/src/sim-password-provision.c b/src/sim-password-provision.c
new file mode 100644
index 00000000..cd295b1e
--- /dev/null
+++ b/src/sim-password-provision.c
@@ -0,0 +1,80 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 201  Kerlink SA.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include "ofono.h"
+
+static GSList *g_drivers = NULL;
+
+ofono_bool_t __ofono_sim_provision_get_password(const char *iccid,
+				enum ofono_sim_password_type password_type,
+				char **password)
+{
+	GSList *d;
+
+	if (iccid == NULL || strlen(iccid) == 0)
+		return FALSE;
+
+	for (d = g_drivers; d != NULL; d = d->next) {
+		const struct ofono_sim_passwd_provision_driver *driver =
+									d->data;
+
+		if (driver->get_password == NULL)
+			continue;
+
+		DBG("Calling sim password provisioning plugin '%s'",
+								driver->name);
+
+		if (driver->get_password(iccid, password_type, password) < 0)
+			continue;
+
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gint compare_priority(gconstpointer a, gconstpointer b)
+{
+	const struct ofono_sim_passwd_provision_driver *plugin1 = a;
+	const struct ofono_sim_passwd_provision_driver *plugin2 = b;
+
+	return plugin2->priority - plugin1->priority;
+}
+
+int ofono_sim_password_provision_driver_register(
+		const struct ofono_sim_passwd_provision_driver *driver)
+{
+	DBG("driver: %p name: %s", driver, driver->name);
+
+	g_drivers = g_slist_insert_sorted(g_drivers, (void *) driver,
+							compare_priority);
+	return 0;
+}
+
+void ofono_sim_password_provision_driver_unregister(
+		const struct ofono_sim_passwd_provision_driver *driver)
+{
+	DBG("driver: %p name: %s", driver, driver->name);
+
+	g_drivers = g_slist_remove(g_drivers, driver);
+}
diff --git a/src/sim.c b/src/sim.c
index ac5b6fde..7cb61991 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -61,6 +61,7 @@ struct ofono_sim {
 
 	enum ofono_sim_password_type pin_type;
 	gboolean locked_pins[OFONO_SIM_PASSWORD_SIM_PUK]; /* Number of PINs */
+	gboolean tried_provisionned_pins;
 
 	int pin_retries[OFONO_SIM_PASSWORD_INVALID];
 
@@ -2828,6 +2829,38 @@ ofono_bool_t ofono_sim_remove_spn_watch(struct ofono_sim *sim, unsigned int *id)
 	return ret;
 }
 
+static void sim_auto_enter_pin_cb(const struct ofono_error *error,
+								void *data)
+{
+	struct ofono_sim *sim = data;
+
+	__ofono_sim_recheck_pin(sim);
+}
+
+static void provision_password(struct ofono_sim *sim)
+{
+	char *password;
+
+	if (__ofono_sim_provision_get_password(sim->iccid, sim->pin_type,
+							&password) == FALSE) {
+		DBG("SIM password provisioning failed");
+		return;
+	}
+
+	/* try to enter password */
+	if (password_is_pin(sim->pin_type) == FALSE)
+		goto end;
+
+	if (!__ofono_is_valid_sim_pin(password, sim->pin_type))
+		goto end;
+
+	sim->tried_provisionned_pins = TRUE;
+	sim->driver->send_passwd(sim, password, sim_auto_enter_pin_cb, sim);
+
+end:
+	g_free(password);
+}
+
 static void sim_pin_query_cb(const struct ofono_error *error,
 				enum ofono_sim_password_type pin_type,
 				void *data)
@@ -2908,6 +2941,8 @@ static void sim_pin_query_cb(const struct ofono_error *error,
 		sim_initialize_after_pin(sim);
 		break;
 	default:
+		if (!sim->tried_provisionned_pins)
+			provision_password(sim);
 		break;
 	}
 }
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] provision: add SIM PIN provisionning plugin
  2017-03-28 14:56 ` [PATCH 0/2] SIM PIN provisionning Christophe Ronco
  2017-03-28 14:56   ` [PATCH 1/2] provision: add " Christophe Ronco
@ 2017-03-28 14:56   ` Christophe Ronco
  1 sibling, 0 replies; 4+ messages in thread
From: Christophe Ronco @ 2017-03-28 14:56 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 5047 bytes --]

---
 Makefile.am                  |   4 ++
 plugins/sim-file-provision.c | 156 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 160 insertions(+)
 create mode 100644 plugins/sim-file-provision.c

diff --git a/Makefile.am b/Makefile.am
index e68a3323..fab55226 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -560,6 +560,10 @@ builtin_sources += plugins/cdma-provision.c
 builtin_modules += file_provision
 builtin_sources += plugins/file-provision.c
 
+builtin_modules += sim_file_provision
+builtin_sources += plugins/sim-file-provision.c
+
+
 endif
 
 if MAINTAINER_MODE
diff --git a/plugins/sim-file-provision.c b/plugins/sim-file-provision.c
new file mode 100644
index 00000000..16e63d65
--- /dev/null
+++ b/plugins/sim-file-provision.c
@@ -0,0 +1,156 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2017  Kerlink SA.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <glib.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/modem.h>
+#include <ofono/log.h>
+#include <ofono/plugin.h>
+#include <ofono/sim.h>
+#include <ofono/sim-passwd-provision.h>
+
+#define CONFIG_FILE STORAGEDIR "/provisioning"
+
+struct passwd_type_dict {
+	enum ofono_sim_password_type passwd_enum;
+	const char *passwd_string;
+};
+
+static const struct passwd_type_dict passwd_dictionary[] = {
+	{ OFONO_SIM_PASSWORD_SIM_PIN, "pin" },
+	{ OFONO_SIM_PASSWORD_SIM_PUK, "puk" },
+	{ OFONO_SIM_PASSWORD_PHSIM_PIN, "phone" },
+	{ OFONO_SIM_PASSWORD_PHFSIM_PIN, "firstphone" },
+	{ OFONO_SIM_PASSWORD_PHFSIM_PUK, "firstphonepuk" },
+	{ OFONO_SIM_PASSWORD_PHNET_PIN, "network" },
+	{ OFONO_SIM_PASSWORD_PHNET_PUK, "networkpuk" },
+	{ OFONO_SIM_PASSWORD_PHNETSUB_PIN, "netsub" },
+	{ OFONO_SIM_PASSWORD_PHNETSUB_PUK, "netsubpuk" },
+	{ OFONO_SIM_PASSWORD_PHSP_PIN, "service" },
+	{ OFONO_SIM_PASSWORD_PHSP_PUK, "servicepuk" },
+	{ OFONO_SIM_PASSWORD_PHCORP_PIN, "corp" },
+	{ OFONO_SIM_PASSWORD_PHCORP_PUK, "corppuk" }
+};
+
+static const char *get_passwd_type_name(
+				enum ofono_sim_password_type passwd_enum)
+{
+	int i;
+	int passwd_dict_size;
+
+	passwd_dict_size = sizeof(passwd_dictionary) /
+					sizeof(struct passwd_type_dict);
+
+	for (i = 0; i < passwd_dict_size; i++) {
+		if (passwd_enum == passwd_dictionary[i].passwd_enum)
+			return passwd_dictionary[i].passwd_string;
+	}
+
+	return NULL;
+}
+
+static int get_password(const char *iccid,
+				enum ofono_sim_password_type passwd_type,
+				char **password)
+{
+	int result = -ENOENT;
+	const char *passwd_type_name;
+	GKeyFile *key_file = NULL;
+	char *setting_group = NULL;
+	char *value = NULL;
+
+	passwd_type_name = get_passwd_type_name(passwd_type);
+
+	if (passwd_type_name == NULL) {
+		DBG("unknown type %d", (int)passwd_type);
+		goto end;
+	}
+
+	DBG("Finding password for iccid %s, password type %s",
+						iccid, passwd_type_name);
+	key_file = g_key_file_new();
+
+	if (!g_key_file_load_from_file(key_file, CONFIG_FILE, 0, NULL))
+		goto end;
+
+	setting_group = g_try_malloc(strlen("sim:") + strlen(iccid) + 1);
+	if (setting_group == NULL) {
+		result = -ENOMEM;
+		goto end;
+	}
+
+	/* try with iccid */
+	sprintf(setting_group, "sim:%s", iccid);
+	value = g_key_file_get_string(key_file, setting_group,
+						passwd_type_name, NULL);
+
+	if (value != NULL)
+		goto end;
+
+	/* try default passwd */
+	value = g_key_file_get_string(key_file, "sim",
+						passwd_type_name, NULL);
+
+end:
+	if (key_file != NULL)
+		g_key_file_free(key_file);
+
+	if (setting_group != NULL)
+		g_free(setting_group);
+
+	if (value != NULL) {
+		DBG("Found. Password:%s", value);
+		*password = value;
+		result = 0;
+	} else {
+		DBG("Not found. Result:%d", result);
+	}
+
+	return result;
+}
+
+static struct ofono_sim_passwd_provision_driver provision_driver = {
+	.name		= "PIN provisioning",
+	.priority	= OFONO_PLUGIN_PRIORITY_HIGH,
+	.get_password	= get_password,
+};
+
+static int sim_password_provision_init(void)
+{
+	return ofono_sim_password_provision_driver_register(
+						&provision_driver);
+}
+
+static void sim_password_provision_exit(void)
+{
+	ofono_sim_password_provision_driver_unregister(
+						&provision_driver);
+}
+
+OFONO_PLUGIN_DEFINE(sim_file_provision, "SIM File Provisioning Plugin",
+			VERSION, OFONO_PLUGIN_PRIORITY_HIGH,
+			sim_password_provision_init,
+			sim_password_provision_exit)
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-03-28 14:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-22 15:30 SIM PIN provisioning Christophe Ronco
2017-03-28 14:56 ` [PATCH 0/2] SIM PIN provisionning Christophe Ronco
2017-03-28 14:56   ` [PATCH 1/2] provision: add " Christophe Ronco
2017-03-28 14:56   ` [PATCH 2/2] provision: add SIM PIN provisionning plugin Christophe Ronco

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.