View Javadoc

1   // ========================================================================
2   // Authors : Van den Broeke Iris, Deville Daniel, Dubois Roger, Greg Wilkins
3   // Copyright (c) 2001 Deville Daniel. All rights reserved.
4   // Permission to use, copy, modify and distribute this software
5   // for non-commercial or commercial purposes and without fee is
6   // hereby granted provided that this copyright notice appears in
7   // all copies.
8   // ========================================================================
9   
10  package org.mortbay.jetty.security;
11  
12  import java.io.BufferedReader;
13  import java.io.IOException;
14  import java.io.InputStreamReader;
15  import java.security.Principal;
16  import java.util.ArrayList;
17  import java.util.HashMap;
18  import java.util.HashSet;
19  import java.util.Map;
20  import java.util.StringTokenizer;
21  
22  import javax.servlet.ServletException;
23  import javax.servlet.http.HttpServletRequest;
24  import javax.servlet.http.HttpServletResponse;
25  
26  import org.mortbay.jetty.Handler;
27  import org.mortbay.jetty.HttpConnection;
28  import org.mortbay.jetty.HttpHeaders;
29  import org.mortbay.jetty.Request;
30  import org.mortbay.jetty.Response;
31  import org.mortbay.jetty.handler.ContextHandler;
32  import org.mortbay.log.Log;
33  import org.mortbay.log.Logger;
34  import org.mortbay.resource.Resource;
35  import org.mortbay.util.StringUtil;
36  import org.mortbay.util.URIUtil;
37  
38  /* ------------------------------------------------------------ */
39  /**
40   * Handler to authenticate access using the Apache's .htaccess files.
41   * 
42   * @author Van den Broeke Iris
43   * @author Deville Daniel
44   * @author Dubois Roger
45   * @author Greg Wilkins
46   * @author Konstantin Metlov
47   * 
48   */
49  public class HTAccessHandler extends SecurityHandler
50  {
51      private Handler protegee;
52      private static Logger log=Log.getLogger(HTAccessHandler.class.getName());
53  
54      String _default=null;
55      String _accessFile=".htaccess";
56  
57      transient HashMap _htCache=new HashMap();
58      
59      /**
60       * DummyPrincipal
61       *
62       * For use when there is no user realm configured.
63       */
64      class DummyPrincipal implements Principal
65      {
66          private String _userName;
67  
68          public DummyPrincipal(String name) 
69          {
70              _userName=name;
71          }
72  
73          public String getName()
74          {
75              return _userName;
76          }
77  
78          public String toString()
79          {
80              return getName();
81          }        
82      }
83  
84  
85      /* ------------------------------------------------------------ */
86      /**
87       * {@inheritDoc}
88       * 
89       * @see org.mortbay.jetty.Handler#handle(java.lang.String,
90       *      javax.servlet.http.HttpServletRequest,
91       *      javax.servlet.http.HttpServletResponse, int)
92       */
93      public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException
94      {
95          Request base_request=(request instanceof Request)?(Request)request:HttpConnection.getCurrentConnection().getRequest();
96          Response base_response=(response instanceof Response)?(Response)response:HttpConnection.getCurrentConnection().getResponse();
97  
98          String pathInContext=target;
99  
100         String user=null;
101         String password=null;
102         boolean IPValid=true;
103 
104         if (log.isDebugEnabled())
105             log.debug("HTAccessHandler pathInContext="+pathInContext,null,null);
106 
107         String credentials=request.getHeader(HttpHeaders.AUTHORIZATION);
108 
109         if (credentials!=null)
110         {
111             credentials=credentials.substring(credentials.indexOf(' ')+1);
112             credentials=B64Code.decode(credentials,StringUtil.__ISO_8859_1);
113             int i=credentials.indexOf(':');
114             user=credentials.substring(0,i);
115             password=credentials.substring(i+1);
116 
117             if (log.isDebugEnabled())
118                 log.debug("User="+user+", password="+"******************************".substring(0,password.length()),null,null);
119         }
120 
121         HTAccess ht=null;
122 
123         try
124         {
125             Resource resource=null;
126             String directory=pathInContext.endsWith("/")?pathInContext:URIUtil.parentPath(pathInContext);
127 
128             // Look for htAccess resource
129             while (directory!=null)
130             {
131                 String htPath=directory+_accessFile;
132                 resource=((ContextHandler)getProtegee()).getResource(htPath);
133                 if (log.isDebugEnabled())
134                     log.debug("directory="+directory+" resource="+resource,null,null);
135 
136                 if (resource!=null&&resource.exists()&&!resource.isDirectory())
137                     break;
138                 resource=null;
139                 directory=URIUtil.parentPath(directory);
140             }
141 
142             boolean haveHtAccess=true;
143 
144             // Try default directory
145             if (resource==null&&_default!=null)
146             {
147                 resource=Resource.newResource(_default);
148                 if (!resource.exists()||resource.isDirectory())
149                     haveHtAccess=false;
150             }
151             if (resource==null)
152                 haveHtAccess=false;
153 
154             // prevent access to htaccess files
155             if (pathInContext.endsWith(_accessFile)
156                 // extra security
157                 ||pathInContext.endsWith(_accessFile+"~")||pathInContext.endsWith(_accessFile+".bak"))
158             {
159                 response.sendError(HttpServletResponse.SC_FORBIDDEN);
160                 base_request.setHandled(true);
161                 return;
162             }
163 
164             if (haveHtAccess)
165             {
166                 if (log.isDebugEnabled())
167                     log.debug("HTACCESS="+resource,null,null);
168 
169                 ht=(HTAccess)_htCache.get(resource);
170                 if (ht==null||ht.getLastModified()!=resource.lastModified())
171                 {
172                     ht=new HTAccess(resource);
173                     _htCache.put(resource,ht);
174                     if (log.isDebugEnabled())
175                         log.debug("HTCache loaded "+ht,null,null);
176                 }
177 
178                 // See if there is a config problem
179                 if (ht.isForbidden())
180                 {
181                     log.warn("Mis-configured htaccess: "+ht,null,null);
182                     response.sendError(HttpServletResponse.SC_FORBIDDEN);
183                     base_request.setHandled(true);
184                     return;
185                 }
186 
187                 // first see if we need to handle based on method type
188                 Map methods=ht.getMethods();
189                 if (methods.size()>0&&!methods.containsKey(request.getMethod()))
190                     return; // Nothing to check
191 
192                 // Check the accesss
193                 int satisfy=ht.getSatisfy();
194 
195                 // second check IP address
196                 IPValid=ht.checkAccess("",request.getRemoteAddr());
197                 if (log.isDebugEnabled())
198                     log.debug("IPValid = "+IPValid,null,null);
199 
200                 // If IP is correct and satify is ANY then access is allowed
201                 if (IPValid==true&&satisfy==HTAccess.ANY)
202                     return;
203 
204                 // If IP is NOT correct and satify is ALL then access is
205                 // forbidden
206                 if (IPValid==false&&satisfy==HTAccess.ALL)
207                 {
208                     response.sendError(HttpServletResponse.SC_FORBIDDEN);
209                     base_request.setHandled(true);
210                     return;
211                 }
212 
213                 // set required page
214                 if (!ht.checkAuth(user,password,getUserRealm(),base_request))
215                 {
216                     log.debug("Auth Failed",null,null);
217                     response.setHeader(HttpHeaders.WWW_AUTHENTICATE,"basic realm="+ht.getName());
218                     response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
219                     base_response.complete();
220                     base_request.setHandled(true);
221                     return;
222                 }
223 
224                 // set user
225                 if (user!=null)
226                 {
227                     base_request.setAuthType(Constraint.__BASIC_AUTH);
228                     base_request.setUserPrincipal(getPrincipal(user, getUserRealm()));
229                 }
230             }
231             
232             if (getHandler()!=null)
233             {
234                 getHandler().handle(target,request,response,dispatch);
235             }
236 
237         }
238         catch (Exception ex)
239         {
240             log.warn("Exception",ex);
241             if (ht!=null)
242             {
243                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
244                 base_request.setHandled(true);
245             }
246         }
247     }
248     
249     /* ------------------------------------------------------------ */
250     /** Get a Principal matching the user.
251      * If there is no user realm, and therefore we are using a
252      * htpassword file instead, then just return a dummy Principal.
253      * @param user
254      * @param realm
255      * @return
256      */
257     public Principal getPrincipal (String user, UserRealm realm)
258     {
259         if (realm==null)
260             return new DummyPrincipal(user);
261         
262         return realm.getPrincipal(user);
263     }
264     /* ------------------------------------------------------------ */
265     /**
266      * set functions for the following .xml administration statements.
267      * 
268      * <Call name="addHandler"> <Arg> <New
269      * class="org.mortbay.http.handler.HTAccessHandler"> <Set
270      * name="Default">./etc/htaccess</Set> <Set name="AccessFile">.htaccess</Set>
271      * </New> </Arg> </Call>
272      * 
273      */
274     public void setDefault(String dir)
275     {
276         _default=dir;
277     }
278 
279     /* ------------------------------------------------------------ */
280     public void setAccessFile(String anArg)
281     {
282         if (anArg==null)
283             _accessFile=".htaccess";
284         else
285             _accessFile=anArg;
286     }
287 
288     /* ------------------------------------------------------------ */
289     /* ------------------------------------------------------------ */
290     /* ------------------------------------------------------------ */
291     private static class HTAccess
292     {
293         // private boolean _debug = false;
294         static final int ANY=0;
295         static final int ALL=1;
296         static final String USER="user";
297         static final String GROUP="group";
298         static final String VALID_USER="valid-user";
299 
300         /* ------------------------------------------------------------ */
301         String _userFile;
302         Resource _userResource;
303         HashMap _users=null;
304         long _userModified;
305 
306         /* ------------------------------------------------------------ */
307         String _groupFile;
308         Resource _groupResource;
309         HashMap _groups=null;
310         long _groupModified;
311 
312         int _satisfy=0;
313         String _type;
314         String _name;
315         HashMap _methods=new HashMap();
316         HashSet _requireEntities=new HashSet();
317         String _requireName;
318         int _order;
319         ArrayList _allowList=new ArrayList();
320         ArrayList _denyList=new ArrayList();
321         long _lastModified;
322         boolean _forbidden=false;
323 
324         /* ------------------------------------------------------------ */
325         public HTAccess(Resource resource)
326         {
327             BufferedReader htin=null;
328             try
329             {
330                 htin=new BufferedReader(new InputStreamReader(resource.getInputStream()));
331                 parse(htin);
332                 _lastModified=resource.lastModified();
333 
334                 if (_userFile!=null)
335                 {
336                     _userResource=Resource.newResource(_userFile);
337                     if (!_userResource.exists())
338                     {
339                         _forbidden=true;
340                         log.warn("Could not find ht user file: "+_userFile,null,null);
341                     }
342                     else if (log.isDebugEnabled())
343                         log.debug("user file: "+_userResource,null,null);
344                 }
345 
346                 if (_groupFile!=null)
347                 {
348                     _groupResource=Resource.newResource(_groupFile);
349                     if (!_groupResource.exists())
350                     {
351                         _forbidden=true;
352                         log.warn("Could not find ht group file: "+_groupResource,null,null);
353                     }
354                     else if (log.isDebugEnabled())
355                         log.debug("group file: "+_groupResource,null,null);
356                 }
357             }
358             catch (IOException e)
359             {
360                 _forbidden=true;
361                 log.warn("LogSupport.EXCEPTION",e);
362             }
363         }
364 
365         /* ------------------------------------------------------------ */
366         public boolean isForbidden()
367         {
368             return _forbidden;
369         }
370 
371         /* ------------------------------------------------------------ */
372         public HashMap getMethods()
373         {
374             return _methods;
375         }
376 
377         /* ------------------------------------------------------------ */
378         public long getLastModified()
379         {
380             return _lastModified;
381         }
382 
383         /* ------------------------------------------------------------ */
384         public Resource getUserResource()
385         {
386             return _userResource;
387         }
388 
389         /* ------------------------------------------------------------ */
390         public Resource getGroupResource()
391         {
392             return _groupResource;
393         }
394 
395         /* ------------------------------------------------------------ */
396         public int getSatisfy()
397         {
398             return (_satisfy);
399         }
400 
401         /* ------------------------------------------------------------ */
402         public String getName()
403         {
404             return _name;
405         }
406 
407         /* ------------------------------------------------------------ */
408         public String getType()
409         {
410             return _type;
411         }
412 
413         /* ------------------------------------------------------------ */
414         public boolean checkAccess(String host, String ip)
415         {
416             String elm;
417             boolean alp=false;
418             boolean dep=false;
419 
420             // if no allows and no deny defined, then return true
421             if (_allowList.size()==0&&_denyList.size()==0)
422                 return (true);
423 
424             // looping for allows
425             for (int i=0; i<_allowList.size(); i++)
426             {
427                 elm=(String)_allowList.get(i);
428                 if (elm.equals("all"))
429                 {
430                     alp=true;
431                     break;
432                 }
433                 else
434                 {
435                     char c=elm.charAt(0);
436                     if (c>='0'&&c<='9')
437                     {
438                         // ip
439                         if (ip.startsWith(elm))
440                         {
441                             alp=true;
442                             break;
443                         }
444                     }
445                     else
446                     {
447                         // hostname
448                         if (host.endsWith(elm))
449                         {
450                             alp=true;
451                             break;
452                         }
453                     }
454                 }
455             }
456 
457             // looping for denies
458             for (int i=0; i<_denyList.size(); i++)
459             {
460                 elm=(String)_denyList.get(i);
461                 if (elm.equals("all"))
462                 {
463                     dep=true;
464                     break;
465                 }
466                 else
467                 {
468                     char c=elm.charAt(0);
469                     if (c>='0'&&c<='9')
470                     { // ip
471                         if (ip.startsWith(elm))
472                         {
473                             dep=true;
474                             break;
475                         }
476                     }
477                     else
478                     { // hostname
479                         if (host.endsWith(elm))
480                         {
481                             dep=true;
482                             break;
483                         }
484                     }
485                 }
486             }
487 
488             if (_order<0) // deny,allow
489                 return !dep||alp;
490             // mutual failure == allow,deny
491             return alp&&!dep;
492         }
493 
494         /* ------------------------------------------------------------ */
495         public boolean checkAuth(String user, String pass, UserRealm realm, Request request)
496         {
497             if (_requireName==null)
498                 return true;
499 
500             // Authenticate with realm
501 
502             Principal principal=realm==null?null:realm.authenticate(user,pass,request);
503             if (principal==null)
504             {
505                 // Have to authenticate the user with the password file
506                 String code=getUserCode(user);
507                 String salt=code!=null?code.substring(0,2):user;
508                 String cred=(user!=null&&pass!=null)?UnixCrypt.crypt(pass,salt):null;
509                 if (code==null||(code.equals("")&&!pass.equals(""))||!code.equals(cred))
510                     return false;
511             }
512 
513             if (_requireName.equalsIgnoreCase(USER))
514             {
515                 if (_requireEntities.contains(user))
516                     return true;
517             }
518             else if (_requireName.equalsIgnoreCase(GROUP))
519             {
520                 ArrayList gps=getUserGroups(user);
521                 if (gps!=null)
522                     for (int g=gps.size(); g-->0;)
523                         if (_requireEntities.contains(gps.get(g)))
524                             return true;
525             }
526             else if (_requireName.equalsIgnoreCase(VALID_USER))
527             {
528                 return true;
529             }
530 
531             return false;
532         }
533 
534         /* ------------------------------------------------------------ */
535         public boolean isAccessLimited()
536         {
537             if (_allowList.size()>0||_denyList.size()>0)
538                 return true;
539             else
540                 return false;
541         }
542 
543         /* ------------------------------------------------------------ */
544         public boolean isAuthLimited()
545         {
546             if (_requireName!=null)
547                 return true;
548             else
549                 return false;
550         }
551 
552         /* ------------------------------------------------------------ */
553         private String getUserCode(String user)
554         {
555             if (_userResource==null)
556                 return null;
557 
558             if (_users==null||_userModified!=_userResource.lastModified())
559             {
560                 if (log.isDebugEnabled())
561                     log.debug("LOAD "+_userResource,null,null);
562                 _users=new HashMap();
563                 BufferedReader ufin=null;
564                 try
565                 {
566                     ufin=new BufferedReader(new InputStreamReader(_userResource.getInputStream()));
567                     _userModified=_userResource.lastModified();
568                     String line;
569                     while ((line=ufin.readLine())!=null)
570                     {
571                         line=line.trim();
572                         if (line.startsWith("#"))
573                             continue;
574                         int spos=line.indexOf(':');
575                         if (spos<0)
576                             continue;
577                         String u=line.substring(0,spos).trim();
578                         String p=line.substring(spos+1).trim();
579                         _users.put(u,p);
580                     }
581                 }
582                 catch (IOException e)
583                 {
584                     log.warn("LogSupport.EXCEPTION",e);
585                 }
586                 finally
587                 {
588                     try
589                     {
590                         if (ufin!=null)
591                             ufin.close();
592                     }
593                     catch (IOException e2)
594                     {
595                         log.warn("LogSupport.EXCEPTION",e2);
596                     }
597                 }
598             }
599 
600             return (String)_users.get(user);
601         }
602 
603         /* ------------------------------------------------------------ */
604         private ArrayList getUserGroups(String group)
605         {
606             if (_groupResource==null)
607                 return null;
608 
609             if (_groups==null||_groupModified!=_groupResource.lastModified())
610             {
611                 if (log.isDebugEnabled())
612                     log.debug("LOAD "+_groupResource,null,null);
613 
614                 _groups=new HashMap();
615                 BufferedReader ufin=null;
616                 try
617                 {
618                     ufin=new BufferedReader(new InputStreamReader(_groupResource.getInputStream()));
619                     _groupModified=_groupResource.lastModified();
620                     String line;
621                     while ((line=ufin.readLine())!=null)
622                     {
623                         line=line.trim();
624                         if (line.startsWith("#")||line.length()==0)
625                             continue;
626 
627                         StringTokenizer tok=new StringTokenizer(line,": \t");
628 
629                         if (!tok.hasMoreTokens())
630                             continue;
631                         String g=tok.nextToken();
632                         if (!tok.hasMoreTokens())
633                             continue;
634                         while (tok.hasMoreTokens())
635                         {
636                             String u=tok.nextToken();
637                             ArrayList gl=(ArrayList)_groups.get(u);
638                             if (gl==null)
639                             {
640                                 gl=new ArrayList();
641                                 _groups.put(u,gl);
642                             }
643                             gl.add(g);
644                         }
645                     }
646                 }
647                 catch (IOException e)
648                 {
649                     log.warn("LogSupport.EXCEPTION",e);
650                 }
651                 finally
652                 {
653                     try
654                     {
655                         if (ufin!=null)
656                             ufin.close();
657                     }
658                     catch (IOException e2)
659                     {
660                         log.warn("LogSupport.EXCEPTION",e2);
661                     }
662                 }
663             }
664 
665             return (ArrayList)_groups.get(group);
666         }
667 
668         /* ------------------------------------------------------------ */
669         public String toString()
670         {
671             StringBuffer buf=new StringBuffer();
672 
673             buf.append("AuthUserFile=");
674             buf.append(_userFile);
675             buf.append(", AuthGroupFile=");
676             buf.append(_groupFile);
677             buf.append(", AuthName=");
678             buf.append(_name);
679             buf.append(", AuthType=");
680             buf.append(_type);
681             buf.append(", Methods=");
682             buf.append(_methods);
683             buf.append(", satisfy=");
684             buf.append(_satisfy);
685             if (_order<0)
686                 buf.append(", order=deny,allow");
687             else if (_order>0)
688                 buf.append(", order=allow,deny");
689             else
690                 buf.append(", order=mutual-failure");
691 
692             buf.append(", Allow from=");
693             buf.append(_allowList);
694             buf.append(", deny from=");
695             buf.append(_denyList);
696             buf.append(", requireName=");
697             buf.append(_requireName);
698             buf.append(" ");
699             buf.append(_requireEntities);
700 
701             return buf.toString();
702         }
703 
704         /* ------------------------------------------------------------ */
705         private void parse(BufferedReader htin) throws IOException
706         {
707             String line;
708             while ((line=htin.readLine())!=null)
709             {
710                 line=line.trim();
711                 if (line.startsWith("#"))
712                     continue;
713                 else if (line.startsWith("AuthUserFile"))
714                 {
715                     _userFile=line.substring(13).trim();
716                 }
717                 else if (line.startsWith("AuthGroupFile"))
718                 {
719                     _groupFile=line.substring(14).trim();
720                 }
721                 else if (line.startsWith("AuthName"))
722                 {
723                     _name=line.substring(8).trim();
724                 }
725                 else if (line.startsWith("AuthType"))
726                 {
727                     _type=line.substring(8).trim();
728                 }
729                 // else if (line.startsWith("<Limit")) {
730                 else if (line.startsWith("<Limit"))
731                 {
732                     int limit=line.length();
733                     int endp=line.indexOf('>');
734                     StringTokenizer tkns;
735 
736                     if (endp<0)
737                         endp=limit;
738                     tkns=new StringTokenizer(line.substring(6,endp));
739                     while (tkns.hasMoreTokens())
740                     {
741                         _methods.put(tkns.nextToken(),Boolean.TRUE);
742                     }
743 
744                     while ((line=htin.readLine())!=null)
745                     {
746                         line=line.trim();
747                         if (line.startsWith("#"))
748                             continue;
749                         else if (line.startsWith("satisfy"))
750                         {
751                             int pos1=7;
752                             limit=line.length();
753                             while ((pos1<limit)&&(line.charAt(pos1)<=' '))
754                                 pos1++;
755                             int pos2=pos1;
756                             while ((pos2<limit)&&(line.charAt(pos2)>' '))
757                                 pos2++;
758                             String l_string=line.substring(pos1,pos2);
759                             if (l_string.equals("all"))
760                                 _satisfy=1;
761                             else if (l_string.equals("any"))
762                                 _satisfy=0;
763                         }
764                         else if (line.startsWith("require"))
765                         {
766                             int pos1=7;
767                             limit=line.length();
768                             while ((pos1<limit)&&(line.charAt(pos1)<=' '))
769                                 pos1++;
770                             int pos2=pos1;
771                             while ((pos2<limit)&&(line.charAt(pos2)>' '))
772                                 pos2++;
773                             _requireName=line.substring(pos1,pos2).toLowerCase();
774                             if (USER.equals(_requireName))
775                                 _requireName=USER;
776                             else if (GROUP.equals(_requireName))
777                                 _requireName=GROUP;
778                             else if (VALID_USER.equals(_requireName))
779                                 _requireName=VALID_USER;
780 
781                             pos1=pos2+1;
782                             if (pos1<limit)
783                             {
784                                 while ((pos1<limit)&&(line.charAt(pos1)<=' '))
785                                     pos1++;
786 
787                                 tkns=new StringTokenizer(line.substring(pos1));
788                                 while (tkns.hasMoreTokens())
789                                 {
790                                     _requireEntities.add(tkns.nextToken());
791                                 }
792                             }
793 
794                         }
795                         else if (line.startsWith("order"))
796                         {
797                             if (log.isDebugEnabled())
798                                 log.debug("orderline="+line+"order="+_order,null,null);
799                             if (line.indexOf("allow,deny")>0)
800                             {
801                                 log.debug("==>allow+deny",null,null);
802                                 _order=1;
803                             }
804                             else if (line.indexOf("deny,allow")>0)
805                             {
806                                 log.debug("==>deny,allow",null,null);
807                                 _order=-1;
808                             }
809                             else if (line.indexOf("mutual-failure")>0)
810                             {
811                                 log.debug("==>mutual",null,null);
812                                 _order=0;
813                             }
814                             else
815                             {
816                             }
817                         }
818                         else if (line.startsWith("allow from"))
819                         {
820                             int pos1=10;
821                             limit=line.length();
822                             while ((pos1<limit)&&(line.charAt(pos1)<=' '))
823                                 pos1++;
824                             if (log.isDebugEnabled())
825                                 log.debug("allow process:"+line.substring(pos1),null,null);
826                             tkns=new StringTokenizer(line.substring(pos1));
827                             while (tkns.hasMoreTokens())
828                             {
829                                 _allowList.add(tkns.nextToken());
830                             }
831                         }
832                         else if (line.startsWith("deny from"))
833                         {
834                             int pos1=9;
835                             limit=line.length();
836                             while ((pos1<limit)&&(line.charAt(pos1)<=' '))
837                                 pos1++;
838                             if (log.isDebugEnabled())
839                                 log.debug("deny process:"+line.substring(pos1),null,null);
840 
841                             tkns=new StringTokenizer(line.substring(pos1));
842                             while (tkns.hasMoreTokens())
843                             {
844                                 _denyList.add(tkns.nextToken());
845                             }
846                         }
847                         else if (line.startsWith("</Limit>"))
848                             break;
849                     }
850                 }
851             }
852         }
853     }
854 
855     /**
856      * Getter for property protegee.
857      * 
858      * @return Returns the protegee.
859      */
860     protected Handler getProtegee()
861     {
862         return this.protegee;
863     }
864 
865     /**
866      * Setter for property protegee.
867      * 
868      * @param protegee
869      *            The protegee to set.
870      */
871     public void setProtegee(Handler protegee)
872     {
873         this.protegee=protegee;
874     }
875 
876 }