feat(flutter_tools): Added proxy validator IPV6 loopback check (#95159)
* feat(flutter_tools): Added proxy validator IPV6 lookback check * Remove whitespace. Co-authored-by: Zachary Anderson <zanderso@users.noreply.github.com>
This commit is contained in:
parent
31eb8fcd98
commit
1fb9b5b3d2
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'base/io.dart';
|
||||||
import 'base/platform.dart';
|
import 'base/platform.dart';
|
||||||
import 'doctor_validator.dart';
|
import 'doctor_validator.dart';
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ class ProxyValidator extends DoctorValidator {
|
|||||||
else
|
else
|
||||||
...<ValidationMessage>[
|
...<ValidationMessage>[
|
||||||
ValidationMessage('NO_PROXY is $_noProxy'),
|
ValidationMessage('NO_PROXY is $_noProxy'),
|
||||||
for (String host in const <String>['127.0.0.1', 'localhost'])
|
for (final String host in await _getLoopbackAddresses())
|
||||||
if (_noProxy.contains(host))
|
if (_noProxy.contains(host))
|
||||||
ValidationMessage('NO_PROXY contains $host')
|
ValidationMessage('NO_PROXY contains $host')
|
||||||
else
|
else
|
||||||
@ -59,4 +60,21 @@ class ProxyValidator extends DoctorValidator {
|
|||||||
messages,
|
messages,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<String>> _getLoopbackAddresses() async {
|
||||||
|
final List<String> loopBackAddresses = <String>['localhost'];
|
||||||
|
|
||||||
|
final List<NetworkInterface> networkInterfaces =
|
||||||
|
await listNetworkInterfaces(includeLinkLocal: true, includeLoopback: true);
|
||||||
|
|
||||||
|
for (final NetworkInterface networkInterface in networkInterfaces) {
|
||||||
|
for (final InternetAddress internetAddress in networkInterface.addresses) {
|
||||||
|
if (internetAddress.isLoopback) {
|
||||||
|
loopBackAddresses.add(internetAddress.address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loopBackAddresses;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:io' as io;
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter_tools/src/base/io.dart';
|
||||||
import 'package:flutter_tools/src/base/platform.dart';
|
import 'package:flutter_tools/src/base/platform.dart';
|
||||||
import 'package:flutter_tools/src/doctor_validator.dart';
|
import 'package:flutter_tools/src/doctor_validator.dart';
|
||||||
import 'package:flutter_tools/src/proxy_validator.dart';
|
import 'package:flutter_tools/src/proxy_validator.dart';
|
||||||
@ -9,6 +13,30 @@ import 'package:flutter_tools/src/proxy_validator.dart';
|
|||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
setUp(() {
|
||||||
|
setNetworkInterfaceLister(
|
||||||
|
({
|
||||||
|
bool includeLoopback = true,
|
||||||
|
bool includeLinkLocal = true,
|
||||||
|
InternetAddressType type = InternetAddressType.any,
|
||||||
|
}) async {
|
||||||
|
final List<FakeNetworkInterface> interfaces = <FakeNetworkInterface>[
|
||||||
|
FakeNetworkInterface(<FakeInternetAddress>[
|
||||||
|
const FakeInternetAddress('127.0.0.1')
|
||||||
|
]),
|
||||||
|
FakeNetworkInterface(<FakeInternetAddress>[
|
||||||
|
const FakeInternetAddress('::1')
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
return Future<List<NetworkInterface>>.value(interfaces);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() {
|
||||||
|
resetNetworkInterfaceLister();
|
||||||
|
});
|
||||||
|
|
||||||
testWithoutContext('ProxyValidator does not show if HTTP_PROXY is not set', () {
|
testWithoutContext('ProxyValidator does not show if HTTP_PROXY is not set', () {
|
||||||
final Platform platform = FakePlatform(environment: <String, String>{});
|
final Platform platform = FakePlatform(environment: <String, String>{});
|
||||||
|
|
||||||
@ -37,16 +65,17 @@ void main() {
|
|||||||
final Platform platform = FakePlatform(
|
final Platform platform = FakePlatform(
|
||||||
environment: <String, String>{
|
environment: <String, String>{
|
||||||
'HTTP_PROXY': 'fakeproxy.local',
|
'HTTP_PROXY': 'fakeproxy.local',
|
||||||
'NO_PROXY': 'localhost,127.0.0.1',
|
'NO_PROXY': 'localhost,127.0.0.1,::1',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
||||||
|
|
||||||
expect(results.messages, const <ValidationMessage>[
|
expect(results.messages, const <ValidationMessage>[
|
||||||
ValidationMessage('HTTP_PROXY is set'),
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
ValidationMessage('NO_PROXY is localhost,127.0.0.1'),
|
ValidationMessage('NO_PROXY is localhost,127.0.0.1,::1'),
|
||||||
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
|
||||||
ValidationMessage('NO_PROXY contains localhost'),
|
ValidationMessage('NO_PROXY contains localhost'),
|
||||||
|
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
||||||
|
ValidationMessage('NO_PROXY contains ::1'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -54,20 +83,89 @@ void main() {
|
|||||||
final Platform platform = FakePlatform(
|
final Platform platform = FakePlatform(
|
||||||
environment: <String, String>{
|
environment: <String, String>{
|
||||||
'http_proxy': 'fakeproxy.local',
|
'http_proxy': 'fakeproxy.local',
|
||||||
'no_proxy': 'localhost,127.0.0.1',
|
'no_proxy': 'localhost,127.0.0.1,::1',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
||||||
|
|
||||||
expect(results.messages, const <ValidationMessage>[
|
expect(results.messages, const <ValidationMessage>[
|
||||||
ValidationMessage('HTTP_PROXY is set'),
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
ValidationMessage('NO_PROXY is localhost,127.0.0.1'),
|
ValidationMessage('NO_PROXY is localhost,127.0.0.1,::1'),
|
||||||
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
|
||||||
ValidationMessage('NO_PROXY contains localhost'),
|
ValidationMessage('NO_PROXY contains localhost'),
|
||||||
|
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
||||||
|
ValidationMessage('NO_PROXY contains ::1'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing localhost', () async {
|
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing localhost', () async {
|
||||||
|
final Platform platform = FakePlatform(
|
||||||
|
environment: <String, String>{
|
||||||
|
'HTTP_PROXY': 'fakeproxy.local',
|
||||||
|
'NO_PROXY': '127.0.0.1,::1',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
||||||
|
|
||||||
|
expect(results.messages, const <ValidationMessage>[
|
||||||
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
|
ValidationMessage('NO_PROXY is 127.0.0.1,::1'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain localhost'),
|
||||||
|
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
||||||
|
ValidationMessage('NO_PROXY contains ::1'),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing 127.0.0.1', () async {
|
||||||
|
final Platform platform = FakePlatform(environment: <String, String>{
|
||||||
|
'HTTP_PROXY': 'fakeproxy.local',
|
||||||
|
'NO_PROXY': 'localhost,::1',
|
||||||
|
});
|
||||||
|
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
||||||
|
|
||||||
|
expect(results.messages, const <ValidationMessage>[
|
||||||
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
|
ValidationMessage('NO_PROXY is localhost,::1'),
|
||||||
|
ValidationMessage('NO_PROXY contains localhost'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain 127.0.0.1'),
|
||||||
|
ValidationMessage('NO_PROXY contains ::1'),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing ::1', () async {
|
||||||
|
final Platform platform = FakePlatform(environment: <String, String>{
|
||||||
|
'HTTP_PROXY': 'fakeproxy.local',
|
||||||
|
'NO_PROXY': 'localhost,127.0.0.1',
|
||||||
|
});
|
||||||
|
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
||||||
|
|
||||||
|
expect(results.messages, const <ValidationMessage>[
|
||||||
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
|
ValidationMessage('NO_PROXY is localhost,127.0.0.1'),
|
||||||
|
ValidationMessage('NO_PROXY contains localhost'),
|
||||||
|
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain ::1'),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing localhost, 127.0.0.1', () async {
|
||||||
|
final Platform platform = FakePlatform(
|
||||||
|
environment: <String, String>{
|
||||||
|
'HTTP_PROXY': 'fakeproxy.local',
|
||||||
|
'NO_PROXY': '::1',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
||||||
|
|
||||||
|
expect(results.messages, const <ValidationMessage>[
|
||||||
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
|
ValidationMessage('NO_PROXY is ::1'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain localhost'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain 127.0.0.1'),
|
||||||
|
ValidationMessage('NO_PROXY contains ::1'),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing localhost, ::1', () async {
|
||||||
final Platform platform = FakePlatform(
|
final Platform platform = FakePlatform(
|
||||||
environment: <String, String>{
|
environment: <String, String>{
|
||||||
'HTTP_PROXY': 'fakeproxy.local',
|
'HTTP_PROXY': 'fakeproxy.local',
|
||||||
@ -79,23 +177,81 @@ void main() {
|
|||||||
expect(results.messages, const <ValidationMessage>[
|
expect(results.messages, const <ValidationMessage>[
|
||||||
ValidationMessage('HTTP_PROXY is set'),
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
ValidationMessage('NO_PROXY is 127.0.0.1'),
|
ValidationMessage('NO_PROXY is 127.0.0.1'),
|
||||||
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
|
||||||
ValidationMessage.hint('NO_PROXY does not contain localhost'),
|
ValidationMessage.hint('NO_PROXY does not contain localhost'),
|
||||||
|
ValidationMessage('NO_PROXY contains 127.0.0.1'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain ::1'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing 127.0.0.1', () async {
|
testWithoutContext('ProxyValidator reports issues when NO_PROXY is missing 127.0.0.1, ::1', () async {
|
||||||
final Platform platform = FakePlatform(environment: <String, String>{
|
final Platform platform = FakePlatform(
|
||||||
'HTTP_PROXY': 'fakeproxy.local',
|
environment: <String, String>{
|
||||||
'NO_PROXY': 'localhost',
|
'HTTP_PROXY': 'fakeproxy.local',
|
||||||
});
|
'NO_PROXY': 'localhost',
|
||||||
|
},
|
||||||
|
);
|
||||||
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
final ValidationResult results = await ProxyValidator(platform: platform).validate();
|
||||||
|
|
||||||
expect(results.messages, const <ValidationMessage>[
|
expect(results.messages, const <ValidationMessage>[
|
||||||
ValidationMessage('HTTP_PROXY is set'),
|
ValidationMessage('HTTP_PROXY is set'),
|
||||||
ValidationMessage('NO_PROXY is localhost'),
|
ValidationMessage('NO_PROXY is localhost'),
|
||||||
ValidationMessage.hint('NO_PROXY does not contain 127.0.0.1'),
|
|
||||||
ValidationMessage('NO_PROXY contains localhost'),
|
ValidationMessage('NO_PROXY contains localhost'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain 127.0.0.1'),
|
||||||
|
ValidationMessage.hint('NO_PROXY does not contain ::1'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FakeNetworkInterface extends NetworkInterface {
|
||||||
|
FakeNetworkInterface(List<FakeInternetAddress> addresses):
|
||||||
|
super(FakeNetworkInterfaceDelegate(addresses));
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get name => 'FakeNetworkInterface$index';
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeNetworkInterfaceDelegate implements io.NetworkInterface {
|
||||||
|
FakeNetworkInterfaceDelegate(this._fakeAddresses);
|
||||||
|
|
||||||
|
final List<FakeInternetAddress> _fakeAddresses;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<io.InternetAddress> get addresses => _fakeAddresses;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get index => addresses.length;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get name => 'FakeNetworkInterfaceDelegate$index';
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeInternetAddress implements io.InternetAddress {
|
||||||
|
const FakeInternetAddress(this._fakeAddress);
|
||||||
|
|
||||||
|
final String _fakeAddress;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get address => _fakeAddress;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get host => throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isLinkLocal => throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isLoopback => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isMulticast => throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Uint8List get rawAddress => throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<io.InternetAddress> reverse() =>
|
||||||
|
throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
io.InternetAddressType get type => throw UnimplementedError();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user