Revision 5d668a55

b/src/android/net/http/SslError.java
1
/*
2
 * Copyright (C) 2006 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

  
17
package android.net.http;
18

  
19
import java.security.cert.X509Certificate;
20

  
21
/**
22
 * One or more individual SSL errors and the associated SSL certificate
23
 */
24
public class SslError {
25

  
26
    /**
27
     * Individual SSL errors (in the order from the least to the most severe):
28
     */
29

  
30
    /**
31
     * The certificate is not yet valid
32
     */
33
  public static final int SSL_NOTYETVALID = 0;
34
    /**
35
     * The certificate has expired
36
     */
37
    public static final int SSL_EXPIRED = 1;
38
    /**
39
     * Hostname mismatch
40
     */
41
    public static final int SSL_IDMISMATCH = 2;
42
    /**
43
     * The certificate authority is not trusted
44
     */
45
    public static final int SSL_UNTRUSTED = 3;
46

  
47

  
48
    /**
49
     * The number of different SSL errors (update if you add a new SSL error!!!)
50
     */
51
    public static final int SSL_MAX_ERROR = 4;
52

  
53
    /**
54
     * The SSL error set bitfield (each individual error is an bit index;
55
     * multiple individual errors can be OR-ed)
56
     */
57
    int mErrors;
58

  
59
    /**
60
     * The SSL certificate associated with the error set
61
     */
62
    SslCertificate mCertificate;
63

  
64
    /**
65
     * Creates a new SSL error set object
66
     * @param error The SSL error
67
     * @param certificate The associated SSL certificate
68
     */
69
    public SslError(int error, SslCertificate certificate) {
70
        addError(error);
71
        mCertificate = certificate;
72
    }
73

  
74
    /**
75
     * Creates a new SSL error set object
76
     * @param error The SSL error
77
     * @param certificate The associated SSL certificate
78
     */
79
    public SslError(int error, X509Certificate certificate) {
80
        addError(error);
81
        mCertificate = new SslCertificate(certificate);
82
    }
83

  
84
    /**
85
     * @return The SSL certificate associated with the error set
86
     */
87
    public SslCertificate getCertificate() {
88
        return mCertificate;
89
    }
90

  
91
    /**
92
     * Adds the SSL error to the error set
93
     * @param error The SSL error to add
94
     * @return True iff the error being added is a known SSL error
95
     */
96
    public boolean addError(int error) {
97
        boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
98
        if (rval) {
99
            mErrors |= (0x1 << error);
100
        }
101

  
102
        return rval;
103
    }
104

  
105
    /**
106
     * @param error The SSL error to check
107
     * @return True iff the set includes the error
108
     */
109
    public boolean hasError(int error) {
110
        boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
111
        if (rval) {
112
            rval = ((mErrors & (0x1 << error)) != 0);
113
        }
114

  
115
        return rval;
116
    }
117

  
118
    /**
119
     * @return The primary, most severe, SSL error in the set
120
     */
121
    public int getPrimaryError() {
122
        if (mErrors != 0) {
123
            // go from the most to the least severe errors
124
            for (int error = SslError.SSL_MAX_ERROR - 1; error >= 0; --error) {
125
                if ((mErrors & (0x1 << error)) != 0) {
126
                    return error;
127
                }
128
            }
129
        }
130

  
131
        return 0;
132
    }
133

  
134
    /**
135
     * @return A String representation of this SSL error object
136
     * (used mostly for debugging).
137
     */
138
    public String toString() {
139
        return "primary error: " + getPrimaryError() +
140
            " certificate: " + getCertificate();
141
    }
142
}
b/src/android/webkit/WebViewClient.java
1
package android.webkit;
2

  
3
import android.graphics.Bitmap;
4
import android.net.http.SslError;
5
import android.os.Message;
6
import android.view.KeyEvent;
7

  
8
public class WebViewClient {
9

  
10
    /**
11
     * Give the host application a chance to take over the control when a new
12
     * url is about to be loaded in the current WebView. If WebViewClient is not
13
     * provided, by default WebView will ask Activity Manager to choose the
14
     * proper handler for the url. If WebViewClient is provided, return true
15
     * means the host application handles the url, while return false means the
16
     * current WebView handles the url.
17
     * 
18
     * @param view The WebView that is initiating the callback.
19
     * @param url The url to be loaded.
20
     * @return True if the host application wants to leave the current WebView
21
     *         and handle the url itself, otherwise return false.
22
     */
23
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
24
        return false;
25
    }
26

  
27
    /**
28
     * Notify the host application that a page has started loading. This method
29
     * is called once for each main frame load so a page with iframes or
30
     * framesets will call onPageStarted one time for the main frame. This also
31
     * means that onPageStarted will not be called when the contents of an
32
     * embedded frame changes, i.e. clicking a link whose target is an iframe.
33
     * 
34
     * @param view The WebView that is initiating the callback.
35
     * @param url The url to be loaded.
36
     * @param favicon The favicon for this page if it already exists in the
37
     *            database.
38
     */
39
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
40
    }
41

  
42
    /**
43
     * Notify the host application that a page has finished loading. This method
44
     * is called only for main frame. When onPageFinished() is called, the
45
     * rendering picture may not be updated yet. To get the notification for the
46
     * new Picture, use {@link WebView.PictureListener#onNewPicture}.
47
     * 
48
     * @param view The WebView that is initiating the callback.
49
     * @param url The url of the page.
50
     */
51
    public void onPageFinished(WebView view, String url) {
52
    }
53

  
54
    /**
55
     * Notify the host application that the WebView will load the resource
56
     * specified by the given url.
57
     * 
58
     * @param view The WebView that is initiating the callback.
59
     * @param url The url of the resource the WebView will load.
60
     */
61
    public void onLoadResource(WebView view, String url) {
62
    }
63

  
64
    /**
65
     * Notify the host application that there have been an excessive number of
66
     * HTTP redirects. As the host application if it would like to continue
67
     * trying to load the resource. The default behavior is to send the cancel
68
     * message.
69
     * 
70
     * @param view The WebView that is initiating the callback.
71
     * @param cancelMsg The message to send if the host wants to cancel
72
     * @param continueMsg The message to send if the host wants to continue
73
     */
74
    public void onTooManyRedirects(WebView view, Message cancelMsg,
75
            Message continueMsg) {
76
        cancelMsg.sendToTarget();
77
    }
78

  
79
    // These ints must match up to the hidden values in EventHandler.
80
    /** Generic error */
81
    public static final int ERROR_UNKNOWN = -1;
82
    /** Server or proxy hostname lookup failed */
83
    public static final int ERROR_HOST_LOOKUP = -2;
84
    /** Unsupported authentication scheme (not basic or digest) */
85
    public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
86
    /** User authentication failed on server */
87
    public static final int ERROR_AUTHENTICATION = -4;
88
    /** User authentication failed on proxy */
89
    public static final int ERROR_PROXY_AUTHENTICATION = -5;
90
    /** Failed to connect to the server */
91
    public static final int ERROR_CONNECT = -6;
92
    /** Failed to read or write to the server */
93
    public static final int ERROR_IO = -7;
94
    /** Connection timed out */
95
    public static final int ERROR_TIMEOUT = -8;
96
    /** Too many redirects */
97
    public static final int ERROR_REDIRECT_LOOP = -9;
98
    /** Unsupported URI scheme */
99
    public static final int ERROR_UNSUPPORTED_SCHEME = -10;
100
    /** Failed to perform SSL handshake */
101
    public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
102
    /** Malformed URL */
103
    public static final int ERROR_BAD_URL = -12;
104
    /** Generic file error */
105
    public static final int ERROR_FILE = -13;
106
    /** File not found */
107
    public static final int ERROR_FILE_NOT_FOUND = -14;
108
    /** Too many requests during this load */
109
    public static final int ERROR_TOO_MANY_REQUESTS = -15;
110

  
111
    /**
112
     * Report an error to the host application. These errors are unrecoverable
113
     * (i.e. the main resource is unavailable). The errorCode parameter
114
     * corresponds to one of the ERROR_* constants.
115
     * @param view The WebView that is initiating the callback.
116
     * @param errorCode The error code corresponding to an ERROR_* value.
117
     * @param description A String describing the error.
118
     * @param failingUrl The url that failed to load.
119
     */
120
    public void onReceivedError(WebView view, int errorCode,
121
            String description, String failingUrl) {
122
    }
123

  
124
    /**
125
     * As the host application if the browser should resend data as the
126
     * requested page was a result of a POST. The default is to not resend the
127
     * data.
128
     * 
129
     * @param view The WebView that is initiating the callback.
130
     * @param dontResend The message to send if the browser should not resend
131
     * @param resend The message to send if the browser should resend data
132
     */
133
    public void onFormResubmission(WebView view, Message dontResend,
134
            Message resend) {
135
        dontResend.sendToTarget();
136
    }
137

  
138
    /**
139
     * Notify the host application to update its visited links database.
140
     * 
141
     * @param view The WebView that is initiating the callback.
142
     * @param url The url being visited.
143
     * @param isReload True if this url is being reloaded.
144
     */
145
    public void doUpdateVisitedHistory(WebView view, String url,
146
            boolean isReload) {
147
    }
148

  
149
    /**
150
     * Notify the host application to handle a ssl certificate error request
151
     * (display the error to the user and ask whether to proceed or not). The
152
     * host application has to call either handler.cancel() or handler.proceed()
153
     * as the connection is suspended and waiting for the response. The default
154
     * behavior is to cancel the load.
155
     * 
156
     * @param view The WebView that is initiating the callback.
157
     * @param handler An SslErrorHandler object that will handle the user's
158
     *            response.
159
     * @param error The SSL error object.
160
     * @hide - hide this because it contains a parameter of type SslError,
161
     * which is located in a hidden package.
162
     */
163
    public void onReceivedSslError(WebView view, SslErrorHandler handler,
164
            SslError error) {
165
        handler.cancel();
166
    }
167

  
168
    /**
169
     * Notify the host application to handle an authentication request. The
170
     * default behavior is to cancel the request.
171
     * 
172
     * @param view The WebView that is initiating the callback.
173
     * @param handler The HttpAuthHandler that will handle the user's response.
174
     * @param host The host requiring authentication.
175
     * @param realm A description to help store user credentials for future
176
     *            visits.
177
     */
178
    public void onReceivedHttpAuthRequest(WebView view,
179
            HttpAuthHandler handler, String host, String realm) {
180
        handler.cancel();
181
    }
182

  
183
    /**
184
     * Give the host application a chance to handle the key event synchronously.
185
     * e.g. menu shortcut key events need to be filtered this way. If return
186
     * true, WebView will not handle the key event. If return false, WebView
187
     * will always handle the key event, so none of the super in the view chain
188
     * will see the key event. The default behavior returns false.
189
     * 
190
     * @param view The WebView that is initiating the callback.
191
     * @param event The key event.
192
     * @return True if the host application wants to handle the key event
193
     *         itself, otherwise return false
194
     */
195
    public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
196
        return false;
197
    }
198

  
199
    /**
200
     * Notify the host application that a key was not handled by the WebView.
201
     * Except system keys, WebView always consumes the keys in the normal flow
202
     * or if shouldOverrideKeyEvent returns true. This is called asynchronously
203
     * from where the key is dispatched. It gives the host application an chance
204
     * to handle the unhandled key events.
205
     * 
206
     * @param view The WebView that is initiating the callback.
207
     * @param event The key event.
208
     */
209
    public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
210
    }
211

  
212
    /**
213
     * Notify the host application that the scale applied to the WebView has
214
     * changed.
215
     * 
216
     * @param view he WebView that is initiating the callback.
217
     * @param oldScale The old scale factor
218
     * @param newScale The new scale factor
219
     */
220
    public void onScaleChanged(WebView view, float oldScale, float newScale) {
221
    }
222
}
b/src/com/rackspace/cloud/android/ListAccountsActivity.java
229 229
	public boolean onOptionsItemSelected(MenuItem item) {
230 230
		switch (item.getItemId()) {
231 231
		case R.id.add_account:
232
			startActivityForResult(new Intent(this, AddAccountActivity.class), 78); // arbitrary number; never used again
232
			Intent intent = new Intent(this, PithosLoginActivity.class);
233
			intent.putExtra("login", "https://pithos.dev.grnet.gr/im/login");
234
			intent.putExtra("auth", Preferences.PITHOS_DEV_SERVER);
235
			startActivityForResult(intent, 78); // arbitrary number; never used again
233 236
			return true;
234 237

  
235 238
		case R.id.contact_rackspace:
......
351 354
			acc.setAuthServer(b.getString("server"));
352 355
			Log.d("info", "the set server was " + b.getString("server"));
353 356
			Log.d("info", "the server is " + acc.getAuthServer());
354
			accounts.add(acc);
357
			boolean found = false;
358
			for(Account a : accounts){
359
				if(a.getUsername().equals(acc.getUsername())&&a.getAuthServer().equals(acc.getAuthServer())){
360
					a.setPassword(acc.getPassword());
361
					found=true;
362
				}
363
			}
364
			if(!found)
365
				accounts.add(acc);
355 366
			writeAccounts();
356 367
			loadAccounts();
357 368
		}
b/src/com/rackspace/cloud/android/PithosLoginActivity.java
1
package com.rackspace.cloud.android;
2

  
3

  
4

  
5
import java.net.URLDecoder;
6
import java.util.Date;
7
import java.util.StringTokenizer;
8
import java.util.regex.Matcher;
9
import java.util.regex.Pattern;
10

  
11
import org.apache.http.impl.cookie.BasicClientCookie;
12

  
13
import android.app.AlertDialog;
14
import android.content.DialogInterface;
15
import android.content.Intent;
16
import android.net.http.SslError;
17
import android.os.Build;
18
import android.os.Bundle;
19
import android.text.format.DateFormat;
20
import android.text.method.PasswordTransformationMethod;
21
import android.util.Log;
22
import android.webkit.CookieManager;
23
import android.webkit.CookieSyncManager;
24
import android.webkit.HttpAuthHandler;
25
import android.webkit.SslErrorHandler;
26
import android.webkit.WebSettings.LayoutAlgorithm;
27
import android.webkit.WebView;
28
import android.webkit.WebViewClient;
29
import android.widget.EditText;
30
import android.widget.LinearLayout;
31
import android.widget.LinearLayout.LayoutParams;
32
import android.widget.TextView;
33

  
34

  
35
public class PithosLoginActivity extends CloudActivity{
36
	String loginUrl=null;
37
	String auth = null;
38
	public void onCreate(Bundle savedInstanceState) {
39
        super.onCreate(savedInstanceState);
40
        trackPageView(GoogleAnalytics.PAGE_PROVIDERS);
41
        Log.i("LOGIN","START");
42
        setContentView(R.layout.login);
43
        loginUrl = getIntent().getExtras().getString("login");
44
        auth = getIntent().getExtras().getString("auth");
45
        doLogin();
46
    
47
        
48
    } 
49
	/*
50
	protected void onSaveInstanceState(Bundle outState) {
51
		super.onSaveInstanceState(outState);
52
		//outState.putBoolean("isHidden", isHidden);
53
	}*/
54
	
55
	private void doLogin(){
56
		CookieSyncManager.createInstance(this);
57
		CookieSyncManager.getInstance().startSync();
58
		final WebView webview = (WebView) findViewById(R.id.browser);//new WebView(this);
59
		webview.getSettings().setJavaScriptEnabled(true);
60
		// webview.setHttpAuthUsernamePassword("vho.grnet.gr", "VHO login",
61
		// "ebs-koutsoub", "mwJBdgbtv");
62
		
63
		webview.clearCache(true);
64
		webview.clearFormData();
65
		webview.clearHistory();
66
		
67

  
68
		webview.getSettings().setBuiltInZoomControls(true);
69
		//webview.getSettings().setDefaultZoom(ZoomDensity.);
70
		if(Build.VERSION.SDK_INT!=7)
71
			webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
72

  
73
		webview.setWebViewClient(new WebViewClient() {
74
			
75
			public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
76
		          handler.proceed();
77
		     }
78

  
79
			  @Override public boolean shouldOverrideUrlLoading(WebView view,
80
			  String url) { 
81
				  view.loadUrl(url); return true;
82
			  }
83
			 
84
			@Override
85
			public void onPageFinished(WebView view, String url) {
86
				super.onPageFinished(view, url);
87
				//webview.loadUrl("javascript:window.HTMLOUT.showHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
88
				CookieSyncManager.getInstance().sync();
89
				String cookie = CookieManager.getInstance().getCookie(url);
90
				Log.i("LOGIN COOKIE","c: "+cookie);
91
				
92
				if(null!=cookie && cookie.startsWith("_pithos2_a")){
93
					try {
94
						String value = URLDecoder.decode(parseRawCookie(cookie).getValue());
95
						StringTokenizer str = new StringTokenizer(value,"|");
96
						if(str.countTokens()==2){
97
							String u = str.nextToken();
98
							String t = str.nextToken();
99
							Log.i("value",value);
100
							Log.i("s1",u);
101
							Log.i("s2",t);
102
							exit(u,t);
103
						}
104
						
105
						//exit(s[0], s[1]);
106
					} catch (Exception e) {
107
						// TODO Auto-generated catch block
108
						e.printStackTrace();
109
					}
110
				}
111
			}
112

  
113
			@Override
114
			public void onReceivedHttpAuthRequest(WebView view,
115
					final HttpAuthHandler handler, String host, String realm) {
116
				String[] up = view.getHttpAuthUsernamePassword(host, realm);
117
				if (up != null && up.length == 2) {
118
					handler.proceed(up[0], up[1]);
119
					
120
				} else {
121
						final AlertDialog.Builder alert = new AlertDialog.Builder(PithosLoginActivity.this);
122
			        	alert.setTitle("Pithos Login");
123
			        	//View lv = findViewById(R.layout.dialoglogin);
124
			        	//alert.setView(lv);
125
			    		final EditText input = new EditText(PithosLoginActivity.this);//(EditText) lv.findViewById(R.id.username); 
126
			    		final EditText pass = new EditText(PithosLoginActivity.this);//(EditText) lv.findViewById(R.id.password);
127
			    		pass.setTransformationMethod(new PasswordTransformationMethod());
128
			    		LinearLayout layout = new LinearLayout(PithosLoginActivity.this);
129
			    		layout.setOrientation(LinearLayout.VERTICAL);
130
			    		LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
131
			    		layout.setLayoutParams(params);
132
			    		input.setLayoutParams(params);
133
			    		pass.setLayoutParams(params);
134
			    		TextView username = new TextView(PithosLoginActivity.this);
135
			    		username.setText("Username:");
136
			    		
137
			    		TextView password = new TextView(PithosLoginActivity.this);
138
			    		password.setText("Password:");
139
			    		layout.addView(username);
140
			    		layout.addView(input);
141
			    		layout.addView(password);
142
			    		layout.addView(pass);
143
			    		alert.setView(layout);
144
			    		
145
			    		alert.setPositiveButton("Login", new DialogInterface.OnClickListener() {
146
			    			public void onClick(DialogInterface dialog, int whichButton) {
147
			    				String uvalue = input.getText().toString().trim();
148
			    				String pvalue = pass.getText().toString().trim();
149
			    				handler.proceed(uvalue, pvalue);			    				
150
			    			}
151
			    		});
152

  
153
			    		alert.setNegativeButton("Cancel",
154
			    				new DialogInterface.OnClickListener() {
155
			    					public void onClick(DialogInterface dialog, int whichButton) {
156
			    						dialog.cancel();
157
			    					}
158
			    				});
159
			    		alert.show();
160
					}
161
				}
162

  
163
			
164
		});
165
		Log.i("LOGIN","LOADING:"+loginUrl);
166
		//setContentView(webview);
167
		webview.clearSslPreferences();
168
		webview.loadUrl("https://pithos.dev.grnet.gr/im/login/invitation?code=6879429392467020041");
169
		//webview.loadUrl("http://www.google.gr");
170
	}
171
	void exit(String username,String token){
172
		Log.i("LOGINA",username+" "+token);
173
		Intent result = new Intent();
174
		Bundle b = new Bundle();
175
		b.putString("username", username);
176
		b.putString("apiKey", token);
177
		b.putString("server", auth);
178
		result.putExtra("accountInfo", b);
179
		setResult(RESULT_OK, result);
180
		finish();
181
	}
182
	
183
	
184
	BasicClientCookie parseRawCookie(String rawCookie) throws Exception {
185
	    String[] rawCookieParams = rawCookie.split(";");
186

  
187
	    String[] rawCookieNameAndValue = rawCookieParams[0].split("=");
188
	    if (rawCookieNameAndValue.length != 2) {
189
	        throw new Exception("Invalid cookie: missing name and value.");
190
	    }
191

  
192
	    String cookieName = rawCookieNameAndValue[0].trim();
193
	    String cookieValue = rawCookieNameAndValue[1].trim();
194
	    BasicClientCookie cookie = new BasicClientCookie(cookieName, cookieValue);
195
	    for (int i = 1; i < rawCookieParams.length; i++) {
196
	        String rawCookieParamNameAndValue[] = rawCookieParams[i].trim().split("=");
197

  
198
	        String paramName = rawCookieParamNameAndValue[0].trim();
199

  
200
	        if (paramName.equalsIgnoreCase("secure")) {
201
	            cookie.setSecure(true);
202
	        } else {
203
	            if (rawCookieParamNameAndValue.length != 2) {
204
	                throw new Exception("Invalid cookie: attribute not a flag or missing value.");
205
	            }
206

  
207
	            String paramValue = rawCookieParamNameAndValue[1].trim();
208

  
209
	            
210
	        }
211
	    }
212

  
213
	    return cookie;
214
	}
215
}
b/src/com/rackspace/cloud/servers/api/client/http/Authentication.java
53 53
			authServer = Account.getAccount().getAuthServerV2();
54 54
		HttpGet get = new HttpGet(authServer);
55 55
		get.addHeader("X-Auth-User", Account.getAccount().getUsername());
56
		get.addHeader("X-Auth-Key", "lMvqjHxChbQY+LgDqwWpYg==");// Account.getAccount().getApiKey());
56
		get.addHeader("X-Auth-Key",  Account.getAccount().getPassword());//"lMvqjHxChbQY+LgDqwWpYg==");//
57 57
		Log.i("AUTH STARTED", authServer);
58 58
		try {
59 59
			HttpResponse resp = httpclient.execute(get);
......
74 74
				Account.getAccount().setCdnManagementUrl(
75 75
						getHeaderValue(resp, "X-Cdn-Management-Url"));
76 76
				Account.getAccount().setLoadBalancerRegions(new String[0]);
77
				BasicResponseHandler responseHandler = new BasicResponseHandler();
78
				String body = responseHandler.handleResponse(resp);
79
				
77 80
				return true;
78 81
			} else {
79 82
				Log.d("status code",

Also available in: Unified diff