1
2
3
4
5
6
7
8
9
10
11
12
13
14 package waffle.windows.auth.impl;
15
16 import waffle.windows.auth.IWindowsCredentialsHandle;
17 import waffle.windows.auth.IWindowsIdentity;
18 import waffle.windows.auth.IWindowsImpersonationContext;
19 import waffle.windows.auth.IWindowsSecurityContext;
20
21 import com.sun.jna.platform.win32.Secur32;
22 import com.sun.jna.platform.win32.Sspi;
23 import com.sun.jna.platform.win32.Sspi.CredHandle;
24 import com.sun.jna.platform.win32.Sspi.CtxtHandle;
25 import com.sun.jna.platform.win32.Sspi.SecBufferDesc;
26 import com.sun.jna.platform.win32.Win32Exception;
27 import com.sun.jna.platform.win32.WinError;
28 import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
29 import com.sun.jna.ptr.IntByReference;
30
31
32
33
34
35
36 public class WindowsSecurityContextImpl implements IWindowsSecurityContext {
37
38
39 private String principalName;
40
41
42 private String securityPackage;
43
44
45 private SecBufferDesc token;
46
47
48 private CtxtHandle ctx;
49
50
51 private IntByReference attr;
52
53
54 private CredHandle credentials;
55
56
57 private boolean continueFlag;
58
59
60
61
62 @Override
63 public IWindowsImpersonationContext impersonate() {
64 return new WindowsSecurityContextImpersonationContextImpl(this.ctx);
65 }
66
67
68
69
70 @Override
71 public IWindowsIdentity getIdentity() {
72 final HANDLEByReference phContextToken = new HANDLEByReference();
73 final int rc = Secur32.INSTANCE.QuerySecurityContextToken(this.ctx, phContextToken);
74 if (WinError.SEC_E_OK != rc) {
75 throw new Win32Exception(rc);
76 }
77 return new WindowsIdentityImpl(phContextToken.getValue());
78 }
79
80
81
82
83 @Override
84 public String getSecurityPackage() {
85 return this.securityPackage;
86 }
87
88
89
90
91 @Override
92 public byte[] getToken() {
93 return this.token == null || this.token.getBytes() == null ? null : this.token.getBytes().clone();
94 }
95
96
97
98
99
100
101
102
103
104
105 public static IWindowsSecurityContext getCurrent(final String securityPackage, final String targetName) {
106 final IWindowsCredentialsHandle credentialsHandle = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
107 credentialsHandle.initialize();
108 try {
109 final WindowsSecurityContextImpl ctx = new WindowsSecurityContextImpl();
110 ctx.setPrincipalName(WindowsAccountImpl.getCurrentUsername());
111 ctx.setCredentialsHandle(credentialsHandle.getHandle());
112 ctx.setSecurityPackage(securityPackage);
113 ctx.initialize(null, null, targetName);
114 return ctx;
115 } finally {
116 credentialsHandle.dispose();
117 }
118 }
119
120
121
122
123 @Override
124 public void initialize(final CtxtHandle continueCtx, final SecBufferDesc continueToken, final String targetName) {
125 this.attr = new IntByReference();
126 this.ctx = new CtxtHandle();
127 int tokenSize = Sspi.MAX_TOKEN_SIZE;
128 int rc = 0;
129 do {
130 this.token = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, tokenSize);
131 rc = Secur32.INSTANCE.InitializeSecurityContext(this.credentials, continueCtx, targetName,
132 Sspi.ISC_REQ_CONNECTION, 0, Sspi.SECURITY_NATIVE_DREP, continueToken, 0, this.ctx, this.token,
133 this.attr, null);
134 switch (rc) {
135 case WinError.SEC_E_INSUFFICIENT_MEMORY:
136 tokenSize += Sspi.MAX_TOKEN_SIZE;
137 break;
138 case WinError.SEC_I_CONTINUE_NEEDED:
139 this.continueFlag = true;
140 break;
141 case WinError.SEC_E_OK:
142 this.continueFlag = false;
143 break;
144 default:
145 throw new Win32Exception(rc);
146 }
147 } while (rc == WinError.SEC_E_INSUFFICIENT_MEMORY);
148 }
149
150
151
152
153 @Override
154 public void dispose() {
155 WindowsSecurityContextImpl.dispose(this.ctx);
156 }
157
158
159
160
161
162
163
164
165 public static boolean dispose(final CtxtHandle ctx) {
166 if (ctx != null && !ctx.isNull()) {
167 final int rc = Secur32.INSTANCE.DeleteSecurityContext(ctx);
168 if (WinError.SEC_E_OK != rc) {
169 throw new Win32Exception(rc);
170 }
171 return true;
172 }
173 return false;
174 }
175
176
177
178
179 @Override
180 public String getPrincipalName() {
181 return this.principalName;
182 }
183
184
185
186
187
188
189
190 public void setPrincipalName(final String value) {
191 this.principalName = value;
192 }
193
194
195
196
197 @Override
198 public CtxtHandle getHandle() {
199 return this.ctx;
200 }
201
202
203
204
205
206
207
208 public void setCredentialsHandle(final CredHandle handle) {
209 this.credentials = handle;
210 }
211
212
213
214
215
216
217
218 public void setToken(final byte[] bytes) {
219 this.token = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, bytes);
220 }
221
222
223
224
225
226
227
228 public void setSecurityPackage(final String value) {
229 this.securityPackage = value;
230 }
231
232
233
234
235
236
237
238 public void setSecurityContext(final CtxtHandle phNewServerContext) {
239 this.ctx = phNewServerContext;
240 }
241
242
243
244
245 @Override
246 public boolean isContinue() {
247 return this.continueFlag;
248 }
249
250
251
252
253
254
255
256 public void setContinue(final boolean b) {
257 this.continueFlag = b;
258 }
259
260 }