KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > drftpd > master > command > plugins > Login


1 /*
2  * This file is part of DrFTPD, Distributed FTP Daemon.
3  *
4  * DrFTPD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * DrFTPD is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with DrFTPD; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package net.sf.drftpd.master.command.plugins;
19
20 import java.io.IOException JavaDoc;
21 import java.net.InetAddress JavaDoc;
22 import java.net.UnknownHostException JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import net.sf.drftpd.HostMask;
27 import net.sf.drftpd.event.UserEvent;
28 import net.sf.drftpd.master.BaseFtpConnection;
29 import net.sf.drftpd.master.FtpReply;
30 import net.sf.drftpd.master.FtpRequest;
31 import net.sf.drftpd.master.command.CommandManager;
32 import net.sf.drftpd.master.command.CommandManagerFactory;
33 import net.sf.drftpd.master.usermanager.NoSuchUserException;
34 import net.sf.drftpd.master.usermanager.User;
35 import net.sf.drftpd.master.usermanager.UserFileException;
36
37 import org.apache.log4j.Logger;
38 import org.drftpd.commands.CommandHandler;
39 import org.drftpd.commands.CommandHandlerFactory;
40 import org.drftpd.commands.UnhandledCommandException;
41
42 import socks.server.Ident;
43
44 /**
45  * @version $Id: Login.java,v 1.29.2.1 2004/06/19 23:37:26 mog Exp $
46  */

47 public class Login
48     implements CommandHandlerFactory, CommandHandler, Cloneable JavaDoc {
49
50     private static final Logger logger = Logger.getLogger(Login.class);
51     /**
52      * If _idntAddress == null, IDNT hasn't been used.
53      */

54     protected InetAddress JavaDoc _idntAddress;
55     protected String JavaDoc _idntIdent;
56
57     /**
58      * Syntax: IDNT ident@ip:dns
59      * Returns nothing on success.
60      */

61     private FtpReply doIDNT(BaseFtpConnection conn) {
62         if (_idntAddress != null) {
63             logger.error("Multiple IDNT commands");
64             return new FtpReply(530, "Multiple IDNT commands");
65         }
66         if (!conn
67             .getConfig()
68             .getBouncerIps()
69             .contains(conn.getClientAddress())) {
70             logger.warn("IDNT from non-bnc");
71             return FtpReply.RESPONSE_530_ACCESS_DENIED;
72         }
73         String JavaDoc arg = conn.getRequest().getArgument();
74         int pos1 = arg.indexOf('@');
75         if (pos1 == -1)
76             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
77         int pos2 = arg.indexOf(':', pos1 + 1);
78         if (pos2 == -1)
79             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
80
81         try {
82             _idntAddress = InetAddress.getByName(arg.substring(pos1 + 1, pos2));
83             _idntIdent = arg.substring(0, pos1).toString();
84         } catch (UnknownHostException JavaDoc e) {
85             logger.info("Invalid hostname passed to IDNT", e);
86             //this will most likely cause control connection to become unsynchronized
87
//but give error anyway, this error is unlikely to happen
88
return new FtpReply(501, "IDNT FAILED: " + e.getMessage());
89         }
90         // bnc doesn't expect any reply
91
return null;
92     }
93
94     /**
95      * <code>PASS &lt;SP&gt; <password> &lt;CRLF&gt;</code><br>
96      *
97      * The argument field is a Telnet string specifying the user's
98      * password. This command must be immediately preceded by the
99      * user name command.
100      */

101     private FtpReply doPASS(BaseFtpConnection conn) {
102         if (conn.getUserNull() == null) {
103             return FtpReply.RESPONSE_503_BAD_SEQUENCE_OF_COMMANDS;
104         }
105
106         FtpRequest request = conn.getRequest();
107
108         // set user password and login
109
String JavaDoc pass = request.hasArgument() ? request.getArgument() : "";
110
111         // login failure - close connection
112
if (conn.getUserNull().checkPassword(pass)) {
113             conn.getUserNull().login();
114             conn.setAuthenticated(true);
115             conn.getConnectionManager().dispatchFtpEvent(
116                 new UserEvent(conn.getUserNull(), "LOGIN"));
117
118             FtpReply response =
119                 new FtpReply(
120                     230,
121                     conn.jprintf(Login.class.getName(), "pass.success"));
122             try {
123                 Textoutput.addTextToResponse(response, "welcome");
124             } catch (IOException JavaDoc e) {
125                 logger.warn("Error reading welcome", e);
126             }
127             return response;
128         } else {
129             return new FtpReply(
130                 530,
131                 conn.jprintf(Login.class.getName(), "pass.fail"));
132         }
133     }
134
135     /**
136      * <code>QUIT &lt;CRLF&gt;</code><br>
137      *
138      * This command terminates a USER and if file transfer is not
139      * in progress, the server closes the control connection.
140      */

141     private FtpReply doQUIT(BaseFtpConnection conn) {
142
143         conn.stop();
144         return new FtpReply(
145             221,
146             conn.jprintf(Login.class.getName(), "quit.success"));
147     }
148
149     /**
150      * <code>USER &lt;SP&gt; &lt;username&gt; &lt;CRLF&gt;</code><br>
151      *
152      * The argument field is a Telnet string identifying the user.
153      * The user identification is that which is required by the
154      * server for access to its file system. This command will
155      * normally be the first command transmitted by the user after
156      * the control connections are made.
157      */

158     private FtpReply doUSER(BaseFtpConnection conn) {
159         FtpRequest request = conn.getRequest();
160         conn.setAuthenticated(false);
161         conn.setUser(null);
162
163         // argument check
164
if (!request.hasArgument()) {
165             return FtpReply.RESPONSE_501_SYNTAX_ERROR;
166         }
167
168         User newUser;
169         try {
170             newUser =
171                 conn.getConnectionManager().getUserManager().getUserByName(
172                     request.getArgument());
173         } catch (NoSuchUserException ex) {
174             return new FtpReply(530, ex.getMessage());
175         } catch (UserFileException ex) {
176             logger.warn("", ex);
177             return new FtpReply(530, "IOException: " + ex.getMessage());
178         } catch (RuntimeException JavaDoc ex) {
179             logger.error("", ex);
180             return new FtpReply(530, ex.getMessage());
181         }
182
183         if (newUser.isDeleted()) {
184             return FtpReply.RESPONSE_530_ACCESS_DENIED;
185         }
186
187         List JavaDoc masks = newUser.getIpMasks2();
188         /**
189          * ident is null if ident hasn't been queried yet.
190          */

191         String JavaDoc ident = null;
192         for (Iterator JavaDoc iter = masks.iterator(); iter.hasNext();) {
193             HostMask mask = (HostMask) iter.next();
194             // request ident if no IDNT, ident hasn't been requested
195
// and ident matters in this hostmask
196
if (_idntAddress == null
197                 && ident == null
198                 && mask.isIdentMaskSignificant()) {
199                 Ident id = new Ident(conn.getControlSocket());
200                 if (id.successful) {
201                     ident = id.userName;
202                     if (ident.indexOf('@') != -1) {
203                         return new FtpReply(530, "Invalid ident response");
204                     }
205                 } else {
206                     logger.warn(
207                         "Failed to get ident response: " + id.errorMessage);
208                     ident = "";
209                 }
210             }
211
212             if ((_idntAddress != null
213                 && mask.matches(_idntIdent, _idntAddress))
214                 || (_idntAddress == null
215                     && (mask.matches(ident, conn.getClientAddress())))) {
216                 //success
217
// max_users and num_logins restriction
218
FtpReply response =
219                     conn.getConnectionManager().canLogin(conn, newUser);
220                 if (response != null) {
221                     return response;
222                 }
223                 conn.setUser(newUser);
224                 return new FtpReply(
225                     331,
226                     conn.jprintf(Login.class.getName(), "user.success"));
227             }
228         }
229         //fail
230
return FtpReply.RESPONSE_530_ACCESS_DENIED;
231     }
232
233     public FtpReply execute(BaseFtpConnection conn)
234         throws UnhandledCommandException {
235         String JavaDoc cmd = conn.getRequest().getCommand();
236         if ("USER".equals(cmd))
237             return doUSER(conn);
238         if ("PASS".equals(cmd))
239             return doPASS(conn);
240         if ("QUIT".equals(cmd))
241             return doQUIT(conn);
242         if ("IDNT".equals(cmd))
243             return doIDNT(conn);
244         throw UnhandledCommandException.create(Login.class, conn.getRequest());
245     }
246
247     public String JavaDoc[] getFeatReplies() {
248         return null;
249     }
250
251     public CommandHandler initialize(
252         BaseFtpConnection conn,
253         CommandManager initializer) {
254         try {
255             return (Login) clone();
256         } catch (CloneNotSupportedException JavaDoc e) {
257             throw new RuntimeException JavaDoc(e);
258         }
259     }
260
261     public void load(CommandManagerFactory initializer) {
262     }
263
264     public void unload() {
265     }
266 }
267
Popular Tags