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  */
16 
17 package com.android.settings.vpn2;
18 
19 import android.util.Log;
20 
21 import com.android.internal.net.VpnProfile;
22 
23 import org.xml.sax.Attributes;
24 import org.xml.sax.SAXException;
25 import org.xml.sax.helpers.DefaultHandler;
26 
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.util.HashMap;
30 import java.util.Map;
31 
32 import javax.xml.parsers.ParserConfigurationException;
33 import javax.xml.parsers.SAXParser;
34 import javax.xml.parsers.SAXParserFactory;
35 
36 /**
37  * Parse VPN profiles from an XML file
38  */
39 public class VpnProfileParser {
40     private final static String TAG = "VpnProfileParser";
41     private static Map<Integer, VpnInfo> mVpnPool = new HashMap<Integer, VpnInfo>();
42 
43     static DefaultHandler mHandler = new DefaultHandler() {
44         boolean name;
45         boolean type;
46         boolean server;
47         boolean username;
48         boolean password;
49         boolean dnsServers;
50         boolean searchDomains;
51         boolean routes;
52         boolean mppe;
53         boolean l2tpSecret;
54         boolean ipsecIdentifier;
55         boolean ipsecSecret;
56         boolean ipsecUserCert;
57         boolean ipsecCaCert;
58         boolean ipsecServerCert;
59         boolean certFile;
60         boolean certFilePassword;
61         VpnProfile profile = null;
62         VpnInfo vpnInfo = null;
63 
64 
65         @Override
66         public void startElement(String uri, String localName, String tagName,
67                 Attributes attributes) throws SAXException {
68             if (tagName.equalsIgnoreCase("vpn")) {
69                 //create a new VPN profile
70                 profile = new VpnProfile(Long.toHexString(System.currentTimeMillis()));
71                 vpnInfo = new VpnInfo(profile);
72             }
73             if (tagName.equalsIgnoreCase("name")) {
74                 name = true;
75             }
76             if (tagName.equalsIgnoreCase("type")) {
77                 type = true;
78             }
79             if (tagName.equalsIgnoreCase("server")) {
80                 server = true;
81             }
82             if (tagName.equalsIgnoreCase("username")) {
83                 username = true;
84             }
85             if (tagName.equalsIgnoreCase("password")) {
86                 password = true;
87             }
88             if (tagName.equalsIgnoreCase("dnsServers")) {
89                 dnsServers = true;
90             }
91             if (tagName.equalsIgnoreCase("searchDomains")) {
92                 searchDomains = true;
93             }
94             if (tagName.equalsIgnoreCase("mppe")) {
95                 mppe = true;
96             }
97             if (tagName.equalsIgnoreCase("l2tpSecret")) {
98                 l2tpSecret = true;
99             }
100             if (tagName.equalsIgnoreCase("ipsecIdentifier")) {
101                 ipsecIdentifier = true;
102             }
103             if (tagName.equalsIgnoreCase("ipsecSecret")) {
104                 ipsecSecret = true;
105             }
106             if (tagName.equalsIgnoreCase("ipsecUserCert")) {
107                 ipsecUserCert = true;
108             }
109             if (tagName.equalsIgnoreCase("ipsecCaCert")) {
110                 ipsecCaCert = true;
111             }
112             if (tagName.equalsIgnoreCase("ipsecServerCert")) {
113                 ipsecServerCert = true;
114             }
115             if (tagName.equalsIgnoreCase("routes")) {
116                 routes = true;
117             }
118             if (tagName.equalsIgnoreCase("cert-file")) {
119                 certFile = true;
120             }
121             if (tagName.equalsIgnoreCase("cert-file-password")) {
122                 certFilePassword = true;
123             }
124         }
125 
126         @Override
127         public void endElement(String uri, String localName, String tagName) throws SAXException {
128             if (tagName.equalsIgnoreCase("vpn")) {
129                 mVpnPool.put(profile.type, vpnInfo);
130             }
131         }
132 
133         @Override
134         public void characters(char ch[], int start, int length) throws SAXException {
135             String strValue = new String(ch, start, length);
136             if (name) {
137                 profile.name = strValue;
138                 name = false;
139             }
140             if (type) {
141                 int t = getVpnProfileType(strValue);
142                 if (t < 0) {
143                     throw new SAXException("not a valid VPN type");
144                 } else {
145                     profile.type = t;
146                 }
147                 type = false;
148             }
149             if (server) {
150                 profile.server = strValue;
151                 server = false;
152             }
153             if (username) {
154                 profile.username = strValue;
155                 username = false;
156             }
157             if (password) {
158                 profile.password = strValue;
159                 password = false;
160             }
161             if (dnsServers) {
162                 profile.dnsServers = strValue;
163                 dnsServers = false;
164             }
165             if (searchDomains) {
166                 profile.searchDomains = strValue;
167                 searchDomains = false;
168             }
169             if (mppe) {
170                 profile.mppe = Boolean.valueOf(strValue);
171                 mppe = false;
172             }
173             if (l2tpSecret) {
174                 profile.l2tpSecret = strValue;
175                 l2tpSecret = false;
176             }
177             if (ipsecIdentifier) {
178                 profile.ipsecIdentifier = strValue;
179                 ipsecIdentifier = false;
180             }
181             if (ipsecSecret) {
182                 profile.ipsecSecret = strValue;
183                 ipsecSecret = false;
184             }
185             if (ipsecUserCert) {
186                 profile.ipsecUserCert = strValue;
187                 ipsecUserCert = false;
188             }
189             if (ipsecCaCert) {
190                 profile.ipsecCaCert = strValue;
191                 ipsecCaCert = false;
192             }
193             if (ipsecServerCert) {
194                 profile.ipsecServerCert = strValue;
195                 ipsecServerCert = false;
196             }
197             if (routes) {
198                 profile.routes = strValue;
199                 routes = false;
200             }
201             if (certFile) {
202                 vpnInfo.setCertificateFile(strValue);
203                 certFile = false;
204             }
205             if (certFilePassword) {
206                 vpnInfo.setPassword(strValue);
207                 certFilePassword = false;
208             }
209         }
210 
211         private int getVpnProfileType(String type) {
212             if (type.equalsIgnoreCase("TYPE_PPTP")) {
213                 return VpnProfile.TYPE_PPTP;
214             } else if (type.equalsIgnoreCase("TYPE_L2TP_IPSEC_PSK")) {
215                 return VpnProfile.TYPE_L2TP_IPSEC_PSK;
216             } else if (type.equalsIgnoreCase("TYPE_L2TP_IPSEC_RSA")) {
217                 return VpnProfile.TYPE_L2TP_IPSEC_RSA;
218             } else if (type.equalsIgnoreCase("TYPE_IPSEC_XAUTH_PSK")) {
219                 return VpnProfile.TYPE_IPSEC_XAUTH_PSK;
220             } else if (type.equalsIgnoreCase("TYPE_IPSEC_XAUTH_RSA")) {
221                 return VpnProfile.TYPE_IPSEC_XAUTH_RSA;
222             } else if (type.equalsIgnoreCase("TYPE_IPSEC_HYBRID_RSA")) {
223                 return VpnProfile.TYPE_IPSEC_HYBRID_RSA;
224             } else {
225                 Log.v(TAG, "Invalid VPN type: " + type);
226                 return -1;
227             }
228         }
229     };
230 
parse(InputStream in)231     public static Map<Integer, VpnInfo> parse(InputStream in) {
232         try {
233             SAXParserFactory factory = SAXParserFactory.newInstance();
234             SAXParser saxParser = factory.newSAXParser();
235             saxParser.parse(in, mHandler);
236         } catch (SAXException e) {
237             Log.e(TAG, "Parse vpn profile exception: " + e.toString());
238         } catch (IOException e) {
239             Log.e(TAG, "Parse vpn profile exception: " + e.toString());
240         } catch (ParserConfigurationException e) {
241             Log.e(TAG, "Parse vpn profile exception: " + e.toString());
242         } finally {
243             return mVpnPool;
244         }
245     }
246 }
247