Send connman mailing list submissions to
[email protected]
To subscribe or unsubscribe via email, send a message with subject or
body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."
Today's Topics:
1. [PATCH v3 6/8] openconnect: Use interactive mode when input to stdin is
required
(Jussi Laakkonen)
2. Re: [PATCH v3 6/8] openconnect: Use interactive mode when input to stdin
is required
(David Woodhouse)
----------------------------------------------------------------------
Date: Wed, 9 Oct 2019 11:34:01 +0300
From: Jussi Laakkonen <[email protected]>
Subject: [PATCH v3 6/8] openconnect: Use interactive mode when input
to stdin is required
To: [email protected]
Message-ID: <[email protected]>
Disable syslog (--syslog) and use interactive mode when OpenConnect
requires input from user. This is the case when PKCS file is encrypted
and pass phrase is requested. Changed also to prompt for the PKCS
password only when needed, instead of having it as mandatory for the
pkcs authentication method. Also, in case self signed certificates are
allowed the answer needs to be written to OpenConnect, thus, interactive
mode is required.
Since the request for PKCS file pass phrase is sent to stderr without
terminating newline character it is imperative to implement additional
way of reading the content. The request for PKCS pass phrase is read
byte by byte in interactive mode to support both encrypted and
unencrypted PKCS#8, and to keep support for PKCS#12. The pass phrase is
queried from VPN agent if needed and in case of error (decryption failed
is regarded as invalid pass phrase) connection is terminated.
Using the interactive mode also fixes the issue of previous commit that
self signed certificate acceptance ("yes") couldn't have been written to
stdin of OpenConnect process. This is because in non-interactive mode
(--non-inter) OpenConnect quits if the certificate is self signed and
server SHA1 fingerprint is not set with --servercert. With these changes
OpenConnect is started in interactive mode if self signed certificates
are allowed and there is no OpenConnect.ServerCert set. Otherwise,
non-interactive mode is used.
Set both the IO channels to have no encoding (rely on content as ASCII).
---
Changes since V3 (actually V2, but previous version should have been omitted):
* Update commit message and subject to be consistent with content.
* Removed PKCS#12 -> PKCS changes from this commit (merged with prev.)
vpn/plugins/openconnect.c | 305 ++++++++++++++++++++++++++++++++------
1 file changed, 256 insertions(+), 49 deletions(-)
diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c
index 6303ba34..a92b28c5 100644
--- a/vpn/plugins/openconnect.c
+++ b/vpn/plugins/openconnect.c
@@ -48,6 +48,7 @@
#include "vpn.h"
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+#define OC_MAX_READBUF_LEN 128
enum opt_type {
OPT_STRING = 0,
@@ -103,6 +104,7 @@ struct oc_private_data {
GIOChannel *out_ch;
GIOChannel *err_ch;
enum oc_connect_type connect_type;
+ bool interactive;
};
static bool is_valid_protocol(const char* protocol)
@@ -489,6 +491,82 @@ static void clear_provider_credentials(struct vpn_provider
*provider)
}
}
+typedef void (* request_input_reply_cb_t) (DBusMessage *reply,
+ void *user_data);
+
+static int request_input_credentials(struct oc_private_data *data,
+ request_input_reply_cb_t cb);
+
+
+static void request_input_pkcs_reply(DBusMessage *reply, void *user_data)
+{
+ struct oc_private_data *data = user_data;
+ const char *password = NULL;
+ const char *key;
+ DBusMessageIter iter, dict;
+ int err;
+
+ DBG("provider %p", data->provider);
+
+ if (!reply)
+ goto err;
+
+ err = vpn_agent_check_and_process_reply_error(reply, data->provider,
+ data->task, data->cb, data->user_data);
+ if (err) {
+ /* Ensure cb is called only once */
+ data->cb = NULL;
+ data->user_data = NULL;
+ goto err;
+ }
+
+ if (!vpn_agent_check_reply_has_dict(reply))
+ goto err;
+
+ dbus_message_iter_init(reply, &iter);
+ dbus_message_iter_recurse(&iter, &dict);
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ break;
+
+ dbus_message_iter_get_basic(&entry, &key);
+
+ if (g_str_equal(key, "OpenConnect.PKCSPassword")) {
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry)
+ != DBUS_TYPE_VARIANT)
+ break;
+ dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value)
+ != DBUS_TYPE_STRING)
+ break;
+ dbus_message_iter_get_basic(&value, &password);
+ vpn_provider_set_string_hide_value(data->provider, key,
+ password);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ if (data->connect_type != OC_CONNECT_PKCS || !password)
+ goto err;
+
+ if (write_data(data->fd_in, password) != 0) {
+ connman_error("openconnect failed to take PKCS pass phrase on"
+ " stdin");
+ goto err;
+ }
+
+ clear_provider_credentials(data->provider);
+
+ return;
+err:
+ oc_connect_done(data, EACCES);
+}
+
static gboolean io_channel_err_cb(GIOChannel *source, GIOCondition condition,
gpointer user_data)
{
@@ -513,7 +591,18 @@ static gboolean io_channel_err_cb(GIOChannel *source,
GIOCondition condition,
"Failed to open HTTPS connection to",
NULL
};
- const char *pkcs_failure = "Failed to decrypt PKCS";
+ /* Handle both PKCS#12 and PKCS#8 failures */
+ const char *pkcs_failures[] = {
+ "Failed to decrypt PKCS#12 certificate file",
+ "Failed to decrypt PKCS#8 certificate file",
+ NULL
+ };
+ /* Handle both PKCS#12 and PKCS#8 requests */
+ const char *pkcs_requests[] = {
+ "Enter PKCS#12 pass phrase",
+ "Enter PKCS#8 pass phrase",
+ NULL
+ };
const char *server_key_hash = " --servercert";
char *str;
bool close = false;
@@ -527,14 +616,60 @@ static gboolean io_channel_err_cb(GIOChannel *source,
GIOCondition condition,
if (source && data->err_ch != source)
return G_SOURCE_REMOVE;
- if ((condition & G_IO_IN) &&
- g_io_channel_read_line(source, &str, NULL, NULL, NULL) ==
- G_IO_STATUS_NORMAL) {
- str[strlen(str) - 1] = '\0';
+ if ((condition & G_IO_IN)) {
+ gsize len;
+ int pos;
+
+ if (!data->interactive) {
+ if (g_io_channel_read_line(source, &str, &len, NULL,
+ NULL) != G_IO_STATUS_NORMAL)
+ err = EIO;
+ else
+ str[len - 1] = '\0';
+ } else {
+ GIOStatus status;
+ str = g_try_new0(char, OC_MAX_READBUF_LEN);
+ if (!str)
+ return G_SOURCE_REMOVE;
+
+ for (pos = 0; pos < OC_MAX_READBUF_LEN - 1 ; ++pos) {
+ status = g_io_channel_read_chars(source,
+ str+pos, 1, &len, NULL);
+
+ if (status == G_IO_STATUS_EOF) {
+ break;
+ } else if (status != G_IO_STATUS_NORMAL) {
+ err = EIO;
+ break;
+ }
+
+ /* Ignore control chars and digits at start */
+ if (!pos && (g_ascii_iscntrl(str[pos]) ||
+ g_ascii_isdigit(str[pos])))
+ --pos;
+
+ /* Read zero length or no more to read */
+ if (!len || g_io_channel_get_buffer_condition(
+ source) != G_IO_IN ||
+ str[pos] == '\n')
+ break;
+ }
+
+ /*
+ * When self signed certificates are allowed and server
+ * SHA1 fingerprint is printed to stderr there is a
+ * newline char at the end of SHA1 fingerprint.
+ */
+ if (str[pos] == '\n')
+ str[pos] = '\0';
+ }
connman_info("openconnect: %s", str);
- if (g_str_has_prefix(str, server_key_hash)) {
+ if (err || !str || !*str) {
+ DBG("error reading from openconnect");
+ } else if (g_str_has_prefix(str, server_key_hash)) {
+ const char *fingerprint;
int position;
bool allow_self_signed;
@@ -545,21 +680,23 @@ static gboolean io_channel_err_cb(GIOChannel *source,
GIOCondition condition,
if (allow_self_signed) {
position = strlen(server_key_hash) + 1;
+ fingerprint = g_strstrip(str + position);
connman_info("Set server key hash: \"%s\"",
- str + position);
+ fingerprint);
vpn_provider_set_string(data->provider,
"OpenConnect.ServerCert",
- str + position);
+ fingerprint);
/*
* OpenConnect waits for "yes" or "no" as
* response to certificate acceptance request.
*/
if (write_data(data->fd_in, "yes") != 0)
- connman_error("cannot write answer to "
- "certificate accept request");
+ connman_error("openconnect: cannot "
+ "write answer to certificate "
+ "accept request");
} else {
connman_warn("Self signed certificate is not "
@@ -573,17 +710,21 @@ static gboolean io_channel_err_cb(GIOChannel *source,
GIOCondition condition,
close = true;
err = ECONNREFUSED;
}
- } else if (g_str_has_prefix(str, pkcs_failure)) {
- connman_warn("invalid PKCS password: %s", str);
- /*
- * Close IO channel to avoid deadlock. This is because
- * after PKCS file decryption fails OpenConnect will
- * wait for a new pass phrase to be written to stdin,
- * blocking vpnd as well. Instead of waiting for a
- * timeout it is better to close the IO channel here.
- */
+ } else if (strv_contains_prefix(pkcs_failures, str)) {
+ connman_warn("PKCS failure: %s", str);
close = true;
err = EACCES;
+ } else if (strv_contains_prefix(pkcs_requests, str)) {
+ DBG("PKCS file pass phrase request: %s", str);
+ err = request_input_credentials(data,
+ request_input_pkcs_reply);
+
+ if (err != -EINPROGRESS) {
+ err = EACCES;
+ close = true;
+ } else {
+ err = 0;
+ }
} else if (strv_contains_prefix(auth_failures, str)) {
connman_warn("authentication failed: %s", str);
err = EACCES;
@@ -633,9 +774,10 @@ static int run_connect(struct oc_private_data *data)
const char *password = NULL;
const char *certificate = NULL;
const char *private_key;
+ const char *setting_str;
bool setting;
bool use_stdout = false;
- int fd_out;
+ int fd_out = -1;
int fd_err;
int err = 0;
@@ -718,14 +860,19 @@ static int run_connect(struct oc_private_data *data)
case OC_CONNECT_PKCS:
certificate = vpn_provider_get_string(provider,
"OpenConnect.PKCSClientCert");
- password = vpn_provider_get_string(data->provider,
- "OpenConnect.PKCSPassword");
- if (!certificate || !password) {
+ if (!certificate) {
err = -EACCES;
goto done;
}
connman_task_add_argument(task, "--certificate", certificate);
+
+ password = vpn_provider_get_string(data->provider,
+ "OpenConnect.PKCSPassword");
+ /* Add password only if it is has been set */
+ if (!password || !g_strcmp0(password, "-"))
+ break;
+
connman_task_add_argument(task, "--passwd-on-stdin", NULL);
break;
}
@@ -751,10 +898,41 @@ static int run_connect(struct oc_private_data *data)
if (setting)
connman_task_add_argument(task, "--no-http-keepalive", NULL);
- connman_task_add_argument(task, "--non-inter", NULL);
+ /*
+ * To clarify complex situation, if cookie is expected to be printed
+ * to stdout all other output must go to syslog. But with PKCS all
+ * output must be catched in order to get message about file decryption
+ * error. For this reason, the mode has to be interactive as well.
+ */
+ switch (data->connect_type) {
+ case OC_CONNECT_COOKIE:
+ /* fall through */
+ case OC_CONNECT_COOKIE_WITH_USERPASS:
+ /* fall through */
+ case OC_CONNECT_USERPASS:
+ /* fall through */
+ case OC_CONNECT_PUBLICKEY:
+ connman_task_add_argument(task, "--syslog", NULL);
+
+ setting = vpn_provider_get_boolean(provider,
+ "OpenConnect.AllowSelfSignedCert",
+ false);
+ setting_str = vpn_provider_get_string(provider,
+ "OpenConnect.ServerCert");
- /* Output all to syslog to output cookie only to stdout */
- connman_task_add_argument(task, "--syslog", NULL);
+ /*
+ * Run in interactive mode if self signed certificates are
+ * allowed and there is no set server SHA1 fingerprint.
+ */
+ if (setting_str || !setting)
+ connman_task_add_argument(task, "--non-inter", NULL);
+ else
+ data->interactive = true;
+ break;
+ case OC_CONNECT_PKCS:
+ data->interactive = true;
+ break;
+ }
connman_task_add_argument(task, "--script", SCRIPTDIR "/vpn-script");
@@ -805,9 +983,12 @@ static int run_connect(struct oc_private_data *data)
case OC_CONNECT_PUBLICKEY:
break;
case OC_CONNECT_PKCS:
+ if (!password || !g_strcmp0(password, "-"))
+ break;
+
if (write_data(data->fd_in, password) != 0) {
connman_error("openconnect failed to take PKCS "
- "password on stdin");
+ "pass phrase on stdin");
err = -EIO;
}
@@ -828,15 +1009,32 @@ static int run_connect(struct oc_private_data *data)
if (use_stdout) {
data->out_ch = g_io_channel_unix_new(fd_out);
- data->out_ch_id = g_io_add_watch(data->out_ch,
- G_IO_IN | G_IO_ERR | G_IO_HUP,
- (GIOFunc)io_channel_out_cb, data);
+
+ /* Use ASCII encoding only */
+ if (g_io_channel_set_encoding(data->out_ch, NULL, NULL) !=
+ G_IO_STATUS_NORMAL) {
+ close_io_channel(data, data->out_ch);
+ err = -EIO;
+ } else {
+ data->out_ch_id = g_io_add_watch(data->out_ch,
+ G_IO_IN | G_IO_ERR | G_IO_HUP,
+ (GIOFunc)io_channel_out_cb,
+ data);
+ }
}
data->err_ch = g_io_channel_unix_new(fd_err);
- data->err_ch_id = g_io_add_watch(data->err_ch,
- G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_PRI,
- (GIOFunc)io_channel_err_cb, data);
+
+ /* Use ASCII encoding only */
+ if (g_io_channel_set_encoding(data->err_ch, NULL, NULL) !=
+ G_IO_STATUS_NORMAL) {
+ close_io_channel(data, data->err_ch);
+ err = -EIO;
+ } else {
+ data->err_ch_id = g_io_add_watch(data->err_ch,
+ G_IO_IN | G_IO_ERR | G_IO_HUP,
+ (GIOFunc)io_channel_err_cb, data);
+ }
done:
clear_provider_credentials(data->provider);
@@ -924,8 +1122,12 @@ static void request_input_append_to_dict(struct
vpn_provider *provider,
static void request_input_credentials_reply(DBusMessage *reply, void
*user_data)
{
struct oc_private_data *data = user_data;
- char *cookie = NULL, *servercert = NULL, *vpnhost = NULL;
- const char *username = NULL, *password = NULL, *pkcspassword = NULL;
+ const char *cookie = NULL;
+ const char *servercert = NULL;
+ const char *vpnhost = NULL;
+ const char *username = NULL;
+ const char *password = NULL;
+ const char *pkcspassword = NULL;
const char *key;
DBusMessageIter iter, dict;
int err;
@@ -1070,10 +1272,14 @@ out:
free_private_data(data);
}
-static int request_input_credentials(struct oc_private_data *data)
+static int request_input_credentials(struct oc_private_data *data,
+ request_input_reply_cb_t cb)
{
DBusMessage *message;
- const char *path, *agent_sender, *agent_path, *username;
+ const char *path;
+ const char *agent_sender;
+ const char *agent_path;
+ const char *username;
DBusMessageIter iter;
DBusMessageIter dict;
int err;
@@ -1084,6 +1290,9 @@ static int request_input_credentials(struct
oc_private_data *data)
connman_info("provider %p", data->provider);
+ if (!data || !cb)
+ return -ESRCH;
+
agent = connman_agent_get_info(data->dbus_sender,
&agent_sender, &agent_path);
if (!data->provider || !agent || !agent_path)
@@ -1163,8 +1372,7 @@ static int request_input_credentials(struct
oc_private_data *data)
connman_dbus_dict_close(&iter, &dict);
err = connman_agent_queue_message(data->provider, message,
- connman_timeout_input_request(),
- request_input_credentials_reply, data, agent);
+ connman_timeout_input_request(), cb, data, agent);
dbus_message_unref(message);
@@ -1205,7 +1413,11 @@ static int oc_connect(struct vpn_provider *provider,
const char *dbus_sender, void *user_data)
{
struct oc_private_data *data;
- const char *vpnhost, *vpncookie, *certificate, *username, *password;
+ const char *vpnhost;
+ const char *vpncookie;
+ const char *certificate;
+ const char *username;
+ const char *password;
const char *private_key;
int err;
@@ -1283,14 +1495,9 @@ static int oc_connect(struct vpn_provider *provider,
break;
case OC_CONNECT_PKCS:
certificate = vpn_provider_get_string(provider,
- "OpenConnect.PKCSClientCert");
- if (certificate) {
- password = vpn_provider_get_string(provider,
- "OpenConnect.PKCSPassword");
- if (!password || !g_strcmp0(password, "-"))
- goto request_input;
- } else {
- DBG("missing PKCS certificate");
+ "OpenConnect.PKCSClientCert");
+ if (!certificate) {
+ connman_warn("missing PKCS certificate");
oc_connect_done(data, EACCES);
free_private_data(data);
return -EACCES;
@@ -1302,7 +1509,7 @@ static int oc_connect(struct vpn_provider *provider,
return run_connect(data);
request_input:
- err = request_input_credentials(data);
+ err = request_input_credentials(data, request_input_credentials_reply);
if (err != -EINPROGRESS) {
oc_connect_done(data, err);
vpn_provider_indicate_error(data->provider,
--
2.20.1
------------------------------
Date: Wed, 09 Oct 2019 10:42:34 +0100
From: David Woodhouse <[email protected]>
Subject: Re: [PATCH v3 6/8] openconnect: Use interactive mode when
input to stdin is required
To: Jussi Laakkonen <[email protected]>, [email protected]
Message-ID:
<[email protected]>
Content-Type: multipart/signed; micalg="sha-256";
protocol="application/x-pkcs7-signature";
boundary="=-P0NxqmkToYzg83YnI7JF"
--=-P0NxqmkToYzg83YnI7JF
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Wed, 2019-10-09 at 11:34 +0300, Jussi Laakkonen wrote:
> Disable syslog (--syslog) and use interactive mode when OpenConnect
> requires input from user. This is the case when PKCS file is encrypted
> and pass phrase is requested. Changed also to prompt for the PKCS
> password only when needed, instead of having it as mandatory for the
> pkcs authentication method. Also, in case self signed certificates are
> allowed the answer needs to be written to OpenConnect, thus, interactive
> mode is required.
Don't screenscrape the openconnect command line tool.
Use libopenconnect instead. It'll call your "user interaction" function
with clear arguments for everything it wants.
See the NetworkManager auth-dialog (or indeed openconnect's main.c) for
an example.
--=-P0NxqmkToYzg83YnI7JF
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Disposition: attachment; filename="smime.p7s"
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCCECow
ggUcMIIEBKADAgECAhEA4rtJSHkq7AnpxKUY8ZlYZjANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UE
BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxPTA7BgNVBAMTNENPTU9ETyBSU0EgQ2xpZW50IEF1dGhl
bnRpY2F0aW9uIGFuZCBTZWN1cmUgRW1haWwgQ0EwHhcNMTkwMTAyMDAwMDAwWhcNMjIwMTAxMjM1
OTU5WjAkMSIwIAYJKoZIhvcNAQkBFhNkd213MkBpbmZyYWRlYWQub3JnMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAsv3wObLTCbUA7GJqKj9vHGf+Fa+tpkO+ZRVve9EpNsMsfXhvFpb8
RgL8vD+L133wK6csYoDU7zKiAo92FMUWaY1Hy6HqvVr9oevfTV3xhB5rQO1RHJoAfkvhy+wpjo7Q
cXuzkOpibq2YurVStHAiGqAOMGMXhcVGqPuGhcVcVzVUjsvEzAV9Po9K2rpZ52FE4rDkpDK1pBK+
uOAyOkgIg/cD8Kugav5tyapydeWMZRJQH1vMQ6OVT24CyAn2yXm2NgTQMS1mpzStP2ioPtTnszIQ
Ih7ASVzhV6csHb8Yrkx8mgllOyrt9Y2kWRRJFm/FPRNEurOeNV6lnYAXOymVJwIDAQABo4IB0zCC
Ac8wHwYDVR0jBBgwFoAUgq9sjPjF/pZhfOgfPStxSF7Ei8AwHQYDVR0OBBYEFLfuNf820LvaT4AK
xrGK3EKx1DE7MA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUF
BwMEBggrBgEFBQcDAjBGBgNVHSAEPzA9MDsGDCsGAQQBsjEBAgEDBTArMCkGCCsGAQUFBwIBFh1o
dHRwczovL3NlY3VyZS5jb21vZG8ubmV0L0NQUzBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3Js
LmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDbGllbnRBdXRoZW50aWNhdGlvbmFuZFNlY3VyZUVtYWls
Q0EuY3JsMIGLBggrBgEFBQcBAQR/MH0wVQYIKwYBBQUHMAKGSWh0dHA6Ly9jcnQuY29tb2RvY2Eu
Y29tL0NPTU9ET1JTQUNsaWVudEF1dGhlbnRpY2F0aW9uYW5kU2VjdXJlRW1haWxDQS5jcnQwJAYI
KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTAeBgNVHREEFzAVgRNkd213MkBpbmZy
YWRlYWQub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQALbSykFusvvVkSIWttcEeifOGGKs7Wx2f5f45b
nv2ghcxK5URjUvCnJhg+soxOMoQLG6+nbhzzb2rLTdRVGbvjZH0fOOzq0LShq0EXsqnJbbuwJhK+
PnBtqX5O23PMHutP1l88AtVN+Rb72oSvnD+dK6708JqqUx2MAFLMevrhJRXLjKb2Mm+/8XBpEw+B
7DisN4TMlLB/d55WnT9UPNHmQ+3KFL7QrTO8hYExkU849g58Dn3Nw3oCbMUgny81ocrLlB2Z5fFG
Qu1AdNiBA+kg/UxzyJZpFbKfCITd5yX49bOriL692aMVDyqUvh8fP+T99PqorH4cIJP6OxSTdxKM
MIIFHDCCBASgAwIBAgIRAOK7SUh5KuwJ6cSlGPGZWGYwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNV
BAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAY
BgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMT0wOwYDVQQDEzRDT01PRE8gUlNBIENsaWVudCBBdXRo
ZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMB4XDTE5MDEwMjAwMDAwMFoXDTIyMDEwMTIz
NTk1OVowJDEiMCAGCSqGSIb3DQEJARYTZHdtdzJAaW5mcmFkZWFkLm9yZzCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBALL98Dmy0wm1AOxiaio/bxxn/hWvraZDvmUVb3vRKTbDLH14bxaW
/EYC/Lw/i9d98CunLGKA1O8yogKPdhTFFmmNR8uh6r1a/aHr301d8YQea0DtURyaAH5L4cvsKY6O
0HF7s5DqYm6tmLq1UrRwIhqgDjBjF4XFRqj7hoXFXFc1VI7LxMwFfT6PStq6WedhROKw5KQytaQS
vrjgMjpICIP3A/CroGr+bcmqcnXljGUSUB9bzEOjlU9uAsgJ9sl5tjYE0DEtZqc0rT9oqD7U57My
ECIewElc4VenLB2/GK5MfJoJZTsq7fWNpFkUSRZvxT0TRLqznjVepZ2AFzsplScCAwEAAaOCAdMw
ggHPMB8GA1UdIwQYMBaAFIKvbIz4xf6WYXzoHz0rcUhexIvAMB0GA1UdDgQWBBS37jX/NtC72k+A
CsaxitxCsdQxOzAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEF
BQcDBAYIKwYBBQUHAwIwRgYDVR0gBD8wPTA7BgwrBgEEAbIxAQIBAwUwKzApBggrBgEFBQcCARYd
aHR0cHM6Ly9zZWN1cmUuY29tb2RvLm5ldC9DUFMwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2Ny
bC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ2xpZW50QXV0aGVudGljYXRpb25hbmRTZWN1cmVFbWFp
bENBLmNybDCBiwYIKwYBBQUHAQEEfzB9MFUGCCsGAQUFBzAChklodHRwOi8vY3J0LmNvbW9kb2Nh
LmNvbS9DT01PRE9SU0FDbGllbnRBdXRoZW50aWNhdGlvbmFuZFNlY3VyZUVtYWlsQ0EuY3J0MCQG
CCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wHgYDVR0RBBcwFYETZHdtdzJAaW5m
cmFkZWFkLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAC20spBbrL71ZEiFrbXBHonzhhirO1sdn+X+O
W579oIXMSuVEY1LwpyYYPrKMTjKECxuvp24c829qy03UVRm742R9Hzjs6tC0oatBF7KpyW27sCYS
vj5wbal+TttzzB7rT9ZfPALVTfkW+9qEr5w/nSuu9PCaqlMdjABSzHr64SUVy4ym9jJvv/FwaRMP
gew4rDeEzJSwf3eeVp0/VDzR5kPtyhS+0K0zvIWBMZFPOPYOfA59zcN6AmzFIJ8vNaHKy5QdmeXx
RkLtQHTYgQPpIP1Mc8iWaRWynwiE3ecl+PWzq4i+vdmjFQ8qlL4fHz/k/fT6qKx+HCCT+jsUk3cS
jDCCBeYwggPOoAMCAQICEGqb4Tg7/ytrnwHV2binUlYwDQYJKoZIhvcNAQEMBQAwgYUxCzAJBgNV
BAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAY
BgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYDVQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRp
b24gQXV0aG9yaXR5MB4XDTEzMDExMDAwMDAwMFoXDTI4MDEwOTIzNTk1OVowgZcxCzAJBgNVBAYT
AkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNV
BAoTEUNPTU9ETyBDQSBMaW1pdGVkMT0wOwYDVQQDEzRDT01PRE8gUlNBIENsaWVudCBBdXRoZW50
aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAvrOeV6wodnVAFsc4A5jTxhh2IVDzJXkLTLWg0X06WD6cpzEup/Y0dtmEatrQPTRI5Or1u6zf
+bGBSyD9aH95dDSmeny1nxdlYCeXIoymMv6pQHJGNcIDpFDIMypVpVSRsivlJTRENf+RKwrB6vcf
WlP8dSsE3Rfywq09N0ZfxcBa39V0wsGtkGWC+eQKiz4pBZYKjrc5NOpG9qrxpZxyb4o4yNNwTqza
aPpGRqXB7IMjtf7tTmU2jqPMLxFNe1VXj9XB1rHvbRikw8lBoNoSWY66nJN/VCJv5ym6Q0mdCbDK
CMPybTjoNCQuelc0IAaO4nLUXk0BOSxSxt8kCvsUtQIDAQABo4IBPDCCATgwHwYDVR0jBBgwFoAU
u69+Aj36pvE8hI6t7jiY7NkyMtQwHQYDVR0OBBYEFIKvbIz4xf6WYXzoHz0rcUhexIvAMA4GA1Ud
DwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMBEGA1UdIAQKMAgwBgYEVR0gADBMBgNVHR8E
RTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9u
QXV0aG9yaXR5LmNybDBxBggrBgEFBQcBAQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29t
b2RvY2EuY29tL0NPTU9ET1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
cC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAHhcsoEoNE887l9Wzp+XVuyPomsX9vP2
SQgG1NgvNc3fQP7TcePo7EIMERoh42awGGsma65u/ITse2hKZHzT0CBxhuhb6txM1n/y78e/4ZOs
0j8CGpfb+SJA3GaBQ+394k+z3ZByWPQedXLL1OdK8aRINTsjk/H5Ns77zwbjOKkDamxlpZ4TKSDM
KVmU/PUWNMKSTvtlenlxBhh7ETrN543j/Q6qqgCWgWuMAXijnRglp9fyadqGOncjZjaaSOGTTFB+
E2pvOUtY+hPebuPtTbq7vODqzCM6ryEhNhzf+enm0zlpXK7q332nXttNtjv7VFNYG+I31gnMrwfH
M5tdhYF/8v5UY5g2xANPECTQdu9vWPoqNSGDt87b3gXb1AiGGaI06vzgkejL580ul+9hz9D0S0U4
jkhJiA7EuTecP/CFtR72uYRBcunwwH3fciPjviDDAI9SnC/2aPY8ydehzuZutLbZdRJ5PDEJM/1t
yZR2niOYihZ+FCbtf3D9mB12D4ln9icgc7CwaxpNSCPt8i/GqK2HsOgkL3VYnwtx7cJUmpvVdZ4o
gnzgXtgtdk3ShrtOS1iAN2ZBXFiRmjVzmehoMof06r1xub+85hFQzVxZx5/bRaTKTlL8YXLI8nAb
R9HWdFqzcOoB/hxfEyIQpx9/s81rgzdEZOofSlZHynoSMYIDyjCCA8YCAQEwga0wgZcxCzAJBgNV
BAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAY
BgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMT0wOwYDVQQDEzRDT01PRE8gUlNBIENsaWVudCBBdXRo
ZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBAhEA4rtJSHkq7AnpxKUY8ZlYZjANBglghkgB
ZQMEAgEFAKCCAe0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTkx
MDA5MDk0MjM0WjAvBgkqhkiG9w0BCQQxIgQgiaXQGxP0kgD8bLeJK9KlPFla//hvXc89zEfYYTyu
Jakwgb4GCSsGAQQBgjcQBDGBsDCBrTCBlzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIg
TWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQx
PTA7BgNVBAMTNENPTU9ETyBSU0EgQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBTZWN1cmUgRW1h
aWwgQ0ECEQDiu0lIeSrsCenEpRjxmVhmMIHABgsqhkiG9w0BCRACCzGBsKCBrTCBlzELMAkGA1UE
BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxPTA7BgNVBAMTNENPTU9ETyBSU0EgQ2xpZW50IEF1dGhl
bnRpY2F0aW9uIGFuZCBTZWN1cmUgRW1haWwgQ0ECEQDiu0lIeSrsCenEpRjxmVhmMA0GCSqGSIb3
DQEBAQUABIIBAIdPSv5SH32BGnzzIb93hy0FEquTiNXTdEsWpUf7XjmG1XND7e38CTS7pzthgdlW
Q6nsWL6jzS3truuSR2kmW4A1Xtp2Y1YoNEUKvWLLU8FnptaH3+b5UXY73zuxob17Qt62wAwFR6Wc
Z7yatdZjDUj/oKdM40VWIpEi8mrj3bBFgZNS+YuUjymUClVLwfDk9uMq3wm806RAbOelSBbWQNnl
SEkw+xaytakgSKkmZfa83eiZghuk/Xsl28J5JwbzxyqRETFEeexZrLBd0uF0wz5cly4IBnkHCwHb
2+EObDTbyX4QTjIHvssdaNzSgA3VEEeR+E4EqUg8c2hxD/SbwQcAAAAAAAA=
--=-P0NxqmkToYzg83YnI7JF--
------------------------------
Subject: Digest Footer
_______________________________________________
connman mailing list -- [email protected]
To unsubscribe send an email to [email protected]
------------------------------
End of connman Digest, Vol 48, Issue 13
***************************************