Merge pull request #25303 from HannahShiSFB/psm-security

PHP: support for PSM security
pull/25396/head
Stanley Cheung 4 years ago committed by GitHub
commit ff028754cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/php/bin/run_gen_code_test.sh
  2. 47
      src/php/ext/grpc/channel_credentials.c
  3. 26
      src/php/tests/generated_code/AbstractGeneratedCodeTest.php
  4. 5
      src/php/tests/generated_code/GeneratedCodeTest.php
  5. 4
      src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
  6. 7
      src/php/tests/generated_code/math_server.js
  7. 2
      src/php/tests/unit_tests/ChannelCredentialsTest.php
  8. 256
      src/php/tests/unit_tests/ChannelTest.php

@ -17,6 +17,8 @@ set -e
cd $(dirname $0)
source ./determine_extension_dir.sh
export GRPC_TEST_HOST=localhost:50051
export GRPC_TEST_INSECURE_HOST=localhost:50052
php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \
../tests/generated_code/GeneratedCodeTest.php
php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \

@ -233,7 +233,46 @@ PHP_METHOD(ChannelCredentials, createComposite) {
* @return null
*/
PHP_METHOD(ChannelCredentials, createInsecure) {
RETURN_NULL();
grpc_channel_credentials* creds = grpc_insecure_credentials_create();
zval* creds_object = grpc_php_wrap_channel_credentials(
creds, strdup("INSECURE"), false TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
}
/**
* Create XDS channel credentials
* @param ChannelCredentials $fallback_creds The fallback credentials used
* if the channel target does not have the 'xds:///' scheme or if the xDS
* control plane does not provide information on how to fetch credentials
* dynamically.
* @return ChannelCredentials The xDS channel credentials object
*/
PHP_METHOD(ChannelCredentials, createXds) {
grpc_channel_credentials* xds_creds = NULL;
zval* fallback_creds = NULL;
if (zend_parse_parameters_ex(0, // ZEND_PARSE_PARAMS_QUIET,
ZEND_NUM_ARGS() TSRMLS_CC, "O", &fallback_creds,
grpc_ce_channel_credentials) != SUCCESS) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"createXds expects a fallback credentials",
1 TSRMLS_CC);
return;
}
wrapped_grpc_channel_credentials* wrapped_fallback_creds =
PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel_credentials,
fallback_creds);
xds_creds = grpc_xds_credentials_create(wrapped_fallback_creds->wrapped);
const char* fallback_creds_hash_str =
wrapped_fallback_creds->hashstr ? wrapped_fallback_creds->hashstr : "";
// prefix "XDS:" as the hash of the xDS channel
char* hash_str = malloc(strlen(fallback_creds_hash_str) + strlen("XDS:") + 1);
strcpy(hash_str, "XDS:");
strcat(hash_str, fallback_creds_hash_str);
zval* xds_creds_obj = grpc_php_wrap_channel_credentials(
xds_creds, hash_str, false /* has_call_creds */ TSRMLS_CC);
RETURN_DESTROY_ZVAL(xds_creds_obj);
}
ZEND_BEGIN_ARG_INFO_EX(arginfo_setDefaultRootsPem, 0, 0, 1)
@ -263,6 +302,10 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_createInsecure, 0, 0, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_createXds, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, fallback_creds, Grpc\\ChannelCredentials, 1)
ZEND_END_ARG_INFO()
static zend_function_entry channel_credentials_methods[] = {
PHP_ME(ChannelCredentials, setDefaultRootsPem, arginfo_setDefaultRootsPem,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
@ -278,6 +321,8 @@ static zend_function_entry channel_credentials_methods[] = {
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(ChannelCredentials, createInsecure, arginfo_createInsecure,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(ChannelCredentials, createXds, arginfo_createXds,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_FE_END
};

@ -134,29 +134,33 @@ abstract class AbstractGeneratedCodeTest extends \PHPUnit\Framework\TestCase
public function testCallCredentialsCallback()
{
$div_arg = new Math\DivArgs();
$div_arg->setDividend(7);
$div_arg->setDivisor(4);
$call = self::$client->Div($div_arg, array(), array(
'call_credentials_callback' => function ($context) {
return array();
},
));
$call->cancel();
list($response, $status) = $call->wait();
$this->assertSame(\Grpc\STATUS_CANCELLED, $status->code);
$this->assertSame(\Grpc\STATUS_OK, $status->code);
}
public function testCallCredentialsCallback2()
public function testInsecureChannelCallCredentialsCallback()
{
$div_arg = new Math\DivArgs();
$call = self::$client->Div($div_arg);
$call_credentials = Grpc\CallCredentials::createFromPlugin(
function ($context) {
$div_arg->setDividend(7);
$div_arg->setDivisor(4);
$client = new Math\MathClient(
getenv('GRPC_TEST_INSECURE_HOST'), [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
$call = $client->Div($div_arg, array(), array(
'call_credentials_callback' => function ($context) {
return array();
}
);
$call->setCallCredentials($call_credentials);
$call->cancel();
},
));
list($response, $status) = $call->wait();
$this->assertSame(\Grpc\STATUS_CANCELLED, $status->code);
$this->assertSame(\Grpc\STATUS_UNAUTHENTICATED, $status->code);
}
public function testInvalidMethodName()

@ -24,7 +24,10 @@ class GeneratedCodeTest extends AbstractGeneratedCodeTest
{
self::$client = new Math\MathClient(
getenv('GRPC_TEST_HOST'), [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
'credentials' => Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__).'/../data/ca.pem')),
'grpc.ssl_target_name_override' => 'foo.test.google.fr',
]);
}

@ -24,7 +24,9 @@ class GeneratedCodeWithCallbackTest extends AbstractGeneratedCodeTest
{
self::$client = new Math\MathClient(
getenv('GRPC_TEST_HOST'),
['credentials' => Grpc\ChannelCredentials::createInsecure(),
['credentials' => Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__).'/../data/ca.pem')),
'grpc.ssl_target_name_override' => 'foo.test.google.fr',
'update_metadata' => function ($a_hash,
$client = []) {
$a_copy = $a_hash;

@ -120,7 +120,12 @@ function main() {
Sum: Sum,
DivMany: DivMany,
});
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
server.bind('0.0.0.0:50052', grpc.ServerCredentials.createInsecure());
var fs = require('fs');
var key_data = fs.readFileSync(__dirname + '/../data/server1.key');
var pem_data = fs.readFileSync(__dirname + '/../data/server1.pem');
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createSsl(null, [{private_key: key_data,
cert_chain: pem_data}]));
server.start();
}

@ -43,7 +43,7 @@ class ChanellCredentialsTest extends \PHPUnit\Framework\TestCase
public function testCreateInsecure()
{
$channel_credentials = Grpc\ChannelCredentials::createInsecure();
$this->assertNull($channel_credentials);
$this->assertNotNull($channel_credentials);
}
public function testDefaultRootsPem()

@ -44,6 +44,31 @@ class ChannelTest extends \PHPUnit\Framework\TestCase
$this->assertNotNull($channel);
}
public function testCreateXdsWithSsl()
{
$xdsCreds = \Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
);
$this->assertNotNull($xdsCreds);
}
public function testCreateXdsWithInsecure() {
$xdsCreds = \Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createInsecure()
);
$this->assertNotNull($xdsCreds);
}
public function testCreateXdsWithNull() {
$this->expectException(\InvalidArgumentException::class);
$xdsCreds = \Grpc\ChannelCredentials::createXds(null);
}
public function testCreateXdsWithInvalidType() {
$this->expectException(\TypeError::class);
$xdsCreds = \Grpc\ChannelCredentials::createXds("invalid-type");
}
public function testGetConnectivityState()
{
$this->channel = new Grpc\Channel('localhost:50001',
@ -275,17 +300,90 @@ class ChannelTest extends \PHPUnit\Framework\TestCase
$this->channel2->close();
}
public function testPersistentChannelSameChannelCredentials()
{
$creds1 = Grpc\ChannelCredentials::createSsl();
$creds2 = Grpc\ChannelCredentials::createSsl();
$this->channel1 = new Grpc\Channel('localhost:50019',
["credentials" => $creds1,
"grpc_target_persist_bound" => 3,
]);
$this->channel2 = new Grpc\Channel('localhost:50019',
["credentials" => $creds2]);
public function persistentChannelSameChannelCredentialsProvider(): array
{
return [
[
Grpc\ChannelCredentials::createSsl(),
Grpc\ChannelCredentials::createSsl(),
50301,
],
[
Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem')
),
Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem')
),
50302,
],
[
Grpc\ChannelCredentials::createInSecure(),
Grpc\ChannelCredentials::createInSecure(),
50303,
],
[
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
),
50304,
],
[
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
),
50305,
],
[
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem')
)
),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem')
)
),
50306,
],
[
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createInSecure()
),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createInSecure()
),
50307,
],
];
}
/**
* @dataProvider persistentChannelSameChannelCredentialsProvider
*/
public function testPersistentChannelSameChannelCredentials(
$creds1,
$creds2,
$port
) {
$this->channel1 = new Grpc\Channel(
'localhost:' . $port,
[
"credentials" => $creds1,
"grpc_target_persist_bound" => 3,
]
);
$this->channel2 = new Grpc\Channel(
'localhost:' . $port,
["credentials" => $creds2]
);
// try to connect on channel1
$state = $this->channel1->getConnectivityState(true);
@ -300,70 +398,78 @@ class ChannelTest extends \PHPUnit\Framework\TestCase
$this->channel2->close();
}
public function testPersistentChannelDifferentChannelCredentials()
{
$creds1 = Grpc\ChannelCredentials::createSsl();
$creds2 = Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
$this->channel1 = new Grpc\Channel('localhost:50020',
["credentials" => $creds1,
"grpc_target_persist_bound" => 3,
]);
$this->channel2 = new Grpc\Channel('localhost:50020',
["credentials" => $creds2]);
// try to connect on channel1
$state = $this->channel1->getConnectivityState(true);
$this->waitUntilNotIdle($this->channel1);
$state = $this->channel1->getConnectivityState();
$this->assertConnecting($state);
$state = $this->channel2->getConnectivityState();
$this->assertEquals(GRPC\CHANNEL_IDLE, $state);
$this->channel1->close();
$this->channel2->close();
}
public function testPersistentChannelSameChannelCredentialsRootCerts()
{
$creds1 = Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
$creds2 = Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
$this->channel1 = new Grpc\Channel('localhost:50021',
["credentials" => $creds1,
"grpc_target_persist_bound" => 3,
]);
$this->channel2 = new Grpc\Channel('localhost:50021',
["credentials" => $creds2]);
// try to connect on channel1
$state = $this->channel1->getConnectivityState(true);
$this->waitUntilNotIdle($this->channel1);
$state = $this->channel1->getConnectivityState();
$this->assertConnecting($state);
$state = $this->channel2->getConnectivityState();
$this->assertConnecting($state);
$this->channel1->close();
$this->channel2->close();
}
public function testPersistentChannelDifferentSecureChannelCredentials()
{
$creds1 = Grpc\ChannelCredentials::createSsl();
$creds2 = Grpc\ChannelCredentials::createInsecure();
$this->channel1 = new Grpc\Channel('localhost:50022',
["credentials" => $creds1,
"grpc_target_persist_bound" => 3,
]);
$this->channel2 = new Grpc\Channel('localhost:50022',
["credentials" => $creds2]);
public function persistentChannelDifferentChannelCredentialsProvider(): array
{
return [
[
Grpc\ChannelCredentials::createSsl(),
Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem')
),
50351,
],
[
Grpc\ChannelCredentials::createSsl(),
Grpc\ChannelCredentials::createInsecure(),
50352,
],
[
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem')
)
),
50353,
],
[
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createInsecure()
),
50354,
],
[
\Grpc\ChannelCredentials::createInsecure(),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createInsecure()
),
50355,
],
[
\Grpc\ChannelCredentials::createSsl(),
\Grpc\ChannelCredentials::createXds(
\Grpc\ChannelCredentials::createSsl()
),
50356,
],
];
}
/**
* @dataProvider persistentChannelDifferentChannelCredentialsProvider
*/
public function testPersistentChannelDifferentChannelCredentials(
$creds1,
$creds2,
$port
) {
$this->channel1 = new Grpc\Channel(
'localhost:' . $port,
[
"credentials" => $creds1,
"grpc_target_persist_bound" => 3,
]
);
$this->channel2 = new Grpc\Channel(
'localhost:' . $port,
["credentials" => $creds2]
);
// try to connect on channel1
$state = $this->channel1->getConnectivityState(true);

Loading…
Cancel
Save