1 /* 2 * Copyright (C) 2011 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 com.android.emailcommon.provider; 18 19 import android.os.Parcel; 20 import android.test.AndroidTestCase; 21 import android.test.mock.MockContext; 22 import android.test.suitebuilder.annotation.SmallTest; 23 24 import org.json.JSONException; 25 import org.json.JSONObject; 26 27 import java.util.Arrays; 28 29 /** 30 * Unit tests for the HostAuth inner class. 31 * These tests must be locally complete - no server(s) required. 32 */ 33 @SmallTest 34 public class HostAuthTests extends AndroidTestCase { 35 36 /** 37 * Test user name and password are set correctly 38 */ testSetLogin()39 public void testSetLogin() { 40 HostAuth ha = new HostAuth(); 41 ha.setLogin("user:password"); 42 assertEquals("user", ha.mLogin); 43 assertEquals("password", ha.mPassword); 44 45 // special characters are not removed during insertion 46 ha.setLogin("%20us%20er%20:password"); 47 assertEquals("%20us%20er%20", ha.mLogin); 48 assertEquals("password", ha.mPassword); 49 50 // special characters are not removed during insertion 51 ha.setLogin("user:%20pass%20word%20"); 52 assertEquals("user", ha.mLogin); 53 assertEquals("%20pass%20word%20", ha.mPassword); 54 55 ha.setLogin("user:"); 56 assertEquals("user", ha.mLogin); 57 assertEquals("", ha.mPassword); 58 59 ha.setLogin(":password"); 60 assertEquals("", ha.mLogin); 61 assertEquals("password", ha.mPassword); 62 63 ha.setLogin(""); 64 assertNull(ha.mLogin); 65 assertNull(ha.mPassword); 66 67 ha.setLogin(null); 68 assertNull(ha.mLogin); 69 assertNull(ha.mPassword); 70 71 ha.setLogin("userpassword"); 72 assertEquals("userpassword", ha.mLogin); 73 assertNull(ha.mPassword); 74 } 75 76 /** 77 * Test the authentication flag is set correctly when setting user name and password 78 */ testSetLoginAuthenticate()79 public void testSetLoginAuthenticate() { 80 HostAuth ha = new HostAuth(); 81 82 ha.mFlags = 0x00000000; 83 ha.setLogin("user", "password"); 84 assertEquals(HostAuth.FLAG_AUTHENTICATE, ha.mFlags); 85 86 ha.mFlags = 0x00000000; 87 ha.setLogin("user", ""); 88 assertEquals(HostAuth.FLAG_AUTHENTICATE, ha.mFlags); 89 90 ha.mFlags = 0xffffffff; 91 ha.setLogin("", "password"); 92 assertEquals(~HostAuth.FLAG_AUTHENTICATE, ha.mFlags); 93 94 ha.mFlags = 0x00000000; 95 ha.setLogin("user", null); 96 assertEquals(HostAuth.FLAG_AUTHENTICATE, ha.mFlags); 97 98 ha.mFlags = 0xffffffff; 99 ha.setLogin(null, "password"); 100 assertEquals(~HostAuth.FLAG_AUTHENTICATE, ha.mFlags); 101 102 ha.mFlags = 0xffffffff; 103 ha.setLogin(null, null); 104 assertEquals(~HostAuth.FLAG_AUTHENTICATE, ha.mFlags); 105 } 106 107 /** 108 * Test setting the connection using a protocol and flags 109 */ testSetConnectionFlags()110 public void testSetConnectionFlags() { 111 HostAuth ha = new HostAuth(); 112 113 // Different port types don't affect flags 114 ha.setConnection("imap", "server", 123, 0); 115 assertEquals(0, ha.mFlags); 116 ha.setConnection("imap", "server", -1, 0); 117 assertEquals(0, ha.mFlags); 118 119 // Different protocol types don't affect flags 120 ha.setConnection("pop3", "server", 123, 0); 121 assertEquals(0, ha.mFlags); 122 ha.setConnection("pop3", "server", -1, 0); 123 assertEquals(0, ha.mFlags); 124 ha.setConnection("eas", "server", 123, 0); 125 assertEquals(0, ha.mFlags); 126 ha.setConnection("eas", "server", -1, 0); 127 assertEquals(0, ha.mFlags); 128 ha.setConnection("smtp", "server", 123, 0); 129 assertEquals(0, ha.mFlags); 130 ha.setConnection("smtp", "server", -1, 0); 131 assertEquals(0, ha.mFlags); 132 133 // Sets SSL flag 134 ha.setConnection("imap", "server", HostAuth.PORT_UNKNOWN, HostAuth.FLAG_SSL); 135 assertEquals(HostAuth.FLAG_SSL, ha.mFlags); 136 137 // Sets SSL+Trusted flags 138 ha.setConnection("imap", "server", HostAuth.PORT_UNKNOWN, 139 HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL); 140 assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, ha.mFlags); 141 142 // Sets TLS flag 143 ha.setConnection("imap", "server", HostAuth.PORT_UNKNOWN, HostAuth.FLAG_TLS); 144 assertEquals(HostAuth.FLAG_TLS, ha.mFlags); 145 146 // Sets TLS+Trusted flags 147 ha.setConnection("imap", "server", HostAuth.PORT_UNKNOWN, 148 HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL); 149 assertEquals(HostAuth.FLAG_TLS | HostAuth.FLAG_TRUST_ALL, ha.mFlags); 150 151 // Test other defined flags; should not affect mFlags 152 ha.setConnection("imap", "server", HostAuth.PORT_UNKNOWN, HostAuth.FLAG_AUTHENTICATE); 153 assertEquals(0, ha.mFlags); 154 155 // Test every other bit; should not affect mFlags 156 // mFlag is evalutated to the following: 157 // mFlag = (0 & (some operation)) | (0xfffffff4 & 0x1b) 158 // mFlag = 0 | 0x10 159 // mFlag = 0x10 160 ha.setConnection("imap", "server", HostAuth.PORT_UNKNOWN, 0xfffffff4); 161 assertEquals(0x10, ha.mFlags); 162 } 163 testSetConnectionWithCerts()164 public void testSetConnectionWithCerts() { 165 HostAuth ha = new HostAuth(); 166 167 ha.setConnection("eas", "server", HostAuth.PORT_UNKNOWN, HostAuth.FLAG_SSL, "client-cert"); 168 assertEquals(HostAuth.FLAG_SSL, ha.mFlags); 169 assertEquals("client-cert", ha.mClientCertAlias); 170 171 ha.setConnection("eas", "server", HostAuth.PORT_UNKNOWN, HostAuth.FLAG_TLS, "client-cert"); 172 assertEquals(HostAuth.FLAG_TLS, ha.mFlags); 173 assertEquals("client-cert", ha.mClientCertAlias); 174 175 // Note that we can still trust all server certificates, even if we present a client 176 // user certificate. 177 ha.setConnection("eas", "server", HostAuth.PORT_UNKNOWN, 178 HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, "client-cert"); 179 assertEquals(HostAuth.FLAG_SSL | HostAuth.FLAG_TRUST_ALL, ha.mFlags); 180 assertEquals("client-cert", ha.mClientCertAlias); 181 182 try { 183 ha.setConnection( 184 "eas", "server", HostAuth.PORT_UNKNOWN, 0 /* no flags */, "client-cert"); 185 fail("Shouldn't be able to set a client certificate on an unsecure connection"); 186 } catch (IllegalArgumentException expected) { 187 // ignore 188 } 189 } 190 testParceling()191 public void testParceling() { 192 final HostAuth orig = new HostAuth(); 193 // Fill in some data 194 orig.mPort = 993; 195 orig.mProtocol = "imap"; 196 orig.mAddress = "example.com"; 197 orig.mLogin = "user"; 198 orig.mPassword = "supersecret"; 199 orig.mDomain = "domain"; 200 orig.mClientCertAlias = "certalias"; 201 202 final Parcel p1 = Parcel.obtain(); 203 orig.writeToParcel(p1, 0); 204 p1.setDataPosition(0); 205 final HostAuth unparceled1 = new HostAuth(p1); 206 p1.recycle(); 207 assertEquals(orig, unparceled1); 208 assertEquals(orig.mCredentialKey, unparceled1.mCredentialKey); 209 assertEquals(orig.mCredential, unparceled1.mCredential); 210 211 orig.getOrCreateCredential(new MockContext()); 212 213 final Parcel p2 = Parcel.obtain(); 214 orig.writeToParcel(p2, 0); 215 p2.setDataPosition(0); 216 final HostAuth unparceled2 = new HostAuth(p2); 217 p2.recycle(); 218 assertEquals(orig, unparceled2); 219 assertEquals(orig.mCredentialKey, unparceled2.mCredentialKey); 220 assertEquals(orig.mCredential, unparceled2.mCredential); 221 } 222 testDeserializeFromJSON()223 public void testDeserializeFromJSON() throws JSONException { 224 final JSONObject json = new JSONObject(); 225 json.put(EmailContent.HostAuthColumns.PROTOCOL, "IMAP"); 226 json.put(EmailContent.HostAuthColumns.ADDRESS, "dhoff@example.com"); 227 json.put(EmailContent.HostAuthColumns.PORT, 1337); 228 json.put(EmailContent.HostAuthColumns.FLAGS, 293847); 229 json.put(EmailContent.HostAuthColumns.LOGIN, "dhoff"); 230 json.put(EmailContent.HostAuthColumns.PASSWORD, "daknightrida"); 231 json.put(EmailContent.HostAuthColumns.DOMAIN, "example.com"); 232 json.put(EmailContent.HostAuthColumns.CLIENT_CERT_ALIAS, "I'm a client cert alias"); 233 json.put(HostAuth.JSON_TAG_CREDENTIAL, Credential.EMPTY.toJson()); 234 235 // deserialize the json 236 final HostAuth ha = HostAuth.fromJson(json); 237 238 // verify that all fields deserialized as expected 239 assertEquals("IMAP", ha.mProtocol); 240 assertEquals("dhoff@example.com", ha.mAddress); 241 assertEquals(1337, ha.mPort); 242 assertEquals(293847, ha.mFlags); 243 assertEquals("dhoff", ha.mLogin); 244 assertEquals("daknightrida", ha.mPassword); 245 assertEquals("example.com", ha.mDomain); 246 assertEquals("I'm a client cert alias", ha.mClientCertAlias); 247 assertEquals(Credential.EMPTY, ha.mCredential); 248 249 assertNull(ha.mServerCert); // server cert is not serialized; field defaults to null 250 assertEquals(-1, ha.mCredentialKey); // cred key is not serialized; field defaults to -1 251 } 252 testSerializeAndDeserializeWithJSON()253 public void testSerializeAndDeserializeWithJSON() { 254 final HostAuth before = new HostAuth(); 255 before.mProtocol = "IMAP"; 256 before.mAddress = "dhoff@example.com"; 257 before.mPort = 1337; 258 before.mFlags = 293847; 259 before.setLogin("dhoff", "daknightrida"); 260 before.mDomain = "example.com"; 261 before.mClientCertAlias = "I'm a client cert alias"; 262 before.mServerCert = new byte[] {(byte) 0xFF, (byte) 0xAA}; 263 before.mCredentialKey = 9873425; 264 before.mCredential = Credential.EMPTY; 265 266 // this must be called before serialization occurs 267 before.ensureLoaded(getContext()); 268 269 // serialize and deserialize 270 final HostAuth after = HostAuth.fromJson(before.toJson()); 271 272 assertEquals(before.mProtocol, after.mProtocol); 273 assertEquals(before.mAddress, after.mAddress); 274 assertEquals(before.mPort, after.mPort); 275 assertEquals(before.mFlags, after.mFlags); 276 assertTrue(Arrays.equals(before.getLogin(), after.getLogin())); 277 assertEquals(before.mDomain, after.mDomain); 278 assertEquals(before.mClientCertAlias, after.mClientCertAlias); 279 assertEquals(before.mCredential, after.mCredential); 280 281 assertNull(after.mServerCert); // server cert is not serialized; field defaults to null 282 assertEquals(-1, after.mCredentialKey); // cred key is not serialized; field defaults to 0 283 } 284 } 285 286