diff --git a/src/GUI/PaintGUI.java b/src/GUI/PaintGUI.java index 0286c632abeecc16cdcc007106ace87f3d961a06..974a5790579193e4cde68cf0dcd4828f4eefb32f 100644 --- a/src/GUI/PaintGUI.java +++ b/src/GUI/PaintGUI.java @@ -27,8 +27,7 @@ public class PaintGUI extends JPanel { JButton clearBtn, newBtn, openBtn, saveBtn, saveAsBtn; JButton freehandBtn, lineBtn, circleBtn, rectBtn, ovalBtn, eraserBtn, textBtn; JButton colorPaletteBtn, setFontBtn; - JTextField textInput; - JTextField textSize; + JTextField textInput, textSize; JComboBox strokeOptions; JComboBox eraserSizeOptions; @@ -133,12 +132,12 @@ public class PaintGUI extends JPanel { toolbox1.add(circleBtn); toolbox1.add(rectBtn); toolbox1.add(ovalBtn); - toolbox1.add(eraserBtn); - toolbox1.add(textBtn); + toolbox1.add(strokeOptions); + toolbox2.add(textBtn); toolbox2.add(textInput); // toolbox2.add(setFontBtn); toolbox2.add(textSize); - toolbox2.add(strokeOptions); + toolbox2.add(eraserBtn); toolbox2.add(eraserSizeOptions); toolbox2.add(clearBtn); @@ -383,17 +382,4 @@ public class PaintGUI extends JPanel { drawingArea.setModeText(textString, size); } - -// public void showGUI() { -// frame = new JFrame("Shared Whiteboard System"); -// JFrame.setDefaultLookAndFeelDecorated(true); -// frame.setContentPane(global); -// -// frame.setSize(800, 600); -// frame.setLocationRelativeTo( null ); -// frame.setResizable(false); -// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); -// frame.setVisible(true); -// } - } \ No newline at end of file diff --git a/src/GUI/StartScreen.form b/src/GUI/StartScreen.form index a6eacb755c0f906ce615768a12eb2fb64b8fbcb2..f348817e1243275dfd3dd145b7bc1983957c0624 100644 --- a/src/GUI/StartScreen.form +++ b/src/GUI/StartScreen.form @@ -40,7 +40,7 @@ </constraints> <properties> <editable value="false"/> - <text value="Welcome to Distributed Whiteboard. Please provide server's IP, username, and password."/> + <text value="Please provide your username and password, as well as server's IP to start."/> </properties> </component> </children> @@ -74,17 +74,22 @@ </properties> <border type="none" title=" "/> <children> + <vspacer id="bb71b"> + <constraints> + <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> + </constraints> + </vspacer> <component id="94078" class="javax.swing.JLabel"> <constraints> - <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Server IP:"/> </properties> </component> - <component id="63209" class="javax.swing.JTextField" binding="textField2"> + <component id="63209" class="javax.swing.JTextField" binding="serverField"> <constraints> - <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> <preferred-size width="150" height="-1"/> </grid> </constraints> @@ -92,43 +97,38 @@ <text value=""/> </properties> </component> - <vspacer id="bb71b"> - <constraints> - <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> - </constraints> - </vspacer> <component id="87b91" class="javax.swing.JLabel"> <constraints> - <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> - <text value="Your name:"/> + <text value="Username:"/> </properties> </component> - <component id="e39f4" class="javax.swing.JTextField" binding="textField1" default-binding="true"> + <component id="e39f4" class="javax.swing.JTextField" binding="usernameField"> <constraints> - <grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> <preferred-size width="150" height="-1"/> </grid> </constraints> <properties/> </component> - <component id="51d9f" class="javax.swing.JPasswordField" binding="passwordField"> + <component id="62e48" class="javax.swing.JLabel"> <constraints> - <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="-1"/> - </grid> + <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> - <columns value="20"/> + <text value="Password:"/> </properties> </component> - <component id="62e48" class="javax.swing.JLabel"> + <component id="51d9f" class="javax.swing.JPasswordField" binding="passwordField"> <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <preferred-size width="150" height="-1"/> + </grid> </constraints> <properties> - <text value="Password:"/> + <columns value="20"/> </properties> </component> </children> diff --git a/src/GUI/StartScreen.java b/src/GUI/StartScreen.java index 70ac2f2e3dc766e42e22451279d9ea89a42fa30b..9494617b0d6e970803ae72aacffab652c01ed50d 100644 --- a/src/GUI/StartScreen.java +++ b/src/GUI/StartScreen.java @@ -2,17 +2,21 @@ package GUI; import client.Client; +import javax.imageio.ImageIO; import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; public class StartScreen { private JTextPane information; private JPanel panel1; - private JTextField textField1; + private JTextField usernameField; private JButton joinButton; - private JTextField textField2; + private JTextField serverField; private JTextField textField3; private JPasswordField passwordField; JFrame frame; @@ -35,8 +39,8 @@ public class StartScreen { { if (e.getSource() == joinButton) { - String serverAddress = textField2.getText(); - String userName = textField1.getText(); + String serverAddress = serverField.getText(); + String userName = usernameField.getText(); String password = new String(passwordField.getPassword()); int connectionStatus = client.connect(userName, serverAddress, password); @@ -49,7 +53,7 @@ public class StartScreen { } else if( connectionStatus == 2 ) { - showErrorMessage("Duplicate username: Please enter a new username"); + showErrorMessage("Duplicate usernameField: Please enter a new usernameField"); } else if( connectionStatus == 3 ) { @@ -84,6 +88,29 @@ public class StartScreen { frame.setLocationRelativeTo(null); frame.getRootPane().setDefaultButton(joinButton); joinButton.requestFocus(); + + //frame.getContentPane().add(new JPanelWithBackground("sample.jpeg")); frame.setVisible(true); } + +// public class JPanelWithBackground extends JPanel +// { +// +// private Image backgroundImage; +// +// // Some code to initialize the background image. +// // Here, we use the constructor to load the image. This +// // can vary depending on the use case of the panel. +// public JPanelWithBackground(String fileName) throws IOException +// { +// backgroundImage = ImageIO.read(new File(fileName)); +// } +// +// public void paintComponent(Graphics g) { +// super.paintComponent(g); +// +// // Draw the background image. +// g.drawImage(backgroundImage, 0, 0, this); +// } +// } } diff --git a/src/client/Client.java b/src/client/Client.java index f5e735fd847a4910f00fea4e19b9f36a7b0653ef..0dca4c8453899959403a33b5051f2fb714e2209d 100644 --- a/src/client/Client.java +++ b/src/client/Client.java @@ -11,11 +11,14 @@ import remote.IDrawingController; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; public class Client { private final String DEFAULT_USERNAME = "Anonymous"; private final String DEFAULT_SERVER_ADDRESS = "localhost"; + private final EncryptionUpdate encryptionUpdate; private String userName; private String serverAddress; @@ -73,7 +76,7 @@ public class Client public IDrawingController getDrawingController() { return drawingController; } - public Client(String username) throws RemoteException + public Client(String username) throws RemoteException, NoSuchProviderException, NoSuchAlgorithmException { this.userName = username; this.clientUpdate = new ClientUpdate(this); @@ -81,6 +84,7 @@ public class Client this.drawingUpdate = new DrawingUpdate(this); this.startScreen = new StartScreen(this); this.applicationMain = new ApplicationMain(this); + this.encryptionUpdate = new EncryptionUpdate(); } public static void main(String[] args) @@ -145,7 +149,7 @@ public class Client if( clientController.checkPassword(password) ) { - if( clientController.join(userName, this.chatUpdate, this.clientUpdate, this.drawingUpdate) ) + if( clientController.join(userName, this.chatUpdate, this.clientUpdate, this.drawingUpdate, this.encryptionUpdate) ) { System.out.println("Connected to server"); diff --git a/src/client/EncryptionUpdate.java b/src/client/EncryptionUpdate.java new file mode 100644 index 0000000000000000000000000000000000000000..001c1295c64d042cba748e108675cbe14f3a4503 --- /dev/null +++ b/src/client/EncryptionUpdate.java @@ -0,0 +1,58 @@ +package client; + +import remote.IDrawingUpdate; +import remote.IEncryptionUpdate; + +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.io.Serializable; +import java.rmi.RemoteException; +import java.rmi.server.UnicastRemoteObject; +import java.security.*; + +public class EncryptionUpdate extends UnicastRemoteObject implements IEncryptionUpdate, Serializable { + + private PrivateKey priv; + private PublicKey pub; + private SecretKey sharedSecretKey; + + public PublicKey getPub() { + return pub; + } + + public void setSharedKey(byte[] encryptedSharedSecretKey){ + try { + Cipher cipher = Cipher.getInstance("RSA", "SunJCE"); + 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) { + e.printStackTrace(); + } catch (NoSuchPaddingException | InvalidKeyException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } + + + } + + EncryptionUpdate() throws RemoteException { + try { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "SunJSSE"); + keyGen.initialize(2048); + KeyPair pair = keyGen.generateKeyPair(); + this.priv = pair.getPrivate(); + this.pub = pair.getPublic(); + + } + catch (Exception e){ + e.printStackTrace(); + } + + } +} diff --git a/src/remote/IClientController.java b/src/remote/IClientController.java index 1dcd165573a381d245924c9966d8a13367439a3f..07f812571e834b2bdf8c87499121d01095064dca 100644 --- a/src/remote/IClientController.java +++ b/src/remote/IClientController.java @@ -7,7 +7,7 @@ public interface IClientController extends Remote { enum Action {KICKOUT, ASSIGNADMIN}; - boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException; + boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing, IEncryptionUpdate encryptionUpdate) throws RemoteException; void quit(String username) throws RemoteException; diff --git a/src/remote/IEncryptionUpdate.java b/src/remote/IEncryptionUpdate.java new file mode 100644 index 0000000000000000000000000000000000000000..3e8edf3e781713db3d351e740c5a692aab733925 --- /dev/null +++ b/src/remote/IEncryptionUpdate.java @@ -0,0 +1,10 @@ +package remote; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.security.PublicKey; + +public interface IEncryptionUpdate extends Remote { + public PublicKey getPub() throws RemoteException; + public void setSharedKey(byte[] encryptedSharedSecretKey) throws RemoteException; +} diff --git a/src/server/ClientController.java b/src/server/ClientController.java index 4c710bbc9d0fa508751c3db651f717aed06798f4..2d40ff1c1bd9ee703f860887713428c4c34619ac 100644 --- a/src/server/ClientController.java +++ b/src/server/ClientController.java @@ -1,9 +1,6 @@ package server; -import remote.IChatUpdate; -import remote.IClientUpdate; -import remote.IDrawingUpdate; -import remote.IClientController; +import remote.*; import java.io.Serializable; import java.rmi.Remote; @@ -20,13 +17,15 @@ public class ClientController extends UnicastRemoteObject implements IClientCont } @Override - public boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException + public boolean join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing, IEncryptionUpdate encryptionUpdate) throws RemoteException { if( getUserIndex(username) < 0 ) { // user with same username is not connected server.chatController.broadcastMessageUserLogin(username); + new MySharedKey(encryptionUpdate); + User newUser = new User(username, clientChat, clientUpdate, clientDrawing); server.users.add(newUser); diff --git a/src/server/MySharedKey.java b/src/server/MySharedKey.java new file mode 100644 index 0000000000000000000000000000000000000000..e16485e2e87a5ff48c8ea4bd2bfe05757dc7802f --- /dev/null +++ b/src/server/MySharedKey.java @@ -0,0 +1,41 @@ +package server; + +import remote.IEncryptionUpdate; + +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.rmi.RemoteException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.util.Base64; + +public class MySharedKey { + private byte[] encryptedSharedSecretKey; + private IEncryptionUpdate encryptionUpdate; + private SecretKey sharedSecretKey; + + + public MySharedKey (IEncryptionUpdate encryptionUpdate) throws RemoteException { + this.encryptionUpdate = encryptionUpdate; + 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); + encryptionUpdate.setSharedKey(encryptedSharedSecretKey); + } + + private byte[] wrapKey(PublicKey clientPubKey){ + + try { + Cipher c = Cipher.getInstance("RSA", "SunJCE"); + c.init(Cipher.WRAP_MODE, clientPubKey); + byte[] result2 = c.wrap(sharedSecretKey); + return result2; + } catch (Exception e) { + e.printStackTrace(); + throw new IllegalStateException( + e); + } + } +} diff --git a/src/server/Server.java b/src/server/Server.java index 0160269bb14d69676c82e568f5521ab9d84ae94d..cb1ef67e4d58a8f673777b4324c0fc783792b1ec 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -4,6 +4,8 @@ import remote.IChatController; import remote.IClientController; import remote.IDrawingController; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; @@ -54,7 +56,6 @@ public class Server public void run() throws RemoteException { - LocateRegistry.createRegistry(1099); Registry registry = LocateRegistry.getRegistry(); @@ -71,5 +72,24 @@ public class Server registry.rebind(drawingControllerName, drawingController); System.out.println("Server is ready"); + + printIP(); + } + + private void printIP() + { + InetAddress inetAddress = null; + + try + { + inetAddress = InetAddress.getLocalHost(); + } + catch (UnknownHostException e) + { + e.printStackTrace(); + } + + System.out.println("IP Address:- " + inetAddress.getHostAddress()); + System.out.println("Host Name:- " + inetAddress.getHostName()); } }