On 05/28/2013 02:39 AM, Osier Yang wrote: > Using plain password is still supported for back-compat reason. > > 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 | 71 +++++++++++++++------- > src/conf/storage_conf.h | 11 +++- > .../pool-iscsi-auth-secret.xml | 19 ++++++ > .../pool-iscsi-auth-secret.xml | 22 +++++++ > 5 files changed, 107 insertions(+), 25 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 0047372..8f83bae 100644 > --- a/src/conf/storage_conf.c > +++ b/src/conf/storage_conf.c > @@ -349,7 +349,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); See [1] below in 'def'... It seems type must be one or the other *IF* we get it defined. As long as there's a "NONE" type option, then this code will be OK; otherwise, you have a bit more refactoring to do. > } > > if (source->authType == VIR_STORAGE_POOL_AUTH_CEPHX) { > @@ -483,6 +486,8 @@ virStoragePoolDefParseAuthChap(xmlXPathContextPtr ctxt, > { > char *login = NULL; > char *username = NULL; > + char *passwd = NULL; > + int rc; > > login = virXPathString("string(./auth/@login)", ctxt); > username = virXPathString("string(./auth/@username)", ctxt); > @@ -507,10 +512,20 @@ virStoragePoolDefParseAuthChap(xmlXPathContextPtr ctxt, > else if (username) > auth->login = username; > > - auth->passwd = virXPathString("string(./auth/@passwd)", ctxt); > - if (auth->passwd == NULL) { > + passwd = virXPathString("string(./auth/@passwd)", ctxt); > + rc = virStoragePoolDefParseAuthSecret(ctxt, &auth->u.secret); > + > + if (passwd) { > + auth->type = VIR_STORAGE_POOL_AUTH_CHAP_PLAIN_PASSWORD; > + auth->u.passwd = passwd; > + } else if (rc == 0) { > + auth->type = VIR_STORAGE_POOL_AUTH_CHAP_SECRET; > + } else if (rc < 0) { > + return -1; > + } else { > virReportError(VIR_ERR_XML_ERROR, "%s", > - _("missing auth passwd attribute")); > + _("Either 'passwd' attribute or 'secret' element " > + "should be specified")); > return -1; > } [1] According to this code - either we have passwd or secret being used; however, there's no check if both were supplied, thus making the default be passwd and ignoring the secret - which will be confusing in other checks... such as a memory leak on the free side... Additionally because this code may not be reached the 'type' would need a "NONE" possibility. If neither is supplied, then we have an error, so at least one must be used. I would think you'd prefer secret over plaintext password.. Thus, consider: if (virStoragePoolDefParseAuthSecret(ctxt, &auth->u.secret) < 0) { auth->passwd = virXPathString("string(./auth/@passwd)", ctxt); if (!auth->passwd) { error condition; return -1; } auth->type = VIR_STORAGE_POOL_AUTH_CHAP_PLAIN_PASSWORD; } else { auth->type = VIR_STORAGE_POOL_AUTH_CHAP_SECRET; } return 0; NOTE: No need for locals passwd and rc. > > @@ -1048,13 +1063,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) { > @@ -1129,26 +1161,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 aff1393..b52cdc4 100644 > --- a/src/conf/storage_conf.h > +++ b/src/conf/storage_conf.h > @@ -153,11 +153,20 @@ struct _virStoragePoolAuthSecret { > bool uuidUsable; > }; > > +enum virStoragePoolAuthChapType { I think you need a VIR_STORAGE_POOL_AUTH_CHAP_NONE = 0, here Depending on the rest of the review not sure if a v2 is necessary, but might be nice to post anyway. John > + 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> > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list