KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > exchange > security > ExchangeOfficer


1 /**
2  * Copyright (C) 2005 Funambol
3  *
4  * This program 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  * This program 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 this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package sync4j.exchange.security;
20
21 import java.security.Principal JavaDoc;
22 import java.util.logging.Level JavaDoc;
23 import java.util.logging.Logger JavaDoc;
24
25 import sync4j.exchange.DataAccessException;
26
27 import sync4j.exchange.items.common.manager.ItemManager;
28
29 import sync4j.framework.core.Authentication;
30 import sync4j.framework.core.Cred;
31 import sync4j.framework.security.Officer;
32 import sync4j.framework.security.Sync4jPrincipal;
33 import sync4j.framework.server.store.*;
34 import sync4j.framework.tools.Base64;
35
36 import sync4j.server.config.Configuration;
37
38
39 /**
40  * This is an implementation of the <i>Officier</i> interface.
41  * It always authenticates and authorizes users and resource accesses.
42  *
43  * @author Fabio Maggi
44  * @version $Id: ExchangeOfficer.java,v 1.1 2005/06/20 14:06:35 fabius Exp $
45  */

46 public class ExchangeOfficer implements Officer, java.io.Serializable JavaDoc {
47
48
49     // ---------------------------------------------------------- Constants
50

51     // ---------------------------------------------------------- Protected data
52

53     protected Logger JavaDoc log = Logger.getLogger("source");
54
55     protected PersistentStore ps = null;
56
57     // ------------------------------------------------------------- Public data
58

59     // -------------------------------------------------------------- Properties
60

61     /**
62      * Has the last login failed for incorrect login/password?
63      */

64     private boolean loginFailed = false;
65
66     public boolean isLoginFailed() {
67         return loginFailed;
68     }
69
70     /**
71      * Has the last login failed for expired temporary login?
72      */

73     private boolean loginExpired = false;
74
75     /**
76      * Which type of authetication does impose the server?
77      */

78     private String JavaDoc clientAuth = Cred.AUTH_TYPE_BASIC;
79
80     public String JavaDoc getClientAuth() {
81         return this.clientAuth;
82     }
83
84     public void setClientAuth(String JavaDoc clientAuth) {
85         this.clientAuth = clientAuth;
86     }
87
88     /**
89      * Which type of authetication use the server to send his credential?
90      */

91     private String JavaDoc serverAuth = Cred.AUTH_TYPE_BASIC;
92
93     public String JavaDoc getServerAuth() {
94         return this.serverAuth;
95     }
96
97     public void setServerAuth(String JavaDoc serverAuth) {
98         this.serverAuth = serverAuth;
99     }
100
101     /**
102      * Exchange host
103      */

104     private String JavaDoc exchangeHost = null;
105
106     public String JavaDoc getExchangeHost() {
107         return this.exchangeHost;
108     }
109
110     public void setExchangeHost(String JavaDoc exchangeHost) {
111         this.exchangeHost = exchangeHost;
112     }
113
114     /**
115      * Exchange port
116      */

117     private int exchangePort = 0;
118
119     public int getExchangePort() {
120         return this.exchangePort;
121     }
122
123     public void setExchangePort(int exchangePort) {
124         this.exchangePort = exchangePort;
125     }
126
127     /**
128      * Exchange folder
129      */

130     private String JavaDoc exchangeFolder = null;
131
132     public String JavaDoc getExchangeFolder() {
133         return this.exchangeFolder;
134     }
135
136     public void setExchangeFolder(String JavaDoc exchangeFolder) {
137         this.exchangeFolder = exchangeFolder;
138     }
139
140     // ---------------------------------------------------------- Public methods
141

142     /**
143      * Authenticates a credential.
144      *
145      * @param credential the credential to be authenticated
146      *
147      * @return true if the credential is autenticated, false otherwise
148      */

149     public boolean authenticate(Cred credential) {
150
151         if (log.isLoggable(Level.FINEST)) {
152             log.finest(" ExchangeOfficer authenticate() Start");
153         }
154
155         Configuration config = Configuration.getConfiguration();
156         ps = config.getStore();
157
158         String JavaDoc type = credential.getType();
159
160         if ((Cred.AUTH_TYPE_BASIC).equals(type)) {
161             return authenticateBasicCredential(credential);
162         }
163         return false;
164     }
165
166
167     /**
168      * Authorizes a resource.
169      *
170      * @param principal the requesting entity
171      * @param resource the name (or the identifier) of the resource to be authorized
172      *
173      * @return true if the credential is authorized to access the resource, false
174      * otherwise
175      */

176     public boolean authorize(Principal JavaDoc principal, String JavaDoc resource) {
177         return true;
178     }
179
180     /**
181      * Un-authenticates a credential.
182      * Do nothing. In the current implementation, the authentication is
183      * discarde as soon as the LoginContext is garbage collected.
184      *
185      * @param credential the credential to be unauthenticated
186      */

187     public void unAuthenticate(Cred credential) {
188     }
189
190     /**
191      * @see sync4j.framework.security.Officer
192      *
193      * @return boolean
194      */

195     public boolean isAccountExpired() {
196         return loginExpired;
197     }
198
199     // --------------------------------------------------------- Private Methods
200

201     /**
202      *
203      */

204     private boolean authenticateBasicCredential(Cred credential) {
205
206         String JavaDoc username = null, password = null;
207         Sync4jPrincipal principal = null;
208
209         Authentication auth = credential.getAuthentication();
210         String JavaDoc deviceId = auth.getDeviceId();
211         String JavaDoc credentials = auth.getData();
212         String JavaDoc userpwd = new String JavaDoc(Base64.decode(auth.getData()));
213
214         int p = userpwd.indexOf(':');
215
216         if (p == -1) {
217             username = userpwd;
218             password = "";
219         } else {
220             username = (p > 0) ? userpwd.substring(0, p) : "";
221             password = (p == (userpwd.length() - 1)) ? "" :
222                        userpwd.substring(p + 1);
223         }
224
225         if (log.isLoggable(Level.FINEST)) {
226             log.finest("Username: " + username );
227             log.finest("Credentials: " + credentials );
228         }
229
230         //
231
// Verify that exist the principal for the
232
// specify deviceId and username
233
//
234
boolean principalFound = false;
235         try {
236             principal = new Sync4jPrincipal(username, deviceId);
237             ps.read(principal);
238             credential.getAuthentication().setPrincipalId(principal.getId());
239             principalFound = true;
240         } catch (NotFoundException nfe) {
241             if (log.isLoggable(Level.FINEST)) {
242                 log.finest("Principal for " + username + ":" + deviceId +
243                            " not found");
244             }
245         } catch (PersistentStoreException e) {
246             log.severe("Error reading principal: " + e);
247             log.throwing(getClass().getName(), "authenticateBasicCredential", e);
248             return false;
249         }
250
251         //
252
// Verify these credentials on Exchange
253
//
254
boolean isExchangeUser = checkExchangeCredentials(
255             exchangeHost,
256             exchangePort,
257             exchangeFolder,
258             username,
259             credentials
260         );
261
262         if (!isExchangeUser) {
263             //
264
// User not authenticate
265
//
266
return false;
267         }
268
269         if (!principalFound) {
270             //
271
// We must create a new principal
272
//
273
principal = new Sync4jPrincipal(username, deviceId);
274             try {
275                 ps.store(principal);
276             } catch (PersistentStoreException ex) {
277                 ex.printStackTrace();
278                 log.severe("Error creating new principal: " + ex);
279                 log.throwing(getClass().getName(),
280                              "authenticateBasicCredential", ex);
281                 return false;
282             }
283
284             credential.getAuthentication().setPrincipalId(principal.getId());
285         }
286
287         return true;
288     }
289
290     /**
291      * Checks if the given login and password are valid
292      * credentials on exchange server
293      *
294      *
295      * @param server String
296      * @param port int
297      * @param login String
298      * @param password String
299      * @param version String
300      * @param appName String
301      *
302      *
303      * @return boolean
304      */

305     private boolean checkExchangeCredentials(String JavaDoc exchangeHost ,
306                                              int exchangePort ,
307                                              String JavaDoc exchangeFolder ,
308                                              String JavaDoc userName ,
309                                              String JavaDoc credentials) {
310         int status = 0;
311
312         if (exchangeHost == null || exchangeHost.equals("")) {
313
314             String JavaDoc message = "'Exchange host' is null or empty. You have to set " +
315                              "the Exchange server host in the file: " +
316                              "Sync4j/config/sync4j/server/security/ExchangeOfficer.xml";
317
318             if (log.isLoggable(Level.SEVERE)) {
319                 log.severe(message);
320             }
321
322             throw new IllegalStateException JavaDoc(message);
323         }
324
325
326         if (exchangeFolder == null || exchangeFolder.equals("")) {
327
328             String JavaDoc message = "'Exchange folder' is null or empty. You have to set " +
329                              "the Exchange folder folder in the file: " +
330                              "Sync4j/config/sync4j/server/security/ExchangeOfficer.xml";
331
332             if (log.isLoggable(Level.SEVERE)) {
333                 log.severe(message);
334             }
335
336             throw new IllegalStateException JavaDoc(message);
337         }
338
339         if (exchangeFolder.indexOf("/") == - 1) {
340
341             String JavaDoc message = "'Exchange folder' must be contain '/'. You have to set " +
342                              "the Exchange folder host in the file: " +
343                              "Sync4j/config/sync4j/server/security/ExchangeOfficer.xml";
344
345             if (log.isLoggable(Level.SEVERE)) {
346                 log.severe(message);
347             }
348
349             throw new IllegalStateException JavaDoc(message);
350         }
351
352         String JavaDoc exchangeServerName
353                         = exchangeFolder.
354                             substring(0,
355                                       exchangeFolder.indexOf("/"));
356
357         boolean check = false;
358
359         try {
360
361             ItemManager im = new ItemManager (exchangeHost,
362                                               exchangePort);
363
364             status = im.getExchangeAccessStatus(exchangeServerName ,
365                                                 userName ,
366                                                 credentials );
367
368             if (status == 401 || status == 406) {
369                 check = false;
370             } else {
371                 check = true;
372             }
373
374         } catch (DataAccessException dae) {
375             log.severe("Error getting connection: " + dae);
376             log.throwing(getClass().getName(), "check Exchange Credentials",
377                          dae);
378         }
379         return check;
380     }
381
382 }
383
Popular Tags