Hm.
quotemedia ist leider auch nicht der Weisheit letzter Schluss:
#!/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?
#!/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:
#!/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. "Escape" ich doch wieder selbst … und mach es mir noch einfacher:
#!/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() in PHP erzeugte Hashs schluckt der Apache 2.4 nämlich.