<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body 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 face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">my $passwordhash = $row->{'pass'};</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">if (&drupal_password_check($passwordhash, $password))</span></font></div></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">…</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">sub drupal_password_check</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my ($ph,$password) = @_;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $iter_log2 = index($itoa64,substr($ph,3,1));</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $iter_count = 1 << $iter_log2;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $phash = substr($ph,0,12);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $salt = substr($ph,4,8);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $hash = sha512($salt.$password);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  do</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    $hash = sha512($hash.$password);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    $iter_count--;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    } while ($iter_count > 0);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><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 face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  return ($encoded eq $ph);</span></font></div><div class=""><font face="Andale Mono" class=""><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 face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""># User password encoding function:</span></font></div><div class=""><font face="Andale Mono" class=""><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 face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">…</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">my $passwordhash = $row->{'pass'};</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">my $encoded = eval $pw_encode;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">if ($encoded eq $passwordhash)</span></font></div></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">…</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">sub drupal_password</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my ($password) = @_;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $iter_log2 = index($itoa64,substr($ph,3,1));</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $iter_count = 1 << $iter_log2;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $phash = substr($ph,0,12);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $salt = substr($ph,4,8);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  my $hash = sha512($salt.$password);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  do</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    $hash = sha512($hash.$password);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    $iter_count--;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">    } while ($iter_count > 0);</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><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 face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  return $encoded;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-style: normal; font-size: 14px;" class="">  }</span></font></div></div></blockquote><div class=""><div><br class=""></div><div>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><br class=""></div><div>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><br class=""></div><div>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><br class=""></div><div>This won’t just affect drupal, but any system with a non-trivial password hashing function.</div><div><br class=""></div><div>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><br class=""></div><div>Regards, Mark.</div><div><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="">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">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">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">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">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 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="">OvmsDev@lists.openvehicles.com</a><br class="">http://lists.openvehicles.com/mailman/listinfo/ovmsdev<br class=""></div></blockquote></div><br class=""></div></body></html>