123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- // Package gssapi implements Generic Security Services Application Program Interface required for SPNEGO kerberos authentication.
- package gssapi
- import (
- "context"
- "fmt"
- "github.com/jcmturner/gofork/encoding/asn1"
- )
- // GSS-API OID names
- const (
- // GSS-API OID names
- OIDKRB5 OIDName = "KRB5" // MechType OID for Kerberos 5
- OIDMSLegacyKRB5 OIDName = "MSLegacyKRB5" // MechType OID for Kerberos 5
- OIDSPNEGO OIDName = "SPNEGO"
- OIDGSSIAKerb OIDName = "GSSIAKerb" // Indicates the client cannot get a service ticket and asks the server to serve as an intermediate to the target KDC. http://k5wiki.kerberos.org/wiki/Projects/IAKERB#IAKERB_mech
- )
- // GSS-API status values
- const (
- StatusBadBindings = 1 << iota
- StatusBadMech
- StatusBadName
- StatusBadNameType
- StatusBadStatus
- StatusBadSig
- StatusBadMIC
- StatusContextExpired
- StatusCredentialsExpired
- StatusDefectiveCredential
- StatusDefectiveToken
- StatusFailure
- StatusNoContext
- StatusNoCred
- StatusBadQOP
- StatusUnauthorized
- StatusUnavailable
- StatusDuplicateElement
- StatusNameNotMN
- StatusComplete
- StatusContinueNeeded
- StatusDuplicateToken
- StatusOldToken
- StatusUnseqToken
- StatusGapToken
- )
- // ContextToken is an interface for a GSS-API context token.
- type ContextToken interface {
- Marshal() ([]byte, error)
- Unmarshal(b []byte) error
- Verify() (bool, Status)
- Context() context.Context
- }
- /*
- CREDENTIAL MANAGEMENT
- GSS_Acquire_cred acquire credentials for use
- GSS_Release_cred release credentials after use
- GSS_Inquire_cred display information about credentials
- GSS_Add_cred construct credentials incrementally
- GSS_Inquire_cred_by_mech display per-mechanism credential information
- CONTEXT-LEVEL CALLS
- GSS_Init_sec_context initiate outbound security context
- GSS_Accept_sec_context accept inbound security context
- GSS_Delete_sec_context flush context when no longer needed
- GSS_Process_context_token process received control token on context
- GSS_Context_time indicate validity time remaining on context
- GSS_Inquire_context display information about context
- GSS_Wrap_size_limit determine GSS_Wrap token size limit
- GSS_Export_sec_context transfer context to other process
- GSS_Import_sec_context import transferred context
- PER-MESSAGE CALLS
- GSS_GetMIC apply integrity check, receive as token separate from message
- GSS_VerifyMIC validate integrity check token along with message
- GSS_Wrap sign, optionally encrypt, encapsulate
- GSS_Unwrap decapsulate, decrypt if needed, validate integrity check
- SUPPORT CALLS
- GSS_Display_status translate status codes to printable form
- GSS_Indicate_mechs indicate mech_types supported on local system
- GSS_Compare_name compare two names for equality
- GSS_Display_name translate name to printable form
- GSS_Import_name convert printable name to normalized form
- GSS_Release_name free storage of normalized-form name
- GSS_Release_buffer free storage of general GSS-allocated object
- GSS_Release_OID_set free storage of OID set object
- GSS_Create_empty_OID_set create empty OID set
- GSS_Add_OID_set_member add member to OID set
- GSS_Test_OID_set_member test if OID is member of OID set
- GSS_Inquire_names_for_mech indicate name types supported by mechanism
- GSS_Inquire_mechs_for_name indicates mechanisms supporting name type
- GSS_Canonicalize_name translate name to per-mechanism form
- GSS_Export_name externalize per-mechanism name
- GSS_Duplicate_name duplicate name object
- */
- // Mechanism is the GSS-API interface for authentication mechanisms.
- type Mechanism interface {
- OID() asn1.ObjectIdentifier
- AcquireCred() error // acquire credentials for use (eg. AS exchange for KRB5)
- InitSecContext() (ContextToken, error) // initiate outbound security context (eg TGS exchange builds AP_REQ to go into ContextToken to send to service)
- AcceptSecContext(ct ContextToken) (bool, context.Context, Status) // service verifies the token server side to establish a context
- MIC() MICToken // apply integrity check, receive as token separate from message
- VerifyMIC(mt MICToken) (bool, error) // validate integrity check token along with message
- Wrap(msg []byte) WrapToken // sign, optionally encrypt, encapsulate
- Unwrap(wt WrapToken) []byte // decapsulate, decrypt if needed, validate integrity check
- }
- // OIDName is the type for defined GSS-API OIDs.
- type OIDName string
- // OID returns the OID for the provided OID name.
- func (o OIDName) OID() asn1.ObjectIdentifier {
- switch o {
- case OIDSPNEGO:
- return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 2}
- case OIDKRB5:
- return asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
- case OIDMSLegacyKRB5:
- return asn1.ObjectIdentifier{1, 2, 840, 48018, 1, 2, 2}
- case OIDGSSIAKerb:
- return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 2, 5}
- }
- return asn1.ObjectIdentifier{}
- }
- // Status is the GSS-API status and implements the error interface.
- type Status struct {
- Code int
- Message string
- }
- // Error returns the Status description.
- func (s Status) Error() string {
- var str string
- switch s.Code {
- case StatusBadBindings:
- str = "channel binding mismatch"
- case StatusBadMech:
- str = "unsupported mechanism requested"
- case StatusBadName:
- str = "invalid name provided"
- case StatusBadNameType:
- str = "name of unsupported type provided"
- case StatusBadStatus:
- str = "invalid input status selector"
- case StatusBadSig:
- str = "token had invalid integrity check"
- case StatusBadMIC:
- str = "preferred alias for GSS_S_BAD_SIG"
- case StatusContextExpired:
- str = "specified security context expired"
- case StatusCredentialsExpired:
- str = "expired credentials detected"
- case StatusDefectiveCredential:
- str = "defective credential detected"
- case StatusDefectiveToken:
- str = "defective token detected"
- case StatusFailure:
- str = "failure, unspecified at GSS-API level"
- case StatusNoContext:
- str = "no valid security context specified"
- case StatusNoCred:
- str = "no valid credentials provided"
- case StatusBadQOP:
- str = "unsupported QOP valu"
- case StatusUnauthorized:
- str = "operation unauthorized"
- case StatusUnavailable:
- str = "operation unavailable"
- case StatusDuplicateElement:
- str = "duplicate credential element requested"
- case StatusNameNotMN:
- str = "name contains multi-mechanism elements"
- case StatusComplete:
- str = "normal completion"
- case StatusContinueNeeded:
- str = "continuation call to routine required"
- case StatusDuplicateToken:
- str = "duplicate per-message token detected"
- case StatusOldToken:
- str = "timed-out per-message token detected"
- case StatusUnseqToken:
- str = "reordered (early) per-message token detected"
- case StatusGapToken:
- str = "skipped predecessor token(s) detected"
- default:
- str = "unknown GSS-API error status"
- }
- if s.Message != "" {
- return fmt.Sprintf("%s: %s", str, s.Message)
- }
- return str
- }
|