KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > security > DelayThread


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.core.security;
66
67 import org.apache.log4j.Logger;
68
69
70 /**
71  * Simple class called to suspend thread execution for x many seconds before
72  * offering a retry to login. Helps to slow down brute force attacks.
73  * [a 40,000 word dictionary attack prolonged by 3 seconds a piece
74  * adds potentially 33 hours to the attack time. Yes this can be partially bypassed
75  * through simultaneous requests, but it still adds significant reponse time]
76  * <p/>
77  * Why this class instead of just sleep(3000) or whatever? The answer is that
78  * this thread is often called from multi-thread handling servers with only
79  * one instance. You can't just call sleep() without becoming the Monitor
80  * "Owner", but synchronized(this) will sleep the whole login object. Thus
81  * effective keeping all login processing happening. A definite DOS attack.
82  * Thus we sleep the requesting thread while waiting on this "lock object"
83  * </p><p>
84  * What about people issuing bad requests in parallel? Simple! It all has
85  * to queue up for a lock on a single instance. Thus delay may be signicantly
86  * longer if lots of people are issuing bad requests. Thus creating an
87  * effective CPU choke point.
88  * </p>
89  *
90  * @author Michael Rimov
91  * @since Expresso v3.0
92  */

93 public class DelayThread
94         extends Thread JavaDoc {
95     protected static DelayThread theInstance = null;
96     private static Logger log = Logger.getLogger(DelayThread.class);
97     volatile protected Object JavaDoc lockObject = new Object JavaDoc();
98
99     /**
100      * The number of seconds to delay when the thread is run.
101      */

102     int secondsDelay = 0;
103
104     public DelayThread() {
105
106     }
107
108     /**
109      * Create the object and when run, pause for x number of seconds.
110      *
111      * @param numSeconds the number of seconds to pause when this thread runs.
112      */

113     public DelayThread(int numSeconds) {
114         setDelay(numSeconds);
115
116     }
117
118     /**
119      * Sets the number of seconds to delay when run.
120      *
121      * @param numSeconds The number of seconds to run.
122      */

123     public void setDelay(int numSeconds) {
124         if (numSeconds >= 0) {
125             secondsDelay = numSeconds;
126         }
127     }
128
129     /**
130      * return the current setting for number of seconds to delay
131      *
132      * @return integer in seconds for delaying things.
133      */

134     public int getDelay() {
135         return secondsDelay;
136     }
137
138     /**
139      * Execution path - simply pause for secondsDelay number of seconds.
140      */

141     public void run() {
142         //Debugging functions
143
java.util.Date JavaDoc startTime = null;
144         java.util.Date JavaDoc endTime = null;
145
146         if (log.isDebugEnabled()) {
147             startTime = new java.util.Date JavaDoc();
148             log.debug("Entering delay thread. Time=" + startTime.getTime());
149         }
150         try {
151             synchronized (lockObject) {
152                 if (this.isInterrupted()) {
153                     return;
154                 }
155                 if (secondsDelay > 0) {
156                     sleep(secondsDelay * 1000);
157                 }
158             }
159         } catch (InterruptedException JavaDoc e) {
160
161             //Do nothing if interrupted
162
}
163         if (log.isDebugEnabled()) {
164             endTime = new java.util.Date JavaDoc();
165             log.debug("Exiting delay thread. Time=" + endTime.getTime() +
166                     " time delta = " +
167                     (endTime.getTime() - startTime.getTime()) + " ms.");
168         }
169     }
170
171     /**
172      * Executed in the main thread. Simply will return when the delay is
173      * complete.
174      */

175     public static void delay() {
176         DelayThread.delay(2);
177
178     }
179
180     /**
181      * Function interrupts the thread so that it exits.
182      * Mainly used for shutdown procedures.
183      */

184     public synchronized static void kill() {
185         if (theInstance == null) {
186             return;
187         }
188
189         theInstance.interrupt();
190
191         try {
192             theInstance.join(1000);
193         } catch (InterruptedException JavaDoc ie) {
194         }
195
196         theInstance = null;
197         log = null;
198
199     }
200
201     /**
202      * Constructs the single instance of the delaythread
203      */

204     private synchronized static void instantiate() {
205         if (theInstance == null) {
206             theInstance = new DelayThread();
207             theInstance.setName("Security Delay Thread");
208             theInstance.setDaemon(false);
209         }
210     }
211
212     /**
213      * Executed in the main thread. Simply will return when the delay is
214      * complete.
215      *
216      * @param numSeconds - The number of seconds to delay
217      */

218     public static void delay(int numSeconds) {
219         if (theInstance == null) {
220             instantiate();
221         }
222         try {
223             theInstance.setDelay(numSeconds);
224             theInstance.run();
225             theInstance.join();
226         } catch (java.lang.InterruptedException JavaDoc e) {
227         }
228     }
229 }
Popular Tags