Skip to content

Commit ad9039c

Browse files
remove Kerberos export
1 parent 04ff082 commit ad9039c

File tree

3 files changed

+230
-241
lines changed

3 files changed

+230
-241
lines changed

lib/index.js

Lines changed: 230 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,235 @@
11
'use strict';
22

3-
const kerberos = require('./kerberos');
3+
const { promisify } = require('util');
4+
const { loadBindings } = require('./util');
45

5-
// Get the Kerberos library
6-
module.exports = kerberos;
6+
const kerberos = loadBindings();
7+
const KerberosClient = kerberos.KerberosClient;
8+
const KerberosServer = kerberos.KerberosServer;
79

8-
// Support legacy versions of the mongodb driver which expect this export
9-
module.exports.Kerberos = kerberos;
10+
// GSS Flags
11+
const GSS_C_DELEG_FLAG = 1;
12+
const GSS_C_MUTUAL_FLAG = 2;
13+
const GSS_C_REPLAY_FLAG = 4;
14+
const GSS_C_SEQUENCE_FLAG = 8;
15+
const GSS_C_CONF_FLAG = 16;
16+
const GSS_C_INTEG_FLAG = 32;
17+
const GSS_C_ANON_FLAG = 64;
18+
const GSS_C_PROT_READY_FLAG = 128;
19+
const GSS_C_TRANS_FLAG = 256;
1020

11-
module.exports.version = require('../package.json').version;
21+
// GSS_OID
22+
const GSS_C_NO_OID = 0;
23+
const GSS_MECH_OID_KRB5 = 9;
24+
const GSS_MECH_OID_SPNEGO = 6;
25+
26+
/**
27+
* @class KerberosClient
28+
*
29+
* @property {string} username The username used for authentication
30+
* @property {string} response The last response received during authentication steps
31+
* @property {string} responseConf Indicates whether confidentiality was applied or not (GSSAPI only)
32+
* @property {boolean} contextComplete Indicates that authentication has successfully completed or not
33+
*/
34+
35+
const promisifiedStep = promisify(KerberosClient.prototype.step);
36+
/**
37+
* Processes a single kerberos client-side step using the supplied server challenge.
38+
*
39+
* @kind function
40+
* @memberof KerberosClient
41+
* @param {string} challenge A string containing the base64-encoded server data (which may be empty for the first step)
42+
* @return {Promise<string>}
43+
*/
44+
KerberosClient.prototype.step = async function step(challenge) {
45+
if (typeof challenge !== 'string') {
46+
throw new TypeError('parameter `challenge` must be a string.');
47+
}
48+
return await promisifiedStep.call(this, challenge);
49+
};
50+
51+
const promsifiedWrap = promisify(KerberosClient.prototype.wrap);
52+
/**
53+
* Perform the client side kerberos wrap step.
54+
*
55+
* @kind function
56+
* @memberof KerberosClient
57+
* @param {string} challenge The response returned after calling `unwrap`
58+
* @param {object} [options] Options
59+
* @param {string} [options.user] The user to authorize
60+
* @param {boolean} [options.protect] Indicates if the wrap should request message confidentiality
61+
* @return {Promise<string>}
62+
*/
63+
KerberosClient.prototype.wrap = async function wrap(challenge, options = {}) {
64+
if (typeof challenge !== 'string') {
65+
throw new TypeError('parameter `challenge` must be a string.');
66+
}
67+
68+
return await promsifiedWrap.call(this, challenge, options);
69+
};
70+
71+
const promisifiedUnwrap = promisify(KerberosClient.prototype.unwrap);
72+
/**
73+
* Perform the client side kerberos unwrap step
74+
*
75+
* @kind function
76+
* @memberof KerberosClient
77+
* @param {string} challenge A string containing the base64-encoded server data
78+
* @return {Promise<string>}
79+
*/
80+
KerberosClient.prototype.unwrap = async function unwrap(challenge) {
81+
if (typeof challenge !== 'string') {
82+
throw new TypeError('parameter `challenge` must be a string.');
83+
}
84+
return await promisifiedUnwrap.call(this, challenge);
85+
};
86+
87+
const promisifiedServerStep = promisify(KerberosServer.prototype.step);
88+
/**
89+
* @class KerberosServer
90+
*
91+
* @property {string} username The username used for authentication
92+
* @property {string} response The last response received during authentication steps
93+
* @property {string} targetName The target used for authentication
94+
* @property {boolean} contextComplete Indicates that authentication has successfully completed or not
95+
*/
96+
97+
/**
98+
* Processes a single kerberos server-side step using the supplied client data.
99+
*
100+
* @kind function
101+
* @memberof KerberosServer
102+
* @param {string} challenge A string containing the base64-encoded client data
103+
* @return {Promise<KerberosServer>}
104+
*/
105+
KerberosServer.prototype.step = async function step(challenge) {
106+
if (typeof challenge !== 'string') {
107+
throw new TypeError('parameter `challenge` must be a string.');
108+
}
109+
return await promisifiedServerStep.call(this, challenge);
110+
};
111+
112+
const promisifiedCheckPassword = promisify(kerberos.checkPassword);
113+
114+
/**
115+
* This function provides a simple way to verify that a user name and password
116+
* match those normally used for Kerberos authentication.
117+
* It does this by checking that the supplied user name and password can be
118+
* used to get a ticket for the supplied service.
119+
* If the user name does not contain a realm, then the default realm supplied
120+
* is used.
121+
*
122+
* For this to work properly the Kerberos must be configured properly on this
123+
* machine.
124+
* That will likely mean ensuring that the edu.mit.Kerberos preference file
125+
* has the correct realms and KDCs listed.
126+
*
127+
* IMPORTANT: This method is vulnerable to KDC spoofing attacks and it should
128+
* only be used for testing. Do not use this in any production system - your
129+
* security could be compromised if you do.
130+
*
131+
* @kind function
132+
* @param {string} username The Kerberos user name. If no realm is supplied, then the `defaultRealm` will be used.
133+
* @param {string} password The password for the user.
134+
* @param {string} service The Kerberos service to check access for.
135+
* @param {string} [defaultRealm] The default realm to use if one is not supplied in the user argument.
136+
* @return {Promise<null>} returns Promise that rejects if the password is invalid
137+
*/
138+
async function checkPassword(username, password, service, defaultRealm) {
139+
if (typeof username !== 'string') {
140+
throw new TypeError('parameter `username` must be a string.');
141+
}
142+
if (typeof password !== 'string') {
143+
throw new TypeError('parameter `password` must be a string.');
144+
}
145+
if (typeof service !== 'string') {
146+
throw new TypeError('parameter `service` must be a string.');
147+
}
148+
if (defaultRealm && typeof defaultRealm !== 'string') {
149+
throw new TypeError('if specified, parameter `defaultRealm` must be a string.');
150+
}
151+
return await promisifiedCheckPassword.call(this, username, password, service, defaultRealm);
152+
}
153+
154+
const promisifiedPrincipalDetails = promisify(kerberos.principalDetails);
155+
/**
156+
* This function returns the service principal for the server given a service type and hostname.
157+
*
158+
* Details are looked up via the `/etc/keytab` file.
159+
*
160+
* @kind function
161+
* @param {string} service The Kerberos service type for the server.
162+
* @param {string} hostname The hostname of the server.
163+
* @return {Promise} returns Promise
164+
*/
165+
async function principalDetails(service, hostname) {
166+
if (typeof service !== 'string') {
167+
throw new TypeError('parameter `service` must be a string.');
168+
}
169+
if (typeof hostname !== 'string') {
170+
throw new TypeError('parameter `hostname` must be a string.');
171+
}
172+
return await promisifiedPrincipalDetails.call(this, service, hostname);
173+
}
174+
175+
const promisifiedInitializeClient = promisify(kerberos.initializeClient);
176+
/**
177+
* Initializes a context for client-side authentication with the given service principal.
178+
*
179+
* @kind function
180+
* @param {string} service A string containing the service principal in the form 'type@fqdn' (e.g. 'imap@mail.apple.com').
181+
* @param {object} [options] Optional settings
182+
* @param {string} [options.principal] Optional string containing the client principal in the form 'user@realm' (e.g. 'jdoe@example.com').
183+
* @param {number} [options.flags] Optional integer used to set GSS flags. (e.g. `GSS_C_DELEG_FLAG\|GSS_C_MUTUAL_FLAG\|GSS_C_SEQUENCE_FLAG` will allow for forwarding credentials to the remote host)
184+
* @param {number} [options.mechOID] Optional GSS mech OID. Defaults to None (GSS_C_NO_OID). Other possible values are `GSS_MECH_OID_KRB5`, `GSS_MECH_OID_SPNEGO`.
185+
* @return {Promise<KerberosClient>} returns Promise
186+
*/
187+
async function initializeClient(service, options = { mechOID: GSS_C_NO_OID }) {
188+
if (typeof service !== 'string') {
189+
throw new TypeError('parameter `service` must be a string.');
190+
}
191+
return await promisifiedInitializeClient.call(this, service, options);
192+
}
193+
194+
const promisifiedInitializeServer = promisify(kerberos.initializeServer);
195+
196+
/**
197+
* Initializes a context for server-side authentication with the given service principal.
198+
*
199+
* @kind function
200+
* @param {string} service A string containing the service principal in the form 'type@fqdn' (e.g. 'imap@mail.apple.com').
201+
* @return {Promise<KerberosServer>} returns Promise
202+
*/
203+
async function initializeServer(service) {
204+
if (typeof service !== 'string') {
205+
throw new TypeError('parameter `service` must be a string.');
206+
}
207+
return await promisifiedInitializeServer.call(this, service);
208+
}
209+
210+
const version = require('../package.json').version;
211+
212+
module.exports = {
213+
initializeClient,
214+
initializeServer,
215+
principalDetails,
216+
checkPassword,
217+
218+
// gss flags
219+
GSS_C_DELEG_FLAG,
220+
GSS_C_MUTUAL_FLAG,
221+
GSS_C_REPLAY_FLAG,
222+
GSS_C_SEQUENCE_FLAG,
223+
GSS_C_CONF_FLAG,
224+
GSS_C_INTEG_FLAG,
225+
GSS_C_ANON_FLAG,
226+
GSS_C_PROT_READY_FLAG,
227+
GSS_C_TRANS_FLAG,
228+
GSS_C_NO_OID,
229+
230+
// mechanism OIDs
231+
GSS_MECH_OID_KRB5,
232+
GSS_MECH_OID_SPNEGO,
233+
234+
version
235+
};

0 commit comments

Comments
 (0)