Allow using a secret object type for 'chap' authentication attributes.
Using plain password is still supported for back-compat reason.
Introduce virStoragePoolAuthChapType enum to allow either "plain password" or
"chap secret" as options keeping the plain text as the first option, even
though it's preferable to use the secret type. When parsing XML check for
secret first, but fall back to plain passwd.
Example XML:
<auth type='chap' username='foo'>
<secret uuid='48dcd4a4-b25f-4fc6-8874-84797c6e3678'/>
</auth>
* docs/schemas/storagepool.rng (Add sourceinfoauthsecret as a choice)
* src/conf/storage_conf.h (union "passwd" and virStoragePoolAuthSecret)
* src/conf/storage_conf.c (s/chap\.passwd/chap\.u\.passwd/;
Add a helper virStoragePoolAuthDefFormat;
Parse the secret XMLs for "chap" auth)
* tests/storagepoolxml2xmlin/pool-iscsi-auth-secret.xml: (New tests)
* tests/storagepoolxml2xmlout/pool-iscsi-auth-secret.xml: (Likewise)
---
docs/schemas/storagepool.rng | 9 ++-
src/conf/storage_conf.c | 69 ++++++++++++++--------
src/conf/storage_conf.h | 11 +++-
.../pool-iscsi-auth-secret.xml | 19 ++++++
.../pool-iscsi-auth-secret.xml | 22 +++++++
5 files changed, 103 insertions(+), 27 deletions(-)
create mode 100644 tests/storagepoolxml2xmlin/pool-iscsi-auth-secret.xml
create mode 100644 tests/storagepoolxml2xmlout/pool-iscsi-auth-secret.xml
diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng
index ba6c741..386de1b 100644
--- a/docs/schemas/storagepool.rng
+++ b/docs/schemas/storagepool.rng
@@ -295,9 +295,12 @@
<text/>
</attribute>
</choice>
- <attribute name='passwd'>
- <text/>
- </attribute>
+ <choice>
+ <attribute name='passwd'>
+ <text/>
+ </attribute>
+ <ref name='sourceinfoauthsecret'/>
+ </choice>
</interleave>
</group>
<group>
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 3b789f7..1e75ba8 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -362,7 +362,10 @@ virStoragePoolSourceClear(virStoragePoolSourcePtr source)
if (source->authType == VIR_STORAGE_POOL_AUTH_CHAP) {
VIR_FREE(source->auth.chap.login);
- VIR_FREE(source->auth.chap.passwd);
+ if (source->auth.chap.type == VIR_STORAGE_POOL_AUTH_CHAP_PLAIN_PASSWORD)
+ VIR_FREE(source->auth.chap.u.passwd);
+ else if (source->auth.chap.type == VIR_STORAGE_POOL_AUTH_CHAP_SECRET)
+ VIR_FREE(source->auth.chap.u.secret.usage);
}
if (source->authType == VIR_STORAGE_POOL_AUTH_CEPHX) {
@@ -517,11 +520,17 @@ virStoragePoolDefParseAuthChap(xmlXPathContextPtr ctxt,
auth->login = username ? username : login;
- auth->passwd = virXPathString("string(./auth/@passwd)", ctxt);
- if (auth->passwd == NULL) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("missing auth passwd attribute"));
- return -1;
+ if (virStoragePoolDefParseAuthSecret(ctxt, &auth->u.secret) < 0) {
+ auth->u.passwd = virXPathString("string(./auth/@passwd)", ctxt);
+ if (!auth->u.passwd) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Either 'passwd' attribute or 'secret'
element "
+ "must be specified"));
+ return -1;
+ }
+ auth->type = VIR_STORAGE_POOL_AUTH_CHAP_PLAIN_PASSWORD;
+ } else {
+ auth->type = VIR_STORAGE_POOL_AUTH_CHAP_SECRET;
}
return 0;
@@ -1067,13 +1076,30 @@ virStoragePoolDefParseFile(const char *filename)
return virStoragePoolDefParse(NULL, filename);
}
+static void
+virStoragePoolAuthDefFormat(virBufferPtr buf,
+ virStoragePoolAuthSecret secret)
+{
+ char uuid[VIR_UUID_STRING_BUFLEN];
+
+ virBufferAddLit(buf, " <secret");
+ if (secret.uuidUsable) {
+ virUUIDFormat(secret.uuid, uuid);
+ virBufferAsprintf(buf, " uuid='%s'", uuid);
+ }
+
+ if (secret.usage != NULL) {
+ virBufferAsprintf(buf, " usage='%s'", secret.usage);
+ }
+ virBufferAddLit(buf, "/>\n");
+}
+
static int
virStoragePoolSourceFormat(virBufferPtr buf,
virStoragePoolOptionsPtr options,
virStoragePoolSourcePtr src)
{
int i, j;
- char uuid[VIR_UUID_STRING_BUFLEN];
virBufferAddLit(buf," <source>\n");
if ((options->flags & VIR_STORAGE_POOL_SOURCE_HOST) && src->nhost)
{
@@ -1148,26 +1174,23 @@ virStoragePoolSourceFormat(virBufferPtr buf,
virBufferAsprintf(buf," <format type='%s'/>\n",
format);
}
- if (src->authType == VIR_STORAGE_POOL_AUTH_CHAP)
- virBufferAsprintf(buf," <auth type='chap'
username='%s' passwd='%s'/>\n",
- src->auth.chap.login,
- src->auth.chap.passwd);
+ if (src->authType == VIR_STORAGE_POOL_AUTH_CHAP) {
+ virBufferAsprintf(buf," <auth type='chap'
username='%s'",
+ src->auth.chap.login);
+ if (src->auth.chap.type == VIR_STORAGE_POOL_AUTH_CHAP_PLAIN_PASSWORD) {
+ virBufferAsprintf(buf, " passwd='%s'/>\n",
+ src->auth.chap.u.passwd);
+ } else if (src->auth.chap.type == VIR_STORAGE_POOL_AUTH_CHAP_SECRET) {
+ virBufferAddLit(buf, ">\n");
+ virStoragePoolAuthDefFormat(buf, src->auth.chap.u.secret);
+ virBufferAddLit(buf," </auth>\n");
+ }
+ }
if (src->authType == VIR_STORAGE_POOL_AUTH_CEPHX) {
virBufferAsprintf(buf," <auth username='%s'
type='ceph'>\n",
src->auth.cephx.username);
-
- virBufferAddLit(buf," <secret");
- if (src->auth.cephx.secret.uuidUsable) {
- virUUIDFormat(src->auth.cephx.secret.uuid, uuid);
- virBufferAsprintf(buf," uuid='%s'", uuid);
- }
-
- if (src->auth.cephx.secret.usage != NULL) {
- virBufferAsprintf(buf," usage='%s'",
src->auth.cephx.secret.usage);
- }
- virBufferAddLit(buf,"/>\n");
-
+ virStoragePoolAuthDefFormat(buf, src->auth.cephx.secret);
virBufferAddLit(buf," </auth>\n");
}
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 452f583..233340e 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -156,11 +156,20 @@ struct _virStoragePoolAuthSecret {
bool uuidUsable;
};
+enum virStoragePoolAuthChapType {
+ VIR_STORAGE_POOL_AUTH_CHAP_PLAIN_PASSWORD,
+ VIR_STORAGE_POOL_AUTH_CHAP_SECRET,
+};
+
typedef struct _virStoragePoolAuthChap virStoragePoolAuthChap;
typedef virStoragePoolAuthChap *virStoragePoolAuthChapPtr;
struct _virStoragePoolAuthChap {
char *login;
- char *passwd;
+ int type; /* enum virStoragePoolAuthChapType */
+ union {
+ char *passwd;
+ virStoragePoolAuthSecret secret;
+ } u;
};
typedef struct _virStoragePoolAuthCephx virStoragePoolAuthCephx;
diff --git a/tests/storagepoolxml2xmlin/pool-iscsi-auth-secret.xml
b/tests/storagepoolxml2xmlin/pool-iscsi-auth-secret.xml
new file mode 100644
index 0000000..c897cc6
--- /dev/null
+++ b/tests/storagepoolxml2xmlin/pool-iscsi-auth-secret.xml
@@ -0,0 +1,19 @@
+<pool type='iscsi'>
+ <name>virtimages</name>
+ <uuid>e9392370-2917-565e-692b-d057f46512d6</uuid>
+ <source>
+ <host name="iscsi.example.com"/>
+ <device path="demo-target"/>
+ <auth type='chap' username='foobar'>
+ <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
+ </auth>
+ </source>
+ <target>
+ <path>/dev/disk/by-path</path>
+ <permissions>
+ <mode>0700</mode>
+ <owner>0</owner>
+ <group>0</group>
+ </permissions>
+ </target>
+</pool>
diff --git a/tests/storagepoolxml2xmlout/pool-iscsi-auth-secret.xml
b/tests/storagepoolxml2xmlout/pool-iscsi-auth-secret.xml
new file mode 100644
index 0000000..0ab3b3d
--- /dev/null
+++ b/tests/storagepoolxml2xmlout/pool-iscsi-auth-secret.xml
@@ -0,0 +1,22 @@
+<pool type='iscsi'>
+ <name>virtimages</name>
+ <uuid>e9392370-2917-565e-692b-d057f46512d6</uuid>
+ <capacity unit='bytes'>0</capacity>
+ <allocation unit='bytes'>0</allocation>
+ <available unit='bytes'>0</available>
+ <source>
+ <host name='iscsi.example.com'/>
+ <device path='demo-target'/>
+ <auth type='chap' username='foobar'>
+ <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
+ </auth>
+ </source>
+ <target>
+ <path>/dev/disk/by-path</path>
+ <permissions>
+ <mode>0700</mode>
+ <owner>0</owner>
+ <group>0</group>
+ </permissions>
+ </target>
+</pool>
--
1.8.1.4