network_library.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/android/network_library.h"
  5. #include <dlfcn.h>
  6. #include <string>
  7. #include <vector>
  8. #include "base/android/build_info.h"
  9. #include "base/android/jni_android.h"
  10. #include "base/android/jni_array.h"
  11. #include "base/android/jni_string.h"
  12. #include "base/android/scoped_java_ref.h"
  13. #include "base/check_op.h"
  14. #include "base/native_library.h"
  15. #include "base/strings/string_split.h"
  16. #include "base/strings/utf_string_conversions.h"
  17. #include "net/base/net_errors.h"
  18. #include "net/dns/public/dns_protocol.h"
  19. #include "net/net_jni_headers/AndroidNetworkLibrary_jni.h"
  20. #include "net/net_jni_headers/DnsStatus_jni.h"
  21. using base::android::AttachCurrentThread;
  22. using base::android::ConvertJavaStringToUTF8;
  23. using base::android::ConvertUTF8ToJavaString;
  24. using base::android::ScopedJavaLocalRef;
  25. using base::android::ToJavaArrayOfByteArray;
  26. using base::android::ToJavaByteArray;
  27. namespace net::android {
  28. void VerifyX509CertChain(const std::vector<std::string>& cert_chain,
  29. base::StringPiece auth_type,
  30. base::StringPiece host,
  31. CertVerifyStatusAndroid* status,
  32. bool* is_issued_by_known_root,
  33. std::vector<std::string>* verified_chain) {
  34. JNIEnv* env = AttachCurrentThread();
  35. ScopedJavaLocalRef<jobjectArray> chain_byte_array =
  36. ToJavaArrayOfByteArray(env, cert_chain);
  37. DCHECK(!chain_byte_array.is_null());
  38. ScopedJavaLocalRef<jstring> auth_string =
  39. ConvertUTF8ToJavaString(env, auth_type);
  40. DCHECK(!auth_string.is_null());
  41. ScopedJavaLocalRef<jstring> host_string =
  42. ConvertUTF8ToJavaString(env, host);
  43. DCHECK(!host_string.is_null());
  44. ScopedJavaLocalRef<jobject> result =
  45. Java_AndroidNetworkLibrary_verifyServerCertificates(
  46. env, chain_byte_array, auth_string, host_string);
  47. ExtractCertVerifyResult(result, status, is_issued_by_known_root,
  48. verified_chain);
  49. }
  50. void AddTestRootCertificate(const uint8_t* cert, size_t len) {
  51. JNIEnv* env = AttachCurrentThread();
  52. ScopedJavaLocalRef<jbyteArray> cert_array = ToJavaByteArray(env, cert, len);
  53. DCHECK(!cert_array.is_null());
  54. Java_AndroidNetworkLibrary_addTestRootCertificate(env, cert_array);
  55. }
  56. void ClearTestRootCertificates() {
  57. JNIEnv* env = AttachCurrentThread();
  58. Java_AndroidNetworkLibrary_clearTestRootCertificates(env);
  59. }
  60. bool IsCleartextPermitted(const std::string& host) {
  61. JNIEnv* env = AttachCurrentThread();
  62. ScopedJavaLocalRef<jstring> host_string = ConvertUTF8ToJavaString(env, host);
  63. return Java_AndroidNetworkLibrary_isCleartextPermitted(env, host_string);
  64. }
  65. bool HaveOnlyLoopbackAddresses() {
  66. JNIEnv* env = AttachCurrentThread();
  67. return Java_AndroidNetworkLibrary_haveOnlyLoopbackAddresses(env);
  68. }
  69. bool GetMimeTypeFromExtension(const std::string& extension,
  70. std::string* result) {
  71. JNIEnv* env = AttachCurrentThread();
  72. ScopedJavaLocalRef<jstring> extension_string =
  73. ConvertUTF8ToJavaString(env, extension);
  74. ScopedJavaLocalRef<jstring> ret =
  75. Java_AndroidNetworkLibrary_getMimeTypeFromExtension(env,
  76. extension_string);
  77. if (!ret.obj())
  78. return false;
  79. *result = ConvertJavaStringToUTF8(ret);
  80. return true;
  81. }
  82. std::string GetTelephonyNetworkOperator() {
  83. return base::android::ConvertJavaStringToUTF8(
  84. Java_AndroidNetworkLibrary_getNetworkOperator(
  85. base::android::AttachCurrentThread()));
  86. }
  87. bool GetIsRoaming() {
  88. return Java_AndroidNetworkLibrary_getIsRoaming(
  89. base::android::AttachCurrentThread());
  90. }
  91. bool GetIsCaptivePortal() {
  92. return Java_AndroidNetworkLibrary_getIsCaptivePortal(
  93. base::android::AttachCurrentThread());
  94. }
  95. std::string GetWifiSSID() {
  96. return base::android::ConvertJavaStringToUTF8(
  97. Java_AndroidNetworkLibrary_getWifiSSID(
  98. base::android::AttachCurrentThread()));
  99. }
  100. void SetWifiEnabledForTesting(bool enabled) {
  101. Java_AndroidNetworkLibrary_setWifiEnabled(
  102. base::android::AttachCurrentThread(), enabled);
  103. }
  104. absl::optional<int32_t> GetWifiSignalLevel() {
  105. const int count_buckets = 5;
  106. int signal_strength = Java_AndroidNetworkLibrary_getWifiSignalLevel(
  107. base::android::AttachCurrentThread(), count_buckets);
  108. if (signal_strength < 0)
  109. return absl::nullopt;
  110. DCHECK_LE(0, signal_strength);
  111. DCHECK_GE(count_buckets - 1, signal_strength);
  112. return signal_strength;
  113. }
  114. namespace {
  115. bool GetDnsServersInternal(JNIEnv* env,
  116. const base::android::JavaRef<jobject>& dns_status,
  117. std::vector<IPEndPoint>* dns_servers,
  118. bool* dns_over_tls_active,
  119. std::string* dns_over_tls_hostname,
  120. std::vector<std::string>* search_suffixes) {
  121. // Parse the DNS servers.
  122. std::vector<std::vector<uint8_t>> dns_servers_data;
  123. base::android::JavaArrayOfByteArrayToBytesVector(
  124. env, Java_DnsStatus_getDnsServers(env, dns_status), &dns_servers_data);
  125. for (const std::vector<uint8_t>& dns_address_data : dns_servers_data) {
  126. IPAddress dns_address(dns_address_data.data(), dns_address_data.size());
  127. IPEndPoint dns_server(dns_address, dns_protocol::kDefaultPort);
  128. dns_servers->push_back(dns_server);
  129. }
  130. *dns_over_tls_active = Java_DnsStatus_getPrivateDnsActive(env, dns_status);
  131. *dns_over_tls_hostname = base::android::ConvertJavaStringToUTF8(
  132. Java_DnsStatus_getPrivateDnsServerName(env, dns_status));
  133. std::string search_suffixes_str = base::android::ConvertJavaStringToUTF8(
  134. Java_DnsStatus_getSearchDomains(env, dns_status));
  135. *search_suffixes =
  136. base::SplitString(search_suffixes_str, ",", base::TRIM_WHITESPACE,
  137. base::SPLIT_WANT_NONEMPTY);
  138. return !dns_servers->empty();
  139. }
  140. } // namespace
  141. bool GetCurrentDnsServers(std::vector<IPEndPoint>* dns_servers,
  142. bool* dns_over_tls_active,
  143. std::string* dns_over_tls_hostname,
  144. std::vector<std::string>* search_suffixes) {
  145. DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(),
  146. base::android::SDK_VERSION_MARSHMALLOW);
  147. JNIEnv* env = AttachCurrentThread();
  148. // Get the DNS status for the current default network.
  149. ScopedJavaLocalRef<jobject> result =
  150. Java_AndroidNetworkLibrary_getCurrentDnsStatus(env);
  151. if (result.is_null())
  152. return false;
  153. return GetDnsServersInternal(env, result, dns_servers, dns_over_tls_active,
  154. dns_over_tls_hostname, search_suffixes);
  155. }
  156. bool GetDnsServersForNetwork(std::vector<IPEndPoint>* dns_servers,
  157. bool* dns_over_tls_active,
  158. std::string* dns_over_tls_hostname,
  159. std::vector<std::string>* search_suffixes,
  160. handles::NetworkHandle network) {
  161. DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(),
  162. base::android::SDK_VERSION_P);
  163. JNIEnv* env = AttachCurrentThread();
  164. ScopedJavaLocalRef<jobject> result =
  165. Java_AndroidNetworkLibrary_getDnsStatusForNetwork(env, network);
  166. if (result.is_null())
  167. return false;
  168. return GetDnsServersInternal(env, result, dns_servers, dns_over_tls_active,
  169. dns_over_tls_hostname, search_suffixes);
  170. }
  171. bool ReportBadDefaultNetwork() {
  172. return Java_AndroidNetworkLibrary_reportBadDefaultNetwork(
  173. AttachCurrentThread());
  174. }
  175. void TagSocket(SocketDescriptor socket, uid_t uid, int32_t tag) {
  176. Java_AndroidNetworkLibrary_tagSocket(AttachCurrentThread(), socket, uid, tag);
  177. }
  178. namespace {
  179. using LollipopSetNetworkForSocket = int (*)(unsigned net_id, int socket_fd);
  180. using MarshmallowSetNetworkForSocket = int (*)(int64_t net_id, int socket_fd);
  181. MarshmallowSetNetworkForSocket GetMarshmallowSetNetworkForSocket() {
  182. // On Android M and newer releases use supported NDK API.
  183. base::FilePath file(base::GetNativeLibraryName("android"));
  184. // See declaration of android_setsocknetwork() here:
  185. // http://androidxref.com/6.0.0_r1/xref/development/ndk/platforms/android-M/include/android/multinetwork.h#65
  186. // Function cannot be called directly as it will cause app to fail to load on
  187. // pre-marshmallow devices.
  188. void* dl = dlopen(file.value().c_str(), RTLD_NOW);
  189. return reinterpret_cast<MarshmallowSetNetworkForSocket>(
  190. dlsym(dl, "android_setsocknetwork"));
  191. }
  192. LollipopSetNetworkForSocket GetLollipopSetNetworkForSocket() {
  193. // On Android L use setNetworkForSocket from libnetd_client.so. Android's netd
  194. // client library should always be loaded in our address space as it shims
  195. // socket().
  196. base::FilePath file(base::GetNativeLibraryName("netd_client"));
  197. // Use RTLD_NOW to match Android's prior loading of the library:
  198. // http://androidxref.com/6.0.0_r5/xref/bionic/libc/bionic/NetdClient.cpp#37
  199. // Use RTLD_NOLOAD to assert that the library is already loaded and avoid
  200. // doing any disk IO.
  201. void* dl = dlopen(file.value().c_str(), RTLD_NOW | RTLD_NOLOAD);
  202. return reinterpret_cast<LollipopSetNetworkForSocket>(
  203. dlsym(dl, "setNetworkForSocket"));
  204. }
  205. } // namespace
  206. int BindToNetwork(SocketDescriptor socket, handles::NetworkHandle network) {
  207. DCHECK_NE(socket, kInvalidSocket);
  208. if (network == handles::kInvalidNetworkHandle)
  209. return ERR_INVALID_ARGUMENT;
  210. // Android prior to Lollipop didn't have support for binding sockets to
  211. // networks.
  212. if (base::android::BuildInfo::GetInstance()->sdk_int() <
  213. base::android::SDK_VERSION_LOLLIPOP)
  214. return ERR_NOT_IMPLEMENTED;
  215. int rv;
  216. if (base::android::BuildInfo::GetInstance()->sdk_int() >=
  217. base::android::SDK_VERSION_MARSHMALLOW) {
  218. static MarshmallowSetNetworkForSocket marshmallow_set_network_for_socket =
  219. GetMarshmallowSetNetworkForSocket();
  220. if (!marshmallow_set_network_for_socket)
  221. return ERR_NOT_IMPLEMENTED;
  222. rv = marshmallow_set_network_for_socket(network, socket);
  223. if (rv)
  224. rv = errno;
  225. } else {
  226. static LollipopSetNetworkForSocket lollipop_set_network_for_socket =
  227. GetLollipopSetNetworkForSocket();
  228. if (!lollipop_set_network_for_socket)
  229. return ERR_NOT_IMPLEMENTED;
  230. rv = -lollipop_set_network_for_socket(network, socket);
  231. }
  232. // If |network| has since disconnected, |rv| will be ENONET. Surface this as
  233. // ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
  234. // the less descriptive ERR_FAILED.
  235. if (rv == ENONET)
  236. return ERR_NETWORK_CHANGED;
  237. return MapSystemError(rv);
  238. }
  239. namespace {
  240. using MarshmallowGetAddrInfoForNetwork = int (*)(int64_t network,
  241. const char* node,
  242. const char* service,
  243. const struct addrinfo* hints,
  244. struct addrinfo** res);
  245. MarshmallowGetAddrInfoForNetwork GetMarshmallowGetAddrInfoForNetwork() {
  246. // On Android M and newer releases use supported NDK API.
  247. base::FilePath file(base::GetNativeLibraryName("android"));
  248. // See declaration of android_getaddrinfofornetwork() here:
  249. // https://developer.android.com/ndk/reference/group/networking#android_getaddrinfofornetwork
  250. // Function cannot be called directly as it will cause app to fail to load on
  251. // pre-marshmallow devices.
  252. void* dl = dlopen(file.value().c_str(), RTLD_NOW);
  253. return reinterpret_cast<MarshmallowGetAddrInfoForNetwork>(
  254. dlsym(dl, "android_getaddrinfofornetwork"));
  255. }
  256. } // namespace
  257. NET_EXPORT_PRIVATE int GetAddrInfoForNetwork(handles::NetworkHandle network,
  258. const char* node,
  259. const char* service,
  260. const struct addrinfo* hints,
  261. struct addrinfo** res) {
  262. if (network == handles::kInvalidNetworkHandle) {
  263. errno = EINVAL;
  264. return EAI_SYSTEM;
  265. }
  266. if (base::android::BuildInfo::GetInstance()->sdk_int() <
  267. base::android::SDK_VERSION_MARSHMALLOW) {
  268. errno = ENOSYS;
  269. return EAI_SYSTEM;
  270. }
  271. static MarshmallowGetAddrInfoForNetwork get_addrinfo_for_network =
  272. GetMarshmallowGetAddrInfoForNetwork();
  273. if (!get_addrinfo_for_network) {
  274. errno = ENOSYS;
  275. return EAI_SYSTEM;
  276. }
  277. return get_addrinfo_for_network(network, node, service, hints, res);
  278. }
  279. } // namespace net::android