Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/native/libnet/NTLMAuthSequence.c
41119 views
1
/*
2
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include <jni.h>
27
#include <windows.h>
28
#include <rpc.h>
29
#include <winsock.h>
30
#include <lm.h>
31
32
#include <stdio.h>
33
#include <stdarg.h>
34
#include <stdlib.h>
35
#include <string.h>
36
#include <tchar.h>
37
#include <fcntl.h>
38
39
#include "jni_util.h"
40
41
#define SECURITY_WIN32
42
#include "sspi.h"
43
44
static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, JNIEnv *env, jobject status);
45
46
static jfieldID ntlm_ctxHandleID;
47
static jfieldID ntlm_crdHandleID;
48
static jfieldID status_seqCompleteID;
49
50
static HINSTANCE lib = NULL;
51
52
JNIEXPORT void JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequence_initFirst
53
(JNIEnv *env, jclass authseq_clazz, jclass status_clazz)
54
{
55
ntlm_ctxHandleID = (*env)->GetFieldID(env, authseq_clazz, "ctxHandle", "J");
56
CHECK_NULL(ntlm_ctxHandleID);
57
ntlm_crdHandleID = (*env)->GetFieldID(env, authseq_clazz, "crdHandle", "J");
58
CHECK_NULL(ntlm_crdHandleID);
59
status_seqCompleteID = (*env)->GetFieldID(env, status_clazz, "sequenceComplete", "Z");
60
}
61
62
/*
63
* Class: sun_net_www_protocol_http_NTLMAuthSequence
64
* Method: getCredentialsHandle
65
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J
66
*/
67
68
JNIEXPORT jlong JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequence_getCredentialsHandle
69
(JNIEnv *env, jobject this, jstring user, jstring domain, jstring password)
70
{
71
SEC_WINNT_AUTH_IDENTITY AuthId;
72
SEC_WINNT_AUTH_IDENTITY * pAuthId;
73
const CHAR *pUser = 0;
74
const CHAR *pDomain = 0;
75
const CHAR *pPassword = 0;
76
CredHandle *pCred;
77
TimeStamp ltime;
78
jboolean isCopy;
79
SECURITY_STATUS ss;
80
81
if (user != 0) {
82
pUser = JNU_GetStringPlatformChars(env, user, &isCopy);
83
if (pUser == NULL)
84
return 0; // pending Exception
85
}
86
if (domain != 0) {
87
pDomain = JNU_GetStringPlatformChars(env, domain, &isCopy);
88
if (pDomain == NULL) {
89
if (pUser != NULL)
90
JNU_ReleaseStringPlatformChars(env, user, pUser);
91
return 0; // pending Exception
92
}
93
}
94
if (password != 0) {
95
pPassword = JNU_GetStringPlatformChars(env, password, &isCopy);
96
if (pPassword == NULL) {
97
if(pUser != NULL)
98
JNU_ReleaseStringPlatformChars(env, user, pUser);
99
if(pDomain != NULL)
100
JNU_ReleaseStringPlatformChars(env, domain, pDomain);
101
return 0; // pending Exception
102
}
103
}
104
pCred = (CredHandle *)malloc(sizeof (CredHandle));
105
if (pCred == NULL) {
106
JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
107
if (pUser != NULL)
108
JNU_ReleaseStringPlatformChars(env, user, pUser);
109
if (pPassword != NULL)
110
JNU_ReleaseStringPlatformChars(env, password, pPassword);
111
if (pDomain != NULL)
112
JNU_ReleaseStringPlatformChars(env, domain, pDomain);
113
return NULL;
114
}
115
116
if ( ((pUser != NULL) || (pPassword != NULL)) || (pDomain != NULL)) {
117
pAuthId = &AuthId;
118
119
memset( &AuthId, 0, sizeof( AuthId ));
120
121
if ( pUser != NULL ) {
122
AuthId.User = (unsigned char *) pUser;
123
AuthId.UserLength = (unsigned long) strlen( pUser );
124
}
125
126
if ( pPassword != NULL ) {
127
AuthId.Password = (unsigned char *) pPassword;
128
AuthId.PasswordLength = (unsigned long) strlen( pPassword );
129
}
130
131
if ( pDomain != NULL ) {
132
AuthId.Domain = (unsigned char *) pDomain;
133
AuthId.DomainLength = (unsigned long) strlen( pDomain );
134
}
135
136
AuthId.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
137
} else {
138
pAuthId = NULL;
139
}
140
141
ss = AcquireCredentialsHandleA(
142
NULL, "NTLM", SECPKG_CRED_OUTBOUND,
143
NULL, pAuthId, NULL, NULL,
144
pCred, &ltime
145
);
146
147
/* Release resources held by JNU_GetStringPlatformChars */
148
if (pUser != NULL)
149
JNU_ReleaseStringPlatformChars(env, user, pUser);
150
if (pPassword != NULL)
151
JNU_ReleaseStringPlatformChars(env, password, pPassword);
152
if (pDomain != NULL)
153
JNU_ReleaseStringPlatformChars(env, domain, pDomain);
154
155
if (ss == 0) {
156
return (jlong) pCred;
157
} else {
158
return 0;
159
}
160
}
161
162
163
/*
164
* Class: sun_net_www_protocol_http_ntlm_NTLMAuthSequence
165
* Method: getNextToken
166
* Signature: (J[BLsun/net/www/protocol/http/ntlm/NTLMAuthSequence/Status;)[B
167
*/
168
JNIEXPORT jbyteArray JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthSequence_getNextToken
169
(JNIEnv *env, jobject this, jlong crdHandle, jbyteArray lastToken, jobject status)
170
{
171
172
VOID *pInput = 0;
173
DWORD inputLen;
174
CHAR buffOut[1024];
175
jboolean isCopy;
176
SECURITY_STATUS ss;
177
SecBufferDesc OutBuffDesc;
178
SecBuffer OutSecBuff;
179
SecBufferDesc InBuffDesc;
180
SecBuffer InSecBuff;
181
ULONG ContextAttributes;
182
CredHandle *pCred = (CredHandle *)crdHandle;
183
CtxtHandle *pCtx;
184
CtxtHandle *newContext;
185
TimeStamp ltime;
186
jbyteArray result;
187
188
189
pCtx = (CtxtHandle *) (*env)->GetLongField (env, this, ntlm_ctxHandleID);
190
if (pCtx == 0) { /* first call */
191
newContext = (CtxtHandle *)malloc(sizeof(CtxtHandle));
192
if (newContext != NULL) {
193
(*env)->SetLongField (env, this, ntlm_ctxHandleID, (jlong)newContext);
194
} else {
195
JNU_ThrowOutOfMemoryError(env, "native memory allocation failed");
196
return NULL;
197
}
198
} else {
199
newContext = pCtx;
200
}
201
202
OutBuffDesc.ulVersion = 0;
203
OutBuffDesc.cBuffers = 1;
204
OutBuffDesc.pBuffers = &OutSecBuff;
205
206
OutSecBuff.cbBuffer = 1024;
207
OutSecBuff.BufferType = SECBUFFER_TOKEN;
208
OutSecBuff.pvBuffer = buffOut;
209
210
/*
211
* Prepare our Input buffer - Note the server is expecting the client's
212
* negotiation packet on the first call
213
*/
214
215
if (lastToken != 0)
216
{
217
pInput = (VOID *)(*env)->GetByteArrayElements(env, lastToken, &isCopy);
218
CHECK_NULL_RETURN(pInput, NULL);
219
inputLen = (*env)->GetArrayLength(env, lastToken);
220
221
InBuffDesc.ulVersion = 0;
222
InBuffDesc.cBuffers = 1;
223
InBuffDesc.pBuffers = &InSecBuff;
224
225
InSecBuff.cbBuffer = inputLen;
226
InSecBuff.BufferType = SECBUFFER_TOKEN;
227
InSecBuff.pvBuffer = pInput;
228
}
229
230
/*
231
* will return success when its done but we still
232
* need to send the out buffer if there are bytes to send
233
*/
234
235
ss = InitializeSecurityContextA(
236
pCred, pCtx, NULL, 0, 0, SECURITY_NATIVE_DREP,
237
lastToken ? &InBuffDesc : NULL, 0, newContext, &OutBuffDesc,
238
&ContextAttributes, &ltime
239
);
240
241
if (pInput != 0) {
242
(*env)->ReleaseByteArrayElements(env, lastToken, pInput, JNI_ABORT);
243
}
244
245
if (ss < 0) {
246
endSequence (pCred, pCtx, env, status);
247
return 0;
248
}
249
250
if ((ss == SEC_I_COMPLETE_NEEDED) || (ss == SEC_I_COMPLETE_AND_CONTINUE) ) {
251
ss = CompleteAuthToken( pCtx, &OutBuffDesc );
252
253
if (ss < 0) {
254
endSequence (pCred, pCtx, env, status);
255
return 0;
256
}
257
}
258
259
if ( OutSecBuff.cbBuffer > 0 ) {
260
jbyteArray ret = (*env)->NewByteArray(env, OutSecBuff.cbBuffer);
261
if (ret != NULL) {
262
(*env)->SetByteArrayRegion(env, ret, 0, OutSecBuff.cbBuffer,
263
OutSecBuff.pvBuffer);
264
}
265
if (lastToken != 0) // 2nd stage
266
endSequence (pCred, pCtx, env, status);
267
result = ret;
268
}
269
270
if ((ss != SEC_I_CONTINUE_NEEDED) && (ss == SEC_I_COMPLETE_AND_CONTINUE)) {
271
endSequence (pCred, pCtx, env, status);
272
}
273
274
return result;
275
}
276
277
static void endSequence (PCredHandle credHand, PCtxtHandle ctxHandle, JNIEnv *env, jobject status) {
278
if (credHand != 0) {
279
FreeCredentialsHandle(credHand);
280
free(credHand);
281
}
282
283
if (ctxHandle != 0) {
284
DeleteSecurityContext(ctxHandle);
285
free(ctxHandle);
286
}
287
288
/* Sequence is complete so set flag */
289
(*env)->SetBooleanField(env, status, status_seqCompleteID, JNI_TRUE);
290
}
291
292