|
在搭建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/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
- $name=~tr/+//;
- $name=~s/%([a-fA-F0-9][a-fA-F0-9])/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[rand(int($#range)+1)].$range[rand(int($#range)+1)];
- #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;
- }
|
|