Ein Lösungsweg
bearbeitet von woodfighterTach,
> Hm.
>
> quotemedia ist leider auch nicht der Weisheit letzter Schluss:
>
> ~~~perl
> #!/usr/bin/perl
> use strict;
> use utf8; #if needed
> print quotemeta('#Ä') . "\n";
> print quotemeta('#ÄÄ') . "\n";
> print quotemeta('#öö') . "\n";
> print quotemeta('ha\'llo') . "\n";
> ~~~
>
> Output:
>
> ~~~
> \#�
> \#��
> \#��
> ha\'llo
>
> ~~~
>
> **Also Mist.** Utf-8? Geht es ohne?
>
> ~~~perl
> #!/usr/bin/perl
> use strict;
> #use utf8; #if needed
> print quotemeta('#Ä') . "\n";
> print quotemeta('#ÄÄ') . "\n";
> print quotemeta('#öö') . "\n";
> print quotemeta('ha\'llo') . "\n";
> ~~~
>
> Ergebnis:
>
> ~~~
> \#\�\�
> \#\�\�\�\�
> \#\�\�\�\�
> ha\'llo
> ~~~
>
> **Will auch keiner.**
>
> Nächster Test:
>
> ~~~perl
> #!/usr/bin/perl
> use strict;
> #use utf8; #if needed
> system ('echo', '#Ä') . "\n";
> system ('echo', '#ÄÄ') . "\n";
> system ('echo', '#öö') . "\n";
> system ('echo', '´$(ls -l);#!#öö\'" ') . "\n";
> system ('echo', 'ha\'llo') . "\n"
> ~~~
>
> Output:
>
> ~~~
> #Ä
> #ÄÄ
> #öö
> ´$(ls -l);#!#öö'"
> ha'llo
> ~~~
>
> **Ok. Geht. Ich bin belehrt:**
>
> **Ich brauche aber die Rückgaben!** [Also ist system() kein Weg](https://wiki.selfhtml.org/wiki/Perl/Funktionen_f%C3%BCr_Betriebssystemaufrufe#system_-_Fremdprogramm_aufrufen_und_eigenen_Prozess_erhalten). "Escape" ich doch wieder selbst … und mach es mir noch einfacher:
>
> ~~~perl
> #!/usr/bin/perl
> use strict;
> use autodie qw(:all);
>
> sub my_escape {
> # gibt String in Hochkomma zurück, entwertet Hochkommas in String
> ## ha'llo' -> 'ha'"'"'llo'
> ## ha''llo' -> 'ha'"'"''"'"'llo'
> my $s=shift;
> $s =~ s/\'/\'\"\'\"\'/g;
> return "'" . $s . "'";
> }
>
> sub htpasswd_wrapper {
> ## return a fine hashed password for Apache 2.4 oder 2.2
> ## usage htpasswd_wrapper($passwd_clear, '2.4')
> ## or htpasswd_wrapper($passwd_clear, '2.2')
>
> my $passwd_clear = shift;
> my $version = shift;
> my $cmd='';
> my $passwd_hash='';
>
> if ( $version eq "2.2" ) {
> $cmd = '/usr/bin/htpasswd -bn \'USER\' ' . my_escape($passwd_clear);
> } elsif ( $version eq "2.4" ) {
> $cmd = '/usr/bin/htpasswd -bnB \'USER\' ' . my_escape($passwd_clear);
> }
>
> if ($cmd) {
> $passwd_hash = `$cmd`;
> $passwd_hash =~ s/\s+$//;
> $passwd_hash =~ s/^USER://;
> print "cmd = " . $cmd . "\n"; # Debug, löschen
> print "echo-Test: "; # Debug, löschen
> my $test='echo ' . my_escape($passwd_clear); # Debug, löschen
> $test=`$test`; # Debug, löschen
> print $test; # Debug, löschen
> print $passwd_hash . "\n"; # Debug, löschen
> print '-' x 60 . "\n"; # Debug, löschen
> return $passwd_hash;
> } else {
> return '';
> }
> }
>
> ## Tests/Usage:
> my $passwd_hash;
> $passwd_hash = htpasswd_wrapper("hallo", '2.4');
> $passwd_hash = htpasswd_wrapper("hallo", '2.4');
>
> print '-' x 60 . "\n";
>
> $passwd_hash = htpasswd_wrapper("ha'llo", '2.4');
> $passwd_hash = htpasswd_wrapper('ha"llo', '2.4');
> $passwd_hash = htpasswd_wrapper('ha`ll`o', '2.4');
> $passwd_hash = htpasswd_wrapper('ha` | less`o', '2.4');
> $passwd_hash = htpasswd_wrapper('!ÖÖööÄÄääüü\/\/', '2.4');
> $passwd_hash = htpasswd_wrapper('${cat /etc/passwd}', '2.4');
> $passwd_hash = htpasswd_wrapper('echo foo | ls -l', '2.4');
> $passwd_hash = htpasswd_wrapper('echo "foo" > /etc/htpasswd', '2.4');
> ~~~
>
> Stellt sich die Frage, warum man das in Perl tun sollte. Mit [password_hash()](http://php.net/manual/de/function.password-hash.php) in PHP erzeugte Hashs schluckt der Apache 2.4 nämlich.
mfg\\
Woodfighter