⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_htaccess.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 3 页
字号:
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%%%% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%-module(mod_htaccess).-export([do/1, load/2]).-include("httpd.hrl").%% We will not make the change to use base64 in stdlib in inets just yet.%% it will be included in the next major release of inets. -compile({nowarn_deprecated_function, {http_base_64, encode, 1}}).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Public methods that interface the eswapi                         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %----------------------------------------------------------------------% Public method called by the webbserver to insert the data about% Names on accessfiles%----------------------------------------------------------------------load("AccessFileName" ++ FileNames, _Context)->    CleanFileNames=httpd_conf:clean(FileNames),    {ok,[],{access_files,string:tokens(CleanFileNames," ")}}.%----------------------------------------------------------------------% Public method that the webbserver calls to control the page %----------------------------------------------------------------------do(Info)->    case httpd_util:key1search(Info#mod.data,status) of	{_Status_code, _PhraseArgs, _Reason}->	    {proceed,Info#mod.data};	undefined ->	    control_path(Info)    end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                  %%%% The functions that start the control if there is a accessfile    %%%% and if so controls if the dir is allowed or not                  %%%%                                                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------------------------------------%Info = record mod as specified in httpd.hrl           %returns either {proceed,Info#mod.data}%{proceed,[{status,403....}|Info#mod.data]}%{proceed,[{status,401....}|Info#mod.data]}%{proceed,[{status,500....}|Info#mod.data]}%----------------------------------------------------------------------control_path(Info) ->    Path = mod_alias:path(Info#mod.data,			  Info#mod.config_db,			  Info#mod.request_uri),    case isErlScriptOrNotAccessibleFile(Path,Info) of	true->	    {proceed,Info#mod.data};	false->	    case getHtAccessData(Path,Info)of		{ok,public}->		    %%There was no restrictions on the page continue		    {proceed,Info#mod.data};		{error, _Reason} ->		    %%Something got wrong continue or quit??????????????????/                   {proceed,Info#mod.data};		{accessData,AccessData}->		    controlAllowedMethod(Info,AccessData)	    end    end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                  %%%% These methods controls that the method the client used in the    %%%% request is one of the limited                                    %%%%                                                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------------------------------------%Control that if the accessmethod used is in the list of modes to challenge%%Info is the mod record as specified in httpd.hrl%AccessData is an ets table whit the data in the .htaccessfiles%----------------------------------------------------------------------controlAllowedMethod(Info,AccessData)->    case allowedRequestMethod(Info,AccessData) of	allow->	    %%The request didnt use one of the limited methods	    ets:delete(AccessData),	    {proceed,Info#mod.data};	challenge->	    authenticateUser(Info,AccessData)    end.%----------------------------------------------------------------------%Check the specified access method in the .htaccessfile%----------------------------------------------------------------------allowedRequestMethod(Info,AccessData)->    case ets:lookup(AccessData,limit) of	[{limit,all}]->	    challenge;	[{limit,Methods}]->	    isLimitedRequestMethod(Info,Methods)    end.%----------------------------------------------------------------------%Check the specified accessmethods in the .htaccesfile against the users %accessmethod%%Info is the record from the do call%Methods is a list of the methods specified in the .htaccessfile%----------------------------------------------------------------------isLimitedRequestMethod(Info,Methods)->    case lists:member(Info#mod.method,Methods) of	true->	    challenge;	false ->	    allow    end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                  %%%% These methods controls that the user comes from an allowwed net  %%%% and if so wheather its a valid user or a challenge shall be      %%%% generated                                                        %%%%                                                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%----------------------------------------------------------------------%The first thing to control is that the user is from a network%that has access to the page%---------------------------------------------------------------------- authenticateUser(Info,AccessData)->    case controlNet(Info,AccessData) of	allow->	    %the network is ok control that it is an allowed user	    authenticateUser2(Info,AccessData);	deny->	    %The user isnt allowed to access the pages from that network	    ets:delete(AccessData),	    {proceed,[{status,{403,Info#mod.request_uri,	    "Restricted area not allowed from your network"}}|Info#mod.data]}    end.%----------------------------------------------------------------------%The network the user comes from is allowed to view the resources %control whether the user needsto supply a password or not %----------------------------------------------------------------------authenticateUser2(Info,AccessData)->    case ets:lookup(AccessData,require) of	[{require,AllowedUsers}]->	    case ets:lookup(AccessData,auth_name) of		[{auth_name,Realm}]->		    authenticateUser2(Info,AccessData,Realm,AllowedUsers);		_NoAuthName->		    ets:delete(AccessData),		    {break,[{status,{500,none,				     ?NICE("mod_htaccess:AuthName directive " 					   "not specified")}}]}	    end;	[] ->	    %%No special user is required the network is ok so let	    %%the user in	    ets:delete(AccessData),	    {proceed,Info#mod.data}    end.%----------------------------------------------------------------------%The user must send a userId and a password to get the resource%Control if its already in the http-request%if the file with users is bad send an 500 response%----------------------------------------------------------------------authenticateUser2(Info,AccessData,Realm,AllowedUsers)->    case authenticateUser(Info,AccessData,AllowedUsers) of	allow ->	    ets:delete(AccessData),	    {user,Name, _Pwd} = getAuthenticatingDataFromHeader(Info),	    {proceed, [{remote_user_name,Name}|Info#mod.data]};	challenge->  	    ets:delete(AccessData),	    ReasonPhrase = httpd_util:reason_phrase(401),	    Message = httpd_util:message(401,none,Info#mod.config_db),	    {proceed,	     [{response,	       {401,		["WWW-Authenticate: Basic realm=\"",Realm,		 "\"\r\n\r\n","<HTML>\n<HEAD>\n<TITLE>",		 ReasonPhrase,"</TITLE>\n",		 "</HEAD>\n<BODY>\n<H1>",ReasonPhrase,		 "</H1>\n",Message,"\n</BODY>\n</HTML>\n"]}}|	      Info#mod.data]};	deny->	    ets:delete(AccessData),	    {break,[{status,{500,none,			     ?NICE("mod_htaccess:Bad path to user " 				   "or group file")}}]}    end.                                                                      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                                  %%%% Methods that validate the netwqork the user comes from           %%%% according to the allowed networks                                %%%%                                                                  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%--------------------------------------------------------------------- %Controls the users networkaddress agains the specifed networks to %allow or deny%%returns either allow or deny%----------------------------------------------------------------------controlNet(Info,AccessData)->    UserNetwork=getUserNetworkAddress(Info),    case getAllowDenyOrder(AccessData) of	{_deny,[],_allow,[]}->	    allow;	{deny,[],allow,AllowedNetworks}->	    controlIfAllowed(AllowedNetworks,UserNetwork,allow,deny);	{allow,AllowedNetworks,deny,[]}->	    controlIfAllowed(AllowedNetworks,UserNetwork,allow,deny);		{deny,DeniedNetworks,allow,[]}->	    controlIfAllowed(DeniedNetworks,UserNetwork,allow,deny);	{allow,[],deny,DeniedNetworks}->	    controlIfAllowed(DeniedNetworks,UserNetwork,allow,deny);        	{deny,DeniedNetworks,allow,AllowedNetworks}->		    	    controlDenyAllow(DeniedNetworks,AllowedNetworks,UserNetwork); 	{allow,AllowedNetworks,deny,DeniedNetworks}->		 	    controlAllowDeny(AllowedNetworks,DeniedNetworks,UserNetwork)    end.%----------------------------------------------------------------------%Returns the users IP-Number%----------------------------------------------------------------------getUserNetworkAddress(Info)->    {_Socket,Address}=(Info#mod.init_data)#init_data.peername,    Address.%----------------------------------------------------------------------%Control the users Ip-number against the ip-numbers in the .htaccessfile%----------------------------------------------------------------------controlIfAllowed(AllowedNetworks,UserNetwork,IfAllowed,IfDenied)->    case AllowedNetworks of	[{allow,all}]->	   IfAllowed;	[{deny,all}]->	    IfDenied;        [{deny,Networks}]->	    memberNetwork(Networks,UserNetwork,IfDenied,IfAllowed);	[{allow,Networks}]->	    memberNetwork(Networks,UserNetwork,IfAllowed,IfDenied);	_Error->	    IfDenied    end.%---------------------------------------------------------------------%%The Denycontrol isn't neccessary to preform since the allow control  %%override the deny control                                            %%---------------------------------------------------------------------% controlDenyAllow(_DeniedNetworks, AllowedNetworks, UserNetwork)->    case AllowedNetworks of	[{allow, all}]->	    allow;	[{allow, Networks}]->	  case memberNetwork(Networks, UserNetwork) of	      true->		  allow;	      false->		  deny	  end    end.%----------------------------------------------------------------------%%Control that the user is in the allowed list if so control that the   %%network is in the denied list                             %----------------------------------------------------------------------%controlAllowDeny(AllowedNetworks,DeniedNetworks,UserNetwork)->    case controlIfAllowed(AllowedNetworks,UserNetwork,allow,deny) of	allow->	    controlIfAllowed(DeniedNetworks,UserNetwork,deny,allow);	deny ->	    deny    end.	    %----------------------------------------------------------------------%Controls if the users Ipnumber is in the list of either denied or%allowed networks%----------------------------------------------------------------------	memberNetwork(Networks,UserNetwork,IfTrue,IfFalse)->    case memberNetwork(Networks,UserNetwork) of	true->	    IfTrue;	false->	    IfFalse    end.%----------------------------------------------------------------------%regexp match the users ip-address against the networks in the list of %ipadresses or subnet addresses.memberNetwork(Networks,UserNetwork)->    case lists:filter(fun(Net)->			      case regexp:match(UserNetwork,						formatRegexp(Net)) of				  {match,1,_}->				      true;				  _NotSubNet ->				      false			      end		      end,Networks) of	[]->	    false;	_MemberNetWork ->	    true    end.%----------------------------------------------------------------------%Creates a regexp from an ip-number i.e "127.0.0-> "^127[.]0[.]0.*"%"127.0.0.-> "^127[.]0[.]0[.].*"%----------------------------------------------------------------------formatRegexp(Net)->	        [SubNet1|SubNets]=string:tokens(Net,"."),    NetRegexp=lists:foldl(fun(SubNet,Newnet)->				  Newnet ++ "[.]" ++SubNet			  end,"^"++SubNet1,SubNets),    case string:len(Net)-string:rchr(Net,$.) of	0->	    NetRegexp++"[.].*";	_->	    NetRegexp++".*"    end.%----------------------------------------------------------------------%If the user has specified if the allow or deny check shall be preformed%first get that order if no order is specified take %allow - deny since its harder that deny - allow

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -