-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from schlenk/claim_no_mic_options
Claim no message integrity options
- Loading branch information
Showing
1 changed file
with
51 additions
and
42 deletions.
There are no files selected for viewing
This file contains 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 |
---|---|---|
|
@@ -46,9 +46,9 @@ class GSSError(KrbError): | |
|
||
def _sspi_spn_from_nt_service_name(nt_service_name, realm=None): | ||
""" | ||
create a service name consumable by sspi from the nt_service_name fromat used by krb, | ||
create a service name consumable by sspi from the nt_service_name format used by krb, | ||
e.g. from http@somehost -> http/somehost[@REALM] | ||
""" | ||
global hostname, defaultrealm | ||
if "/" not in nt_service_name and "@" in nt_service_name: | ||
|
@@ -71,11 +71,11 @@ def checkPassword(user, pswd, service, default_realm): | |
those normally used for Kerberos authentication. It does this by checking that the | ||
supplied user name and password can be used to get a ticket for the supplied service. | ||
If the user name does not contain a realm, then the default realm supplied is used. | ||
NB For this to work properly the Kerberos must be configured properly on this machine. | ||
That will likely mean ensuring that the edu.mit.Kerberos preference file has the correct | ||
realms and KDCs listed. | ||
@param user: a string containing the Kerberos user name. A realm may be | ||
included by appending an '@' followed by the realm string to the actual user id. | ||
If no realm is supplied, then the realm set in the default_realm argument will | ||
|
@@ -125,7 +125,7 @@ def getServerPrincipalDetails(service, hostname): | |
""" | ||
This function returns the service principal for the server given a service type | ||
and hostname. Details are looked up via the /etc/keytab file. | ||
@param service: a string containing the Kerberos service type for the server. | ||
@param hostname: a string containing the hostname of the server. | ||
@return: a string containing the service principal. | ||
|
@@ -135,30 +135,30 @@ def getServerPrincipalDetails(service, hostname): | |
|
||
""" | ||
GSSAPI Function Result Codes: | ||
-1 : Error | ||
0 : GSSAPI step continuation (only returned by 'Step' function) | ||
1 : GSSAPI step complete, or function return OK | ||
""" | ||
|
||
# Some useful result codes | ||
AUTH_GSS_CONTINUE = 0 | ||
AUTH_GSS_COMPLETE = 1 | ||
# Some useful gss flags | ||
GSS_C_DELEG_FLAG = sspicon.ISC_REQ_DELEGATE | ||
AUTH_GSS_CONTINUE = 0 | ||
AUTH_GSS_COMPLETE = 1 | ||
|
||
# Some useful gss flags | ||
GSS_C_DELEG_FLAG = sspicon.ISC_REQ_DELEGATE | ||
GSS_C_MUTUAL_FLAG = sspicon.ISC_REQ_MUTUAL_AUTH | ||
GSS_C_REPLAY_FLAG = sspicon.ISC_REQ_REPLAY_DETECT | ||
GSS_C_SEQUENCE_FLAG = sspicon.ISC_REQ_SEQUENCE_DETECT | ||
GSS_C_CONF_FLAG = sspicon.ISC_REQ_CONFIDENTIALITY | ||
GSS_C_INTEG_FLAG = sspicon.ISC_REQ_INTEGRITY | ||
GSS_C_CONF_FLAG = sspicon.ISC_REQ_CONFIDENTIALITY | ||
GSS_C_INTEG_FLAG = sspicon.ISC_REQ_INTEGRITY | ||
|
||
# leave the following undefined, so if someone relies on them they know that this package | ||
# is not for them | ||
#GSS_C_ANON_FLAG = 0 | ||
#GSS_C_PROT_READY_FLAG = 0 | ||
#GSS_C_TRANS_FLAG = 0 | ||
#GSS_C_ANON_FLAG = 0 | ||
#GSS_C_PROT_READY_FLAG = 0 | ||
#GSS_C_TRANS_FLAG = 0 | ||
|
||
GSS_AUTH_P_NONE = 1 | ||
GSS_AUTH_P_INTEGRITY = 2 | ||
|
@@ -176,15 +176,15 @@ def authGSSClientInit(service, gssflags=GSS_C_MUTUAL_FLAG|GSS_C_SEQUENCE_FLAG): | |
@param service: a string containing the service principal in the form 'type@fqdn' | ||
(e.g. '[email protected]'). | ||
@param gssflags: optional integer used to set GSS flags. | ||
(e.g. GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_SEQUENCE_FLAG will allow | ||
(e.g. GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_SEQUENCE_FLAG will allow | ||
for forwarding credentials to the remote host) | ||
@return: a tuple of (result, context) where result is the result code (see above) and | ||
context is an opaque value that will need to be passed to subsequent functions. | ||
""" | ||
|
||
spn=_sspi_spn_from_nt_service_name(service) | ||
ctx={"csa":sspi.ClientAuth("Kerberos", scflags=gssflags, targetspn=spn), | ||
"service":service, | ||
ctx={"csa":sspi.ClientAuth("Kerberos", scflags=gssflags, targetspn=spn), | ||
"service":service, | ||
"gssflags":gssflags, | ||
"response":None | ||
} | ||
|
@@ -242,12 +242,12 @@ def authGSSClientUserName(context): | |
|
||
return context["csa"].ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_NAMES) | ||
|
||
def authGSSClientUnwrap(context, challenge): | ||
""" | ||
Perform the client side GSSAPI unwrap step | ||
@param challenge: a string containing the base64-encoded server data. | ||
@return: a result code (see above) | ||
def authGSSClientUnwrap(context, challenge): | ||
""" | ||
Perform the client side GSSAPI unwrap step | ||
@param challenge: a string containing the base64-encoded server data. | ||
@return: a result code (see above) | ||
""" | ||
data = decodestring(challenge) if challenge else None | ||
|
||
|
@@ -259,33 +259,42 @@ def authGSSClientUnwrap(context, challenge): | |
encbuf[1].Buffer=data | ||
ca.ctxt.DecryptMessage(encbuf,ca._get_next_seq_num()) | ||
context["response"]= encbuf[0].Buffer | ||
|
||
return AUTH_GSS_COMPLETE | ||
|
||
def authGSSClientWrap(context, data, user=None): | ||
""" | ||
Perform the client side GSSAPI wrap step. | ||
@param data:the result of the authGSSClientResponse after the authGSSClientUnwrap | ||
@param user: the user to authorize | ||
@return: a result code (see above) | ||
""" | ||
def authGSSClientWrap(context, data, user=None): | ||
""" | ||
Perform the client side GSSAPI wrap step. | ||
@param data:the result of the authGSSClientResponse after the authGSSClientUnwrap | ||
@param user: the user to authorize | ||
@return: a result code (see above) | ||
""" | ||
|
||
ca = context["csa"] | ||
|
||
data = decodestring(data) if data else None | ||
# RFC 4752 Section 3.1 last 2 paragraphs | ||
if user and data: | ||
if data: | ||
import struct | ||
conf_and_size = data[:struct.calcsize("!L")] # network unsigned long | ||
conf = struct.unpack("B", conf_and_size[0])[0] # B .. unsigned char | ||
size = struct.unpack("!L", conf_and_size)[0] & 0x00ffffff | ||
logger.info("N" if conf & GSS_AUTH_P_NONE else "-") | ||
logger.info("I" if conf & GSS_AUTH_P_INTEGRITY else "-") | ||
logger.info("P" if conf & GSS_AUTH_P_PRIVACY else "-") | ||
logger.info("Maximum GSS token size is %d", size) | ||
conf_and_size=chr(GSS_AUTH_P_NONE) + conf_and_size[1:] | ||
data = conf_and_size + user.encode("utf-8") | ||
logger.info("Maximum GSS message size for server side is %d", size) | ||
# Tell the truth, we do not handle any security layer | ||
# (aka GSS_AUTH_P_NONE). RFC 4752 demands that the | ||
# max client message size is zero in this case. | ||
max_size_client_message = 0 | ||
security_layer = GSS_AUTH_P_NONE | ||
conf_and_size = struct.pack("!L", security_layer << 24 + | ||
(max_size_client_message & 0x00ffffff)) | ||
if user: | ||
data = conf_and_size + user.encode("utf-8") | ||
else: | ||
data = conf_and_size | ||
|
||
pkg_size_info=ca.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES) | ||
trailersize=pkg_size_info['SecurityTrailer'] | ||
|
@@ -299,7 +308,7 @@ def authGSSClientWrap(context, data, user=None): | |
ca.ctxt.EncryptMessage(0,encbuf, ca._get_next_seq_num()) | ||
#ca.ctxt.EncryptMessage(0,encbuf, 0) | ||
|
||
|
||
context["response"] = encbuf[0].Buffer+encbuf[1].Buffer+encbuf[2].Buffer | ||
|
||
return AUTH_GSS_COMPLETE | ||
|
@@ -316,8 +325,8 @@ def authGSSServerInit(service): | |
context is an opaque value that will need to be passed to subsequent functions. | ||
""" | ||
spn=_sspi_spn_from_nt_service_name(service) | ||
ctx={"csa":sspi.ServerAuth("Kerberos", spn=spn), | ||
"service":service, | ||
ctx={"csa":sspi.ServerAuth("Kerberos", spn=spn), | ||
"service":service, | ||
"response":None, | ||
} | ||
return AUTH_GSS_COMPLETE, ctx | ||
|