Robert Greenwalt | c462177 | 2012-01-31 12:46:45 -0800 | [diff] [blame] | 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 | |
Dan Albert | aa1be2b | 2015-01-06 09:36:17 -0800 | [diff] [blame] | 17 | #include <ctype.h> |
| 18 | #include <errno.h> |
Lorenzo Colitti | 70afde6 | 2013-03-04 17:58:40 +0900 | [diff] [blame] | 19 | #include <fcntl.h> |
Lorenzo Colitti | ba25df9 | 2014-06-18 00:22:17 +0900 | [diff] [blame] | 20 | #include <netdb.h> |
Dan Albert | aa1be2b | 2015-01-06 09:36:17 -0800 | [diff] [blame] | 21 | #include <net/if.h> |
Lorenzo Colitti | ba25df9 | 2014-06-18 00:22:17 +0900 | [diff] [blame] | 22 | #include <netinet/in.h> |
Ben Schwartz | e760181 | 2017-04-28 16:38:29 -0400 | [diff] [blame] | 23 | #include <openssl/ssl.h> |
Lorenzo Colitti | ba25df9 | 2014-06-18 00:22:17 +0900 | [diff] [blame] | 24 | #include <stdlib.h> |
Jeff Sharkey | 8e188ed | 2012-07-12 18:32:03 -0700 | [diff] [blame] | 25 | #include <string.h> |
Rom Lemarchand | 838ef64 | 2013-01-24 15:14:41 -0800 | [diff] [blame] | 26 | #include <sys/wait.h> |
Jeff Sharkey | 8e188ed | 2012-07-12 18:32:03 -0700 | [diff] [blame] | 27 | |
Jeff Sharkey | bec6d04 | 2012-09-06 15:45:56 -0700 | [diff] [blame] | 28 | #define LOG_TAG "Netd" |
| 29 | |
Lorenzo Colitti | c1306ea | 2017-03-27 05:52:31 +0900 | [diff] [blame] | 30 | #include <android-base/stringprintf.h> |
Lorenzo Colitti | 548bbd4 | 2017-08-28 23:05:12 +0900 | [diff] [blame] | 31 | #include <cutils/sockets.h> |
Logan Chien | 3f46148 | 2018-04-23 14:31:32 +0800 | [diff] [blame^] | 32 | #include <log/log.h> |
Rom Lemarchand | 838ef64 | 2013-01-24 15:14:41 -0800 | [diff] [blame] | 33 | #include <logwrap/logwrap.h> |
Jeff Sharkey | 8e188ed | 2012-07-12 18:32:03 -0700 | [diff] [blame] | 34 | |
Narayan Kamath | a5ace89 | 2017-01-06 15:10:02 +0000 | [diff] [blame] | 35 | #include "Controllers.h" |
Robert Greenwalt | c462177 | 2012-01-31 12:46:45 -0800 | [diff] [blame] | 36 | #include "NetdConstants.h" |
Narayan Kamath | a5ace89 | 2017-01-06 15:10:02 +0000 | [diff] [blame] | 37 | #include "IptablesRestoreController.h" |
Robert Greenwalt | c462177 | 2012-01-31 12:46:45 -0800 | [diff] [blame] | 38 | |
Ben Schwartz | e760181 | 2017-04-28 16:38:29 -0400 | [diff] [blame] | 39 | const size_t SHA256_SIZE = EVP_MD_size(EVP_sha256()); |
| 40 | |
Robert Greenwalt | c462177 | 2012-01-31 12:46:45 -0800 | [diff] [blame] | 41 | const char * const OEM_SCRIPT_PATH = "/system/bin/oem-iptables-init.sh"; |
Robert Greenwalt | c462177 | 2012-01-31 12:46:45 -0800 | [diff] [blame] | 42 | const char * const ADD = "add"; |
| 43 | const char * const DEL = "del"; |
Jeff Sharkey | 8e188ed | 2012-07-12 18:32:03 -0700 | [diff] [blame] | 44 | |
Lorenzo Colitti | cd28377 | 2017-01-31 19:00:49 +0900 | [diff] [blame] | 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 | |
Lorenzo Colitti | 89faa34 | 2016-02-26 11:38:47 +0900 | [diff] [blame] | 50 | int execIptablesRestore(IptablesTarget target, const std::string& commands) { |
Lorenzo Colitti | cd28377 | 2017-01-31 19:00:49 +0900 | [diff] [blame] | 51 | return execIptablesRestoreWithOutput(target, commands, nullptr); |
Lorenzo Colitti | 89faa34 | 2016-02-26 11:38:47 +0900 | [diff] [blame] | 52 | } |
| 53 | |
Lorenzo Colitti | c1306ea | 2017-03-27 05:52:31 +0900 | [diff] [blame] | 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 | |
JP Abgrall | 69261cb | 2014-06-19 18:35:24 -0700 | [diff] [blame] | 61 | /* |
| 62 | * Check an interface name for plausibility. This should e.g. help against |
| 63 | * directory traversal. |
| 64 | */ |
Joel Scherpelz | bcad661 | 2017-05-30 10:55:11 +0900 | [diff] [blame] | 65 | bool isIfaceName(const std::string& name) { |
JP Abgrall | 69261cb | 2014-06-19 18:35:24 -0700 | [diff] [blame] | 66 | size_t i; |
Joel Scherpelz | bcad661 | 2017-05-30 10:55:11 +0900 | [diff] [blame] | 67 | if ((name.empty()) || (name.size() > IFNAMSIZ)) { |
JP Abgrall | 69261cb | 2014-06-19 18:35:24 -0700 | [diff] [blame] | 68 | return false; |
| 69 | } |
| 70 | |
| 71 | /* First character must be alphanumeric */ |
| 72 | if (!isalnum(name[0])) { |
| 73 | return false; |
| 74 | } |
| 75 | |
Joel Scherpelz | bcad661 | 2017-05-30 10:55:11 +0900 | [diff] [blame] | 76 | for (i = 1; i < name.size(); i++) { |
JP Abgrall | 69261cb | 2014-06-19 18:35:24 -0700 | [diff] [blame] | 77 | if (!isalnum(name[i]) && (name[i] != '_') && (name[i] != '-') && (name[i] != ':')) { |
| 78 | return false; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | return true; |
| 83 | } |
Lorenzo Colitti | ba25df9 | 2014-06-18 00:22:17 +0900 | [diff] [blame] | 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 | } |
Lorenzo Colitti | 839d7d6 | 2017-04-03 15:37:19 +0900 | [diff] [blame] | 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 | } |
Lorenzo Colitti | 548bbd4 | 2017-08-28 23:05:12 +0900 | [diff] [blame] | 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 | } |