Skip to content

Commit 484733c

Browse files
committed
fixed a bug related to using only a username and refactored a little.
1 parent 2b8a860 commit 484733c

File tree

4 files changed

+115
-107
lines changed

4 files changed

+115
-107
lines changed

examples/count/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"context"
55
"log"
6+
"time"
67

78
"flag"
89

@@ -37,8 +38,10 @@ func main() {
3738
}
3839

3940
ctx := context.Background()
41+
timeoutCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
42+
defer cancel()
4043

41-
s, err := c.SelectServer(ctx, cluster.WriteSelector())
44+
s, err := c.SelectServer(timeoutCtx, cluster.WriteSelector())
4245
if err != nil {
4346
log.Fatalf("%v: %v", err, c.Model().Servers[0].LastError)
4447
}

internal/auth/gssapi/sspi.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func (sc *SaslClient) Start() (string, []byte, error) {
9898
status := C.sspi_client_init(&sc.state, cusername, cpassword)
9999

100100
if status != C.SSPI_OK {
101-
return mechName, nil, fmt.Errorf("unable to intitialize sspi client state: %s", statusMessage(sc.state.status))
101+
return mechName, nil, sc.getError("unable to intitialize client")
102102
}
103103

104104
return mechName, nil, nil
@@ -112,9 +112,9 @@ func (sc *SaslClient) Next(challenge []byte) ([]byte, error) {
112112
if sc.contextComplete {
113113
if sc.username == "" {
114114
var cusername *C.char
115-
status := C.sspi_client_get_username(&sc.state, &cusername)
115+
status := C.sspi_client_username(&sc.state, &cusername)
116116
if status != C.SSPI_OK {
117-
return nil, fmt.Errorf("unable to acquire username: %v", statusMessage(sc.state.status))
117+
return nil, sc.getError("unable to acquire username")
118118
}
119119
defer C.free(unsafe.Pointer(cusername))
120120
sc.username = C.GoString((*C.char)(unsafe.Pointer(cusername)))
@@ -125,7 +125,7 @@ func (sc *SaslClient) Next(challenge []byte) ([]byte, error) {
125125
bufLen := C.ULONG(len(bytes))
126126
status := C.sspi_client_wrap_msg(&sc.state, buf, bufLen, &outBuf, &outBufLen)
127127
if status != C.SSPI_OK {
128-
return nil, fmt.Errorf("unable to wrap authz: %v", statusMessage(sc.state.status))
128+
return nil, sc.getError("unable to wrap authz")
129129
}
130130

131131
sc.done = true
@@ -139,13 +139,13 @@ func (sc *SaslClient) Next(challenge []byte) ([]byte, error) {
139139
cservicePrincipalName := C.CString(sc.servicePrincipalName)
140140
defer C.free(unsafe.Pointer(cservicePrincipalName))
141141

142-
status := C.sspi_init_sec_context(&sc.state, cservicePrincipalName, buf, bufLen, &outBuf, &outBufLen)
142+
status := C.sspi_client_negotiate(&sc.state, cservicePrincipalName, buf, bufLen, &outBuf, &outBufLen)
143143
switch status {
144144
case C.SSPI_OK:
145145
sc.contextComplete = true
146146
case C.SSPI_CONTINUE:
147147
default:
148-
return nil, fmt.Errorf("unable to initialize sec context: %v", statusMessage(sc.state.status))
148+
return nil, sc.getError("unable to negotiate with server")
149149
}
150150
}
151151

@@ -160,6 +160,10 @@ func (sc *SaslClient) Completed() bool {
160160
return sc.done
161161
}
162162

163+
func (sc *SaslClient) getError(prefix string) error {
164+
return getError(prefix, sc.state.status)
165+
}
166+
163167
var initOnce sync.Once
164168
var initError error
165169

@@ -170,7 +174,7 @@ func initSSPI() {
170174
}
171175
}
172176

173-
func statusMessage(status C.SECURITY_STATUS) string {
177+
func getError(prefix string, status C.SECURITY_STATUS) error {
174178
var s string
175179
switch status {
176180
case C.SEC_E_ALGORITHM_MISMATCH:
@@ -326,8 +330,8 @@ func statusMessage(status C.SECURITY_STATUS) string {
326330
case C.SEC_I_RENEGOTIATE:
327331
s = "The context data must be renegotiated with the peer."
328332
default:
329-
return fmt.Sprintf("status code 0x%x", uint32(status))
333+
return fmt.Errorf("%s: 0x%x", prefix, uint32(status))
330334
}
331335

332-
return fmt.Sprintf("status code 0x%x: %s", uint32(status), s)
336+
return fmt.Errorf("%s: %s(0x%x)", prefix, s, uint32(status))
333337
}

internal/auth/gssapi/sspi_wrapper.c

Lines changed: 87 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,24 @@ int sspi_client_init(
3636
TimeStamp timestamp;
3737

3838
if (username) {
39-
SEC_WINNT_AUTH_IDENTITY auth_identity;
40-
41-
#ifdef _UNICODE
42-
auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
43-
#else
44-
auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
45-
#endif
46-
auth_identity.User = (LPSTR) username;
47-
auth_identity.UserLength = strlen(username);
48-
auth_identity.Password = NULL;
49-
auth_identity.PasswordLength = 0;
5039
if (password) {
40+
SEC_WINNT_AUTH_IDENTITY auth_identity;
41+
42+
#ifdef _UNICODE
43+
auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
44+
#else
45+
auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
46+
#endif
47+
auth_identity.User = (LPSTR) username;
48+
auth_identity.UserLength = strlen(username);
5149
auth_identity.Password = (LPSTR) password;
5250
auth_identity.PasswordLength = strlen(password);
51+
auth_identity.Domain = NULL;
52+
auth_identity.DomainLength = 0;
53+
client->status = sspi_functions->AcquireCredentialsHandle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_identity, NULL, NULL, &client->cred, &timestamp);
54+
} else {
55+
client->status = sspi_functions->AcquireCredentialsHandle(username, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &client->cred, &timestamp);
5356
}
54-
auth_identity.Domain = NULL;
55-
auth_identity.DomainLength = 0;
56-
client->status = sspi_functions->AcquireCredentialsHandle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_identity, NULL, NULL, &client->cred, &timestamp);
5757
} else {
5858
client->status = sspi_functions->AcquireCredentialsHandle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &client->cred, &timestamp);
5959
}
@@ -65,20 +65,7 @@ int sspi_client_init(
6565
return SSPI_OK;
6666
}
6767

68-
int sspi_client_destroy(
69-
sspi_client_state *client
70-
)
71-
{
72-
if (client->has_ctx > 0) {
73-
sspi_functions->DeleteSecurityContext(&client->ctx);
74-
}
75-
76-
sspi_functions->FreeCredentialsHandle(&client->cred);
77-
78-
return SSPI_OK;
79-
}
80-
81-
int sspi_client_get_username(
68+
int sspi_client_username(
8269
sspi_client_state *client,
8370
char** username
8471
)
@@ -94,17 +81,78 @@ int sspi_client_get_username(
9481
*username = malloc(len);
9582
memcpy(*username, names.sUserName, len);
9683

97-
client->status = sspi_functions->FreeContextBuffer(names.sUserName);
98-
if (client->status != SEC_E_OK) {
84+
sspi_functions->FreeContextBuffer(names.sUserName);
85+
86+
return SSPI_OK;
87+
}
88+
89+
int sspi_client_negotiate(
90+
sspi_client_state *client,
91+
char* spn,
92+
PVOID input,
93+
ULONG input_length,
94+
PVOID* output,
95+
ULONG* output_length
96+
)
97+
{
98+
SecBufferDesc inbuf;
99+
SecBuffer in_bufs[1];
100+
SecBufferDesc outbuf;
101+
SecBuffer out_bufs[1];
102+
103+
if (client->has_ctx > 0) {
104+
inbuf.ulVersion = SECBUFFER_VERSION;
105+
inbuf.cBuffers = 1;
106+
inbuf.pBuffers = in_bufs;
107+
in_bufs[0].pvBuffer = input;
108+
in_bufs[0].cbBuffer = input_length;
109+
in_bufs[0].BufferType = SECBUFFER_TOKEN;
110+
}
111+
112+
outbuf.ulVersion = SECBUFFER_VERSION;
113+
outbuf.cBuffers = 1;
114+
outbuf.pBuffers = out_bufs;
115+
out_bufs[0].pvBuffer = NULL;
116+
out_bufs[0].cbBuffer = 0;
117+
out_bufs[0].BufferType = SECBUFFER_TOKEN;
118+
119+
ULONG context_attr = 0;
120+
121+
client->status = sspi_functions->InitializeSecurityContext(
122+
&client->cred,
123+
client->has_ctx > 0 ? &client->ctx : NULL,
124+
(LPSTR) spn,
125+
ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_MUTUAL_AUTH,
126+
0,
127+
SECURITY_NETWORK_DREP,
128+
client->has_ctx > 0 ? &inbuf : NULL,
129+
0,
130+
&client->ctx,
131+
&outbuf,
132+
&context_attr,
133+
NULL);
134+
135+
if (client->status != SEC_E_OK && client->status != SEC_I_CONTINUE_NEEDED) {
99136
return SSPI_ERROR;
100137
}
101138

139+
client->has_ctx = 1;
140+
141+
*output = malloc(out_bufs[0].cbBuffer);
142+
*output_length = out_bufs[0].cbBuffer;
143+
memcpy(*output, out_bufs[0].pvBuffer, *output_length);
144+
sspi_functions->FreeContextBuffer(out_bufs[0].pvBuffer);
145+
146+
if (client->status == SEC_I_CONTINUE_NEEDED) {
147+
return SSPI_CONTINUE;
148+
}
149+
102150
return SSPI_OK;
103151
}
104152

105153
int sspi_client_wrap_msg(
106154
sspi_client_state *client,
107-
PVOID* input,
155+
PVOID input,
108156
ULONG input_length,
109157
PVOID* output,
110158
ULONG* output_length
@@ -156,62 +204,15 @@ int sspi_client_wrap_msg(
156204
return SSPI_OK;
157205
}
158206

159-
int sspi_init_sec_context(
160-
sspi_client_state *client,
161-
char* spn,
162-
PVOID input,
163-
ULONG input_length,
164-
PVOID* output,
165-
ULONG* output_length
207+
int sspi_client_destroy(
208+
sspi_client_state *client
166209
)
167210
{
168-
SecBufferDesc inbuf;
169-
SecBuffer in_bufs[1];
170-
SecBufferDesc outbuf;
171-
SecBuffer out_bufs[1];
172-
173-
if (client->has_ctx > 0) {
174-
inbuf.ulVersion = SECBUFFER_VERSION;
175-
inbuf.cBuffers = 1;
176-
inbuf.pBuffers = in_bufs;
177-
in_bufs[0].pvBuffer = input;
178-
in_bufs[0].cbBuffer = input_length;
179-
in_bufs[0].BufferType = SECBUFFER_TOKEN;
180-
}
181-
182-
outbuf.ulVersion = SECBUFFER_VERSION;
183-
outbuf.cBuffers = 1;
184-
outbuf.pBuffers = out_bufs;
185-
out_bufs[0].pvBuffer = NULL;
186-
out_bufs[0].cbBuffer = 0;
187-
out_bufs[0].BufferType = SECBUFFER_TOKEN;
188-
189-
ULONG context_attr = 0;
190-
191-
client->status = sspi_functions->InitializeSecurityContext(
192-
&client->cred,
193-
client->has_ctx > 0 ? &client->ctx : NULL,
194-
(LPSTR) spn,
195-
ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_MUTUAL_AUTH,
196-
0,
197-
SECURITY_NETWORK_DREP,
198-
client->has_ctx > 0 ? &inbuf : NULL,
199-
0,
200-
&client->ctx,
201-
&outbuf,
202-
&context_attr,
203-
NULL);
204-
205-
*output = malloc(out_bufs[0].cbBuffer);
206-
*output_length = out_bufs[0].cbBuffer;
207-
memcpy(*output, out_bufs[0].pvBuffer, *output_length);
208-
client->has_ctx = 1;
209-
210-
if (client->status == SEC_I_CONTINUE_NEEDED || client->status == SEC_I_COMPLETE_AND_CONTINUE) {
211-
return SSPI_CONTINUE;
212-
} else if (client->status == SEC_E_OK) {
213-
return SSPI_OK;
211+
if (client->has_ctx > 0) {
212+
sspi_functions->DeleteSecurityContext(&client->ctx);
214213
}
215214

216-
return SSPI_ERROR;
217-
}
215+
sspi_functions->FreeCredentialsHandle(&client->cred);
216+
217+
return SSPI_OK;
218+
}

internal/auth/gssapi/sspi_wrapper.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,30 @@ int sspi_client_init(
2929
char* password
3030
);
3131

32-
int sspi_client_destroy(
33-
sspi_client_state *client
34-
);
35-
36-
int sspi_client_get_username(
32+
int sspi_client_username(
3733
sspi_client_state *client,
3834
char** username
3935
);
4036

41-
int sspi_client_wrap_msg(
37+
int sspi_client_negotiate(
4238
sspi_client_state *client,
43-
PVOID* input,
39+
char* spn,
40+
PVOID input,
4441
ULONG input_length,
4542
PVOID* output,
46-
ULONG* output_length
43+
ULONG* output_length
4744
);
4845

49-
int sspi_init_sec_context(
46+
int sspi_client_wrap_msg(
5047
sspi_client_state *client,
51-
char* spn,
5248
PVOID input,
5349
ULONG input_length,
5450
PVOID* output,
55-
ULONG* output_length
51+
ULONG* output_length
52+
);
53+
54+
int sspi_client_destroy(
55+
sspi_client_state *client
5656
);
5757

5858
#endif

0 commit comments

Comments
 (0)