sandboxedjs 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +77 -2
- package/dist/index.js +77 -2
- package/dist/python-abi.cjs +5 -1
- package/dist/python-abi.js +5 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21057,7 +21057,7 @@ var wheels_default = {
|
|
|
21057
21057
|
|
|
21058
21058
|
// package.json
|
|
21059
21059
|
var package_default = {
|
|
21060
|
-
version: "0.2.
|
|
21060
|
+
version: "0.2.6"};
|
|
21061
21061
|
|
|
21062
21062
|
// src/python/extension-abi.ts
|
|
21063
21063
|
var EXTENSION_ABI = {
|
|
@@ -22722,8 +22722,12 @@ function createHostAbiServer(proc) {
|
|
|
22722
22722
|
}
|
|
22723
22723
|
case Op.resolve: {
|
|
22724
22724
|
const sockets = proc.sockets;
|
|
22725
|
+
const name = r.string();
|
|
22726
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(name)) {
|
|
22727
|
+
return { status: 0, payload: new Writer().string(name).finish() };
|
|
22728
|
+
}
|
|
22725
22729
|
if (!sockets?.outbound) throw new PosixError(Errno.ENOSYS);
|
|
22726
|
-
const address = sockets.outbound.resolve(
|
|
22730
|
+
const address = sockets.outbound.resolve(name);
|
|
22727
22731
|
return { status: 0, payload: new Writer().string(address).finish() };
|
|
22728
22732
|
}
|
|
22729
22733
|
case Op.send: {
|
|
@@ -24850,6 +24854,77 @@ if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1":
|
|
|
24850
24854
|
sys.meta_path.insert(0, _SbxTruststoreHook())
|
|
24851
24855
|
|
|
24852
24856
|
|
|
24857
|
+
# Literal addresses are answered here rather than through the host.
|
|
24858
|
+
#
|
|
24859
|
+
# The container's resolver is a host call, and a container with no outbound
|
|
24860
|
+
# sockets configured has no resolver to call: it answers ENOSYS. That is the
|
|
24861
|
+
# right answer for a name, but the egress hop below dials 127.0.0.1, and
|
|
24862
|
+
# http.client calls getaddrinfo even for an address that needs no resolving --
|
|
24863
|
+
# so every request through the egress died with "Function not implemented"
|
|
24864
|
+
# before it reached the endpoint. A numeric address (and loopback by its usual
|
|
24865
|
+
# names) is now formed here, which is what a resolver would have returned.
|
|
24866
|
+
def _sbx_local_addresses():
|
|
24867
|
+
import socket as _socket_module
|
|
24868
|
+
import _socket as _socket_native
|
|
24869
|
+
|
|
24870
|
+
# The native entry point, not socket.getaddrinfo: the stdlib wrapper
|
|
24871
|
+
# delegates to _socket, so wrapping the wrapper and replacing _socket with
|
|
24872
|
+
# the wrapper makes the two call each other forever.
|
|
24873
|
+
_real_getaddrinfo = _socket_native.getaddrinfo
|
|
24874
|
+
|
|
24875
|
+
_literals = {"localhost": "127.0.0.1", "localhost.localdomain": "127.0.0.1",
|
|
24876
|
+
"ip6-localhost": "127.0.0.1"}
|
|
24877
|
+
|
|
24878
|
+
def _literal(host):
|
|
24879
|
+
"""The address host already is, or None when it needs a resolver."""
|
|
24880
|
+
if isinstance(host, (bytes, bytearray)):
|
|
24881
|
+
host = bytes(host).decode("ascii", "replace")
|
|
24882
|
+
if host is None:
|
|
24883
|
+
return None
|
|
24884
|
+
host = _literals.get(host.lower(), host)
|
|
24885
|
+
parts = host.split(".")
|
|
24886
|
+
if len(parts) != 4:
|
|
24887
|
+
return None
|
|
24888
|
+
for part in parts:
|
|
24889
|
+
if not part.isdigit() or len(part) > 3 or int(part) > 255:
|
|
24890
|
+
return None
|
|
24891
|
+
return host
|
|
24892
|
+
|
|
24893
|
+
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
|
|
24894
|
+
address = _literal(host)
|
|
24895
|
+
if address is None:
|
|
24896
|
+
return _real_getaddrinfo(host, port, family, type, proto, flags)
|
|
24897
|
+
if isinstance(port, (bytes, bytearray)):
|
|
24898
|
+
port = bytes(port).decode("ascii", "replace")
|
|
24899
|
+
if isinstance(port, str):
|
|
24900
|
+
port = int(port) if port.isdigit() else _socket_module.getservbyname(port)
|
|
24901
|
+
if port is None:
|
|
24902
|
+
port = 0
|
|
24903
|
+
if family not in (0, _socket_module.AF_UNSPEC, _socket_module.AF_INET):
|
|
24904
|
+
raise _socket_module.gaierror(
|
|
24905
|
+
_socket_module.EAI_FAMILY, "only AF_INET is supported in this container"
|
|
24906
|
+
)
|
|
24907
|
+
kind = type or _socket_module.SOCK_STREAM
|
|
24908
|
+
protocol = proto or (_socket_module.IPPROTO_TCP
|
|
24909
|
+
if kind == _socket_module.SOCK_STREAM else 0)
|
|
24910
|
+
return [(_socket_module.AF_INET, kind, protocol, "", (address, int(port)))]
|
|
24911
|
+
|
|
24912
|
+
def gethostbyname(host):
|
|
24913
|
+
return getaddrinfo(host, 0)[0][4][0]
|
|
24914
|
+
|
|
24915
|
+
def gethostbyname_ex(host):
|
|
24916
|
+
return (host, [], [gethostbyname(host)])
|
|
24917
|
+
|
|
24918
|
+
_socket_module.getaddrinfo = getaddrinfo
|
|
24919
|
+
_socket_module.gethostbyname = gethostbyname
|
|
24920
|
+
_socket_module.gethostbyname_ex = gethostbyname_ex
|
|
24921
|
+
_socket_native.getaddrinfo = getaddrinfo
|
|
24922
|
+
_socket_native.gethostbyname = gethostbyname
|
|
24923
|
+
_socket_native.gethostbyname_ex = gethostbyname_ex
|
|
24924
|
+
|
|
24925
|
+
|
|
24926
|
+
_sbx_local_addresses()
|
|
24927
|
+
|
|
24853
24928
|
_egress = None if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1" else os.environ.get("SBX_HTTP_EGRESS")
|
|
24854
24929
|
if _egress:
|
|
24855
24930
|
import http.client
|
package/dist/index.js
CHANGED
|
@@ -21040,7 +21040,7 @@ var wheels_default = {
|
|
|
21040
21040
|
|
|
21041
21041
|
// package.json
|
|
21042
21042
|
var package_default = {
|
|
21043
|
-
version: "0.2.
|
|
21043
|
+
version: "0.2.6"};
|
|
21044
21044
|
|
|
21045
21045
|
// src/python/extension-abi.ts
|
|
21046
21046
|
var EXTENSION_ABI = {
|
|
@@ -22705,8 +22705,12 @@ function createHostAbiServer(proc) {
|
|
|
22705
22705
|
}
|
|
22706
22706
|
case Op.resolve: {
|
|
22707
22707
|
const sockets = proc.sockets;
|
|
22708
|
+
const name = r.string();
|
|
22709
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(name)) {
|
|
22710
|
+
return { status: 0, payload: new Writer().string(name).finish() };
|
|
22711
|
+
}
|
|
22708
22712
|
if (!sockets?.outbound) throw new PosixError(Errno.ENOSYS);
|
|
22709
|
-
const address = sockets.outbound.resolve(
|
|
22713
|
+
const address = sockets.outbound.resolve(name);
|
|
22710
22714
|
return { status: 0, payload: new Writer().string(address).finish() };
|
|
22711
22715
|
}
|
|
22712
22716
|
case Op.send: {
|
|
@@ -24833,6 +24837,77 @@ if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1":
|
|
|
24833
24837
|
sys.meta_path.insert(0, _SbxTruststoreHook())
|
|
24834
24838
|
|
|
24835
24839
|
|
|
24840
|
+
# Literal addresses are answered here rather than through the host.
|
|
24841
|
+
#
|
|
24842
|
+
# The container's resolver is a host call, and a container with no outbound
|
|
24843
|
+
# sockets configured has no resolver to call: it answers ENOSYS. That is the
|
|
24844
|
+
# right answer for a name, but the egress hop below dials 127.0.0.1, and
|
|
24845
|
+
# http.client calls getaddrinfo even for an address that needs no resolving --
|
|
24846
|
+
# so every request through the egress died with "Function not implemented"
|
|
24847
|
+
# before it reached the endpoint. A numeric address (and loopback by its usual
|
|
24848
|
+
# names) is now formed here, which is what a resolver would have returned.
|
|
24849
|
+
def _sbx_local_addresses():
|
|
24850
|
+
import socket as _socket_module
|
|
24851
|
+
import _socket as _socket_native
|
|
24852
|
+
|
|
24853
|
+
# The native entry point, not socket.getaddrinfo: the stdlib wrapper
|
|
24854
|
+
# delegates to _socket, so wrapping the wrapper and replacing _socket with
|
|
24855
|
+
# the wrapper makes the two call each other forever.
|
|
24856
|
+
_real_getaddrinfo = _socket_native.getaddrinfo
|
|
24857
|
+
|
|
24858
|
+
_literals = {"localhost": "127.0.0.1", "localhost.localdomain": "127.0.0.1",
|
|
24859
|
+
"ip6-localhost": "127.0.0.1"}
|
|
24860
|
+
|
|
24861
|
+
def _literal(host):
|
|
24862
|
+
"""The address host already is, or None when it needs a resolver."""
|
|
24863
|
+
if isinstance(host, (bytes, bytearray)):
|
|
24864
|
+
host = bytes(host).decode("ascii", "replace")
|
|
24865
|
+
if host is None:
|
|
24866
|
+
return None
|
|
24867
|
+
host = _literals.get(host.lower(), host)
|
|
24868
|
+
parts = host.split(".")
|
|
24869
|
+
if len(parts) != 4:
|
|
24870
|
+
return None
|
|
24871
|
+
for part in parts:
|
|
24872
|
+
if not part.isdigit() or len(part) > 3 or int(part) > 255:
|
|
24873
|
+
return None
|
|
24874
|
+
return host
|
|
24875
|
+
|
|
24876
|
+
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
|
|
24877
|
+
address = _literal(host)
|
|
24878
|
+
if address is None:
|
|
24879
|
+
return _real_getaddrinfo(host, port, family, type, proto, flags)
|
|
24880
|
+
if isinstance(port, (bytes, bytearray)):
|
|
24881
|
+
port = bytes(port).decode("ascii", "replace")
|
|
24882
|
+
if isinstance(port, str):
|
|
24883
|
+
port = int(port) if port.isdigit() else _socket_module.getservbyname(port)
|
|
24884
|
+
if port is None:
|
|
24885
|
+
port = 0
|
|
24886
|
+
if family not in (0, _socket_module.AF_UNSPEC, _socket_module.AF_INET):
|
|
24887
|
+
raise _socket_module.gaierror(
|
|
24888
|
+
_socket_module.EAI_FAMILY, "only AF_INET is supported in this container"
|
|
24889
|
+
)
|
|
24890
|
+
kind = type or _socket_module.SOCK_STREAM
|
|
24891
|
+
protocol = proto or (_socket_module.IPPROTO_TCP
|
|
24892
|
+
if kind == _socket_module.SOCK_STREAM else 0)
|
|
24893
|
+
return [(_socket_module.AF_INET, kind, protocol, "", (address, int(port)))]
|
|
24894
|
+
|
|
24895
|
+
def gethostbyname(host):
|
|
24896
|
+
return getaddrinfo(host, 0)[0][4][0]
|
|
24897
|
+
|
|
24898
|
+
def gethostbyname_ex(host):
|
|
24899
|
+
return (host, [], [gethostbyname(host)])
|
|
24900
|
+
|
|
24901
|
+
_socket_module.getaddrinfo = getaddrinfo
|
|
24902
|
+
_socket_module.gethostbyname = gethostbyname
|
|
24903
|
+
_socket_module.gethostbyname_ex = gethostbyname_ex
|
|
24904
|
+
_socket_native.getaddrinfo = getaddrinfo
|
|
24905
|
+
_socket_native.gethostbyname = gethostbyname
|
|
24906
|
+
_socket_native.gethostbyname_ex = gethostbyname_ex
|
|
24907
|
+
|
|
24908
|
+
|
|
24909
|
+
_sbx_local_addresses()
|
|
24910
|
+
|
|
24836
24911
|
_egress = None if os.environ.get("SBX_OUTBOUND_SOCKETS") == "1" else os.environ.get("SBX_HTTP_EGRESS")
|
|
24837
24912
|
if _egress:
|
|
24838
24913
|
import http.client
|
package/dist/python-abi.cjs
CHANGED
|
@@ -1653,8 +1653,12 @@ function createHostAbiServer(proc) {
|
|
|
1653
1653
|
}
|
|
1654
1654
|
case Op.resolve: {
|
|
1655
1655
|
const sockets = proc.sockets;
|
|
1656
|
+
const name = r.string();
|
|
1657
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(name)) {
|
|
1658
|
+
return { status: 0, payload: new Writer().string(name).finish() };
|
|
1659
|
+
}
|
|
1656
1660
|
if (!sockets?.outbound) throw new PosixError(Errno.ENOSYS);
|
|
1657
|
-
const address = sockets.outbound.resolve(
|
|
1661
|
+
const address = sockets.outbound.resolve(name);
|
|
1658
1662
|
return { status: 0, payload: new Writer().string(address).finish() };
|
|
1659
1663
|
}
|
|
1660
1664
|
case Op.send: {
|
package/dist/python-abi.js
CHANGED
|
@@ -1651,8 +1651,12 @@ function createHostAbiServer(proc) {
|
|
|
1651
1651
|
}
|
|
1652
1652
|
case Op.resolve: {
|
|
1653
1653
|
const sockets = proc.sockets;
|
|
1654
|
+
const name = r.string();
|
|
1655
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(name)) {
|
|
1656
|
+
return { status: 0, payload: new Writer().string(name).finish() };
|
|
1657
|
+
}
|
|
1654
1658
|
if (!sockets?.outbound) throw new PosixError(Errno.ENOSYS);
|
|
1655
|
-
const address = sockets.outbound.resolve(
|
|
1659
|
+
const address = sockets.outbound.resolve(name);
|
|
1656
1660
|
return { status: 0, payload: new Writer().string(address).finish() };
|
|
1657
1661
|
}
|
|
1658
1662
|
case Op.send: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sandboxedjs",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "A Linux-like container that runs entirely inside Node.js — POSIX shell, ~140 coreutils, Node.js and Python runtimes, virtual filesystem and networking. No Docker, no VM, no native modules.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|