From 6f6076659f4e35a903ffaf217db8e05175345977 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 27 Apr 2016 16:38:33 -0700 Subject: [PATCH] Load default roots.pem in Node via grpc_set_ssl_roots_override_callback --- src/node/ext/node_grpc.cc | 35 +++++++++++++++++++++++++++++++++++ src/node/index.js | 7 +++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index b988f29878b..6b6e42737b5 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -35,6 +35,8 @@ #include #include #include "grpc/grpc.h" +#include "grpc/grpc_security.h" +#include "grpc/support/alloc.h" #include "call.h" #include "call_credentials.h" @@ -51,6 +53,8 @@ using v8::Object; using v8::Uint32; using v8::String; +static char *pem_root_certs = NULL; + void InitStatusConstants(Local exports) { Nan::HandleScope scope; Local status = Nan::New(); @@ -268,9 +272,36 @@ NAN_METHOD(MetadataKeyIsBinary) { grpc_is_binary_header(key_str, static_cast(key->Length())))); } +static grpc_ssl_roots_override_result get_ssl_roots_override( + char **pem_root_certs_ptr) { + *pem_root_certs_ptr = pem_root_certs; + if (pem_root_certs == NULL) { + return GRPC_SSL_ROOTS_OVERRIDE_FAIL; + } else { + return GRPC_SSL_ROOTS_OVERRIDE_OK; + } +} + +/* This should only be called once, and only before creating any + *ServerCredentials */ +NAN_METHOD(SetDefaultRootsPem) { + if (!info[0]->IsString()) { + return Nan::ThrowTypeError( + "setDefaultRootsPem's argument must be a string"); + } + Nan::Utf8String utf8_roots(info[0]); + size_t length = static_cast(utf8_roots.length()); + if (length > 0) { + const char *data = *utf8_roots; + pem_root_certs = (char *)gpr_malloc((length + 1) * sizeof(char)); + memcpy(pem_root_certs, data, length + 1); + } +} + void init(Local exports) { Nan::HandleScope scope; grpc_init(); + grpc_set_ssl_roots_override_callback(get_ssl_roots_override); InitStatusConstants(exports); InitCallErrorConstants(exports); InitOpTypeConstants(exports); @@ -298,6 +329,10 @@ void init(Local exports) { Nan::GetFunction( Nan::New(MetadataKeyIsBinary) ).ToLocalChecked()); + Nan::Set(exports, Nan::New("setDefaultRootsPem").ToLocalChecked(), + Nan::GetFunction( + Nan::New(SetDefaultRootsPem) + ).ToLocalChecked()); } NODE_MODULE(grpc_node, init) diff --git a/src/node/index.js b/src/node/index.js index d345a5142d5..66664d94b5a 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -34,13 +34,10 @@ 'use strict'; var path = require('path'); +var fs = require('fs'); var SSL_ROOTS_PATH = path.resolve(__dirname, '..', '..', 'etc', 'roots.pem'); -if (!process.env.GRPC_DEFAULT_SSL_ROOTS_FILE_PATH) { - process.env.GRPC_DEFAULT_SSL_ROOTS_FILE_PATH = SSL_ROOTS_PATH; -} - var _ = require('lodash'); var ProtoBuf = require('protobufjs'); @@ -53,6 +50,8 @@ var Metadata = require('./src/metadata.js'); var grpc = require('./src/grpc_extension'); +grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii')); + /** * Load a gRPC object from an existing ProtoBuf.Reflect object. * @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load.