View Javadoc

1   /**
2    * This file is part of Waarp Project.
3    * 
4    * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
5    * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
6    * 
7    * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
8    * the GNU General Public License as published by the Free Software Foundation, either version 3 of
9    * the License, or (at your option) any later version.
10   * 
11   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
12   * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13   * Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License along with Waarp . If not, see
16   * <http://www.gnu.org/licenses/>.
17   */
18  package org.waarp.ftp.simpleimpl.file;
19  
20  import java.io.File;
21  
22  import org.waarp.common.command.NextCommandReply;
23  import org.waarp.common.command.ReplyCode;
24  import org.waarp.common.command.exception.Reply421Exception;
25  import org.waarp.common.command.exception.Reply502Exception;
26  import org.waarp.common.command.exception.Reply530Exception;
27  import org.waarp.common.logging.WaarpLogger;
28  import org.waarp.common.logging.WaarpLoggerFactory;
29  import org.waarp.ftp.core.command.FtpCommandCode;
30  import org.waarp.ftp.core.file.FtpDir;
31  import org.waarp.ftp.core.session.FtpSession;
32  import org.waarp.ftp.filesystembased.FilesystemBasedFtpAuth;
33  import org.waarp.ftp.simpleimpl.config.FileBasedConfiguration;
34  
35  /**
36   * FtpAuth implementation based on a list of (user/password/account) stored in a xml file load at
37   * startup from configuration. Not to be used in production!
38   * 
39   * @author Frederic Bregier
40   * 
41   */
42  public class FileBasedAuth extends FilesystemBasedFtpAuth {
43      /**
44       * Internal Logger
45       */
46      private static final WaarpLogger logger = WaarpLoggerFactory
47              .getLogger(FileBasedAuth.class);
48  
49      /**
50       * Current authentication
51       */
52      private SimpleAuth currentAuth = null;
53  
54      /**
55       * @param session
56       */
57      public FileBasedAuth(FtpSession session) {
58          super(session);
59      }
60  
61      @Override
62      protected void businessClean() {
63          currentAuth = null;
64      }
65  
66      /**
67       * @param user
68       *            the user to set
69       * @return (NOOP,230) if the user is OK, else return the following command that must follow
70       *         (usually PASS) and the associated reply
71       * @throws Reply421Exception
72       *             if there is a problem during the authentication
73       * @throws Reply530Exception
74       *             if there is a problem during the authentication
75       */
76      @Override
77      protected NextCommandReply setBusinessUser(String user)
78              throws Reply421Exception, Reply530Exception {
79          SimpleAuth auth = ((FileBasedConfiguration) ((FtpSession) getSession())
80                  .getConfiguration()).getSimpleAuth(user);
81          if (auth == null) {
82              setIsIdentified(false);
83              currentAuth = null;
84              throw new Reply530Exception("User name not allowed");
85          }
86          currentAuth = auth;
87          // logger.debug("User: {}", user);
88          return new NextCommandReply(FtpCommandCode.PASS,
89                  ReplyCode.REPLY_331_USER_NAME_OKAY_NEED_PASSWORD, null);
90      }
91  
92      /**
93       * Set the password according to any implementation and could set the rootFromAuth. If NOOP is
94       * returned, isIdentifed must be TRUE. A special case is implemented for test user.
95       * 
96       * @param password
97       * @return (NOOP,230) if the Password is OK, else return the following command that must follow
98       *         (usually ACCT) and the associated reply
99       * @throws Reply421Exception
100      *             if there is a problem during the authentication
101      * @throws Reply530Exception
102      *             if there is a problem during the authentication
103      */
104     @Override
105     protected NextCommandReply setBusinessPassword(String password)
106             throws Reply421Exception, Reply530Exception {
107         if (currentAuth == null) {
108             setIsIdentified(false);
109             throw new Reply530Exception("PASS needs a USER first");
110         }
111         if (currentAuth.isPasswordValid(password)) {
112             if (user.equals("test")) {
113                 // logger.debug("User test");
114                 try {
115                     return setAccount("test");
116                 } catch (Reply502Exception e) {
117                 }
118             }
119             return new NextCommandReply(FtpCommandCode.ACCT,
120                     ReplyCode.REPLY_332_NEED_ACCOUNT_FOR_LOGIN, null);
121         }
122         throw new Reply530Exception("Password is not valid");
123     }
124 
125     /**
126      * Set the account according to any implementation and could set the rootFromAuth. If NOOP is
127      * returned, isIdentifed must be TRUE.
128      * 
129      * @param account
130      * @return (NOOP,230) if the Account is OK, else return the following command that must follow
131      *         and the associated reply
132      * @throws Reply421Exception
133      *             if there is a problem during the authentication
134      * @throws Reply530Exception
135      *             if there is a problem during the authentication
136      */
137     @Override
138     protected NextCommandReply setBusinessAccount(String account)
139             throws Reply421Exception, Reply530Exception {
140         if (currentAuth == null) {
141             throw new Reply530Exception("ACCT needs a USER first");
142         }
143         if (currentAuth.isAccountValid(account)) {
144             // logger.debug("Account: {}", account);
145             setIsIdentified(true);
146             logger.info("User {} is authentified with account {}", user,
147                     account);
148             return new NextCommandReply(FtpCommandCode.NOOP,
149                     ReplyCode.REPLY_230_USER_LOGGED_IN, null);
150         }
151         throw new Reply530Exception("Account is not valid");
152     }
153 
154     public boolean isBusinessPathValid(String newPath) {
155         if (newPath == null) {
156             return false;
157         }
158         return newPath.startsWith(getBusinessPath());
159     }
160 
161     @Override
162     protected String setBusinessRootFromAuth() throws Reply421Exception {
163         String path = null;
164         if (account == null) {
165             path = FtpDir.SEPARATOR + user;
166         } else {
167             path = FtpDir.SEPARATOR + user + FtpDir.SEPARATOR +
168                     account;
169         }
170         String fullpath = getAbsolutePath(path);
171         File file = new File(fullpath);
172         if (!file.isDirectory()) {
173             throw new Reply421Exception("Filesystem not ready");
174         }
175         return path;
176     }
177 
178     public boolean isAdmin() {
179         return currentAuth.isAdmin();
180     }
181 }