Skip to content

Expose setting TLS file and dir lookup locations via settings module #884

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 53 additions & 4 deletions pygit2/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
# 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 ssl import get_default_verify_paths

from _pygit2 import option
from _pygit2 import GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH
Expand All @@ -33,9 +36,13 @@
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


class SearchPathList(object):
class SearchPathList:

def __getitem__(self, key):
return option(GIT_OPT_GET_SEARCH_PATH, key)
Expand All @@ -44,13 +51,20 @@ def __setitem__(self, key, value):
option(GIT_OPT_SET_SEARCH_PATH, key, value)


class Settings(object):
"""Library-wide settings"""
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.
Expand Down Expand Up @@ -101,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
30 changes: 30 additions & 0 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions src/pygit2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down