Alain: passwort entfernen in der .htpasswd

Guten morgen,
Ich versuche mich da bei einem cgi skript das sich in einem geschützten bereich befindet.
Das problem ist,ich weiss nicht genau welchen befehl ich benötige um ein
username zu löschen oder zumindest zu ändern im cgi.
Die variable username und htpasswd ist ja bekannt im cgi.
Das hier war mein versuch:

$htpasswd  = '/htdocs/geschützt/.htprivat';

sub del{
if (open File($htpasswd,''))
  {delete {$username} || die "can not open file"; }}

geht aber nicht,brauchts da noch mehr?
Schönen dank
grüsse vom Alain

  1. Hallo Alain

    Ich gehe mal davon aus, dass wir von Apache sprechen (Zeus und andere haben die gleichen Files).

    Um einen Benutzer zu löschen kannst Du einfach den ensprechenden Record (Zeile) im File löschen.

    Ich hoffe allerdings, dass dieser Script nicht von einer öffentlich zugänglichen Seite ausgeführt werden kann, sonst ständen da Sicherheitsprobleme ins Haus.

    Benutzer ändern und anlegen kann man mit dem Befehl 'htpasswd'.
    Hier gilt dann das gleiche wie oben. Dieser Befehl sollte ausserhalb des roots liegen. Wenn Du diesen Befehl trotzdem zugänglich machen möchtest, solltest Du diese Webseite als sogenannte Jailed-Applikation (chroot) betreiben (Leider nicht in Windows möglich).

    Grüsse

    Daniel

  2. Hallo Alain

    Mir ist da noch etwas in den Sinn gekommen, dass Dir vielleicht hilft. Du arbeitest ja mit Perl. Da gibt es ein Modul von CPAN das genau solche Aufgaben handelt. Nachfolgend ein Auszug des entsprechenden Readme.

    Gruss Daniel

    NAME
        Apache::Htpasswd - Manage Unix crypt-style password file.

    SYNOPSIS
            use Apache::Htpasswd;

    $foo = new Apache::Htpasswd("path-to-file");

    # Add an entry
            $foo->htpasswd("zog", "password");

    # Change a password
            $foo->htpasswd("zog", "new-password", "old-password");

    # Change a password without checking against old password
            # The 1 signals that the change is being forced.

    $foo->htpasswd("zog", "new-password", 1);

    # Check that a password is correct
            $pwdFile->htCheckPassword("zog", "password");

    # Fetch an encrypted password
            $foo->fetchPass("foo");

    # Delete entry
            $foo->htDelete("foo");

    # If something fails, check error
            $foo->error;

    # Write in the extra info field
            $foo->writeInfo("login", "info");

    # Get extra info field for a user
            $foo->fetchInfo("login");

    1. hallo Daniel,
      Danke für den tip.Dazu möchte ich aber wissen,ob dieser
      $foo->htpasswd("zog", "new-password", 1);

      z.B.
      direkt im perl ausführbar wäre?
      Ich meine ist das ein offizieller befehl im allgemeinen jetzt für perl?
      Mir ist schon klar,dass man im perl erst die variablen mitteilen muss,
      aber mich interessiert eigentlich nur wie man eine htpasswd öffnet,
      ein vorhandenes username oder passwort direkt ohne wenn und aber ändern kann
      und anschliessend das passfile wieder schliesst.
      Ja es handelt sich um apache und htaccess.Ich möchte mit einem sub
      diesen standard befehl ausführen und wenn nötig später diesen account wieder
      manuell aktivieren,aber das manuelle weiss ich schon.
      Das andere mit dem ändern soll aber automatisch geschehen
      Ich hab da noch ein beispiel:

      $username   = $ENV{'REMOTE_USER'};
      $htpasswd  = '/htdocs/geschützt/.htpasswd';
      $password={'noaccess'};

      sub depas
      {
      if (open files($htpasswd,'>>'))
                      {
        print FILE "$username:$password\n" || die "can not open file";
                               close files(); }
                      }        }

      Habs noch nicht probiert
      aber ich denke er würde in dem fall nur ein neuen usernamen schreiben
      mit dem passwort "noaccess"
      oder seh ich das falsch?
      Grüsse vom Alain

      1. Hallo Alain

        Bei 'Apache::Htpasswd' handelt es sich um ein Modul.
        Du kannst es unter der nachfolgenden URL runterladen.

        Perl-Modul:
        http://www.cpan.org/modules/by-category/15_World_Wide_Web_HTML_HTTP_CGI/Apache/Apache-Htpasswd-1.5.5.tar.gz

        Readme:
        http://www.cpan.org/modules/by-category/15_World_Wide_Web_HTML_HTTP_CGI/Apache/Apache-Htpasswd-1.5.5.readme

        Das Readme enthält eine detaillierte Installationsanweisung.
        Um damit zu arbeiten, musst Du sie dann mit 'use Apache::Htpasswd;'
        in Deinem Code einbinden. Danach kannst mit den genannten Befehlen arbeiten wie wenn sie direkt im Perl vorhanden wären.

        Gruss

        Daniel

        1. Hallo Daniel und CO,
          Ich hoffe ihr seid alle gut gerutscht ins neue Jahr.
          Ich bin mehr oder weniger gesessen,am PC :-)
          Aber ich tus ja gern.Trotzdem muss ich sagen dass es nicht so leicht ist
          mit perl eine einfache textdatei zu öffnen einen eintrag zu änden oder
          zu löschen und dann das dokument wieder zu schliessen.

          Du kannst es unter der nachfolgenden URL runterladen.
          Das Readme enthält eine detaillierte Installationsanweisung.

          Ich hab das vom readme auch gelesen und mal probiert,aber ich denke da gehört
          noch einiges mehr dazu als diesen standart befehl.
          Naja jedenfalls hab ich mal an dem skript von selfhtml rumgebastelt,
          aber da kamen praktisch nur 500 error meldungen.
          Ist es denn überhaubt möglich eine .ht datei mit cgi anzufassen?
          Die datei wurde jedenfalls nicht mal geöffnet von meinem selfhtml-skript.

          Soviel ich weiss muss die .ht datei ja auch geschützt geöffnet werden beim prozess oder?
          Also das skript sieht im moment so aus:

          $htpasswd  = '/homepages/geschützt/.htpasswd';

          $FILE{$username} = $password ( (split(/:/$_))[0] eq $username);

          sub del
          if (open(FILE,$htpasswd,0666)) || die "can not open file";
           flock(FILE,2) if ($doflocks) || die "can not open file";
          {
          if ($username != /webmaster/)
           {
           delete $FILE{$username} || die "can not open file";
           }

          close(FILE);
          flock(FILE,8) if ($doflocks);}

          Die Sache ist die,der browser zeigt nicht mal an dass die datei nicht geöffnet werden kann.
          Grüsse vom Alain

          1. Hallo Alain

            Schönes neues Jahr auch Dir.

            Ich hab das vom readme auch gelesen und mal probiert,aber ich denke da gehört
            noch einiges mehr dazu als diesen standart befehl.
            Naja jedenfalls hab ich mal an dem skript von selfhtml rumgebastelt,
            aber da kamen praktisch nur 500 error meldungen.
            Ist es denn überhaubt möglich eine .ht datei mit cgi anzufassen?
            Die datei wurde jedenfalls nicht mal geöffnet von meinem selfhtml-skript.

            Soviel ich weiss muss die .ht datei ja auch geschützt geöffnet werden beim prozess oder?

            Ich hatte diese Bibliothek in der Vergangenheit mal benutzt. Es gab eigentlich keine Probleme damit. Ich werde mal kramen und Dir ein Beispiel bringen.

            Zur Frage ob dir Datei überhaupt geöffnet werden kann, fürchte ich kommt als Antwort ein klassisches Jein. Die Frage ist, ob die CGI und/oder die Webserverkonfiguration dies zulässt. Normalerweise wird ja im httpd.conf ein Documentroot für die Seite und für cgi die entsprechenden Pfade konfiguriert. Diese stellen dann denn Rootpfad für die jeweiligen Gebilde dar. Ausserhalb dieser Pfade sollte natürlich kein Zugriff erfolgen können. Dies müsstest Du prüfen.

            Kannst Du zum Beispiel den Script mit absoluten Pfad von der Kommandozeile ausführen? Wenn Ja, würde ich mal tippen, dass der CGI-Script aufgrund der oben erwähnten Konfiguration nicht an die Datei rankommt. Schau bitte auch, ob Du eine restriktive <Directory>-Direktive im httpd.conf für das geschützte Verzeichnis gesetzt hast.
            Ferner würden 'illegale' Abfragen auch in den Logfiles des Apache zu sehen sein.

            Dann ist da noch die Frage wie der Apache kompiliert wurde. Zum Beispiel die Direktive '--enable-force-cgi-redirect'.

            Die Frage nach dem geschützt öffnen würde ich mal pauschal mit ja beantworten. Das sollte jedoch kein Problem sein, solange eine Datei nicht exklusiv gesperrt ist. Ich denke hier könnten auch noch OS-spezifische Funktionalitäten zum tragen kommen. Arbeitest Du mit Unix oder Windows?

            Ich werde für die nächsten paar Tage weg sein. Wir haben uns zu einem Spontanurlaub entschlossen. Ich werde mich dann melden.

            Gruss

            Daniel

            1. Hallo Daniel

              Ich hatte diese Bibliothek in der Vergangenheit mal benutzt. Es gab eigentlich keine Probleme damit. Ich werde mal kramen und Dir ein Beispiel bringen.

              cool.
              Also das cgi kann ich überall hinschmeissen auch im geschützten bereich.
              Ich brauch kein spezielles cgi-bin verzeichniss.

              Dann ist da noch die Frage wie der Apache kompiliert wurde. Zum Beispiel die Direktive '--enable-force-cgi-redirect'.

              »»

              Also es sollte eigentlich mit einem cgi möglich sein die .htfile zu öffnen und zu bearbeiten.
              ich denke einfach dass ich da noch was rumschreiben muss bis es eben geht.Kann aber lange dauern.

              Die Frage nach dem geschützt öffnen würde ich mal pauschal mit ja beantworten. Das sollte jedoch kein Problem sein, solange eine Datei nicht exklusiv gesperrt ist. Ich denke hier könnten auch noch OS-spezifische Funktionalitäten zum tragen kommen. Arbeitest Du mit Unix oder Windows?

              Ja mit unix.
              Ich hab da ne vorgabe von einem anderen cgi ,aber das was da alles drinn steht brauch ich nicht.
              Ich benötige nur den teil wo die htacces geöffnet wird und den spezifischen befehl den aktuellen remonte user
              aus der password liste zu knallen,das ist alles.
              Hier waren meine vorgaben:
              #' remove a password from htpasswd
              elsif ($do eq 'remove')
              {
                      foreach $htpass (@htpasswdall)
                      {
                              if (&fileopen($htpass,''))
                              {
                                      if ($isdbfile) {delete $FILE{$username};}
                                      else
                                      {
                                              @newlines = ();
                                              @lines = <FILE>;
                                              &fileclose();
                                              foreach $l (@lines) {
                                                      chomp($l);
                                                      next if (!&OkUname($l));
                                         push @newlines, $l if ($l !~ /^$username:/i);
                                              }
                                              $newfile = join("\n",@newlines);
              &Dead('Cannot backup pass file during remove!') if (!rename($htpass,$htpass . "glo"));
                                              &fileopen($htpass,'>');
                                              print FILE "$newfile\n";
                                              system("chmod 666 $htpass");
                                      }
                                      &fileclose();
                              } else {&Dead('Cannot rw locate or open htpasswd file for rewrite');}
                      }
              }

              Ich werde für die nächsten paar Tage weg sein. Wir haben uns zu einem Spontanurlaub entschlossen. Ich werde mich dann melden.

              schön,sport soll ja gesund sein hab ich gehört,na dann viel Spass
              grüsse vom Alain

              1. Hallo Alain

                Den Spass werde ich haben (hoffe ich) ;-).

                Ich hab noch schnell ein Beispiel generiert. Ich hab's mal auf der Kommadozeile getestet. Läuft tadellos.

                --------- Begin of htpasswd.pl -------------------------------
                #!/usr/bin/perl

                use Apache::Htpasswd;

                $filename = ".htpasswd";
                if ( -e $filename )
                   { print "file ' " . $filename . " already exist"; }
                else
                   { exec("touch " . $filename); }

                $htpasswd = new Apache::Htpasswd($filename);

                Add an entry

                $htpasswd->htpasswd("daniel", "12345");

                Add an entry

                $htpasswd->htpasswd("test", "test");

                Delete entry

                $htpasswd->htDelete("test");

                --------- End of htpasswd.pl -------------------------------

                Gruss

                Daniel

                1. Hallo Daniel
                  Danke für die Ausführung
                  Ich habs gleich getestet wurde aber mit 500 error zurückgewiesen.
                  Als ich use Apache::Htpasswd; und print "Content-type: text/html\n\n";
                  eingefügt habe funktionierte es aber nur im anzeigen vom " already exist"
                  als ich das file gelöscht habe kam wieder 500 error,aber er schrieb das .htfile neu
                  Also zum skript selbst,wenn alles funktionieren soll müsste da lediglich
                  als Bsp.
                  #!/usr/bin/perl  -w

                  print "Content-type: text/html\n\n";

                  $filename = ".htpass";
                  if ( -e $filename )
                     { print "file ' " . $filename . " already exist"; }
                  else
                     { exec("touch " . $filename); }

                  $htpass = new Apache::Htpass($filename);

                  Add an entry

                  $htpass->htpass("daniel", "12345");

                  -------------------------------
                  stehen um ein user pass in die liste zu setzten?
                  Also einfach durch aufruf dieses skriptes meinetwegen mit dem browser?
                  Grüsse vom Alain

                2. Hallo Daniel
                  Ich habs jetzt doch geschafft ohne dieses module,
                  das wahrscheinlich nicht gefuntzt hätte bei mir jedenfalls. :)
                  Ok hier ist die Auflösung dess skriptes falls es Dich interessiert:

                  sub del    {
                  $htpasswd  = '/homepages/geschützt/.htpasswd';
                  $isdbfile            = 0;
                  $ignorecrypts        = 0;

                  $do = $posts{'do'}; $username=$ENV{'REMOTE_USER'};$password=$posts{'password'};
                  @htpasswdall = ($htpasswd);

                  $unameok = &OkUname("$username:$password");
                  $do = 'remove';

                  print "Content-type: text/html\n\n";
                  if ($do eq 'remove')
                  {
                          foreach $htpass (@htpasswdall)
                          {
                          if (&fileopen($htpass,''))
                          {
                          {
                                                  @newlines = ();
                                                  @lines = <FILE>;
                                                  &fileclose();
                                                  foreach $l (@lines)
                                                  {
                                                  chomp($l);
                                                  next if (!&OkUname($l));
                            push @newlines, $l if ($l !~ /^$username:/i);
                                                  }
                                          $newfile = join("\n",@newlines);
                       &Dead('Cannot backup file!') if (!rename($htpass,$htpass . "glo"));
                                                  &fileopen($htpass,'>');
                                                  print FILE "$newfile\n";
                                                  system("chmod 666 $htpass");
                                                  }
                                                  &fileclose();
                                                  }
                                                  else
                        {&Dead('Cannot locate or open file for ');}  }   }

                  &Dead('your user and password has been deleted now contact the webmaster ');

                  sub Dead
                  {
                          #' print a header
                          print "</HTML><HEAD>
                      <META HTTP-EQUIV='REFRESH' CONTENT='5; URL=../abuse.htm'>
                      <TITLE>access denied</Title>
                      <script SRC='mouse.js' type='text/javascript'></script>
                      </HEAD>
                      <BODY BGCOLOR=#000000 TEXT=#FF0000 onLoad='abuse()'>\n";
                          print " " . (@_)[0] . "\n<BR>";
                          print " denied </CENTER><BR></BODY></HTML>\n";
                                                      SendMail();
                                                    }

                  #opening/closing
                  sub fileopen {
                          local($f,$mode) = @_;
                          $res= open(FILE,"$mode$f");
                          &lock();
                          return $res;
                  }
                  sub fileclose {
                          local($f) = @);
                          &unlock();
                          $res= close(FILE);
                          return $res;
                  }
                  #' locking/unlocking
                  sub lock {
                          local($mode)=@_;
                          flock(FILE,2);
                          seek(FILE, 0, 2) if (!$isdbfile && $mode eq '>>');
                  }
                      sub unlock {flock(FILE,8);}
                      sub OkUname {local($str) = @_; chomp $str; return (length($str) >= 4);
                      }
                      }

                  Besten dank und Grüsse vom Alain

      2. hallo Daniel,
        Ich hab da aber noch ein Problem.
        Das cgi das ich habe ist nicht so programiert nach use Apache::Htpasswd;
        und funktioniert noch für andere Dinge.
        Ich möchte aber diese delete oder unlink funktion unbedingt in meinem
        cgi ausführen lassen.
        Gibt es dann keine andere Lösung ?
        Ich habe mich mal im selfhtml umgeschaut und kam darauf:

        open(DATEI, "</tmp/server.cfg") || die "Datei nicht gefunden";
          my @Zeilen = <DATEI>;
          close(DATEI);

        my @NeueZeilen;
          foreach(@Zeilen) {
            $_ =~ s/#.*//;
            push(@NeueZeilen,$_) if $_ !~ /^\s*\n/;
          }
          open(DATEI, ">/tmp/server.cfg") || die "Datei nicht gefunden";
          print DATEI @NeueZeilen;
          close(DATEI);

        könnte man es nicht so in etwa in diesem sinne verarbeiten?
        Grüsse und falls ich nix mehr höre guten rutsch ins 2003
        vom Alain