You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by hb...@apache.org on 2001/11/18 02:00:37 UTC

cvs commit: jakarta-james/src/java/org/apache/james/nntpserver AuthServiceImpl.java AuthServiceImpl.xinfo NNTPHandler.java NNTPServer.xinfo

hbedi       01/11/17 17:00:37

  Modified:    src/java/org/apache/james/nntpserver NNTPHandler.java
                        NNTPServer.xinfo
  Added:       src/java/org/apache/james/nntpserver AuthServiceImpl.java
                        AuthServiceImpl.xinfo
  Log:
  bugfix: Implementation did not comply with 7.1.1: Initial connection, if message posting is not allowed
  	separated authentication and authorization checks.
  
  Revision  Changes    Path
  1.4       +29 -51    jakarta-james/src/java/org/apache/james/nntpserver/NNTPHandler.java
  
  Index: NNTPHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/nntpserver/NNTPHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- NNTPHandler.java	2001/11/10 23:09:27	1.3
  +++ NNTPHandler.java	2001/11/18 01:00:37	1.4
  @@ -36,8 +36,6 @@
   import org.apache.james.nntpserver.repository.NNTPGroup;
   import org.apache.james.nntpserver.repository.NNTPLineReaderImpl;
   import org.apache.james.nntpserver.repository.NNTPRepository;
  -import org.apache.james.services.UsersRepository;
  -import org.apache.james.services.UsersStore;
   
   /**
    * The NNTP protocol is defined by RFC 977.
  @@ -52,8 +50,6 @@
   public class NNTPHandler extends BaseConnectionHandler
       implements ConnectionHandler, Composable, Configurable, Target {
   
  -    private final static boolean DEEP_DEBUG = true;
  -
       // timeout controllers
       private TimeScheduler scheduler;
   
  @@ -62,46 +58,32 @@
       private BufferedReader reader;
       private PrintWriter writer;
   
  -    // authentication.
  -    private AuthState authState;
  -    private boolean authRequired = false;
  -    private UsersRepository users;
  +    // authentication & authorization.
  +    private AuthService auth;
   
       // data abstractions.
       private NNTPGroup group;
       private NNTPRepository repo;
   
  -
       public void compose( final ComponentManager componentManager )
           throws ComponentException
       {
           //System.out.println(getClass().getName()+": compose - "+authRequired);
  -        UsersStore usersStore = (UsersStore)componentManager.
  -            lookup( "org.apache.james.services.UsersStore" );
  -        users = usersStore.getRepository("LocalUsers");
  +        auth = (AuthService)componentManager.
  +            lookup( "org.apache.james.nntpserver.AuthService" );
           scheduler = (TimeScheduler)componentManager.
               lookup( "org.apache.avalon.cornerstone.services.scheduler.TimeScheduler" );
           repo = (NNTPRepository)componentManager
               .lookup("org.apache.james.nntpserver.repository.NNTPRepository");
       }
   
  -
  -    public void configure( Configuration configuration )
  -           throws ConfigurationException {
  -        super.configure(configuration);
  -        authRequired =
  -            configuration.getChild("authRequired").getValueAsBoolean(false);
  -        getLogger().debug("Auth required state is :" + authRequired);
  -        authState = new AuthState(authRequired,users);
  -    }
  -
  -
       public void handleConnection( Socket connection ) throws IOException {
           try {
               this.socket = connection;
               reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
               writer = new PrintWriter(socket.getOutputStream()) {
                       public void println() {
  +                        // lines must end with CRLF, irrespective of the OS
                           print("\r\n");
                           flush();
                       }
  @@ -116,8 +98,10 @@
               scheduler.addTrigger( this.toString(), trigger, this );
   
               // section 7.1
  -            writer.println("200 "+helloName+
  -                           (repo.isReadOnly()?" Posting Not Premitted":" Posting Permitted"));
  +            if ( repo.isReadOnly() )
  +                writer.println("201 "+helloName+" NNTP Service Ready, posting prohibited");
  +            else
  +                writer.println("200 "+helloName+" NNTP Service Ready, posting permitted");
   
               while (parseCommand(reader.readLine()))
                   scheduler.resetTrigger(this.toString());
  @@ -144,18 +128,6 @@
           } catch (IOException e) { }
       }
   
  -    // checks if a command is allowed. The authentication state is validated.
  -    private boolean isAllowed(String command) {
  -        boolean allowed = authState.isAuthenticated();
  -        // some commads are allowed, even if the user is not authenticated
  -        allowed = allowed || command.equalsIgnoreCase("AUTHINFO");
  -        allowed = allowed || command.equalsIgnoreCase("AUTHINFO");
  -        allowed = allowed || command.equalsIgnoreCase("MODE");
  -        allowed = allowed || command.equalsIgnoreCase("QUIT");
  -        if ( allowed == false )
  -            writer.println("502 User is not authenticated");
  -        return allowed;
  -    }
       private boolean parseCommand(String commandRaw) {
           if (commandRaw == null)
               return false;
  @@ -167,13 +139,11 @@
               return false;
           final String command = tokens.nextToken();
   
  -        //System.out.println("allowed="+isAllowed(command)+","+authState.isAuthenticated());
  -        if (! isAllowed(command) ){
  -	    if (DEEP_DEBUG) {
  -		getLogger().debug("Command not allowed.");
  -	    }
  +        if (!auth.isAuthorized(command) ) {
  +            writer.println("502 User is not authenticated");
  +            getLogger().debug("Command not allowed.");
               return true;
  -	}
  +        }
           if ( command.equalsIgnoreCase("MODE") && tokens.hasMoreTokens() &&
                tokens.nextToken().equalsIgnoreCase("READER") )
               doMODEREADER();
  @@ -236,11 +206,11 @@
       private void doAUTHINFO(StringTokenizer tok) {
           String command = tok.nextToken();
           if ( command.equalsIgnoreCase("USER") ) {
  -            authState.setUser(tok.nextToken());
  +            auth.setUser(tok.nextToken());
               writer.println("381 More authentication information required");
           } else if ( command.equalsIgnoreCase("PASS") ) {
  -            authState.setPassword(tok.nextToken());
  -            if ( authState.isAuthenticated() )
  +            auth.setPassword(tok.nextToken());
  +            if ( auth.isAuthenticated() )
                   writer.println("281 Authentication accepted");
               else
                   writer.println("482 Authentication rejected");
  @@ -432,12 +402,20 @@
           // section 9.1.1.1
           if ( group == null )
               writer.println("411 no such newsgroup");
  -        else
  -            writer.println("211 "+group.getNumberOfArticles()+" "+
  -                           group.getFirstArticleNumber()+" "+
  -                           group.getLastArticleNumber()+" "+
  +        else {
  +            // if the number of articles in group == 0
  +            // then the server may return this information in 3 ways, 
  +            // The clients must honor all those 3 ways.
  +            // our response is: 
  +            // highWaterMark == lowWaterMark and number of articles == 0
  +            int articleCount = group.getNumberOfArticles();
  +            int lowWaterMark = group.getFirstArticleNumber();
  +            int highWaterMark = group.getLastArticleNumber();
  +            writer.println("211 "+articleCount+" "+
  +                           lowWaterMark+" "+
  +                           highWaterMark+" "+
                              group.getName()+" group selected");
  -
  +        }
       }
       private void doLISTEXTENSIONS() {
           // 8.1.1
  
  
  
  1.3       +9 -8      jakarta-james/src/java/org/apache/james/nntpserver/NNTPServer.xinfo
  
  Index: NNTPServer.xinfo
  ===================================================================
  RCS file: /home/cvs/jakarta-james/src/java/org/apache/james/nntpserver/NNTPServer.xinfo,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- NNTPServer.xinfo	2001/09/25 04:51:19	1.2
  +++ NNTPServer.xinfo	2001/11/18 01:00:37	1.3
  @@ -14,23 +14,24 @@
   
     <dependencies>
       <dependency>
  -      <service name="org.apache.james.services.MailStore" version="1.0"/>
  +      <role>org.apache.avalon.cornerstone.services.connection.ConnectionManager</role>
  +      <service name="org.apache.avalon.cornerstone.services.connection.ConnectionManager" version="1.0"/>
       </dependency>
       <dependency>
  -      <service name="org.apache.james.services.UsersStore" version="1.0"/>
  -    </dependency>
  -    <dependency>
  -      <service name="org.apache.avalon.cornerstone.services.connection.ConnectionManager" 
  -               version="1.0"/>
  -    </dependency>
  -    <dependency>
  +      <role>org.apache.avalon.cornerstone.services.sockets.SocketManager</role>
         <service name="org.apache.avalon.cornerstone.services.sockets.SocketManager" version="1.0"/>
       </dependency>
       <dependency>
  +      <role>org.apache.avalon.cornerstone.services.scheduler.TimeScheduler</role>
         <service name="org.apache.avalon.cornerstone.services.scheduler.TimeScheduler" version="1.0"/>
       </dependency> 
       <dependency>
  +      <role>org.apache.james.nntpserver.repository.NNTPRepository</role>
         <service name="org.apache.james.nntpserver.repository.NNTPRepository" version="1.0"/>
  +    </dependency> 
  +    <dependency>
  +      <role>org.apache.james.nntpserver.AuthService</role>
  +      <service name="org.apache.james.nntpserver.AuthService" version="1.0"/>
       </dependency> 
     </dependencies>
   
  
  
  
  1.1                  jakarta-james/src/java/org/apache/james/nntpserver/AuthServiceImpl.java
  
  Index: AuthServiceImpl.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.james.nntpserver;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.logger.AbstractLoggable;
  import org.apache.avalon.phoenix.Block;
  import org.apache.james.services.UsersRepository;
  import org.apache.james.services.UsersStore;
  
  /**
   * Provides Authentication State. 
   * Authenticates users.
   * Access Control for User Commands.
   *
   * Implementation is NNTP Specific. 
   * Would it be better to have a James Authentication Service ?
   *
   * Application could define and plugin their own authentication service.
   *
   * @author  Harmeet <ha...@kodemuse.com> 
   */
  public class AuthServiceImpl extends AbstractLoggable 
      implements AuthService, Composable, Configurable, Block 
  {
      protected boolean authRequired;
      protected UsersRepository repo;
      protected String user;
      protected String password;
      protected boolean userSet = false;
      protected boolean passwordSet = false;
  
      public boolean isAuthorized(String command) {
          boolean allowed = isAuthenticated();
          // some commads are authorized, even if the user is not authenticated
          allowed = allowed || command.equalsIgnoreCase("AUTHINFO");
          allowed = allowed || command.equalsIgnoreCase("AUTHINFO");
          allowed = allowed || command.equalsIgnoreCase("MODE");
          allowed = allowed || command.equalsIgnoreCase("QUIT");
          return allowed;
      }
  
      public void compose( final ComponentManager componentManager )
          throws ComponentException
      {
          UsersStore usersStore = (UsersStore)componentManager.lookup(UsersStore.ROLE);
          repo = usersStore.getRepository("LocalUsers");
      }
  
      public void configure( Configuration configuration ) throws ConfigurationException {
          authRequired =
              configuration.getChild("authRequired").getValueAsBoolean(false);
          getLogger().debug("Auth required state is :" + authRequired);
      }
  
      public boolean isAuthenticated() {
          if ( authRequired ) {
              if  (userSet && passwordSet ) {
                  return repo.test(user,password);
              } else {
                  return false;
              }
          } else {
              return true;
          }
      }
  
      public void setUser(String user) {
          if (user != null && user.trim().length() != 0) {
              this.user = user;
              userSet = true;
          }
          this.password = null;
      }
  
      public void setPassword(String password) {
          if (password != null && password.trim().length() != 0) {
              this.password = password;
              passwordSet = true;
          }
      }
  }
  
  
  1.1                  jakarta-james/src/java/org/apache/james/nntpserver/AuthServiceImpl.xinfo
  
  Index: AuthServiceImpl.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <blockinfo>
  
    <!-- section to describe block -->
    <block>
      <version>1.0</version>
    </block>
  
    <!-- services that are offered by this block -->
    <services>
      <service name="org.apache.james.nntpserver.AuthService" version="1.0"/>
    </services>
  
    <dependencies>
      <dependency>
        <service name="org.apache.james.services.UsersStore" version="1.0"/>
      </dependency>
    </dependencies>
  
  </blockinfo>
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>