From 1863055fbb8ab26c5de48a0735aaa2c84fb9baf5 Mon Sep 17 00:00:00 2001 From: "Eugene San (eugenesan)" Date: Thu, 14 Nov 2013 09:09:17 +0200 Subject: [PATCH 1/2] code cleanups and cosmetic changes --- JAuth/AuthenticatorGUI.java | 315 +++++++++++++----------------------- JAuth/Base32String.java | 12 +- 2 files changed, 118 insertions(+), 209 deletions(-) diff --git a/JAuth/AuthenticatorGUI.java b/JAuth/AuthenticatorGUI.java index 9efc6ba..8713f5e 100644 --- a/JAuth/AuthenticatorGUI.java +++ b/JAuth/AuthenticatorGUI.java @@ -19,12 +19,7 @@ import java.lang.reflect.*; -//import com.install4j.api.launcher.Variables; - -//import com.apple.eawt.*; - public final class AuthenticatorGUI extends JPanel implements ActionListener, MouseListener, MouseMotionListener { - public JLabel codeField = new JLabel("--- ---"); public JLabel copyLabel = new JLabel(" Copy"); public JLabel nextLabel = new JLabel(" next"); @@ -59,7 +54,7 @@ public AuthenticatorGUI(Image image,Font font) { componentInit(); } - + public AuthenticatorGUI(String secret,Image image, Font font) { this(image,font); @@ -69,13 +64,13 @@ public AuthenticatorGUI(String secret,Image image, Font font) { public void setSecret(String secret) { try { this.secret = secret; - + // Do the magic with the secret key final byte[] keybytes = Base32String.decode(secret); - + mac = Mac.getInstance("HMACSHA1"); mac.init(new SecretKeySpec(keybytes,"")); - + pcg = new PasscodeGenerator(mac); } catch (Exception e) { @@ -84,19 +79,16 @@ public void setSecret(String secret) { } private void componentInit() { - FormLayout layout = new FormLayout("17px,fill:pref:grow,1dlu,40px,10px", // Cols - "10px,2px,14px,14px,2px,5px,17px"); // Rows - + "10px,2px,14px,14px,2px,5px,17px"); // Rows + setLayout(layout); setBackground(Color.white); CellConstraints cc = new CellConstraints(); try { - // Load the LCD font - Font font32 = this.font.deriveFont(32f); Font font16 = this.font.deriveFont(16f); Font font20 = this.font.deriveFont(20f); @@ -111,9 +103,6 @@ private void componentInit() { Color c = new Color(150,150,150); closeLabel.setForeground(c); - //closeLabel.setBorder(BorderFactory.createLineBorder(Color.red)); - - } catch (Exception e) { e.printStackTrace(); } @@ -126,9 +115,10 @@ private void componentInit() { closeLabel.setPreferredSize(new Dimension(10,10)); closeLabel.addMouseListener(this); + // Show textfield with number - add(codeField, cc.xywh(2,3,1,2)); // 2nd col 3rd row - + add(codeField, cc.xywh(2,3,1,2)); // 2nd col 3rd row + // Show copy button add(copyLabel, cc.xy(4,3)); // 4th col 3rd row @@ -137,9 +127,8 @@ private void componentInit() { // Show timer countdown add(progressLabel, cc.xywh(2,6,3,1)); // 2nd col 6th row spans 3 cols - add(closeLabel, cc.xy(5,1)); // - - // Start the counter thread - fires an event every two seconds + add(closeLabel, cc.xy(5,1)); // Start the counter thread - + // fires an event every two seconds Counter cd = new Counter(); cd.addActionListener(this); @@ -149,10 +138,8 @@ private void componentInit() { public void paintComponent(Graphics g) { Image tmpimage = image.getScaledInstance(this.getSize().width,this.getSize().height, Image.SCALE_DEFAULT); g.drawImage(tmpimage, 0, 0, null); - } - public void mouseEntered(MouseEvent evt) { } public void mouseExited (MouseEvent evt) { } public void mouseClicked(MouseEvent evt) { @@ -160,10 +147,10 @@ public void mouseClicked(MouseEvent evt) { System.exit(0); } } + public void mouseDragged(MouseEvent evt) { } - public void mousePressed(MouseEvent evt) { + public void mousePressed(MouseEvent evt) { // Copies the code to the clipboard when the copy label is clicked - if (evt.getSource() == copyLabel) { String tmp = codeField.getText(); @@ -181,24 +168,21 @@ public void mousePressed(MouseEvent evt) { this.shownextcode = !this.shownextcode; if (this.shownextcode) { - nextLabel.setForeground(this.darkred); + nextLabel.setForeground(this.darkred); } else { - nextLabel.setForeground(Color.black); + nextLabel.setForeground(Color.black); } this.currcode = null; - } + } - } public void mouseMoved (MouseEvent evt) { } - public void mouseReleased(MouseEvent evt) { - + public void mouseReleased(MouseEvent evt) { try { - if (evt.getSource() == copyLabel) { - Thread.currentThread().sleep(1000); - - copyLabel.setForeground(Color.black); + Thread.currentThread().sleep(1000); + + copyLabel.setForeground(Color.black); } } catch (InterruptedException ie){ System.out.println("Thread interrupted"); @@ -208,61 +192,52 @@ public void mouseReleased(MouseEvent evt) { public String getNewCode() { try { if (this.shownextcode) { - return pcg.generateNextTimeoutCode(); + return pcg.generateNextTimeoutCode(); } else { - return pcg.generateTimeoutCode(); + return pcg.generateTimeoutCode(); } } catch (java.security.GeneralSecurityException ex) { } return ""; } - + public String getCurrentCode() { return this.currcode; } - + public void actionPerformed(ActionEvent e){ - if (e.getSource() instanceof Counter) { try { - String currcode = this.getCurrentCode(); - String newcode = this.getNewCode(); - String tmp = newcode; - - if (this.shownextcode) { - - codeField.setForeground(this.darkred); - nextLabel.setForeground(this.darkred); - } else { - - codeField.setForeground(Color.black); - nextLabel.setForeground(Color.black); - - } - - - String newcodestr = tmp.substring(0,3) + " " + tmp.substring(3,6); - - int remain = (int)(System.currentTimeMillis()%30000/2000); - - if (currcode == null || !newcode.equals(currcode)){ - - codeField.setText(newcodestr); - this.currcode = newcode; - //new Application().setDockIconBadge(tmp); - int i = 0; - String s = ""; - while (i <= 15-remain) { - s += "-"; - i++; - } - progressLabel.setText(s); - - - } + String currcode = this.getCurrentCode(); + String newcode = this.getNewCode(); + String tmp = newcode; + + if (this.shownextcode) { + codeField.setForeground(this.darkred); + nextLabel.setForeground(this.darkred); + } else { + codeField.setForeground(Color.black); + nextLabel.setForeground(Color.black); + } + + String newcodestr = tmp.substring(0,3) + " " + tmp.substring(3,6); + + int remain = (int)(System.currentTimeMillis()%30000/2000); + + if (currcode == null || !newcode.equals(currcode)){ + codeField.setText(newcodestr); + this.currcode = newcode; + int i = 0; + String s = ""; + while (i <= 15-remain) { + s += "-"; + i++; + } + progressLabel.setText(s); + } } catch (Exception ex) { - ex.printStackTrace(); + ex.printStackTrace(); } String val = progressLabel.getText(); @@ -270,14 +245,14 @@ public void actionPerformed(ActionEvent e){ len--; if (len < 0) { - len = 15; + len = 15; }; String s = ""; int i = 0; while (i < len) { - s += "-"; - i++; + s += "-"; + i++; } progressLabel.setText(s); } @@ -287,91 +262,74 @@ public static String getSecret(String[] args,Icon icon) { try { // Gets the secret from a number of places. - String homedir = System.getProperty("user.home"); - + // Command line first - if (args.length > 0 && args[0].indexOf("-secret=") == 0) { - return args[0].substring(8); + return args[0].substring(8); } - + if (args.length > 0) { - String secretfile = args[0]; - - byte[] buffer = new byte[(int) new File(secretfile).length()]; - BufferedInputStream f = new BufferedInputStream(new FileInputStream(secretfile)); + String secretfile = args[0]; - f.read(buffer); - return new String(buffer); + byte[] buffer = new byte[(int) new File(secretfile).length()]; + BufferedInputStream f = new BufferedInputStream(new FileInputStream(secretfile)); + + f.read(buffer); + return new String(buffer); } - - // Jar file next - + // Read the .JAuth.rc file if (new File(homedir + File.separator + ".JAuth.rc").exists()) { - String secretfile = homedir + File.separator + ".JAuth.rc"; - - FileInputStream fstream = new FileInputStream(secretfile); - DataInputStream in = new DataInputStream(fstream); - BufferedReader br = new BufferedReader(new InputStreamReader(in)); - String strLine; - - while ((strLine = br.readLine()) != null) { - if (strLine.indexOf("secret=") == 0) { - return strLine.substring(7); - } - } - in.close(); + String secretfile = homedir + File.separator + ".JAuth.rc"; + + FileInputStream fstream = new FileInputStream(secretfile); + DataInputStream in = new DataInputStream(fstream); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + String strLine; + + while ((strLine = br.readLine()) != null) { + if (strLine.indexOf("secret=") == 0) { + return strLine.substring(7); + } + } + in.close(); } - + if (new File(homedir + File.separator + ".google_authenticator").exists()) { - - String secretfile = homedir + File.separator + ".google_authenticator"; - - byte[] buffer = new byte[(int) new File(secretfile).length()]; - BufferedInputStream f = new BufferedInputStream(new FileInputStream(secretfile)); - - f.read(buffer); - return new String(buffer); - - } - - - //JOptionPane.showMessageDialog(null, "Installer secret is " + secret); - - String secret = (String)JOptionPane.showInputDialog( - null, - "Enter secret key: ", - "Enter secret key", - JOptionPane.PLAIN_MESSAGE, - null, - null, - ""); - + String secretfile = homedir + File.separator + ".google_authenticator"; + + byte[] buffer = new byte[(int) new File(secretfile).length()]; + BufferedInputStream f = new BufferedInputStream(new FileInputStream(secretfile)); + + f.read(buffer); + return new String(buffer); + } + + String secret = (String)JOptionPane.showInputDialog(null, "Enter secret key: ", "Enter secret key", JOptionPane.PLAIN_MESSAGE, + null, null, ""); + String secretfile = homedir + File.separator + ".JAuth.rc"; try { - BufferedWriter f = new BufferedWriter(new FileWriter(new File(secretfile))); - f.write("secret="+secret); - f.newLine(); - f.close(); - return secret; + BufferedWriter f = new BufferedWriter(new FileWriter(new File(secretfile))); + f.write("secret="+secret); + f.newLine(); + f.close(); + return secret; } catch (IOException e) { - JOptionPane.showMessageDialog(null, "Error writing secret string to [" + secretfile + "]", "JAuth Error", JOptionPane.ERROR_MESSAGE); - e.printStackTrace(); - System.exit(0); + JOptionPane.showMessageDialog(null, "Error writing secret string to [" + secretfile + "]", "JAuth Error", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + System.exit(0); } - } catch (Exception e) { - JOptionPane.showMessageDialog(null, "Error reading secret string."); e.printStackTrace(); System.exit(0); - } return ""; } + public static void main(String[] args) { String secret = ""; String secretfile = ""; @@ -385,16 +343,12 @@ public static void main(String[] args) { InputStream imagestream = AuthenticatorGUI.class.getResourceAsStream("logo/lcd3.png"); InputStream iconstream = AuthenticatorGUI.class.getResourceAsStream("logo/logo48.png"); - //secret = (String)Variables.getInstallerVariable("secret"); - font = Font.createFont( Font.TRUETYPE_FONT,fontStream ); image = ImageIO.read(imagestream); icon = ImageIO.read(iconstream); secret = AuthenticatorGUI.getSecret(args,new ImageIcon(icon)); - //JOptionPane.showMessageDialog(null, "Secret is " + secret); - } catch (Exception e) { JOptionPane.showMessageDialog(null, "Error reading secret string. This should be contained in [" + secretfile + "]", "JAuth Error", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); @@ -402,62 +356,30 @@ public static void main(String[] args) { } try { - - /* - if (Class.forName("com.apple.eawt.Application",false,null)!= null) { - com.apple.eawt.Application app = com.apple.eawt.Application.getApplication(); - app.setDockIconImage(icon); - app.setAboutHandler(new JAuthAboutHandler(icon)); - }*/ Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); AuthenticatorGUI gui = new AuthenticatorGUI(secret,image,font); AuthenticatorFrame jf = new AuthenticatorFrame(); - - gui.addMouseMotionListener(jf); gui.addMouseListener(jf); - //new Application().setDockIconImage(image); jf.setIconImage(icon); jf.setUndecorated(true); jf.add(gui); jf.setDefaultCloseOperation(2); jf.pack(); - + jf.setSize(175,60); jf.setLocation(dim.width - jf.getSize().width -50,30); - - + jf.setVisible(true); } catch (Exception e) { JOptionPane.showMessageDialog(null, "Error creating GUI","JAuth Error", JOptionPane.ERROR_MESSAGE); System.exit(0); } } - } -/* -class JAuthAboutHandler implements com.apple.eawt.AboutHandler { - Image icon; - ImageIcon imageicon; - - public JAuthAboutHandler(Image icon) { - this.icon = icon; - this.imageicon = new ImageIcon(this.icon); - } - - public void handleAbout(com.apple.eawt.AppEvent.AboutEvent e) { - String version = AuthenticatorGUI.class.getPackage().getImplementationVersion(); - String title = AuthenticatorGUI.class.getPackage().getImplementationTitle(); - String aboutGreeting = "JAuth OpenAuth desktop client version "+version; - JOptionPane.showMessageDialog(null,aboutGreeting,"JAuth",JOptionPane.INFORMATION_MESSAGE,imageicon); - } - - -} -*/ class Counter extends Thread { public ActionListener l; public int time = 0; @@ -465,16 +387,16 @@ class Counter extends Thread { public void addActionListener(ActionListener l) { this.l = l; } - + public void run() { while (true) { try { - Thread.sleep(2000); - time+= 2000; + Thread.sleep(2000); + time+= 2000; - l.actionPerformed(new ActionEvent((Object)this,time,String.valueOf(time))); + l.actionPerformed(new ActionEvent((Object)this,time,String.valueOf(time))); } catch (InterruptedException e) { - e.printStackTrace(); + e.printStackTrace(); } } } @@ -486,55 +408,42 @@ class AuthenticatorFrame extends JFrame implements MouseListener, MouseMotionLis int x1; int y1; - + int x2; int y2; public void mouseDragged(MouseEvent evt) { this.positionx = evt.getXOnScreen(); this.positiony = evt.getYOnScreen(); - - if (this.positionx > this.x1){ + if (this.positionx > this.x1) { this.x2 = this.positionx - this.x1; this.setLocation(this.getX() + this.x2, this.getY()); - } else if(this.positionx < this.x1){ - this.x2 = this.x1 - this.positionx; this.setLocation(this.getX() - this.x2, this.getY()); - } if (this.positiony > this.y1) { - this.y2 = this.positiony - this.y1; this.setLocation(this.getX(), this.getY() + this.y2); - } else if(this.positiony < this.y1) { - this.y2 = this.y1 - this.positiony; this.setLocation(this.getX(), this.getY() - this.y2); - } this.x1 = this.positionx; this.y1 = this.positiony; - } - public void mousePressed(MouseEvent evt) { + + public void mousePressed(MouseEvent evt) { this.x1 = evt.getXOnScreen(); this.y1 = evt.getYOnScreen(); } public void mouseEntered(MouseEvent evt) { } public void mouseExited (MouseEvent evt) { } - public void mouseClicked(MouseEvent evt) { - } + public void mouseClicked(MouseEvent evt) { } public void mouseReleased(MouseEvent evt) { } public void mouseMoved(MouseEvent evt) { } - } - - - diff --git a/JAuth/Base32String.java b/JAuth/Base32String.java index ad05fac..ada2178 100644 --- a/JAuth/Base32String.java +++ b/JAuth/Base32String.java @@ -4,20 +4,20 @@ /** * Encodes arbitrary byte arrays as case-insensitive base-32 strings - * + * * @author sweis@google.com (Steve Weis) * @author Neal Gafter */ public class Base32String { // singleton - + private static final Base32String INSTANCE = new Base32String("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"); // RFC 4668/3548 static Base32String getInstance() { return INSTANCE; } - + //32 alpha-numeric characters. Excluding 0, 1, O, and I private String ALPHABET; private char[] DIGITS; @@ -68,8 +68,8 @@ protected byte[] decodeInternal(String encoded) throws DecodingException { bitsLeft -= 8; } } - // We'll ignore leftover bits for now. - // + // We'll ignore leftover bits for now. + // // if (next != outLength || bitsLeft >= SHIFT) { // throw new DecodingException("Bits left: " + bitsLeft); // } @@ -116,7 +116,7 @@ protected String encodeInternal(byte[] data) { } return result.toString(); } - + @Override // enforce that this class is a singleton public Object clone() throws CloneNotSupportedException { From 9999a126c94692900839d7e56d52780206b9d28b Mon Sep 17 00:00:00 2001 From: "Eugene San (eugenesan)" Date: Thu, 14 Nov 2013 09:05:34 +0200 Subject: [PATCH 2/2] add cli version - new CLI class taken from http://www.jcuff.net/files/Authenticator.tgz - tweak readme - rename makejar to makejars and add CLI build --- JAuth/AuthenticatorCLI.java | 84 +++++++++++++++++++++++++++++++++++++ README | 50 +++++++++++----------- makejar | 17 -------- makejars | 27 ++++++++++++ 4 files changed, 137 insertions(+), 41 deletions(-) create mode 100644 JAuth/AuthenticatorCLI.java delete mode 100755 makejar create mode 100755 makejars diff --git a/JAuth/AuthenticatorCLI.java b/JAuth/AuthenticatorCLI.java new file mode 100644 index 0000000..99d92e8 --- /dev/null +++ b/JAuth/AuthenticatorCLI.java @@ -0,0 +1,84 @@ +package JAuth; + +import java.security.GeneralSecurityException; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.util.Timer; +import java.util.TimerTask; +import java.io.*; + +public class AuthenticatorCLI { + Timer timer; + + public static void main(String[] args) { + System.out.println("\nAuthenticator Started!"); + System.out.println(":----------------------------:--------:"); + System.out.println(": Code Wait Time : Code :"); + System.out.println(":----------------------------:--------:"); + AuthenticatorCLI main = new AuthenticatorCLI(); + String inFile=args[0]; + + try { + RandomAccessFile raf= new RandomAccessFile(inFile,"r"); + FileReader fileReader = new FileReader(raf.getFD()); + BufferedReader bufReader = new LineNumberReader(fileReader,65536); + main.reminder(bufReader.readLine()); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + public void reminder(String secret) { + timer = new Timer(); + timer.scheduleAtFixedRate(new TimedPin(secret), 0, 1 * 1000); + } + + int count=1; + + class TimedPin extends TimerTask { + private String secret; + + public TimedPin (String secret){ + this.secret=secret; + } + + String previouscode = ""; + + public void run() { + String newout = AuthenticatorCLI.computePin(secret,null); + if(previouscode.equals(newout)) { + System.out.print("."); + } else { + if(count<=30) { + for (int i=count+1; i<=30;i++) { + System.out.print("+"); + } + } + + System.out.println(": "+ newout + " :"); + count=0; + } + previouscode = newout; + count++; + } + } + + public static String computePin(String secret, Long counter) { + if (secret == null || secret.length() == 0) { + return "Null or empty secret"; + } + + try { + final byte[] keyBytes = Base32String.decode(secret); + Mac mac = Mac.getInstance("HMACSHA1"); + mac.init(new SecretKeySpec(keyBytes, "")); + PasscodeGenerator pcg = new PasscodeGenerator(mac); + return pcg.generateTimeoutCode(); + } catch (GeneralSecurityException e) { + return "General security exception"; + } catch (Base32String.DecodingException e) { + return "Decoding exception"; + } + } +} diff --git a/README b/README index c177cc9..2caf055 100644 --- a/README +++ b/README @@ -1,14 +1,16 @@ Authors : James Cuff and Michele Clamp 2011/2012 -------------------------------------------- +----------------------------------------------- Description ------------ -JAuth is a reference desktop client for the google authenticator. Intended -as an alternative to the iPhone Google Authenticator app and similar. -http://code.google.com/p/google-authenticator/ +JAuth is a reference desktop and command line client for the google authenticator. +Intended as an alternative to the iPhone/Android Google Authenticator app and similar. +Refer to http://code.google.com/p/google-authenticator for more information. -Explanatory bloggage at http://blog.jcuff.net/2011/09/beautiful-two-factor-desktop-client.html +Explanatory bloggage at: + http://blog.jcuff.net/2011/09/beautiful-two-factor-desktop-client.html + http://blog.jcuff.net/2011/02/cli-java-based-google-authenticator.html Installation using GUI Installer -------------------------------- @@ -22,34 +24,35 @@ All installers available from https://github.com/mclamp/JAuth/tree/master/Instal Installation ------------ -To compile and run in bash - - ./makejar - -then to run - - java -jar JAuth.jar +To compile and run in shell: + $ ./makejars +To run: + $ java -jar JAuth.jar or - - java -jar JAuth.jar + $ java -jar JAuth.jar By default it looks in the home directory for a file called .google_authenticator -Alternatively : +Alternatively: + $ java -jar JAuth.jar -secret=MY_SECRET_KEY - java -jar JAuth.jar -secret=MY_SECRET_KEY +For command line version, replace JAuth.jar with JAuthCLI.jar +Output should something as following: +Authenticator Started! +:----------------------------:--------: +: Code Wait Time : Code : +:----------------------------:--------: ++++++++++++++++++++++++++++++: 000000 : Webstart -------- -Initialize your keystore (do this only once) +Initialize your keystore (do this only once): + $ keytool -genkey -alias JAuth -keyalg RSA -keystore keystore.jks -keysize 2048 - keytool -genkey -alias JAuth -keyalg RSA -keystore keystore.jks -keysize 2048 - -Sign your jar - - jarsigner -keystore keystore.jks JAuth.jar JAuth +Sign your GUI jar: + $ jarsigner -keystore keystore.jks JAuth.jar JAuth Edit the JAuth.jnlp file to reflect your local webserver path. Copy the JAuth.jnlp and JAuth.jar files into the webserver path. @@ -57,6 +60,7 @@ Copy the JAuth.jnlp and JAuth.jar files into the webserver path. Acknowledgements ---------------- +Thanks to JGoodies for forms library (http://www.jgoodies.com/downloads/libraries) Thanks to bookest (Christopher Grim) for the secret key dialog code Installer Software Install4j from ej-technologies @@ -70,7 +74,6 @@ PasscodeGenerator and Base32String code from -------------------------------------------- sweis@google.com - LCD Font from ------------- Digital-7: 1.00 Oct 03 13:24:00 2008 @@ -88,4 +91,3 @@ modified from http://www.e-lab.de/diverse/LCD2x16.jpg Layout code from jgoodies.com ----------------------------- JGoodies Karsten Lentzsch - diff --git a/makejar b/makejar deleted file mode 100755 index efe1900..0000000 --- a/makejar +++ /dev/null @@ -1,17 +0,0 @@ -. setpath - -javac JAuth/AuthenticatorGUI.java - -jar xf jars/forms-1.1.0.jar - -echo "Main-Class: JAuth.AuthenticatorGUI" > manifest -echo "Name: JAuth" >> manifest -echo "Implementation-Title: JAuth" >> manifest -echo "Implementation-Version: 1.0" >> manifest -echo "Specification-Title: JAuth" >> manifest -echo "Specification-Version: 1.0" >> manifest -echo "Created-By: Michele Clamp, James Cuff, John Brunelle" >> manifest - -jar cmf manifest JAuth.jar JAuth/*.class JAuth/fonts/*.ttf JAuth/logo/*.png JAuth/logo/*.icns com - - diff --git a/makejars b/makejars new file mode 100755 index 0000000..f2efd81 --- /dev/null +++ b/makejars @@ -0,0 +1,27 @@ +#!/bin/sh + +. setpath + +echo "Making GUI" +javac JAuth/AuthenticatorGUI.java +echo "Main-Class: JAuth.AuthenticatorGUI" > JAuth/manifest +echo "Name: JAuth" >> JAuth/manifest +echo "Implementation-Title: JAuth" >> JAuth/manifest +echo "Implementation-Version: 1.0" >> JAuth/manifest +echo "Specification-Title: JAuth" >> JAuth/manifest +echo "Specification-Version: 1.0" >> JAuth/manifest +echo "Created-By: Michele Clamp, James Cuff, John Brunelle" >> JAuth/manifest +jar cmf JAuth/manifest JAuth.jar JAuth/*.class JAuth/fonts/*.ttf JAuth/logo/*.png JAuth/logo/*.icns +rm -rf JAuth/manifest JAuth/*.class + +echo "Making CLI" +javac JAuth/AuthenticatorCLI.java +echo "Main-Class: JAuth.AuthenticatorCLI" > JAuth/manifest +echo "Name: JAuth" >> JAuth/manifest +echo "Implementation-Title: JAuth" >> JAuth/manifest +echo "Implementation-Version: 1.0" >> JAuth/manifest +echo "Specification-Title: JAuth" >> JAuth/manifest +echo "Specification-Version: 1.0" >> JAuth/manifest +echo "Created-By: Michele Clamp, James Cuff, John Brunelle" >> JAuth/manifest +jar cmf JAuth/manifest JAuthCLI.jar JAuth/*.class +rm -rf JAuth/manifest JAuth/*.class