From 178cec24993d7d74bde4f35de5b8f57cff07280f Mon Sep 17 00:00:00 2001 From: Sriram Raghu Date: Sun, 24 Feb 2019 13:24:40 -0500 Subject: [PATCH 1/4] Add hooks for GIT_OPT_SET_SSL_CERT_LOCATIONS in C Bind them to git_libgit2_opts --- src/options.c | 30 ++++++++++++++++++++++++++++++ src/pygit2.c | 1 + 2 files changed, 31 insertions(+) diff --git a/src/options.c b/src/options.c index 7e3e1f089..0968277d3 100644 --- a/src/options.c +++ b/src/options.c @@ -272,6 +272,36 @@ option(PyObject *self, PyObject *args) return tup; } + case GIT_OPT_SET_SSL_CERT_LOCATIONS: + { + PyObject *py_file, *py_dir; + const char *file_path, *dir_path; + int err; + + py_file = PyTuple_GetItem(args, 1); + py_dir = PyTuple_GetItem(args, 2); + + /* py_file and py_dir are only valid if they are strings */ + if (PyUnicode_Check(py_file) || PyBytes_Check(py_file)) { + file_path = py_str_to_c_str(py_file, Py_FileSystemDefaultEncoding); + } else { + file_path = NULL; + } + + if (PyUnicode_Check(py_dir) || PyBytes_Check(py_dir)) { + dir_path = py_str_to_c_str(py_dir, Py_FileSystemDefaultEncoding); + } else { + dir_path = NULL; + } + + err = git_libgit2_opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, file_path, dir_path); + + if (err < 0) + return Error_set(err); + + Py_RETURN_NONE; + } + } PyErr_SetString(PyExc_ValueError, "unknown/unsupported option value"); diff --git a/src/pygit2.c b/src/pygit2.c index 06141cef9..defd32f06 100644 --- a/src/pygit2.c +++ b/src/pygit2.c @@ -242,6 +242,7 @@ moduleinit(PyObject* m) ADD_CONSTANT_INT(m, GIT_OPT_GET_CACHED_MEMORY); ADD_CONSTANT_INT(m, GIT_OPT_ENABLE_CACHING); ADD_CONSTANT_INT(m, GIT_OPT_SET_CACHE_MAX_SIZE); + ADD_CONSTANT_INT(m, GIT_OPT_SET_SSL_CERT_LOCATIONS); /* Errors */ GitError = PyErr_NewException("_pygit2.GitError", NULL, NULL); From cf9c5acca0e415189b52679de4f2603e6c5615ca Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sat, 2 Mar 2019 12:12:32 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=8E=A8=20Improve=20docstrings=20in=20?= =?UTF-8?q?settings=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pygit2/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pygit2/settings.py b/pygit2/settings.py index 9d5fd2f6a..97e9bdf49 100644 --- a/pygit2/settings.py +++ b/pygit2/settings.py @@ -24,6 +24,7 @@ # along with this program; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. +"""Settings mapping.""" from _pygit2 import option from _pygit2 import GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH @@ -45,7 +46,7 @@ def __setitem__(self, key, value): class Settings(object): - """Library-wide settings""" + """Library-wide settings interface.""" __slots__ = [] From a1505e6ccc1502c11f897c118592b988fbeda4d3 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sat, 2 Mar 2019 12:13:04 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=8E=A8=20Enable=20new-style=20cls=20b?= =?UTF-8?q?y=20default=20in=20settings=20mod?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pygit2/settings.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pygit2/settings.py b/pygit2/settings.py index 97e9bdf49..5bbe74189 100644 --- a/pygit2/settings.py +++ b/pygit2/settings.py @@ -36,7 +36,11 @@ from _pygit2 import GIT_OPT_SET_CACHE_MAX_SIZE -class SearchPathList(object): + +__metaclass__ = type # make all classes new-style by default + + +class SearchPathList: def __getitem__(self, key): return option(GIT_OPT_GET_SEARCH_PATH, key) @@ -45,7 +49,7 @@ def __setitem__(self, key, value): option(GIT_OPT_SET_SEARCH_PATH, key, value) -class Settings(object): +class Settings: """Library-wide settings interface.""" __slots__ = [] From ca610262097ab9235136725df3c3a784e55f6f26 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Tue, 5 Mar 2019 13:49:02 +0100 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=8E=A8=20Wire=20up=20TLS=20cert=20opt?= =?UTF-8?q?ion=20interfaces=20in=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usage:: import pygit2 pygit2.settings.ssl_cert_file = '/path/to/file' pygit2.settings.ssl_cert_dir = '/path/to/folder' del pygit2.settings.ssl_cert_file pygit2.settings.set_ssl_cert_locations( '/path/to/new/file', '/path/to/new/folder', ) Co-authored-by: Sriram Raghu Closes #876 Superseeds and closes #879 --- pygit2/settings.py | 48 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/pygit2/settings.py b/pygit2/settings.py index 5bbe74189..43904c5b0 100644 --- a/pygit2/settings.py +++ b/pygit2/settings.py @@ -26,6 +26,8 @@ # Boston, MA 02110-1301, USA. """Settings mapping.""" +from ssl import get_default_verify_paths + from _pygit2 import option from _pygit2 import GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH from _pygit2 import GIT_OPT_GET_MWINDOW_SIZE, GIT_OPT_SET_MWINDOW_SIZE @@ -34,7 +36,7 @@ from _pygit2 import GIT_OPT_GET_CACHED_MEMORY from _pygit2 import GIT_OPT_ENABLE_CACHING from _pygit2 import GIT_OPT_SET_CACHE_MAX_SIZE - +from _pygit2 import GIT_OPT_SET_SSL_CERT_LOCATIONS __metaclass__ = type # make all classes new-style by default @@ -52,10 +54,17 @@ def __setitem__(self, key, value): class Settings: """Library-wide settings interface.""" - __slots__ = [] + __slots__ = '_default_tls_verify_paths', '_ssl_cert_dir', '_ssl_cert_file' _search_path = SearchPathList() + def __init__(self): + self._default_tls_verify_paths = get_default_verify_paths() + self.set_ssl_cert_locations( + self._default_tls_verify_paths.cafile, + self._default_tls_verify_paths.capath, + ) + @property def search_path(self): """Configuration file search path. @@ -106,4 +115,39 @@ def cache_object_limit(self, object_type, value): """ return option(GIT_OPT_SET_CACHE_OBJECT_LIMIT, object_type, value) + @property + def ssl_cert_file(self): + """TLS certificate file path.""" + return self._ssl_cert_file + + @ssl_cert_file.setter + def ssl_cert_file(self, value): + """Set the TLS cert file path.""" + self.set_ssl_cert_locations(value, self._ssl_cert_dir) + + @ssl_cert_file.deleter + def ssl_cert_file(self): + """Reset the TLS cert file path.""" + self.ssl_cert_file = self._default_tls_verify_paths.cafile + @property + def ssl_cert_dir(self): + """TLS certificates lookup directory path.""" + return self._ssl_cert_dir + + @ssl_cert_dir.setter + def ssl_cert_dir(self, value): + """Set the TLS certificate lookup folder.""" + self.set_ssl_cert_locations(self._ssl_cert_file, value) + + @ssl_cert_dir.deleter + def ssl_cert_dir(self): + """Reset the TLS certificate lookup folder.""" + self.ssl_cert_dir = self._default_tls_verify_paths.capath + + def set_ssl_cert_locations(self, ssl_cert_file, ssl_cert_dir): + """Set both file path and lookup dir for TLS certs in libgit2. + """ + option(GIT_OPT_SET_SSL_CERT_LOCATIONS, ssl_cert_file, ssl_cert_dir) + self._ssl_cert_file = ssl_cert_file + self._ssl_cert_dir = ssl_cert_dir