Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/jext/JextLoader.java


1   /*
2    * 01/20/2003 - 23:56:01
3    *
4    * JextLoader.java - Loads Jext instances in a single JVM
5    * Copyright (C) 2000 Romain Guy
6    * romain.guy@jext.org
7    * www.jext.org
8    *
9    * This program is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU General Public License
11   * as published by the Free Software Foundation; either version 2
12   * of the License, or any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   *
19   * You should have received a copy of the GNU General Public License
20   * along with this program; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22   */
23  
24  package org.jext;
25  
26  import java.io.*;
27  import java.net.*;
28  import java.util.*;
29  
30  import javax.swing.JOptionPane;
31  
32  /**
33   * This class creates a new socket connection which listens to client requests. Whenever
34   * a client logs onto the socket, we check its IP address.<br>
35   * Security implementation:<p>
36   * <ul>
37   * <li>If this address isn't 127.0.0.1 (aka localhost), the connection is rejected.</li>
38   * <li>The socket also needs to get the good message which must contain a give authorization key.
39   * If the given key or message is wrong, the connection is rejected.</li>
40   * <li>If the server rejects a connection, it also closes itself to avoid Denial Of Service
41   * attacks or brutal ones (trying for instance random keys).</li>
42   * </ul>
43   * @author Romain Guy
44   * @version 1.1.1
45   */
46  
47  final class JextLoader implements Runnable
48  {
49    private int port;
50    private File auth;
51    private String key;
52    private Thread tServer;
53    private ServerSocket server;
54  
55    JextLoader()
56    {
57      auth = new File(Jext.SETTINGS_DIRECTORY + ".auth-key");
58      // creates the authorization key
59      try
60      {
61        BufferedWriter writer = new BufferedWriter(new FileWriter(auth));
62        // 16 383 = unreserved range of ports
63        port = Math.abs(new Random().nextInt()) % (16383);
64        String portStr = Integer.toString(port);
65        key = Integer.toString(Math.abs(new Random().nextInt()) % (int) Math.pow(2, 30));
66        writer.write(portStr, 0, portStr.length());
67        writer.newLine();
68        writer.write(key, 0, key.length());
69        writer.flush();
70        writer.close();
71  
72        // creates the server
73        server = new ServerSocket(Jext.JEXT_SERVER_PORT + port);
74  
75      } catch (IOException ioe) {
76        ioe.printStackTrace();
77      }
78  
79      // server is necessarily threaded
80      tServer = new Thread(this);
81      tServer.start();
82    }
83  
84    /**
85     * Stops the server by inerrupting the thread, killing it and then
86     * closing the server itself. Finally, it erases the authorization
87     * key.
88     */
89  
90    public void stop()
91    {
92      tServer.interrupt();
93      tServer = null;
94  
95      try
96      {
97        if (server != null)
98          server.close();
99        auth.delete();
100     } catch (IOException ioe) { }
101   }
102 
103   /**
104    * Waits for a connexion request and handle it. The client should provide a special line
105    * containing a message, the arguments for the loading and the authorization key. This
106    * key is used to avoid security holes in your system.
107    */
108 
109   public void run()
110   {
111     while (tServer != null)
112     {
113       try
114       {
115         Socket client = server.accept();
116         if (client == null)
117           continue;
118 
119         if (!"127.0.0.1".equals(client.getLocalAddress().getHostAddress()))
120         {
121           client.close();
122           Jext.stopServer();
123           intrusion();
124           return;
125         }
126 
127         BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
128         String givenKey = reader.readLine();
129         reader.close();
130 
131         if (givenKey != null)//when backgrounding connects to check existance of server but sends
132           //nothing.
133           if (givenKey.startsWith("load_jext:") && givenKey.endsWith(":" + key))
134           {
135             Vector args = new Vector(1);
136             StringTokenizer st = new StringTokenizer(givenKey.substring(10,
137                        givenKey.length() - (key.length() + 1)), "?");
138             while (st.hasMoreTokens())
139               args.addElement(st.nextToken());
140 
141             if (args.size() > 0)
142             {
143               String arguments[] = new String[args.size()];
144               args.copyInto(arguments);
145               args = null;
146 
147               if (Jext.getBooleanProperty("jextLoader.newWindow"))
148               {
149           Jext.newWindow(arguments);
150               } else if (!Jext.isRunningBg()) {
151           ArrayList instances = Jext.getInstances();
152                 synchronized(instances) {
153                   if (instances.size() != 0) {//can be 0 when backgrounding.??? No more!
154                     JextFrame parent = (JextFrame) instances.get(0);
155                     for (int i = 0; i < arguments.length; i++)
156                       parent.open(arguments[i]);
157                     //parent.setVisible(true);//this code is not good when running background server,
158                     //since Jext keeps builtTextArea set(and doesn't open a new one until it isn't unset).
159                     //And so setVisible is not needed.
160                   } else {
161                     Jext.newWindow(arguments);
162                     System.err.println("DEBUG - instances.size() == 0 in JextLoader.java!");
163                   }
164                 }
165 
166               } else                    //when Jext.isRunningBg()
167                 Jext.newWindow(arguments);
168             } else
169               Jext.newWindow();
170 
171             client.close();
172           } else if (givenKey.equals("kill:" + key)) {
173             if (Jext.isRunningBg())// && Jext.getWindowsCount() <= 1 )
174             {
175               ArrayList instances = Jext.getInstances();
176               synchronized (instances)
177               {
178                 //normally at least one window is always open, even if hidden, but in some moments
179                 //this isn't true(when the user exits jext and it has not still started a new window).
180                 //If one window is open, we must check it is not shown.
181                 JextFrame lastInstance = null;
182                 if (instances.size() == 0 || instances.size() == 1 && 
183                     ! ( lastInstance = (JextFrame)instances.get(0) ) .isVisible())
184                 {
185                   if (instances.size() != 0)
186                   {
187                     Jext.closeToQuit(lastInstance, true);
188                     //since the window has not been shown this could be useless, but maybe not, especially to
189                     //dispatch JextEvent's.
190                   }
191                   //I've commented out the above code since it causes bugs with the ProjectManagement,
192                   //that is NullPointerEx. I'm trying if this doesn't happen without cleanMemory.
193                   Jext.finalCleanupAndExit();//check well this! TODO
194                 }
195               }
196             }
197           } else {
198             client.close();
199             Jext.stopServer();
200             intrusion();
201             return;
202           }
203       } catch (IOException ioe) { }
204     }
205   }
206 
207   // warn the user that someone is attempting to break into his system
208 
209   private void intrusion()
210   {
211     JOptionPane.showMessageDialog(null,
212             "An intrusion is attempted against your system !\nJext will close its opened " + "sockets to preserve system integrity.\nYou should warn the network administrator.",
213             "Intrusion attempt...", JOptionPane.WARNING_MESSAGE);
214   }
215 
216   /***************************************************************************
217   Patch
218      -> Memory management improvements : it may help the garbage collector.
219      -> Author : Julien Ponge (julien@izforge.com)
220      -> Date : 23, May 2001
221   ***************************************************************************/
222   protected void finalize() throws Throwable
223   {
224     super.finalize();
225 
226     auth = null;
227     key = null;
228     tServer = null;
229     server = null;
230   }
231   // End of patch
232 }
233 
234 // End of JextLoader.java