ソースを参照

https for unsigned certificates in logging and uploading

Bartek Przybylski 13 年 前
コミット
2bc41ee331

+ 7 - 5
.classpath

@@ -5,11 +5,13 @@
 	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
 	<classpathentry kind="lib" path="lib/commons-codec-1.4.jar"/>
 	<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
-	<classpathentry kind="lib" path="lib/httpclient-4.1.1.jar"/>
-	<classpathentry kind="lib" path="lib/httpclient-cache-4.1.1.jar"/>
-	<classpathentry kind="lib" path="lib/httpcore-4.1.jar"/>
-	<classpathentry kind="lib" path="lib/httpmime-4.1.1.jar"/>
 	<classpathentry kind="lib" path="lib/commons-httpclient-3.0.1.jar"/>
 	<classpathentry kind="lib" path="lib/commons-io-2.0.1.jar"/>
-	<classpathentry kind="output" path="bin"/>
+	<classpathentry kind="lib" path="lib/android-support-v4.jar"/>
+	<classpathentry kind="lib" path="lib/commons-httpclient-contrib-3.0.jar"/>
+	<classpathentry kind="lib" path="lib/httpclient-4.1.2.jar"/>
+	<classpathentry kind="lib" path="lib/httpcore-4.1.2.jar"/>
+	<classpathentry kind="lib" path="lib/httpmime-4.1.2.jar"/>
+	<classpathentry kind="lib" path="lib/httpclient-cache-4.1.2.jar"/>
+	<classpathentry kind="output" path="bin/classes"/>
 </classpath>

+ 2 - 13
AndroidManifest.xml

@@ -15,12 +15,6 @@
         android:name="android.permission.INTERNET" />
     <uses-permission
         android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission
-        android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission
-        android:name="android.permission.READ_CONTACTS" />
-    <uses-permission
-        android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission
         android:name="android.permission.READ_SYNC_STATS" />
     <uses-permission
@@ -38,7 +32,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity android:name="OwnCloudUploader">
+        <activity android:name=".Uploader">
             <intent-filter>
                 <action android:name="android.intent.action.SEND"></action>
                 <category android:name="android.intent.category.DEFAULT"></category>
@@ -74,12 +68,7 @@
         </service>
          <provider android:name="cp" android:enabled="true" android:syncable="true" android:exported="false" android:authorities="org.owncloud" android:label="@string/sync_string_files"></provider>
          <activity android:name=".authenticator.AuthenticatorActivity"></activity>
-         <provider android:label="@string/sync_string_contacts" android:name="cp2" android:syncable="true" android:enabled="true" android:exported="false" android:authorities=""></provider>
-         <service android:name=".syncadapter.ContactSyncService" android:exported="true">
-             <intent-filter>
-                 <action android:name="android.content.SyncAdapter"></action>
-             </intent-filter>
-             <meta-data android:resource="@xml/syncadapter_contacts" android:name="android.content.SyncAdapter"></meta-data>
+         <service android:name="FileDownloader">
          </service>
     </application>
 </manifest>

BIN
lib/android-support-v4.jar


BIN
lib/commons-httpclient-contrib-3.0.jar


BIN
lib/httpclient-4.1.2.jar


BIN
lib/httpclient-cache-4.1.2.jar


BIN
lib/httpcore-4.1.2.jar


BIN
lib/httpmime-4.1.2.jar


BIN
lib/not-yet-commons-ssl-0.3.11.jar


+ 1 - 1
default.properties → project.properties

@@ -4,7 +4,7 @@
 # This file must be checked in Version Control Systems.
 #
 # To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
+# "ant.properties", and override values to adapt the script to your
 # project structure.
 
 # Project target.

+ 141 - 0
src/eu/alefzero/owncloud/FileDownloader.java

@@ -0,0 +1,141 @@
+package eu.alefzero.owncloud;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.UnknownHostException;
+import java.util.Date;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.BasicHttpContext;
+
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
+import eu.alefzero.webdav.HttpPropFind;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.IBinder;
+import android.util.Log;
+import android.widget.FrameLayout;
+
+public class FileDownloader extends Service {
+  static final String EXTRA_ACCOUNT = "ACCOUNT";
+  static final String EXTRA_FILE_PATH = "FILE_PATH";
+  static final String TAG = "OC_FileDownloader";
+  
+  NotificationManager nm;
+  
+  @Override
+  public IBinder onBind(Intent arg0) {
+    return null;
+  }
+  
+  @Override
+  public int onStartCommand(Intent intent, int flags, int startId) {
+    if (!intent.hasExtra(EXTRA_ACCOUNT) && !intent.hasExtra(EXTRA_FILE_PATH)) {
+      Log.e(TAG, "Not enough information provided in intent");
+      return START_NOT_STICKY;
+    }
+    
+    nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+    
+    Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
+    String file_path = intent.getStringExtra(EXTRA_FILE_PATH);
+    AccountManager am = (AccountManager)getSystemService(ACCOUNT_SERVICE);
+    Uri oc_url = Uri.parse(am.getUserData(account, AccountAuthenticator.KEY_OC_URL));
+
+    DefaultHttpClient client = new DefaultHttpClient();
+    Log.d(TAG,  oc_url.toString());
+    HttpGet query = new HttpGet(oc_url + file_path);
+    query.setHeader("Content-type", "text/xml");
+    query.setHeader("User-Agent", "Android-ownCloud");
+    
+    BasicHttpContext httpContext = new BasicHttpContext();
+    BasicScheme basicAuth = new BasicScheme();
+    httpContext.setAttribute("preemptive-auth", basicAuth);
+    
+    String username = account.name.split("@")[0];
+    String password = "";
+    try {
+      password = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE, true);
+    } catch (OperationCanceledException e1) {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    } catch (AuthenticatorException e1) {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    } catch (IOException e1) {
+      // TODO Auto-generated catch block
+      e1.printStackTrace();
+    }
+    if (am.getUserData(account, AccountAuthenticator.KEY_OC_URL) == null) {
+      
+    }
+
+    client.getCredentialsProvider().setCredentials(
+      new AuthScope(oc_url.getHost(), oc_url.getPort()==-1?80:oc_url.getPort()),
+      new UsernamePasswordCredentials(username, password)
+    );
+    
+    HttpHost host = new HttpHost(oc_url.getHost(), oc_url.getPort()==-1?80:oc_url.getPort());
+    
+    Notification n = new Notification(R.drawable.icon, "Downloading file", System.currentTimeMillis());
+    PendingIntent pi = PendingIntent.getActivity(this, 1, new Intent(this, OwnCloudMainScreen.class), 0);
+    n.setLatestEventInfo(this, "A", "B", pi);
+    nm.notify(1, n);
+    
+    HttpResponse response = null;
+    try {
+      response = client.execute(host, query, httpContext);
+    } catch (ClientProtocolException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    
+    File sdCard = Environment.getExternalStorageDirectory();
+    File dir = new File (sdCard.getAbsolutePath() + "/owncloud");
+    dir.mkdirs();
+    File file = new File(dir, "filename");
+
+    try {
+      FileOutputStream f = new FileOutputStream(file);
+      byte[] b = new byte[(int)response.getEntity().getContentLength()];
+      response.getEntity().getContent().read(b);
+      f.write(b);
+    } catch (FileNotFoundException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IllegalStateException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+    
+    
+    return START_NOT_STICKY;
+  }
+
+}

+ 0 - 5
src/eu/alefzero/owncloud/FileListActionListAdapter.java

@@ -21,7 +21,6 @@ package eu.alefzero.owncloud;
 import java.io.File;
 
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta;
 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
 import android.accounts.Account;
 import android.accounts.AccountManager;
@@ -30,14 +29,10 @@ import android.content.Intent;
 import android.database.Cursor;
 import android.database.DataSetObserver;
 import android.net.Uri;
-import android.provider.MediaStore.Images.Media;
-import android.sax.StartElementListener;
 import android.text.TextUtils;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.View.OnClickListener;
 import android.widget.ImageView;
 import android.widget.ListAdapter;
 import android.widget.TextView;

+ 27 - 2
src/eu/alefzero/owncloud/OwnCloudMainScreen.java

@@ -18,6 +18,10 @@
 
 package eu.alefzero.owncloud;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.LinkedList;
 import java.util.Stack;
 
@@ -36,6 +40,7 @@ import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Environment;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.Menu;
@@ -276,13 +281,33 @@ public class OwnCloudMainScreen extends ListActivity {
       try {
         Intent i = (Intent) getListAdapter().getItem(position);
         if (i.hasExtra("toDownload")) {
+          
+          Uri data = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() + "/owncloud/filename");
+          Log.d("DUPA", data.toString());
+          File f = new File(data.toString());
+          FileInputStream fis = new FileInputStream(f);
+          byte buffer[] = new byte[512];
+          fis.read(buffer);
+          Log.d("DUPA", new String(buffer));
+          
+          //Intent intent = new Intent(this, FileDownloader.class);
+          /*intent.putExtra(FileDownloader.EXTRA_FILE_PATH, "/docsy.py");
+          intent.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
+          startService(intent);
+          /*
           if (i.getBooleanExtra("toDownload", false)) {
             startActivityForResult(i, 200);
           } else {
             startActivity(i);            
-          }
+          }*/
         }
-      } catch (ClassCastException e) {}
+      } catch (ClassCastException e) {} catch (FileNotFoundException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      } catch (IOException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
     }
   }
   

+ 17 - 89
src/eu/alefzero/owncloud/OwnCloudUploader.java → src/eu/alefzero/owncloud/Uploader.java

@@ -1,22 +1,8 @@
 package eu.alefzero.owncloud;
 
-import java.io.File;
-import java.sql.Date;
-import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Stack;
 
-import org.apache.http.HttpHost;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.entity.FileEntity;
-import org.apache.http.entity.mime.MultipartEntity;
-import org.apache.http.entity.mime.content.FileBody;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.protocol.BasicHttpContext;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.app.AlertDialog;
@@ -24,7 +10,6 @@ import android.app.Dialog;
 import android.app.ListActivity;
 import android.app.ProgressDialog;
 import android.app.AlertDialog.Builder;
-import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -52,10 +37,9 @@ import android.widget.AdapterView.OnItemClickListener;
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
 import eu.alefzero.owncloud.db.ProviderMeta;
 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.webdav.HttpMkCol;
 import eu.alefzero.webdav.WebdavUtils;
 
-public class OwnCloudUploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
+public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
   private static final String TAG = "ownCloudUploader";
 
   private Account mAccount;
@@ -403,91 +387,35 @@ public class OwnCloudUploader extends ListActivity implements OnItemClickListene
     }
 
     public void run() {
-      boolean any_failed = false;
-      DefaultHttpClient httpClient = new DefaultHttpClient();
-      Uri uri = Uri.parse(mAccountManager.getUserData(mAccount,
-          AccountAuthenticator.KEY_OC_URL));
-      httpClient.getCredentialsProvider().setCredentials(
-          new AuthScope(uri.getHost(), (uri.getPort() == -1) ? 80 : uri
-              .getPort()),
-          new UsernamePasswordCredentials(mUsername, mPassword));
-      BasicHttpContext httpContext = new BasicHttpContext();
-      BasicScheme basicAuth = new BasicScheme();
-      httpContext.setAttribute("preemptive-auth", basicAuth);
-      HttpHost targetHost = new HttpHost(uri.getHost(), (uri.getPort() == -1)
-          ? 80
-          : uri.getPort(), (uri.getScheme() == "https") ? "https" : "http");
+      WebdavClient wdc = new WebdavClient(Uri.parse(mAccountManager.getUserData(mAccount,
+          AccountAuthenticator.KEY_OC_URL)));
+      wdc.setCredentials(mUsername, mPassword);
+      wdc.allowUnsignedCertificates();
 
       // create last directory in path if nessesary
       if (mCreateDir) {
-        HttpMkCol method = new HttpMkCol(uri.toString() + mUploadPath + "/");
-        method.setHeader("User-Agent", "Android-ownCloud");
-        try {
-          httpClient.execute(targetHost, method, httpContext);
-          Log.i(TAG, "Creating dir completed");
-        } catch (final Exception e) {
-          e.printStackTrace();
-          mHandler.post(new Runnable() {
-            public void run() {
-              OwnCloudUploader.this.onUploadComplete(false, e.getLocalizedMessage());
-            }
-          });
-          return;
-        }
+        wdc.createDirectory(mUploadPath);
       }
       
       for (int i = 0; i < mUploadStreams.size(); ++i) {
-        final Cursor c = getContentResolver().query((Uri)mUploadStreams.get(i), null, null, null, null);
+        final Cursor c = getContentResolver().query((Uri) mUploadStreams.get(i), null, null, null, null);
         c.moveToFirst();
-
-        HttpPut method = new HttpPut(uri.toString() + mUploadPath + "/"
-            + c.getString(c.getColumnIndex(Media.DISPLAY_NAME)).replace(" ", "%20"));
-        method.setHeader("Content-type", c.getString(c.getColumnIndex(Media.MIME_TYPE)));
-        method.setHeader("User-Agent", "Android-ownCloud");
-
-        try {
-          FileBody fb = new FileBody(new File(c.getString(c.getColumnIndex(Media.DATA))), c.getString(c.getColumnIndex(Media.MIME_TYPE)));
-          MultipartEntity entity = new MultipartEntity();
-          final FileEntity fileEntity = new FileEntity(new File(c.getString(c.getColumnIndex(Media.DATA))),
-               c.getString(c.getColumnIndex(Media.MIME_TYPE)));
-
-          entity.addPart(c.getString(c.getColumnIndex(Media.DISPLAY_NAME)).replace(" ", "%20"), fb);
-
-          method.setEntity(fileEntity);
-          Log.i(TAG, "executing:" + method.getRequestLine().toString());
-
-          httpClient.execute(targetHost, method, httpContext);
-          mHandler.post(new Runnable() {
-            public void run() {
-              OwnCloudUploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),
-                                                        c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
-                                                        mUploadPath + (mUploadPath.equals("/")?"":"/"),
-                                                        fileEntity.getContentType().getValue(),
-                                                        fileEntity.getContentLength()+"");
-            }
-          });
-          Log.i(TAG, "Uploading, done");
-
-        } catch (final Exception e) {
-          any_failed = true;
+        
+        if (!wdc.putFile(c.getString(c.getColumnIndex(Media.DATA)),
+                         mUploadPath+"/"+c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
+                         c.getString(c.getColumnIndex(Media.MIME_TYPE)))) {
           mHandler.post(new Runnable() {
             public void run() {
-              OwnCloudUploader.this.onUploadComplete(false, c.getString(c.getColumnIndex(Media.DISPLAY_NAME))+ " " + e.getLocalizedMessage());
+              Uploader.this.onUploadComplete(false, "Error while uploading file: " + c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
             }
           });
         }
       }
-      if (!any_failed) {
-        mHandler.post(new Runnable() {
-          public void run() {
-            OwnCloudUploader.this.onUploadComplete(true, "Success");
-          }
-        });
-      }
-      Bundle bundle = new Bundle();
-      bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
-      //ContentResolver.requestSync(mAccount, AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
-
+      mHandler.post(new Runnable() {
+        public void run() {
+          Uploader.this.onUploadComplete(true, null);
+        }
+      });
     }
 
   }

+ 146 - 0
src/eu/alefzero/owncloud/WebdavClient.java

@@ -0,0 +1,146 @@
+package eu.alefzero.owncloud;
+
+import java.io.File;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpVersion;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.params.ConnManagerPNames;
+import org.apache.http.conn.params.ConnPerRouteBean;
+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.FileEntity;
+import org.apache.http.entity.mime.content.FileBody;
+import org.apache.http.impl.auth.BasicScheme;
+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.BasicHttpContext;
+
+import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
+import eu.alefzero.webdav.HttpMkCol;
+
+import android.net.Uri;
+import android.util.Log;
+
+public class WebdavClient {
+  private DefaultHttpClient mHttpClient;
+  private BasicHttpContext mHttpContext;
+  private HttpHost mTargetHost;
+  private SchemeRegistry mSchemeRegistry;
+  private Uri mUri;
+  final private static String TAG = "WebdavClient";
+  
+  WebdavClient(Uri uri) {
+    mUri = uri;
+    mSchemeRegistry = new SchemeRegistry();
+    setupHttpClient();
+  }
+  
+  void setCredentials(String username, String password) {
+    // determine default port for http or https
+    int targetPort = mTargetHost.getPort() == -1 ? 
+                        ( mUri.getScheme().equals("https") ? 443 : 80)
+                        : mUri.getPort();
+
+    mHttpClient.getCredentialsProvider().setCredentials(
+        new AuthScope(mUri.getHost(), targetPort), 
+        new UsernamePasswordCredentials(username, password));
+    BasicScheme basicAuth = new BasicScheme();
+    mHttpContext.setAttribute("preemptive-auth", basicAuth);
+  }
+  
+  void allowUnsignedCertificates() {
+    // https
+    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+  }
+  
+  boolean downloadFile(String filepath) {
+    return true;
+  }
+  
+  void getFileList(String dirPath) {
+    
+  }
+  
+  boolean putFile(String localFile,
+                  String remoteTarget,
+                  String contentType) {
+    boolean result = true;
+    HttpPut method = new HttpPut(mUri.toString() + remoteTarget.replace(" ", "%20"));
+    method.setHeader("Content-type", contentType);
+    method.setHeader("Host", mUri.getHost());
+    method.setHeader("User-Agent", "Android-ownCloud");
+
+    try {
+      FileBody fb = new FileBody(new File(localFile, contentType));
+      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);
+
+      method.setEntity(fileEntity);
+      Log.i(TAG, "executing:" + method.getRequestLine().toString());
+
+      mHttpClient.execute(mTargetHost, method, mHttpContext);
+      /*mHandler.post(new Runnable() {
+      public void run() {
+        Uploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),
+                                                  c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
+                                                  mUploadPath + (mUploadPath.equals("/")?"":"/"),
+                                                  fileEntity.getContentType().getValue(),
+                                                  fileEntity.getContentLength()+"");
+      }
+    });
+    Log.i(TAG, "Uploading, done");
+*/
+      Log.i(TAG, "Uploading, done");
+    } catch (final Exception e) {
+      Log.i(TAG, e.getLocalizedMessage());
+      result = false;
+    }
+    
+    return result;
+  }
+  
+  public boolean createDirectory(String path) {
+    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");
+    method.setHeader("User-Agent", "Android-ownCloud");
+    
+    try {
+      mHttpClient.execute(mTargetHost, method, mHttpContext);
+      Log.i(TAG, "Creating dir completed");
+    } catch (final Exception e) {
+      e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+  
+  private void setupHttpClient() {
+    // http scheme
+    mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+    mSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
+    
+    HttpParams params = new BasicHttpParams();
+    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
+    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
+    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
+    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+
+    mHttpContext = new BasicHttpContext();
+    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, mSchemeRegistry);
+
+    int port = mUri.getPort() == -1 ? 
+                 mUri.getScheme().equals("https") ? 443 : 80
+               : mUri.getPort();
+    
+    mTargetHost = new HttpHost(mUri.getHost(), port, mUri.getScheme());
+    
+    mHttpClient = new DefaultHttpClient(cm, params);
+  }
+}

+ 56 - 5
src/eu/alefzero/owncloud/authenticator/AuthUtils.java

@@ -22,17 +22,51 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
 
+import javax.net.SocketFactory;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import javax.security.cert.CertificateException;
+import javax.security.cert.X509Certificate;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import org.apache.commons.httpclient.auth.BasicScheme;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.HttpHead;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.conn.params.ConnManagerPNames;
+import org.apache.http.conn.params.ConnPerRouteBean;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.conn.SingleClientConnManager;
+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.BasicHttpContext;
 
+
 import android.content.Context;
 import android.os.Handler;
 import android.util.Log;
@@ -103,10 +137,25 @@ public class AuthUtils {
     sendResult(false, handler, context, "Server error: " + mResultMsg);
     return false;
   }
-
+  
   public static boolean tryGetWebdav(URL url, String username, String pwd,
                                      Handler handler, Context context) {
-    DefaultHttpClient c = new DefaultHttpClient();
+    SchemeRegistry schemeRegistry = new SchemeRegistry();
+ // http scheme
+ schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ // https scheme
+ schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+
+ HttpParams params = new BasicHttpParams();
+ params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
+ params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
+ params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+
+ ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
+    
+    DefaultHttpClient c = new DefaultHttpClient(cm, params);
+    
     c.getCredentialsProvider().setCredentials(
         new AuthScope(url.getHost(), (url.getPort() == -1)?80:url.getPort()), 
         new UsernamePasswordCredentials(username, pwd));
@@ -117,8 +166,9 @@ public class AuthUtils {
     localcontext.setAttribute("preemptive-auth", basicAuth);
     HttpHost targetHost = new HttpHost(url.getHost(), (url.getPort() == -1)
         ? 80
-        : url.getPort(), (url.getProtocol() == "https") ? "https" : "http");
+        : url.getPort(), (url.getProtocol().equals("https")) ? "https" : "http");
     HttpHead httpget = new HttpHead(url.toString());
+    httpget.setHeader("Host", url.getHost());
     HttpResponse response = null;
     try {
       response = c.execute(targetHost, httpget, localcontext);
@@ -134,6 +184,7 @@ public class AuthUtils {
       return false;
     }
     String status = response.getStatusLine().toString();
+
     status = status.split(" ")[1];
     Log.i("AuthUtils", "Status returned: " + status);
     if (status.equals("200")) {

+ 138 - 0
src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java

@@ -0,0 +1,138 @@
+package eu.alefzero.owncloud.authenticator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.scheme.LayeredSocketFactory;
+import org.apache.http.conn.scheme.SocketFactory;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+
+/**
+ * This socket factory will create ssl socket that accepts self signed
+ * certificate
+ * 
+ * @author olamy
+ * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
+ *          $
+ * @since 1.2.3
+ */
+public class EasySSLSocketFactory implements SocketFactory,
+    LayeredSocketFactory {
+
+  private SSLContext sslcontext = null;
+
+  private static SSLContext createEasySSLContext() throws IOException {
+    try {
+      SSLContext context = SSLContext.getInstance("TLS");
+      context.init(null, new TrustManager[] { new EasyX509TrustManager(
+          null) }, null);
+      return context;
+    } catch (Exception e) {
+      throw new IOException(e.getMessage());
+    }
+  }
+
+  private SSLContext getSSLContext() throws IOException {
+    if (this.sslcontext == null) {
+      this.sslcontext = createEasySSLContext();
+    }
+    return this.sslcontext;
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
+   *      java.lang.String, int, java.net.InetAddress, int,
+   *      org.apache.http.params.HttpParams)
+   */
+  public Socket connectSocket(Socket sock, String host, int port,
+      InetAddress localAddress, int localPort, HttpParams params)
+      throws IOException, UnknownHostException, ConnectTimeoutException {
+    int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
+    int soTimeout = HttpConnectionParams.getSoTimeout(params);
+
+    InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
+    SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
+
+    if ((localAddress != null) || (localPort > 0)) {
+      // we need to bind explicitly
+      if (localPort < 0) {
+        localPort = 0; // indicates "any"
+      }
+      InetSocketAddress isa = new InetSocketAddress(localAddress,
+          localPort);
+      sslsock.bind(isa);
+    }
+
+    sslsock.connect(remoteAddress, connTimeout);
+    sslsock.setSoTimeout(soTimeout);
+    return sslsock;
+
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
+   */
+  public Socket createSocket() throws IOException {
+    return getSSLContext().getSocketFactory().createSocket();
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
+   */
+  public boolean isSecure(Socket socket) throws IllegalArgumentException {
+    return true;
+  }
+
+  /**
+   * @see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket,
+   *      java.lang.String, int, boolean)
+   */
+  public Socket createSocket(Socket socket, String host, int port,
+      boolean autoClose) throws IOException, UnknownHostException {
+    return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
+  }
+
+  // -------------------------------------------------------------------
+  // javadoc in org.apache.http.conn.scheme.SocketFactory says :
+  // Both Object.equals() and Object.hashCode() must be overridden
+  // for the correct operation of some connection managers
+  // -------------------------------------------------------------------
+
+  public boolean equals(Object obj) {
+    return ((obj != null) && obj.getClass().equals(
+        EasySSLSocketFactory.class));
+  }
+
+  public int hashCode() {
+    return EasySSLSocketFactory.class.hashCode();
+  }
+
+}

+ 93 - 0
src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java

@@ -0,0 +1,93 @@
+package eu.alefzero.owncloud.authenticator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * @author olamy
+ * @version $Id: EasyX509TrustManager.java 765355 2009-04-15 20:59:07Z evenisse $
+ * @since 1.2.3
+ */
+public class EasyX509TrustManager
+    implements X509TrustManager
+{
+
+    private X509TrustManager standardTrustManager = null;
+
+    /**
+     * Constructor for EasyX509TrustManager.
+     */
+    public EasyX509TrustManager( KeyStore keystore )
+        throws NoSuchAlgorithmException, KeyStoreException
+    {
+        super();
+        TrustManagerFactory factory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
+        factory.init( keystore );
+        TrustManager[] trustmanagers = factory.getTrustManagers();
+        if ( trustmanagers.length == 0 )
+        {
+            throw new NoSuchAlgorithmException( "no trust manager found" );
+        }
+        this.standardTrustManager = (X509TrustManager) trustmanagers[0];
+    }
+
+    /**
+     * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
+     */
+    public void checkClientTrusted( X509Certificate[] certificates, String authType )
+        throws CertificateException
+    {
+        standardTrustManager.checkClientTrusted( certificates, authType );
+    }
+
+    /**
+     * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
+     */
+    public void checkServerTrusted( X509Certificate[] certificates, String authType )
+        throws CertificateException
+    {
+        if ( ( certificates != null ) && ( certificates.length == 1 ) )
+        {
+            certificates[0].checkValidity();
+        }
+        else
+        {
+            //standardTrustManager.checkServerTrusted( certificates, authType );
+        }
+    }
+
+    /**
+     * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+     */
+    public X509Certificate[] getAcceptedIssuers()
+    {
+        return this.standardTrustManager.getAcceptedIssuers();
+    }
+
+}

+ 0 - 47
src/eu/alefzero/owncloud/cp2.java

@@ -1,47 +0,0 @@
-package eu.alefzero.owncloud;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class cp2 extends ContentProvider {
-
-  @Override
-  public int delete(Uri arg0, String arg1, String[] arg2) {
-    // TODO Auto-generated method stub
-    return 0;
-  }
-
-  @Override
-  public String getType(Uri arg0) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public Uri insert(Uri arg0, ContentValues arg1) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public boolean onCreate() {
-    // TODO Auto-generated method stub
-    return false;
-  }
-
-  @Override
-  public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
-      String arg4) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  @Override
-  public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
-    // TODO Auto-generated method stub
-    return 0;
-  }
-
-}

+ 0 - 133
src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java

@@ -1,133 +0,0 @@
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import android.accounts.AccountManager;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.entity.ByteArrayEntity;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.webdav.HttpPropFind;
-
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.content.SyncResult;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.util.Log;
-
-public class ContactSyncAdapter extends AbstractOwnCloudSyncAdapter {
-
-    private static final String TAG = "ContactSyncAdapter";
-
-    public ContactSyncAdapter(Context context, boolean autoInitialize) {
-        super(context, autoInitialize);
-    }
-
-    @Override
-    public synchronized void onPerformSync(
-            Account account, 
-            Bundle extras, 
-            String authority, 
-            ContentProviderClient provider, 
-            SyncResult syncResult) {
-
-        this.setAccount(account);
-        this.setContentProvider(provider);
-
-        // TODO find all contacts on ownCloud that not synced or the sync date is behind than the last sync date
-        Cursor cursor = getContacts();
-        if (cursor != null && cursor.getCount() > 0) {
-            while (cursor.moveToNext()) {
-                String id = cursor.getString(
-                        cursor.getColumnIndex(ContactsContract.Contacts._ID));
-                String lookup = cursor.getString(
-                        cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
-
-                try {
-                    FileInputStream fis = getContactVcard(lookup);
-                    
-                    HttpPut query = new HttpPut(
-                        getUri() + 
-                        "/addressbooks/"+
-                        getAccount().name.split("@")[0]+
-                        "/default/"+
-                        lookup+
-                        ".vcf"
-                    );
-                    byte[] b = new byte[fis.available()];
-                    fis.read(b);
-                    query.setEntity(new ByteArrayEntity(b));
-                    HttpResponse response = fireRawRequest(query);
-                    if(201 != response.getStatusLine().getStatusCode()) {
-                        syncResult.stats.numIoExceptions++;
-                    }
-                    // TODO make a webdav request based on the stream
-                    // TODO send request to the ownCloud server
-                    // TODO mark the current contact as synced - where to store?
-                    fis.close();
-                } catch (IOException e) {
-                    syncResult.stats.numIoExceptions++;
-                } catch (OperationCanceledException e) {
-                    //TODO maybe to a better break here
-                    return;
-                } catch (AuthenticatorException e) {
-                    syncResult.stats.numAuthExceptions++;
-                }
-            }
-        }
-    }
-
-    protected Uri getUri() {
-        Uri uri = Uri.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_CONTACT_URL));
-        return uri;
-    }
-
-   /**
-     * Returns the vCard based on the LookupKey for Contact as Stream 
-     * 
-     * @param lookupKey
-     * @return
-     * @throws IOException
-     */
-    private FileInputStream getContactVcard(String lookupKey) throws IOException {
-        Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
-        AssetFileDescriptor fd = getContext().getContentResolver().openAssetFileDescriptor(uri, "r");
-        return fd.createInputStream();
-    }
-
-    /**
-     * Obtains the contact list.
-     *
-     * @return A cursor for for accessing the contact list.
-     */
-    private Cursor getContacts()
-    {
-        // Run query
-        Uri uri = ContactsContract.Contacts.CONTENT_URI;
-        String[] projection = new String[] {
-                ContactsContract.Contacts._ID,
-                ContactsContract.Contacts.LOOKUP_KEY
-        };
-
-        boolean showInvisible = false;
-        String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" + 
-                (showInvisible ? "0" : "1") + "'";
-        String[] selectionArgs = null;
-        String sortOrder = ContactsContract.Contacts._ID + " DESC";
-
-        return getContext().getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
-    }
-
-
-
-}

+ 0 - 31
src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java

@@ -1,31 +0,0 @@
-package eu.alefzero.owncloud.syncadapter;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class ContactSyncService extends Service {
-    private static final Object syncAdapterLock = new Object();
-    private static AbstractOwnCloudSyncAdapter concretSyncAdapter = null;
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void onCreate() {
-        synchronized (syncAdapterLock) {
-            if (concretSyncAdapter == null) {
-                concretSyncAdapter = new ContactSyncAdapter(getApplicationContext(), true);
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public IBinder onBind(Intent intent) {
-        return concretSyncAdapter.getSyncAdapterBinder();
-    }
-
-}