使用htpasswd.pl脚本远程管理apache密码文件

来源:互联网 发布:手机传奇辅助软件 编辑:程序博客网 时间:2024/06/07 04:59
   在搭建trac/svn系统时,一般都会采用apache的.htacces 认证方法 但trac本身并不提供修改密码的功能,修改密码只能通过htpasswd/htpasswd2命令来进行,这的确是一件相当不make sense的事。
   其实,利用一个免费的perl脚本可以方便的通过http方式修改apache的认证文件。
  文件名:htpasswd.pl,获取地址http://home.xnet.com/~efflandt/pub/htpasswd.pl
   该脚本可以通过web浏览器从你的htpasswd文件直接增加或者删除用户,管理者密码是经过加密的。该脚本本身并不保护一个目录,也不创建一个口令保护功能。它仅用来帮助你管理你的口令文件。这就是说在你的服务器上事先应有口令文件时,该脚本方可发挥作用。

   安装&配置

   step1.拷贝htpasswd.pl至cgi-bin目录
   suse对应/srv/www/cgi-bin
   fedora对应/var/www/cgi-bin
   step2.改名
   把htpasswd.pl改名为htpasswd.cgi
   step3.
用文本编辑器打开配置脚本(cfg.pl)
    编辑如下变量:
    #!/usr/local/bin/perl 修改为 #!/bin/perl
    配置要修改的apache认证文件,找到以下几行
   
# Password file with full system path (where not accessible by URL).
    $file = '/full_path_to/.htpasswd';
修改为 $file='/etc/svn-auth-file'#假设你的验证文件是/etc/svn-auth-file  
   step4 chmod 755 htpasswd.cgi

   不出意外的话,访问http://localhost/cgi-bin/htpasswd.cgi即可出现密码修改页面
 有关密码文件创建,请参见 http://blog.csdn.net/forlinux/archive/2006/06/11/787703.aspx
 
  -----htpasswd.pl-------
  1. #! /usr/local/bin/perl -T
  2. # htpasswd.cgi by David Efflandt (efflandt@xnet.com) 8/97
  3. # Last update 10/4/99
  4. #
  5. # Update password file from the web for use with user authentication.
  6. # Stores each line in the format: username:crypted_password
  7. #
  8. # Built-in form is provided if you GET the script.
  9. # Form is processed if you POST to this script.
  10. #
  11. # If you want your passwords to be secure, it is best to run this
  12. # suid as you (chmod 4705 htpasswd.cgi) which may require C wrapper.
  13. # Also keep this script in a directory that requires user authentication
  14. # unless you allow new users to set their own password (see $allow_new).
  15. #
  16. # If not running suid you should touch the password file first and
  17. chmod 606 (or whatever is req'd to access it as you and webserver).
  18. #
  19. # To add or remove users by an administrator, create a user called 'admin'
  20. # with a password.  Enter username you want to add or remove with admin
  21. # password as "Current Password" (plus new passwords for new users).
  22. #
  23. # Anyone may remove their own name from the password file if they supply
  24. # their correct password.
  25. ### Variables
  26. # Password file with full system path (where not accessible by URL).
  27. $file = '/full_path_to/.htpasswd';
  28. # Allow anyone to add new users (1 = yes, 0 = no)
  29. $allow_new = 0;
  30. # Set untainted path for suid scripts
  31. $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
  32. $ENV{IFS} = "" if $ENV{IFS} ne "";
  33. ### End of Variables
  34. # Create form and exit on GET
  35. &make_form unless ($ENV{'REQUEST_METHOD'} eq "POST");
  36. # Get POST input
  37. read(STDIN, $buffer$ENV{'CONTENT_LENGTH'});
  38. # Split the name-value pairs
  39. @pairs = split(/&/, $buffer);
  40. foreach $pair (@pairs)
  41. {
  42.   ($name$value) = split(/=/, $pair);
  43.   $value =~ tr/+/ /;
  44.   $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  45.   $name =~ tr/+/ /;
  46.   $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  47.   $FORM{$name} = $value;
  48. }
  49. if ($FORM{user}) {
  50.   $user = $FORM{user};
  51. else {
  52.   &error("Error""Username missing from form.");
  53. }
  54. $pwd = $FORM{old};
  55. $command = $FORM{command};
  56. unless (($command eq 'remove')
  57.     ||($FORM{new} && $FORM{new} eq $FORM{new2})) {
  58.   &error("Password Mismatch""New password mismatch or missing.");
  59. }
  60. # Get existing passwords
  61. if (-e $file) {
  62.   open (IN, $fileor &error("Error""Can't open password file: $!");
  63.   flock(IN,2);
  64.   seek(IN,0,0);
  65.   while (<IN>) {
  66.     chomp;
  67.     ($name$value$tail) = split(/:/, $_, 3);
  68.     $hash{$name} = $value;
  69.     $tail{$name} = $tail;   # maintain any additional fields
  70.   }
  71.   close IN;
  72. }
  73. # Salt for crypt
  74. @range = ('0'..'9','a'..'z','A'..'Z','.','/');
  75. srand ( time() ^ ($$ + ($$ << 15)) );
  76. $salt = $range[rand(int($#range)+1)] . $range[rand(int($#range)+1)];
  77. # Check for valid password or existing user
  78. $pass = $hash{$userif $hash{$user};
  79. $cpwd = crypt($pwd$pass);
  80. $admin = $hash{admin} && crypt($pwd$hash{admin}) eq $hash{admin};
  81. if (($command ne 'new') && ($admin || $pass && $cpwd eq $pass)) {
  82.   if ($command eq 'remove') {
  83.     delete($hash{$user}); delete($tail{$user});
  84.     $msg = "User <B>$user</B> was removed from password file.";
  85.   } elsif (!$pass) {
  86.     $msg = "WARNING! 'Change Password' checked for non-existing user?/n"
  87.     . "<P>Assigning password for new user <B>$user</B> anyway./n"
  88.     . "<P>If this was an error, go back and 'Remove User'";
  89.   } else {
  90.     $msg = "Password has been updated for $user.";
  91.   }
  92. } elsif ($FORM{command} eq 'new') {
  93.   if ($pass) {
  94.     &error("Sorry""User <B>$user</B> is already assigned.");
  95.   }elsif ($allow_new || $admin) {
  96.     $msg = "Password has been assigned for new user $user.";
  97.   } else {
  98.     &begin_html("Sorry, New User");
  99.     print "Contact file owner for password you can change later.";
  100.     &end_html;
  101.     exit;
  102.   }
  103. else {
  104.   &error("Password Error"
  105.     "Invalid user or password or forgot to check 'New User'.");
  106. }
  107. # Assign new password to user and write to file
  108. $hash{$user} = crypt($FORM{new}, $saltif $command ne 'remove';
  109. if (open(OUT, ">$file")) {
  110.   flock(OUT,2);
  111.   seek(OUT,0,0);
  112.   foreach $name (sort keys %hash) {
  113.     print OUT "$name:$hash{$name}";
  114.     print OUT ":$tail{$name}" if $tail{$name};
  115.     print OUT "/n";
  116.   }
  117. else {
  118.   &error("Error","Can't update password file: $!");
  119. }
  120. # Print Return HTML
  121. &begin_html("Thank You");
  122. print "$msg/n";
  123. &end_html;
  124. ### Subroutines
  125. #subroutine begin_html(title)
  126. sub begin_html {
  127.   local ($title) = @_;
  128.   print "Content-type: text/html/n/n";
  129.   print "<html><head><title>$title</title></head><body>/n";
  130.   print "<center><h1>$title</h1></center>/n<hr><p>/n";
  131. }
  132. #subroutine end_html
  133. sub end_html {
  134. # Add footer links here
  135.   print "<P></body></html>/n";
  136. }
  137. #subroutine make_form
  138. sub make_form {
  139.   &begin_html("Change or Add Password");
  140. print <<NEW_FORM;
  141. Use this form to change your password for access to restricted
  142. directories here.  New users will be informed if password was assigned or
  143. if they need to contact the owner of these pages.
  144. <FORM METHOD="POST" ACTION="$ENV{SCRIPT_NAME}">
  145. <DL>
  146. <DT> E-mail Address (or username on this system): 
  147.  <DD><INPUT NAME="user">
  148. <DT> Current Password (required unless new user): 
  149.  <DD><INPUT TYPE=PASSWORD NAME="old">
  150. <DT> New Password: 
  151.  <DD><INPUT TYPE=PASSWORD NAME="new">
  152. <DT> Confirm New Password: 
  153.  <DD><INPUT TYPE=PASSWORD NAME="new2">
  154. <DT>Request:
  155.  <DD>
  156.   <INPUT TYPE="radio" NAME="command" VALUE="change" CHECKED> Change Password
  157.  <DD>
  158.   <INPUT TYPE="radio" NAME="command" VALUE="new"> New User
  159.  <DD>
  160.   <INPUT TYPE="radio" NAME="command" VALUE="remove"> Remove User
  161. </DL>
  162. <P><INPUT TYPE="submit" VALUE=" Submit Request ">
  163. </FORM>
  164. NEW_FORM
  165.   &end_html;
  166.   exit;
  167. }
  168. sub error {
  169.   local($title,$msg) = @_;
  170.   &begin_html($title);
  171.   print "<P>$msg/n";
  172.   print "<P>Please check your name and re-enter passwords./n";
  173.   &end_html;
  174.   exit;
  175. }

 
原创粉丝点击