11package com .emeryferrari .iosrr ;
22import javax .swing .*;
33import java .awt .event .*;
4+ import java .io .*;
45public class Display {
56 private Display () {}
67 private static final Display CLASS_OBJ = new Display ();
7- private static JFrame FRAME = new JFrame (RRConst .NAME + " - v " + RRConst .VERSION );
8+ private static JFrame FRAME = new JFrame (RRConst .NAME + " " + RRConst .VERSION );
89 private static JLabel TITLE = new JLabel (RRConst .TITLE );
10+ private static JLabel DESC = new JLabel (RRConst .DESC );
911 private static JButton KEY_SALT_BUTTON = new JButton (RRConst .KEY_SALT_BUTTON );
1012 private static JButton FILE_BUTTON = new JButton (RRConst .FILE_BUTTON );
1113 private static JButton SSH_BUTTON = new JButton (RRConst .SSH_BUTTON );
1214 private static JButton IPROXY_BUTTON = new JButton (RRConst .IPROXY_BUTTON );
15+ private static JButton ITUNES_BACKUP = new JButton (RRConst .ITUNES_BACKUP );
16+ private static InfoPlist [] plists = null ;
17+ private static boolean initialized = false ;
1318 public static void createDisplay () {
14- Display .FRAME .setDefaultCloseOperation (JFrame .EXIT_ON_CLOSE );
15- Display .FRAME .setSize (800 , 600 );
16- Display .FRAME .setLayout (new BoxLayout (FRAME .getContentPane (), BoxLayout .Y_AXIS ));
17- Display .KEY_SALT_BUTTON .addActionListener (Display .CLASS_OBJ .new KeySaltButtonListener ());
18- Display .FILE_BUTTON .addActionListener (Display .CLASS_OBJ .new FileButtonListener ());
19- Display .SSH_BUTTON .addActionListener (Display .CLASS_OBJ .new SSHButtonListener ());
20- Display .IPROXY_BUTTON .addActionListener (Display .CLASS_OBJ .new IproxyButtonListener ());
21- Display .IPROXY_BUTTON .setEnabled (false );
19+ if (!initialized ) {
20+ Display .FRAME .setDefaultCloseOperation (JFrame .EXIT_ON_CLOSE );
21+ Display .FRAME .setSize (800 , 600 );
22+ Display .FRAME .setLayout (new BoxLayout (FRAME .getContentPane (), BoxLayout .Y_AXIS ));
23+ Display .KEY_SALT_BUTTON .addActionListener (Display .CLASS_OBJ .new KeySaltButtonListener ());
24+ Display .FILE_BUTTON .addActionListener (Display .CLASS_OBJ .new FileButtonListener ());
25+ Display .SSH_BUTTON .addActionListener (Display .CLASS_OBJ .new SSHButtonListener ());
26+ Display .IPROXY_BUTTON .addActionListener (Display .CLASS_OBJ .new IproxyButtonListener ());
27+ Display .IPROXY_BUTTON .setEnabled (false );
28+ Display .ITUNES_BACKUP .addActionListener (Display .CLASS_OBJ .new ItunesBackupListener ());
29+ initialized = true ;
30+ }
2231 Display .FRAME .getContentPane ().add (Display .TITLE );
32+ Display .FRAME .getContentPane ().add (Display .DESC );
2333 Display .FRAME .getContentPane ().add (Display .KEY_SALT_BUTTON );
2434 Display .FRAME .getContentPane ().add (Display .FILE_BUTTON );
2535 Display .FRAME .getContentPane ().add (Display .SSH_BUTTON );
26- Display .FRAME .getContentPane ().add (Display .IPROXY_BUTTON );
36+ Display .FRAME .getContentPane ().add (Display .ITUNES_BACKUP );
2737 Display .FRAME .setVisible (true );
2838 }
39+ public class ItunesBackupListener implements ActionListener {
40+ public void actionPerformed (ActionEvent ev ) {
41+ try {
42+ OperatingSystem currentOS = RestrictionsRecovery .identifyHostOS ();
43+ String backupPath = System .getProperty ("user.home" ) + "\\ " ;
44+ if (currentOS == OperatingSystem .WINDOWS ) {
45+ String y = JOptionPane .showInputDialog ("Are you using the Microsoft Store version of iTunes? (y/n)" );
46+ if (y .equalsIgnoreCase ("y" ) || y .equalsIgnoreCase ("yes" )) {
47+ backupPath += "Apple\\ MobileSync\\ Backup\\ " ;
48+ } else {
49+ backupPath += "AppData\\ Roaming\\ Apple Computer\\ MobileSync\\ Backup\\ " ;
50+ }
51+ } else if (currentOS == OperatingSystem .MACOSMOJAVE || currentOS == OperatingSystem .MACOSCATALINA ) {
52+
53+ } else {
54+ throw new Exception ("Your OS is not supported because it is not possible to install iTunes on your OS." );
55+ }
56+ File backupLocation = new File (backupPath );
57+ String [] backups = backupLocation .list (new FilenameFilter () {
58+ @ Override
59+ public boolean accept (File current , String name ) {
60+ return new File (current , name ).isDirectory ();
61+ }
62+ });
63+ Display .FRAME .getContentPane ().removeAll ();
64+ Display .FRAME .getContentPane ().add (new JLabel (RRConst .ITUNES_BACKUPS ));
65+ plists = new InfoPlist [backups .length ];
66+ for (int i = 0 ; i < backups .length ; i ++) {
67+ InfoPlist plist = InfoPlist .getInstance (backupPath + backups [i ] + "\\ " );
68+ plists [i ] = plist ;
69+ if (plist != null ) {
70+ JButton button = new JButton (plist .getDeviceName () + " / " + plist .getiOSVersion () + " / " + plist .getBackupDate () + " / " + plist .getDisplayName ());
71+ if (plist .getiOSRelease () < 7 || plist .getiOSRelease () > 11 ) {
72+ button .setEnabled (false );
73+ }
74+ button .addActionListener (Display .CLASS_OBJ .new BackupListener (i ));
75+ Display .FRAME .getContentPane ().add (button );
76+ }
77+ }
78+ JButton back = new JButton ("Back" );
79+ back .addActionListener (new BackListener ());
80+ Display .FRAME .getContentPane ().add (back );
81+ Display .refresh ();
82+ } catch (Exception ex ) {
83+ Display .handleException (ex , true );
84+ }
85+ }
86+ }
87+ public class BackupListener implements ActionListener {
88+ private int index ;
89+ public BackupListener (int index ) {
90+ this .index = index ;
91+ }
92+ public void actionPerformed (ActionEvent ev ) {
93+ try {
94+ KeySaltPair pair = PropertyListReader .getKeyAndSaltFromPlist (plists [index ].getFile () + "398bc9c2aeeab4cb0c12ada0f52eea12cf14f40b" );
95+ Display .FRAME .getContentPane ().add (new JLabel ("<html><body><strong>Calculating passcode...</strong></body></html>" ));
96+ Display .refresh ();
97+ String passcode = RestrictionsRecovery .calculate (pair .getKey (), pair .getSalt (), false );
98+ if (passcode == null ) {
99+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
100+ } else {
101+ JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
102+ }
103+ Display .FRAME .getContentPane ().removeAll ();
104+ Display .createDisplay ();
105+ Display .refresh ();
106+ } catch (Exception ex ) {
107+ Display .handleException (ex , true );
108+ }
109+ }
110+ }
111+ public static void refresh () {
112+ Display .FRAME .revalidate ();
113+ Display .FRAME .repaint ();
114+ }
115+ public static class BackListener implements ActionListener {
116+ public void actionPerformed (ActionEvent ev ) {
117+ Display .FRAME .getContentPane ().removeAll ();
118+ Display .createDisplay ();
119+ Display .refresh ();
120+ }
121+ }
29122 public class KeySaltButtonListener implements ActionListener {
30123 public void actionPerformed (ActionEvent ev ) {
31124 try {
32125 String key = JOptionPane .showInputDialog ("Key?" );
33126 String salt = JOptionPane .showInputDialog ("Salt?" );
127+ Display .DESC .setText ("<html><b>Calculating passcode...</b></html>" );
128+ Display .refresh ();
34129 String passcode = RestrictionsRecovery .calculate (key , salt , false );
35130 if (passcode == null ) {
36- throw new Exception ();
131+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
37132 } else {
38133 JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
39134 }
40135 } catch (Exception ex ) {
41- Display .handleException (ex );
136+ Display .handleException (ex , true );
42137 }
138+ Display .DESC .setText (RRConst .DESC );
139+ Display .refresh ();
43140 }
44141 }
45142 public class FileButtonListener implements ActionListener {
46143 public void actionPerformed (ActionEvent ev ) {
47144 try {
48- String file = JOptionPane .showInputDialog ("Property list path?" );
145+ String file = JOptionPane .showInputDialog ("Property list path? (Do not include quotes) " );
49146 KeySaltPair pair = PropertyListReader .getKeyAndSaltFromPlist (file );
147+ Display .DESC .setText ("<html><b>Calculating passcode...</b></html>" );
148+ Display .refresh ();
50149 String passcode = RestrictionsRecovery .calculate (pair .getKey (), pair .getSalt (), false );
51150 if (passcode == null ) {
52- throw new Exception ();
151+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
53152 } else {
54153 JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
55154 }
56155 } catch (Exception ex ) {
57- Display .handleException (ex );
156+ Display .handleException (ex , true );
58157 }
158+ Display .DESC .setText (RRConst .DESC );
159+ Display .refresh ();
59160 }
60161 }
61162 public class SSHButtonListener implements ActionListener {
@@ -64,26 +165,32 @@ public void actionPerformed(ActionEvent ev) {
64165 String ip = JOptionPane .showInputDialog ("Device IP address?" );
65166 String password = JOptionPane .showInputDialog ("Device root password?" );
66167 String port = JOptionPane .showInputDialog ("Device SSH port?" );
168+ Display .DESC .setText ("<html><b>Calculating passcode...</b></html>" );
169+ Display .refresh ();
67170 RestrictionsRecovery .downloadViaSSH (ip , Integer .parseInt (port ), password , false );
68171 KeySaltPair pair = PropertyListReader .getKeyAndSaltFromPlist ("password.plist" );
69172 String passcode = RestrictionsRecovery .calculate (pair .getKey (), pair .getSalt (), false );
70173 if (passcode == null ) {
71- throw new Exception ();
174+ throw new Exception ("Passcode could not be found. Key and salt does not correspond to any passcode between 0000 and 9999." );
72175 } else {
73176 JOptionPane .showMessageDialog (null , "Passcode: " + passcode );
74177 }
75178 } catch (Exception ex ) {
76- Display .handleException (ex );
179+ Display .handleException (ex , true );
77180 }
181+ Display .DESC .setText (RRConst .DESC );
182+ Display .refresh ();
78183 }
79184 }
80185 public class IproxyButtonListener implements ActionListener {
81186 public void actionPerformed (ActionEvent ev ) {
82187 // not implemented yet
83188 }
84189 }
85- private static void handleException (Exception ex ) {
190+ private static void handleException (Exception ex , boolean message ) {
86191 ex .printStackTrace ();
87- JOptionPane .showMessageDialog (null , "Error occurred while calculating the passcode. Check the console for details." );
192+ if (message ) {
193+ JOptionPane .showMessageDialog (null , "Error: " + ex .getClass ().toString ().split (" " )[1 ] + ": " + ex .getMessage ());
194+ }
88195 }
89196}
0 commit comments