<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div dir="ltr">Ok. I will rework a modular approach. Should be able to get this done over the weekend.</div><div dir="ltr"><br></div><div dir="ltr">Yes, strict and warn would help.</div><div dir="ltr"><br></div><div dir="ltr">Mark</div><div dir="ltr"><br></div><div dir="ltr">P.S. Explains why nobody used the http api on my server :-)</div><div dir="ltr"><br><blockquote type="cite">On 21 Feb 2020, at 9:35 PM, Michael Balzer <dexter@expeedo.de> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Thanks Mark,<br>
<br>
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.<br>
<br>
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…<br>
<br>
A modular solution seems to be best, easy to add custom
implementations and to provide some standard modules.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div class="moz-cite-prefix">Am 21.02.20 um 12:15 schrieb Mark
Webb-Johnson:<br>
</div>
<blockquote type="cite" cite="mid:F4FAF182-04FF-4255-AAB6-6D7C1F9F565B@webb-johnson.net">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<div class=""><br class="">
</div>
An alternative would be to implement a server authentication
module, and to ‘require’ that into the system at startup:
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class=""><br class="">
require $config->val('db',’pw_module’,’auth_none.pl’);</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class=""><br class="">
</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">…</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class=""><br class="">
</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">If (&auth_password_check($passwordhash,
$password))</blockquote>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class=""> ...</blockquote>
<div class="">
<div><br class="">
</div>
<div>Provide a ‘auto_none.pl’:</div>
<div><br class="">
</div>
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding:
0px;" class="">
<div class="">
<div>#!/usr/bin/perl</div>
</div>
<div><br class="">
</div>
<div>sub auth_password_check</div>
<div> {</div>
<div> my ($hash,$password) = @_;</div>
<div><br class="">
</div>
<div> return 0;</div>
<div> }</div>
</blockquote>
<div class="">
<div><br class="">
</div>
<div>Then a ‘auth_drupal7.pl’, ‘auth_sha1.pl’, etc.</div>
<div><br class="">
</div>
<div>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.</div>
<div><br class="">
</div>
<div>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.</div>
<div><br class="">
</div>
<div>Is that a better solution?</div>
<div><br class="">
</div>
<div>Regards, Mark.</div>
<div><br class="">
<blockquote type="cite" class="">
<div class="">On 21 Feb 2020, at 11:37 AM, Mark Webb-Johnson
<<a href="mailto:mark@webb-johnson.net" class="" moz-do-not-send="true">mark@webb-johnson.net</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8" class="">
<div style="word-wrap: break-word; -webkit-nbsp-mode:
space; line-break: after-white-space;" class="">Michael,
<div class=""><br class="">
</div>
<div class="">Just before your commit, the server code
was:</div>
<div class=""><br class="">
</div>
<blockquote style="margin: 0 0 0 40px; border: none;
padding: 0px;" class="">
<div class="">
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">my $passwordhash = $row->{'pass'};</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">if
(&drupal_password_check($passwordhash,
$password))</span></font></div>
</div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">…</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class="">
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">sub drupal_password_check</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> {</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my ($ph,$password) = @_;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $iter_log2 =
index($itoa64,substr($ph,3,1));</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $iter_count = 1 <<
$iter_log2;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $phash = substr($ph,0,12);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $salt = substr($ph,4,8);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $hash = sha512($salt.$password);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> do</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> {</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> $hash = sha512($hash.$password);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> $iter_count--;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> } while ($iter_count > 0);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $encoded = substr($phash .
&drupal_password_base64_encode($hash,length($hash)),0,55);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> return ($encoded eq $ph);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> }</span></font></div>
</div>
</blockquote>
<div class=""><br class="">
</div>
<div class="">Your change was:</div>
<div class=""><br class="">
</div>
<blockquote style="margin: 0 0 0 40px; border: none;
padding: 0px;" class="">
<div class="">
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""># User password encoding function:</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">my $pw_encode =
$config->val('db','pw_encode','drupal_password($password)’);</span></font></div>
</div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">…</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class="">
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">my $passwordhash = $row->{'pass'};</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">my $encoded = eval $pw_encode;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">if ($encoded eq $passwordhash)</span></font></div>
</div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">…</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class="">
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class="">sub drupal_password</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> {</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my ($password) = @_;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $iter_log2 =
index($itoa64,substr($ph,3,1));</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $iter_count = 1 <<
$iter_log2;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $phash = substr($ph,0,12);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $salt = substr($ph,4,8);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $hash = sha512($salt.$password);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> do</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> {</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> $hash = sha512($hash.$password);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> $iter_count--;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> } while ($iter_count > 0);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> my $encoded = substr($phash .
&drupal_password_base64_encode($hash,length($hash)),0,55);</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""><br class="">
</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> return $encoded;</span></font></div>
<div class=""><font class="" face="Andale Mono"><span style="font-style: normal; font-size: 14px;" class=""> }</span></font></div>
</div>
</blockquote>
<div class="">
<div class=""><br class="">
</div>
<div class="">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.</div>
<div class=""><br class="">
</div>
<div class="">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.</div>
<div class=""><br class="">
</div>
<div class="">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.</div>
<div class=""><br class="">
</div>
<div class="">This won’t just affect drupal, but any
system with a non-trivial password hashing function.</div>
<div class=""><br class="">
</div>
<div class="">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).</div>
<div class=""><br class="">
</div>
<div class="">Regards, Mark.</div>
<div class=""><br class="">
<blockquote type="cite" class="">
<div class="">On 21 Feb 2020, at 1:12 AM, Michael
Balzer <<a href="mailto:dexter@expeedo.de" class="" moz-do-not-send="true">dexter@expeedo.de</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" class="">
<div class=""> Mark,<br class="">
<br class="">
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).<br class="">
<br class="">
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.<br class="">
<br class="">
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.<br class="">
<br class="">
Regards,<br class="">
Michael<br class="">
<br class="">
<br class="">
<div class="moz-cite-prefix">Am 20.02.20 um
04:09 schrieb Mark Webb-Johnson:<br class="">
</div>
<blockquote type="cite" cite="mid:F48FF6EE-9CB9-4DB5-8106-BE4CD73C5AE3@webb-johnson.net" class="">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" class="">
Even stranger. This conversation obviously
triggered someone to try it and then raise a
support ticket that HTTP API authentication
didn’t work.
<div class=""><br class="">
</div>
<div class="">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).</div>
<div class=""><br class="">
</div>
<div class="">I standardised to use a new
pw_check (overridable in the config)
parameter, which defaults to:</div>
<div class=""><br class="">
</div>
<blockquote style="margin: 0 0 0 40px;
border: none; padding: 0px;" class="">
<div class=""><font class="" face="Andale
Mono"><span style="font-style: normal;
font-size: 14px;" class="">drupal_password_check($passwordhash,$password)</span></font></div>
</blockquote>
<div class="">
<div class=""><br class="">
</div>
<div class="">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.</div>
<div class=""><br class="">
</div>
<div class="">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.</div>
<div class=""><br class="">
</div>
<div class="">Regards, Mark</div>
<div class=""><br class="">
<blockquote type="cite" class="">
<div class="">On 19 Feb 2020, at 1:53
PM, Mark Webb-Johnson <<a href="mailto:mark@webb-johnson.net" class="" moz-do-not-send="true">mark@webb-johnson.net</a>>
wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div class="">Strange. I have zero
using mine. Must be a EU thing?<br class="">
<br class="">
I’ll keep it in mind and try not
to break anything.<br class="">
<br class="">
Regards, Mark.<br class="">
<br class="">
<blockquote type="cite" class="">On
18 Feb 2020, at 8:41 PM, Michael
Balzer <<a href="mailto:dexter@expeedo.de" class="" moz-do-not-send="true">dexter@expeedo.de</a>>
wrote:<br class="">
<br class="">
Mark,<br class="">
<br class="">
grep "main: http" in the log:
yes, I've got some users
accessing the API frequently.<br class="">
<br class="">
Usage is mostly /api/charge
followed by /api/status &
/api/historical, but almost all
calls have been used during the
last days.<br class="">
<br class="">
Regards,<br class="">
Michael<br class="">
<br class="">
<br class="">
Am 18.02.20 um 04:28 schrieb
Mark Webb-Johnson:<br class="">
<blockquote type="cite" class="">Is
anyone here using the HTTP API
at all?<br class="">
<br class="">
It seems so tied to the v2
protocol, as to not be much
use.<br class="">
<br class="">
Regards, Mark.<br class="">
_______________________________________________<br class="">
OvmsDev mailing list<br class="">
<a href="mailto:OvmsDev@lists.openvehicles.com" class="" moz-do-not-send="true">OvmsDev@lists.openvehicles.com</a><br class="">
<a class="moz-txt-link-freetext" href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br class="">
</blockquote>
<br class="">
<br class="">
-- <br class="">
Michael Balzer * Helkenberger
Weg 9 * D-58256 Ennepetal<br class="">
Fon 02333 / 833 5735 * Handy
0176 / 206 989 26<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
OvmsDev mailing list<br class="">
<a href="mailto:OvmsDev@lists.openvehicles.com" class="" moz-do-not-send="true">OvmsDev@lists.openvehicles.com</a><br class="">
<a class="moz-txt-link-freetext" href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br class="">
</blockquote>
<br class="">
_______________________________________________<br class="">
OvmsDev mailing list<br class="">
<a href="mailto:OvmsDev@lists.openvehicles.com" class="" moz-do-not-send="true">OvmsDev@lists.openvehicles.com</a><br class="">
<a class="moz-txt-link-freetext" href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br class="">
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
<br class="">
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.openvehicles.com" moz-do-not-send="true">OvmsDev@lists.openvehicles.com</a>
<a class="moz-txt-link-freetext" href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" moz-do-not-send="true">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br class="">
<pre class="moz-signature" cols="160">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
</div>
_______________________________________________<br class="">
OvmsDev mailing list<br class="">
<a href="mailto:OvmsDev@lists.openvehicles.com" class="" moz-do-not-send="true">OvmsDev@lists.openvehicles.com</a><br class="">
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" class="" moz-do-not-send="true">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br class="">
</div>
</blockquote>
</div>
<br class="">
</div>
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.openvehicles.com">OvmsDev@lists.openvehicles.com</a>
<a class="moz-txt-link-freetext" href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="160">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
</pre>
<span>_______________________________________________</span><br><span>OvmsDev mailing list</span><br><span>OvmsDev@lists.openvehicles.com</span><br><span>http://lists.openvehicles.com/mailman/listinfo/ovmsdev</span><br></div></blockquote></body></html>