DNS problems on Android - android

I had gotten reports from a few users that they couldn't login to our app (which makes HTTP calls to our site) or visit our website in their browser, so I added some code to our latest build to check what IP our host name is resolving to. I've gotten reports from several different users now that they get 127.0.0.1 for our hostname when the app starts, which obviously isn't going to work.
They claim they aren't running any proxy software, and this happens on both 2.1 and 2.2. This also happens on both wifi & 3g, which makes me suspect it is some piece of software on their phone that is interfering with DNS resolution somehow. Does anyone know of any popular software that might do that? Or does anyone have any ideas about how to identify which software might be doing it?
Thanks,

import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.TXTRecord;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
public class DNSLookUpActivity extends Activity {
private String url = "https://spectracore.americanlogistics.com/rdac/AdmissionController/CheckMddAdmission";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
funDNS(url);
}
private static void funDNS(String url) {
try {
Lookup lookup = new Lookup(url, Type.ANY);
Record[] records = lookup.run();
if (lookup.getResult() == Lookup.SUCCESSFUL) {
String responseMessage = null;
String listingType = null;
for (int i = 0; i < records.length; i++) {
if (records[i] instanceof TXTRecord) {
TXTRecord txt = (TXTRecord) records[i];
for (Iterator j = txt.getStrings().iterator(); j
.hasNext();) {
responseMessage += (String) j.next();
}
Log.e("TXRecord ", "" + responseMessage);
} else if (records[i] instanceof ARecord) {
listingType = ((ARecord) records[i]).getAddress()
.getHostAddress();
Log.e("ARecord address : ", "" + listingType);
}
}
}
} catch (TextParseException e) {
e.printStackTrace();
}
}
}
Need android ask version 2.3.3 or above

Get their DNS config, and try their DNS servers directly with dig or nslookup. This is not perfect, but it has a good chance of showing you the problem.

dnsjava/org.xbill.DNS is too big for android app, Scott Means's DNSQuery is promiseful:
http://smeans.com/programming/dns-queries-in-java/

Related

React Native: Zoom Android SDK: "startMeetingWithParams" starts a meeting as a participant - need it to start a meeting as host

"startMeetingWithParams" starts a meeting as a participant - need it to start a meeting as host:
I'm trying to create a simple app with the react-native-zoom-us open source project which is claimed to be acting as a minimum bridge to the "zoom android sdk". The zoom android sdk is being accessed in this bridge through importing "us.zoom.sdk.ZoomSDK". The basic functionality provided by it includes startMeetingWithParams() function of the MeetingService of the android sdk. In the code (attached below), I can see that they are setting StartMeetingParamsWithoutLogin() with certain params and then passing it as an argument to startMeetingWithParams(). This is starting a meeting with user as a participant (even when host_id of the meeting is set in the parameter "userId") and the default waiting room screen shows up waiting for the host to start the meeting, whereas it is expected to start the meeting as the host. Please give your inferences on this and let me know what needs to be done to solve this. And does something have to be done with the StartMeetingOptions? Also what is the userType parameter here? It is said to be 'integer: 2' for a pro user. However, I'm not sure what type of a zoom user I am. Kindly let me know how I can know about the userType.
#ReactMethod
public void startMeeting(
final String displayName,
final String meetingNo,
final String userId,
final int userType,
final String zoomAccessToken,
final String zoomToken,
Promise promise
) {
try {
meetingPromise = promise;
ZoomSDK zoomSDK = ZoomSDK.getInstance();
if(!zoomSDK.isInitialized()) {
promise.reject("ERR_ZOOM_START", "ZoomSDK has not been initialized successfully");
return;
}
final MeetingService meetingService = zoomSDK.getMeetingService();
if(meetingService.getMeetingStatus() != MeetingStatus.MEETING_STATUS_IDLE) {
long lMeetingNo = 0;
try {
lMeetingNo = Long.parseLong(meetingNo);
} catch (NumberFormatException e) {
promise.reject("ERR_ZOOM_START", "Invalid meeting number: " + meetingNo);
return;
}
if(meetingService.getCurrentRtcMeetingNumber() == lMeetingNo) {
meetingService.returnToMeeting(reactContext.getCurrentActivity());
promise.resolve("Already joined zoom meeting");
return;
}
}
StartMeetingOptions opts = new StartMeetingOptions();
StartMeetingParamsWithoutLogin params = new StartMeetingParamsWithoutLogin();
params.displayName = displayName;
params.meetingNo = meetingNo;
params.userId = userId;
params.userType = userType;
params.zoomAccessToken = zoomAccessToken;
// params.zoomToken = zoomToken;
int startMeetingResult = meetingService.startMeetingWithParams(reactContext.getCurrentActivity(), params, opts);
Log.i(TAG, "startMeeting, startMeetingResult=" + startMeetingResult);
if (startMeetingResult != MeetingError.MEETING_ERROR_SUCCESS) {
promise.reject("ERR_ZOOM_START", "startMeeting, errorCode=" + startMeetingResult);
}
} catch (Exception ex) {
promise.reject("ERR_UNEXPECTED_EXCEPTION", ex);
}
}
To work with api, you need to upgrade your subscription to paid user. To check that you should be able to host meetings greater than 40 minutes.
According to the ZOOM Android SDK reference here https://marketplace.zoom.us/docs/sdk/sdk-reference/android-reference:
and after taking look at the SDK source code, these are the values for userTypes:
int USER_TYPE_API_USER = 0;
int USER_TYPE_ZOOM = 1;
int USER_TYPE_FACEBOOK = 2;
int USER_TYPE_GOOGLE_OAUTH = 3;
int USER_TYPE_SSO = 4;
int USER_TYPE_UNKNOWN = -1;
As you can see, it references the way, how user was logged in.
I decided to use USER_TYPE_API_USER, as I needed to download Zoom Access Token (via using Zoom API).
I also created tutorial about inegrating Zoom SDK into React Native here:
https://stefanmajiros.medium.com/how-to-integrate-zoom-sdk-into-react-native-47492d4e46a6

Preventing an android app being cloned by an app cloner

Created an app that used the device's uniqueID which is fetched by the following code snippet
String deviceId = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID);
When the user tries to clone the app by app cloner, then it creates a different deviceID and the app is not allowed to work
Is there any way to make our app non clonable
or
Any possible way to have the same deviceId even if the app instance is cloned?
Is there any way to find out whether the app is running in a cloned instance?
Applications like Cloner usually change your application's package name so you can retrieve package name and check if it is changed or not.
if (!context.getPackageName().equals("your.package.name")){
// close the app or do whatever
}
Also they usually sign cloned apk so the signature might be different from yours, you can check if signature is changed or not. I usually use this function:
#SuppressLint("PackageManagerGetSignatures")
public static int getCertificateValue(Context ctx){
try {
Signature[] signatures = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try {
signatures = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES).signingInfo.getApkContentsSigners();
}catch (Throwable ignored){}
}
if (signatures == null){
signatures = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
}
int value = 1;
for (Signature signature : signatures) {
value *= signature.hashCode();
}
return value;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public static boolean checkCertificate(Context ctx, int trustedValue){
return getCertificateValue(ctx) == trustedValue;
}
Before releasing your app call getCertificateValue(context) and write down the value and alongside with package name, check if that value matches the value that you get in runtime.
PS: as #vladyslav-matviienko said hackers will always find a way so try to make cloning harder by running some obfuscations on hardcoded package name and that value. Also try to tangle and spread these kind of logics all around the source code.
I found a story in proandroiddev by Siddhant Panhalkar and with some minor changes it's work perfectly in Mi device I did checked in Mi phones default Dual apps and some third party apps from playstore and it prevents from cloning (means not working properly after clone).
private const val APP_PACKAGE_DOT_COUNT = 3 // number of dots present in package name
private const val DUAL_APP_ID_999 = "999"
private const val DOT = '.'
fun CheckAppCloning(activity: Activity) {
val path: String = activity.filesDir.getPath()
if (path.contains(DUAL_APP_ID_999)) {
killProcess(activity)
} else {
val count: Int = getDotCount(path)
if (count > APP_PACKAGE_DOT_COUNT) {
killProcess(activity)
}
}
}
private fun getDotCount(path: String): Int {
var count = 0
for (element in path) {
if (count > APP_PACKAGE_DOT_COUNT) {
break
}
if (element == DOT) {
count++
}
}
return count
}
private fun killProcess(context: Activity) {
context.finish()
android.os.Process.killProcess( android.os.Process.myPid())
}

How to properly install mysql connector in Eclipse?

First of all I'd like to say that it is a project for a course in my university and at the same time my first app for Android which is more complicated that a calculator, so I understand that I could have done some unforgivable mistakes, but my priority is that the code should work. It can be insecure and not considering some cases, but as long as those cases won't appear, it will do.
My app is intended to be running on Android and first of all there should appear login screen which takes login and password, makes the hash of the password and contacts a database on a web server to compare hashes. I was told to use a free database db4free.net.
I created a class Serwer, which would be responsible exclusively for contacting the database. As far as I understood from tutorials and stackoverflow questions and answers, the connection should consist of:
Loading the driver,
Registering it in the DriverManager class,
Using getConnection method to open the connection, passing the credentials,
Preparing and executing SQL query,
Fetching a result set.
I also learned that I should download a mysql-connector-java-5.1.38-bin.jar file. As some threads on stackoverflow suggested, I copied it into main directory of the project (I have to copy the workspace and take to professor's computer when I finish), added it to Libraries tab of properties as an external library. Now when I run the project on my smartphone, I get a java.lang.ClassNotFoundException: Didn't find class "com.mysql.jdbc.Driver" error. I also tried to check the library in Order and Export tab - then it even doesn't compile, returning Conversion to Dalvik format failed with error 1.
I've tried many scenarios in other stackoverflow threads, such as cleaning the project in many configurations, changing the order of build path, etc. I suspect that I've made a simple, stupid mistake that I do not see and I hope you will recognize it.
Here is my Serwer class:
package com.planer.serwer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Driver;
import com.planer.MainActivity;
import com.example.planer.R;
import com.planer.pracownik.Pracownik;
public class Serwer {
private Connection conn = null;
private static Driver driver;
private static int status;
private MainActivity parentActivity;
private final String user = parentActivity.getResources().getString(R.string.db_login);
private final String pass = parentActivity.getResources().getString(R.string.db_pass);
private final String url= "jdbc:mysql://db4free.net:3306/kalendarzplaner";
public static final int STATUS_GOOD = 0;
public static final int STATUS_NO_CONNECTION = 1;
public static final int STATUS_NOT_AUTHENTICATED = 2;
public static final int STATUS_SQL_EXCEPTION = 4;
public static final int STATUS_NO_DRIVER = 8;
public Serwer(MainActivity parentActivity){
status = STATUS_NO_CONNECTION;
try {
driver = new com.mysql.jdbc.Driver();
} catch (Exception ex) {
status |= STATUS_NO_DRIVER;
} catch (NoClassDefFoundError e){
status |= STATUS_NO_DRIVER;
}
this.parentActivity = parentActivity;
}
public Pracownik authorize(String login, String passhash){
Pracownik pracownik = new Pracownik("","",false,status);
status |= this.polacz();
if(status != Serwer.STATUS_GOOD) {
pracownik.status |= status;
return pracownik;
}
Statement statement = null;
ResultSet resultSet = null;
String query = "select passhash, imie_nazwisko, czy_kierownik from auth where login='" + login + "';";
try {
statement = conn.prepareStatement(query);
resultSet = statement.executeQuery(query);
resultSet.first();
if(resultSet.getString("passhash").toString().compareTo(passhash)!= 0){
status |= Serwer.STATUS_NOT_AUTHENTICATED;
pracownik.status |= status;
return pracownik;
}
pracownik.login = login;
pracownik.imie_nazwisko = resultSet.getString("imie_nazwisko");
pracownik.czy_kierownik = resultSet.getBoolean("czy_kierownik");
} catch (SQLException ex) {
pracownik.status |= Pracownik.STATUS_SQL_EXCEPTION;
}
return pracownik;
}
public int polacz() {
int done = STATUS_NO_CONNECTION;
if((status & STATUS_NO_DRIVER) != 0)
return done;
// Connection
try {
DriverManager.registerDriver(driver);
conn = DriverManager.getConnection(url, user, pass);
done = Serwer.STATUS_GOOD;
} catch (java.sql.SQLException ex) {
done |= Serwer.STATUS_SQL_EXCEPTION;
System.out.println("SQLException: " + ex.getMessage());
}
return done;
}
}
As I said, the status of the result of authorise method is 9, which is expected when the driver is not loaded. I also append my workspace contents.
First, I want to start by suggesting that you tried out Android Studio. It's the new more modern IDE developed specifically for the purpose of Android Development.
Secondly, contacting a database on Android is a lot different than for example contacting a DB from Java/C# in an Desktop application.
To contact an online MySQL Database you need a RESTful service (written in PHP for example) that gets the data from the database and sends it over to the application. The service is like a communication point between the App and the Database. The service usually sends data to the application in a human-unfriendly format like JSON, so your app needs to parse that and then display it.

How connect SQLite with Adobe Air for Android using Flash CS6 and AS3 language?

I am developing a small game for Air Android in flash CS6, this game I'm programming object-oriented with classes written in AS3.
I want you to help me write a class that connects to SQLite from scratch, please!
I googled but only there information to FLEX or code for insert into frames (and i get lost because i don't know that libraries to import), it's not what I want.
I want to create the connection class to use in my class Main.
I hope I have your support, thank you.
Excuse my English but I speak Spanish.
You need 'Synchronous' or 'Asynchronous' sqlite connection ? You can see differences here: - Best practices for developing AIR Application with SQLite
1. There is an example for 'async' connection :SQLConnection - you just have to modify and remove transactions part (if you do not need it).
2. 'sync' is easy and i prefer this way
import flash.data.SQLConnection;
import flash.filesystem.File;
import flash.data.SQLMode; //if you use SQLMode: CREATE | UPDATE | READ
import flash.data.SQLStatement;
import flash.data.SQLResult;
import flash.errors.SQLError;
public class SQLiteConn
{
private var dbFile:File = new File("pathtofile");
private var conn:SQLConnection;
private var stmt:SQLStatement;
private var arr:Array;
public function SQLiteConn()
{
}
//open sqlite DB
public function openSQLite():Boolean {
conn = new SQLConnection;
if (dbFile.exists) {
try {
conn.open(dbFile);
return true;
}
catch (error:SQLError) {
trace(error.details, error.message);
}
}
return false;
}
//execute statement and get result/s
public function executeStatement(stmtText:String, param1:String, param2:String):Array {
if (conn.connected) {
stmt = new SQLStatement();
stmt.sqlConnection = con;
stmt.text = stmtText;
stmt.parameters[0] = param1;
stmt.parameters[1] = param2;
try {
stmt.execute();
var result:SQLResult = stmt.getResult();
if (result.data != null) {
var total:int = result.data.length;
for (var i:int = 0; i < total; i++) {
row = result.data[i];
arr.push( { id:row.tablerowID } );
}
}
else {
arr.push({id: -1}); //no result/s
}
}
catch (error:SQLError) {
arr.push({id: -2}); //sqlite error
}
}
else {
arr.push({id: -2}); //no connection
}
return arr;
}
//close sqliteConnection
public function closeSQLiteConn():void {
if (conn.connected) {
conn.close();
}
}
}
you can also 'dispatch event' from that class - it is your choise :)

How to get Mobile Device Identification in Webservice

I have android native application & web service. Our application is University application. Generate long live token for session issue.So we planned to go for MDM, i searched on Google, , I got some solution
Open Mobster (Open Source Mobile Enterprise Backend)
Apache USerGrid_ (Mobile Backend as a service)
OpenMeap - not support native
Problem is I could not find out , whether this MDM are provide device identification facility.If any one knows about it please tell me. Device identification may be any unique id or mac address
or If i am going to developed our own middle layer , how we can get mac address from request header. without passing to service method , from the request should take.
is there any way to take sort-out this issue?
Please help me
Here is how OpenMEAP grabs the Mac address and passes it in the header.
package com.openmeap.thinclient;
import java.io.ByteArrayInputStream;
import com.openmeap.http.HttpRequestExecuter;
import com.openmeap.http.HttpResponse;
import com.openmeap.util.Utils;
public class FirstRunCheck implements Runnable {
private SLICConfig config;
private String macAddress;
private HttpRequestExecuter executer;
public FirstRunCheck(SLICConfig config, String macAddress, HttpRequestExecuter executer) {
this.config = config;
this.macAddress = macAddress;
this.executer = executer;
}
public void run() {
if( config.isDevelopmentMode().equals(Boolean.TRUE) ) {
return;
}
if( config.getNotFirstRun()==null ) {
config.setNotFirstRun(Boolean.TRUE);
try {
String macWithSalt = macAddress+".OPENMEAP#$!#3__234";
String hashValue = Utils.hashInputStream("sha1", new ByteArrayInputStream(macWithSalt.getBytes("UTF-8")));
HttpResponse response = executer.get("http://usage.openmeap.com/tracker.gif?hash="+hashValue);
Utils.consumeInputStream(response.getResponseBody());
} catch( Exception ioe ) {
return;
}
}
}
}

Categories

Resources