Salmon posts can only be made for local users. More typing!

Since we of course don't have the remote party's private keys anyway.

I made some small fixes in Magicsig class too, removing unnecessary code.
This commit is contained in:
Mikael Nordfeldth 2014-06-02 19:44:57 +02:00
parent 2cd25039af
commit 537dff7987
6 changed files with 22 additions and 57 deletions

View File

@ -143,9 +143,9 @@ class Magicsig extends Managed_DataObject
* Warning: this can be very slow on systems without the GMP module.
* Runtimes of 20-30 seconds are not unheard-of.
*
* @param int $user_id id of local user we're creating a key for
* @param User $user the local user (since we don't have remote private keys)
*/
public function generate($user_id, $bits=1024)
public function generate(User $user, $bits=1024)
{
$rsa = new Crypt_RSA();
@ -157,7 +157,7 @@ class Magicsig extends Managed_DataObject
$this->publicKey = new Crypt_RSA();
$this->publicKey->loadKey($keypair['publickey']);
$this->user_id = $user_id;
$this->user_id = $user->id;
$this->insert();
}
@ -179,25 +179,6 @@ class Magicsig extends Managed_DataObject
return 'RSA.' . $mod . '.' . $exp . $private_exp;
}
/**
* Decode a string representation of an RSA public key or keypair
* as a Magicsig object which can be used to sign or verify.
*
* @param string $text
* @return Magicsig
*/
public static function fromString($text)
{
$magic_sig = new Magicsig();
// remove whitespace
$text = preg_replace('/\s+/', '', $text);
$magic_sig->importKeys($text);
// Please note this object will be missing the user_id field
return $magic_sig;
}
/**
* importKeys will load the object's keypair string, which initiates
* loadKey() and configures Crypt_RSA objects.
@ -206,10 +187,10 @@ class Magicsig extends Managed_DataObject
*/
public function importKeys($keypair=null)
{
$keypair = $keypair ?: $this->keypair;
$this->keypair = $keypair===null ? $this->keypair : preg_replace('/\s+/', '', $keypair);
// parse components
if (!preg_match('/RSA\.([^\.]+)\.([^\.]+)(\.([^\.]+))?/', $keypair, $matches)) {
if (!preg_match('/RSA\.([^\.]+)\.([^\.]+)(\.([^\.]+))?/', $this->keypair, $matches)) {
common_debug('Magicsig error: RSA key not found in provided string.');
throw new ServerException('RSA key not found in keypair string.');
}
@ -241,7 +222,7 @@ class Magicsig extends Managed_DataObject
common_log(LOG_DEBUG, "Adding ".$type." key: (".$mod .', '. $exp .")");
$rsa = new Crypt_RSA();
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$rsa->setHash($this->getHash());
$rsa->modulus = new Math_BigInteger(Magicsig::base64_url_decode($mod), 256);
$rsa->k = strlen($rsa->modulus->toBytes());

View File

@ -289,17 +289,8 @@ class Ostatus_profile extends Managed_DataObject
* @param string $verb Activity::SUBSCRIBE or Activity::JOIN
* @param Object $object object of the action; must define asActivityNoun($tag)
*/
public function notify($actor, $verb, $object=null, $target=null)
public function notify(Profile $actor, $verb, $object=null, $target=null)
{
if (!($actor instanceof Profile)) {
$type = gettype($actor);
if ($type == 'object') {
$type = get_class($actor);
}
// TRANS: Server exception.
// TRANS: %1$s is the method name the exception occured in, %2$s is the actor type.
throw new ServerException(sprintf(_m('Invalid actor passed to %1$s: %2$s.'),__METHOD__,$type));
}
if ($object == null) {
$object = $this;
}
@ -340,8 +331,7 @@ class Ostatus_profile extends Managed_DataObject
$xml = $entry->getString();
common_log(LOG_INFO, "Posting to Salmon endpoint $this->salmonuri: $xml");
$salmon = new Salmon();
$salmon->post($this->salmonuri, $xml, $actor);
Salmon::post($this->salmonuri, $xml, $actor->getUser());
}
/**
@ -355,8 +345,7 @@ class Ostatus_profile extends Managed_DataObject
public function notifyActivity($entry, Profile $actor)
{
if ($this->salmonuri) {
$salmon = new Salmon();
return $salmon->post($this->salmonuri, $this->notifyPrepXml($entry), $actor);
return Salmon::post($this->salmonuri, $this->notifyPrepXml($entry), $actor->getUser());
}
common_debug(__CLASS__.' error: No salmonuri for Ostatus_profile uri: '.$this->uri);

View File

@ -324,25 +324,21 @@ class MagicEnvelope
* on some systems.
*
* @param string $text XML fragment to sign, assumed to be Atom
* @param Profile $actor Profile of a local user to use as signer
* @param User $user User who cryptographically signs $text
*
* @return string XML string representation of magic envelope
*
* @throws Exception on bad profile input or key generation problems
* @fixme if signing fails, this seems to return the original text without warning. Is there a reason for this?
*/
public static function signForProfile($text, Profile $actor)
public static function signAsUser($text, User $user)
{
// We only generate keys for our local users of course, so let
// getUser throw an exception if the profile is not local.
$user = $actor->getUser();
// Find already stored key
$magicsig = Magicsig::getKV('user_id', $user->id);
if (!$magicsig instanceof Magicsig) {
// No keypair yet, let's generate one.
$magicsig = new Magicsig();
$magicsig->generate($user->id);
$magicsig->generate($user);
}
$magic_env = self::signMessage($text, 'application/atom+xml', $magicsig);

View File

@ -43,18 +43,18 @@ class Salmon
*
* @param string $endpoint_uri
* @param string $xml string representation of payload
* @param Profile $actor local user profile whose keys to sign with
* @param User $user local user profile whose keys we sign with
* @return boolean success
*/
public function post($endpoint_uri, $xml, Profile $actor)
public static function post($endpoint_uri, $xml, User $user)
{
if (empty($endpoint_uri)) {
common_debug('No endpoint URI for Salmon post to '.$actor->getUri());
common_debug('No endpoint URI for Salmon post to '.$user->getUri());
return false;
}
try {
$magic_env = MagicEnvelope::signForProfile($xml, $actor);
$magic_env = MagicEnvelope::signAsUser($xml, $user);
$envxml = $magic_env->toXML();
} catch (Exception $e) {
common_log(LOG_ERR, "Salmon unable to sign: " . $e->getMessage());
@ -73,7 +73,7 @@ class Salmon
}
if ($response->getStatus() != 200) {
common_log(LOG_ERR, sprintf('Salmon (from profile %d) endpoint %s returned status %s: %s',
$actor->id, $endpoint_uri, $response->getStatus(), $response->getBody()));
$user->id, $endpoint_uri, $response->getStatus(), $response->getBody()));
return false;
}

View File

@ -41,8 +41,7 @@ class SalmonQueueHandler extends QueueHandler
$actor = Profile::getKV($data['actor']);
$salmon = new Salmon();
$salmon->post($data['salmonuri'], $data['entry'], $actor);
Salmon::post($data['salmonuri'], $data['entry'], $actor->getUser());
// @fixme detect failure and attempt to resend
return true;

View File

@ -51,7 +51,7 @@ echo "== Original entry ==\n\n";
print $entry;
print "\n\n";
$magic_env = MagicEnvelope::signForProfile($entry, $profile);
$magic_env = MagicEnvelope::signAsUser($entry, $profile->getUser());
$envxml = $magic_env->toXML();
echo "== Signed envelope ==\n\n";
@ -61,8 +61,8 @@ print "\n\n";
echo "== Testing local verification ==\n\n";
$magic_env = new MagicEnvelope($envxml);
$activity = new Activity($magic_env->getPayload()->documentElement);
$profile = Profile::fromUri($activity->actor->id);
$ok = $magic_env->verify($profile);
$actprofile = Profile::fromUri($activity->actor->id);
$ok = $magic_env->verify($actprofile);
if ($ok) {
print "OK\n\n";
} else {
@ -86,7 +86,7 @@ if (have_option('--slap')) {
echo "== Remote salmon slap ==\n\n";
print "Sending signed Salmon slap to $url ...\n";
$ok = $salmon->post($url, $entry, $profile);
$ok = Salmon::post($url, $entry, $profile->getUser());
if ($ok) {
print "OK\n\n";
} else {