Created
July 2, 2013 00:30
-
-
Save ralphbean/5905893 to your computer and use it in GitHub Desktop.
A test script to see if we can send a message signed consistently.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// globals | |
$config = 0; | |
$queue = 0; | |
// A utility function, taken from the comments at | |
// http://php.net/manual/en/language.types.boolean.php | |
function to_bool ($_val) { | |
$_trueValues = array('yes', 'y', 'true'); | |
$_forceLowercase = true; | |
if (is_string($_val)) { | |
return (in_array( | |
($_forceLowercase?strtolower($_val):$_val), | |
$_trueValues | |
)); | |
} else { | |
return (boolean) $_val; | |
} | |
} | |
// A utility function to recursively sort an associative | |
// array by key. Kind of like ordereddict from Python. | |
// Used for encoding and signing messages. | |
function deep_ksort(&$arr) { | |
ksort($arr); | |
foreach ($arr as &$a) { | |
if (is_array($a) && !empty($a)) { | |
deep_ksort($a); | |
} | |
} | |
} | |
function initialize() { | |
global $config, $queue; | |
/* Load the config. Create a publishing socket. */ | |
// Danger! Danger! | |
$json = shell_exec("fedmsg-config"); | |
$config = json_decode($json, true); | |
/* Just make sure everything is sane with the fedmsg config */ | |
if (!array_key_exists('relay_inbound', $config)) { | |
echo("fedmsg-config has no 'relay_inbound'"); | |
return false; | |
} | |
$context = new ZMQContext(1, true); | |
$queue = $context->getSocket(ZMQ::SOCKET_PUB, "pub-a-dub-dub"); | |
$queue->setSockOpt(ZMQ::SOCKOPT_LINGER, $config['zmq_linger']); | |
if (is_array($config['relay_inbound'])) { | |
// API for fedmsg >= 0.5.2 | |
// TODO - be more robust here and if connecting to the first one fails, try | |
// the next, and the next, and etc... | |
$queue->connect($config['relay_inbound'][0]); | |
} else { | |
// API for fedmsg <= 0.5.1 | |
$queue->connect($config['relay_inbound']); | |
} | |
# Go to sleep for a brief moment.. just long enough to let our zmq socket | |
# initialize. | |
if (array_key_exists('post_init_sleep', $config)) { | |
usleep($config['post_init_sleep'] * 1000000); | |
} | |
return true; | |
} | |
# This is a reimplementation of the python code in fedmsg/crypto.py | |
# That file is authoritative. Changes there should be reflected here. | |
function sign_message($message_obj) { | |
global $config; | |
# This is required so that the string we sign is identical in python and in | |
# php. Ordereddict is used there; ksort here. | |
deep_ksort($message_obj); | |
# It would be best to pass JSON_UNESCAPE_SLASHES as an option here, but it is | |
# not available until php-5.4 | |
$message = json_encode($message_obj); | |
# In the meantime, we'll remove escaped slashes ourselves. This is | |
# necessary in order to produce the exact same encoding as python (so that our | |
# signatures match for validation). | |
$message = stripcslashes($message); | |
# Step 0) - Find our cert. | |
$fqdn = gethostname(); | |
$tokens = explode('.', $fqdn); | |
$hostname = $tokens[0]; | |
$ssldir = $config['ssldir']; | |
$certname = $config['certnames']['mediawiki.'.$hostname]; | |
# Step 1) - Load and encode the X509 cert | |
$cert_obj = openssl_x509_read(file_get_contents( | |
$ssldir.'/'.$certname.".crt" | |
)); | |
$cert = ""; | |
openssl_x509_export($cert_obj, $cert); | |
$cert = base64_encode($cert); | |
# Step 2) - Load and sign the jsonified message with the RSA private key | |
$rsa_private = openssl_get_privatekey(file_get_contents( | |
$ssldir.'/'.$certname.".key" | |
)); | |
$signature = ""; | |
openssl_sign($message, $signature, $rsa_private); | |
$signature = base64_encode($signature); | |
# Step 3) - Stuff it back in the message and return | |
$message_obj['signature'] = $signature; | |
$message_obj['certificate'] = $cert; | |
return $message_obj; | |
} | |
function emit_message($subtopic, $message) { | |
global $config, $queue; | |
# Re-implement some of the logc from fedmsg/core.py | |
# We'll have to be careful to keep this up to date. | |
$prefix = "org.fedoraproject." . $config['environment'] . ".wiki."; | |
$topic = $prefix . $subtopic; | |
$message_obj = array( | |
"topic" => $topic, | |
"msg" => $message, | |
"timestamp" => time(), | |
# TODO -> we don't have a good way to increment this counter from php yet. | |
"i" => 1, | |
); | |
if (array_key_exists('sign_messages', $config) and to_bool($config['sign_messages'])) { | |
$message_obj = sign_message($message_obj); | |
} | |
$envelope = json_encode($message_obj); | |
$queue->send($topic, ZMQ::MODE_SNDMORE); | |
$queue->send($envelope); | |
} | |
function test_message() { | |
initialize(); | |
emit_message("php.test", array("content"=>"something")); | |
} | |
echo("Hello."); | |
test_message(); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment