diff -Nru dummydroid-1.1/debian/changelog dummydroid-1.2/debian/changelog --- dummydroid-1.1/debian/changelog 2017-02-17 16:12:31.000000000 +0000 +++ dummydroid-1.2/debian/changelog 2017-08-30 10:19:11.000000000 +0000 @@ -1,8 +1,14 @@ -dummydroid (1.1-1~vivid1) vivid; urgency=medium +dummydroid (1.2-1~vivid) vivid; urgency=medium * backport to vivid - -- Hans-Christoph Steiner Fri, 17 Feb 2017 15:35:15 +0100 + -- Hans-Christoph Steiner Wed, 30 Aug 2017 12:13:54 +0200 + +dummydroid (1.2-1) unstable; urgency=medium + + * New upstream release (Closes: #867730) + + -- Hans-Christoph Steiner Wed, 30 Aug 2017 11:35:51 +0200 dummydroid (1.1-1) unstable; urgency=low diff -Nru dummydroid-1.1/debian/control dummydroid-1.2/debian/control --- dummydroid-1.1/debian/control 2016-10-31 10:56:05.000000000 +0000 +++ dummydroid-1.2/debian/control 2017-08-30 10:03:38.000000000 +0000 @@ -1,6 +1,6 @@ Source: dummydroid Section: devel -Priority: extra +Priority: optional Maintainer: Android tools Maintainer Uploaders: Hans-Christoph Steiner Build-Depends: cdbs, @@ -10,7 +10,7 @@ libmaven-assembly-plugin-java, libprotobuf-java, maven-debian-helper (>= 1.5~) -Standards-Version: 3.9.8 +Standards-Version: 4.1.0 Homepage: http://www.onyxbits.de/dummydroid Vcs-Git: https://anonscm.debian.org/git/android-tools/dummydroid.git Vcs-Browser: https://anonscm.debian.org/cgit/android-tools/dummydroid.git diff -Nru dummydroid-1.1/debian/copyright dummydroid-1.2/debian/copyright --- dummydroid-1.1/debian/copyright 2016-10-30 22:35:24.000000000 +0000 +++ dummydroid-1.2/debian/copyright 2017-08-30 10:03:00.000000000 +0000 @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0 +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0 Upstream-Name: dummydroid Source: https://github.com/onyxbits/dummydroid diff -Nru dummydroid-1.1/debian/install dummydroid-1.2/debian/install --- dummydroid-1.1/debian/install 2016-10-31 10:44:13.000000000 +0000 +++ dummydroid-1.2/debian/install 2017-08-30 09:47:51.000000000 +0000 @@ -4,4 +4,4 @@ debian/Google_Nexus_6.prop /usr/share/doc/dummydroid/examples/ debian/Motorola_Moto_G_1st_gen.prop /usr/share/doc/dummydroid/examples/ debian/Samsung_Galaxy_Note_2_CyanogenMod.prop /usr/share/doc/dummydroid/examples/ -target/DummyDroid-1.1.jar /usr/share/dummydroid/ +target/DummyDroid-1.2.jar /usr/share/dummydroid/ diff -Nru dummydroid-1.1/debian/links dummydroid-1.2/debian/links --- dummydroid-1.1/debian/links 2016-10-30 22:47:10.000000000 +0000 +++ dummydroid-1.2/debian/links 2017-08-30 09:47:44.000000000 +0000 @@ -1 +1 @@ -/usr/share/dummydroid/DummyDroid-1.1.jar /usr/bin/dummydroid +/usr/share/dummydroid/DummyDroid-1.2.jar /usr/bin/dummydroid diff -Nru dummydroid-1.1/pom.xml dummydroid-1.2/pom.xml --- dummydroid-1.1/pom.xml 2015-04-19 14:33:11.000000000 +0000 +++ dummydroid-1.2/pom.xml 2017-07-18 11:16:06.000000000 +0000 @@ -4,7 +4,7 @@ de.onyxbits dummydroid - 1.1 + 1.2 jar DummyDroid @@ -12,6 +12,7 @@ UTF-8 + 1.6 diff -Nru dummydroid-1.1/src/main/java/com/akdeniz/googleplaycrawler/GooglePlayAPI.java dummydroid-1.2/src/main/java/com/akdeniz/googleplaycrawler/GooglePlayAPI.java --- dummydroid-1.1/src/main/java/com/akdeniz/googleplaycrawler/GooglePlayAPI.java 2015-04-19 14:33:11.000000000 +0000 +++ dummydroid-1.2/src/main/java/com/akdeniz/googleplaycrawler/GooglePlayAPI.java 2017-07-18 11:16:06.000000000 +0000 @@ -3,9 +3,18 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; +import java.security.Key; +import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.PublicKey; +import java.security.spec.RSAPublicKeySpec; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; + +import javax.crypto.Cipher; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -39,6 +48,7 @@ import com.akdeniz.googleplaycrawler.GooglePlay.SearchResponse; import com.akdeniz.googleplaycrawler.GooglePlay.UploadDeviceConfigRequest; import com.akdeniz.googleplaycrawler.GooglePlay.UploadDeviceConfigResponse; +import com.akdeniz.googleplaycrawler.misc.Base64; /** * This class provides @@ -102,6 +112,7 @@ private HttpClient client; private String securityToken; private String localization; + private String useragent; /** * Default constructor. ANDROID ID and Authentication token must be supplied @@ -127,6 +138,8 @@ this.setEmail(email); this.password = password; setClient(new DefaultHttpClient(getConnectionManager())); + // setUseragent("Android-Finsky/3.10.14 (api=3,versionCode=8016014,sdk=15,device=GT-I9300,hardware=aries,product=GT-I9300)"); + setUseragent("Android-Finsky/6.5.08.D-all (versionCode=80650800,sdk=23,device=noblelte,hardware=noblelte,product=noblelte,build=MMB29K:user)"); } /** @@ -160,6 +173,8 @@ setSecurityToken((BigInteger.valueOf(checkinResponse.getSecurityToken()).toString(16))); String c2dmAuth = loginAC2DM(); + //login(); + //String c2dmAuth= getToken(); AndroidCheckinRequest.Builder checkInbuilder = AndroidCheckinRequest.newBuilder(Utils .generateAndroidCheckinRequest()); @@ -171,6 +186,61 @@ // this is the second checkin to match credentials with android-id return postCheckin(build.toByteArray()); } + + private static int readInt(byte[] bArr, int i) { + return (((((bArr[i] & 255) << 24) | 0) | ((bArr[i + 1] & 255) << 16)) | ((bArr[i + 2] & 255) << 8)) + | (bArr[i + 3] & 255); + } + public static PublicKey createKeyFromString(String str, byte[] bArr) { + try { + byte[] decode = Base64.decode(str, 0); + int readInt = readInt(decode, 0); + byte[] obj = new byte[readInt]; + System.arraycopy(decode, 4, obj, 0, readInt); + BigInteger bigInteger = new BigInteger(1, obj); + int readInt2 = readInt(decode, readInt + 4); + byte[] obj2 = new byte[readInt2]; + System.arraycopy(decode, readInt + 8, obj2, 0, readInt2); + BigInteger bigInteger2 = new BigInteger(1, obj2); + decode = MessageDigest.getInstance("SHA-1").digest(decode); + bArr[0] = (byte) 0; + System.arraycopy(decode, 0, bArr, 1, 4); + return KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(bigInteger, bigInteger2)); + } catch (Throwable e) { + throw new RuntimeException(e); + } +} + +private static String encryptString(String str) { +int i = 0; +ResourceBundle bundle = PropertyResourceBundle.getBundle("com.akdeniz.googleplaycrawler.crypt"); +String string=bundle.getString("key"); + +byte[] obj = new byte[5]; +Key createKeyFromString = createKeyFromString(string, obj); +if (createKeyFromString == null) { + return null; +} +try { + Cipher instance = Cipher + .getInstance("RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING"); + byte[] bytes = str.getBytes("UTF-8"); + int length = ((bytes.length - 1) / 86) + 1; + byte[] obj2 = new byte[(length * 133)]; + while (i < length) { + instance.init(1, createKeyFromString); + byte[] doFinal = instance.doFinal(bytes, i * 86, i == length + + -1 ? bytes.length - (i * 86) : 86); + System.arraycopy(obj, 0, obj2, i * 133, obj.length); + System.arraycopy(doFinal, 0, obj2, (i * 133) + obj.length, + doFinal.length); + i++; + } + return Base64.encodeToString(obj2, 10); +} catch (Throwable e) { + throw new RuntimeException(e); +} +} /** * Logins AC2DM server and returns authentication string. @@ -179,7 +249,8 @@ HttpEntity c2dmResponseEntity = executePost(URL_LOGIN, new String[][] { { "Email", this.getEmail() }, - { "Passwd", this.password }, + { "EncryptedPasswd", encryptString(this.getEmail()+"\u0000"+this.password) }, + { "add_account", "1"}, { "service", "ac2dm" }, { "accountType", ACCOUNT_TYPE_HOSTED_OR_GOOGLE }, { "has_permission", "1" }, @@ -188,7 +259,7 @@ { "device_country", "us" }, { "device_country", "us" }, { "lang", "en" }, - { "sdk_version", "21" }, }, null); + { "sdk_version", "17" }, }, null); Map c2dmAuth = Utils.parseResponse(new String(Utils.readAll(c2dmResponseEntity .getContent()))); @@ -225,8 +296,9 @@ HttpEntity responseEntity = executePost(URL_LOGIN, new String[][] { { "Email", this.getEmail() }, - { "Passwd", this.password }, + { "EncryptedPasswd", encryptString(this.getEmail()+"\u0000"+this.password) }, { "service", "androidmarket" }, + { "add_account", "1"}, { "accountType", ACCOUNT_TYPE_HOSTED_OR_GOOGLE }, { "has_permission", "1" }, { "source", "android" }, @@ -234,7 +306,7 @@ { "app", "com.android.vending" }, { "device_country", "en" }, { "lang", "en" }, - { "sdk_version", "21" }, }, null); + { "sdk_version", "17" }, }, null); Map response = Utils.parseResponse(new String(Utils.readAll(responseEntity .getContent()))); @@ -598,9 +670,7 @@ "nocache:billing.use_charging_poller,market_emails,buyer_currency,prod_baseline,checkin.set_asset_paid_app_field,shekel_test,content_ratings,buyer_currency_in_app,nocache:encrypted_apk,recent_changes" }, { "X-DFE-Device-Id", this.getAndroidID() }, { "X-DFE-Client-Id", "am-android-google" }, - { - "User-Agent", - "Android-Finsky/3.10.14 (api=3,versionCode=8016014,sdk=15,device=GT-I9300,hardware=aries,product=GT-I9300)" }, + { "User-Agent", getUseragent() }, { "X-DFE-SmallestScreenWidthDp", "320" }, { "X-DFE-Filter-Level", "3" }, { "Host", "android.clients.google.com" }, @@ -678,4 +748,19 @@ this.localization = localization; } + /** + * @return the useragent + */ + public String getUseragent() { + return useragent; + } + + /** + * @param useragent + * the useragent to set + */ + public void setUseragent(String useragent) { + this.useragent = useragent; + } + } diff -Nru dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/CheckinWorker.java dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/CheckinWorker.java --- dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/CheckinWorker.java 2015-04-19 14:33:11.000000000 +0000 +++ dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/CheckinWorker.java 2017-07-18 11:16:06.000000000 +0000 @@ -2,7 +2,10 @@ import java.io.File; import java.io.PrintWriter; +import java.io.FileInputStream; +import java.io.IOException; import java.math.BigInteger; +import java.util.Properties; import javax.swing.SwingWorker; @@ -11,7 +14,14 @@ import com.akdeniz.googleplaycrawler.GooglePlay.ResponseWrapper; import com.akdeniz.googleplaycrawler.GooglePlay.UploadDeviceConfigRequest; import com.akdeniz.googleplaycrawler.GooglePlayAPI; -import com.akdeniz.googleplaycrawler.Utils; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.HttpClient; +import org.apache.http.conn.params.ConnRoutePNames; +import org.apache.http.impl.client.DefaultHttpClient; + /** * A swingworker for uploading the checkinrequest to Play and getting a GSF ID. @@ -24,17 +34,49 @@ private FormData formData; private CheckinForm callback; + /** + * Name of the file containing the network config + */ + public static final String NETCFG = "network.cfg"; + public static final String PROXYHOST = "proxyhost"; + public static final String PROXYPORT = "proxyport"; + public static final String PROXYUSER = "proxyuser"; + public static final String PROXYPASS = "proxypass"; + public CheckinWorker(CheckinForm callback, FormData formData) { this.formData = formData; this.callback = callback; } + protected void setProxy(HttpClient client) throws IOException { + File cfgfile = new File(NETCFG); + if (cfgfile.exists()) { + Properties cfg = new Properties(); + cfg.load(new FileInputStream(cfgfile)); + String ph = cfg.getProperty(PROXYHOST, null); + String pp = cfg.getProperty(PROXYPORT, null); + String pu = cfg.getProperty(PROXYUSER, null); + String pw = cfg.getProperty(PROXYPASS, null); + if (ph == null || pp == null) { + return; + } + final HttpHost proxy = new HttpHost(ph, Integer.parseInt(pp)); + client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); + if (pu != null && pw != null) { + ((DefaultHttpClient) client).getCredentialsProvider().setCredentials( + new AuthScope(proxy), new UsernamePasswordCredentials(pu, pw)); + } + } + } + @Override protected String doInBackground() throws Exception { GooglePlayAPI api = new GooglePlayAPI(formData.getUsername(), formData.getPassword()); + setProxy(api.getClient()); // this first checkin is for generating android-id - AndroidCheckinResponse checkinResponse = api.postCheckin(Utils.generateAndroidCheckinRequest() - .toByteArray()); + byte[] buf = AndroidCheckinRequest.newBuilder(formData + .getAndroidCheckinRequestBuilder().build()).build().toByteArray(); + AndroidCheckinResponse checkinResponse = api.postCheckin(buf); api.setAndroidID(BigInteger.valueOf(checkinResponse.getAndroidId()).toString(16)); api.setSecurityToken((BigInteger.valueOf(checkinResponse.getSecurityToken()).toString(16))); diff -Nru dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/CredentialsForm.java dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/CredentialsForm.java --- dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/CredentialsForm.java 2015-04-19 14:33:11.000000000 +0000 +++ dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/CredentialsForm.java 2017-07-18 11:16:06.000000000 +0000 @@ -3,6 +3,8 @@ import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JLabel; @@ -12,7 +14,7 @@ import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; -public class CredentialsForm extends AbstractForm implements CaretListener { +public class CredentialsForm extends AbstractForm implements CaretListener, ActionListener { /** * @@ -54,6 +56,10 @@ username.addCaretListener(this); password.removeCaretListener(this); password.addCaretListener(this); + username.removeActionListener(this); + username.addActionListener(this); + password.removeActionListener(this); + password.addActionListener(this); stopIfEmpty(); } @@ -64,12 +70,21 @@ } private void stopIfEmpty() { - forwardAction - .setEnabled(username.getText().length() > 0 && password.getPassword().length > 0); + forwardAction.setEnabled(username.getText().length() > 0 && password.getPassword().length > 0); } public void caretUpdate(CaretEvent arg0) { stopIfEmpty(); } + public void actionPerformed(ActionEvent event) { + if (event.getSource().equals(username) && username.getText().length() > 0) { + password.requestFocus(); + } + if (event.getSource().equals(password) && password.getPassword() != null + && password.getPassword().length > 0) { + forwardAction.actionPerformed(null); + } + } + } diff -Nru dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/MainWindow.java dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/MainWindow.java --- dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/MainWindow.java 2015-04-19 14:33:11.000000000 +0000 +++ dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/MainWindow.java 2017-07-18 11:16:06.000000000 +0000 @@ -38,11 +38,12 @@ description.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); description.addHyperlinkListener(new BrowseUtil()); JPanel formContainer = new JPanel(); + JLabel step = new JLabel(); formContainer.setLayout(new CardLayout()); - NavigateAction forward = new NavigateAction(description, formContainer, NavigateAction.FORWARD, + NavigateAction forward = new NavigateAction(description, formContainer, step, NavigateAction.FORWARD, formData); - NavigateAction backward = new NavigateAction(description, formContainer, NavigateAction.BACK, + NavigateAction backward = new NavigateAction(description, formContainer, step, NavigateAction.BACK, formData); formContainer.add(new LoadForm(forward, backward), LoadForm.class.getName()); @@ -59,9 +60,13 @@ JButton next = new JButton(forward); JButton previous = new JButton(backward); JLabel content = new JLabel(""); - JPanel buttonBar = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - buttonBar.add(previous); - buttonBar.add(next); + JPanel buttonBar = new JPanel(new BorderLayout()); + JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttons.add(previous); + buttons.add(next); + step.setBorder(BorderFactory.createEmptyBorder(0,15,0,0)); + buttonBar.add(step,BorderLayout.WEST); + buttonBar.add(buttons,BorderLayout.EAST); content.setLayout(new BorderLayout()); JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(description), formContainer); diff -Nru dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/NavigateAction.java dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/NavigateAction.java --- dummydroid-1.1/src/main/java/de/onyxbits/dummydroid/NavigateAction.java 2015-04-19 14:33:11.000000000 +0000 +++ dummydroid-1.2/src/main/java/de/onyxbits/dummydroid/NavigateAction.java 2017-07-18 11:16:06.000000000 +0000 @@ -6,6 +6,7 @@ import javax.swing.AbstractAction; import javax.swing.JEditorPane; +import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -30,6 +31,7 @@ private static final long serialVersionUID = 1L; private JPanel formContainer; private JEditorPane description; + private JLabel step; private int type; private FormData formData; @@ -39,12 +41,15 @@ * the textfield that holds the forms description * @param formContainer * the container in which the editor form is sitting + * @param step * @param type * BACK or FORWARD. */ - public NavigateAction(JEditorPane description, JPanel formContainer, int type, FormData formData) { + public NavigateAction(JEditorPane description, JPanel formContainer, JLabel step, int type, + FormData formData) { this.formContainer = formContainer; this.type = type; + this.step = step; this.formData = formData; if (type == BACK) { putValue(NAME, "back"); @@ -83,8 +88,20 @@ return null; } + private int getCurrentIndex() { + int i = 0; + for (Component comp : formContainer.getComponents()) { + i++; + if (comp.isVisible() == true) { + return i; + } + } + return -1; + } + public void toScreen() { AbstractForm form = getCurrent(); + step.setText(getCurrentIndex() + " / " + formContainer.getComponentCount()); description.setText(form.getFormDescription()); form.edit(formData); } diff -Nru dummydroid-1.1/src/main/resources/com/akdeniz/googleplaycrawler/crypt.properties dummydroid-1.2/src/main/resources/com/akdeniz/googleplaycrawler/crypt.properties --- dummydroid-1.1/src/main/resources/com/akdeniz/googleplaycrawler/crypt.properties 1970-01-01 00:00:00.000000000 +0000 +++ dummydroid-1.2/src/main/resources/com/akdeniz/googleplaycrawler/crypt.properties 2017-07-18 11:16:06.000000000 +0000 @@ -0,0 +1 @@ +key=AAAAgMom/1a/v0lblO2Ubrt60J2gcuXSljGFQXgcyZWveWLEwo6prwgi3iJIZdodyhKZQrNWp5nKJ3srRXcUW+F1BD3baEVGcmEgqaLZUNBjm057pKRI16kB0YppeGx5qIQ5QjKzsR8ETQbKLNWgRY0QRNVz34kMJR3P/LgHax/6rmf5AAAAAwEAAQ==