[libvirt] [PATCH] add support for libssh2 password from auth file

Michal Novotny minovotn at redhat.com
Fri Jun 28 11:03:21 UTC 2013


On 06/28/2013 12:28 PM, Peter Krempa wrote:
> On 06/27/13 14:31, David Maciejak wrote:
>> Hi,
>>
>> I was discussing with Daniel about the best way to pass the ssh password
>> when using such kind of uri:
>> 'xen+libssh2://root at 192.168.0.10?sshauth=password
>> <http://root@192.168.0.10?sshauth=password>'
>>
>> As it seems passing the password in the uri is not a good option, maybe we
>> can grab it from auth conf ? it seems it's not the case as now (tell me
>> if i am wrong).
> I was planing on doing this stuff, but never managed to finish this.
>
>> So enclosed a patch to add this feature.
>>
>> As you can see in virnetclient.c there is no virAuthGetPassword call, so
>> the authfile is never used.
>>
>> The patch enclosed is modifying the function prototype to add
>> virConnectPtr parameter (so remote_driver.c virNetClientNewLibSSH2 call
>> has to be updated too and the corresponding .h too).
>>
>> Once we have access to virConnectPtr, as you will see in the patch we
>> can check if authMethods is set to 'password' and grab the password from
>> auth file by calling virAuthGetPassword.
>>
>>
> please use git format-patch and send-email in the future, it makes 
> reviewing easier.
>
> See the attached patch for the review.
>
> Peter
>
>
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

Hi all,
Peter, you could have reformatted it for better replies on separate code
hunks ;-) Like I did now ;-)

Comment inline ...

>> diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
>> index 7a0c1f6..012d6d5 100644
>> --- a/src/remote/remote_driver.c
>> +++ b/src/remote/remote_driver.c
>> @@ -658,7 +658,9 @@ doRemoteOpen(virConnectPtr conn,
>>                                                sshauth,
>>                                                netcat,
>>                                                sockname,
>> -                                              auth);
>> +                                              auth,
>> +                                              conn);
>> 
> This line will require tweaking ... see below ...
>> 
> 
> ... the virConnectPtr should be the first argument in this case. Also the
> closing brace of the parameter list should be on the same line as the last
> argument.
> 
>> 
>> +                                       )
>>  {
>>      virNetSocketPtr sock = NULL;
>>      virNetClientPtr ret = NULL;
>> @@ -402,6 +405,7 @@ virNetClientPtr virNetClientNewLibSSH2(const char *host,
>>      char *confdir = virGetUserConfigDirectory();
>>      char *knownhosts = NULL;
>>      char *privkey = NULL;
>> +    char *password = NULL;
>>  
>>      /* Use default paths for known hosts an public keys if not provided */
>>      if (confdir) {
>> @@ -471,11 +475,21 @@ virNetClientPtr virNetClientNewLibSSH2(const char *host,
>>      if (!(command = virBufferContentAndReset(&buf)))
>>          goto no_memory;
>> 
>> -    if (virNetSocketNewConnectLibSSH2(host, port, username, NULL, privkey,
>> +    password = virAuthGetPassword(conn, authPtr, "libssh2", username, host);
>> +
>> +    if ((strcmp(authMethods,"password") == 0) && password) {
> 
> authMethods is a comma separated list of possible methods to use. With a strcmp
> this will not work if the list will contain other methods too. Use strstr() instead of
> strcmp. Also this condition should make the call to virAuthGetPassword conditional
> otherwise we would always ask the user for the password if it isn't stored in the auth
> file even if it will never be used.


You suggest using strstr() ? Interesting libvirt doesn't have it's own implementation like it does on many other things. However using the substring matching approach is not good IMHO as it can also match the substring of real method, e.g. if you have e.g. authMethods = "password,auth-password" (bogus but works for the example to demonstrate) and you do strstr(authMethods, "password") is can also match if authMethods = "auth-password" but doesn't contain real "password" method.

I suggest tokenizing it after commas, like I'm doing for my personal projects, e.g. something like:

typedef struct tTokenizer {
        char **tokens;
        int numTokens;
} tTokenizer;

tTokenizer tokenize(char *string, char *by);
void free_tokens(tTokenizer t);

tTokenizer tokenize(char *string, char *by)
{
        char *tmp;
        char *str;
        char *save;
        char *token;
        int i = 0;
        tTokenizer t;

        tmp = strdup(string);
        t.tokens = malloc( sizeof(char *) );
        for (str = tmp; ; str = NULL) {
                token = strtok_r(str, by, &save);
                if (token == NULL)
                        break;

                t.tokens = realloc( t.tokens, (i + 1) * sizeof(char *) );
                t.tokens[i++] = strdup(token);
        }

        t.numTokens = i;
        return t;
}

void free_tokens(tTokenizer t)
{
        int i;

        for (i = 0; i < t.numTokens; i++)
                t.tokens[i] = free( t.tokens[i]);
}

[Code borrowed from my CDVWS project (available at https://github.com/MigNov/CDVWS)]

where you could easily call something like: tTokenizer authMethodTokens = tokenize(authMethods, ",") and then check it using approach like:

hasPasswordMethod = false;
for (i = 0; i < t.numTokens; i++)
    if (strcmp(t.tokens[i], "password") == 0)
        hasPasswordMethod = true;

I think libvirt already have some similar functions to do it, doesn't it?

Thanks,
Michal


-- 
Michal Novotny <minovotn at redhat.com>, RHCE, Red Hat
Virtualization | libvirt-php bindings | php-virt-control.org




More information about the libvir-list mailing list