@@ -2,117 +2,109 @@ import { AuthProvider, AuthContext } from './auth_provider';
2
2
import { MongoError } from '../../error' ;
3
3
import { Kerberos , KerberosClient } from '../../deps' ;
4
4
import type { Callback } from '../../utils' ;
5
- import type { HandshakeDocument } from '../connect' ;
6
5
import type { Document } from '../../bson' ;
7
6
8
- const kGssapiClient = Symbol ( 'GSSAPI_CLIENT' ) ;
9
-
10
7
type MechanismProperties = {
11
8
gssapiCanonicalizeHostName ?: boolean ;
12
9
} ;
13
10
14
11
import * as dns from 'dns' ;
15
12
16
13
export class GSSAPI extends AuthProvider {
17
- [ kGssapiClient ] : KerberosClient ;
18
- prepare (
19
- handshakeDoc : HandshakeDocument ,
20
- authContext : AuthContext ,
21
- callback : Callback < HandshakeDocument >
22
- ) : void {
23
- const { host, port } = authContext . options ;
24
- const { credentials } = authContext ;
25
- if ( ! host || ! port || ! credentials ) {
26
- return callback (
27
- new MongoError (
28
- `Connection must specify: ${ host ? 'host' : '' } , ${ port ? 'port' : '' } , ${
29
- credentials ? 'host' : 'credentials'
30
- } .`
31
- )
32
- ) ;
33
- }
34
-
35
- if ( 'kModuleError' in Kerberos ) {
36
- return callback ( Kerberos [ 'kModuleError' ] ) ;
37
- }
38
-
39
- const { username, password, mechanismProperties } = credentials ;
40
- const serviceName =
41
- mechanismProperties [ 'gssapiservicename' ] ||
42
- mechanismProperties [ 'gssapiServiceName' ] ||
43
- 'mongodb' ;
44
-
45
- performGssapiCanonicalizeHostName (
46
- host ,
47
- mechanismProperties as MechanismProperties ,
48
- ( err ?: Error | MongoError , host ?: string ) => {
49
- if ( err ) return callback ( err ) ;
50
-
51
- const initOptions = { } ;
52
- if ( password != null ) {
53
- Object . assign ( initOptions , { user : username , password : password } ) ;
54
- }
55
-
56
- Kerberos . initializeClient (
57
- `${ serviceName } ${ process . platform === 'win32' ? '/' : '@' } ${ host } ` ,
58
- initOptions ,
59
- ( err : string , client : KerberosClient ) : void => {
60
- if ( err ) return callback ( new MongoError ( err ) ) ;
61
- if ( client == null ) return callback ( ) ;
62
- this [ kGssapiClient ] = client ;
63
- callback ( undefined , handshakeDoc ) ;
64
- }
65
- ) ;
66
- }
67
- ) ;
68
- }
69
-
70
14
auth ( authContext : AuthContext , callback : Callback ) : void {
71
15
const { connection, credentials } = authContext ;
72
16
if ( credentials == null ) return callback ( new MongoError ( 'credentials required' ) ) ;
73
17
const { username } = credentials ;
74
- const client = this [ kGssapiClient ] ;
75
- if ( client == null ) return callback ( new MongoError ( 'gssapi client missing' ) ) ;
76
18
function externalCommand (
77
19
command : Document ,
78
20
cb : Callback < { payload : string ; conversationId : any } >
79
21
) {
80
22
return connection . command ( '$external.$cmd' , command , cb ) ;
81
23
}
82
- client . step ( '' , ( err , payload ) => {
24
+ makeKerberosClient ( authContext , ( err , client ) => {
83
25
if ( err ) return callback ( err ) ;
84
-
85
- externalCommand ( saslStart ( payload ) , ( err , result ) => {
26
+ if ( client == null ) return callback ( new MongoError ( 'gssapi client missing' ) ) ;
27
+ client . step ( '' , ( err , payload ) => {
86
28
if ( err ) return callback ( err ) ;
87
- if ( result == null ) return callback ( ) ;
88
- negotiate ( client , 10 , result . payload , ( err , payload ) => {
89
- if ( err ) return callback ( err ) ;
90
29
91
- externalCommand ( saslContinue ( payload , result . conversationId ) , ( err , result ) => {
30
+ externalCommand ( saslStart ( payload ) , ( err , result ) => {
31
+ if ( err ) return callback ( err ) ;
32
+ if ( result == null ) return callback ( ) ;
33
+ negotiate ( client , 10 , result . payload , ( err , payload ) => {
92
34
if ( err ) return callback ( err ) ;
93
- if ( result == null ) return callback ( ) ;
94
- finalize ( client , username , result . payload , ( err , payload ) => {
95
- if ( err ) return callback ( err ) ;
96
35
97
- externalCommand (
98
- {
99
- saslContinue : 1 ,
100
- conversationId : result . conversationId ,
101
- payload
102
- } ,
103
- ( err , result ) => {
104
- if ( err ) return callback ( err ) ;
105
-
106
- callback ( undefined , result ) ;
107
- }
108
- ) ;
36
+ externalCommand ( saslContinue ( payload , result . conversationId ) , ( err , result ) => {
37
+ if ( err ) return callback ( err ) ;
38
+ if ( result == null ) return callback ( ) ;
39
+ finalize ( client , username , result . payload , ( err , payload ) => {
40
+ if ( err ) return callback ( err ) ;
41
+
42
+ externalCommand (
43
+ {
44
+ saslContinue : 1 ,
45
+ conversationId : result . conversationId ,
46
+ payload
47
+ } ,
48
+ ( err , result ) => {
49
+ if ( err ) return callback ( err ) ;
50
+
51
+ callback ( undefined , result ) ;
52
+ }
53
+ ) ;
54
+ } ) ;
109
55
} ) ;
110
56
} ) ;
111
57
} ) ;
112
58
} ) ;
113
59
} ) ;
114
60
}
115
61
}
62
+ function makeKerberosClient ( authContext : AuthContext , callback : Callback < KerberosClient > ) : void {
63
+ const { host, port } = authContext . options ;
64
+ const { credentials } = authContext ;
65
+ if ( ! host || ! port || ! credentials ) {
66
+ return callback (
67
+ new MongoError (
68
+ `Connection must specify: ${ host ? 'host' : '' } , ${ port ? 'port' : '' } , ${
69
+ credentials ? 'host' : 'credentials'
70
+ } .`
71
+ )
72
+ ) ;
73
+ }
74
+
75
+ if ( 'kModuleError' in Kerberos ) {
76
+ return callback ( Kerberos [ 'kModuleError' ] ) ;
77
+ }
78
+
79
+ const { username, password, mechanismProperties } = credentials ;
80
+ const serviceName =
81
+ mechanismProperties [ 'gssapiservicename' ] ||
82
+ mechanismProperties [ 'gssapiServiceName' ] ||
83
+ 'mongodb' ;
84
+
85
+ performGssapiCanonicalizeHostName (
86
+ host ,
87
+ mechanismProperties as MechanismProperties ,
88
+ ( err ?: Error | MongoError , host ?: string ) => {
89
+ if ( err ) return callback ( err ) ;
90
+
91
+ const initOptions = { } ;
92
+ if ( password != null ) {
93
+ Object . assign ( initOptions , { user : username , password : password } ) ;
94
+ }
95
+
96
+ Kerberos . initializeClient (
97
+ `${ serviceName } ${ process . platform === 'win32' ? '/' : '@' } ${ host } ` ,
98
+ initOptions ,
99
+ ( err : string , client : KerberosClient ) : void => {
100
+ if ( err ) return callback ( new MongoError ( err ) ) ;
101
+ callback ( undefined , client ) ;
102
+ }
103
+ ) ;
104
+ }
105
+ ) ;
106
+ }
107
+
116
108
function saslStart ( payload ?: string ) : Document {
117
109
return {
118
110
saslStart : 1 ,
0 commit comments