1// Package gssapi implements Generic Security Services Application Program Interface required for SPNEGO kerberos authentication. 2package gssapi 3 4import ( 5 "context" 6 "fmt" 7 8 "github.com/jcmturner/gofork/encoding/asn1" 9) 10 11// GSS-API OID names 12const ( 13 // GSS-API OID names 14 OIDKRB5 OIDName = "KRB5" // MechType OID for Kerberos 5 15 OIDMSLegacyKRB5 OIDName = "MSLegacyKRB5" // MechType OID for Kerberos 5 16 OIDSPNEGO OIDName = "SPNEGO" 17) 18 19// GSS-API status values 20const ( 21 StatusBadBindings = 1 << iota 22 StatusBadMech 23 StatusBadName 24 StatusBadNameType 25 StatusBadStatus 26 StatusBadSig 27 StatusBadMIC 28 StatusContextExpired 29 StatusCredentialsExpired 30 StatusDefectiveCredential 31 StatusDefectiveToken 32 StatusFailure 33 StatusNoContext 34 StatusNoCred 35 StatusBadQOP 36 StatusUnauthorized 37 StatusUnavailable 38 StatusDuplicateElement 39 StatusNameNotMN 40 StatusComplete 41 StatusContinueNeeded 42 StatusDuplicateToken 43 StatusOldToken 44 StatusUnseqToken 45 StatusGapToken 46) 47 48// ContextToken is an interface for a GSS-API context token. 49type ContextToken interface { 50 Marshal() ([]byte, error) 51 Unmarshal(b []byte) error 52 Verify() (bool, Status) 53 Context() context.Context 54} 55 56/* 57CREDENTIAL MANAGEMENT 58 59GSS_Acquire_cred acquire credentials for use 60GSS_Release_cred release credentials after use 61GSS_Inquire_cred display information about credentials 62GSS_Add_cred construct credentials incrementally 63GSS_Inquire_cred_by_mech display per-mechanism credential information 64 65CONTEXT-LEVEL CALLS 66 67GSS_Init_sec_context initiate outbound security context 68GSS_Accept_sec_context accept inbound security context 69GSS_Delete_sec_context flush context when no longer needed 70GSS_Process_context_token process received control token on context 71GSS_Context_time indicate validity time remaining on context 72GSS_Inquire_context display information about context 73GSS_Wrap_size_limit determine GSS_Wrap token size limit 74GSS_Export_sec_context transfer context to other process 75GSS_Import_sec_context import transferred context 76 77PER-MESSAGE CALLS 78 79GSS_GetMIC apply integrity check, receive as token separate from message 80GSS_VerifyMIC validate integrity check token along with message 81GSS_Wrap sign, optionally encrypt, encapsulate 82GSS_Unwrap decapsulate, decrypt if needed, validate integrity check 83 84SUPPORT CALLS 85 86GSS_Display_status translate status codes to printable form 87GSS_Indicate_mechs indicate mech_types supported on local system 88GSS_Compare_name compare two names for equality 89GSS_Display_name translate name to printable form 90GSS_Import_name convert printable name to normalized form 91GSS_Release_name free storage of normalized-form name 92GSS_Release_buffer free storage of general GSS-allocated object 93GSS_Release_OID_set free storage of OID set object 94GSS_Create_empty_OID_set create empty OID set 95GSS_Add_OID_set_member add member to OID set 96GSS_Test_OID_set_member test if OID is member of OID set 97GSS_Inquire_names_for_mech indicate name types supported by mechanism 98GSS_Inquire_mechs_for_name indicates mechanisms supporting name type 99GSS_Canonicalize_name translate name to per-mechanism form 100GSS_Export_name externalize per-mechanism name 101GSS_Duplicate_name duplicate name object 102*/ 103 104// Mechanism is the GSS-API interface for authentication mechanisms. 105type Mechanism interface { 106 OID() asn1.ObjectIdentifier 107 AcquireCred() error // acquire credentials for use (eg. AS exchange for KRB5) 108 InitSecContext() (ContextToken, error) // initiate outbound security context (eg TGS exchange builds AP_REQ to go into ContextToken to send to service) 109 AcceptSecContext(ct ContextToken) (bool, context.Context, Status) // service verifies the token server side to establish a context 110 MIC() MICToken // apply integrity check, receive as token separate from message 111 VerifyMIC(mt MICToken) (bool, error) // validate integrity check token along with message 112 Wrap(msg []byte) WrapToken // sign, optionally encrypt, encapsulate 113 Unwrap(wt WrapToken) []byte // decapsulate, decrypt if needed, validate integrity check 114} 115 116// OIDName is the type for defined GSS-API OIDs. 117type OIDName string 118 119// OID returns the OID for the provided OID name. 120func OID(o OIDName) asn1.ObjectIdentifier { 121 switch o { 122 case OIDSPNEGO: 123 return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 2} 124 case OIDKRB5: 125 return asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2} 126 case OIDMSLegacyKRB5: 127 return asn1.ObjectIdentifier{1, 2, 840, 48018, 1, 2, 2} 128 } 129 return asn1.ObjectIdentifier{} 130} 131 132// Status is the GSS-API status and implements the error interface. 133type Status struct { 134 Code int 135 Message string 136} 137 138// Error returns the Status description. 139func (s Status) Error() string { 140 var str string 141 switch s.Code { 142 case StatusBadBindings: 143 str = "channel binding mismatch" 144 case StatusBadMech: 145 str = "unsupported mechanism requested" 146 case StatusBadName: 147 str = "invalid name provided" 148 case StatusBadNameType: 149 str = "name of unsupported type provided" 150 case StatusBadStatus: 151 str = "invalid input status selector" 152 case StatusBadSig: 153 str = "token had invalid integrity check" 154 case StatusBadMIC: 155 str = "preferred alias for GSS_S_BAD_SIG" 156 case StatusContextExpired: 157 str = "specified security context expired" 158 case StatusCredentialsExpired: 159 str = "expired credentials detected" 160 case StatusDefectiveCredential: 161 str = "defective credential detected" 162 case StatusDefectiveToken: 163 str = "defective token detected" 164 case StatusFailure: 165 str = "failure, unspecified at GSS-API level" 166 case StatusNoContext: 167 str = "no valid security context specified" 168 case StatusNoCred: 169 str = "no valid credentials provided" 170 case StatusBadQOP: 171 str = "unsupported QOP valu" 172 case StatusUnauthorized: 173 str = "operation unauthorized" 174 case StatusUnavailable: 175 str = "operation unavailable" 176 case StatusDuplicateElement: 177 str = "duplicate credential element requested" 178 case StatusNameNotMN: 179 str = "name contains multi-mechanism elements" 180 case StatusComplete: 181 str = "normal completion" 182 case StatusContinueNeeded: 183 str = "continuation call to routine required" 184 case StatusDuplicateToken: 185 str = "duplicate per-message token detected" 186 case StatusOldToken: 187 str = "timed-out per-message token detected" 188 case StatusUnseqToken: 189 str = "reordered (early) per-message token detected" 190 case StatusGapToken: 191 str = "skipped predecessor token(s) detected" 192 default: 193 str = "unknown GSS-API error status" 194 } 195 if s.Message != "" { 196 return fmt.Sprintf("%s: %s", str, s.Message) 197 } 198 return str 199} 200