Skip to content

Commit 515f4bf

Browse files
arabullMichael Johnsbaileympearsondurran
authored
feat(NODE-6333): Allow callers to specify the 'protect' flag (#198)
Co-authored-by: Michael Johns <[email protected]> Co-authored-by: Bailey Pearson <[email protected]> Co-authored-by: Durran Jordan <[email protected]> Co-authored-by: Bailey Pearson <[email protected]>
1 parent 281d076 commit 515f4bf

File tree

7 files changed

+64
-3
lines changed

7 files changed

+64
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ Processes a single kerberos client-side step using the supplied server challenge
182182
| challenge | <code>string</code> | The response returned after calling `unwrap` |
183183
| [options] | <code>object</code> | Optional settings |
184184
| [options.user] | <code>string</code> | The user to authorize |
185+
| [options.protect] | <code>boolean</code> | Indicates if the wrap should request message confidentiality |
185186
| [callback] | <code>function</code> | |
186187

187188
Perform the client side kerberos wrap step.

lib/kerberos.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ KerberosClient.prototype.step = defineOperation(KerberosClient.prototype.step, [
5252
* @param {string} challenge The response returned after calling `unwrap`
5353
* @param {object} [options] Optional settings
5454
* @param {string} [options.user] The user to authorize
55+
* @param {boolean} [options.protect] Indicates if the wrap should request message confidentiality
5556
* @param {function} [callback]
5657
* @return {Promise} returns Promise if no callback passed
5758
*/

src/kerberos.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ std::string ToStringWithNonStringAsEmpty(Napi::Value value) {
3737
return value.As<String>();
3838
}
3939

40+
int KerberosClient::ParseWrapOptionsProtect(const Napi::Object& options) {
41+
if (!options.Has("protect")) return 0;
42+
43+
if (!options.Get("protect").IsBoolean()) {
44+
throw TypeError::New(options.Env(), "options.protect must be a boolean.");
45+
}
46+
47+
bool protect = options.Get("protect").As<Boolean>();
48+
return protect ? 1 : 0;
49+
}
50+
4051
Function KerberosClient::Init(Napi::Env env) {
4152
return
4253
DefineClass(env,

src/kerberos.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class KerberosClient : public Napi::ObjectWrap<KerberosClient> {
5555
void UnwrapData(const Napi::CallbackInfo& info);
5656
void WrapData(const Napi::CallbackInfo& info);
5757

58+
int ParseWrapOptionsProtect(const Napi::Object& options);
59+
5860
private:
5961
friend class Napi::ObjectWrap<KerberosClient>;
6062
explicit KerberosClient(const Napi::CallbackInfo& info);

src/unix/kerberos_unix.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ void KerberosClient::WrapData(const CallbackInfo& info) {
7474
Object options = info[1].ToObject();
7575
Function callback = info[2].As<Function>();
7676
std::string user = ToStringWithNonStringAsEmpty(options["user"]);
77-
78-
int protect = 0; // NOTE: this should be an option
77+
int protect = ParseWrapOptionsProtect(options);
7978

8079
KerberosWorker::Run(callback, "kerberos:ClientWrap", [=](KerberosWorker::SetOnFinishedHandler onFinished) {
8180
gss_result result = authenticate_gss_client_wrap(

src/win32/kerberos_win32.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void KerberosClient::WrapData(const CallbackInfo& info) {
9292
Object options = info[1].ToObject();
9393
Function callback = info[2].As<Function>();
9494
std::string user = ToStringWithNonStringAsEmpty(options["user"]);
95-
int protect = 0; // NOTE: this should be an option
95+
int protect = ParseWrapOptionsProtect(options);
9696

9797
if (isStringTooLong(user)) {
9898
throw Error::New(info.Env(), "User name is too long");

test/kerberos_tests.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const request = require('request');
44
const chai = require('chai');
55
const expect = chai.expect;
66
const os = require('os');
7+
const { test } = require('mocha');
78
chai.use(require('chai-string'));
89

910
// environment variables
@@ -122,4 +123,50 @@ describe('Kerberos', function () {
122123
});
123124
});
124125
});
126+
127+
describe('Client.wrap()', function () {
128+
async function establishConext() {
129+
const service = `HTTP@${hostname}`;
130+
client = await kerberos.initializeClient(service, {});
131+
server = await kerberos.initializeServer(service);
132+
const clientResponse = await client.step('');
133+
const serverResponse = await server.step(clientResponse);
134+
await client.step(serverResponse);
135+
expect(client.contextComplete).to.be.true;
136+
return { client, server };
137+
}
138+
139+
let client;
140+
let server;
141+
142+
before(establishConext);
143+
describe('options.protect', function () {
144+
context('valid values for `protect`', function () {
145+
test('no options provided', async function () {
146+
await client.wrap('challenge');
147+
});
148+
149+
test('options provided (protect omitted)', async function () {
150+
await client.wrap('challenge', {});
151+
});
152+
153+
test('protect = false', async function () {
154+
await client.wrap('challenge', { protect: false });
155+
});
156+
157+
test('protect = true', async function () {
158+
await client.wrap('challenge', { protect: true });
159+
});
160+
});
161+
162+
context('when set to an invalid value', function () {
163+
it('throws a TypeError', async function () {
164+
const error = await client.wrap('challenge', { protect: 'non-boolean' }).catch(e => e);
165+
expect(error)
166+
.to.be.instanceOf(TypeError)
167+
.to.match(/options.protect must be a boolean/);
168+
});
169+
});
170+
});
171+
});
125172
});

0 commit comments

Comments
 (0)