Author: bdonlan
Date: 2005-05-31 00:02:26 -0400 (Tue, 31 May 2005)
New Revision: 743
Added:
trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannel.java
trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannelPlugin.java
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/AlreadyExistsException.java
Modified:
trunk/clients/Javer2/server.conf
trunk/clients/Javer2/src/org/haverdev/haver/Client.java
trunk/clients/Javer2/src/org/haverdev/haver/server/Channel.java
trunk/clients/Javer2/src/org/haverdev/haver/server/ChannelBase.java
trunk/clients/Javer2/src/org/haverdev/haver/server/PersistantLobby.java
trunk/clients/Javer2/src/org/haverdev/haver/server/SSLAcceptLoop.java
trunk/clients/Javer2/src/org/haverdev/haver/server/UserConnection.java
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/UserAlreadyExists.java
trunk/clients/Javer2/src/org/haverdev/javer2/JaverForm.java
Log:
OPEN/CLOSE, SSL for client, various other tweaks
Modified: trunk/clients/Javer2/server.conf
===================================================================
--- trunk/clients/Javer2/server.conf 2005-05-30 01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/server.conf 2005-05-31 04:02:26 UTC (rev 743)
@@ -38,7 +38,7 @@
# they will be tried in listed order
haver.state.init=init
haver.state.login=login
-haver.state.normal=normal
+haver.state.normal=normal dynachan
# The implementation class
init.class=org.haverdev.haver.server.InitContext
@@ -50,11 +50,15 @@
normal.class=org.haverdev.haver.server.NormalContext
+dynachan.class=org.haverdev.haver.server.DynamicChannelPlugin
+
# Optional stugg
# Plugin classes to load
-haver.Plugins=org.haverdev.haver.server.EntityLoader
+haver.Plugins=org.haverdev.haver.server.EntityLoader
org.haverdev.haver.server.DynamicChannelPlugin
+org.haverdev.haver.server.DynamicChannelPlugin.store=channelStore.xml
+
# Entities to load
org.haverdev.haver.server.EntityLoader.entities=stats persist
Modified: trunk/clients/Javer2/src/org/haverdev/haver/Client.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/haver/Client.java 2005-05-30
01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/haver/Client.java 2005-05-31
04:02:26 UTC (rev 743)
@@ -15,6 +15,7 @@
* @author bdonlan
*/
public class Client {
+
HashSet listening = new java.util.HashSet();
CallbackDist dist;
@@ -379,8 +380,11 @@
} catch (IOException e2) {}
return;
}
+ run();
+ }
+
+ protected void run() {
try {
-
writer = new PrintWriter
(new OutputStreamWriter
(s = new NonblockingOutputStream
@@ -469,6 +473,21 @@
io.start();
}
+ public synchronized void connect(Socket s) throws IllegalStateException
+ {
+ if (io != null && io.isAlive()) {
+ throw new IllegalStateException("Already connecting");
+ }
+ name = null;
+ theSocket = s;
+ io = new Thread(new Runnable() {
+ public void run() {
+ self.run();
+ }
+ });
+ io.start();
+ }
+
/**
* Base class for event listeners for synchronous methods
*/
@@ -584,6 +603,12 @@
m.block();
}
+ public void syncConnect(Socket s, String name) throws IOException,
InterruptedException {
+ ConnectMonitor m = new ConnectMonitor(name);
+ connect(s);
+ m.block();
+ }
+
/**
* Adds a callback to notify when an event occurs
* @param c Callback class to add
Modified: trunk/clients/Javer2/src/org/haverdev/haver/server/Channel.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/haver/server/Channel.java
2005-05-30 01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/haver/server/Channel.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -30,7 +30,7 @@
* Silently adds an entity to the channel
* @param e The entity to add
*/
- public void register(Entity e);
+ public void register(Entity e) throws PropagatedException;
/**
* Silently removes an entity from the channel
* @param e The entity to remove
Modified: trunk/clients/Javer2/src/org/haverdev/haver/server/ChannelBase.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/haver/server/ChannelBase.java
2005-05-30 01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/haver/server/ChannelBase.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -6,6 +6,7 @@
package org.haverdev.haver.server;
import java.util.*;
+import org.haverdev.haver.server.exceptions.*;
/**
*
@@ -13,8 +14,8 @@
*/
public abstract class ChannelBase extends EntityBase implements Channel {
- HashSet everything = new HashSet();
- HashMap namespaces = new HashMap();
+ protected HashSet everything = new HashSet();
+ protected HashMap namespaces = new HashMap();
static final String[] emptyArray = {};
@@ -74,7 +75,7 @@
return (Entity)subset.get(name.toLowerCase());
}
- public synchronized void register(Entity e) {
+ public synchronized void register(Entity e) throws PropagatedException {
String namespace = e.getNamespace().toLowerCase();
String name = e.getName().toLowerCase().intern();
if (contains(e))
Added: trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannel.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannel.java
2005-05-30 01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannel.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -0,0 +1,55 @@
+/*
+ * DynamicChannel.java
+ *
+ * Created on May 30, 2005, 11:29 PM
+ */
+
+package org.haverdev.haver.server;
+import org.haverdev.haver.server.exceptions.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class DynamicChannel extends ChatChannel {
+
+ /** Creates a new instance of DynamicChannel */
+ public DynamicChannel() {
+ }
+
+ volatile boolean isClosing = false;
+
+ public void setClosing(boolean c) {
+ isClosing = c;
+ }
+
+ public boolean isClosing() {
+ return isClosing;
+ }
+
+ public void register(Entity e) throws PropagatedException {
+ if (isClosing)
+ throw new Forbidden("Channel is closing.");
+ super.register(e);
+ }
+
+ public void close() {
+ synchronized (this) {
+ if (isClosing)
+ return;
+ isClosing = true;
+ }
+ Entity[] everyone = filterContents("user");
+ UserEntity[] users = new UserEntity[everyone.length];
+ System.arraycopy(everyone, 0, users, 0, everyone.length);
+
+ for (int i = 0; i < users.length; i++) {
+ users[i].drop(this);
+ users[i].notifyPart(this, users[i]);
+ unregister(users[i]);
+ }
+
+ Lobby.theLobby.unregister(this);
+ }
+
+}
Property changes on:
trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannel.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added:
trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannelPlugin.java
===================================================================
---
trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannelPlugin.java
2005-05-30 01:30:02 UTC (rev 742)
+++
trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannelPlugin.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -0,0 +1,83 @@
+/*
+ * DynamicChannelPlugin.java
+ *
+ * Created on May 30, 2005, 11:28 PM
+ */
+
+package org.haverdev.haver.server;
+
+import org.haverdev.haver.server.exceptions.*;
+import java.util.*;
+import java.io.*;
+import java.beans.*;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author bdonlan
+ */
+public final class DynamicChannelPlugin extends UserCommandReflect {
+
+ static Logger log = Logger.getLogger(DynamicChannelPlugin.class);
+ static HashMap theChannels = new HashMap();
+ static String file =
System.getProperty("org.haverdev.haver.server.DynamicChannelPlugin.store");
+
+ UserConnection conn;
+
+ public DynamicChannelPlugin(UserConnection conn, String name) {
+ super(conn, name);
+ }
+
+ public static void initPlugin() {
+ try {
+ FileInputStream f = new FileInputStream(file);
+ BufferedInputStream b = new BufferedInputStream(f);
+ XMLDecoder xd = new XMLDecoder(b);
+ theChannels = (HashMap)xd.readObject();
+ xd.close();
+ Iterator i = theChannels.values().iterator();
+ while (i.hasNext())
+ Lobby.theLobby.register((Entity)i.next());
+ } catch (Throwable t) {
+ log.error("Error while loading store, ignoring", t);
+ }
+
+
+ }
+
+ public synchronized static void commit() {
+ try {
+ FileOutputStream f = new FileOutputStream(file);
+ BufferedOutputStream b = new BufferedOutputStream(f);
+ XMLEncoder xe = new XMLEncoder(b);
+ xe.writeObject(theChannels);
+ xe.close();
+ } catch (IOException e) {
+ log.error("Error while saving", e);
+ }
+ }
+
+ public synchronized void handle_OPEN(String[] args) throws
PropagatedException {
+ String channel = args[1];
+ DynamicChannel newchan = new DynamicChannel();
+ newchan.setName(channel);
+
+ Lobby.theLobby.register(newchan);
+ if (newchan != Lobby.theLobby.lookup("channel", channel))
+ throw new AlreadyExistsException("channel", channel);
+
+ theChannels.put(channel, newchan);
+ commit();
+ }
+
+ public synchronized void handle_CLOSE(String[] args) throws
PropagatedException {
+ String channel = args[1];
+
+ if (!theChannels.containsKey(channel))
+ throw new ChannelNotFound(channel);
+ DynamicChannel dc = (DynamicChannel)theChannels.get(channel);
+ dc.close();
+ theChannels.remove(channel);
+ commit();
+ }
+}
Property changes on:
trunk/clients/Javer2/src/org/haverdev/haver/server/DynamicChannelPlugin.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified:
trunk/clients/Javer2/src/org/haverdev/haver/server/PersistantLobby.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/haver/server/PersistantLobby.java
2005-05-30 01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/haver/server/PersistantLobby.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -5,6 +5,8 @@
*/
package org.haverdev.haver.server;
+import org.haverdev.haver.server.exceptions.*;
+
import java.io.*;
import java.beans.*;
import java.util.zip.*;
@@ -27,7 +29,7 @@
static final Logger logger = Logger.getLogger(PersistantLobby.class);
/** Creates a new instance of PersistentLobby */
- public PersistantLobby() throws java.io.IOException {
+ public PersistantLobby() throws java.io.IOException, PropagatedException {
super();
setPersistant(false);
storePath =
System.getProperty("org.haverdev.haver.server.PersistantLobby.storePath");
@@ -56,12 +58,12 @@
commitTimer.schedule(commitTask, commitInterval, commitInterval);
}
- public PersistantLobby(String name) throws IOException {
+ public PersistantLobby(String name) throws IOException,
PropagatedException {
this();
setName(name);
}
- void loadAll() throws IOException {
+ void loadAll() throws IOException, PropagatedException {
FileInputStream fs = new FileInputStream(storePath);
GZIPInputStream zs = new GZIPInputStream(fs);
BufferedInputStream bs = new BufferedInputStream(zs);
Modified: trunk/clients/Javer2/src/org/haverdev/haver/server/SSLAcceptLoop.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/haver/server/SSLAcceptLoop.java
2005-05-30 01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/haver/server/SSLAcceptLoop.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -28,7 +28,9 @@
for (int i = 0; i < ports.length; i++) {
int port = Integer.decode(ports[i]).intValue();
try {
- ServerSocket ssocket = ssocketFactory.createServerSocket(port);
+ SSLServerSocket ssocket;
+ ssocket =
(SSLServerSocket)ssocketFactory.createServerSocket(port);
+ ssocket.setWantClientAuth(true);
new SSLAcceptLoop(ssocket, port).start();
} catch (Throwable t) {
Logger.getLogger(SSLAcceptLoop.class).error("While opening
listening socket on port " + port, t);
Modified: trunk/clients/Javer2/src/org/haverdev/haver/server/UserConnection.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/haver/server/UserConnection.java
2005-05-30 01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/haver/server/UserConnection.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -237,7 +237,7 @@
public void sendLine(String[] args) {
String line = Misc.encodeLine(args);
outgoing.post(line);
- log.debug("S: " + line);
+ log.debug("S: " + line.replaceAll("[\n\r]", ""));
}
public synchronized void processLine(String line) throws
PropagatedException {
Added:
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/AlreadyExistsException.java
===================================================================
---
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/AlreadyExistsException.java
2005-05-30 01:30:02 UTC (rev 742)
+++
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/AlreadyExistsException.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -0,0 +1,20 @@
+/*
+ * AlreadyExistsException.java
+ *
+ * Created on May 30, 2005, 11:47 PM
+ */
+
+package org.haverdev.haver.server.exceptions;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class AlreadyExistsException extends SimplePropagatedException {
+
+ /** Creates a new instance of AlreadyExistsException */
+ public AlreadyExistsException(String namespace, String name) {
+ super("exists." + namespace, name);
+ }
+
+}
Property changes on:
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/AlreadyExistsException.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified:
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/UserAlreadyExists.java
===================================================================
---
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/UserAlreadyExists.java
2005-05-30 01:30:02 UTC (rev 742)
+++
trunk/clients/Javer2/src/org/haverdev/haver/server/exceptions/UserAlreadyExists.java
2005-05-31 04:02:26 UTC (rev 743)
@@ -1,7 +1,7 @@
package org.haverdev.haver.server.exceptions;
-public final class UserAlreadyExists extends SimplePropagatedException {
+public final class UserAlreadyExists extends AlreadyExistsException {
public UserAlreadyExists(String name) {
- super("exists.user", name);
+ super("user", name);
}
}
Modified: trunk/clients/Javer2/src/org/haverdev/javer2/JaverForm.java
===================================================================
--- trunk/clients/Javer2/src/org/haverdev/javer2/JaverForm.java 2005-05-30
01:30:02 UTC (rev 742)
+++ trunk/clients/Javer2/src/org/haverdev/javer2/JaverForm.java 2005-05-31
04:02:26 UTC (rev 743)
@@ -10,16 +10,36 @@
import org.haverdev.haver.*;
import java.lang.reflect.*;
import java.io.*;
+import javax.net.*;
+import javax.net.ssl.*;
+
/**
*
* @author bdonlan
*/
public class JaverForm extends javax.swing.JPanel {
+ static final TrustManager[] trustAllCerts = new TrustManager[]{
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType) {
+ }
+ }
+ };
+
+ String host;
+ int port;
Thread connectThread = null;
Client cli = null;
Watcher watch = null;
+ SocketFactory factory;
class Watcher extends Callback {
public void onPrivateMessage(Client source, final String from, final
String type, final String[] args) throws Throwable {
@@ -38,7 +58,7 @@
watch = new Watcher();
cli.addNotify(watch);
try {
- cli.syncConnect("localhost", 7070, nick);
+ cli.syncConnect(factory.createSocket(host, port), nick);
serverpane.putLine("Connected!");
} catch (final Throwable t) {
SwingUtilities.invokeLater(new Runnable() {
@@ -52,11 +72,29 @@
}
}
- public final static void main(String[] args) {
+ public final static void main(final String[] args) throws Throwable {
+ if (args.length != 2 && (args.length != 3 || !args[0].equals("-ssl")))
{
+ System.err.println("Usage: [...] org.haverdev.javer2.JaverForm
[-ssl] host port");
+ System.exit(1);
+ }
+
+ final boolean ssl = args.length == 3;
+ final String host = args[args.length - 2];
+ final int port = Integer.decode(args[args.length - 1]).intValue();
+ SocketFactory sf_;
+ if (ssl) {
+ SSLContext sc = SSLContext.getInstance("SSL");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ sf_ = sc.getSocketFactory();
+ } else {
+ sf_ = SocketFactory.getDefault();
+ }
+ final SocketFactory sf = sf_;
+
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("test");
- JaverForm form = new JaverForm();
+ JaverForm form = new JaverForm(host, port, sf);
f.getContentPane().add(form);
f.pack();
f.setVisible(true);
@@ -68,11 +106,17 @@
ServerPane serverpane;
/** Creates new form JaverForm */
- public JaverForm() {
+ public JaverForm(String host, int port, SocketFactory sf) {
+ this.host = host;
+ this.port = port;
+ this.factory = sf;
initComponents();
serverpane = new ServerPane();
addPane(serverpane);
- serverpane.putLine("Welcome to haver!");
+ serverpane.putLine("Welcome to haver! Enter your username to login");
+ if (factory instanceof SSLSocketFactory) {
+ serverpane.putLine("Warning: SSL mode in use. Currently, no server
certificate authentication is performed on SSL connections. There is no
protection against man-in-the-middle attacks.");
+ }
}
HashMap panes = new HashMap();
@@ -165,12 +209,12 @@
add(jPanel1, java.awt.BorderLayout.SOUTH);
}//GEN-END:initComponents
-
+
private void inputBoxKeyTyped(java.awt.event.KeyEvent evt)
{//GEN-FIRST:event_inputBoxKeyTyped
if (evt.getKeyChar() == '\n')
sendLine(null);
}//GEN-LAST:event_inputBoxKeyTyped
-
+
private void sendLine(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_sendLine
if (connectThread != null) {
serverpane.putLine("Still connecting, please wait...");
@@ -225,7 +269,7 @@
}
void slash_XYZZY(String arg) {
- ((Pane)currentPane()).putLine("Nothing happens.");
+ ((Pane)currentPane()).putLine("--- Nothing happens.");
}
void slash_MSG(String arg) throws IOException {