-
Notifications
You must be signed in to change notification settings - Fork 55
Add gss_localname and friends #374
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
Open
JacobHenner
wants to merge
2
commits into
pythongssapi:main
Choose a base branch
from
JacobHenner:feat/gss_localname-and-friends
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| import typing as t | ||
|
|
||
| if t.TYPE_CHECKING: | ||
| from gssapi.raw.names import Name | ||
| from gssapi.raw.oids import OID | ||
|
|
||
|
|
||
| def localname( | ||
| name: "Name", | ||
| mech: t.Optional["OID"] = None, | ||
| ) -> bytes: | ||
| """Get the local name for a GSSAPI name. | ||
|
|
||
| This method determines the local name associated with a GSSAPI | ||
| name, optionally for a given mechanism. | ||
|
|
||
| Args: | ||
| name (Name): the GSSAPI name to map to a local name | ||
| mech (~gssapi.OID): the mechanism to use for the mapping | ||
| (or None for the default) | ||
|
|
||
| Returns: | ||
| bytes: the local name | ||
|
|
||
| Raises: | ||
| ~gssapi.exceptions.GSSError | ||
| """ | ||
|
|
||
|
|
||
| def userok( | ||
| name: "Name", | ||
| username: t.Union[bytes, str], | ||
| ) -> bool: | ||
| """Determine whether a GSSAPI name is authorized to act as a local user. | ||
|
|
||
| This method determines whether a given GSSAPI name is authorized | ||
| to act as the given local username. This is a simple wrapper | ||
| around :func:`authorize_localname` that only supports system | ||
| usernames as local names. | ||
|
|
||
| Args: | ||
| name (Name): the GSSAPI name to check | ||
| username (Union[bytes, str]): the local username to check against | ||
|
|
||
| Returns: | ||
| bool: whether or not the name is authorized to act as the user | ||
| """ | ||
|
|
||
|
|
||
| def authorize_localname( | ||
| name: "Name", | ||
| user: "Name", | ||
| ) -> bool: | ||
| """Determine whether a GSSAPI name is authorized to act as a local name. | ||
|
|
||
| This method determines whether a given GSSAPI name is authorized | ||
| to act as the given local name. | ||
|
|
||
| Args: | ||
| name (Name): the mechanism name to check | ||
| user (Name): the local name to check against | ||
|
|
||
| Returns: | ||
| bool: whether or not the name is authorized | ||
|
|
||
| Raises: | ||
| ~gssapi.exceptions.GSSError | ||
| """ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| GSSAPI="BASE" # This ensures that a full module is generated by Cython | ||
|
|
||
| from gssapi.raw.cython_types cimport * | ||
| from gssapi.raw.names cimport Name | ||
| from gssapi.raw.oids cimport OID | ||
|
|
||
| from gssapi.raw.misc import GSSError | ||
| from gssapi import _utils | ||
|
|
||
| cdef extern from "python_gssapi_ext.h": | ||
| OM_uint32 gss_localname(OM_uint32 *minor, | ||
| const gss_name_t name, | ||
| const gss_OID mech_type, | ||
| gss_buffer_t localname) nogil | ||
|
|
||
| int gss_userok(const gss_name_t name, | ||
| const char *username) nogil | ||
|
|
||
| OM_uint32 gss_authorize_localname(OM_uint32 *minor, | ||
| const gss_name_t name, | ||
| const gss_name_t user) nogil | ||
|
|
||
|
|
||
| def localname(Name name not None, OID mech=None): | ||
| """Get the local name for a GSSAPI name. | ||
|
|
||
| This method determines the local name associated with a GSSAPI | ||
| name, optionally for a given mechanism. | ||
|
|
||
| Args: | ||
| name (Name): the GSSAPI name to map to a local name | ||
| mech (~gssapi.OID): the mechanism to use for the mapping | ||
| (or None for the default) | ||
|
|
||
| Returns: | ||
| bytes: the local name | ||
|
|
||
| Raises: | ||
| ~gssapi.exceptions.GSSError | ||
| """ | ||
| cdef gss_OID m = GSS_C_NO_OID | ||
| if mech is not None: | ||
| m = &mech.raw_oid | ||
|
|
||
| cdef gss_buffer_desc output = gss_buffer_desc(0, NULL) | ||
|
|
||
| cdef OM_uint32 maj_stat, min_stat | ||
|
|
||
| with nogil: | ||
| maj_stat = gss_localname(&min_stat, name.raw_name, m, &output) | ||
|
|
||
| if maj_stat == GSS_S_COMPLETE: | ||
| py_output = (<char*>output.value)[:output.length] | ||
| gss_release_buffer(&min_stat, &output) | ||
| return py_output | ||
| else: | ||
| raise GSSError(maj_stat, min_stat) | ||
|
|
||
|
|
||
| def userok(Name name not None, username not None): | ||
| """Determine whether a GSSAPI name is authorized to act as a local user. | ||
|
|
||
| This method determines whether a given GSSAPI name is authorized | ||
| to act as the given local username. This is a simple wrapper | ||
| around :func:`authorize_localname` that only supports system | ||
| usernames as local names. | ||
|
|
||
| Args: | ||
| name (Name): the GSSAPI name to check | ||
| username (Union[bytes, str]): the local username to check against | ||
|
|
||
| Returns: | ||
| bool: whether or not the name is authorized to act as the user | ||
| """ | ||
| cdef int res | ||
|
|
||
| if isinstance(username, str): | ||
| username = username.encode(_utils._get_encoding()) | ||
|
Comment on lines
+77
to
+78
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a benefit to accepting both bytes and str here? I would have thought we would just use bytes but it's been a while since I've looked at what some of the other functions are doing. |
||
|
|
||
| cdef char *c_username = username | ||
|
|
||
| with nogil: | ||
| res = gss_userok(name.raw_name, c_username) | ||
|
|
||
| return res == 1 | ||
|
|
||
|
|
||
| def authorize_localname(Name name not None, Name user not None): | ||
| """Determine whether a GSSAPI name is authorized to act as a local name. | ||
|
|
||
| This method determines whether a given GSSAPI name is authorized | ||
| to act as the given local name. | ||
|
|
||
| Args: | ||
| name (Name): the mechanism name to check | ||
| user (Name): the local name to check against | ||
|
|
||
| Returns: | ||
| bool: whether or not the name is authorized | ||
|
|
||
| Raises: | ||
| ~gssapi.exceptions.GSSError | ||
| """ | ||
| cdef OM_uint32 maj_stat, min_stat | ||
|
|
||
| with nogil: | ||
| maj_stat = gss_authorize_localname(&min_stat, name.raw_name, | ||
| user.raw_name) | ||
|
|
||
| if maj_stat == GSS_S_COMPLETE: | ||
| return True | ||
| else: | ||
| raise GSSError(maj_stat, min_stat) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| ATTR_LOCAL_LOGIN_USER: bytes | ||
| """The attribute name for the local login username. | ||
|
|
||
| This can be used with RFC 6680 :func:`~gssapi.raw.ext_rfc6680.get_name_attribute` | ||
| and :func:`~gssapi.raw.ext_rfc6680.set_name_attribute` to retrieve or set the | ||
| local login username for a GSSAPI name. | ||
| """ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| GSSAPI="BASE" # This ensures that a full module is generated by Cython | ||
|
|
||
| from gssapi.raw.cython_types cimport gss_buffer_t | ||
|
|
||
| cdef extern from "python_gssapi_ext.h": | ||
| gss_buffer_t GSS_C_ATTR_LOCAL_LOGIN_USER | ||
|
|
||
|
|
||
| # Export the attribute name constant as a Python bytes object. | ||
| # This can be used with RFC 6680 get_name_attribute/set_name_attribute | ||
| # to retrieve or set the local login username for a GSSAPI name. | ||
| ATTR_LOCAL_LOGIN_USER = (<char*>GSS_C_ATTR_LOCAL_LOGIN_USER.value)[ | ||
| :GSS_C_ATTR_LOCAL_LOGIN_USER.length] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import typing as t | ||
|
|
||
| if t.TYPE_CHECKING: | ||
| from gssapi.raw.names import Name | ||
| from gssapi.raw.oids import OID | ||
|
|
||
|
|
||
| def pname_to_uid( | ||
| name: "Name", | ||
| mech: t.Optional["OID"] = None, | ||
| ) -> int: | ||
| """Get the local UID for a GSSAPI name. | ||
|
|
||
| This method determines the local UID associated with a GSSAPI | ||
| name, optionally for a given mechanism. | ||
|
|
||
| Note: | ||
| This function is not available on Windows. | ||
|
|
||
| Args: | ||
| name (Name): the GSSAPI name to map to a local UID | ||
| mech (~gssapi.OID): the mechanism to use for the mapping | ||
| (or None for the default) | ||
|
|
||
| Returns: | ||
| int: the local UID | ||
|
|
||
| Raises: | ||
| ~gssapi.exceptions.GSSError | ||
| """ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| GSSAPI="BASE" # This ensures that a full module is generated by Cython | ||
|
|
||
| from posix.types cimport uid_t | ||
|
|
||
| from gssapi.raw.cython_types cimport * | ||
| from gssapi.raw.names cimport Name | ||
| from gssapi.raw.oids cimport OID | ||
|
|
||
| from gssapi.raw.misc import GSSError | ||
|
|
||
| cdef extern from "python_gssapi_ext.h": | ||
| OM_uint32 gss_pname_to_uid(OM_uint32 *minor, | ||
| const gss_name_t name, | ||
| const gss_OID mech_type, | ||
| uid_t *uid_out) nogil | ||
|
|
||
|
|
||
| def pname_to_uid(Name name not None, OID mech=None): | ||
| """Get the local UID for a GSSAPI name. | ||
|
|
||
| This method determines the local UID associated with a GSSAPI | ||
| name, optionally for a given mechanism. | ||
|
|
||
| Note: | ||
| This function is not available on Windows. | ||
|
|
||
| Args: | ||
| name (Name): the GSSAPI name to map to a local UID | ||
| mech (~gssapi.OID): the mechanism to use for the mapping | ||
| (or None for the default) | ||
|
|
||
| Returns: | ||
| int: the local UID | ||
|
|
||
| Raises: | ||
| ~gssapi.exceptions.GSSError | ||
| """ | ||
| cdef gss_OID m = GSS_C_NO_OID | ||
| if mech is not None: | ||
| m = &mech.raw_oid | ||
|
|
||
| cdef uid_t uid_out | ||
| cdef OM_uint32 maj_stat, min_stat | ||
|
|
||
| with nogil: | ||
| maj_stat = gss_pname_to_uid(&min_stat, name.raw_name, m, &uid_out) | ||
|
|
||
| if maj_stat == GSS_S_COMPLETE: | ||
| return uid_out | ||
| else: | ||
| raise GSSError(maj_stat, min_stat) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this check, I don't think the names and oids files will need to import this ext file and we shouldn't need to use the
t.TYPE_CHECKINGconditional import.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was following the pattern I observed in the other ext_*.pyi files within the same directory, but perhaps I've overlooked some other aspect that establishes the necessity for this block. What's the criteria for including/not including?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fairly certain it's only there when there are circular imports, e.g.
namesoroidsimport this file. The__init__.pyis somewhat different enough that maybe it is required here but I wouldn't have thought so.