19ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk/** 29ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * Copyright (c) 2013, The Android Open Source Project 39ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * 49ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 59ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * you may not use this file except in compliance with the License. 69ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * You may obtain a copy of the License at 79ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * 89ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 99ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * 109ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * Unless required by applicable law or agreed to in writing, software 119ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 129ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * See the License for the specific language governing permissions and 149ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk * limitations under the License. 159ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk */ 169ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkpackage com.android.pacprocessor; 179ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 189ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.app.Service; 199ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.content.Intent; 209ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.os.Binder; 219ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.os.IBinder; 229ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.os.Process; 239ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.os.RemoteException; 249ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport android.util.Log; 259ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 269ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkimport com.android.net.IProxyService; 279ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 287a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monkimport java.net.MalformedURLException; 297a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monkimport java.net.URL; 307a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk 319ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monkpublic class PacService extends Service { 329ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private static final String TAG = "PacService"; 339ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 349ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private PacNative mPacNative; 359ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private ProxyServiceStub mStub; 369ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 379ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 389ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void onCreate() { 399ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk super.onCreate(); 409ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (mPacNative == null) { 419ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative = new PacNative(); 429ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mStub = new ProxyServiceStub(mPacNative); 439ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 449ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 459ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 469ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 479ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void onDestroy() { 489ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk super.onDestroy(); 499ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (mPacNative != null) { 509ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative.stopPacSupport(); 519ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative = null; 529ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mStub = null; 539ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 549ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 559ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 569ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 579ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public IBinder onBind(Intent intent) { 589ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (mPacNative == null) { 599ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative = new PacNative(); 609ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mStub = new ProxyServiceStub(mPacNative); 619ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 629ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk return mStub; 639ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 649ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 659ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private static class ProxyServiceStub extends IProxyService.Stub { 669ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk private final PacNative mPacNative; 679ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 689ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public ProxyServiceStub(PacNative pacNative) { 699ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative = pacNative; 709ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 719ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 729ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 739ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public String resolvePacFile(String host, String url) throws RemoteException { 747a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk try { 7544c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov if (host == null) { 7644c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov throw new IllegalArgumentException("The host must not be null"); 7744c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov } 7844c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov if (url == null) { 7944c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov throw new IllegalArgumentException("The URL must not be null"); 8044c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov } 817a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk // Check for characters that could be used for an injection attack. 827a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk new URL(url); 837a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk for (char c : host.toCharArray()) { 847a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk if (!Character.isLetterOrDigit(c) && (c != '.') && (c != '-')) { 8544c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov throw new IllegalArgumentException("Invalid host was passed"); 867a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk } 877a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk } 887a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk return mPacNative.makeProxyRequest(url, host); 897a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk } catch (MalformedURLException e) { 9044c02590374bda5928669be0d14110b12c271461Andrei Kapishnikov throw new IllegalArgumentException("Invalid URL was passed"); 917a6af1c09306fa833d11f5ffd100eff7b1a35a4cJason Monk } 929ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 939ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 949ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 959ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void setPacFile(String script) throws RemoteException { 969ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (Binder.getCallingUid() != Process.SYSTEM_UID) { 979ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.e(TAG, "Only system user is allowed to call setPacFile"); 989ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk throw new SecurityException(); 999ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1009ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative.setCurrentProxyScript(script); 1019ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1029ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 1039ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 1049ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void startPacSystem() throws RemoteException { 1059ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (Binder.getCallingUid() != Process.SYSTEM_UID) { 1069ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.e(TAG, "Only system user is allowed to call startPacSystem"); 1079ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk throw new SecurityException(); 1089ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1099ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative.startPacSupport(); 1109ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1119ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk 1129ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk @Override 1139ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk public void stopPacSystem() throws RemoteException { 1149ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk if (Binder.getCallingUid() != Process.SYSTEM_UID) { 1159ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk Log.e(TAG, "Only system user is allowed to call stopPacSystem"); 1169ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk throw new SecurityException(); 1179ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1189ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk mPacNative.stopPacSupport(); 1199ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1209ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk } 1219ced3cd9d6ea414523051ec872fffc68f5fdbf08Jason Monk} 122