mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 11:14:38 +08:00
Fix ssl-vendor (OpenSSL) (#7985)
Closes: #7893 Fix 1: `foreign-types-shared` needs to match `openssl`'s version. Bumping it is a SemVer violation because the latest versions of the crate aren't backwards compatible with older versions. See: rust-openssl/rust-openssl#2461 Fix 2: The second fix is to align the `openssl` module with the latest `host_env` and `ssl` changes.
This commit is contained in:
1 parent
e80a14ba12
commit
7d54ba502e
4 files changed
+44
-33
No files matched your search
@@ -140,6 +140,10 @@ jobs:
|
||||
run: cargo build --no-default-features --features ssl-openssl
|
||||
if: runner.os == 'Linux'
|
||||
|
||||
- name: Test vendored OpenSSL build
|
||||
run: cargo build --no-default-features --features ssl-vendor
|
||||
if: runner.os == 'Linux'
|
||||
|
||||
# - name: Install tk-dev for tkinter build
|
||||
# run: sudo apt-get update && sudo apt-get install -y tk-dev
|
||||
# if: runner.os == 'Linux'
|
||||
|
||||
@@ -217,6 +217,7 @@ exitcode = "1.1.2"
|
||||
flame = "0.2.2"
|
||||
flamer = "0.5"
|
||||
flate2 = { version = "1.1.9", default-features = false }
|
||||
# Bump only when the openssl crate bumps it
|
||||
foreign-types-shared = "0.1"
|
||||
gethostname = "1.0.2"
|
||||
getrandom = { version = "0.3", features = ["std"] }
|
||||
|
||||
@@ -65,7 +65,7 @@ mod _ssl {
|
||||
LazyLock, PyMappedRwLockReadGuard, PyMutex, PyRwLock, PyRwLockReadGuard,
|
||||
PyRwLockWriteGuard,
|
||||
},
|
||||
socket::{self, PySocket},
|
||||
socket::{self, PySocket, SockWaitKind, sock_wait},
|
||||
vm::{
|
||||
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
builtins::{
|
||||
@@ -2297,34 +2297,31 @@ mod _ssl {
|
||||
needs: SslNeeds,
|
||||
deadline: &SocketDeadline,
|
||||
vm: &VirtualMachine,
|
||||
) -> SelectRet {
|
||||
let sock = match self.0.sock_opt() {
|
||||
Some(s) => s,
|
||||
None => return SelectRet::Closed,
|
||||
) -> PyResult<SelectRet> {
|
||||
let Some(sock) = self.0.sock_opt() else {
|
||||
return Ok(SelectRet::Closed);
|
||||
};
|
||||
// For blocking sockets without timeout, call sock_wait with None timeout
|
||||
// For blocking sockets without timeout, call sock_select with None timeout
|
||||
// to actually block waiting for data instead of busy-looping
|
||||
let timeout = match &deadline {
|
||||
Ok(deadline) => match deadline.checked_duration_since(Instant::now()) {
|
||||
Some(d) => Some(d),
|
||||
None => return SelectRet::TimedOut,
|
||||
None => return Ok(SelectRet::TimedOut),
|
||||
},
|
||||
Err(true) => None, // Blocking: no timeout, wait indefinitely
|
||||
Err(false) => return SelectRet::Nonblocking,
|
||||
Err(false) => return Ok(SelectRet::Nonblocking),
|
||||
};
|
||||
let res = socket::sock_wait(
|
||||
&sock,
|
||||
match needs {
|
||||
SslNeeds::Read => socket::SockWaitKind::Read,
|
||||
SslNeeds::Write => socket::SockWaitKind::Write,
|
||||
},
|
||||
timeout,
|
||||
vm,
|
||||
);
|
||||
match res {
|
||||
Ok(true) => SelectRet::TimedOut,
|
||||
_ => SelectRet::Ok,
|
||||
}
|
||||
let wait_kind = match needs {
|
||||
SslNeeds::Read => SockWaitKind::Read,
|
||||
SslNeeds::Write => SockWaitKind::Write,
|
||||
};
|
||||
sock_wait(&*sock, wait_kind, timeout, vm).map(|timed_out| {
|
||||
if timed_out {
|
||||
SelectRet::TimedOut
|
||||
} else {
|
||||
SelectRet::Ok
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn socket_needs(
|
||||
@@ -2332,14 +2329,15 @@ mod _ssl {
|
||||
err: &ssl::Error,
|
||||
deadline: &SocketDeadline,
|
||||
vm: &VirtualMachine,
|
||||
) -> (Option<SslNeeds>, SelectRet) {
|
||||
) -> PyResult<(Option<SslNeeds>, SelectRet)> {
|
||||
let needs = match err.code() {
|
||||
ssl::ErrorCode::WANT_READ => Some(SslNeeds::Read),
|
||||
ssl::ErrorCode::WANT_WRITE => Some(SslNeeds::Write),
|
||||
_ => None,
|
||||
};
|
||||
let state = needs.map_or(SelectRet::Ok, |needs| self.select(needs, deadline, vm));
|
||||
(needs, state)
|
||||
let state =
|
||||
needs.map_or(Ok(SelectRet::Ok), |needs| self.select(needs, deadline, vm))?;
|
||||
Ok((needs, state))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2857,7 +2855,7 @@ mod _ssl {
|
||||
break;
|
||||
}
|
||||
// Wait briefly for peer's close_notify before retrying
|
||||
match socket_stream.select(SslNeeds::Read, &deadline, vm) {
|
||||
match socket_stream.select(SslNeeds::Read, &deadline, vm)? {
|
||||
SelectRet::TimedOut => {
|
||||
return Err(socket::timeout_error_msg(
|
||||
vm,
|
||||
@@ -2895,7 +2893,7 @@ mod _ssl {
|
||||
};
|
||||
|
||||
// Wait on the socket
|
||||
match socket_stream.select(needs, &deadline, vm) {
|
||||
match socket_stream.select(needs, &deadline, vm)? {
|
||||
SelectRet::TimedOut => {
|
||||
let msg = if err == sys::SSL_ERROR_WANT_READ {
|
||||
"The read operation timed out"
|
||||
@@ -2991,7 +2989,7 @@ mod _ssl {
|
||||
let (needs, state) = stream
|
||||
.get_ref()
|
||||
.expect("handshake called in bio mode; should only be called in socket mode")
|
||||
.socket_needs(&err, &timeout, vm);
|
||||
.socket_needs(&err, &timeout, vm)?;
|
||||
match state {
|
||||
SelectRet::TimedOut => {
|
||||
// Clean up SNI ex_data before returning error
|
||||
@@ -3045,7 +3043,7 @@ mod _ssl {
|
||||
.get_ref()
|
||||
.expect("write called in bio mode; should only be called in socket mode");
|
||||
let timeout = socket_ref.timeout_deadline();
|
||||
let state = socket_ref.select(SslNeeds::Write, &timeout, vm);
|
||||
let state = socket_ref.select(SslNeeds::Write, &timeout, vm)?;
|
||||
match state {
|
||||
SelectRet::TimedOut => {
|
||||
return Err(socket::timeout_error_msg(
|
||||
@@ -3065,7 +3063,7 @@ mod _ssl {
|
||||
let (needs, state) = stream
|
||||
.get_ref()
|
||||
.expect("write called in bio mode; should only be called in socket mode")
|
||||
.socket_needs(&err, &timeout, vm);
|
||||
.socket_needs(&err, &timeout, vm)?;
|
||||
match state {
|
||||
SelectRet::TimedOut => {
|
||||
return Err(socket::timeout_error_msg(
|
||||
@@ -3236,7 +3234,7 @@ mod _ssl {
|
||||
let (needs, state) = stream
|
||||
.get_ref()
|
||||
.expect("read called in bio mode; should only be called in socket mode")
|
||||
.socket_needs(&err, &timeout, vm);
|
||||
.socket_needs(&err, &timeout, vm)?;
|
||||
match state {
|
||||
SelectRet::TimedOut => {
|
||||
return Err(socket::timeout_error_msg(
|
||||
@@ -4149,7 +4147,7 @@ mod bio {
|
||||
use openssl_sys as sys;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct MemBioSlice<'a>(*mut sys::BIO, PhantomData<&'a [u8]>);
|
||||
pub(super) struct MemBioSlice<'a>(*mut sys::BIO, PhantomData<&'a [u8]>);
|
||||
|
||||
impl Drop for MemBioSlice<'_> {
|
||||
fn drop(&mut self) {
|
||||
@@ -4160,7 +4158,7 @@ mod bio {
|
||||
}
|
||||
|
||||
impl<'a> MemBioSlice<'a> {
|
||||
pub fn new(buf: &'a [u8]) -> Result<MemBioSlice<'a>, ErrorStack> {
|
||||
pub(super) fn new(buf: &'a [u8]) -> Result<MemBioSlice<'a>, ErrorStack> {
|
||||
openssl::init();
|
||||
|
||||
assert!(buf.len() <= c_int::MAX as usize);
|
||||
@@ -4172,7 +4170,7 @@ mod bio {
|
||||
Ok(MemBioSlice(bio, PhantomData))
|
||||
}
|
||||
|
||||
pub fn as_ptr(&self) -> *mut sys::BIO {
|
||||
pub(super) fn as_ptr(&self) -> *mut sys::BIO {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,10 @@ pub(crate) mod ssl_error {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
all(feature = "ssl-openssl", not(feature = "ssl-rustls")),
|
||||
expect(dead_code)
|
||||
)]
|
||||
pub(crate) fn create_ssl_zero_return_error(vm: &VirtualMachine) -> PyRef<PyOSError> {
|
||||
vm.new_os_subtype_error(
|
||||
PySSLZeroReturnError::class(&vm.ctx).to_owned(),
|
||||
@@ -133,6 +137,10 @@ pub(crate) mod ssl_error {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
all(feature = "ssl-openssl", not(feature = "ssl-rustls")),
|
||||
expect(dead_code)
|
||||
)]
|
||||
pub(crate) fn create_ssl_syscall_error(
|
||||
vm: &VirtualMachine,
|
||||
msg: impl Into<String>,
|
||||
|
||||
Reference in new issue
Block a user