package de.tudarmstadt.informatik.hostage.sync.tracing; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.security.KeyStore; import java.util.ArrayList; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import org.json.JSONException; import org.json.JSONObject; import android.app.IntentService; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.os.ResultReceiver; import android.preference.PreferenceManager; import android.util.Log; import de.tudarmstadt.informatik.hostage.logging.NetworkRecord; import de.tudarmstadt.informatik.hostage.logging.SyncInfoRecord; import de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory; import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper; /** * Service that synchronizes with a specified remote server. * * @author Lars Pandikow */ public class TracingSyncService extends IntentService { public static final String REMOTE_DEVICE = "de.tudarmstadt.informatik.hostage.REMOTE_DEVICE"; public static final String ACTION_START_SYNC = "de.tudarmstadt.informatik.hostage.ACTION_START_SYNC"; public static final String EXTRA_RECEIVER = "de.tudarmstadt.informatik.hostage.EXTRA_HANDLER"; public static final String UPLOAD_SIZE = "de.tudarmstadt.informatik.hostage.UPLOAD_SIZE"; public static final String UPLOAD_PROGRESS = "de.tudarmstadt.informatik.hostage.UPLOAD_PROGRESS"; public static final int RECORD_UPLOADED = 0x00; public static final int SYNC_COMPLETE = 0x01; private HttpClient httpClient; private ResultReceiver receiver; HostageDBOpenHelper dbh; SharedPreferences pref; Editor editor; public TracingSyncService() { super(TracingSyncService.class.getName()); } @Override public void onCreate() { super.onCreate(); pref = PreferenceManager.getDefaultSharedPreferences(this); editor = pref.edit(); dbh = new HostageDBOpenHelper(this); } /** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, * IntentService stops the service, as appropriate. */ @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_START_SYNC.equals(action)) { receiver = intent.getParcelableExtra(EXTRA_RECEIVER); syncNewRecords(); dbh.clearSyncInfos(); if (receiver != null) { receiver.send(SYNC_COMPLETE, null); } } } } /** * Uploads all new Records to a server, specified in the settings. */ private void syncNewRecords() { int lastUploadedAttackId = pref.getInt("LAST_UPLOADED_ATTACK_ID", -1); // String serverAddress = pref.getString("pref_upload", // "https://ssi.cased.de"); String serverAddress = "http://87.230.23.240/hostage/push.php"; ArrayList recordList = dbh.getNetworkInformation(); int size = recordList.size(); int offset = 1; for (NetworkRecord record : recordList) { boolean success = uploadSingleRecord(record, serverAddress); Log.i("Tracing upload", "Upload of record: " + offset + "/" + size + ((success) ? " successful." : " failed.")); if (receiver != null) { Bundle data = new Bundle(); data.putInt(UPLOAD_SIZE, size); data.putInt(UPLOAD_PROGRESS, offset); receiver.send(RECORD_UPLOADED, data); } offset++; // TODO pull // getRemoteData(record.getBssid(), record.getTimestamp()); } } /** * Uploads a single Record to a server, specified in the settings. * * @param record * The Record to upload. * @serverAddress Address of the target server * @return True if the upload was successful, else false. */ private boolean uploadSingleRecord(NetworkRecord record, String serverAddress) { // Create a https client. Uses MySSLSocketFactory to accept all // certificates HttpPost httppost; try { httpClient = createHttpClient(); // Create HttpPost httppost = new HttpPost(serverAddress); // Create JSON String of Record // TODO StringEntity se = new // StringEntity(record.toString(TraCINgFormatter.getInstance())); String s = record.toJSON(); StringEntity se = new StringEntity("record=" + record.toJSON()); httppost.addHeader("content-type", "application/x-www-form-urlencoded"); httppost.setEntity(se); // Execute HttpPost HttpResponse response = httpClient.execute(httppost); getRemoteData(record.getBssid(), record.getTimestampLocation()); Log.i("TracingSyncService", "Status Code: " + response.getStatusLine().getStatusCode()); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * Gets the data from the server and updates the database. */ private void getRemoteData(String bssid, long timestamp) { HttpURLConnection connection; OutputStreamWriter request = null; URL url = null; String response = null; String parameters = "bssid=" + bssid; try { url = new URL("http://87.230.23.240/hostage/pull.php"); connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestProperty("content-type", "application/x-www-form-urlencoded"); connection.setRequestMethod("POST"); request = new OutputStreamWriter(connection.getOutputStream()); request.write(parameters); request.flush(); request.close(); String line = ""; InputStreamReader isr = new InputStreamReader(connection.getInputStream()); BufferedReader reader = new BufferedReader(isr); StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) { sb.append(line); } response = sb.toString(); JSONObject jsonObj = new JSONObject(response); NetworkRecord net = new NetworkRecord(); net.setBssid(jsonObj.getString("bssid")); net.setSsid(jsonObj.getString("ssid")); net.setLatitude(jsonObj.getDouble("latitude")); net.setLongitude(jsonObj.getDouble("longitude")); net.setTimestampLocation(jsonObj.getLong("timestamp")); SyncInfoRecord sync = new SyncInfoRecord(); sync.setBSSID(jsonObj.getString("bssid")); sync.setDeviceID("-1"); sync.setNumber_of_attacks(jsonObj.getLong("attacks")); sync.setNumber_of_portscans(jsonObj.getLong("portscans")); dbh.updateNetworkInformation(net); isr.close(); reader.close(); } catch (IOException e) { Log.i("NetworkTest", "Network Error: " + e); } catch (JSONException e) { e.printStackTrace(); } } /** * Creates a HttpClient with an own SSL Socket. * * @return HttpsClient who accepts accepts all certificates. * @see MySSLSocketFactory */ private HttpClient createHttpClient() { try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); SSLSocketFactory sf = new MySSLSocketFactory(trustStore); sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", sf, 443)); ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); return new DefaultHttpClient(ccm, params); } catch (Exception e) { e.printStackTrace(); return new DefaultHttpClient(); } } }