Re: [ovs-dev] [PATCH v3 2/2] python: replace pyOpenSSL with ssl

2021-10-27 Thread Terry Wilson
On Mon, Oct 25, 2021 at 8:46 AM Timothy Redaelli  wrote:
>
> Currently, pyOpenSSL is half-deprecated upstream and so it's removed on
> some distributions (for example on CentOS Stream 9,
> https://issues.redhat.com/browse/CS-336), but since OVS only
> supports Python 3 it's possible to replace pyOpenSSL with "import ssl"
> included in base Python 3.
>
> Stream recv and send had to be splitted as _recv and _send, since SSLError
> is a subclass of socket.error and so it was not possible to except for
> SSLWantReadError and SSLWantWriteError in recv and send of SSLStream.
>
> TCPstream._open cannot be used in SSLStream, since Python ssl module
> requires the SSL socket to be created before connecting it, so
> SSLStream._open needs to create the socket, create SSL socket and then
> connect the SSL socket.
>
> Reported-by: Timothy Redaelli 
> Reported-at: https://bugzilla.redhat.com/1988429
> Signed-off-by: Timothy Redaelli 
> ---
>  .ci/linux-prepare.sh |  2 +-
>  .cirrus.yml  |  2 +-
>  .travis.yml  |  1 -
>  python/ovs/poller.py |  6 +--
>  python/ovs/stream.py | 91 ++--
>  tests/ovsdb-idl.at   |  2 +-
>  6 files changed, 60 insertions(+), 44 deletions(-)
>
> diff --git a/.ci/linux-prepare.sh b/.ci/linux-prepare.sh
> index c55125cf7..b9b499bad 100755
> --- a/.ci/linux-prepare.sh
> +++ b/.ci/linux-prepare.sh
> @@ -21,7 +21,7 @@ make -j4 HAVE_LLVM= HAVE_SQLITE= install
>  cd ..
>
>  pip3 install --disable-pip-version-check --user \
> -flake8 hacking sphinx pyOpenSSL wheel setuptools
> +flake8 hacking sphinx wheel setuptools
>  pip3 install --user --upgrade docutils
>  pip3 install --user  'meson==0.47.1'
>
> diff --git a/.cirrus.yml b/.cirrus.yml
> index 480fea242..a7ae793bc 100644
> --- a/.cirrus.yml
> +++ b/.cirrus.yml
> @@ -9,7 +9,7 @@ freebsd_build_task:
>
>env:
>  DEPENDENCIES: automake libtool gmake gcc wget openssl python3
> -PY_DEPS:  sphinx|openssl
> +PY_DEPS:  sphinx
>  matrix:
>COMPILER: gcc
>COMPILER: clang
> diff --git a/.travis.yml b/.travis.yml
> index 51d051108..c7aeede06 100644
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -17,7 +17,6 @@ addons:
>- libjemalloc-dev
>- libnuma-dev
>- libpcap-dev
> -  - python3-openssl
>- python3-pip
>- python3-sphinx
>- libelf-dev
> diff --git a/python/ovs/poller.py b/python/ovs/poller.py
> index 3624ec865..157719c3a 100644
> --- a/python/ovs/poller.py
> +++ b/python/ovs/poller.py
> @@ -26,9 +26,9 @@ if sys.platform == "win32":
>  import ovs.winutils as winutils
>
>  try:
> -from OpenSSL import SSL
> +import ssl
>  except ImportError:
> -SSL = None
> +ssl = None
>
>  try:
>  from eventlet import patcher as eventlet_patcher
> @@ -73,7 +73,7 @@ class _SelectSelect(object):
>  def register(self, fd, events):
>  if isinstance(fd, socket.socket):
>  fd = fd.fileno()
> -if SSL and isinstance(fd, SSL.Connection):
> +if ssl and isinstance(fd, ssl.SSLSocket):
>  fd = fd.fileno()
>
>  if sys.platform != 'win32':
> diff --git a/python/ovs/stream.py b/python/ovs/stream.py
> index f5a520862..40d484827 100644
> --- a/python/ovs/stream.py
> +++ b/python/ovs/stream.py
> @@ -22,9 +22,9 @@ import ovs.socket_util
>  import ovs.vlog
>
>  try:
> -from OpenSSL import SSL
> +import ssl
>  except ImportError:
> -SSL = None
> +ssl = None
>
>  if sys.platform == 'win32':
>  import ovs.winutils as winutils
> @@ -322,6 +322,12 @@ class Stream(object):
>  The recv function will not block waiting for data to arrive.  If no
>  data have been received, it returns (errno.EAGAIN, "") 
> immediately."""
>
> +try:
> +return self._recv(n)
> +except socket.error as e:
> +return (ovs.socket_util.get_exception_errno(e), "")
> +
> +def _recv(self, n):
>  retval = self.connect()
>  if retval != 0:
>  return (retval, "")
> @@ -331,10 +337,7 @@ class Stream(object):
>  if sys.platform == 'win32' and self.socket is None:
>  return self.__recv_windows(n)
>
> -try:
> -return (0, self.socket.recv(n))
> -except socket.error as e:
> -return (ovs.socket_util.get_exception_errno(e), "")
> +return (0, self.socket.recv(n))
>
>  def __recv_windows(self, n):
>  if self._read_pending:
> @@ -396,6 +399,12 @@ class Stream(object):
>  Will not block.  If no bytes can be immediately accepted for
>  transmission, returns -errno.EAGAIN immediately."""
>
> +try:
> +return self._send(buf)
> +except socket.error as e:
> +return -ovs.socket_util.get_exception_errno(e)
> +
> +def _send(self, buf):
>  retval = self.connect()
>  if retval != 0:
>  return -retval
> @@ -409,10 +418,7 @@ class Stream(object):
>  if 

[ovs-dev] [PATCH v3 2/2] python: replace pyOpenSSL with ssl

2021-10-25 Thread Timothy Redaelli
Currently, pyOpenSSL is half-deprecated upstream and so it's removed on
some distributions (for example on CentOS Stream 9,
https://issues.redhat.com/browse/CS-336), but since OVS only
supports Python 3 it's possible to replace pyOpenSSL with "import ssl"
included in base Python 3.

Stream recv and send had to be splitted as _recv and _send, since SSLError
is a subclass of socket.error and so it was not possible to except for
SSLWantReadError and SSLWantWriteError in recv and send of SSLStream.

TCPstream._open cannot be used in SSLStream, since Python ssl module
requires the SSL socket to be created before connecting it, so
SSLStream._open needs to create the socket, create SSL socket and then
connect the SSL socket.

Reported-by: Timothy Redaelli 
Reported-at: https://bugzilla.redhat.com/1988429
Signed-off-by: Timothy Redaelli 
---
 .ci/linux-prepare.sh |  2 +-
 .cirrus.yml  |  2 +-
 .travis.yml  |  1 -
 python/ovs/poller.py |  6 +--
 python/ovs/stream.py | 91 ++--
 tests/ovsdb-idl.at   |  2 +-
 6 files changed, 60 insertions(+), 44 deletions(-)

diff --git a/.ci/linux-prepare.sh b/.ci/linux-prepare.sh
index c55125cf7..b9b499bad 100755
--- a/.ci/linux-prepare.sh
+++ b/.ci/linux-prepare.sh
@@ -21,7 +21,7 @@ make -j4 HAVE_LLVM= HAVE_SQLITE= install
 cd ..
 
 pip3 install --disable-pip-version-check --user \
-flake8 hacking sphinx pyOpenSSL wheel setuptools
+flake8 hacking sphinx wheel setuptools
 pip3 install --user --upgrade docutils
 pip3 install --user  'meson==0.47.1'
 
diff --git a/.cirrus.yml b/.cirrus.yml
index 480fea242..a7ae793bc 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -9,7 +9,7 @@ freebsd_build_task:
 
   env:
 DEPENDENCIES: automake libtool gmake gcc wget openssl python3
-PY_DEPS:  sphinx|openssl
+PY_DEPS:  sphinx
 matrix:
   COMPILER: gcc
   COMPILER: clang
diff --git a/.travis.yml b/.travis.yml
index 51d051108..c7aeede06 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,7 +17,6 @@ addons:
   - libjemalloc-dev
   - libnuma-dev
   - libpcap-dev
-  - python3-openssl
   - python3-pip
   - python3-sphinx
   - libelf-dev
diff --git a/python/ovs/poller.py b/python/ovs/poller.py
index 3624ec865..157719c3a 100644
--- a/python/ovs/poller.py
+++ b/python/ovs/poller.py
@@ -26,9 +26,9 @@ if sys.platform == "win32":
 import ovs.winutils as winutils
 
 try:
-from OpenSSL import SSL
+import ssl
 except ImportError:
-SSL = None
+ssl = None
 
 try:
 from eventlet import patcher as eventlet_patcher
@@ -73,7 +73,7 @@ class _SelectSelect(object):
 def register(self, fd, events):
 if isinstance(fd, socket.socket):
 fd = fd.fileno()
-if SSL and isinstance(fd, SSL.Connection):
+if ssl and isinstance(fd, ssl.SSLSocket):
 fd = fd.fileno()
 
 if sys.platform != 'win32':
diff --git a/python/ovs/stream.py b/python/ovs/stream.py
index f5a520862..40d484827 100644
--- a/python/ovs/stream.py
+++ b/python/ovs/stream.py
@@ -22,9 +22,9 @@ import ovs.socket_util
 import ovs.vlog
 
 try:
-from OpenSSL import SSL
+import ssl
 except ImportError:
-SSL = None
+ssl = None
 
 if sys.platform == 'win32':
 import ovs.winutils as winutils
@@ -322,6 +322,12 @@ class Stream(object):
 The recv function will not block waiting for data to arrive.  If no
 data have been received, it returns (errno.EAGAIN, "") immediately."""
 
+try:
+return self._recv(n)
+except socket.error as e:
+return (ovs.socket_util.get_exception_errno(e), "")
+
+def _recv(self, n):
 retval = self.connect()
 if retval != 0:
 return (retval, "")
@@ -331,10 +337,7 @@ class Stream(object):
 if sys.platform == 'win32' and self.socket is None:
 return self.__recv_windows(n)
 
-try:
-return (0, self.socket.recv(n))
-except socket.error as e:
-return (ovs.socket_util.get_exception_errno(e), "")
+return (0, self.socket.recv(n))
 
 def __recv_windows(self, n):
 if self._read_pending:
@@ -396,6 +399,12 @@ class Stream(object):
 Will not block.  If no bytes can be immediately accepted for
 transmission, returns -errno.EAGAIN immediately."""
 
+try:
+return self._send(buf)
+except socket.error as e:
+return -ovs.socket_util.get_exception_errno(e)
+
+def _send(self, buf):
 retval = self.connect()
 if retval != 0:
 return -retval
@@ -409,10 +418,7 @@ class Stream(object):
 if sys.platform == 'win32' and self.socket is None:
 return self.__send_windows(buf)
 
-try:
-return self.socket.send(buf)
-except socket.error as e:
-return -ovs.socket_util.get_exception_errno(e)
+return self.socket.send(buf)
 
 def __send_windows(self, buf):