package it.fdev.unisaconnect.wifilogin; import it.fdev.unisaconnect.R; import it.fdev.unisaconnect.data.SharedPrefDataManager; import it.fdev.utils.MySSLSocketFactory; import it.fdev.utils.Utils; import java.io.IOException; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.UnknownHostException; import java.security.KeyStore; import java.util.ArrayList; import java.util.List; import javax.net.ssl.SSLHandshakeException; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.NameValuePair; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; 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.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; import android.os.Handler; import android.util.Log; import android.widget.Toast; public class LoginManager extends IntentService { static { HttpURLConnection.setFollowRedirects(false); } private final static String INTENT_TAG = Utils.TAG + " LoginManager"; private final static String URL = "http://google.com/"; private final static String FORM_URL = "https://wlc.unisa.it/login.html?buttonClicked=0&redirect_url=google.com"; private final static String LOGOUT_URL = "https://wlc.unisa.it/logout.html"; private final static String REDIRECT_PAGE_PATTERN = "Web Authentication Redirect"; private final static String LOGIN_SUCCESSFUL_PATTERN = "You can now use all our regular network services over the wireless network"; private final static String LOGOUT_SUCCESSFUL_PATTERN = "To complete the log off"; private static final int CONNECTION_TIMEOUT = 4000; private static final int SOCKET_TIMEOUT = 4000; private static final int RETRY_COUNT = 2; // Serve per creare il toast private final Handler mHandler = new Handler(); private static DefaultHttpClient mHttpClient; static { mHttpClient = getNewHttpClient(); } public LoginManager() { super(INTENT_TAG); } @Override public void onCreate() { super.onCreate(); } // Viene lanciato in automatico dall'intent, cioè quando cambia lo stato della wifi @Override protected void onHandleIntent(Intent intent) { try { int response_connect = login(getApplicationContext()); if (response_connect == 1) { //Update checher } if (response_connect == 1) { createToastNotification(R.string.login_ok, Toast.LENGTH_SHORT); Log.v(Utils.TAG, "Login successful"); } } catch (Exception e) { // a bug in HttpClient library // thrown when there is a connection failure when handling a // redirect Log.w(Utils.TAG, "Login failed: Exception"); Log.w(Utils.TAG, e.toString()); } } /** * Returns: 0 if already logged in / no action taken * 1 if login successful * 2 if unknown exception retrieving page * 3 if internet is not available even though login was supposedly successful * @param context * @return status result/problem */ protected static int login(Context context) { SharedPrefDataManager mDataManager = new SharedPrefDataManager(context); if (!mDataManager.loginDataExists()) // Non sono memorizzati i dati utente return 3; try { int wificode; if ((wificode = isWifiOk(context)) != 1) return wificode; if (!isLoginRequired()) // Gia si ha l'accesso ad internet return 0; String user = mDataManager.getUser(); String pass = mDataManager.getPass(); user += "@studenti.unisa.it"; List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("referer", "https://captive.unisa.it/main.htm")); formparams.add(new BasicNameValuePair("err_flag", "0")); formparams.add(new BasicNameValuePair("username", user)); formparams.add(new BasicNameValuePair("password", pass)); formparams.add(new BasicNameValuePair("buttonClicked", "4")); formparams.add(new BasicNameValuePair("redirect_url", "")); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8"); HttpPost httppost = new HttpPost(FORM_URL); httppost.setEntity(entity); HttpResponse response = mHttpClient.execute(httppost); Log.v(Utils.TAG, "Post done...checking response"); String strRes = EntityUtils.toString(response.getEntity()); if (strRes.contains(LOGIN_SUCCESSFUL_PATTERN)) { // login successful return 1; } else { return 3; } } catch (Exception e) { Log.e(Utils.TAG, "CAUSA FALLIMENTO CONNESSIONE:" + e.getMessage()); e.printStackTrace(); return 2; } } protected static boolean logout(Context context) { if (isWifiOk(context) != 1) //Wifi non collegata - spenta - altra rete return false; if(isLoginRequired()) // Non si è loggati return true; try { List<NameValuePair> formparams = new ArrayList<NameValuePair>(); formparams.add(new BasicNameValuePair("err_flag", "0")); formparams.add(new BasicNameValuePair("buttonClicked", "4")); formparams.add(new BasicNameValuePair("redirect_url", "")); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8"); HttpPost httppost = new HttpPost(LOGOUT_URL); httppost.setEntity(entity); HttpResponse response = mHttpClient.execute(httppost); String strRes = EntityUtils.toString(response.getEntity()); if (strRes.contains(LOGOUT_SUCCESSFUL_PATTERN)) { return true; } else { return false; } } catch (Exception e) { Log.e(Utils.TAG, "CAUSA FALLIMENTO CONNESSIONE LOGOUT:" + e.getMessage()); e.printStackTrace(); return false; } } // Controlla che il wifi sia acceso e che si sia collegati alla rete dell'università private static int isWifiOk(Context context) { ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); if (wifi != NetworkInfo.State.CONNECTED) { return 2; } // Check SSID WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (wifi==null || wifiMan==null || wifiMan.getConnectionInfo()==null || wifiMan.getConnectionInfo().getSSID()==null || !wifiMan.getConnectionInfo().getSSID().contains(SharedPrefDataManager.SSID_STUDENTI)) { return 4; } return 1; } private static boolean isLoginRequired() { try { HttpResponse response = mHttpClient.execute(new HttpGet(URL)); String strRes = EntityUtils.toString(response.getEntity()); Log.v(Utils.TAG, "Richiesta controllo login richiesta completata"); if (strRes.contains(REDIRECT_PAGE_PATTERN)) { Log.v(Utils.TAG, "The device is not logged in"); return true; } else { return false; } } catch(IOException e) { e.printStackTrace(); return true; } } private void createToastNotification(final int message, final int length) { mHandler.post(new Runnable() { public void run() { Toast.makeText(LoginManager.this, message, length).show(); } }); } public static DefaultHttpClient getNewHttpClient() { 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(); params.setParameter("http.protocol.handle-redirects",false); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT); 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); DefaultHttpClient defHttpClient = new DefaultHttpClient(ccm, params); // Also retry POST requests (normally not retried because it is not regarded idempotent) defHttpClient.setHttpRequestRetryHandler(new HttpRequestRetryHandler() { public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { if (executionCount >= RETRY_COUNT) { // Do not retry if over max retry count return false; } if (exception instanceof UnknownHostException) { // Unknown host return false; } if (exception instanceof ConnectException) { // Connection refused return false; } if (exception instanceof SSLHandshakeException) { // SSL handshake exception return false; } return true; } }); return defHttpClient; } catch (Exception e) { return new DefaultHttpClient(); } } }