You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2015/10/14 12:09:20 UTC
[23/52] [partial] couchdb-nmo git commit: prepare for release
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos.js
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos.js b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos.js
new file mode 100644
index 0000000..c7bae58
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos.js
@@ -0,0 +1,164 @@
+var kerberos = require('../build/Release/kerberos')
+ , KerberosNative = kerberos.Kerberos;
+
+var Kerberos = function() {
+ this._native_kerberos = new KerberosNative();
+}
+
+// callback takes two arguments, an error string if defined and a new context
+// uri should be given as service@host. Services are not always defined
+// in a straightforward way. Use 'HTTP' for SPNEGO / Negotiate authentication.
+Kerberos.prototype.authGSSClientInit = function(uri, flags, callback) {
+ return this._native_kerberos.authGSSClientInit(uri, flags, callback);
+}
+
+// This will obtain credentials using a credentials cache. To override the default
+// location (posible /tmp/krb5cc_nnnnnn, where nnnn is your numeric uid) use
+// the environment variable KRB5CNAME.
+// The credentials (suitable for using in an 'Authenticate: ' header, when prefixed
+// with 'Negotiate ') will be available as context.response inside the callback
+// if no error is indicated.
+// callback takes one argument, an error string if defined
+Kerberos.prototype.authGSSClientStep = function(context, challenge, callback) {
+ if(typeof challenge == 'function') {
+ callback = challenge;
+ challenge = '';
+ }
+
+ return this._native_kerberos.authGSSClientStep(context, challenge, callback);
+}
+
+Kerberos.prototype.authGSSClientUnwrap = function(context, challenge, callback) {
+ if(typeof challenge == 'function') {
+ callback = challenge;
+ challenge = '';
+ }
+
+ return this._native_kerberos.authGSSClientUnwrap(context, challenge, callback);
+}
+
+Kerberos.prototype.authGSSClientWrap = function(context, challenge, user_name, callback) {
+ if(typeof user_name == 'function') {
+ callback = user_name;
+ user_name = '';
+ }
+
+ return this._native_kerberos.authGSSClientWrap(context, challenge, user_name, callback);
+}
+
+// free memory used by a context created using authGSSClientInit.
+// callback takes one argument, an error string if defined.
+Kerberos.prototype.authGSSClientClean = function(context, callback) {
+ return this._native_kerberos.authGSSClientClean(context, callback);
+}
+
+// The server will obtain credentials using a keytab. To override the
+// default location (probably /etc/krb5.keytab) set the KRB5_KTNAME
+// environment variable.
+// The service name should be in the form service, or service@host.name
+// e.g. for HTTP, use "HTTP" or "HTTP@my.host.name". See gss_import_name
+// for GSS_C_NT_HOSTBASED_SERVICE.
+//
+// a boolean turns on "constrained_delegation". this enables acquisition of S4U2Proxy
+// credentials which will be stored in a credentials cache during the authGSSServerStep
+// method. this parameter is optional.
+//
+// when "constrained_delegation" is enabled, a username can (optionally) be provided and
+// S4U2Self protocol transition will be initiated. In this case, we will not
+// require any "auth" data during the authGSSServerStep. This parameter is optional
+// but constrained_delegation MUST be enabled for this to work. When S4U2Self is
+// used, the username will be assumed to have been already authenticated, and no
+// actual authentication will be performed. This is basically a way to "bootstrap"
+// kerberos credentials (which can then be delegated with S4U2Proxy) for a user
+// authenticated externally.
+//
+// callback takes two arguments, an error string if defined and a new context
+//
+Kerberos.prototype.authGSSServerInit = function(service, constrained_delegation, username, callback) {
+ if(typeof(constrained_delegation) === 'function') {
+ callback = constrained_delegation;
+ constrained_delegation = false;
+ username = null;
+ }
+
+ if (typeof(constrained_delegation) === 'string') {
+ throw new Error("S4U2Self protocol transation is not possible without enabling constrained delegation");
+ }
+
+ if (typeof(username) === 'function') {
+ callback = username;
+ username = null;
+ }
+
+ constrained_delegation = !!constrained_delegation;
+
+ return this._native_kerberos.authGSSServerInit(service, constrained_delegation, username, callback);
+};
+
+//callback takes one argument, an error string if defined.
+Kerberos.prototype.authGSSServerClean = function(context, callback) {
+ return this._native_kerberos.authGSSServerClean(context, callback);
+};
+
+// authData should be the base64 encoded authentication data obtained
+// from client, e.g., in the Authorization header (without the leading
+// "Negotiate " string) during SPNEGO authentication. The authenticated user
+// is available in context.username after successful authentication.
+// callback takes one argument, an error string if defined.
+//
+// Note: when S4U2Self protocol transition was requested in the authGSSServerInit
+// no actual authentication will be performed and authData will be ignored.
+//
+Kerberos.prototype.authGSSServerStep = function(context, authData, callback) {
+ return this._native_kerberos.authGSSServerStep(context, authData, callback);
+};
+
+Kerberos.prototype.acquireAlternateCredentials = function(user_name, password, domain) {
+ return this._native_kerberos.acquireAlternateCredentials(user_name, password, domain);
+}
+
+Kerberos.prototype.prepareOutboundPackage = function(principal, inputdata) {
+ return this._native_kerberos.prepareOutboundPackage(principal, inputdata);
+}
+
+Kerberos.prototype.decryptMessage = function(challenge) {
+ return this._native_kerberos.decryptMessage(challenge);
+}
+
+Kerberos.prototype.encryptMessage = function(challenge) {
+ return this._native_kerberos.encryptMessage(challenge);
+}
+
+Kerberos.prototype.queryContextAttribute = function(attribute) {
+ if(typeof attribute != 'number' && attribute != 0x00) throw new Error("Attribute not supported");
+ return this._native_kerberos.queryContextAttribute(attribute);
+}
+
+// Some useful result codes
+Kerberos.AUTH_GSS_CONTINUE = 0;
+Kerberos.AUTH_GSS_COMPLETE = 1;
+
+// Some useful gss flags
+Kerberos.GSS_C_DELEG_FLAG = 1;
+Kerberos.GSS_C_MUTUAL_FLAG = 2;
+Kerberos.GSS_C_REPLAY_FLAG = 4;
+Kerberos.GSS_C_SEQUENCE_FLAG = 8;
+Kerberos.GSS_C_CONF_FLAG = 16;
+Kerberos.GSS_C_INTEG_FLAG = 32;
+Kerberos.GSS_C_ANON_FLAG = 64;
+Kerberos.GSS_C_PROT_READY_FLAG = 128;
+Kerberos.GSS_C_TRANS_FLAG = 256;
+
+// Export Kerberos class
+exports.Kerberos = Kerberos;
+
+// If we have SSPI (windows)
+if(kerberos.SecurityCredentials) {
+ // Put all SSPI classes in it's own namespace
+ exports.SSIP = {
+ SecurityCredentials: require('./win32/wrappers/security_credentials').SecurityCredentials
+ , SecurityContext: require('./win32/wrappers/security_context').SecurityContext
+ , SecurityBuffer: require('./win32/wrappers/security_buffer').SecurityBuffer
+ , SecurityBufferDescriptor: require('./win32/wrappers/security_buffer_descriptor').SecurityBufferDescriptor
+ }
+}
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.cc
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.cc b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.cc
new file mode 100644
index 0000000..bf24118
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.cc
@@ -0,0 +1,134 @@
+#include "kerberos_context.h"
+
+Nan::Persistent<FunctionTemplate> KerberosContext::constructor_template;
+
+KerberosContext::KerberosContext() : Nan::ObjectWrap() {
+ state = NULL;
+ server_state = NULL;
+}
+
+KerberosContext::~KerberosContext() {
+}
+
+KerberosContext* KerberosContext::New() {
+ Nan::HandleScope scope;
+ Local<Object> obj = Nan::New(constructor_template)->GetFunction()->NewInstance();
+ KerberosContext *kerberos_context = Nan::ObjectWrap::Unwrap<KerberosContext>(obj);
+ return kerberos_context;
+}
+
+NAN_METHOD(KerberosContext::New) {
+ // Create code object
+ KerberosContext *kerberos_context = new KerberosContext();
+ // Wrap it
+ kerberos_context->Wrap(info.This());
+ // Return the object
+ info.GetReturnValue().Set(info.This());
+}
+
+void KerberosContext::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
+ // Grab the scope of the call from Node
+ Nan::HandleScope scope;
+
+ // Define a new function template
+ Local<FunctionTemplate> t = Nan::New<v8::FunctionTemplate>(static_cast<NAN_METHOD((*))>(New));
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->SetClassName(Nan::New<String>("KerberosContext").ToLocalChecked());
+
+ // Get prototype
+ Local<ObjectTemplate> proto = t->PrototypeTemplate();
+
+ // Getter for the response
+ Nan::SetAccessor(proto, Nan::New<String>("response").ToLocalChecked(), KerberosContext::ResponseGetter);
+
+ // Getter for the username
+ Nan::SetAccessor(proto, Nan::New<String>("username").ToLocalChecked(), KerberosContext::UsernameGetter);
+
+ // Getter for the targetname - server side only
+ Nan::SetAccessor(proto, Nan::New<String>("targetname").ToLocalChecked(), KerberosContext::TargetnameGetter);
+
+ Nan::SetAccessor(proto, Nan::New<String>("delegatedCredentialsCache").ToLocalChecked(), KerberosContext::DelegatedCredentialsCacheGetter);
+
+ // Set persistent
+ constructor_template.Reset(t);
+ // NanAssignPersistent(constructor_template, t);
+
+ // Set the symbol
+ target->ForceSet(Nan::New<String>("KerberosContext").ToLocalChecked(), t->GetFunction());
+}
+
+
+// Response Setter / Getter
+NAN_GETTER(KerberosContext::ResponseGetter) {
+ gss_client_state *client_state;
+ gss_server_state *server_state;
+
+ // Unpack the object
+ KerberosContext *context = Nan::ObjectWrap::Unwrap<KerberosContext>(info.This());
+
+ // Response could come from client or server state...
+ client_state = context->state;
+ server_state = context->server_state;
+
+ // If client state is in use, take response from there, otherwise from server
+ char *response = client_state != NULL ? client_state->response :
+ server_state != NULL ? server_state->response : NULL;
+
+ if(response == NULL) {
+ info.GetReturnValue().Set(Nan::Null());
+ } else {
+ // Return the response
+ info.GetReturnValue().Set(Nan::New<String>(response).ToLocalChecked());
+ }
+}
+
+// username Getter
+NAN_GETTER(KerberosContext::UsernameGetter) {
+ // Unpack the object
+ KerberosContext *context = Nan::ObjectWrap::Unwrap<KerberosContext>(info.This());
+
+ gss_client_state *client_state = context->state;
+ gss_server_state *server_state = context->server_state;
+
+ // If client state is in use, take response from there, otherwise from server
+ char *username = client_state != NULL ? client_state->username :
+ server_state != NULL ? server_state->username : NULL;
+
+ if(username == NULL) {
+ info.GetReturnValue().Set(Nan::Null());
+ } else {
+ info.GetReturnValue().Set(Nan::New<String>(username).ToLocalChecked());
+ }
+}
+
+// targetname Getter - server side only
+NAN_GETTER(KerberosContext::TargetnameGetter) {
+ // Unpack the object
+ KerberosContext *context = Nan::ObjectWrap::Unwrap<KerberosContext>(info.This());
+
+ gss_server_state *server_state = context->server_state;
+
+ char *targetname = server_state != NULL ? server_state->targetname : NULL;
+
+ if(targetname == NULL) {
+ info.GetReturnValue().Set(Nan::Null());
+ } else {
+ info.GetReturnValue().Set(Nan::New<String>(targetname).ToLocalChecked());
+ }
+}
+
+// targetname Getter - server side only
+NAN_GETTER(KerberosContext::DelegatedCredentialsCacheGetter) {
+ // Unpack the object
+ KerberosContext *context = Nan::ObjectWrap::Unwrap<KerberosContext>(info.This());
+
+ gss_server_state *server_state = context->server_state;
+
+ char *delegated_credentials_cache = server_state != NULL ? server_state->delegated_credentials_cache : NULL;
+
+ if(delegated_credentials_cache == NULL) {
+ info.GetReturnValue().Set(Nan::Null());
+ } else {
+ info.GetReturnValue().Set(Nan::New<String>(delegated_credentials_cache).ToLocalChecked());
+ }
+}
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.h
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.h b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.h
new file mode 100644
index 0000000..23eb577
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberos_context.h
@@ -0,0 +1,64 @@
+#ifndef KERBEROS_CONTEXT_H
+#define KERBEROS_CONTEXT_H
+
+#include <node.h>
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_generic.h>
+#include <gssapi/gssapi_krb5.h>
+
+#include "nan.h"
+#include <node_object_wrap.h>
+#include <v8.h>
+
+extern "C" {
+ #include "kerberosgss.h"
+}
+
+using namespace v8;
+using namespace node;
+
+class KerberosContext : public Nan::ObjectWrap {
+
+public:
+ KerberosContext();
+ ~KerberosContext();
+
+ static inline bool HasInstance(Local<Value> val) {
+ if (!val->IsObject()) return false;
+ Local<Object> obj = val->ToObject();
+ return Nan::New(constructor_template)->HasInstance(obj);
+ };
+
+ inline bool IsClientInstance() {
+ return state != NULL;
+ }
+
+ inline bool IsServerInstance() {
+ return server_state != NULL;
+ }
+
+ // Constructor used for creating new Kerberos objects from C++
+ static Nan::Persistent<FunctionTemplate> constructor_template;
+
+ // Initialize function for the object
+ static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target);
+
+ // Public constructor
+ static KerberosContext* New();
+
+ // Handle to the kerberos client context
+ gss_client_state *state;
+
+ // Handle to the kerberos server context
+ gss_server_state *server_state;
+
+private:
+ static NAN_METHOD(New);
+ // In either client state or server state
+ static NAN_GETTER(ResponseGetter);
+ static NAN_GETTER(UsernameGetter);
+ // Only in the "server_state"
+ static NAN_GETTER(TargetnameGetter);
+ static NAN_GETTER(DelegatedCredentialsCacheGetter);
+};
+#endif
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.c
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.c b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.c
new file mode 100644
index 0000000..2fbca00
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.c
@@ -0,0 +1,931 @@
+/**
+ * Copyright (c) 2006-2010 Apple Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ **/
+/*
+ * S4U2Proxy implementation
+ * Copyright (C) 2015 David Mansfield
+ * Code inspired by mod_auth_kerb.
+ */
+
+#include "kerberosgss.h"
+
+#include "base64.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <krb5.h>
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
+void die1(const char *message) {
+ if(errno) {
+ perror(message);
+ } else {
+ printf("ERROR: %s\n", message);
+ }
+
+ exit(1);
+}
+
+static gss_client_response *gss_error(const char *func, const char *op, OM_uint32 err_maj, OM_uint32 err_min);
+static gss_client_response *other_error(const char *fmt, ...);
+static gss_client_response *krb5_ctx_error(krb5_context context, krb5_error_code problem);
+
+static gss_client_response *store_gss_creds(gss_server_state *state);
+static gss_client_response *create_krb5_ccache(gss_server_state *state, krb5_context context, krb5_principal princ, krb5_ccache *ccache);
+
+/*
+char* server_principal_details(const char* service, const char* hostname)
+{
+ char match[1024];
+ int match_len = 0;
+ char* result = NULL;
+
+ int code;
+ krb5_context kcontext;
+ krb5_keytab kt = NULL;
+ krb5_kt_cursor cursor = NULL;
+ krb5_keytab_entry entry;
+ char* pname = NULL;
+
+ // Generate the principal prefix we want to match
+ snprintf(match, 1024, "%s/%s@", service, hostname);
+ match_len = strlen(match);
+
+ code = krb5_init_context(&kcontext);
+ if (code)
+ {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
+ "Cannot initialize Kerberos5 context", code));
+ return NULL;
+ }
+
+ if ((code = krb5_kt_default(kcontext, &kt)))
+ {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
+ "Cannot get default keytab", code));
+ goto end;
+ }
+
+ if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor)))
+ {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
+ "Cannot get sequence cursor from keytab", code));
+ goto end;
+ }
+
+ while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0)
+ {
+ if ((code = krb5_unparse_name(kcontext, entry.principal, &pname)))
+ {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
+ "Cannot parse principal name from keytab", code));
+ goto end;
+ }
+
+ if (strncmp(pname, match, match_len) == 0)
+ {
+ result = malloc(strlen(pname) + 1);
+ strcpy(result, pname);
+ krb5_free_unparsed_name(kcontext, pname);
+ krb5_free_keytab_entry_contents(kcontext, &entry);
+ break;
+ }
+
+ krb5_free_unparsed_name(kcontext, pname);
+ krb5_free_keytab_entry_contents(kcontext, &entry);
+ }
+
+ if (result == NULL)
+ {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
+ "Principal not found in keytab", -1));
+ }
+
+end:
+ if (cursor)
+ krb5_kt_end_seq_get(kcontext, kt, &cursor);
+ if (kt)
+ krb5_kt_close(kcontext, kt);
+ krb5_free_context(kcontext);
+
+ return result;
+}
+*/
+gss_client_response *authenticate_gss_client_init(const char* service, long int gss_flags, gss_client_state* state) {
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
+ gss_client_response *response = NULL;
+ int ret = AUTH_GSS_COMPLETE;
+
+ state->server_name = GSS_C_NO_NAME;
+ state->context = GSS_C_NO_CONTEXT;
+ state->gss_flags = gss_flags;
+ state->username = NULL;
+ state->response = NULL;
+
+ // Import server name first
+ name_token.length = strlen(service);
+ name_token.value = (char *)service;
+
+ maj_stat = gss_import_name(&min_stat, &name_token, gss_krb5_nt_service_name, &state->server_name);
+
+ if (GSS_ERROR(maj_stat)) {
+ response = gss_error(__func__, "gss_import_name", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+end:
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ return response;
+}
+
+gss_client_response *authenticate_gss_client_clean(gss_client_state *state) {
+ OM_uint32 min_stat;
+ int ret = AUTH_GSS_COMPLETE;
+ gss_client_response *response = NULL;
+
+ if(state->context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&min_stat, &state->context, GSS_C_NO_BUFFER);
+
+ if(state->server_name != GSS_C_NO_NAME)
+ gss_release_name(&min_stat, &state->server_name);
+
+ if(state->username != NULL) {
+ free(state->username);
+ state->username = NULL;
+ }
+
+ if (state->response != NULL) {
+ free(state->response);
+ state->response = NULL;
+ }
+
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ return response;
+}
+
+gss_client_response *authenticate_gss_client_step(gss_client_state* state, const char* challenge) {
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ int ret = AUTH_GSS_CONTINUE;
+ gss_client_response *response = NULL;
+
+ // Always clear out the old response
+ if (state->response != NULL) {
+ free(state->response);
+ state->response = NULL;
+ }
+
+ // If there is a challenge (data from the server) we need to give it to GSS
+ if (challenge && *challenge) {
+ int len;
+ input_token.value = base64_decode(challenge, &len);
+ input_token.length = len;
+ }
+
+ // Do GSSAPI step
+ maj_stat = gss_init_sec_context(&min_stat,
+ GSS_C_NO_CREDENTIAL,
+ &state->context,
+ state->server_name,
+ GSS_C_NO_OID,
+ (OM_uint32)state->gss_flags,
+ 0,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &input_token,
+ NULL,
+ &output_token,
+ NULL,
+ NULL);
+
+ if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED)) {
+ response = gss_error(__func__, "gss_init_sec_context", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ ret = (maj_stat == GSS_S_COMPLETE) ? AUTH_GSS_COMPLETE : AUTH_GSS_CONTINUE;
+ // Grab the client response to send back to the server
+ if(output_token.length) {
+ state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);
+ maj_stat = gss_release_buffer(&min_stat, &output_token);
+ }
+
+ // Try to get the user name if we have completed all GSS operations
+ if (ret == AUTH_GSS_COMPLETE) {
+ gss_name_t gssuser = GSS_C_NO_NAME;
+ maj_stat = gss_inquire_context(&min_stat, state->context, &gssuser, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ if(GSS_ERROR(maj_stat)) {
+ response = gss_error(__func__, "gss_inquire_context", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ gss_buffer_desc name_token;
+ name_token.length = 0;
+ maj_stat = gss_display_name(&min_stat, gssuser, &name_token, NULL);
+
+ if(GSS_ERROR(maj_stat)) {
+ if(name_token.value)
+ gss_release_buffer(&min_stat, &name_token);
+ gss_release_name(&min_stat, &gssuser);
+
+ response = gss_error(__func__, "gss_display_name", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ } else {
+ state->username = (char *)malloc(name_token.length + 1);
+ if(state->username == NULL) die1("Memory allocation failed");
+ strncpy(state->username, (char*) name_token.value, name_token.length);
+ state->username[name_token.length] = 0;
+ gss_release_buffer(&min_stat, &name_token);
+ gss_release_name(&min_stat, &gssuser);
+ }
+ }
+
+end:
+ if(output_token.value)
+ gss_release_buffer(&min_stat, &output_token);
+ if(input_token.value)
+ free(input_token.value);
+
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ // Return the response
+ return response;
+}
+
+gss_client_response *authenticate_gss_client_unwrap(gss_client_state *state, const char *challenge) {
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ gss_client_response *response = NULL;
+ int ret = AUTH_GSS_CONTINUE;
+
+ // Always clear out the old response
+ if(state->response != NULL) {
+ free(state->response);
+ state->response = NULL;
+ }
+
+ // If there is a challenge (data from the server) we need to give it to GSS
+ if(challenge && *challenge) {
+ int len;
+ input_token.value = base64_decode(challenge, &len);
+ input_token.length = len;
+ }
+
+ // Do GSSAPI step
+ maj_stat = gss_unwrap(&min_stat,
+ state->context,
+ &input_token,
+ &output_token,
+ NULL,
+ NULL);
+
+ if(maj_stat != GSS_S_COMPLETE) {
+ response = gss_error(__func__, "gss_unwrap", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ } else {
+ ret = AUTH_GSS_COMPLETE;
+ }
+
+ // Grab the client response
+ if(output_token.length) {
+ state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);
+ gss_release_buffer(&min_stat, &output_token);
+ }
+end:
+ if(output_token.value)
+ gss_release_buffer(&min_stat, &output_token);
+ if(input_token.value)
+ free(input_token.value);
+
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ // Return the response
+ return response;
+}
+
+gss_client_response *authenticate_gss_client_wrap(gss_client_state* state, const char* challenge, const char* user) {
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ int ret = AUTH_GSS_CONTINUE;
+ gss_client_response *response = NULL;
+ char buf[4096], server_conf_flags;
+ unsigned long buf_size;
+
+ // Always clear out the old response
+ if(state->response != NULL) {
+ free(state->response);
+ state->response = NULL;
+ }
+
+ if(challenge && *challenge) {
+ int len;
+ input_token.value = base64_decode(challenge, &len);
+ input_token.length = len;
+ }
+
+ if(user) {
+ // get bufsize
+ server_conf_flags = ((char*) input_token.value)[0];
+ ((char*) input_token.value)[0] = 0;
+ buf_size = ntohl(*((long *) input_token.value));
+ free(input_token.value);
+#ifdef PRINTFS
+ printf("User: %s, %c%c%c\n", user,
+ server_conf_flags & GSS_AUTH_P_NONE ? 'N' : '-',
+ server_conf_flags & GSS_AUTH_P_INTEGRITY ? 'I' : '-',
+ server_conf_flags & GSS_AUTH_P_PRIVACY ? 'P' : '-');
+ printf("Maximum GSS token size is %ld\n", buf_size);
+#endif
+
+ // agree to terms (hack!)
+ buf_size = htonl(buf_size); // not relevant without integrity/privacy
+ memcpy(buf, &buf_size, 4);
+ buf[0] = GSS_AUTH_P_NONE;
+ // server decides if principal can log in as user
+ strncpy(buf + 4, user, sizeof(buf) - 4);
+ input_token.value = buf;
+ input_token.length = 4 + strlen(user);
+ }
+
+ // Do GSSAPI wrap
+ maj_stat = gss_wrap(&min_stat,
+ state->context,
+ 0,
+ GSS_C_QOP_DEFAULT,
+ &input_token,
+ NULL,
+ &output_token);
+
+ if (maj_stat != GSS_S_COMPLETE) {
+ response = gss_error(__func__, "gss_wrap", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ } else
+ ret = AUTH_GSS_COMPLETE;
+ // Grab the client response to send back to the server
+ if (output_token.length) {
+ state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);;
+ gss_release_buffer(&min_stat, &output_token);
+ }
+end:
+ if (output_token.value)
+ gss_release_buffer(&min_stat, &output_token);
+
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ // Return the response
+ return response;
+}
+
+gss_client_response *authenticate_gss_server_init(const char *service, bool constrained_delegation, const char *username, gss_server_state *state)
+{
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
+ int ret = AUTH_GSS_COMPLETE;
+ gss_client_response *response = NULL;
+ gss_cred_usage_t usage = GSS_C_ACCEPT;
+
+ state->context = GSS_C_NO_CONTEXT;
+ state->server_name = GSS_C_NO_NAME;
+ state->client_name = GSS_C_NO_NAME;
+ state->server_creds = GSS_C_NO_CREDENTIAL;
+ state->client_creds = GSS_C_NO_CREDENTIAL;
+ state->username = NULL;
+ state->targetname = NULL;
+ state->response = NULL;
+ state->constrained_delegation = constrained_delegation;
+ state->delegated_credentials_cache = NULL;
+
+ // Server name may be empty which means we aren't going to create our own creds
+ size_t service_len = strlen(service);
+ if (service_len != 0)
+ {
+ // Import server name first
+ name_token.length = strlen(service);
+ name_token.value = (char *)service;
+
+ maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_HOSTBASED_SERVICE, &state->server_name);
+
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_import_name", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ if (state->constrained_delegation)
+ {
+ usage = GSS_C_BOTH;
+ }
+
+ // Get credentials
+ maj_stat = gss_acquire_cred(&min_stat, state->server_name, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, usage, &state->server_creds, NULL, NULL);
+
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_acquire_cred", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+ }
+
+ // If a username was passed, perform the S4U2Self protocol transition to acquire
+ // a credentials from that user as if we had done gss_accept_sec_context.
+ // In this scenario, the passed username is assumed to be already authenticated
+ // by some external mechanism, and we are here to "bootstrap" some gss credentials.
+ // In authenticate_gss_server_step we will bypass the actual authentication step.
+ if (username != NULL)
+ {
+ gss_name_t gss_username;
+
+ name_token.length = strlen(username);
+ name_token.value = (char *)username;
+
+ maj_stat = gss_import_name(&min_stat, &name_token, GSS_C_NT_USER_NAME, &gss_username);
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_import_name", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ maj_stat = gss_acquire_cred_impersonate_name(&min_stat,
+ state->server_creds,
+ gss_username,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET,
+ GSS_C_INITIATE,
+ &state->client_creds,
+ NULL,
+ NULL);
+
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_acquire_cred_impersonate_name", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ }
+
+ gss_release_name(&min_stat, &gss_username);
+
+ if (response != NULL)
+ {
+ goto end;
+ }
+
+ // because the username MAY be a "local" username,
+ // we want get the canonical name from the acquired creds.
+ maj_stat = gss_inquire_cred(&min_stat, state->client_creds, &state->client_name, NULL, NULL, NULL);
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_inquire_cred", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+ }
+
+end:
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ // Return the response
+ return response;
+}
+
+gss_client_response *authenticate_gss_server_clean(gss_server_state *state)
+{
+ OM_uint32 min_stat;
+ int ret = AUTH_GSS_COMPLETE;
+ gss_client_response *response = NULL;
+
+ if (state->context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&min_stat, &state->context, GSS_C_NO_BUFFER);
+ if (state->server_name != GSS_C_NO_NAME)
+ gss_release_name(&min_stat, &state->server_name);
+ if (state->client_name != GSS_C_NO_NAME)
+ gss_release_name(&min_stat, &state->client_name);
+ if (state->server_creds != GSS_C_NO_CREDENTIAL)
+ gss_release_cred(&min_stat, &state->server_creds);
+ if (state->client_creds != GSS_C_NO_CREDENTIAL)
+ gss_release_cred(&min_stat, &state->client_creds);
+ if (state->username != NULL)
+ {
+ free(state->username);
+ state->username = NULL;
+ }
+ if (state->targetname != NULL)
+ {
+ free(state->targetname);
+ state->targetname = NULL;
+ }
+ if (state->response != NULL)
+ {
+ free(state->response);
+ state->response = NULL;
+ }
+ if (state->delegated_credentials_cache)
+ {
+ // TODO: what about actually destroying the cache? It can't be done now as
+ // the whole point is having it around for the lifetime of the "session"
+ free(state->delegated_credentials_cache);
+ }
+
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ // Return the response
+ return response;
+}
+
+gss_client_response *authenticate_gss_server_step(gss_server_state *state, const char *auth_data)
+{
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+ int ret = AUTH_GSS_CONTINUE;
+ gss_client_response *response = NULL;
+
+ // Always clear out the old response
+ if (state->response != NULL)
+ {
+ free(state->response);
+ state->response = NULL;
+ }
+
+ // we don't need to check the authentication token if S4U2Self protocol
+ // transition was done, because we already have the client credentials.
+ if (state->client_creds == GSS_C_NO_CREDENTIAL)
+ {
+ if (auth_data && *auth_data)
+ {
+ int len;
+ input_token.value = base64_decode(auth_data, &len);
+ input_token.length = len;
+ }
+ else
+ {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->message = strdup("No auth_data value in request from client");
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ maj_stat = gss_accept_sec_context(&min_stat,
+ &state->context,
+ state->server_creds,
+ &input_token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &state->client_name,
+ NULL,
+ &output_token,
+ NULL,
+ NULL,
+ &state->client_creds);
+
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_accept_sec_context", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ // Grab the server response to send back to the client
+ if (output_token.length)
+ {
+ state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);
+ maj_stat = gss_release_buffer(&min_stat, &output_token);
+ }
+ }
+
+ // Get the user name
+ maj_stat = gss_display_name(&min_stat, state->client_name, &output_token, NULL);
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_display_name", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+ state->username = (char *)malloc(output_token.length + 1);
+ strncpy(state->username, (char*) output_token.value, output_token.length);
+ state->username[output_token.length] = 0;
+
+ // Get the target name if no server creds were supplied
+ if (state->server_creds == GSS_C_NO_CREDENTIAL)
+ {
+ gss_name_t target_name = GSS_C_NO_NAME;
+ maj_stat = gss_inquire_context(&min_stat, state->context, NULL, &target_name, NULL, NULL, NULL, NULL, NULL);
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_inquire_context", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+ maj_stat = gss_display_name(&min_stat, target_name, &output_token, NULL);
+ if (GSS_ERROR(maj_stat))
+ {
+ response = gss_error(__func__, "gss_display_name", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+ state->targetname = (char *)malloc(output_token.length + 1);
+ strncpy(state->targetname, (char*) output_token.value, output_token.length);
+ state->targetname[output_token.length] = 0;
+ }
+
+ if (state->constrained_delegation && state->client_creds != GSS_C_NO_CREDENTIAL)
+ {
+ if ((response = store_gss_creds(state)) != NULL)
+ {
+ goto end;
+ }
+ }
+
+ ret = AUTH_GSS_COMPLETE;
+
+end:
+ if (output_token.length)
+ gss_release_buffer(&min_stat, &output_token);
+ if (input_token.value)
+ free(input_token.value);
+
+ if(response == NULL) {
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->return_code = ret;
+ }
+
+ // Return the response
+ return response;
+}
+
+static gss_client_response *store_gss_creds(gss_server_state *state)
+{
+ OM_uint32 maj_stat, min_stat;
+ krb5_principal princ = NULL;
+ krb5_ccache ccache = NULL;
+ krb5_error_code problem;
+ krb5_context context;
+ gss_client_response *response = NULL;
+
+ problem = krb5_init_context(&context);
+ if (problem) {
+ response = other_error("No auth_data value in request from client");
+ return response;
+ }
+
+ problem = krb5_parse_name(context, state->username, &princ);
+ if (problem) {
+ response = krb5_ctx_error(context, problem);
+ goto end;
+ }
+
+ if ((response = create_krb5_ccache(state, context, princ, &ccache)))
+ {
+ goto end;
+ }
+
+ maj_stat = gss_krb5_copy_ccache(&min_stat, state->client_creds, ccache);
+ if (GSS_ERROR(maj_stat)) {
+ response = gss_error(__func__, "gss_krb5_copy_ccache", maj_stat, min_stat);
+ response->return_code = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ krb5_cc_close(context, ccache);
+ ccache = NULL;
+
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ // TODO: something other than AUTH_GSS_COMPLETE?
+ response->return_code = AUTH_GSS_COMPLETE;
+
+ end:
+ if (princ)
+ krb5_free_principal(context, princ);
+ if (ccache)
+ krb5_cc_destroy(context, ccache);
+ krb5_free_context(context);
+
+ return response;
+}
+
+static gss_client_response *create_krb5_ccache(gss_server_state *state, krb5_context kcontext, krb5_principal princ, krb5_ccache *ccache)
+{
+ char *ccname = NULL;
+ int fd;
+ krb5_error_code problem;
+ krb5_ccache tmp_ccache = NULL;
+ gss_client_response *error = NULL;
+
+ // TODO: mod_auth_kerb used a temp file under /run/httpd/krbcache. what can we do?
+ ccname = strdup("FILE:/tmp/krb5cc_nodekerberos_XXXXXX");
+ if (!ccname) die1("Memory allocation failed");
+
+ fd = mkstemp(ccname + strlen("FILE:"));
+ if (fd < 0) {
+ error = other_error("mkstemp() failed: %s", strerror(errno));
+ goto end;
+ }
+
+ close(fd);
+
+ problem = krb5_cc_resolve(kcontext, ccname, &tmp_ccache);
+ if (problem) {
+ error = krb5_ctx_error(kcontext, problem);
+ goto end;
+ }
+
+ problem = krb5_cc_initialize(kcontext, tmp_ccache, princ);
+ if (problem) {
+ error = krb5_ctx_error(kcontext, problem);
+ goto end;
+ }
+
+ state->delegated_credentials_cache = strdup(ccname);
+
+ // TODO: how/when to cleanup the creds cache file?
+ // TODO: how to expose the credentials expiration time?
+
+ *ccache = tmp_ccache;
+ tmp_ccache = NULL;
+
+ end:
+ if (tmp_ccache)
+ krb5_cc_destroy(kcontext, tmp_ccache);
+
+ if (ccname && error)
+ unlink(ccname);
+
+ if (ccname)
+ free(ccname);
+
+ return error;
+}
+
+
+gss_client_response *gss_error(const char *func, const char *op, OM_uint32 err_maj, OM_uint32 err_min) {
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+
+ gss_client_response *response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+
+ char *message = NULL;
+ message = calloc(1024, 1);
+ if(message == NULL) die1("Memory allocation failed");
+
+ response->message = message;
+
+ int nleft = 1024;
+ int n;
+
+ n = snprintf(message, nleft, "%s(%s)", func, op);
+ message += n;
+ nleft -= n;
+
+ do {
+ maj_stat = gss_display_status (&min_stat,
+ err_maj,
+ GSS_C_GSS_CODE,
+ GSS_C_NO_OID,
+ &msg_ctx,
+ &status_string);
+ if(GSS_ERROR(maj_stat))
+ break;
+
+ n = snprintf(message, nleft, ": %.*s",
+ (int)status_string.length, (char*)status_string.value);
+ message += n;
+ nleft -= n;
+
+ gss_release_buffer(&min_stat, &status_string);
+
+ maj_stat = gss_display_status (&min_stat,
+ err_min,
+ GSS_C_MECH_CODE,
+ GSS_C_NULL_OID,
+ &msg_ctx,
+ &status_string);
+ if(!GSS_ERROR(maj_stat)) {
+ n = snprintf(message, nleft, ": %.*s",
+ (int)status_string.length, (char*)status_string.value);
+ message += n;
+ nleft -= n;
+
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+ return response;
+}
+
+static gss_client_response *krb5_ctx_error(krb5_context context, krb5_error_code problem)
+{
+ gss_client_response *response = NULL;
+ const char *error_text = krb5_get_error_message(context, problem);
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->message = strdup(error_text);
+ // TODO: something other than AUTH_GSS_ERROR? AUTH_KRB5_ERROR ?
+ response->return_code = AUTH_GSS_ERROR;
+ krb5_free_error_message(context, error_text);
+ return response;
+}
+
+static gss_client_response *other_error(const char *fmt, ...)
+{
+ size_t needed;
+ char *msg;
+ gss_client_response *response = NULL;
+ va_list ap, aps;
+
+ va_start(ap, fmt);
+
+ va_copy(aps, ap);
+ needed = snprintf(NULL, 0, fmt, aps);
+ va_end(aps);
+
+ msg = malloc(needed);
+ if (!msg) die1("Memory allocation failed");
+
+ vsnprintf(msg, needed, fmt, ap);
+ va_end(ap);
+
+ response = calloc(1, sizeof(gss_client_response));
+ if(response == NULL) die1("Memory allocation failed");
+ response->message = msg;
+
+ // TODO: something other than AUTH_GSS_ERROR?
+ response->return_code = AUTH_GSS_ERROR;
+
+ return response;
+}
+
+
+#pragma clang diagnostic pop
+
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.h
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.h b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.h
new file mode 100644
index 0000000..fa7e311
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/kerberosgss.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2006-2009 Apple Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+#ifndef KERBEROS_GSS_H
+#define KERBEROS_GSS_H
+
+#include <stdbool.h>
+
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_generic.h>
+#include <gssapi/gssapi_krb5.h>
+
+#define krb5_get_err_text(context,code) error_message(code)
+
+#define AUTH_GSS_ERROR -1
+#define AUTH_GSS_COMPLETE 1
+#define AUTH_GSS_CONTINUE 0
+
+#define GSS_AUTH_P_NONE 1
+#define GSS_AUTH_P_INTEGRITY 2
+#define GSS_AUTH_P_PRIVACY 4
+
+typedef struct {
+ int return_code;
+ char *message;
+} gss_client_response;
+
+typedef struct {
+ gss_ctx_id_t context;
+ gss_name_t server_name;
+ long int gss_flags;
+ char* username;
+ char* response;
+} gss_client_state;
+
+typedef struct {
+ gss_ctx_id_t context;
+ gss_name_t server_name;
+ gss_name_t client_name;
+ gss_cred_id_t server_creds;
+ gss_cred_id_t client_creds;
+ char* username;
+ char* targetname;
+ char* response;
+ bool constrained_delegation;
+ char* delegated_credentials_cache;
+} gss_server_state;
+
+// char* server_principal_details(const char* service, const char* hostname);
+
+gss_client_response *authenticate_gss_client_init(const char* service, long int gss_flags, gss_client_state* state);
+gss_client_response *authenticate_gss_client_clean(gss_client_state *state);
+gss_client_response *authenticate_gss_client_step(gss_client_state *state, const char *challenge);
+gss_client_response *authenticate_gss_client_unwrap(gss_client_state* state, const char* challenge);
+gss_client_response *authenticate_gss_client_wrap(gss_client_state* state, const char* challenge, const char* user);
+
+gss_client_response *authenticate_gss_server_init(const char* service, bool constrained_delegation, const char *username, gss_server_state* state);
+gss_client_response *authenticate_gss_server_clean(gss_server_state *state);
+gss_client_response *authenticate_gss_server_step(gss_server_state *state, const char *challenge);
+
+#endif
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/sspi.js
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/sspi.js b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/sspi.js
new file mode 100644
index 0000000..d9120fb
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/sspi.js
@@ -0,0 +1,15 @@
+// Load the native SSPI classes
+var kerberos = require('../build/Release/kerberos')
+ , Kerberos = kerberos.Kerberos
+ , SecurityBuffer = require('./win32/wrappers/security_buffer').SecurityBuffer
+ , SecurityBufferDescriptor = require('./win32/wrappers/security_buffer_descriptor').SecurityBufferDescriptor
+ , SecurityCredentials = require('./win32/wrappers/security_credentials').SecurityCredentials
+ , SecurityContext = require('./win32/wrappers/security_context').SecurityContext;
+var SSPI = function() {
+}
+
+exports.SSPI = SSPI;
+exports.SecurityBuffer = SecurityBuffer;
+exports.SecurityBufferDescriptor = SecurityBufferDescriptor;
+exports.SecurityCredentials = SecurityCredentials;
+exports.SecurityContext = SecurityContext;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.c
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.c b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.c
new file mode 100644
index 0000000..502a021
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.c
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+#include "base64.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+// base64 tables
+static char basis_64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static signed char index_64[128] =
+{
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+ 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
+ -1, 0, 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,-1, -1,-1,-1,-1,
+ -1,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,-1, -1,-1,-1,-1
+};
+#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
+
+// base64_encode : base64 encode
+//
+// value : data to encode
+// vlen : length of data
+// (result) : new char[] - c-str of result
+char *base64_encode(const unsigned char *value, int vlen)
+{
+ char *result = (char *)malloc((vlen * 4) / 3 + 5);
+ char *out = result;
+ unsigned char oval;
+
+ while (vlen >= 3)
+ {
+ *out++ = basis_64[value[0] >> 2];
+ *out++ = basis_64[((value[0] << 4) & 0x30) | (value[1] >> 4)];
+ *out++ = basis_64[((value[1] << 2) & 0x3C) | (value[2] >> 6)];
+ *out++ = basis_64[value[2] & 0x3F];
+ value += 3;
+ vlen -= 3;
+ }
+ if (vlen > 0)
+ {
+ *out++ = basis_64[value[0] >> 2];
+ oval = (value[0] << 4) & 0x30;
+ if (vlen > 1) oval |= value[1] >> 4;
+ *out++ = basis_64[oval];
+ *out++ = (vlen < 2) ? '=' : basis_64[(value[1] << 2) & 0x3C];
+ *out++ = '=';
+ }
+ *out = '\0';
+
+ return result;
+}
+
+// base64_decode : base64 decode
+//
+// value : c-str to decode
+// rlen : length of decoded result
+// (result) : new unsigned char[] - decoded result
+unsigned char *base64_decode(const char *value, int *rlen)
+{
+ int c1, c2, c3, c4;
+ int vlen = (int)strlen(value);
+ unsigned char *result =(unsigned char *)malloc((vlen * 3) / 4 + 1);
+ unsigned char *out = result;
+ *rlen = 0;
+
+ while (1)
+ {
+ if (value[0]==0)
+ return result;
+ c1 = value[0];
+ if (CHAR64(c1) == -1)
+ goto base64_decode_error;;
+ c2 = value[1];
+ if (CHAR64(c2) == -1)
+ goto base64_decode_error;;
+ c3 = value[2];
+ if ((c3 != '=') && (CHAR64(c3) == -1))
+ goto base64_decode_error;;
+ c4 = value[3];
+ if ((c4 != '=') && (CHAR64(c4) == -1))
+ goto base64_decode_error;;
+
+ value += 4;
+ *out++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
+ *rlen += 1;
+ if (c3 != '=')
+ {
+ *out++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
+ *rlen += 1;
+ if (c4 != '=')
+ {
+ *out++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
+ *rlen += 1;
+ }
+ }
+ }
+
+base64_decode_error:
+ *result = 0;
+ *rlen = 0;
+ return result;
+}
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.h
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.h b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.h
new file mode 100644
index 0000000..f0e1f06
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/base64.h
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+
+char *base64_encode(const unsigned char *value, int vlen);
+unsigned char *base64_decode(const char *value, int *rlen);
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.cc
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.cc b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.cc
new file mode 100644
index 0000000..c7b583f
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.cc
@@ -0,0 +1,51 @@
+#include "kerberos.h"
+#include <stdlib.h>
+#include <tchar.h>
+#include "base64.h"
+#include "wrappers/security_buffer.h"
+#include "wrappers/security_buffer_descriptor.h"
+#include "wrappers/security_context.h"
+#include "wrappers/security_credentials.h"
+
+Nan::Persistent<FunctionTemplate> Kerberos::constructor_template;
+
+Kerberos::Kerberos() : Nan::ObjectWrap() {
+}
+
+void Kerberos::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
+ // Grab the scope of the call from Node
+ Nan::HandleScope scope;
+
+ // Define a new function template
+ Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->SetClassName(Nan::New<String>("Kerberos").ToLocalChecked());
+
+ // Set persistent
+ constructor_template.Reset(t);
+
+ // Set the symbol
+ Nan::Set(target, Nan::New<String>("Kerberos").ToLocalChecked(), t->GetFunction());
+}
+
+NAN_METHOD(Kerberos::New) {
+ // Load the security.dll library
+ load_library();
+ // Create a Kerberos instance
+ Kerberos *kerberos = new Kerberos();
+ // Return the kerberos object
+ kerberos->Wrap(info.This());
+ // Return the object
+ info.GetReturnValue().Set(info.This());
+}
+
+// Exporting function
+NAN_MODULE_INIT(init) {
+ Kerberos::Initialize(target);
+ SecurityContext::Initialize(target);
+ SecurityBuffer::Initialize(target);
+ SecurityBufferDescriptor::Initialize(target);
+ SecurityCredentials::Initialize(target);
+}
+
+NODE_MODULE(kerberos, init);
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.h
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.h b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.h
new file mode 100644
index 0000000..0fd2760
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos.h
@@ -0,0 +1,60 @@
+#ifndef KERBEROS_H
+#define KERBEROS_H
+
+#include <node.h>
+#include <node_object_wrap.h>
+#include <v8.h>
+#include "nan.h"
+
+extern "C" {
+ #include "kerberos_sspi.h"
+ #include "base64.h"
+}
+
+using namespace v8;
+using namespace node;
+
+class Kerberos : public Nan::ObjectWrap {
+
+public:
+ Kerberos();
+ ~Kerberos() {};
+
+ // Constructor used for creating new Kerberos objects from C++
+ static Nan::Persistent<FunctionTemplate> constructor_template;
+
+ // Initialize function for the object
+ static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target);
+
+ // Method available
+ static NAN_METHOD(AcquireAlternateCredentials);
+ static NAN_METHOD(PrepareOutboundPackage);
+ static NAN_METHOD(DecryptMessage);
+ static NAN_METHOD(EncryptMessage);
+ static NAN_METHOD(QueryContextAttributes);
+
+private:
+ static NAN_METHOD(New);
+
+ // Pointer to context object
+ SEC_WINNT_AUTH_IDENTITY m_Identity;
+ // credentials
+ CredHandle m_Credentials;
+ // Expiry time for ticket
+ TimeStamp Expiration;
+ // package info
+ SecPkgInfo m_PkgInfo;
+ // context
+ CtxtHandle m_Context;
+ // Do we have a context
+ bool m_HaveContext;
+ // Attributes
+ DWORD CtxtAttr;
+
+ // Handles the uv calls
+ static void Process(uv_work_t* work_req);
+ // Called after work is done
+ static void After(uv_work_t* work_req);
+};
+
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.c
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.c b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.c
new file mode 100644
index 0000000..d75c9ab
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.c
@@ -0,0 +1,244 @@
+#include "kerberos_sspi.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+static HINSTANCE _sspi_security_dll = NULL;
+static HINSTANCE _sspi_secur32_dll = NULL;
+
+/**
+ * Encrypt A Message
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_EncryptMessage(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo) {
+ // Create function pointer instance
+ encryptMessage_fn pfn_encryptMessage = NULL;
+
+ // Return error if library not loaded
+ if(_sspi_security_dll == NULL) return -1;
+
+ // Map function to library method
+ pfn_encryptMessage = (encryptMessage_fn)GetProcAddress(_sspi_security_dll, "EncryptMessage");
+ // Check if the we managed to map function pointer
+ if(!pfn_encryptMessage) {
+ printf("GetProcAddress failed.\n");
+ return -2;
+ }
+
+ // Call the function
+ return (*pfn_encryptMessage)(phContext, fQOP, pMessage, MessageSeqNo);
+}
+
+/**
+ * Acquire Credentials
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_AcquireCredentialsHandle(
+ LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse,
+ void * pvLogonId, void * pAuthData, SEC_GET_KEY_FN pGetKeyFn, void * pvGetKeyArgument,
+ PCredHandle phCredential, PTimeStamp ptsExpiry
+) {
+ SECURITY_STATUS status;
+ // Create function pointer instance
+ acquireCredentialsHandle_fn pfn_acquireCredentialsHandle = NULL;
+
+ // Return error if library not loaded
+ if(_sspi_security_dll == NULL) return -1;
+
+ // Map function
+ #ifdef _UNICODE
+ pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn)GetProcAddress(_sspi_security_dll, "AcquireCredentialsHandleW");
+ #else
+ pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn)GetProcAddress(_sspi_security_dll, "AcquireCredentialsHandleA");
+ #endif
+
+ // Check if the we managed to map function pointer
+ if(!pfn_acquireCredentialsHandle) {
+ printf("GetProcAddress failed.\n");
+ return -2;
+ }
+
+ // Status
+ status = (*pfn_acquireCredentialsHandle)(pszPrincipal, pszPackage, fCredentialUse,
+ pvLogonId, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry
+ );
+
+ // Call the function
+ return status;
+}
+
+/**
+ * Delete Security Context
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_DeleteSecurityContext(PCtxtHandle phContext) {
+ // Create function pointer instance
+ deleteSecurityContext_fn pfn_deleteSecurityContext = NULL;
+
+ // Return error if library not loaded
+ if(_sspi_security_dll == NULL) return -1;
+ // Map function
+ pfn_deleteSecurityContext = (deleteSecurityContext_fn)GetProcAddress(_sspi_security_dll, "DeleteSecurityContext");
+
+ // Check if the we managed to map function pointer
+ if(!pfn_deleteSecurityContext) {
+ printf("GetProcAddress failed.\n");
+ return -2;
+ }
+
+ // Call the function
+ return (*pfn_deleteSecurityContext)(phContext);
+}
+
+/**
+ * Decrypt Message
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, unsigned long MessageSeqNo, unsigned long pfQOP) {
+ // Create function pointer instance
+ decryptMessage_fn pfn_decryptMessage = NULL;
+
+ // Return error if library not loaded
+ if(_sspi_security_dll == NULL) return -1;
+ // Map function
+ pfn_decryptMessage = (decryptMessage_fn)GetProcAddress(_sspi_security_dll, "DecryptMessage");
+
+ // Check if the we managed to map function pointer
+ if(!pfn_decryptMessage) {
+ printf("GetProcAddress failed.\n");
+ return -2;
+ }
+
+ // Call the function
+ return (*pfn_decryptMessage)(phContext, pMessage, MessageSeqNo, pfQOP);
+}
+
+/**
+ * Initialize Security Context
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_initializeSecurityContext(
+ PCredHandle phCredential, PCtxtHandle phContext,
+ LPSTR pszTargetName, unsigned long fContextReq,
+ unsigned long Reserved1, unsigned long TargetDataRep,
+ PSecBufferDesc pInput, unsigned long Reserved2,
+ PCtxtHandle phNewContext, PSecBufferDesc pOutput,
+ unsigned long * pfContextAttr, PTimeStamp ptsExpiry
+) {
+ SECURITY_STATUS status;
+ // Create function pointer instance
+ initializeSecurityContext_fn pfn_initializeSecurityContext = NULL;
+
+ // Return error if library not loaded
+ if(_sspi_security_dll == NULL) return -1;
+
+ // Map function
+ #ifdef _UNICODE
+ pfn_initializeSecurityContext = (initializeSecurityContext_fn)GetProcAddress(_sspi_security_dll, "InitializeSecurityContextW");
+ #else
+ pfn_initializeSecurityContext = (initializeSecurityContext_fn)GetProcAddress(_sspi_security_dll, "InitializeSecurityContextA");
+ #endif
+
+ // Check if the we managed to map function pointer
+ if(!pfn_initializeSecurityContext) {
+ printf("GetProcAddress failed.\n");
+ return -2;
+ }
+
+ // Execute intialize context
+ status = (*pfn_initializeSecurityContext)(
+ phCredential, phContext, pszTargetName, fContextReq,
+ Reserved1, TargetDataRep, pInput, Reserved2,
+ phNewContext, pOutput, pfContextAttr, ptsExpiry
+ );
+
+ // Call the function
+ return status;
+}
+/**
+ * Query Context Attributes
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_QueryContextAttributes(
+ PCtxtHandle phContext, unsigned long ulAttribute, void * pBuffer
+) {
+ // Create function pointer instance
+ queryContextAttributes_fn pfn_queryContextAttributes = NULL;
+
+ // Return error if library not loaded
+ if(_sspi_security_dll == NULL) return -1;
+
+ #ifdef _UNICODE
+ pfn_queryContextAttributes = (queryContextAttributes_fn)GetProcAddress(_sspi_security_dll, "QueryContextAttributesW");
+ #else
+ pfn_queryContextAttributes = (queryContextAttributes_fn)GetProcAddress(_sspi_security_dll, "QueryContextAttributesA");
+ #endif
+
+ // Check if the we managed to map function pointer
+ if(!pfn_queryContextAttributes) {
+ printf("GetProcAddress failed.\n");
+ return -2;
+ }
+
+ // Call the function
+ return (*pfn_queryContextAttributes)(
+ phContext, ulAttribute, pBuffer
+ );
+}
+
+/**
+ * InitSecurityInterface
+ */
+PSecurityFunctionTable _ssip_InitSecurityInterface() {
+ INIT_SECURITY_INTERFACE InitSecurityInterface;
+ PSecurityFunctionTable pSecurityInterface = NULL;
+
+ // Return error if library not loaded
+ if(_sspi_security_dll == NULL) return NULL;
+
+ #ifdef _UNICODE
+ // Get the address of the InitSecurityInterface function.
+ InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress (
+ _sspi_secur32_dll,
+ TEXT("InitSecurityInterfaceW"));
+ #else
+ // Get the address of the InitSecurityInterface function.
+ InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress (
+ _sspi_secur32_dll,
+ TEXT("InitSecurityInterfaceA"));
+ #endif
+
+ if(!InitSecurityInterface) {
+ printf (TEXT("Failed in getting the function address, Error: %x"), GetLastError ());
+ return NULL;
+ }
+
+ // Use InitSecurityInterface to get the function table.
+ pSecurityInterface = (*InitSecurityInterface)();
+
+ if(!pSecurityInterface) {
+ printf (TEXT("Failed in getting the function table, Error: %x"), GetLastError ());
+ return NULL;
+ }
+
+ return pSecurityInterface;
+}
+
+/**
+ * Load security.dll dynamically
+ */
+int load_library() {
+ DWORD err;
+ // Load the library
+ _sspi_security_dll = LoadLibrary("security.dll");
+
+ // Check if the library loaded
+ if(_sspi_security_dll == NULL) {
+ err = GetLastError();
+ return err;
+ }
+
+ // Load the library
+ _sspi_secur32_dll = LoadLibrary("secur32.dll");
+
+ // Check if the library loaded
+ if(_sspi_secur32_dll == NULL) {
+ err = GetLastError();
+ return err;
+ }
+
+ return 0;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.h
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.h b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.h
new file mode 100644
index 0000000..a3008dc
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/kerberos_sspi.h
@@ -0,0 +1,106 @@
+#ifndef SSPI_C_H
+#define SSPI_C_H
+
+#define SECURITY_WIN32 1
+
+#include <windows.h>
+#include <sspi.h>
+
+/**
+ * Encrypt A Message
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_EncryptMessage(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo);
+
+typedef DWORD (WINAPI *encryptMessage_fn)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo);
+
+/**
+ * Acquire Credentials
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_AcquireCredentialsHandle(
+ LPSTR pszPrincipal, // Name of principal
+ LPSTR pszPackage, // Name of package
+ unsigned long fCredentialUse, // Flags indicating use
+ void * pvLogonId, // Pointer to logon ID
+ void * pAuthData, // Package specific data
+ SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func
+ void * pvGetKeyArgument, // Value to pass to GetKey()
+ PCredHandle phCredential, // (out) Cred Handle
+ PTimeStamp ptsExpiry // (out) Lifetime (optional)
+);
+
+typedef DWORD (WINAPI *acquireCredentialsHandle_fn)(
+ LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse,
+ void * pvLogonId, void * pAuthData, SEC_GET_KEY_FN pGetKeyFn, void * pvGetKeyArgument,
+ PCredHandle phCredential, PTimeStamp ptsExpiry
+ );
+
+/**
+ * Delete Security Context
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_DeleteSecurityContext(
+ PCtxtHandle phContext // Context to delete
+);
+
+typedef DWORD (WINAPI *deleteSecurityContext_fn)(PCtxtHandle phContext);
+
+/**
+ * Decrypt Message
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_DecryptMessage(
+ PCtxtHandle phContext,
+ PSecBufferDesc pMessage,
+ unsigned long MessageSeqNo,
+ unsigned long pfQOP
+);
+
+typedef DWORD (WINAPI *decryptMessage_fn)(
+ PCtxtHandle phContext, PSecBufferDesc pMessage, unsigned long MessageSeqNo, unsigned long pfQOP);
+
+/**
+ * Initialize Security Context
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_initializeSecurityContext(
+ PCredHandle phCredential, // Cred to base context
+ PCtxtHandle phContext, // Existing context (OPT)
+ LPSTR pszTargetName, // Name of target
+ unsigned long fContextReq, // Context Requirements
+ unsigned long Reserved1, // Reserved, MBZ
+ unsigned long TargetDataRep, // Data rep of target
+ PSecBufferDesc pInput, // Input Buffers
+ unsigned long Reserved2, // Reserved, MBZ
+ PCtxtHandle phNewContext, // (out) New Context handle
+ PSecBufferDesc pOutput, // (inout) Output Buffers
+ unsigned long * pfContextAttr, // (out) Context attrs
+ PTimeStamp ptsExpiry // (out) Life span (OPT)
+);
+
+typedef DWORD (WINAPI *initializeSecurityContext_fn)(
+ PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, unsigned long fContextReq,
+ unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2,
+ PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long * pfContextAttr, PTimeStamp ptsExpiry);
+
+/**
+ * Query Context Attributes
+ */
+SECURITY_STATUS SEC_ENTRY _sspi_QueryContextAttributes(
+ PCtxtHandle phContext, // Context to query
+ unsigned long ulAttribute, // Attribute to query
+ void * pBuffer // Buffer for attributes
+);
+
+typedef DWORD (WINAPI *queryContextAttributes_fn)(
+ PCtxtHandle phContext, unsigned long ulAttribute, void * pBuffer);
+
+/**
+ * InitSecurityInterface
+ */
+PSecurityFunctionTable _ssip_InitSecurityInterface();
+
+typedef DWORD (WINAPI *initSecurityInterface_fn) ();
+
+/**
+ * Load security.dll dynamically
+ */
+int load_library();
+
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.cc
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.cc b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.cc
new file mode 100644
index 0000000..e7a472f
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.cc
@@ -0,0 +1,7 @@
+#include "worker.h"
+
+Worker::Worker() {
+}
+
+Worker::~Worker() {
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.h
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.h b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.h
new file mode 100644
index 0000000..c2ccb6b
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/worker.h
@@ -0,0 +1,38 @@
+#ifndef WORKER_H_
+#define WORKER_H_
+
+#include <node.h>
+#include <node_object_wrap.h>
+#include <v8.h>
+#include <nan.h>
+
+using namespace node;
+using namespace v8;
+
+class Worker {
+ public:
+ Worker();
+ virtual ~Worker();
+
+ // libuv's request struct.
+ uv_work_t request;
+ // Callback
+ Nan::Callback *callback;
+ // Parameters
+ void *parameters;
+ // Results
+ void *return_value;
+ // Did we raise an error
+ bool error;
+ // The error message
+ char *error_message;
+ // Error code if not message
+ int error_code;
+ // Any return code
+ int return_code;
+ // Method we are going to fire
+ void (*execute)(Worker *worker);
+ Local<Value> (*mapper)(Worker *worker);
+};
+
+#endif // WORKER_H_
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.cc
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.cc b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.cc
new file mode 100644
index 0000000..fdf8e49
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.cc
@@ -0,0 +1,101 @@
+#include <node.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <v8.h>
+#include <node_buffer.h>
+#include <cstring>
+#include <cmath>
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+
+#include "security_buffer.h"
+
+using namespace node;
+
+Nan::Persistent<FunctionTemplate> SecurityBuffer::constructor_template;
+
+SecurityBuffer::SecurityBuffer(uint32_t security_type, size_t size) : Nan::ObjectWrap() {
+ this->size = size;
+ this->data = calloc(size, sizeof(char));
+ this->security_type = security_type;
+ // Set up the data in the sec_buffer
+ this->sec_buffer.BufferType = security_type;
+ this->sec_buffer.cbBuffer = (unsigned long)size;
+ this->sec_buffer.pvBuffer = this->data;
+}
+
+SecurityBuffer::SecurityBuffer(uint32_t security_type, size_t size, void *data) : Nan::ObjectWrap() {
+ this->size = size;
+ this->data = data;
+ this->security_type = security_type;
+ // Set up the data in the sec_buffer
+ this->sec_buffer.BufferType = security_type;
+ this->sec_buffer.cbBuffer = (unsigned long)size;
+ this->sec_buffer.pvBuffer = this->data;
+}
+
+SecurityBuffer::~SecurityBuffer() {
+ free(this->data);
+}
+
+NAN_METHOD(SecurityBuffer::New) {
+ SecurityBuffer *security_obj;
+
+ if(info.Length() != 2)
+ return Nan::ThrowError("Two parameters needed integer buffer type and [32 bit integer/Buffer] required");
+
+ if(!info[0]->IsInt32())
+ return Nan::ThrowError("Two parameters needed integer buffer type and [32 bit integer/Buffer] required");
+
+ if(!info[1]->IsInt32() && !Buffer::HasInstance(info[1]))
+ return Nan::ThrowError("Two parameters needed integer buffer type and [32 bit integer/Buffer] required");
+
+ // Unpack buffer type
+ uint32_t buffer_type = info[0]->ToUint32()->Value();
+
+ // If we have an integer
+ if(info[1]->IsInt32()) {
+ security_obj = new SecurityBuffer(buffer_type, info[1]->ToUint32()->Value());
+ } else {
+ // Get the length of the Buffer
+ size_t length = Buffer::Length(info[1]->ToObject());
+ // Allocate space for the internal void data pointer
+ void *data = calloc(length, sizeof(char));
+ // Write the data to out of V8 heap space
+ memcpy(data, Buffer::Data(info[1]->ToObject()), length);
+ // Create new SecurityBuffer
+ security_obj = new SecurityBuffer(buffer_type, length, data);
+ }
+
+ // Wrap it
+ security_obj->Wrap(info.This());
+ // Return the object
+ info.GetReturnValue().Set(info.This());
+}
+
+NAN_METHOD(SecurityBuffer::ToBuffer) {
+ // Unpack the Security Buffer object
+ SecurityBuffer *security_obj = Nan::ObjectWrap::Unwrap<SecurityBuffer>(info.This());
+ // Create a Buffer
+ Local<Object> buffer = Nan::CopyBuffer((char *)security_obj->data, (uint32_t)security_obj->size).ToLocalChecked();
+ // Return the buffer
+ info.GetReturnValue().Set(buffer);
+}
+
+void SecurityBuffer::Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target) {
+ // Define a new function template
+ Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->SetClassName(Nan::New<String>("SecurityBuffer").ToLocalChecked());
+
+ // Class methods
+ Nan::SetPrototypeMethod(t, "toBuffer", ToBuffer);
+
+ // Set persistent
+ constructor_template.Reset(t);
+
+ // Set the symbol
+ target->ForceSet(Nan::New<String>("SecurityBuffer").ToLocalChecked(), t->GetFunction());
+}
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.h
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.h b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.h
new file mode 100644
index 0000000..0c97d56
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.h
@@ -0,0 +1,48 @@
+#ifndef SECURITY_BUFFER_H
+#define SECURITY_BUFFER_H
+
+#include <node.h>
+#include <node_object_wrap.h>
+#include <v8.h>
+
+#define SECURITY_WIN32 1
+
+#include <winsock2.h>
+#include <windows.h>
+#include <sspi.h>
+#include <nan.h>
+
+using namespace v8;
+using namespace node;
+
+class SecurityBuffer : public Nan::ObjectWrap {
+ public:
+ SecurityBuffer(uint32_t security_type, size_t size);
+ SecurityBuffer(uint32_t security_type, size_t size, void *data);
+ ~SecurityBuffer();
+
+ // Internal values
+ void *data;
+ size_t size;
+ uint32_t security_type;
+ SecBuffer sec_buffer;
+
+ // Has instance check
+ static inline bool HasInstance(Local<Value> val) {
+ if (!val->IsObject()) return false;
+ Local<Object> obj = val->ToObject();
+ return Nan::New(constructor_template)->HasInstance(obj);
+ };
+
+ // Functions available from V8
+ static void Initialize(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target);
+ static NAN_METHOD(ToBuffer);
+
+ // Constructor used for creating new Long objects from C++
+ static Nan::Persistent<FunctionTemplate> constructor_template;
+
+ private:
+ static NAN_METHOD(New);
+};
+
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/753f1767/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.js
----------------------------------------------------------------------
diff --git a/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.js b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.js
new file mode 100644
index 0000000..4996163
--- /dev/null
+++ b/node_modules/couchbulkimporter/node_modules/mongodb/node_modules/mongodb-core/node_modules/kerberos/lib/win32/wrappers/security_buffer.js
@@ -0,0 +1,12 @@
+var SecurityBufferNative = require('../../../build/Release/kerberos').SecurityBuffer;
+
+// Add some attributes
+SecurityBufferNative.VERSION = 0;
+SecurityBufferNative.EMPTY = 0;
+SecurityBufferNative.DATA = 1;
+SecurityBufferNative.TOKEN = 2;
+SecurityBufferNative.PADDING = 9;
+SecurityBufferNative.STREAM = 10;
+
+// Export the modified class
+exports.SecurityBuffer = SecurityBufferNative;
\ No newline at end of file