FTPS connection in android - android

I am new to android, i want to download the files from FTPs server, On emulater i am able to download files but when i try on target board it is giving error at ftp.auth(SSLFTPClient.AUTH_TLS);
Below is the my code, please suggest me where i am wrong.
package com.android.ftp;
import java.io.File;
import android.app.Activity;
import android.os.Bundle;
import com.enterprisedt.net.ftp.FTPClientInterface;
import com.enterprisedt.net.ftp.FTPConnectMode;
import com.enterprisedt.net.ftp.FTPTransferType;
import com.enterprisedt.net.ftp.ssl.SSLFTPClient;
import com.enterprisedt.util.debug.Level;
import com.enterprisedt.util.debug.Logger;
public class Ftp_testActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String host = "ftp.xyz.com";
String username = "abcd";
String password = "pqr";
String filename = "/mnt/sdcard/video1/747.3gp";
// set up logger so that we get some output
Logger log = Logger.getLogger(Ftp_testActivity.class);
Logger.setLevel(Level.INFO);
SSLFTPClient ftp = null;
try {
// create client
log.info("Creating FTPS (explicit) client");
ftp = new SSLFTPClient();
// disable standard SSL closure
log.info("Setting configuration flags");
ftp.setConfigFlags(SSLFTPClient.ConfigFlags.DISABLE_SSL_CLOSURE);
// set remote host
log.info("Setting remote host");
ftp.setRemoteHost(host);
ftp.setRemotePort(21);
// turn off server validation
log.info("Turning off server validation");
ftp.setValidateServer(false);
// connect to the server
log.info("Connecting to server " + host);
ftp.connect();
// switch to SSL on control channel
log.info("Switching to FTPS (explicit mode)");
ftp.auth(SSLFTPClient.AUTH_TLS);
// log in
log.info("Logging in with username=" + username + " and password="
+ password);
ftp.login(username, password);
log.info("Logged in");
ftp.setConnectMode(FTPConnectMode.PASV);
ftp.setType(FTPTransferType.ASCII);
putGetDelete(filename, ftp);
log.info("Successfully transferred in ASCII mode");
// Shut down client
log.info("Quitting client");
ftp.quit();
log.info("Example complete");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void putGetDelete(String name, FTPClientInterface ftp)
throws Exception {
ftp.put(name, name);
ftp.get(name + ".copy", name);
ftp.delete(name);
File file = new File(name + ".copy");
file.delete();
}
}

You should try:
ftp.setRemotePort(990);
where 990 is port SSL default.

Related

read html code made by arduino at android

I want to read html code of arduino web server.
I can make web server simply with from example 4. code is below.
#include <SoftwareSerial.h>
#include "WiFly.h"
#define SSID "yum2"
#define KEY "yum000000"
// check your access point's security mode, mine was WPA20-PSK
// if yours is different you'll need to change the AUTH constant, see the file WiFly.h for avalable security codes
#define AUTH WIFLY_AUTH_WPA2_PSK
int flag = 0;
// Pins' connection
// Arduino WiFly
// 2 <----> TX
// 3 <----> RX
SoftwareSerial wiflyUart(2, 3); // create a WiFi shield serial object
WiFly wifly(&wiflyUart); // pass the wifi siheld serial object to the WiFly class
void setup()
{
wiflyUart.begin(9600); // start wifi shield uart port
Serial.begin(9600); // start the arduino serial port
Serial.println("--------- WIFLY Webserver --------");
// wait for initilization of wifly
delay(1000);
wifly.reset(); // reset the shield
delay(1000);
//set WiFly params
wifly.sendCommand("set ip local 80\r"); // set the local comm port to 80
delay(100);
wifly.sendCommand("set comm remote 0\r"); // do not send a default string when a connection opens
delay(100);
wifly.sendCommand("set comm open *OPEN*\r"); // set the string that the wifi shield will output when a connection is opened
delay(100);
Serial.println("Join " SSID );
if (wifly.join(SSID, KEY, AUTH)) {
Serial.println("OK");
} else {
Serial.println("Failed");
}
delay(5000);
wifly.sendCommand("get ip\r");
char c;
while (wifly.receive((uint8_t *)&c, 1, 300) > 0) { // print the response from the get ip command
Serial.print((char)c);
}
Serial.println("Web server ready");
}
void loop()
{
if(wifly.available())
{ // the wifi shield has data available
if(wiflyUart.find("*OPEN*")) // see if the data available is from an open connection by looking for the *OPEN* string
{
Serial.println("New Browser Request!");
delay(1000); // delay enough time for the browser to complete sending its HTTP request string
// send HTTP header
wiflyUart.println("HTTP/1.1 200 OK");
wiflyUart.println("Content-Type: text/html; charset=UTF-8");
wiflyUart.println("Content-Length: 244"); // length of HTML code
wiflyUart.println("Connection: close");
wiflyUart.println();
// send webpage's HTML code
wiflyUart.print("<html>");
wiflyUart.print("<head>");
wiflyUart.print("<title>My WiFI Shield Webpage</title>");
wiflyUart.print("</head>");
wiflyUart.print("<body>");
wiflyUart.print("<h1>Hello World!</h1>");
wiflyUart.print("<h3>10 20 30 40 50</h3>");
wiflyUart.print("Yahoo! Google");
wiflyUart.print("<br/><button>My Button</button>");
wiflyUart.print("</body>");
wiflyUart.print("</html>");
}
}
}
the web server work well.
I wrote simple android code to read html is below.
package com.example.http;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private TextView tv;
String urlAddress = "192.168.0.10"; // doesn't show
// String urlAddress = "http://www.kma.go.kr/weather/main.jsp#1159068000"; // work well
Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.textView1);
Button b = (Button)findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadHtml();
}
});
}
void loadHtml() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
final StringBuffer sb = new StringBuffer();
try {
URL url = new URL(urlAddress);
HttpURLConnection conn =
(HttpURLConnection) url.openConnection();
if (conn != null) {
conn.setConnectTimeout(2000);
conn.setUseCaches(false);
if (conn.getResponseCode()
== HttpURLConnection.HTTP_OK) {
BufferedReader br
= new BufferedReader(new InputStreamReader
(conn.getInputStream()));
while (true) {
String line = br.readLine();
if (line == null) break;
sb.append(line + "\n");
}
br.close();
}
conn.disconnect();
}
Log.d("test", sb.toString());
handler.post(new Runnable() {
#Override
public void run() {
tv.setText(sb.toString());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
}
}
It work very well with String urlAddress = "http://www.kma.go.kr/weather/main.jsp#1159068000";
but it doesn't show when using
String urlAddress = "192.168.0.10"; instead of before one.
the 192.168.0.10 is allocated ip of arduino from DHCP that i can check on serial monitor.
there is any way to read html from arduino web server??
Your urlAddress isn't a URL, it's just an IP address. You should fully qualify the address with the protocol and the path you want to land on, for example:
String urlAddress = "http://192.168.0.10/";
I would expect you're getting a MalformedURLException.

Simple SSH connect open source code with JSch

I am trying to make something from this simple example :
SSH, execute remote commands with Android
i am trying to control my raspberry pi through ssh with simple command execution, everything ok except , it doesn't work! the command i am trying is to make empty text.txt, but when i check on the raspberry, there is no such file created. also tried a sudo reboot command , still doesn't work
Here is my main code:
package com.example.thesacredhaven.samplessh;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
executeRemoteCommand("pi","root","192.168.219.178",22);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void executeRemoteCommand(
String username,
String password,
String hostname,
int port) throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, 22);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.setTimeout(10000);
session.connect();
// SSH Channel
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("lsusb > /home/pi/test.txt");
channel.connect();
channel.disconnect();
}
}
What did I do wrong ? I have no error messages and I don't see any SSH connection on my Linux. is there any library ? or some missing step?

SafetyNet attestation fails with internal error

I want to use the SafetyNet Attestation API (mind that this documentation seems to be outdated since the methods it uses are deprecated). Using the latest version of Play Services (11.0.1) I came up with the following code:
SecureRandom secureRandom = new SecureRandom();
byte[] nonce = new byte[16];
secureRandom.nextBytes(nonce); // just some random bytes for testing
SafetyNet.getClient(this)
.attest(nonce, API_KEY)
.addOnCompleteListener(this, task -> {
if (task.isSuccessful()) {
SafetyNetApi.AttestationResponse result = task.getResult();
String jws = result.getJwsResult();
Log.d(TAG, "JWS: " + jws);
} else {
Exception e = task.getException();
if (e instanceof ApiException) {
Log.e(TAG, "Attestation failure: " + ((ApiException) e).getStatusMessage() + ", code: " + ((ApiException) e).getStatusCode(), e);
} else {
Log.e(TAG, "Attestation failure: " + e, e);
}
}
});
where API_KEY is the API key from the Google Developer Console. This code is called in an Activity's onCreate(...). Whatever I tried, it results in failure and the e is an instance of ApiException, but it does not provide any useful information about what went wrong since the status message is null and the status code is 8, which - according to the documentation - is an "internal error". I tried to call this with a 5 second delay but no success. The test device has API 24 and Google Play services 11.0.55.
Anyone has any idea what goes wrong and what's the solution for this?
Edit: the old SafetyNet.SafetyNetApi.attest(googleApiClient, nonce) way seems to work fine but it's deprecated so I don't want to use it.
Based from this thread, if you get error code 8 (INTERNAL_ERROR), please double check your app registration in dev console. Note that every registered Android client is uniquely identified by the (package name, Android Signing Certificate SHA-1) pair. If you have multiple package names / signing certificate for your debug and production environments, make sure to register every pair of them.
To verify:
Open the Credentials page and select your project
Make sure every pair has an Android typed OAuth 2.0 client IDs. To create a new OAuth 2.0 client ID for your Android client, select New Credentials->OAuth2 Client ID from the dropdown, select Android and input your Package name / Signing-certificate fingerprint there.
If it doesn't work, I recommend you to contact the Google Play team for help. You can reach them from this link here: https://support.google.com/googleplay#topic=3364260&contact=1.
Ensure that you are using correct WEB API KEY in your following code:
SafetyNet.getClient(this)
.attest(nonce, WEB_API_KEY)......
See following image to find WEB API KEY:
FCM Console
// Build.gradle
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.google.firebase:firebase-messaging:20.1.0'
implementation 'com.android.support:support-annotations:28.0.0'
implementation 'com.google.android.gms:play-services-safetynet:17.0.0'
implementation 'com.google.android.gms:play-services-tasks:17.0.0'
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.safetynet.SafetyNetClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.safetynet.SafetyNetClient;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNetApi.AttestationResponse;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;
#Override
public void onConnected(Bundle bundle) {
Log.d("My Project Name:", "Google play services connected");
runSafetyNetTest(mContext);
}
private byte[] getRequestNonce(String data) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byte[] bytes = new byte[24];
mRandom.nextBytes(bytes);
try {
byteStream.write(bytes);
byteStream.write(data.getBytes());
} catch (IOException e) {
return null;
}
public void runSafetyNetTest(Context context) {
String nonceData = "734K78J56KJ745JH78LKJ9CSOC3477tj35f345j7" + System.currentTimeMillis();
byte[] nonce = getRequestNonce(nonceData);
SafetyNetClient client = SafetyNet.getClient(context);
Task<SafetyNetApi.AttestationResponse> task = client.attest(nonce, this.googleDeviceVerificationApiKey);
task.addOnSuccessListener( mSuccessListener).addOnFailureListener(mFailureListener);
}
private OnSuccessListener<SafetyNetApi.AttestationResponse> mSuccessListener =
new OnSuccessListener<SafetyNetApi.AttestationResponse>() {
#Override
public void onSuccess(SafetyNetApi.AttestationResponse attestationResponse) {
mResult = attestationResponse.getJwsResult();
// writeLog( "Success! SafetyNet result:\n" + mResult + "\n");
final String jwsResult = mResult;
final SafetyNetResponse response = parseJsonWebSignature(jwsResult);
lastResponse = response;
//only need to validate the response if it says we pass
if (!response.isCtsProfileMatch() || !response.isBasicIntegrity()) {
// This is Result........
callback.success(response.isCtsProfileMatch(), response.isBasicIntegrity());
return;
} else {
//validate payload of the response
if(true/*validateSafetyNetResponsePayload(response)*/) {
if (googleDeviceVerificationApiKey != "")
{
//if the api key is set, run the AndroidDeviceVerifier
AndroidDeviceVerifier androidDeviceVerifier = new AndroidDeviceVerifier(googleDeviceVerificationApiKey, jwsResult);
androidDeviceVerifier.verify(new AndroidDeviceVerifier.AndroidDeviceVerifierCallback() {
#Override
public void error(String errorMsg) {
callback.error(RESPONSE_ERROR_VALIDATING_SIGNATURE, "Response signature validation error: " + errorMsg);
}
#Override
public void success(boolean isValidSignature) {
if (isValidSignature) {
callback.success(response.isCtsProfileMatch(), response.isBasicIntegrity());
} else {
callback.error(RESPONSE_FAILED_SIGNATURE_VALIDATION, "Response signature invalid");
}
}
});
} else {
Log.w(TAG, "No google Device Verification ApiKey defined");
callback.error(RESPONSE_FAILED_SIGNATURE_VALIDATION_NO_API_KEY, "No Google Device Verification ApiKey defined. Marking as failed. SafetyNet CtsProfileMatch: " + response.isCtsProfileMatch());
}
} else {
callback.error(RESPONSE_VALIDATION_FAILED, "Response payload validation failed");
}
}
}
};
private OnFailureListener mFailureListener = new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// An error occurred while communicating with the service.
mResult = null;
if (e instanceof ApiException) {
// An error with the Google Play Services API contains some additional details.
ApiException apiException = (ApiException) e;
writeLog( "Error: " +
CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " +
apiException.getStatusMessage());
} else {
// A different, unknown type of error occurred.
writeLog( "ERROR! " + e.getMessage());
}
}
};

Dropbox Sync API startLink() method not working

I'm developing an Android app that uses the Dropbox Sync API to upload files. I have already created the app on Dropbox, gotten the APP_KEY and the APP_SECRET. I have included all the necessary libraries, set the proper keys in my activity code and the Manifest. My app is similar to the HelloDropbox sample provided in the documentation, but when I click on the "Link to Dropbox" button which is supposed to display a place to enter my dropbox credentials, nothing happens. Here's the source code:
package com.diamondtrust66.helix.player;
import java.io.File;
import java.io.IOException;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.sync.android.DbxAccountManager;
import com.dropbox.sync.android.DbxFile;
import com.dropbox.sync.android.DbxFileInfo;
import com.dropbox.sync.android.DbxFileSystem;
import com.dropbox.sync.android.DbxPath;
public class HelixPlayer extends Activity {
private static final String appKey = "1234-my-key";
private static final String appSecret = "1234-my-secret";
private static final int REQUEST_LINK_TO_DBX = 0;
private TextView mTestOutput;
private Button mLinkButton;
private DbxAccountManager mDbxAcctMgr;
private DropboxAPI<?> mDBApi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_helix_player);
mTestOutput = (TextView) findViewById(R.id.test_output);
mLinkButton = (Button) findViewById(R.id.link_button);
mLinkButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
onClickLinkToDropbox();
}
});
mDbxAcctMgr = DbxAccountManager.getInstance(getApplicationContext(), appKey, appSecret);
}
#Override
protected void onResume() {
super.onResume();
if (mDbxAcctMgr.hasLinkedAccount()) {
showLinkedView();
doDropboxTest();
} else {
showUnlinkedView();
}
}
private void showLinkedView() {
mLinkButton.setVisibility(View.GONE);
mTestOutput.setVisibility(View.VISIBLE);
}
private void showUnlinkedView() {
mLinkButton.setVisibility(View.VISIBLE);
mTestOutput.setVisibility(View.GONE);
}
private void onClickLinkToDropbox() {
mDbxAcctMgr.startLink((Activity)this, REQUEST_LINK_TO_DBX);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_LINK_TO_DBX) {
if (resultCode == Activity.RESULT_OK) {
doDropboxTest();
} else {
Toast.makeText(getApplicationContext(), "FAILURE", Toast.LENGTH_LONG).show();
mTestOutput.setText("Link to Dropbox failed or was cancelled.");
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
private void doDropboxTest() {
try {
final String TEST_DATA = "Hello Dropbox";
final String TEST_FILE_NAME = "be like that.mp3";
DbxPath testPath = new DbxPath(DbxPath.ROOT, TEST_FILE_NAME);
// Create DbxFileSystem for synchronized file access.
DbxFileSystem dbxFs = DbxFileSystem.forAccount(mDbxAcctMgr.getLinkedAccount());
// Print the contents of the root folder. This will block until we can
// sync metadata the first time.
List<DbxFileInfo> infos = dbxFs.listFolder(DbxPath.ROOT);
mTestOutput.setText("\nContents of app folder:\n");
for (DbxFileInfo info : infos) {
mTestOutput.append(" " + info.path + ", " + info.modifiedTime + '\n');
}
// Create a test file only if it doesn't already exist.
if (!dbxFs.exists(testPath)) {
DbxFile testFile = dbxFs.create(testPath);
try {
File myFile = new File("/mnt/sdcard/alarms/be like that.mp3");
//testFile.writeString(TEST_DATA);
testFile.writeFromExistingFile(myFile, false);
} finally {
testFile.close();
}
mTestOutput.append("\nCreated new file '" + testPath + "'.\n");
}
// Read and print the contents of test file. Since we're not making
// any attempt to wait for the latest version, this may print an
// older cached version. Use getSyncStatus() and/or a listener to
// check for a new version.
/*if (dbxFs.isFile(testPath)) {
String resultData;
DbxFile testFile = dbxFs.open(testPath);
try {
resultData = testFile.readString();
} finally {
testFile.close();
}
mTestOutput.append("\nRead file '" + testPath + "' and got data:\n " + resultData);
} else if (dbxFs.isFolder(testPath)) {
mTestOutput.append("'" + testPath.toString() + "' is a folder.\n");
}*/
} catch (IOException e) {
mTestOutput.setText("Dropbox test failed: " + e);
}
}
}
Are you able to run the unmodified Hello Dropbox example on the same emulator/device where you're experiencing this problem? You can try replacing the app key/secret in the sample with your own as well. If those also fail, it may be there's something wrong with the configuration of your device which is keeping the API from launching a browser to complete authentication. If the example works, but your app doesn't, then I'd suspect something misconfigured there. Can you check with a log statement whether your call to startLink() is actually happening? Do you see anything appear in LogCat after that point?
The best way to debug this further might be to open a suppot ticket. Use the API Support link here: https://www.dropbox.com/developers
I ran into the same problem, the startLink() was doing nothing when I tried to use the same dropbox app credentials I was using with another android app my device had installed (although not running), but it didn't work. So you have two options: Uninstall any other android app using the same credentials OR create another dropbox app and renew the set of app/pass keys. Only then the Dropbox Login Dialog appears.

(a)Smack: TLS socket is closed when trying to login with XMPP

I am trying to connect with asmack (Android Gingerbread) to google talk. I have set connectionConfig.setTruststoreType("BKS") - so I get over the certificates problem. Now the failure is in the XMPPConnection.proceedTLSReceived() function, that is called after the server sent 'proceed' for the 'starttls' request.
This function is supposed to initialize the TSL socket. It fails with an exception "java.net.SocketException: Socket closed".
// Verify certificate presented by the server
context.init(kms,
new javax.net.ssl.TrustManager[]{new ServerTrustManager(getServiceName(), config)},
//new javax.net.ssl.TrustManager[]{new OpenTrustManager()},
new java.security.SecureRandom());
Socket plain = socket;
// Secure the plain connection
socket = context.getSocketFactory().createSocket(plain, plain.getInetAddress().getHostName(), plain.getPort(), false);
socket.setSoTimeout(0); ////// THIS LINE THROWS THE EXCEPTION
Any clues?
The socket is described as:
SSL socket over Socket[addr=talk.google.com/173.194.70.125,port=5222,localport=34840]
It fails on the emulator, and on my Galaxy S I9000.
As it turns out, there was a timeout issue with the SSL connection. It took my application so much time to generate the SSL socket (over the plain socket) that the other side simply gave up... This, or there was a key problem (but I did not receive any authentication errors).
I resolved the problem by:
Moving to API level 15 - that uses AndroidCSStore, and not BKS (which I used for API 10).
Get password using getAuthToken - it is actually a token, but it is later used as a password when connecting.
I do not have spare time to really get to the bottom of the problem. It now works, and that's all that matters.
I posted my code below. SASLXOAuth2Mechanism is complete. But the code from Main is methodical, not complete. I ripped pieces of code from other answers on this site, I apologize in advance for my plagiary.
Main.java - initiate asmack
// Init asmack, and register new mechanisms.
asmack = SmackAndroid.init(ctx);
SASLAuthentication.registerSASLMechanism("X-OAUTH2", SASLXOAuth2Mechanism.class);
SASLAuthentication.supportSASLMechanism("X-OAUTH2", 0);
ConnectionConfiguration connectionConfig =
new ConnectionConfiguration (getHost(), getPort(), getService());
connectionConfig.setSASLAuthenticationEnabled(true);
connectionConfig.setSecurityMode(true);
connectionConfig.setRosterLoadedAtLogin(true);
connectionConfig.setReconnectionAllowed(true);
connectionConfig.setSendPresence(false);
//connectionConfig.setCompressionEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
connectionConfig.setTruststoreType("AndroidCAStore");
connectionConfig.setTruststorePassword(null);
connectionConfig.setTruststorePath(null);
} /*else {
connectionConfig.setTruststoreType("BKS");
String path = System.getProperty("javax.net.ssl.trustStore");
if (path == null)
path = System.getProperty("java.home") + File.separator + "etc"
+ File.separator + "security" + File.separator
+ "cacerts.bks";
connectionConfig.setTruststorePath(path);
connectionConfig.setTruststorePassword("changeit");
//} */
XMPPConnection con = new XMPPConnection(connectionConfig);
SASLXOAuth2Mechanism.java - the XOAuth2 mechanism
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.Base64;
import de.measite.smack.Sasl;
public class SASLXOAuth2Mechanism extends SASLMechanism
{
static final String AUTHENTICATOR_URL = "http://www.google.com/talk/protocol/auth";
protected String authenticationText = null;
static final String TAG = "SASLXOAuth2Mechanism";
public SASLXOAuth2Mechanism(SASLAuthentication saslAuthentication) {
super(saslAuthentication);
}
#Override
protected String getName()
{
return "X-OAUTH2";
}
#Override
public void authenticate(String username, String host, String password) throws IOException, XMPPException {
this.password = password;
this.authenticationId = username;
StringBuilder credentials = new StringBuilder();
credentials.append("\0");
credentials.append(username);
credentials.append("\0");
credentials.append(password);
authenticationText = Base64.encodeBytes(credentials.toString().getBytes("UTF-8"), Base64.DONT_BREAK_LINES);
String[] mechanisms = { "PLAIN" };
Map<String,String> props = new HashMap<String,String>();
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this);
authenticate();
}
protected void authenticate() throws IOException, XMPPException {
// Send the authentication to the server
getSASLAuthentication().send(new XOAuth2AuthMechanism(getName(), authenticationText));
}
/**
* Initiating SASL authentication by select a mechanism.
*/
public class XOAuth2AuthMechanism extends Packet {
final private String name;
final private String authenticationText;
public XOAuth2AuthMechanism(String name, String authenticationText) {
super();
this.name = name;
this.authenticationText = authenticationText;
}
public String toXML() {
StringBuilder stanza = new StringBuilder();
stanza.append("<auth mechanism=\"").append(name);
stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" auth:service=\"oauth2\" xmlns:auth=\"").append(AUTHENTICATOR_URL);
stanza.append("\">");
if (authenticationText != null) {
stanza.append(authenticationText);
}
stanza.append("</auth>");
return stanza.toString();
}
}
}

Categories

Resources