-
Notifications
You must be signed in to change notification settings - Fork 249
/
gssapi.go
199 lines (181 loc) · 6.84 KB
/
gssapi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// 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"
)
// 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 OID(o OIDName) 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}
}
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
}