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                // Check for characters that could be used for an injection attack.
76                new URL(url);
77                for (char c : host.toCharArray()) {
78                    if (!Character.isLetterOrDigit(c) && (c != '.') && (c != '-')) {
79                        throw new RemoteException("Invalid host was passed");
80                    }
81                }
82                return mPacNative.makeProxyRequest(url, host);
83            } catch (MalformedURLException e) {
84                throw new RemoteException("Invalid URL was passed");
85            }
86        }
87
88        @Override
89        public void setPacFile(String script) throws RemoteException {
90            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
91                Log.e(TAG, "Only system user is allowed to call setPacFile");
92                throw new SecurityException();
93            }
94            mPacNative.setCurrentProxyScript(script);
95        }
96
97        @Override
98        public void startPacSystem() throws RemoteException {
99            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
100                Log.e(TAG, "Only system user is allowed to call startPacSystem");
101                throw new SecurityException();
102            }
103            mPacNative.startPacSupport();
104        }
105
106        @Override
107        public void stopPacSystem() throws RemoteException {
108            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
109                Log.e(TAG, "Only system user is allowed to call stopPacSystem");
110                throw new SecurityException();
111            }
112            mPacNative.stopPacSupport();
113        }
114    }
115}
116