2 gleiche User im Geschützen Verz. [forbidden]
Alain
- webserver
Meine Frage diesbezüglich,ist es Möglich diese Funktion (zwei gleiche usernames mit unterschiedlicher IP-addresse für gleichzeitige requests im geschützen bereich-verbieten) nur per htaccess zu steuern ohne an der httpd.conf file was zu ändern?
Grüsse vom Alain--
Moin!
Ich möchte mal wissen ob es irgendwie (nur) mit einer htaccess datei Möglich
wäre einen demensprechenden code reinzuschreiben,der es verbietet zwei gleiche
user in ein geschützes verzeichniss zu lassen?
Ich würde mal tippen: Nein.
Was du brauchst, ist ein Gedächtnis, damit du dir merken kannst, was in der Vergangenheit ausgeliefert wurde. HTTP hat kein Gedächtnis, HTTP liefert einfach nur Ressourcen aus. Der Zugriff auf Ressourcen kann durch Passwort geschützt sein - aber das ändert am grundlegenden Prinzip von HTTP nichts.
Die Frage ist also: Woran willst du erkennen, dass der soeben hereingekommene Request von einem anderen, aber als gleich angemeldeten User kommt, als der Request davor? Dazu müßtest du den Benutzer eindeutig identifizieren. Der Username (authentifiziert durch Passwort) reicht dafür nicht aus, du mußt im Zweifel schon den Browser mit einer eindeutigen Kennung versehen (denn auch die IP-Adresse kann zwischen zwei Zugriffen wechseln). Und nach allem, was die Programmierkunst bisher so hervorgebracht hat, sind solche eindeutigen Kennungen als Sessions bekannt.
Sessions wiederum werden am besten mit einer serverseitigen Programmiersprache ausgewertet, und nicht mit Methoden, die Apache in .htaccess-Dateien bereitstellt. Mir ist in der Tat nicht bekannt, dass Apache überhaupt irgendwelche Programmiermöglichkeiten in der .htaccess (oder auch in der httpd.conf) anbietet, was natürlich auch eine Wissenslücke meinerseits sein kann. Jedenfalls ist bei den üblicherweise zu erwartenden Apache-Installationen wohl eher nicht davon auszugehen, dass Session-Mechanismen (und darauf aufbauende Methoden zur Userverwaltung) zur Verfügung stehen.
Allerdings frage ich mich, welches Anliegen hinter deiner Frage steckt. Als Nutzer eines Content Management Systems namens Reddot ärgere ich mich immer tierisch, weil ich als Benutzer nicht die Möglichkeit habe, als ein Benutzer mit mehreren Browserfenstern zu arbeiten, um diverse Ansichten auf das System zu erhalten. Ich kann mich pro Browser nur mit einer einzigen Userkennung anmelden - und Mehrfachfenster sind verboten. Ich bin gezwungen, für die effektive Arbeit mit dem System _zwei Rechner_ mit zwei Benutzeranmeldungen zu nutzen.
Also frage ich mich natürlich, was du bezwecken willst. Einschränkungen der Benutzer sind in den seltensten Fällen sinnvoll, insbesondere dann, dafür die Ausschaltung bzw. Umgehung von vollkommen natürlichen Gegebenheiten des HTTP-Protokolls notwendig sind. Viel Aufwand für viel Usereinschränkung, wo wenig Aufwand für keine Usereinschränkung möglicherweise besser wären.
Also: Was planst du?
- Sven Rautenberg
Moin,
Also frage ich mich natürlich, was du bezwecken willst. Einschränkungen der Benutzer sind in den seltensten Fällen sinnvoll, insbesondere dann, dafür die Ausschaltung bzw. Umgehung von vollkommen natürlichen Gegebenheiten des HTTP-Protokolls notwendig sind. Viel Aufwand für viel Usereinschränkung, wo wenig Aufwand für keine Usereinschränkung möglicherweise besser wären.
Also: Was planst du?
ok schwierigschwierig, Ich weiss irgendwie gehts auf jeden Fall,weil ichs selber gesehen habe,jedoch nur durchs surfen,desshalb kam ich auf diese idee. Ich weiss es mag für Dich nicht möglich sein. Ich redete ja auch vom request bzw. während des laden einer datei, wenn jetzt zwei gleiche user im geschützen verzeichniss eine datei gleichzeitig anfordern dann sendet der jweilige client dem server die user daten und der server gibt dann die daten raus... das heisst dem server sind die daten wie remonte user und remonte address also die IP bekannt, wenn jetzt beim laden einer datei von userNr.1 der server eine anfrage vom anderen user mit dem selben usernamen,aber anderen IP erhält so müsste der server mit [F] wie forbidden dem anderen client antworten. Weiss jetzt nicht ob das deutlich genug war? Beim apache hab ich mal was davon gelesen jedenfalls über mein oben geschriebenes ,jedoch war mir dies etwas zu english :) http://httpd.apache.org/docs/mod/mod_rewrite.html#RewriteCond
Hi Sven,
Mir ist in der Tat nicht bekannt, dass Apache überhaupt irgendwelche Programmiermöglichkeiten in der .htaccess (oder auch in der httpd.conf) anbietet, was natürlich auch eine Wissenslücke meinerseits sein kann.
mehr als mod_setenvif und mod_rewrite fällt mir spontan auch nicht ein - jedenfalls kein Standardmodul mit Request-übergreifendem Gedächtnis. Cookies gelten in unserem Fall ja nicht als Lösung.
Also frage ich mich natürlich, was du bezwecken willst. Einschränkungen der Benutzer sind in den seltensten Fällen sinnvoll, insbesondere dann, dafür die Ausschaltung bzw. Umgehung von vollkommen natürlichen Gegebenheiten des HTTP-Protokolls notwendig sind. Viel Aufwand für viel Usereinschränkung, wo wenig Aufwand für keine Usereinschränkung möglicherweise besser wären.
Naja, wenn man Benutzerkennungen pro Stück bezahlt bekommt, dann will man nicht unbedingt, daß beliebig viele Kunden dieselbe Kennung parallel benutzen ...
Viele Grüße
Michael
Moin,
Ich möchte mal wissen ob es irgendwie (nur) mit einer htaccess datei
Möglich wäre einen demensprechenden code reinzuschreiben,der es verbietet
zwei gleiche user in ein geschützes verzeichniss zu lassen?
Da du mit der .htaccess nur die Konfiguration des Apache beeinflussen kannst und der Apache ein Webserver ist, der HTTP spricht: Nein.
HTTP kennt weder das Konzept eines Users (im Sinne von einem Menschen vor einer Maschine) noch das Konzept des in einem Verzeichnis seins. Zumindest letzteres könntest du mit FTP hinkriegen, aber User unterscheiden kann keine Software.
Wenn du glaubst, dass dir die IP-Addresse als Menschenkennung reicht, dann mag dein Anliegen mit FTP oder etwas über HTTP draufgelegtem (PHP mit Sessions und einer Datenbank etwa) realisierbar sein, aber Vorsicht: Ein User kann mehrere IP-Addressen haben und mehrere IP-Addressen können einen User haben.
#!/usr/bin/perl
###################################################### # Pennywize Online Client # Version 2.0, December 17, 2001 ######################################################
# Pennywize Online # Copyright (C) 1997-2001 Zarvon Pty Ltd # All Rights Reserved
# See http://www.pennywize.com for more info
# written consent of the author.
###################################################### use Socket;
$PENNYWIZE_USERNAME = "meinusername"; $PENNYWIZE_PASSWORD = "meinpasswort";
$PENNYWIZE_SERVER = "online.pennywize.com"; $PENNYWIZE_PORT = "80"; $PENNYWIZE_VERSION="2.0-20011217"; $BAPS = 2; $BAPS_TIME = 60;
# Signal Handler $SIG{'HUP'} = sub { exit(0) };
if (defined($ENV{'SCRIPT_FILENAME'})) { # Unblock Output $|=1;
# Extract the QUERY STRING variables %params = (); @query_string = split(/[&;]/, $ENV{'QUERY_STRING'}); foreach $i (0 .. $#query_string) { # Split $params[$i] =~ s/+/ /g; ($key, $val) = split(/=/,$query_string[$i],2); $key =~ s/%(..)/pack("c",hex($1))/ge; $val =~ s/%(..)/pack("c",hex($1))/ge; $params{$key} .= "\0" if (defined($query_string{$key})); $params{$key} .= $val; }
# Determine the CGIBIN_PATH ($CGIBIN_PATH, $ignore) = &SplitPath ($ENV{'SCRIPT_FILENAME'}); $CGIBIN_PATH =~ s//$//;
# If cgiwrap is involved, fix it if (($CGIBIN_PATH =~ /cgiwrap/) && (-r $ENV{'PATH_TRANSLATED'})) { ($CGIBIN_PATH, $ignore) = &SplitPath ($ENV{'PATH_TRANSLATED'}); $CGIBIN_PATH =~ s//$//; }
# Taint Checking $failed = 0; $failed = 1 if ($params{'ACTION'} !~ /^\w*$/); $failed = 1 if ($params{'SITE'} !~ /^\w*$/); $failed = 1 if ($params{'PASSWORD'} !~ /^\w*$/); $failed = 1 if ($params{'DATA'} =~ /\/~|/); $failed = 1 if ($params{'TIME'} !~ /^\d*$/);
if ($failed == 1) { # Print out the header print "Content-type: text/html\n\n";
&WelcomeScreen; print "ERROR: One or more of your variables failed taint checking\n"; exit; }
# Validate the password if ($params{'PASSWORD'} eq $PENNYWIZE_PASSWORD) { # Check the action if (!(defined($params{'ACTION'}))) { # Print out the header print "Content-type: text/html\n\n";
&WelcomeScreen; &TestSetup($params{'SITE'}); }
if ($params{'ACTION'} eq "DISABLE") { # Print out the header print "Content-type: text/html\n\n";
$result = &AddRule ($params{'DATA'}, $params{'SITE'}, $params{'TIME'}); print $result; } } else { # Print out the header print "Content-type: text/html\n\n";
&WelcomeScreen; print "You are not authorised to access this script [$ENV{'REMOTE_ADDR'}]\n"; } exit; }
# Determine the CGIBIN_BASE ($CGIBIN_PATH, $ignore) = &SplitPath ($0); $CGIBIN_PATH =~ s//$//; if (($CGIBIN_PATH !~ /^//) || (!(-d "$CGIBIN_PATH/pennywize"))) { print ("Pennywize has been incorrectly called. Please email support@pennywize.com\n"); exit (1); }
# Children Process Handling $SIG{CHLD} = sub { wait };
%hits = (); %bytes = (); %blocked = (); %second_attempts = (); ($last_minute, $last_second) = &GetTime(); while ($line = <STDIN>) { chop ($line); if ($line =~ /^.+|.+|\d+|.+$/) { ($ip, $username, $status, $site, $bytes) = split (/|/, $line); if (($username ne "-") && (($status eq "200") || ($status eq "401")) && ($ip =~ /^\d+.\d+.\d+.\d+$/)) { # Form the subnet only @ipz = split (/./, $ip); $subnet = "$ipz[0].$ipz[1].$ipz[2]";
# Regular hit if ($status eq "401") { $username = "$-PPP-$"; $subnet = $ip; $status = "200"; }
# Get the time ($this_minute, $this_second) = &GetTime();
if ($status eq "200") { # Add the hit if (defined($hits{"$site|$username|$subnet"})) { $hits{"$site|$username|$subnet"}++; $bytes{"$site|$username|$subnet"} += $bytes; $second_attempts{"$site|$username|$subnet|$this_second"}++; } else { $hits{"$site|$username|$subnet"} = 1; $bytes{"$site|$username|$subnet"} = $bytes; $second_attempts{"$site|$username|$subnet|$this_second"} = 1; }
# Check to see if this 401 exceeds the limit per second if ($username eq "$-PPP-$") { if ($second_attempts{"$site|$username|$subnet|$this_second"} >= $BAPS) { if ($blocked{"$site|$subnet"} ne "1") { &AddRule ($subnet, $site, $BAPS_TIME); $blocked{"$site|$subnet"} = "1"; } } } }
# Check the current minute if ($this_minute != $last_minute) { if (fork() == 0) { # Flush all the hits &ProcessHits (%hits, %bytes);
# Expire IP address bans &ExpireFiles();
# Exit child process exit; }
%hits = (); %bytes = (); %blocked = (); %second_attempts = (); $last_minute = $this_minute; } } } } exit;
sub ProcessHits { local ($hits, $bytes) = @_; local ($combo, $numhits); local ($query, $rin, $win, $ein, $timeout, $nfound, $timeleft) = "";
if (&EstablishConnection) { print PPP "POST /cgi-bin/ppp_server_isp.pl HTTP/1.0\n"; print PPP "Connection: Keep-Alive\n"; print PPP "User-Agent: Pennywize Password Protection/2.0\n"; print PPP "Host: online.pennywize.com\n"; print PPP "Content-type: application/x-www-form-urlencoded\n";
# Construct the content string $query = "DATA="; while (($combo, $numhits) = each (%$hits)) { ($site, $username, $ip) = split (/|/, $combo); $bytez = $$bytes{$combo} || 0; $query .= &Escape("$PENNYWIZE_USERNAME|$PENNYWIZE_PASSWORD|$site|$username|$ip|$numhits|$bytez|$PENNYWIZE_VERSION\n"); }
# Calculate the length of the content print PPP "Content-length: ".length($query)."\n";
# Print the content print PPP "\n$query\n";
# Wait for any response or max 30 seconds $rin = $win = $ein = ''; vec($rin,fileno(PPP),1) = 1; $ein = $rin | $win; $timeout = 30; ($nfound,$timeleft) = select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
# Close the connection &CloseConnection; }
}
sub EstablishConnection { local ($pppaddr, $oldfh);
# Get the server address $pppaddr = ($PENNYWIZE_SERVER =~ /^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})$/) ? pack('C4',$1,$2,$3,$4) : (gethostbyname($PENNYWIZE_SERVER))[4];
# Get the socket $proto = (getprotobyname('tcp'))[2]; if (!socket(PPP, AF_INET, SOCK_STREAM, $proto)) { return (0); }
if (!(connect(PPP, sockaddr_in($PENNYWIZE_PORT, $pppaddr)))) { return (0); }
# Unbuffer the output $oldfh = select(PPP); $| = 1; select($oldfh);
# Return Success return (1); }
sub CloseConnection { shutdown (PPP, 2); }
sub GetTime { local ($sec, $min, $ignore, $ignore, $ignore, $ignore) = localtime(time); return ($min, $sec); }
sub Escape { local ($text) = @_; local ($escapes);
return undef unless defined $text;
# Build the escape hash for (0..255) { $escapes{chr($)} = sprintf("%%%02X", $); }
# Default unsafe characters. (RFC 2396 ^uric) $text =~ s/([^;/?:@&=+$,A-Za-z0-9-_.!~*'()])/$escapes{$1}/g;
return ($text); }
sub AddRule { local ($data, $site, $time) = @_; my ($now); my ($directory) = "$CGIBIN_PATH/pennywize/$site"; my ($filename) = "$directory/$data";
# Create the sub-directory if it doesnt exist mkdir ($directory, 0777) or return ("Unable to create directory $directory") if (!(-d $directory)); chmod 0777, $directory;
# Write out the data if (!(-e $filename)) { open (OUTPUT, "> $filename") or return ("Unable to open file $filename"); close (OUTPUT); chmod 0777, $filename;
# Change the file modification time $now = time() + $time; utime $now, $now, $filename; }
# Return return ("Disable rule successfully written:\n$CGIBIN_PATH/pennywize/$site/$data\n"); }
sub ExpireFiles { local ($dir, $file, $age); local (@files) = ();
# Get all the files opendir (DIR, "$CGIBIN_PATH/pennywize"); while ($dir = readdir(DIR)) { # Test to see if it's a directory if ((-d ("$CGIBIN_PATH/pennywize/$dir")) && ($dir !~ /^./)) { # Get all files within the directory opendir (FILES, "$CGIBIN_PATH/pennywize/$dir"); while ($file = readdir(FILES)) { if (-f "$CGIBIN_PATH/pennywize/$dir/$file") { push (@files, "$CGIBIN_PATH/pennywize/$dir/$file"); } } closedir (FILES); } } closedir (DIR);
for (@files) { local ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($_);
# Remove the block if the file has 'expired' if ((time() > $mtime) && ($size == 0)) { unlink ($_); } } }
sub SplitPath { my ($path) = @_; my ($directory,$file) = ('','','');
This code may not be redistributed in part or in whole
without the written consent of the author.
Hast du eine schriftliche Genehmigung dafür?
H.
Moin,
Hast du eine schriftliche Genehmigung dafür?
das musste ja kommen,nö nicht, aber ich hätte diesen autortext ja auch löschen können, dann wärs auch gewesen...nun jetzt bin ich wohl verkauft oder?