Skip to content

Commit 93f30ed

Browse files
committed
Protoype of kerberos support (non parameterized with TODOs)
1 parent b5281f5 commit 93f30ed

File tree

6 files changed

+231
-4
lines changed

6 files changed

+231
-4
lines changed

packages/pg-protocol/src/parser.ts

+7
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,13 @@ export class Parser {
327327
return new AuthenticationMD5Password(length, salt)
328328
}
329329
break
330+
case 7: // GSS Init (Kerberos)
331+
message.name = 'GSSInit';
332+
break;
333+
case 8: // GSSAPI Continue (Kerberos)
334+
message.name = 'GSSContinue';
335+
message.inToken = this.reader.bytes(length - 8).toString('base64');
336+
return message
330337
case 10: // AuthenticationSASL
331338
message.name = 'authenticationSASL'
332339
message.mechanisms = []

packages/pg-protocol/src/serializer.ts

+5
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ const copyData = (chunk: Buffer): Buffer => {
239239
return writer.add(chunk).flush(code.copyFromChunk)
240240
}
241241

242+
const sendBinaryPassword = (chunk: Buffer): Buffer => {
243+
return writer.add(chunk).flush(code.startup)
244+
}
245+
242246
const copyFail = (message: string): Buffer => {
243247
return cstringMessage(code.copyFail, message)
244248
}
@@ -266,6 +270,7 @@ const serialize = {
266270
sync: () => syncBuffer,
267271
end: () => endBuffer,
268272
copyData,
273+
sendBinaryPassword,
269274
copyDone: () => copyDoneBuffer,
270275
copyFail,
271276
cancel,

packages/pg/lib/client.js

+37
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ class Client extends EventEmitter {
174174
}
175175

176176
_attachListeners(con) {
177+
// kerberos
178+
con.on('GSSInit', this._handleGSSInit.bind(this))
179+
con.on('GSSContinue', this._handleGSSContinue.bind(this))
180+
177181
// password request handling
178182
con.on('authenticationCleartextPassword', this._handleAuthCleartextPassword.bind(this))
179183
// password request handling
@@ -198,6 +202,39 @@ class Client extends EventEmitter {
198202
con.on('notification', this._handleNotification.bind(this))
199203
}
200204

205+
async _handleGSSInit(msg) {
206+
try {
207+
// TODO: Below needs to be parameterized
208+
this.client = await kerberos.initializeClient('[email protected]', {
209+
mechOID: kerberos.GSS_MECH_OID_SPNEGO,
210+
})
211+
212+
// TODO: below this might need to be a recursive loop to step multiple times.
213+
const token = await this.client.step('')
214+
215+
const buf = Buffer.from(token, 'base64')
216+
this.connection.sendBinaryPassword(buf)
217+
} catch (e) {
218+
this.emit('error', e)
219+
}
220+
}
221+
222+
async _handleGSSContinue(msg) {
223+
try {
224+
const inToken = msg.inToken
225+
const token = await this.client.step(inToken)
226+
227+
// TODO: probably a better way to handle this.
228+
if (token == null) {
229+
return
230+
}
231+
const buf = Buffer.from(token, 'base64')
232+
this.connection.sendBinaryPassword(buf)
233+
} catch (e) {
234+
this.emit('error', e)
235+
}
236+
}
237+
201238
// TODO(bmc): deprecate pgpass "built in" integration since this.password can be a function
202239
// it can be supplied by the user if required - this is a breaking change!
203240
_checkPgPass(cb) {

packages/pg/lib/connection.js

+4
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ class Connection extends EventEmitter {
133133
this._send(serialize.password(password))
134134
}
135135

136+
sendBinaryPassword(password) {
137+
this._send(serialize.sendBinaryPassword(password))
138+
}
139+
136140
sendSASLInitialResponseMessage(mechanism, initialResponse) {
137141
this._send(serialize.sendSASLInitialResponseMessage(mechanism, initialResponse))
138142
}

packages/pg/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"author": "Brian Carlson <[email protected]>",
2121
"main": "./lib",
2222
"dependencies": {
23+
"kerberos": "^2.1.0",
2324
"pg-connection-string": "^2.6.4",
2425
"pg-pool": "^3.6.2",
2526
"pg-protocol": "^1.6.1",

0 commit comments

Comments
 (0)