-
Notifications
You must be signed in to change notification settings - Fork 9
/
sspi-client-test.js
126 lines (103 loc) · 3.39 KB
/
sspi-client-test.js
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
'use strict';
const net = require('net');
const SspiClientApi = require('../../src_js/index.js').SspiClientApi;
const Fqdn = require('../../src_js/index.js').Fqdn;
const MakeSpn = require('../../src_js/index.js').MakeSpn;
let sspiClient = null;
let serverResponse = null;
let expectedServerResponseSize = 0;
let canInvokeGetNextBlob = false;
const getBufferLengthSafe = (buffer) => {
if (buffer) {
return buffer.length;
} else {
return 0;
}
}
const host = 'localhost';
const port = 2000;
const connectOpts = {
host: host,
port: port
};
const clientSocket = net.connect(connectOpts);
const onConnect = () => {
console.log('Connected to server.');
getFqdn();
}
const onError = (err) => {
console.log('Error: ', err);
clientSocket.destroy();
}
const onData = (data) => {
// console.log('Data Length: ', data.length, ' Data: ', data);
if (canInvokeGetNextBlob) {
throw new Error('Unexpected data from server while client ready to generate token.');
}
if (serverResponse) {
serverResponse = Buffer.concat([serverResponse, data]);
} else {
serverResponse = data;
}
// First 4 bytes in the server response indicate the response size.
if (!expectedServerResponseSize && serverResponse.length >= 4) {
expectedServerResponseSize = serverResponse.readUInt32LE(0);
serverResponse = serverResponse.slice(4);
}
if (expectedServerResponseSize && serverResponse.length == expectedServerResponseSize) {
canInvokeGetNextBlob = true;
console.log('Token buffer received (', expectedServerResponseSize, 'bytes):');
console.log();
}
if (expectedServerResponseSize && serverResponse.length > expectedServerResponseSize) {
throw new Error('Too many bytes from server: expected response size: ' + expectedServerResponseSize
+ ' , actual response size: ' + serverResponse.length);
}
}
clientSocket.on('connect', onConnect);
clientSocket.on('error', onError);
clientSocket.on('data', onData);
const getFqdn = () => {
Fqdn.getFqdn(host, (err, fqdn) => {
if (err) {
console.log(err);
return;
}
const spn = MakeSpn.makeSpn('MSSQLSvc', fqdn, 2000);
console.log();
sspiClient = new SspiClientApi.SspiClient(spn);
canInvokeGetNextBlob = true;
getNextBlob();
});
}
const getNextBlob = () => {
if (canInvokeGetNextBlob) {
canInvokeGetNextBlob = false;
sspiClient.getNextBlob(serverResponse, 0, getBufferLengthSafe(serverResponse), (clientResponse, isDone, errorCode, errorString) => {
if (errorCode) {
console.log(errorString);
} else {
if (clientResponse.length) {
// First 4 bytes in client response indicate response size to the server.
const buf = new Buffer(4);
buf.writeUInt32LE(clientResponse.length);
clientSocket.write(buf);
clientSocket.write(clientResponse);
}
console.log('Token buffer generated (', clientResponse.length, 'bytes): isDone=', isDone);
// console.log('Sent Data: ', clientResponse);
serverResponse = null;
expectedServerResponseSize = 0;
if (!isDone) {
setTimeout(getNextBlob, 1);
} else {
console.log();
console.log('Authentication succeeded. Security package = ', SspiClientApi.getDefaultSspiPackageName());
}
}
});
} else {
// Didn't get full server response yet. Try again.
setTimeout(getNextBlob, 1);
}
}