WifiSettings überarbeitet, kleine fixes
[DHBWCampusApp.git] / app / src / main / java / de / dhbwloe / campusapp / wifi / SecureLoginManager.java
1 package de.dhbwloe.campusapp.wifi;
2
3 import android.app.DownloadManager;
4 import android.net.NetworkInfo;
5 import android.net.SSLCertificateSocketFactory;
6 import android.net.SSLSessionCache;
7 import android.net.wifi.WifiInfo;
8 import android.os.AsyncTask;
9 import android.util.Log;
10
11 import java.io.BufferedReader;
12 import java.io.BufferedWriter;
13 import java.io.IOException;
14 import java.io.InputStreamReader;
15 import java.io.OutputStream;
16 import java.io.OutputStreamWriter;
17 import java.io.UnsupportedEncodingException;
18 import java.net.HttpURLConnection;
19 import java.net.URL;
20 import java.net.URLConnection;
21 import java.net.URLEncoder;
22 import java.security.KeyManagementException;
23 import java.security.NoSuchAlgorithmException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29 import javax.net.ssl.HttpsURLConnection;
30 import javax.net.ssl.KeyManager;
31 import javax.net.ssl.SSLContext;
32 import javax.net.ssl.SSLSocket;
33 import javax.net.ssl.SSLSocketFactory;
34 import javax.net.ssl.TrustManager;
35
36 import cz.msebera.android.httpclient.HttpVersion;
37 import cz.msebera.android.httpclient.NameValuePair;
38 import cz.msebera.android.httpclient.client.HttpClient;
39 import cz.msebera.android.httpclient.client.methods.HttpPost;
40 import cz.msebera.android.httpclient.conn.ClientConnectionManager;
41 import cz.msebera.android.httpclient.conn.scheme.PlainSocketFactory;
42 import cz.msebera.android.httpclient.conn.scheme.Scheme;
43 import cz.msebera.android.httpclient.conn.scheme.SchemeRegistry;
44 import cz.msebera.android.httpclient.impl.client.DefaultHttpClient;
45 import cz.msebera.android.httpclient.impl.conn.tsccm.ThreadSafeClientConnManager;
46 import cz.msebera.android.httpclient.message.BasicNameValuePair;
47 import cz.msebera.android.httpclient.params.BasicHttpParams;
48 import cz.msebera.android.httpclient.params.HttpParams;
49 import cz.msebera.android.httpclient.params.HttpProtocolParams;
50 import cz.msebera.android.httpclient.protocol.HTTP;
51 import de.dhbwloe.campusapp.CampusAppContext;
52
53 /**
54  * Created by pk910 on 08.02.2016.
55  */
56 public class SecureLoginManager extends AsyncTask<SecureLoginTask, Void, SecureLoginTask> {
57     private static final String SECURELOGIN_URL = "https://securelogin1.dhbw-loerrach.de/cgi-bin/login";
58     private static final int SECURELOGIN_TIMEOUT = 20000;
59     private static final int SECURELOGIN_HANDSHAKE_TIMEOUT = 10000;
60     private static String SECURELOGIN_FAILED_REGEX = "Authentication failed";
61     private static String SECURELOGIN_SUCCESS_REGEX = "User Authenticated";
62
63     public interface SecureLoginResult {
64         void onSecureLoginFailed(String errMsg);
65         void onSecureLoginSuccess();
66     }
67
68     private CampusAppContext AppContext;
69     private SecureLoginTask task;
70     private String responseString;
71
72     @Override
73     protected SecureLoginTask doInBackground(SecureLoginTask... params) {
74         task = params[0];
75         if (AppContext == null)
76             AppContext = CampusAppContext.getInstance();
77
78         task.responseReceived = false;
79         task.responseString = null;
80
81         //build login post request:
82         //https://securelogin1.dhbw-loerrach.de/cgi-bin/login
83         // user=***censored***
84         // password=***censored***
85         // cmd=authenticate
86         // Login=Log+In
87
88         /* Dear DHBW Tech Guys
89         * Go and replace these fucking outdated and insecure SSL implementation for your "secure"login page!
90         * 3DES_EDE_CBC
91         *
92         * Ok,  after ~3 days android ssl library analysis, i've finnaly made it communicating with an 3DES Endpoint.
93         * Dear DHBW Tech Guys, gu fuck yourself! If you don't know why, continue (^.^)
94         */
95
96         //SSLSocket socket = null;
97         StringBuilder responseString = new StringBuilder();
98         try {
99             SSLContext sslContext = SSLContext.getInstance("TLS");
100             SecureLoginTrustManager loginTrustManager = new SecureLoginTrustManager();
101             sslContext.init(null, new TrustManager[]{loginTrustManager}, null);
102             SSLSocketFactory innerSslSocketPactory = SSLCertificateSocketFactory.getInsecure(SECURELOGIN_HANDSHAKE_TIMEOUT, new SSLSessionCache(AppContext.getMainActivity()));
103             SSLSocketFactory sslSocketFactory = new SecureLoginSocketFactory(sslContext, innerSslSocketPactory);
104
105             //SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket("securelogin1.dhbw-loerrach.de", 443);
106             //socket.startHandshake();
107
108             Log.i("SecureLogin", "HTTPS INITIALIZED");
109
110             URL url = new URL(SECURELOGIN_URL);
111             URLConnection conn = url.openConnection();
112
113             if (conn instanceof HttpsURLConnection) {
114                 ((HttpsURLConnection)conn).setSSLSocketFactory(sslSocketFactory);
115                 ((HttpsURLConnection )conn).setRequestMethod("POST");
116                 ((HttpsURLConnection)conn).setHostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
117             } else {
118                 ((HttpURLConnection) conn).setRequestMethod("POST");
119             }
120             conn.setConnectTimeout(SECURELOGIN_TIMEOUT);
121             conn.setReadTimeout(SECURELOGIN_TIMEOUT);
122
123             conn.setDoInput(true);
124             conn.setDoOutput(true);
125
126             List<NameValuePair> postData = new ArrayList<NameValuePair>();
127             postData.add(new BasicNameValuePair("cmd", "authenticate"));
128             postData.add(new BasicNameValuePair("Login", "Log+In"));
129             postData.add(new BasicNameValuePair("user", task.settings.username));
130             postData.add(new BasicNameValuePair("password", task.settings.password));
131
132             OutputStream os = conn.getOutputStream();
133             BufferedWriter writer = new BufferedWriter(
134                     new OutputStreamWriter(os, "UTF-8"));
135             String postString = encodePostData(postData);
136             writer.write(postString);
137             writer.flush();
138             writer.close();
139             os.close();
140
141             conn.connect();
142
143             int responseCode;
144             if (conn instanceof HttpsURLConnection)
145                 responseCode = ((HttpsURLConnection)conn).getResponseCode();
146             else
147                 responseCode = ((HttpURLConnection)conn).getResponseCode();
148
149             if (responseCode == HttpsURLConnection.HTTP_OK) {
150                 task.responseReceived = true;
151                 String line;
152                 BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
153                 while ((line=br.readLine()) != null) {
154                     responseString.append(line);
155                 }
156             } else {
157                 task.responseError = "HTTP " + Integer.toString(responseCode);
158             }
159
160         } catch (Exception e) {
161             task.responseError = e.getMessage();
162             Log.i("SecureLogin", e.toString() + ":" + e.getMessage());
163         }
164
165         task.responseString = responseString.toString();
166
167         return task;
168     }
169
170     @Override
171     protected void onPreExecute() {
172         super.onPreExecute();
173
174     }
175
176     @Override
177     protected void onPostExecute(SecureLoginTask task) {
178         super.onPostExecute(task);
179
180         boolean success = false;
181         String error = null;
182
183         if(task.responseReceived) {
184             Pattern p1 = Pattern.compile(SECURELOGIN_SUCCESS_REGEX);
185             Pattern p2 = Pattern.compile(SECURELOGIN_FAILED_REGEX);
186
187             Matcher m1 = p1.matcher(task.responseString);
188             Matcher m2 = p2.matcher(task.responseString);
189
190             if(m1.find())
191                 success = true;
192             else if(m2.find())
193                 error = "Incorrect username or password code entered. Please try again.";
194             else
195                 error = "An unknown error occured!";
196         } else if(task.responseError != null) {
197             error = task.responseError;
198         }
199         if(success)
200             task.loginCallback.onSecureLoginSuccess();
201         else
202             task.loginCallback.onSecureLoginFailed(error);
203     }
204
205     private String encodePostData(List<NameValuePair> params) throws UnsupportedEncodingException {
206         StringBuilder result = new StringBuilder();
207         boolean first = true;
208
209         for (NameValuePair pair : params) {
210             if (first)
211                 first = false;
212             else
213                 result.append("&");
214
215             result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
216             result.append("=");
217             result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
218         }
219
220         return result.toString();
221     }
222 }