On 06/06/13 23:34, John Ferlan wrote:
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...
Indeed.
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;
Agreed.
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
I see no need, since it must be either PASSWORD or SECRET,
otherwise there is error, it's mandatory to have either a 'passwd'
or 'secret'.
Osier