1 /* 2 * Copyright (C) 2009, 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.server.vpn; 18 19 import android.util.Log; 20 21 import java.io.IOException; 22 import java.io.Serializable; 23 import java.util.ArrayList; 24 import java.util.Arrays; 25 import java.util.List; 26 27 /** 28 * A helper class for managing native VPN daemons. 29 */ 30 class VpnDaemons implements Serializable { 31 static final long serialVersionUID = 1L; 32 private final String TAG = VpnDaemons.class.getSimpleName(); 33 34 private static final String MTPD = "mtpd"; 35 private static final String IPSEC = "racoon"; 36 37 private static final String L2TP = "l2tp"; 38 private static final String L2TP_PORT = "1701"; 39 40 private static final String PPTP = "pptp"; 41 private static final String PPTP_PORT = "1723"; 42 43 private static final String VPN_LINKNAME = "vpn"; 44 private static final String PPP_ARGS_SEPARATOR = ""; 45 46 private List<DaemonProxy> mDaemonList = new ArrayList<DaemonProxy>(); 47 48 public DaemonProxy startL2tp(String serverIp, String secret, 49 String username, String password) throws IOException { 50 return startMtpd(L2TP, serverIp, L2TP_PORT, secret, username, password, 51 false); 52 } 53 54 public DaemonProxy startPptp(String serverIp, String username, 55 String password, boolean encryption) throws IOException { 56 return startMtpd(PPTP, serverIp, PPTP_PORT, null, username, password, 57 encryption); 58 } 59 60 public DaemonProxy startIpsecForL2tp(String serverIp, String pskKey) 61 throws IOException { 62 DaemonProxy ipsec = startDaemon(IPSEC); 63 ipsec.sendCommand(serverIp, L2TP_PORT, pskKey); 64 return ipsec; 65 } 66 67 public DaemonProxy startIpsecForL2tp(String serverIp, String userKeyKey, 68 String userCertKey, String caCertKey) throws IOException { 69 DaemonProxy ipsec = startDaemon(IPSEC); 70 ipsec.sendCommand(serverIp, L2TP_PORT, userKeyKey, userCertKey, 71 caCertKey); 72 return ipsec; 73 } 74 75 public synchronized void stopAll() { 76 new DaemonProxy(MTPD).stop(); 77 new DaemonProxy(IPSEC).stop(); 78 } 79 80 public synchronized void closeSockets() { 81 for (DaemonProxy s : mDaemonList) s.closeControlSocket(); 82 } 83 84 public synchronized boolean anyDaemonStopped() { 85 for (DaemonProxy s : mDaemonList) { 86 if (s.isStopped()) { 87 Log.w(TAG, " VPN daemon gone: " + s.getName()); 88 return true; 89 } 90 } 91 return false; 92 } 93 94 public synchronized int getSocketError() { 95 for (DaemonProxy s : mDaemonList) { 96 int errCode = getResultFromSocket(s); 97 if (errCode != 0) return errCode; 98 } 99 return 0; 100 } 101 102 private synchronized DaemonProxy startDaemon(String daemonName) 103 throws IOException { 104 DaemonProxy daemon = new DaemonProxy(daemonName); 105 mDaemonList.add(daemon); 106 daemon.start(); 107 return daemon; 108 } 109 110 private int getResultFromSocket(DaemonProxy s) { 111 try { 112 return s.getResultFromSocket(); 113 } catch (IOException e) { 114 return -1; 115 } 116 } 117 118 private DaemonProxy startMtpd(String protocol, 119 String serverIp, String port, String secret, String username, 120 String password, boolean encryption) throws IOException { 121 ArrayList<String> args = new ArrayList<String>(); 122 args.addAll(Arrays.asList(protocol, serverIp, port)); 123 if (secret != null) args.add(secret); 124 args.add(PPP_ARGS_SEPARATOR); 125 addPppArguments(args, serverIp, username, password, encryption); 126 127 DaemonProxy mtpd = startDaemon(MTPD); 128 mtpd.sendCommand(args.toArray(new String[args.size()])); 129 return mtpd; 130 } 131 132 private static void addPppArguments(ArrayList<String> args, String serverIp, 133 String username, String password, boolean encryption) 134 throws IOException { 135 args.addAll(Arrays.asList( 136 "linkname", VPN_LINKNAME, 137 "name", username, 138 "password", password, 139 "refuse-eap", "nodefaultroute", "usepeerdns", 140 "idle", "1800", 141 "mtu", "1400", 142 "mru", "1400")); 143 if (encryption) { 144 args.add("+mppe"); 145 } 146 } 147 } 148