>From ab1cb5d40765383ea1c11eca9c3d641f9d49bdd8 Mon Sep 17 00:00:00 2001
From: Yclept Nemo <pscjtwjdjtAhnbjm/dpn>
Date: Mon, 18 May 2015 14:07:13 -0400
Subject: [PATCH] smbclient auth support
There is now a backend block which in turns provides several password
configuration backends:
Configuration file:
backend {
name "smbclient"
password_backend "config"
username "ExampleName"
password "ExamplePassword"
}
Libsecret (keyring):
backend {
name "smbclient"
password_backend "libsecret"
username "ExampleName"
}
Some values are optional:
backend {
name "smbclient"
workgroup "FANCYWORKGROUP"
username "ExampleName"
}
Defaults:
workgroup "WORKGROUP"
username ""
password ""
password_backend "config"
Use scripts/mpd.secret.py to store a secret (password) and optionally
create a new collection (keyring).
---
.gitignore | 1 +
Makefile.am | 12 +++-
configure.ac | 5 ++
scripts/mpd.secret.py | 111 +++++++++++++++++++++++++++++++
src/config/ConfigOption.hxx | 1 +
src/config/ConfigTemplates.cxx | 1 +
src/lib/smbclient/Init.cxx | 144
++++++++++++++++++++++++++++++++++++++---
src/lib/smbclient/Init.hxx | 63 +++++++++++++++++-
8 files changed, 323 insertions(+), 15 deletions(-)
create mode 100755 scripts/mpd.secret.py
diff --git a/.gitignore b/.gitignore
index ba6d3b3..e28c23b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
*.lo
*.o
*.exe
+*.*.swp
*~
diff --git a/Makefile.am b/Makefile.am
index c6bcfa1..bda719a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -611,12 +611,14 @@ libstorage_a_SOURCES = \
libstorage_a_CPPFLAGS = $(AM_CPPFLAGS) \
$(NFS_CFLAGS) \
- $(SMBCLIENT_CFLAGS)
+ $(SMBCLIENT_CFLAGS) \
+ $(LIBSECRET_CFLAGS)
STORAGE_LIBS = \
libstorage.a \
$(NFS_LIBS) \
- $(SMBCLIENT_LIBS)
+ $(SMBCLIENT_LIBS) \
+ $(LIBSECRET_LIBS)
if ENABLE_SMBCLIENT
libstorage_a_SOURCES += \
@@ -651,7 +653,8 @@ libneighbor_a_SOURCES = \
src/neighbor/NeighborPlugin.hxx
libneighbor_a_CPPFLAGS = $(AM_CPPFLAGS) \
- $(SMBCLIENT_CFLAGS)
+ $(SMBCLIENT_CFLAGS) \
+ $(LIBSECRET_CFLAGS)
if ENABLE_SMBCLIENT
libneighbor_a_SOURCES += \
@@ -661,6 +664,7 @@ endif
NEIGHBOR_LIBS = \
$(SMBCLIENT_LIBS) \
+ $(LIBSECRET_LIBS) \
libneighbor.a
if ENABLE_UPNP
@@ -1165,6 +1169,7 @@ libinput_a_SOURCES = \
libinput_a_CPPFLAGS = $(AM_CPPFLAGS) \
$(CURL_CFLAGS) \
$(SMBCLIENT_CFLAGS) \
+ $(LIBSECRET_CFLAGS) \
$(NFS_CFLAGS) \
$(CDIO_PARANOIA_CFLAGS) \
$(FFMPEG_CFLAGS) \
@@ -1174,6 +1179,7 @@ INPUT_LIBS = \
libinput.a \
$(CURL_LIBS) \
$(SMBCLIENT_LIBS) \
+ $(LIBSECRET_LIBS) \
$(NFS_LIBS) \
$(CDIO_PARANOIA_LIBS) \
$(FFMPEG_LIBS2) \
diff --git a/configure.ac b/configure.ac
index dfd208a..82f814d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -709,6 +709,10 @@ dnl ----------------------------------- CURL
----------------------------------
MPD_ENABLE_AUTO_PKG(curl, CURL, [libcurl >= 7.18],
[libcurl HTTP streaming], [libcurl not found])
+dnl --------------------------------- LIBSECRET
-------------------------------
+MPD_ENABLE_AUTO_PKG(libsecret, LIBSECRET, [libsecret-1],
+ [libsecret password support], [libsecret not found])
+
dnl ----------------------------------- smbclient
-----------------------------
MPD_ENABLE_AUTO_PKG_LIB(smbclient, SMBCLIENT, [smbclient >= 0.2],
[smbclient], [smbc_init], [-lsmbclient], [],
@@ -1421,6 +1425,7 @@ results(soxr, [libsoxr])
results(libmpdclient, [libmpdclient])
results(inotify, [inotify])
results(sqlite, [SQLite])
+results(libsecret, [LIBSECRET])
printf '\nMetadata support:\n\t'
results(id3,[ID3])
diff --git a/scripts/mpd.secret.py b/scripts/mpd.secret.py
new file mode 100755
index 0000000..30cb497
--- /dev/null
+++ b/scripts/mpd.secret.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2003-2015 The Music Player Daemon Project
+# http://www.musicpd.org
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+
+import getpass
+from gi.repository import Secret
+
+
+mpd_schema_attributes =\
+ { "server" : Secret.SchemaAttributeType.STRING
+ , "share" : Secret.SchemaAttributeType.STRING
+ , "workgroup" : Secret.SchemaAttributeType.STRING
+ , "username" : Secret.SchemaAttributeType.STRING
+ }
+
+mpd_schema = Secret.Schema.new\
+ ( "org.mpd.smbclient.password"
+ , Secret.SchemaFlags.NONE
+ , mpd_schema_attributes
+ )
+
+mpd_default_input_data =\
+ { "collection" : { "default": "MusicPD" }
+ , "password" : { "secret": True }
+ , "server" : { }
+ , "share" : { }
+ , "workgroup" : { "default": "WORKGROUP" }
+ , "username" : { }
+ }
+
+
+def mpd_prompt(prompt, default=None, secret=False):
+ if default is None:
+ prompt = "{}: ".format(prompt)
+ else:
+ prompt = "{} [{}]: ".format(prompt, default)
+ string = ""
+ while not string:
+ if secret:
+ string = getpass.getpass(prompt)
+ else:
+ string = input(prompt)
+ if not string and default is not None:
+ string = default
+ break
+ return string
+
+def mpd_main():
+ input_data = mpd_input(mpd_default_input_data)
+ mpd_collection_ensure(input_data["collection"])
+ mpd_password_store(input_data)
+
+def mpd_input(input_data_arguments):
+ input_data = {}
+ print("<Enter> for default values (in parentheses)")
+ for attribute, arguments in sorted(input_data_arguments.items()):
+ input_data[attribute] = mpd_prompt(attribute, **arguments)
+ return input_data
+
+def mpd_collection_ensure(label):
+ service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
+ collections = Secret.Service.get_collections(service)
+ labels = [collection.get_label() for collection in collections]
+
+ if label not in labels:
+ Secret.Collection.create_sync\
+ ( service
+ , label
+ , None
+ , Secret.CollectionCreateFlags.COLLECTION_CREATE_NONE
+ , None
+ )
+
+def mpd_input_to_attributes(d):
+ return {k:v for k,v in d.items() if k in mpd_schema_attributes}
+
+def mpd_input_get_collection_path(input_data):
+ return
"/org/freedesktop/secrets/collection/{}".format(input_data["collection"])
+
+def mpd_input_get_password_label(input_data):
+ return "Smbclient Password: {}".format(input_data["server"])
+
+def mpd_password_store(input_data):
+ Secret.password_store_sync\
+ ( mpd_schema
+ , mpd_input_to_attributes(input_data)
+ , mpd_input_get_collection_path(input_data)
+ , mpd_input_get_password_label(input_data)
+ , input_data["password"]
+ , None
+ )
+
+if __name__ == "__main__":
+ mpd_main()
diff --git a/src/config/ConfigOption.hxx b/src/config/ConfigOption.hxx
index 5acd6fd..8d11a3f 100644
--- a/src/config/ConfigOption.hxx
+++ b/src/config/ConfigOption.hxx
@@ -90,6 +90,7 @@ enum class ConfigBlockOption {
AUDIO_FILTER,
DATABASE,
NEIGHBORS,
+ BACKEND,
MAX
};
diff --git a/src/config/ConfigTemplates.cxx b/src/config/ConfigTemplates.cxx
index 6fbf025..d283e29 100644
--- a/src/config/ConfigTemplates.cxx
+++ b/src/config/ConfigTemplates.cxx
@@ -90,6 +90,7 @@ const ConfigTemplate config_block_templates[] = {
{ "filter", true },
{ "database", false },
{ "neighbors", true },
+ { "backend", "true" },
};
static constexpr unsigned n_config_block_templates =
diff --git a/src/lib/smbclient/Init.cxx b/src/lib/smbclient/Init.cxx
index 999e60f..991d02d 100644
--- a/src/lib/smbclient/Init.cxx
+++ b/src/lib/smbclient/Init.cxx
@@ -22,22 +22,146 @@
#include "Mutex.hxx"
#include "thread/Mutex.hxx"
#include "util/Error.hxx"
+#include "config/ConfigGlobal.hxx"
#include <libsmbclient.h>
#include <string.h>
-static void
-mpd_smbc_get_auth_data(gcc_unused const char *srv,
- gcc_unused const char *shr,
- char *wg, gcc_unused int wglen,
- char *un, gcc_unused int unlen,
- char *pw, gcc_unused int pwlen)
+
+#ifdef ENABLE_LIBSECRET
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+const SecretSchema mpd_schema =
+ { "org.mpd.smbclient.password"
+ , SECRET_SCHEMA_NONE
+ , { { "server"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "share"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "workgroup"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "username"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "NULL"
+ , (SecretSchemaAttributeType)0
+ }
+ }
+ };
+#pragma GCC diagnostic pop
+#endif
+
+#ifdef ENABLE_LIBSECRET
+const char*
+mpd_smbc_get_auth_data_secret
+ ( SmbAuthData* smb_auth_data
+ )
{
- // TODO: implement
- strcpy(wg, "WORKGROUP");
- strcpy(un, "");
- strcpy(pw, "");
+ GError *error = NULL;
+
+ // When to free?
+ const char* password = (const char*)secret_password_lookup_sync
+ ( &mpd_schema , NULL , &error
+ , "server", smb_auth_data->server
+ , "share", smb_auth_data->share
+ , "workgroup", smb_auth_data->workgroup
+ , "username", smb_auth_data->username
+ , NULL
+ );
+
+ if (error != NULL) {
+ g_error_free(error);
+ return "";
+ }
+
+ if (password == NULL) {
+ return "";
+ }
+
+ return password;
+}
+#endif
+
+const char*
+mpd_smbc_get_auth_data_password
+ ( SmbAuthData* smb_auth_data
+ , const ConfigBlock* block
+ )
+{ const char* password_backend =
block->GetBlockValue("password_backend", "config");
+
+ if (strcmp(password_backend, "config") == 0) {
+ return block->GetBlockValue("password", "");
+ }
+#ifdef ENABLE_LIBSECRET
+ if (strcmp(password_backend, "libsecret") == 0)
+ return mpd_smbc_get_auth_data_secret(smb_auth_data);
+#endif
+ return "";
+}
+
+SmbAuthData
+mpd_smbc_get_auth_data_default()
+{ return { .server = ""
+ , .share = ""
+ , .workgroup = "WORKGROUP"
+ , .username = ""
+ , .password = ""
+ };
+}
+
+void
+mpd_smbc_get_auth_data_config
+ ( SmbAuthData* smb_auth_data
+ )
+{ const ConfigBlock* block =
config_get_block(ConfigBlockOption::BACKEND);
+
+ if (block == nullptr)
+ return;
+
+ const char* backend_name = block->GetBlockValue("name", "");
+
+ if (strcmp(backend_name, "smbclient") != 0)
+ return;
+
+ smb_auth_data->workgroup = block->GetBlockValue("workgroup",
"WORKGROUP");
+ smb_auth_data->username = block->GetBlockValue("username", "");
+ smb_auth_data->password =
mpd_smbc_get_auth_data_password(smb_auth_data, block);
+}
+
+void
+mpd_smbc_set_auth_data
+ ( char* destination
+ , const char* source
+ , size_t num
+ )
+{ size_t source_len = strlen(source) + 1;
+ memcpy(destination, source, std::min(source_len, num));
+ if (source_len > num)
+ destination[num] = '\0';
+}
+
+void
+mpd_smbc_get_auth_data
+ ( const char* server
+ , const char* share
+ , char* workgroup, int workgrouplen
+ , char* username, int usernamelen
+ , char* password, int passwordlen
+ )
+{ SmbAuthData smb_auth_data;
+
+ smb_auth_data = mpd_smbc_get_auth_data_default();
+ smb_auth_data.server = server;
+ smb_auth_data.share = share;
+ mpd_smbc_get_auth_data_config(&smb_auth_data);
+
+ mpd_smbc_set_auth_data(workgroup, smb_auth_data.workgroup,
workgrouplen);
+ mpd_smbc_set_auth_data(username, smb_auth_data.username, usernamelen);
+ mpd_smbc_set_auth_data(password, smb_auth_data.password, passwordlen);
}
bool
diff --git a/src/lib/smbclient/Init.hxx b/src/lib/smbclient/Init.hxx
index 1ccaec0..7f1994a 100644
--- a/src/lib/smbclient/Init.hxx
+++ b/src/lib/smbclient/Init.hxx
@@ -22,12 +22,71 @@
#include "check.h"
+#include "config/Block.hxx"
+
+#ifdef ENABLE_LIBSECRET
+#include <libsecret/secret.h>
+#endif
+
+
class Error;
-/**
+#ifdef ENABLE_LIBSECRET
+extern const SecretSchema mpd_schema;
+#endif
+
+struct SmbAuthData
+ { const char* server;
+ const char* share;
+ const char* workgroup;
+ const char* username;
+ const char* password;
+ };
+
+#ifdef ENABLE_LIBSECRET
+const char*
+mpd_smbc_get_auth_data_secret
+ ( SmbAuthData*
+ );
+#endif
+
+const char*
+mpd_smbc_get_auth_data_password
+ ( SmbAuthData*
+ , const ConfigBlock*
+ );
+
+SmbAuthData
+mpd_smbc_get_auth_data_default
+ ();
+
+void
+mpd_smbc_get_auth_data_config
+ ( SmbAuthData*
+ );
+
+void
+mpd_smbc_set_auth_data
+ ( char*
+ , const char*
+ , size_t
+ );
+
+void
+mpd_smbc_get_auth_data
+ ( const char*
+ , const char*
+ , char*, int
+ , char*, int
+ , char*, int
+ );
+
+/*
* Initialize libsmbclient.
*/
bool
-SmbclientInit(Error &error);
+SmbclientInit
+ (Error&
+ );
#endif
--
2.1.4
From ab1cb5d40765383ea1c11eca9c3d641f9d49bdd8 Mon Sep 17 00:00:00 2001
From: Yclept Nemo <pscjtwjdjtAhnbjm/dpn>
Date: Mon, 18 May 2015 14:07:13 -0400
Subject: [PATCH] smbclient auth support
There is now a backend block which in turns provides several password
configuration backends:
Configuration file:
backend {
name "smbclient"
password_backend "config"
username "ExampleName"
password "ExamplePassword"
}
Libsecret (keyring):
backend {
name "smbclient"
password_backend "libsecret"
username "ExampleName"
}
Some values are optional:
backend {
name "smbclient"
workgroup "FANCYWORKGROUP"
username "ExampleName"
}
Defaults:
workgroup "WORKGROUP"
username ""
password ""
password_backend "config"
Use scripts/mpd.secret.py to store a secret (password) and optionally
create a new collection (keyring).
---
.gitignore | 1 +
Makefile.am | 12 +++-
configure.ac | 5 ++
scripts/mpd.secret.py | 111 +++++++++++++++++++++++++++++++
src/config/ConfigOption.hxx | 1 +
src/config/ConfigTemplates.cxx | 1 +
src/lib/smbclient/Init.cxx | 144 ++++++++++++++++++++++++++++++++++++++---
src/lib/smbclient/Init.hxx | 63 +++++++++++++++++-
8 files changed, 323 insertions(+), 15 deletions(-)
create mode 100755 scripts/mpd.secret.py
diff --git a/.gitignore b/.gitignore
index ba6d3b3..e28c23b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
*.lo
*.o
*.exe
+*.*.swp
*~
diff --git a/Makefile.am b/Makefile.am
index c6bcfa1..bda719a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -611,12 +611,14 @@ libstorage_a_SOURCES = \
libstorage_a_CPPFLAGS = $(AM_CPPFLAGS) \
$(NFS_CFLAGS) \
- $(SMBCLIENT_CFLAGS)
+ $(SMBCLIENT_CFLAGS) \
+ $(LIBSECRET_CFLAGS)
STORAGE_LIBS = \
libstorage.a \
$(NFS_LIBS) \
- $(SMBCLIENT_LIBS)
+ $(SMBCLIENT_LIBS) \
+ $(LIBSECRET_LIBS)
if ENABLE_SMBCLIENT
libstorage_a_SOURCES += \
@@ -651,7 +653,8 @@ libneighbor_a_SOURCES = \
src/neighbor/NeighborPlugin.hxx
libneighbor_a_CPPFLAGS = $(AM_CPPFLAGS) \
- $(SMBCLIENT_CFLAGS)
+ $(SMBCLIENT_CFLAGS) \
+ $(LIBSECRET_CFLAGS)
if ENABLE_SMBCLIENT
libneighbor_a_SOURCES += \
@@ -661,6 +664,7 @@ endif
NEIGHBOR_LIBS = \
$(SMBCLIENT_LIBS) \
+ $(LIBSECRET_LIBS) \
libneighbor.a
if ENABLE_UPNP
@@ -1165,6 +1169,7 @@ libinput_a_SOURCES = \
libinput_a_CPPFLAGS = $(AM_CPPFLAGS) \
$(CURL_CFLAGS) \
$(SMBCLIENT_CFLAGS) \
+ $(LIBSECRET_CFLAGS) \
$(NFS_CFLAGS) \
$(CDIO_PARANOIA_CFLAGS) \
$(FFMPEG_CFLAGS) \
@@ -1174,6 +1179,7 @@ INPUT_LIBS = \
libinput.a \
$(CURL_LIBS) \
$(SMBCLIENT_LIBS) \
+ $(LIBSECRET_LIBS) \
$(NFS_LIBS) \
$(CDIO_PARANOIA_LIBS) \
$(FFMPEG_LIBS2) \
diff --git a/configure.ac b/configure.ac
index dfd208a..82f814d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -709,6 +709,10 @@ dnl ----------------------------------- CURL ----------------------------------
MPD_ENABLE_AUTO_PKG(curl, CURL, [libcurl >= 7.18],
[libcurl HTTP streaming], [libcurl not found])
+dnl --------------------------------- LIBSECRET -------------------------------
+MPD_ENABLE_AUTO_PKG(libsecret, LIBSECRET, [libsecret-1],
+ [libsecret password support], [libsecret not found])
+
dnl ----------------------------------- smbclient -----------------------------
MPD_ENABLE_AUTO_PKG_LIB(smbclient, SMBCLIENT, [smbclient >= 0.2],
[smbclient], [smbc_init], [-lsmbclient], [],
@@ -1421,6 +1425,7 @@ results(soxr, [libsoxr])
results(libmpdclient, [libmpdclient])
results(inotify, [inotify])
results(sqlite, [SQLite])
+results(libsecret, [LIBSECRET])
printf '\nMetadata support:\n\t'
results(id3,[ID3])
diff --git a/scripts/mpd.secret.py b/scripts/mpd.secret.py
new file mode 100755
index 0000000..30cb497
--- /dev/null
+++ b/scripts/mpd.secret.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2003-2015 The Music Player Daemon Project
+# http://www.musicpd.org
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+
+import getpass
+from gi.repository import Secret
+
+
+mpd_schema_attributes =\
+ { "server" : Secret.SchemaAttributeType.STRING
+ , "share" : Secret.SchemaAttributeType.STRING
+ , "workgroup" : Secret.SchemaAttributeType.STRING
+ , "username" : Secret.SchemaAttributeType.STRING
+ }
+
+mpd_schema = Secret.Schema.new\
+ ( "org.mpd.smbclient.password"
+ , Secret.SchemaFlags.NONE
+ , mpd_schema_attributes
+ )
+
+mpd_default_input_data =\
+ { "collection" : { "default": "MusicPD" }
+ , "password" : { "secret": True }
+ , "server" : { }
+ , "share" : { }
+ , "workgroup" : { "default": "WORKGROUP" }
+ , "username" : { }
+ }
+
+
+def mpd_prompt(prompt, default=None, secret=False):
+ if default is None:
+ prompt = "{}: ".format(prompt)
+ else:
+ prompt = "{} [{}]: ".format(prompt, default)
+ string = ""
+ while not string:
+ if secret:
+ string = getpass.getpass(prompt)
+ else:
+ string = input(prompt)
+ if not string and default is not None:
+ string = default
+ break
+ return string
+
+def mpd_main():
+ input_data = mpd_input(mpd_default_input_data)
+ mpd_collection_ensure(input_data["collection"])
+ mpd_password_store(input_data)
+
+def mpd_input(input_data_arguments):
+ input_data = {}
+ print("<Enter> for default values (in parentheses)")
+ for attribute, arguments in sorted(input_data_arguments.items()):
+ input_data[attribute] = mpd_prompt(attribute, **arguments)
+ return input_data
+
+def mpd_collection_ensure(label):
+ service = Secret.Service.get_sync(Secret.ServiceFlags.LOAD_COLLECTIONS)
+ collections = Secret.Service.get_collections(service)
+ labels = [collection.get_label() for collection in collections]
+
+ if label not in labels:
+ Secret.Collection.create_sync\
+ ( service
+ , label
+ , None
+ , Secret.CollectionCreateFlags.COLLECTION_CREATE_NONE
+ , None
+ )
+
+def mpd_input_to_attributes(d):
+ return {k:v for k,v in d.items() if k in mpd_schema_attributes}
+
+def mpd_input_get_collection_path(input_data):
+ return "/org/freedesktop/secrets/collection/{}".format(input_data["collection"])
+
+def mpd_input_get_password_label(input_data):
+ return "Smbclient Password: {}".format(input_data["server"])
+
+def mpd_password_store(input_data):
+ Secret.password_store_sync\
+ ( mpd_schema
+ , mpd_input_to_attributes(input_data)
+ , mpd_input_get_collection_path(input_data)
+ , mpd_input_get_password_label(input_data)
+ , input_data["password"]
+ , None
+ )
+
+if __name__ == "__main__":
+ mpd_main()
diff --git a/src/config/ConfigOption.hxx b/src/config/ConfigOption.hxx
index 5acd6fd..8d11a3f 100644
--- a/src/config/ConfigOption.hxx
+++ b/src/config/ConfigOption.hxx
@@ -90,6 +90,7 @@ enum class ConfigBlockOption {
AUDIO_FILTER,
DATABASE,
NEIGHBORS,
+ BACKEND,
MAX
};
diff --git a/src/config/ConfigTemplates.cxx b/src/config/ConfigTemplates.cxx
index 6fbf025..d283e29 100644
--- a/src/config/ConfigTemplates.cxx
+++ b/src/config/ConfigTemplates.cxx
@@ -90,6 +90,7 @@ const ConfigTemplate config_block_templates[] = {
{ "filter", true },
{ "database", false },
{ "neighbors", true },
+ { "backend", "true" },
};
static constexpr unsigned n_config_block_templates =
diff --git a/src/lib/smbclient/Init.cxx b/src/lib/smbclient/Init.cxx
index 999e60f..991d02d 100644
--- a/src/lib/smbclient/Init.cxx
+++ b/src/lib/smbclient/Init.cxx
@@ -22,22 +22,146 @@
#include "Mutex.hxx"
#include "thread/Mutex.hxx"
#include "util/Error.hxx"
+#include "config/ConfigGlobal.hxx"
#include <libsmbclient.h>
#include <string.h>
-static void
-mpd_smbc_get_auth_data(gcc_unused const char *srv,
- gcc_unused const char *shr,
- char *wg, gcc_unused int wglen,
- char *un, gcc_unused int unlen,
- char *pw, gcc_unused int pwlen)
+
+#ifdef ENABLE_LIBSECRET
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+const SecretSchema mpd_schema =
+ { "org.mpd.smbclient.password"
+ , SECRET_SCHEMA_NONE
+ , { { "server"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "share"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "workgroup"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "username"
+ , SECRET_SCHEMA_ATTRIBUTE_STRING
+ }
+ , { "NULL"
+ , (SecretSchemaAttributeType)0
+ }
+ }
+ };
+#pragma GCC diagnostic pop
+#endif
+
+#ifdef ENABLE_LIBSECRET
+const char*
+mpd_smbc_get_auth_data_secret
+ ( SmbAuthData* smb_auth_data
+ )
{
- // TODO: implement
- strcpy(wg, "WORKGROUP");
- strcpy(un, "");
- strcpy(pw, "");
+ GError *error = NULL;
+
+ // When to free?
+ const char* password = (const char*)secret_password_lookup_sync
+ ( &mpd_schema , NULL , &error
+ , "server", smb_auth_data->server
+ , "share", smb_auth_data->share
+ , "workgroup", smb_auth_data->workgroup
+ , "username", smb_auth_data->username
+ , NULL
+ );
+
+ if (error != NULL) {
+ g_error_free(error);
+ return "";
+ }
+
+ if (password == NULL) {
+ return "";
+ }
+
+ return password;
+}
+#endif
+
+const char*
+mpd_smbc_get_auth_data_password
+ ( SmbAuthData* smb_auth_data
+ , const ConfigBlock* block
+ )
+{ const char* password_backend = block->GetBlockValue("password_backend", "config");
+
+ if (strcmp(password_backend, "config") == 0) {
+ return block->GetBlockValue("password", "");
+ }
+#ifdef ENABLE_LIBSECRET
+ if (strcmp(password_backend, "libsecret") == 0)
+ return mpd_smbc_get_auth_data_secret(smb_auth_data);
+#endif
+ return "";
+}
+
+SmbAuthData
+mpd_smbc_get_auth_data_default()
+{ return { .server = ""
+ , .share = ""
+ , .workgroup = "WORKGROUP"
+ , .username = ""
+ , .password = ""
+ };
+}
+
+void
+mpd_smbc_get_auth_data_config
+ ( SmbAuthData* smb_auth_data
+ )
+{ const ConfigBlock* block = config_get_block(ConfigBlockOption::BACKEND);
+
+ if (block == nullptr)
+ return;
+
+ const char* backend_name = block->GetBlockValue("name", "");
+
+ if (strcmp(backend_name, "smbclient") != 0)
+ return;
+
+ smb_auth_data->workgroup = block->GetBlockValue("workgroup", "WORKGROUP");
+ smb_auth_data->username = block->GetBlockValue("username", "");
+ smb_auth_data->password = mpd_smbc_get_auth_data_password(smb_auth_data, block);
+}
+
+void
+mpd_smbc_set_auth_data
+ ( char* destination
+ , const char* source
+ , size_t num
+ )
+{ size_t source_len = strlen(source) + 1;
+ memcpy(destination, source, std::min(source_len, num));
+ if (source_len > num)
+ destination[num] = '\0';
+}
+
+void
+mpd_smbc_get_auth_data
+ ( const char* server
+ , const char* share
+ , char* workgroup, int workgrouplen
+ , char* username, int usernamelen
+ , char* password, int passwordlen
+ )
+{ SmbAuthData smb_auth_data;
+
+ smb_auth_data = mpd_smbc_get_auth_data_default();
+ smb_auth_data.server = server;
+ smb_auth_data.share = share;
+ mpd_smbc_get_auth_data_config(&smb_auth_data);
+
+ mpd_smbc_set_auth_data(workgroup, smb_auth_data.workgroup, workgrouplen);
+ mpd_smbc_set_auth_data(username, smb_auth_data.username, usernamelen);
+ mpd_smbc_set_auth_data(password, smb_auth_data.password, passwordlen);
}
bool
diff --git a/src/lib/smbclient/Init.hxx b/src/lib/smbclient/Init.hxx
index 1ccaec0..7f1994a 100644
--- a/src/lib/smbclient/Init.hxx
+++ b/src/lib/smbclient/Init.hxx
@@ -22,12 +22,71 @@
#include "check.h"
+#include "config/Block.hxx"
+
+#ifdef ENABLE_LIBSECRET
+#include <libsecret/secret.h>
+#endif
+
+
class Error;
-/**
+#ifdef ENABLE_LIBSECRET
+extern const SecretSchema mpd_schema;
+#endif
+
+struct SmbAuthData
+ { const char* server;
+ const char* share;
+ const char* workgroup;
+ const char* username;
+ const char* password;
+ };
+
+#ifdef ENABLE_LIBSECRET
+const char*
+mpd_smbc_get_auth_data_secret
+ ( SmbAuthData*
+ );
+#endif
+
+const char*
+mpd_smbc_get_auth_data_password
+ ( SmbAuthData*
+ , const ConfigBlock*
+ );
+
+SmbAuthData
+mpd_smbc_get_auth_data_default
+ ();
+
+void
+mpd_smbc_get_auth_data_config
+ ( SmbAuthData*
+ );
+
+void
+mpd_smbc_set_auth_data
+ ( char*
+ , const char*
+ , size_t
+ );
+
+void
+mpd_smbc_get_auth_data
+ ( const char*
+ , const char*
+ , char*, int
+ , char*, int
+ , char*, int
+ );
+
+/*
* Initialize libsmbclient.
*/
bool
-SmbclientInit(Error &error);
+SmbclientInit
+ (Error&
+ );
#endif
--
2.1.4
_______________________________________________
mpd-devel mailing list
[email protected]
http://mailman.blarg.de/listinfo/mpd-devel