1/**
2 * Copyright (c) 2013, 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 */
16package com.android.pacprocessor;
17
18import android.app.Service;
19import android.content.Intent;
20import android.os.Binder;
21import android.os.IBinder;
22import android.os.Process;
23import android.os.RemoteException;
24import android.util.Log;
25
26import com.android.net.IProxyService;
27
28import java.net.MalformedURLException;
29import java.net.URL;
30
31public class PacService extends Service {
32    private static final String TAG = "PacService";
33
34    private PacNative mPacNative;
35    private ProxyServiceStub mStub;
36
37    @Override
38    public void onCreate() {
39        super.onCreate();
40        if (mPacNative == null) {
41            mPacNative = new PacNative();
42            mStub = new ProxyServiceStub(mPacNative);
43        }
44    }
45
46    @Override
47    public void onDestroy() {
48        super.onDestroy();
49        if (mPacNative != null) {
50            mPacNative.stopPacSupport();
51            mPacNative = null;
52            mStub = null;
53        }
54    }
55
56    @Override
57    public IBinder onBind(Intent intent) {
58        if (mPacNative == null) {
59            mPacNative = new PacNative();
60            mStub = new ProxyServiceStub(mPacNative);
61        }
62        return mStub;
63    }
64
65    private static class ProxyServiceStub extends IProxyService.Stub {
66        private final PacNative mPacNative;
67
68        public ProxyServiceStub(PacNative pacNative) {
69            mPacNative = pacNative;
70        }
71
72        @Override
73        public String resolvePacFile(String host, String url) throws RemoteException {
74            try {
75                if (host == null) {
76                    throw new IllegalArgumentException("The host must not be null");
77                }
78                if (url == null) {
79                    throw new IllegalArgumentException("The URL must not be null");
80                }
81                // Check for characters that could be used for an injection attack.
82                new URL(url);
83                for (char c : host.toCharArray()) {
84                    if (!Character.isLetterOrDigit(c) && (c != '.') && (c != '-')) {
85                        throw new IllegalArgumentException("Invalid host was passed");
86                    }
87                }
88                return mPacNative.makeProxyRequest(url, host);
89            } catch (MalformedURLException e) {
90                throw new IllegalArgumentException("Invalid URL was passed");
91            }
92        }
93
94        @Override
95        public void setPacFile(String script) throws RemoteException {
96            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
97                Log.e(TAG, "Only system user is allowed to call setPacFile");
98                throw new SecurityException();
99            }
100            mPacNative.setCurrentProxyScript(script);
101        }
102
103        @Override
104        public void startPacSystem() throws RemoteException {
105            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
106                Log.e(TAG, "Only system user is allowed to call startPacSystem");
107                throw new SecurityException();
108            }
109            mPacNative.startPacSupport();
110        }
111
112        @Override
113        public void stopPacSystem() throws RemoteException {
114            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
115                Log.e(TAG, "Only system user is allowed to call stopPacSystem");
116                throw new SecurityException();
117            }
118            mPacNative.stopPacSupport();
119        }
120    }
121}
122