blob: 2f0500f1a68ed6be0d10e990692671197c04fcaa [file] [log] [blame]
Robert Greenwaltc4621772012-01-31 12:46:45 -08001/*
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 Albertaa1be2b2015-01-06 09:36:17 -080017#include <ctype.h>
18#include <errno.h>
Lorenzo Colitti70afde62013-03-04 17:58:40 +090019#include <fcntl.h>
Lorenzo Colittiba25df92014-06-18 00:22:17 +090020#include <netdb.h>
Dan Albertaa1be2b2015-01-06 09:36:17 -080021#include <net/if.h>
Lorenzo Colittiba25df92014-06-18 00:22:17 +090022#include <netinet/in.h>
Ben Schwartze7601812017-04-28 16:38:29 -040023#include <openssl/ssl.h>
Lorenzo Colittiba25df92014-06-18 00:22:17 +090024#include <stdlib.h>
Jeff Sharkey8e188ed2012-07-12 18:32:03 -070025#include <string.h>
Rom Lemarchand838ef642013-01-24 15:14:41 -080026#include <sys/wait.h>
Jeff Sharkey8e188ed2012-07-12 18:32:03 -070027
Jeff Sharkeybec6d042012-09-06 15:45:56 -070028#define LOG_TAG "Netd"
29
Lorenzo Colittic1306ea2017-03-27 05:52:31 +090030#include <android-base/stringprintf.h>
Lorenzo Colitti548bbd42017-08-28 23:05:12 +090031#include <cutils/sockets.h>
Logan Chien3f461482018-04-23 14:31:32 +080032#include <log/log.h>
Rom Lemarchand838ef642013-01-24 15:14:41 -080033#include <logwrap/logwrap.h>
Jeff Sharkey8e188ed2012-07-12 18:32:03 -070034
Narayan Kamatha5ace892017-01-06 15:10:02 +000035#include "Controllers.h"
Robert Greenwaltc4621772012-01-31 12:46:45 -080036#include "NetdConstants.h"
Narayan Kamatha5ace892017-01-06 15:10:02 +000037#include "IptablesRestoreController.h"
Robert Greenwaltc4621772012-01-31 12:46:45 -080038
Ben Schwartze7601812017-04-28 16:38:29 -040039const size_t SHA256_SIZE = EVP_MD_size(EVP_sha256());
40
Robert Greenwaltc4621772012-01-31 12:46:45 -080041const char * const ADD = "add";
42const char * const DEL = "del";
Jeff Sharkey8e188ed2012-07-12 18:32:03 -070043
Lorenzo Colitticd283772017-01-31 19:00:49 +090044int execIptablesRestoreWithOutput(IptablesTarget target, const std::string& commands,
45 std::string *output) {
46 return android::net::gCtls->iptablesRestoreCtrl.execute(target, commands, output);
47}
48
Lorenzo Colitti89faa342016-02-26 11:38:47 +090049int execIptablesRestore(IptablesTarget target, const std::string& commands) {
Lorenzo Colitticd283772017-01-31 19:00:49 +090050 return execIptablesRestoreWithOutput(target, commands, nullptr);
Lorenzo Colitti89faa342016-02-26 11:38:47 +090051}
52
Lorenzo Colittic1306ea2017-03-27 05:52:31 +090053int execIptablesRestoreCommand(IptablesTarget target, const std::string& table,
54 const std::string& command, std::string *output) {
55 std::string fullCmd = android::base::StringPrintf("*%s\n%s\nCOMMIT\n", table.c_str(),
56 command.c_str());
57 return execIptablesRestoreWithOutput(target, fullCmd, output);
58}
59
JP Abgrall69261cb2014-06-19 18:35:24 -070060/*
61 * Check an interface name for plausibility. This should e.g. help against
62 * directory traversal.
63 */
Joel Scherpelzbcad6612017-05-30 10:55:11 +090064bool isIfaceName(const std::string& name) {
JP Abgrall69261cb2014-06-19 18:35:24 -070065 size_t i;
Joel Scherpelzbcad6612017-05-30 10:55:11 +090066 if ((name.empty()) || (name.size() > IFNAMSIZ)) {
JP Abgrall69261cb2014-06-19 18:35:24 -070067 return false;
68 }
69
70 /* First character must be alphanumeric */
71 if (!isalnum(name[0])) {
72 return false;
73 }
74
Joel Scherpelzbcad6612017-05-30 10:55:11 +090075 for (i = 1; i < name.size(); i++) {
JP Abgrall69261cb2014-06-19 18:35:24 -070076 if (!isalnum(name[i]) && (name[i] != '_') && (name[i] != '-') && (name[i] != ':')) {
77 return false;
78 }
79 }
80
81 return true;
82}
Lorenzo Colittiba25df92014-06-18 00:22:17 +090083
84int parsePrefix(const char *prefix, uint8_t *family, void *address, int size, uint8_t *prefixlen) {
85 if (!prefix || !family || !address || !prefixlen) {
86 return -EFAULT;
87 }
88
89 // Find the '/' separating address from prefix length.
90 const char *slash = strchr(prefix, '/');
91 const char *prefixlenString = slash + 1;
92 if (!slash || !*prefixlenString)
93 return -EINVAL;
94
95 // Convert the prefix length to a uint8_t.
96 char *endptr;
97 unsigned templen;
98 templen = strtoul(prefixlenString, &endptr, 10);
99 if (*endptr || templen > 255) {
100 return -EINVAL;
101 }
102 *prefixlen = templen;
103
104 // Copy the address part of the prefix to a local buffer. We have to copy
105 // because inet_pton and getaddrinfo operate on null-terminated address
106 // strings, but prefix is const and has '/' after the address.
107 std::string addressString(prefix, slash - prefix);
108
109 // Parse the address.
110 addrinfo *res;
111 addrinfo hints = {
112 .ai_flags = AI_NUMERICHOST,
113 };
114 int ret = getaddrinfo(addressString.c_str(), NULL, &hints, &res);
115 if (ret || !res) {
116 return -EINVAL; // getaddrinfo return values are not errno values.
117 }
118
119 // Convert the address string to raw address bytes.
120 void *rawAddress;
121 int rawLength;
122 switch (res[0].ai_family) {
123 case AF_INET: {
124 if (*prefixlen > 32) {
125 return -EINVAL;
126 }
127 sockaddr_in *sin = (sockaddr_in *) res[0].ai_addr;
128 rawAddress = &sin->sin_addr;
129 rawLength = 4;
130 break;
131 }
132 case AF_INET6: {
133 if (*prefixlen > 128) {
134 return -EINVAL;
135 }
136 sockaddr_in6 *sin6 = (sockaddr_in6 *) res[0].ai_addr;
137 rawAddress = &sin6->sin6_addr;
138 rawLength = 16;
139 break;
140 }
141 default: {
142 freeaddrinfo(res);
143 return -EAFNOSUPPORT;
144 }
145 }
146
147 if (rawLength > size) {
148 freeaddrinfo(res);
149 return -ENOSPC;
150 }
151
152 *family = res[0].ai_family;
153 memcpy(address, rawAddress, rawLength);
154 freeaddrinfo(res);
155
156 return rawLength;
157}
Lorenzo Colitti839d7d62017-04-03 15:37:19 +0900158
159void blockSigpipe() {
160 sigset_t mask;
161
162 sigemptyset(&mask);
163 sigaddset(&mask, SIGPIPE);
164 if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
165 ALOGW("WARNING: SIGPIPE not blocked\n");
166}
Lorenzo Colitti548bbd42017-08-28 23:05:12 +0900167
168void setCloseOnExec(const char *sock) {
169 int fd = android_get_control_socket(sock);
170 int flags = fcntl(fd, F_GETFD, 0);
171 if (flags == -1) {
172 ALOGE("Can't get fd flags for control socket %s", sock);
173 flags = 0;
174 }
175 flags |= FD_CLOEXEC;
176 if (fcntl(fd, F_SETFD, flags) == -1) {
177 ALOGE("Can't set control socket %s to FD_CLOEXEC", sock);
178 }
179}