diff --git a/src/GUI/ChatScreen.form b/src/GUI/ChatScreen.form index 8628672c8b03ba53bb54ae10847a29458c98b80e..8d821a823277ef2693243eb5e949cc285b0c8033 100644 --- a/src/GUI/ChatScreen.form +++ b/src/GUI/ChatScreen.form @@ -121,6 +121,24 @@ <text value="Exit This Room"/> </properties> </component> + <grid id="e92cc" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <margin top="0" left="0" bottom="0" right="0"/> + <constraints> + <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + </constraints> + <properties/> + <border type="none" title="Drawing Users"/> + <children> + <component id="9aa9f" class="javax.swing.JList" binding="list1" default-binding="true"> + <constraints> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="2" anchor="0" fill="3" indent="0" use-parent-layout="false"> + <preferred-size width="150" height="50"/> + </grid> + </constraints> + <properties/> + </component> + </children> + </grid> </children> </grid> <grid id="5d886" binding="chatPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> diff --git a/src/GUI/ChatScreen.java b/src/GUI/ChatScreen.java index 6e86ccf552a8c42e06d51889dcf9916c71b51407..f5f694af8a0277e3517f0aaaaecdbb655610623a 100644 --- a/src/GUI/ChatScreen.java +++ b/src/GUI/ChatScreen.java @@ -1,9 +1,11 @@ package GUI; import client.Client; +import remote.EncryptDecrypt; import remote.IChatController; import remote.IClientController; +import javax.crypto.SealedObject; import javax.swing.*; import java.awt.event.*; import java.rmi.RemoteException; @@ -11,10 +13,10 @@ import java.rmi.RemoteException; public class ChatScreen { public JPanel panel2; - public JPanel othersPanel; private JButton sendButton; + private JPanel othersPanel; private JComboBox sendMessageToComboBox; private JTextArea chatDisplayBox; private JComboBox kickUserComboBox; @@ -30,6 +32,13 @@ public class ChatScreen { private JPanel managersPanel; private JPanel chatPanel; private JButton exitThisRoomButton; + private JList list1; + + public JTextArea getActiveDrawingUserBox() { + return activeDrawingUserBox; + } + + private JTextArea activeDrawingUserBox; private JFrame frame; public Client getClient() { @@ -107,14 +116,14 @@ public class ChatScreen { System.out.println("Send button pressed"); String toUser = sendMessageToComboBox.getSelectedItem().toString(); - + SealedObject messageSealed = EncryptDecrypt.encryptString(message,client.getEncryptionUpdate().getSharedSecretKey()); if( toUser.equals("All") ) { - chatController.broadcastMessage(client.getUserName(), message); + chatController.broadcastMessage(client.getUserName(), messageSealed); } else { - chatController.sendPrivateMessage(client.getUserName(), toUser, message); + chatController.sendPrivateMessage(client.getUserName(), toUser, messageSealed); } } catch (RemoteException ex) diff --git a/src/GUI/DrawingArea.java b/src/GUI/DrawingArea.java index 42b74cdfd99efea2d9e05d4ab74cc1e5c1921de2..4df0903efa1151b3bbc3042599a995097fb82ce4 100644 --- a/src/GUI/DrawingArea.java +++ b/src/GUI/DrawingArea.java @@ -287,6 +287,7 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis try { drawingController.broadcastDrawing(client.getUserName(), drawing, currentMode.toString(), shapeColor, strokeSize); + drawingController.broadcastDrawingUser(client.getUserName()); } catch (RemoteException ex) { ex.printStackTrace(); } diff --git a/src/client/ChatUpdate.java b/src/client/ChatUpdate.java index 2edc3ccdd3c5a1c5262fdc2107d9f28b74b556ce..9447ca5c1f29f9122f1bfdb2eacdc0d538c2995a 100644 --- a/src/client/ChatUpdate.java +++ b/src/client/ChatUpdate.java @@ -1,7 +1,9 @@ package client; +import remote.EncryptDecrypt; import remote.IChatUpdate; +import javax.crypto.SealedObject; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -17,8 +19,9 @@ public class ChatUpdate extends UnicastRemoteObject implements IChatUpdate, Seri } @Override - public boolean notifyChat(String fromClient, String message, boolean isPrivate) throws RemoteException - { + public boolean notifyChat(String fromClient, SealedObject messageSealed, boolean isPrivate) throws RemoteException + { String message; + message = EncryptDecrypt.decryptString(messageSealed,client.getEncryptionUpdate().getSharedSecretKey()); String outputString; if( isPrivate ) diff --git a/src/client/Client.java b/src/client/Client.java index a241d3301ac316466caf8ef33262d6f07ac28a1f..a9ca1b3b1ec660e097ede6d0cebefa7401f7738b 100644 --- a/src/client/Client.java +++ b/src/client/Client.java @@ -4,10 +4,13 @@ import GUI.ApplicationMain; import GUI.ChatScreen; import GUI.PaintGUI; import GUI.StartScreen; +import remote.EncryptDecrypt; import remote.IChatController; import remote.IClientController; import remote.IDrawingController; +import javax.crypto.Cipher; +import javax.crypto.SealedObject; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; @@ -18,6 +21,11 @@ public class Client { private final String DEFAULT_USERNAME = "Anonymous"; private final String DEFAULT_SERVER_ADDRESS = "localhost"; + + public EncryptionUpdate getEncryptionUpdate() { + return encryptionUpdate; + } + private final EncryptionUpdate encryptionUpdate; private String defaultUserName; @@ -156,16 +164,19 @@ public class Client System.out.println("User name:" + getUserName()); System.out.println("Password: " + password); - if( clientController.checkPassword(password) ) - { - if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate, this.encryptionUpdate)) - { - System.out.println("Connected to server"); - return 5; + if (clientController.setSharedKey(this.encryptionUpdate)) { + SealedObject sealedPassword = EncryptDecrypt.encryptString(password, this.encryptionUpdate.getSharedSecretKey()); + + if (clientController.checkPassword(sealedPassword)) { + if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate)) { + System.out.println("Connected to server"); + return 5; + } else { + return 6; + } } - else - { - return 6; + else { + return 4; } } else @@ -186,17 +197,19 @@ public class Client System.out.println("User name:" + getUserName()); System.out.println("Password: " + password); - - if( clientController.checkPassword(password) ) - { - if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate, this.encryptionUpdate)) - { - System.out.println("Connected to server"); - return 1; + if (clientController.setSharedKey(this.encryptionUpdate)) { + SealedObject sealedPassword = EncryptDecrypt.encryptString(password, this.encryptionUpdate.getSharedSecretKey()); + + if (clientController.checkPassword(sealedPassword)) { + if (clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate)) { + System.out.println("Connected to server"); + return 1; + } else { + return 2; + } } - else - { - return 2; + else { + return 4; } } else diff --git a/src/client/DrawingUpdate.java b/src/client/DrawingUpdate.java index 00f9bd09ada757434e3a8143f936f52913c59cbd..c2941d4425815e58a0ac495901b2eb56cdfd68db 100644 --- a/src/client/DrawingUpdate.java +++ b/src/client/DrawingUpdate.java @@ -20,6 +20,10 @@ public class DrawingUpdate extends UnicastRemoteObject implements IDrawingUpdate this.client = client; } + public void notifyUserIsDrawing(String fromClient){ + client.getApplicationMain().getChatScreen().getActiveDrawingUserBox().append(fromClient); + } + @Override public boolean notifyTextDrawing(String fromClient, String text, Font font, Color color, Point startPoint) throws RemoteException { client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); diff --git a/src/client/EncryptionUpdate.java b/src/client/EncryptionUpdate.java index 001c1295c64d042cba748e108675cbe14f3a4503..52d1fa52d2f6ee065599c615ec936c707b733e24 100644 --- a/src/client/EncryptionUpdate.java +++ b/src/client/EncryptionUpdate.java @@ -14,7 +14,13 @@ public class EncryptionUpdate extends UnicastRemoteObject implements IEncryption private PrivateKey priv; private PublicKey pub; + + public SecretKey getSharedSecretKey() { + return sharedSecretKey; + } + private SecretKey sharedSecretKey; + private Cipher myCipher; public PublicKey getPub() { return pub; @@ -26,6 +32,8 @@ public class EncryptionUpdate extends UnicastRemoteObject implements IEncryption cipher.init(Cipher.DECRYPT_MODE, priv); sharedSecretKey = new SecretKeySpec(cipher.doFinal(encryptedSharedSecretKey), "AES"); System.out.println("Client holds this shared key: "+sharedSecretKey); + + } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { @@ -55,4 +63,5 @@ public class EncryptionUpdate extends UnicastRemoteObject implements IEncryption } } + } diff --git a/src/remote/IChatController.java b/src/remote/IChatController.java index 82305870e4b5438637dc6b8759ce3235b6a02dd0..6c6bb3802b19e08c81d3a18ab0cfe380ba67036c 100644 --- a/src/remote/IChatController.java +++ b/src/remote/IChatController.java @@ -1,12 +1,13 @@ package remote; +import javax.crypto.SealedObject; import java.rmi.Remote; import java.rmi.RemoteException; public interface IChatController extends Remote { - boolean broadcastMessage(String fromClient, String message) throws RemoteException; + boolean broadcastMessage(String fromClient, SealedObject messageSealed) throws RemoteException; boolean broadcastMessageUserLogin(String fromClient) throws RemoteException; boolean broadcastMessageUserLogout(String fromClient) throws RemoteException; - boolean sendPrivateMessage(String fromClient, String toClient, String message) throws RemoteException; + boolean sendPrivateMessage(String fromClient, String toClient, SealedObject messageSealed) throws RemoteException; } diff --git a/src/remote/IChatUpdate.java b/src/remote/IChatUpdate.java index 0c9b54d9daab6367372e1987f2c988a94bcbde8d..ffde71cc00a9bf8ab373df8be513f20d6476a4a2 100644 --- a/src/remote/IChatUpdate.java +++ b/src/remote/IChatUpdate.java @@ -1,12 +1,13 @@ package remote; +import javax.crypto.SealedObject; import java.io.Serializable; import java.rmi.Remote; import java.rmi.RemoteException; public interface IChatUpdate extends Remote, Serializable { - boolean notifyChat(String fromClient, String message, boolean isPrivate) throws RemoteException; + boolean notifyChat(String fromClient, SealedObject messageSealed, boolean isPrivate) throws RemoteException; boolean notifyUserLogin(String fromClient) throws RemoteException; boolean notifyUserLogout(String fromClient) throws RemoteException; } diff --git a/src/remote/IClientController.java b/src/remote/IClientController.java index a8b583f54c6e13d9bf60c7450dab34118ae8045b..67b319d8d260b6dacec7edb0d87d0fe1a4a5122a 100644 --- a/src/remote/IClientController.java +++ b/src/remote/IClientController.java @@ -1,5 +1,6 @@ package remote; +import javax.crypto.SealedObject; import java.rmi.Remote; import java.rmi.RemoteException; @@ -7,7 +8,7 @@ public interface IClientController extends Remote { enum Action {KICKOUT, ASSIGNADMIN, KICKALL}; - boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing, IEncryptionUpdate encryptionUpdate) throws RemoteException; + boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException; void quit(String username) throws RemoteException; @@ -21,5 +22,6 @@ public interface IClientController extends Remote String getAdmin() throws RemoteException; - boolean checkPassword(String password) throws RemoteException; + boolean checkPassword(SealedObject sealedPassword) throws RemoteException; + public boolean setSharedKey(IEncryptionUpdate encryptionUpdate) throws RemoteException; } diff --git a/src/remote/IDrawingController.java b/src/remote/IDrawingController.java index 3aa40d3bcc5f77607e8df4e711a63305e083edc6..8b2e030b1842076a371d4c5a63c4b0a86ee71e17 100644 --- a/src/remote/IDrawingController.java +++ b/src/remote/IDrawingController.java @@ -21,5 +21,6 @@ public interface IDrawingController extends Remote { boolean broadcastClearCanvas(String fromClient) throws RemoteException; boolean broadcastUpdateImage(String fromClient) throws RemoteException; boolean updateImage(byte[] rawImage) throws RemoteException; + void broadcastDrawingUser (String fromClient) throws RemoteException; void getImage(String fromClient) throws RemoteException; } diff --git a/src/remote/IDrawingUpdate.java b/src/remote/IDrawingUpdate.java index a52781b7d17b92e080a36c8661e82107c95580af..73d1d849dbc4380102a52929a0e46c3545749eef 100644 --- a/src/remote/IDrawingUpdate.java +++ b/src/remote/IDrawingUpdate.java @@ -11,4 +11,5 @@ public interface IDrawingUpdate extends Remote, Serializable { boolean notifyDraggingDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException; boolean notifyCanvasClearance(String fromClient) throws RemoteException; boolean receiveImage(byte[] rawImage) throws RemoteException; + public void notifyUserIsDrawing(String fromClient) throws RemoteException; } diff --git a/src/server/ChatController.java b/src/server/ChatController.java index a2a38a03e75bb952ed298a7f8050029cb38b0324..206bc18cdbc23971de7ee7462fdb9eb500d0e1bd 100644 --- a/src/server/ChatController.java +++ b/src/server/ChatController.java @@ -1,8 +1,10 @@ package server; +import remote.EncryptDecrypt; import remote.IChatController; import remote.IChatUpdate; +import javax.crypto.SealedObject; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -17,13 +19,16 @@ public class ChatController extends UnicastRemoteObject implements IChatControll } @Override - public boolean broadcastMessage(String fromClient, String message) throws RemoteException + public boolean broadcastMessage(String fromClient, SealedObject messageSealed) throws RemoteException { System.out.print("Broadcasting message to everyone..."); + int fromClientIndex = server.clientController.getUserIndex(fromClient); + String message = EncryptDecrypt.decryptString(messageSealed,server.users.get(fromClientIndex).getSharedSecretKey()); for( User u : server.users ) - { - u.getIChatUpdate().notifyChat(fromClient, message, false); + { u.getSharedSecretKey(); + SealedObject messageSealedTo = EncryptDecrypt.encryptString(message,u.getSharedSecretKey()); + u.getIChatUpdate().notifyChat(fromClient, messageSealedTo, false); } System.out.print("...DONE\n"); @@ -68,16 +73,22 @@ public class ChatController extends UnicastRemoteObject implements IChatControll } @Override - public boolean sendPrivateMessage(String fromClient, String toClient, String message) throws RemoteException - { + public boolean sendPrivateMessage(String fromClient, String toClient, SealedObject messageSealed) throws RemoteException + { String message; int toClientIndex = server.clientController.getUserIndex(toClient); int fromClientIndex = server.clientController.getUserIndex(fromClient); if( toClientIndex >= 0 && fromClientIndex >= 0 ) { - server.users.get(toClientIndex).getIChatUpdate().notifyChat(fromClient, message, true); + message = EncryptDecrypt.decryptString(messageSealed,server.users.get(fromClientIndex).getSharedSecretKey()); + + SealedObject messageSealedOutgoingFrom = EncryptDecrypt.encryptString(message,server.users.get(fromClientIndex).getSharedSecretKey()); + + SealedObject messageSealedOutgoingTo = EncryptDecrypt.encryptString(message,server.users.get(toClientIndex).getSharedSecretKey()); + + server.users.get(toClientIndex).getIChatUpdate().notifyChat(fromClient, messageSealedOutgoingTo, true); - server.users.get(fromClientIndex).getIChatUpdate().notifyChat(fromClient, message, true); + server.users.get(fromClientIndex).getIChatUpdate().notifyChat(fromClient, messageSealedOutgoingFrom, true); return true; } diff --git a/src/server/ClientController.java b/src/server/ClientController.java index 6ff46e6e94e5dc7a6cc1d986ced4ff7866e9181f..d8ced8a05b6310956f922349b69e0bf42a1a63c4 100644 --- a/src/server/ClientController.java +++ b/src/server/ClientController.java @@ -2,8 +2,8 @@ package server; import remote.*; +import javax.crypto.*; import java.io.Serializable; -import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -16,8 +16,10 @@ public class ClientController extends UnicastRemoteObject implements IClientCont this.server = server; } + private SecretKey sharedSecretKey; + @Override - public boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing, IEncryptionUpdate encryptionUpdate) throws RemoteException + public boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException { System.out.println("I am in join"); if( getUserIndex(username) < 0 ) @@ -25,9 +27,7 @@ public class ClientController extends UnicastRemoteObject implements IClientCont // user with same username is not connected server.chatController.broadcastMessageUserLogin(username); - new MySharedKey(encryptionUpdate); - - User newUser = new User(username, clientChat, clientUpdate, clientDrawing); + User newUser = new User(username, clientChat, clientUpdate, clientDrawing, sharedSecretKey); server.users.add(newUser); @@ -219,8 +219,12 @@ public class ClientController extends UnicastRemoteObject implements IClientCont } } - public boolean checkPassword(String password) + @Override + public boolean checkPassword(SealedObject sealedPassword) { + System.out.println("Sealed passwords" + sealedPassword); + String password = EncryptDecrypt.decryptString(sealedPassword,this.sharedSecretKey); + System.out.println("unsealed password" + password); if( server.users.size() == 0 ) { server.setPassword(password); @@ -236,4 +240,14 @@ public class ClientController extends UnicastRemoteObject implements IClientCont return false; } } + public boolean setSharedKey(IEncryptionUpdate encryptionUpdate) throws RemoteException { + try { + sharedSecretKey = new MySharedKey(encryptionUpdate).getSharedSecretKey(); + return true; + + }catch (Exception e){ + return false; + } + + } } diff --git a/src/server/DrawingController.java b/src/server/DrawingController.java index 484ecdab32ba571564c62dbf2f2ff872698d9077..ce95c36a5236afe4e340c3ffcc934dafeedd5a90 100644 --- a/src/server/DrawingController.java +++ b/src/server/DrawingController.java @@ -1,5 +1,7 @@ package server; +import client.Client; +import remote.IChatUpdate; import remote.IDrawingController; import remote.IDrawingUpdate; @@ -7,6 +9,7 @@ import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; +import java.lang.reflect.Array; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -162,6 +165,18 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo } + public void broadcastDrawingUser (String fromClient) throws RemoteException { + System.out.println("Current client is drawing: " + fromClient); + IDrawingUpdate client; + for (User u: server.users){ + client = u.getIDrawingUpdate(); + client.notifyUserIsDrawing(fromClient); + } + + } + + + public boolean broadcastUpdateImage(String fromClient) throws RemoteException { System.out.print("Broadcasting new image loading to everyone..."); diff --git a/src/server/MySharedKey.java b/src/server/MySharedKey.java index e16485e2e87a5ff48c8ea4bd2bfe05757dc7802f..bd4c8abc513f1cd69605dc3da48583e643254988 100644 --- a/src/server/MySharedKey.java +++ b/src/server/MySharedKey.java @@ -13,6 +13,11 @@ import java.util.Base64; public class MySharedKey { private byte[] encryptedSharedSecretKey; private IEncryptionUpdate encryptionUpdate; + + public SecretKey getSharedSecretKey() { + return sharedSecretKey; + } + private SecretKey sharedSecretKey; @@ -21,7 +26,7 @@ public class MySharedKey { this.sharedSecretKey = new SecretKeySpec(new byte[16], "AES"); System.out.println(sharedSecretKey); this.encryptedSharedSecretKey = wrapKey(encryptionUpdate.getPub()); - System.out.println("Shared key on server:" + encryptedSharedSecretKey); + System.out.println("Shared key on server:" + sharedSecretKey); encryptionUpdate.setSharedKey(encryptedSharedSecretKey); } diff --git a/src/server/Server.java b/src/server/Server.java index 5a9b983141a46f1dd5fd60d0076f0e733aadff47..9e0084d77316ae0cdabc05dc2755b48cf327bef0 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -88,18 +88,6 @@ public class Server registry.rebind(clientControllerName, clientController); registry.rebind(chatControllerName, chatController); registry.rebind(drawingControllerName, drawingController); -// registry.rebind(clientControllerName, UnicastRemoteObject.exportObject(clientController, 1099)); -// registry.rebind(chatControllerName, UnicastRemoteObject.exportObject(chatController, 1099)); -// registry.rebind(drawingControllerName, UnicastRemoteObject.exportObject(drawingController, 1099)); - -// try { -// Naming.rebind(clientControllerName, clientController); -// Naming.rebind(chatControllerName, chatController); -// Naming.rebind(drawingControllerName, drawingController); -// } catch (MalformedURLException e) { -// e.printStackTrace(); -// } - System.out.println("Server is ready"); diff --git a/src/server/User.java b/src/server/User.java index 543f26e6c9056a69b382ae8dc4819d4116e95559..c3166674cf9d3cc67d04b547213a5377242088b0 100644 --- a/src/server/User.java +++ b/src/server/User.java @@ -4,6 +4,8 @@ import remote.IChatUpdate; import remote.IClientUpdate; import remote.IDrawingUpdate; +import javax.crypto.SecretKey; + public class User { private String username; @@ -12,12 +14,19 @@ public class User private IClientUpdate IClientUpdate; private boolean isAdmin; - public User(String username, IChatUpdate IChatUpdate, IClientUpdate IClientUpdate, IDrawingUpdate IDrawingUpdate) + public SecretKey getSharedSecretKey() { + return sharedSecretKey; + } + + private SecretKey sharedSecretKey; + + public User(String username, IChatUpdate IChatUpdate, IClientUpdate IClientUpdate, IDrawingUpdate IDrawingUpdate, SecretKey sharedSecretKey) { this.username = username; this.IChatUpdate = IChatUpdate; this.IDrawingUpdate = IDrawingUpdate; this.IClientUpdate = IClientUpdate; + this.sharedSecretKey = sharedSecretKey; this.isAdmin = false; }