[Ovmsdev] Anyone using HTTP API?

Michael Balzer dexter at expeedo.de
Fri Feb 21 21:35:20 HKT 2020


Thanks Mark,

I must have been blind… but perl also never fails to amaze me in terms of "compiles fine, but won't run" -- $ph isn't defined anywhere else. Maybe "strict" mode
would have told me about that.

And I didn't think about meta data in the hash. You're right, we need to pass both values to the function. And I need to rework my password hashing…

A modular solution seems to be best, easy to add custom implementations and to provide some standard modules.

Regards,
Michael


Am 21.02.20 um 12:15 schrieb Mark Webb-Johnson:
>
> An alternative would be to implement a server authentication module, and to ‘require’ that into the system at startup:
>
>
>     require $config->val('db',’pw_module’,’auth_none.pl’);
>
>
>>
>
>     If (&auth_password_check($passwordhash, $password))
>
>       ...
>
>
> Provide a ‘auto_none.pl’:
>
>     #!/usr/bin/perl
>
>     sub auth_password_check
>       {
>       my ($hash,$password) = @_;
>
>       return 0;
>       }
>
>
> Then a ‘auth_drupal7.pl’, ‘auth_sha1.pl’, etc.
>
> This could also be done in a perl modular fashion by having the module provided as an object (using ‘use …’). Probably cleaner than the old-style require.
>
> That is much more extendable and standardised. In particular, there is also code that syncs Drupal users to ovms_owners (svr_tim) and if we have a separate
> module that drupal-dependant code could be removed from ovms_server.pl.
>
> Is that a better solution?
>
> Regards, Mark.
>
>> On 21 Feb 2020, at 11:37 AM, Mark Webb-Johnson <mark at webb-johnson.net <mailto:mark at webb-johnson.net>> wrote:
>>
>> Michael,
>>
>> Just before your commit, the server code was:
>>
>>     my $passwordhash = $row->{'pass'};
>>     if (&drupal_password_check($passwordhash, $password))
>>
>>>>
>>     sub drupal_password_check
>>       {
>>       my ($ph,$password) = @_;
>>
>>       my $iter_log2 = index($itoa64,substr($ph,3,1));
>>       my $iter_count = 1 << $iter_log2;
>>
>>       my $phash = substr($ph,0,12);
>>       my $salt = substr($ph,4,8);
>>
>>       my $hash = sha512($salt.$password);
>>       do
>>         {
>>         $hash = sha512($hash.$password);
>>         $iter_count--;
>>         } while ($iter_count > 0);
>>
>>       my $encoded = substr($phash . &drupal_password_base64_encode($hash,length($hash)),0,55);
>>
>>       return ($encoded eq $ph);
>>       }
>>
>>
>> Your change was:
>>
>>     # User password encoding function:
>>     my $pw_encode        = $config->val('db','pw_encode','drupal_password($password)’);
>>
>>>>
>>     my $passwordhash = $row->{'pass'};
>>     my $encoded = eval $pw_encode;
>>     if ($encoded eq $passwordhash)
>>
>>>>
>>     sub drupal_password
>>       {
>>       my ($password) = @_;
>>
>>       my $iter_log2 = index($itoa64,substr($ph,3,1));
>>       my $iter_count = 1 << $iter_log2;
>>
>>       my $phash = substr($ph,0,12);
>>       my $salt = substr($ph,4,8);
>>
>>       my $hash = sha512($salt.$password);
>>       do
>>         {
>>         $hash = sha512($hash.$password);
>>         $iter_count--;
>>         } while ($iter_count > 0);
>>
>>       my $encoded = substr($phash . &drupal_password_base64_encode($hash,length($hash)),0,55);
>>
>>       return $encoded;
>>       }
>>
>>
>> You changed the parameters from ($ph,$password) to just ($password), but the drupal_password function still needs to use $ph (the hash) to extract meta data
>> to set the encoding parameters.
>>
>> The problem is that Drupal (and others) has a strong hashing function with multiple iterations. The meta data for that is stored in the password hash itself.
>> The unix crypt library does something similar (with the encoding method and salt stored as meta data in the hash). Just storing passwords as straight hashes
>> (md5, sha1, etc) is fundamentally not secure, as it is trivial to use rainbow tables to break the hashes - so most modern systems use iterations, salts, or
>> other techniques to limit the effectiveness of rainbow tables and make brute force approaches computationally unfeasible.
>>
>> For many systems, we can only encode a password in the same way as a previous encoding if we know the meta data of the previous encoding (and that is stored
>> in the hash). Hence we need the hash as a parameter, to extract the meta data to be able to encode the new password in the same way.
>>
>> This won’t just affect drupal, but any system with a non-trivial password hashing function.
>>
>> So, pw_encode() needs both the old hash as well as the plaintext password to encode. At which point, I think it becomes easier to make it simply pw_check()
>> returning a boolean. It also seems easier to me to do that as a plugin function (pw_check vs pw_encode) as it will allow other non-trivial hashing
>> comparisons if required. For example, say you needed to check the password against an external lookup (ldap, etc).
>>
>> Regards, Mark.
>>
>>> On 21 Feb 2020, at 1:12 AM, Michael Balzer <dexter at expeedo.de <mailto:dexter at expeedo.de>> wrote:
>>>
>>> Mark,
>>>
>>> I did 1b73a7f8 to split the "create & compare password" function into separate "create" & "compare" steps, and introduced the "pw_encode" config hook to be
>>> able to supply just a custom "create" operation. That simplifies the config (see example).
>>>
>>> That change has been working since 2016 on my server. I see you reintroduced the "create & compare" function as a separate function for the MQTT auth, but
>>> don't see why that was needed. I also don't see why the separated function was broken on your server. Can you please elaborate? I'd like to understand what
>>> was going wrong.
>>>
>>> With reverting to the "create & compare", this breaks the configuration of servers not using Drupal. Essentially, the new "pw_check" hook does just the
>>> previous "pw_encode" and adds the comparison to that, so I'd rather opt for adding a default function here that simply reuses the existing "pw_encode" hook.
>>>
>>> Regards,
>>> Michael
>>>
>>>
>>> Am 20.02.20 um 04:09 schrieb Mark Webb-Johnson:
>>>> Even stranger. This conversation obviously triggered someone to try it and then raise a support ticket that HTTP API authentication didn’t work.
>>>>
>>>> It seems  a change was made back in 2016-02-01 23:59:22 (1b73a7f8) that broke the pw_encode function (drupal_password). It was also weird because we had
>>>> drupal_password and drupal_password_check functions, doing pretty much the same thing (one used by HTTP API and the other by MQ authentication).
>>>>
>>>> I standardised to use a new pw_check (overridable in the config) parameter, which defaults to:
>>>>
>>>>     drupal_password_check($passwordhash,$password)
>>>>
>>>>
>>>> and stopped using the pw_encode config value. I also changed the MQ authentication stuff to use the same pw_check parameter (so both authentication uses
>>>> are now able to be changed in the same config). If using something other than drupal, just need to change the pw_check parameter in the config.
>>>>
>>>> I realise that this may break other users of the server, but it doesn’t seem a difficult fix to make, and is a much better approach.
>>>>
>>>> Regards, Mark
>>>>
>>>>> On 19 Feb 2020, at 1:53 PM, Mark Webb-Johnson <mark at webb-johnson.net <mailto:mark at webb-johnson.net>> wrote:
>>>>>
>>>>> Strange. I have zero using mine. Must be a EU thing?
>>>>>
>>>>> I’ll keep it in mind and try not to break anything.
>>>>>
>>>>> Regards, Mark.
>>>>>
>>>>>> On 18 Feb 2020, at 8:41 PM, Michael Balzer <dexter at expeedo.de <mailto:dexter at expeedo.de>> wrote:
>>>>>>
>>>>>> Mark,
>>>>>>
>>>>>> grep "main: http" in the log: yes, I've got some users accessing the API frequently.
>>>>>>
>>>>>> Usage is mostly /api/charge followed by /api/status & /api/historical, but almost all calls have been used during the last days.
>>>>>>
>>>>>> Regards,
>>>>>> Michael
>>>>>>
>>>>>>
>>>>>> Am 18.02.20 um 04:28 schrieb Mark Webb-Johnson:
>>>>>>> Is anyone here using the HTTP API at all?
>>>>>>>
>>>>>>> It seems so tied to the v2 protocol, as to not be much use.
>>>>>>>
>>>>>>> Regards, Mark.
>>>>>>> _______________________________________________
>>>>>>> OvmsDev mailing list
>>>>>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>>
>>>>>>
>>>>>> -- 
>>>>>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>>>>>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> OvmsDev mailing list
>>>>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>
>>>>> _______________________________________________
>>>>> OvmsDev mailing list
>>>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>
>>>>
>>>> _______________________________________________
>>>> OvmsDev mailing list
>>>> OvmsDev at lists.openvehicles.com
>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>
>>> -- 
>>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>> _______________________________________________
>>> OvmsDev mailing list
>>> OvmsDev at lists.openvehicles.com <mailto:OvmsDev at lists.openvehicles.com>
>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>
>
>
> _______________________________________________
> OvmsDev mailing list
> OvmsDev at lists.openvehicles.com
> http://lists.openvehicles.com/mailman/listinfo/ovmsdev

-- 
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20200221/adddf089/attachment.htm>


More information about the OvmsDev mailing list