lishenghan 发表于 2017-1-11 09:06:04

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

在搭建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-------

[*]#!/usr/local/bin/perl-T
[*]
[*]#htpasswd.cgibyDavidEfflandt(efflandt@xnet.com)8/97
[*]#Lastupdate10/4/99
[*]#
[*]#Updatepasswordfilefromthewebforusewithuserauthentication.
[*]#Storeseachlineintheformat:username:crypted_password
[*]#
[*]#Built-informisprovidedifyouGETthescript.
[*]#FormisprocessedifyouPOSTtothisscript.
[*]#
[*]#Ifyouwantyourpasswordstobesecure,itisbesttorunthis
[*]#suidasyou(chmod4705htpasswd.cgi)whichmayrequireCwrapper.
[*]#Alsokeepthisscriptinadirectorythatrequiresuserauthentication
[*]#unlessyouallownewuserstosettheirownpassword(see$allow_new).
[*]#
[*]#Ifnotrunningsuidyoushouldtouchthepasswordfilefirstand
[*]#chmod606(orwhateverisreq'dtoaccessitasyouandwebserver).
[*]#
[*]#Toaddorremoveusersbyanadministrator,createausercalled'admin'
[*]#withapassword.Enterusernameyouwanttoaddorremovewithadmin
[*]#passwordas"CurrentPassword"(plusnewpasswordsfornewusers).
[*]#
[*]#Anyonemayremovetheirownnamefromthepasswordfileiftheysupply
[*]#theircorrectpassword.
[*]
[*]###Variables
[*]
[*]#Passwordfilewithfullsystempath(wherenotaccessiblebyURL).
[*]$file='/full_path_to/.htpasswd';
[*]
[*]#Allowanyonetoaddnewusers(1=yes,0=no)
[*]$allow_new=0;
[*]
[*]#Setuntaintedpathforsuidscripts
[*]$ENV{PATH}='/bin:/usr/bin:/usr/local/bin';
[*]$ENV{IFS}=""if$ENV{IFS}ne"";
[*]
[*]###EndofVariables
[*]
[*]#CreateformandexitonGET
[*]&make_formunless($ENV{'REQUEST_METHOD'}eq"POST");
[*]
[*]#GetPOSTinput
[*]read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
[*]
[*]#Splitthename-valuepairs
[*]@pairs=split(/&/,$buffer);
[*]
[*]foreach$pair(@pairs)
[*]{
[*]($name,$value)=split(/=/,$pair);
[*]
[*]$value=~tr/+//;
[*]$value=~s/%()/pack("C",hex($1))/eg;
[*]$name=~tr/+//;
[*]$name=~s/%()/pack("C",hex($1))/eg;
[*]
[*]$FORM{$name}=$value;
[*]}
[*]
[*]if($FORM{user}){
[*]$user=$FORM{user};
[*]}else{
[*]&error("Error","Usernamemissingfromform.");
[*]}
[*]$pwd=$FORM{old};
[*]$command=$FORM{command};
[*]unless(($commandeq'remove')
[*]||($FORM{new}&&$FORM{new}eq$FORM{new2})){
[*]&error("PasswordMismatch","Newpasswordmismatchormissing.");
[*]}
[*]
[*]#Getexistingpasswords
[*]if(-e$file){
[*]open(IN,$file)or&error("Error","Can'topenpasswordfile:$!");
[*]flock(IN,2);
[*]seek(IN,0,0);
[*]while(<IN>){
[*]chomp;
[*]($name,$value,$tail)=split(/:/,$_,3);
[*]$hash{$name}=$value;
[*]$tail{$name}=$tail;#maintainanyadditionalfields
[*]}
[*]closeIN;
[*]}
[*]
[*]#Saltforcrypt
[*]@range=('0'..'9','a'..'z','A'..'Z','.','/');
[*]srand(time()^($$+($$<<15)));
[*]$salt=$range.$range;
[*]
[*]#Checkforvalidpasswordorexistinguser
[*]$pass=$hash{$user}if$hash{$user};
[*]$cpwd=crypt($pwd,$pass);
[*]$admin=$hash{admin}&&crypt($pwd,$hash{admin})eq$hash{admin};
[*]
[*]if(($commandne'new')&&($admin||$pass&&$cpwdeq$pass)){
[*]if($commandeq'remove'){
[*]delete($hash{$user});delete($tail{$user});
[*]$msg="User<B>$user</B>wasremovedfrompasswordfile.";
[*]}elsif(!$pass){
[*]$msg="WARNING!'ChangePassword'checkedfornon-existinguser?\n"
[*]."<P>Assigningpasswordfornewuser<B>$user</B>anyway.\n"
[*]."<P>Ifthiswasanerror,gobackand'RemoveUser'";
[*]}else{
[*]$msg="Passwordhasbeenupdatedfor$user.";
[*]}
[*]}elsif($FORM{command}eq'new'){
[*]if($pass){
[*]&error("Sorry","User<B>$user</B>isalreadyassigned.");
[*]}elsif($allow_new||$admin){
[*]$msg="Passwordhasbeenassignedfornewuser$user.";
[*]}else{
[*]&begin_html("Sorry,NewUser");
[*]print"Contactfileownerforpasswordyoucanchangelater.";
[*]&end_html;
[*]exit;
[*]}
[*]}else{
[*]&error("PasswordError",
[*]"Invaliduserorpasswordorforgottocheck'NewUser'.");
[*]}
[*]
[*]#Assignnewpasswordtouserandwritetofile
[*]$hash{$user}=crypt($FORM{new},$salt)if$commandne'remove';
[*]if(open(OUT,">$file")){
[*]flock(OUT,2);
[*]seek(OUT,0,0);
[*]foreach$name(sortkeys%hash){
[*]printOUT"$name:$hash{$name}";
[*]printOUT":$tail{$name}"if$tail{$name};
[*]printOUT"\n";
[*]}
[*]}else{
[*]&error("Error","Can'tupdatepasswordfile:$!");
[*]}
[*]
[*]#PrintReturnHTML
[*]&begin_html("ThankYou");
[*]print"$msg\n";
[*]&end_html;
[*]
[*]###Subroutines
[*]
[*]#subroutinebegin_html(title)
[*]subbegin_html{
[*]local($title)=@_;
[*]print"Content-type:text/html\n\n";
[*]print"<html><head><title>$title</title></head><body>\n";
[*]print"<center><h1>$title</h1></center>\n<hr><p>\n";
[*]}
[*]
[*]#subroutineend_html
[*]subend_html{
[*]#Addfooterlinkshere
[*]print"<P></body></html>\n";
[*]}
[*]
[*]#subroutinemake_form
[*]submake_form{
[*]&begin_html("ChangeorAddPassword");
[*]
[*]print<<NEW_FORM;
[*]Usethisformtochangeyourpasswordforaccesstorestricted
[*]directorieshere.Newuserswillbeinformedifpasswordwasassignedor
[*]iftheyneedtocontacttheownerofthesepages.
[*]
[*]<FORMMETHOD="POST"ACTION="$ENV{SCRIPT_NAME}">
[*]
[*]<DL>
[*]<DT>E-mailAddress(orusernameonthissystem):
[*]<DD><INPUTNAME="user">
[*]
[*]<DT>CurrentPassword(requiredunlessnewuser):
[*]<DD><INPUTTYPE=PASSWORDNAME="old">
[*]
[*]<DT>NewPassword:
[*]<DD><INPUTTYPE=PASSWORDNAME="new">
[*]
[*]<DT>ConfirmNewPassword:
[*]<DD><INPUTTYPE=PASSWORDNAME="new2">
[*]
[*]<DT>Request:
[*]<DD>
[*]<INPUTTYPE="radio"NAME="command"VALUE="change"CHECKED>ChangePassword
[*]<DD>
[*]<INPUTTYPE="radio"NAME="command"VALUE="new">NewUser
[*]<DD>
[*]<INPUTTYPE="radio"NAME="command"VALUE="remove">RemoveUser
[*]</DL>
[*]
[*]<P><INPUTTYPE="submit"VALUE="SubmitRequest">
[*]</FORM>
[*]NEW_FORM
[*]
[*]&end_html;
[*]exit;
[*]}
[*]
[*]suberror{
[*]local($title,$msg)=@_;
[*]&begin_html($title);
[*]print"<P>$msg\n";
[*]print"<P>Pleasecheckyournameandre-enterpasswords.\n";
[*]&end_html;
[*]exit;
[*]}
[*]


页: [1]
查看完整版本: 使用htpasswd.pl脚本远程管理apache密码文件