costin      02/02/06 21:07:36

  Modified:    src/share/org/apache/tomcat/modules/server
                        Ajp13Interceptor.java
  Log:
  Added the logic to check for the password on ajp13 connections.
  
  Also cut&paste the logic to generate the 'ajp13.id' if useSecret is set
  ( with a random generated password and the connection info ). If a
  secret is set, shutdown via ajp13 is enabled automatically.
  
  All normal code is running as before if no secret is set.
  
  Revision  Changes    Path
  1.18      +110 -6    
jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13Interceptor.java
  
  Index: Ajp13Interceptor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13Interceptor.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Ajp13Interceptor.java     4 Oct 2001 20:27:47 -0000       1.17
  +++ Ajp13Interceptor.java     7 Feb 2002 05:07:36 -0000       1.18
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13Interceptor.java,v
 1.17 2001/10/04 20:27:47 costin Exp $
  - * $Revision: 1.17 $
  - * $Date: 2001/10/04 20:27:47 $
  + * $Header: 
/home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/server/Ajp13Interceptor.java,v
 1.18 2002/02/07 05:07:36 costin Exp $
  + * $Revision: 1.18 $
  + * $Date: 2002/02/07 05:07:36 $
    *
    * ====================================================================
    *
  @@ -70,6 +70,7 @@
   import org.apache.tomcat.util.net.*;
   import org.apache.tomcat.util.*;
   import org.apache.tomcat.util.log.*;
  +import org.apache.tomcat.util.io.FileUtil;
   
   /* Frozen, bug fixes only: all active development goes in
        jakarta-tomcat-connectors/jk/org/apache/ajp/Ajp14*
  @@ -85,6 +86,8 @@
       private boolean decoded=true;
   
       private int decodedNote;
  +    private String secret;
  +    private File ajpidFile;
       
       public Ajp13Interceptor()
       {
  @@ -109,6 +112,36 @@
        shutDownEnable=b;
       }
   
  +    /** Enable the use of a secret. The secret will be
  +     *  randomly generated. mod_jk must read the secret to
  +     *  communicate with tomcat. 
  +     *
  +     *  Note that we don't use the secret only for shutdown, but
  +     *  for normal request processing. A 'bad' request may forge
  +     *  auth, etc.
  +     */
  +    public void setUseSecret(boolean b ) {
  +     secret=Double.toString(Math.random());
  +    }
  +
  +    /** Set the 'secret'. If this is set, all sensitive operations
  +     *   will be disabled unless the request includes a password.
  +     *
  +     *  This requires a recent version of mod_jk and the
  +     *    worker.NAME.secret property in workers.properties.
  +     */
  +    public void setSecret( String s ) {
  +        secret=s;
  +        shutDownEnable=true;
  +    }
  +
  +    /** Specify ajpid file used when shutting down tomcat
  +     */
  +    public void setAjpidFile( String path ) {
  +        ajpidFile=( path==null?null:new File(path));
  +    }
  +    
  +    
       public void setDecodedUri( boolean b ) {
        decoded=b;
       }
  @@ -125,6 +158,50 @@
                                  "req.decoded" );
       }
   
  +    public void engineState(ContextManager cm, int state )
  +     throws TomcatException
  +    {
  +
  +        if( state==ContextManager.STATE_START ) {
  +            // the engine is now started, create the ajp12.id
  +            // file that will allow us to stop the server and
  +            // know that the server is started ok.
  +            Ajp13Interceptor tcpCon=this;
  +            int portInt=tcpCon.getPort();
  +            InetAddress address=tcpCon.getAddress();
  +            File sf=FileUtil.getConfigFile(ajpidFile, new File(cm.getHome()),
  +                                           "conf/ajp13.id");
  +            Properties props=new Properties();
  +            
  +            if( ajpidFile != null || debug > 0)
  +                log( "Using stop file: "+sf);
  +            try {
  +                //  PrintWriter stopF=new PrintWriter
  +                //                     (new FileWriter(sf));
  +                FileOutputStream stopF=new FileOutputStream( sf );
  +                props.put( "port", Integer.toString( portInt ));
  +                // stopF.println( portInt );
  +                if( address==null ) {
  +                    // stopF.println( "" );
  +                } else {
  +                    //stopF.println( address.getHostAddress() );
  +                    props.put( "address", address.getHostAddress() );
  +                }
  +                if( secret !=null ) {
  +                    //stopF.println( secret );
  +                    props.put( "secret", secret );
  +                } else {
  +                    // stopF.println();
  +                }
  +                //            stopF.close();
  +                props.save( stopF, "Automatically generated, don't edit" );
  +            } catch( IOException ex ) {
  +                log( "Can't create stop file: "+sf, ex );
  +            }
  +        }
  +
  +    }
  +
       
       // -------------------- Handler implementation --------------------
       
  @@ -188,13 +265,36 @@
               con.setSocket(socket);
   
               boolean moreRequests = true;
  +            boolean authenticated = false;
  +            // If we are not configured with a secret, assume
  +            // we trust the remote party ( as we did before )
  +            if( secret == null )
  +                authenticated=true;
  +            
               while(moreRequests) {
                int status=req.receiveNextRequest();
   
  +                if( !authenticated ) {
  +                    // we need to authenticate - the user set a
  +                    // secret and expects the web server to send it
  +                    String conSecret=con.getSecret();
  +                    if(  conSecret == null ) {
  +                        log("Unauthenticated server");
  +                        break;
  +                    }
  +                    if( ! secret.equals( conSecret )) {
  +                        log("Bad server secret");
  +                        break;
  +                    }
  +                    // allow further requests without checking
  +                    authenticated=true;
  +                }
  +                
                if( status==-2) {
                    // special case - shutdown
                    // XXX need better communication, refactor it
  -                 if( !doShutdown(socket.getLocalAddress(),
  +                 if( !doShutdown(con,
  +                                    socket.getLocalAddress(),
                                    socket.getInetAddress())) {
                        moreRequests = false;
                        continue;
  @@ -228,14 +328,18 @@
           this.cm=(ContextManager)contextM;
       }
   
  -    protected boolean doShutdown(InetAddress serverAddr,
  +    protected boolean doShutdown(Ajp13 con,
  +                                 InetAddress serverAddr,
                                    InetAddress clientAddr)
       {
           try {
  +            // continue with the other checks. XXX We may allow shutdown
  +            // with the right secret from a different address.
            // close the socket connection before handling any signal
            // but get the addresses first so they are not corrupted
               if(shutDownEnable && Ajp12.isSameAddress(serverAddr, clientAddr)) {
  -             cm.stop();
  +             cm.shutdown();
  +                log( "Exiting" );
                // same behavior as in past, because it seems that
                // stopping everything doesn't work - need to figure
                // out what happens with the threads ( XXX )
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to