[libvirt] [PATCH 04/11] storage: Introduce XMLs to use secret object for pool auth

John Ferlan jferlan at redhat.com
Thu Jun 6 15:34:45 UTC 2013


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>
> 




More information about the libvir-list mailing list