1 /* 2 * Copyright (C) 2012 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 #include <ctype.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <netdb.h> 21 #include <net/if.h> 22 #include <netinet/in.h> 23 #include <openssl/ssl.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <sys/wait.h> 27 28 #define LOG_TAG "Netd" 29 30 #include <android-base/stringprintf.h> 31 #include <cutils/log.h> 32 #include <cutils/sockets.h> 33 #include <logwrap/logwrap.h> 34 35 #include "Controllers.h" 36 #include "NetdConstants.h" 37 #include "IptablesRestoreController.h" 38 39 const size_t SHA256_SIZE = EVP_MD_size(EVP_sha256()); 40 41 const char * const OEM_SCRIPT_PATH = "/system/bin/oem-iptables-init.sh"; 42 const char * const ADD = "add"; 43 const char * const DEL = "del"; 44 45 int execIptablesRestoreWithOutput(IptablesTarget target, const std::string& commands, 46 std::string *output) { 47 return android::net::gCtls->iptablesRestoreCtrl.execute(target, commands, output); 48 } 49 50 int execIptablesRestore(IptablesTarget target, const std::string& commands) { 51 return execIptablesRestoreWithOutput(target, commands, nullptr); 52 } 53 54 int execIptablesRestoreCommand(IptablesTarget target, const std::string& table, 55 const std::string& command, std::string *output) { 56 std::string fullCmd = android::base::StringPrintf("*%s\n%s\nCOMMIT\n", table.c_str(), 57 command.c_str()); 58 return execIptablesRestoreWithOutput(target, fullCmd, output); 59 } 60 61 /* 62 * Check an interface name for plausibility. This should e.g. help against 63 * directory traversal. 64 */ 65 bool isIfaceName(const std::string& name) { 66 size_t i; 67 if ((name.empty()) || (name.size() > IFNAMSIZ)) { 68 return false; 69 } 70 71 /* First character must be alphanumeric */ 72 if (!isalnum(name[0])) { 73 return false; 74 } 75 76 for (i = 1; i < name.size(); i++) { 77 if (!isalnum(name[i]) && (name[i] != '_') && (name[i] != '-') && (name[i] != ':')) { 78 return false; 79 } 80 } 81 82 return true; 83 } 84 85 int parsePrefix(const char *prefix, uint8_t *family, void *address, int size, uint8_t *prefixlen) { 86 if (!prefix || !family || !address || !prefixlen) { 87 return -EFAULT; 88 } 89 90 // Find the '/' separating address from prefix length. 91 const char *slash = strchr(prefix, '/'); 92 const char *prefixlenString = slash + 1; 93 if (!slash || !*prefixlenString) 94 return -EINVAL; 95 96 // Convert the prefix length to a uint8_t. 97 char *endptr; 98 unsigned templen; 99 templen = strtoul(prefixlenString, &endptr, 10); 100 if (*endptr || templen > 255) { 101 return -EINVAL; 102 } 103 *prefixlen = templen; 104 105 // Copy the address part of the prefix to a local buffer. We have to copy 106 // because inet_pton and getaddrinfo operate on null-terminated address 107 // strings, but prefix is const and has '/' after the address. 108 std::string addressString(prefix, slash - prefix); 109 110 // Parse the address. 111 addrinfo *res; 112 addrinfo hints = { 113 .ai_flags = AI_NUMERICHOST, 114 }; 115 int ret = getaddrinfo(addressString.c_str(), NULL, &hints, &res); 116 if (ret || !res) { 117 return -EINVAL; // getaddrinfo return values are not errno values. 118 } 119 120 // Convert the address string to raw address bytes. 121 void *rawAddress; 122 int rawLength; 123 switch (res[0].ai_family) { 124 case AF_INET: { 125 if (*prefixlen > 32) { 126 return -EINVAL; 127 } 128 sockaddr_in *sin = (sockaddr_in *) res[0].ai_addr; 129 rawAddress = &sin->sin_addr; 130 rawLength = 4; 131 break; 132 } 133 case AF_INET6: { 134 if (*prefixlen > 128) { 135 return -EINVAL; 136 } 137 sockaddr_in6 *sin6 = (sockaddr_in6 *) res[0].ai_addr; 138 rawAddress = &sin6->sin6_addr; 139 rawLength = 16; 140 break; 141 } 142 default: { 143 freeaddrinfo(res); 144 return -EAFNOSUPPORT; 145 } 146 } 147 148 if (rawLength > size) { 149 freeaddrinfo(res); 150 return -ENOSPC; 151 } 152 153 *family = res[0].ai_family; 154 memcpy(address, rawAddress, rawLength); 155 freeaddrinfo(res); 156 157 return rawLength; 158 } 159 160 void blockSigpipe() { 161 sigset_t mask; 162 163 sigemptyset(&mask); 164 sigaddset(&mask, SIGPIPE); 165 if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0) 166 ALOGW("WARNING: SIGPIPE not blocked\n"); 167 } 168 169 void setCloseOnExec(const char *sock) { 170 int fd = android_get_control_socket(sock); 171 int flags = fcntl(fd, F_GETFD, 0); 172 if (flags == -1) { 173 ALOGE("Can't get fd flags for control socket %s", sock); 174 flags = 0; 175 } 176 flags |= FD_CLOEXEC; 177 if (fcntl(fd, F_SETFD, flags) == -1) { 178 ALOGE("Can't set control socket %s to FD_CLOEXEC", sock); 179 } 180 } 181