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>