Exemple #1
0
 public function msgHandle($msgName, $msgData)
 {
     #fwrite(STDOUT, 'msgHandle: /'.$msgRaw.'/'."\n");
     $msgHandleReturnValue = '';
     if ($msgName == 'noop') {
         $this->log('debug', 'no operation');
     } elseif ($msgName == 'test') {
         $len = 0;
         $test_data = 'N/A';
         if (array_key_exists('len', $msgData)) {
             $len = (int) $msgData['len'];
         }
         if (array_key_exists('test_data', $msgData)) {
             $test_data = $msgData['test_data'];
         }
         $this->log('debug', 'test: ' . $len . ' /' . $test_data . '/');
     } elseif ($msgName == 'hello') {
         if (array_key_exists('ip', $msgData)) {
             $ip = $msgData['ip'];
             if ($ip != '127.0.0.1' && strIsIp($ip)) {
                 $this->getSettings()->data['node']['uriPub'] = 'tcp://' . $ip;
                 $this->getSettings()->setDataChanged(true);
             }
         }
         $this->log('debug', 'actions execute: CRITERION_AFTER_HELLO');
         $this->actionsExecute(ClientAction::CRITERION_AFTER_HELLO);
         $msgHandleReturnValue .= $this->sendId();
     } elseif ($msgName == 'id') {
         #print __CLASS__.'->'.__FUNCTION__.': '.$msgName.', '.(int)$this->getStatus('hasId')."\n";
         if ($this->getTable()) {
             if (!$this->getStatus('hasId')) {
                 $release = 0;
                 $id = '';
                 $port = 0;
                 $strKeyPub = '';
                 $strKeyPubSign = '';
                 $strKeyPubFingerprint = '';
                 $bridgeServer = false;
                 $bridgeClient = false;
                 $isChannelPeer = false;
                 $hashcash = '';
                 if (array_key_exists('release', $msgData)) {
                     $release = (int) $msgData['release'];
                 }
                 if (array_key_exists('id', $msgData)) {
                     $id = $msgData['id'];
                 }
                 if (array_key_exists('port', $msgData)) {
                     $port = (int) $msgData['port'];
                 }
                 if (array_key_exists('sslKeyPub', $msgData)) {
                     $strKeyPub = base64_decode($msgData['sslKeyPub']);
                 }
                 if (array_key_exists('sslKeyPubSign', $msgData)) {
                     $strKeyPubSign = base64_decode($msgData['sslKeyPubSign']);
                 }
                 if (array_key_exists('bridgeServer', $msgData)) {
                     $bridgeServer = (bool) $msgData['bridgeServer'];
                 }
                 if (array_key_exists('bridgeClient', $msgData)) {
                     $bridgeClient = (bool) $msgData['bridgeClient'];
                 }
                 if (array_key_exists('isChannel', $msgData)) {
                     // isChannelPeer
                     $isChannelPeer = (bool) $msgData['isChannel'];
                 }
                 if ($isChannelPeer) {
                     $this->setStatus('isChannelPeer', true);
                 }
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': /' . $id . '/ /' . $port . '/ bs=' . (int) $bridgeServer . '');
                 $idOk = false;
                 $node = new Node();
                 if (Uuid::isValid($id) && $id != Uuid::NIL) {
                     $node->setIdHexStr($id);
                     $node->setUri('tcp://' . $this->getUri()->getHost() . ':' . $port);
                     $node->setBridgeServer($bridgeServer);
                     $node->setBridgeClient($bridgeClient);
                     $node->setTimeLastSeen(time());
                     $node = $this->getTable()->nodeEnclose($node);
                     #$this->log('debug', 'node ok: '.(int)is_object($node).' /'.$node->getIdHexStr().'/');
                     // Check if not Local Node
                     if (!$this->getLocalNode()->isEqual($node)) {
                         if ($strKeyPub) {
                             if ($strKeyPubSign) {
                                 if (openssl_verify($strKeyPub, $strKeyPubSign, $strKeyPub, OPENSSL_ALGO_SHA1)) {
                                     if (Node::genIdHexStr($strKeyPub) == $id) {
                                         // Check if a public key already exists.
                                         if ($node->getSslKeyPub()) {
                                             #$this->logColor('debug', 'SSL public key ok [Aa]', 'green');
                                             $idOk = true;
                                             if ($node->getSslKeyPub() == $strKeyPub) {
                                                 #$this->logColor('debug', 'SSL public key ok [Ab]', 'green');
                                                 $node->setSslKeyPubStatus('C');
                                                 $node->setDataChanged(true);
                                             }
                                         } else {
                                             // No public key found.
                                             $sslPubKey = openssl_pkey_get_public($strKeyPub);
                                             if ($sslPubKey !== false) {
                                                 $sslPubKeyDetails = openssl_pkey_get_details($sslPubKey);
                                                 if ($sslPubKeyDetails['bits'] >= Node::SSL_KEY_LEN_MIN) {
                                                     #$this->logColor('debug', 'SSL public key ok [B]', 'green');
                                                     $idOk = true;
                                                     $node->setSslKeyPub($strKeyPub);
                                                     $node->setSslKeyPubStatus('C');
                                                     $node->setDataChanged(true);
                                                 } else {
                                                     $msgHandleReturnValue .= $this->sendError(2020, $msgName);
                                                     $this->log('error', static::getErrorMsg(2020));
                                                 }
                                             } else {
                                                 $msgHandleReturnValue .= $this->sendError(2040, $msgName);
                                                 $this->log('error', static::getErrorMsg(2040));
                                             }
                                         }
                                     } else {
                                         $msgHandleReturnValue .= $this->sendError(1030, $msgName);
                                         $this->log('error', static::getErrorMsg(1030));
                                     }
                                 } else {
                                     $msgHandleReturnValue .= $this->sendError(2080, $msgName);
                                     $this->log('error', static::getErrorMsg(2080));
                                     while ($openSslErrorStr = openssl_error_string()) {
                                         $this->log('error', 'SSL: ' . $openSslErrorStr);
                                     }
                                 }
                             } else {
                                 $msgHandleReturnValue .= $this->sendError(2005, $msgName);
                                 $this->log('error', static::getErrorMsg(2005));
                             }
                         } else {
                             $msgHandleReturnValue .= $this->sendError(2000, $msgName);
                             $this->log('error', static::getErrorMsg(2000));
                         }
                     } else {
                         // It's the ID from the Local Node. Something is wrong.
                         $msgHandleReturnValue .= $this->sendError(1020, $msgName);
                         $this->log('error', static::getErrorMsg(1020));
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                     $this->log('error', static::getErrorMsg(9000));
                 }
                 if ($idOk) {
                     $this->setStatus('hasId', true);
                     $this->setNode($node);
                     if ($this->getStatus('isOutbound')) {
                         $this->getNode()->incConnectionsOutboundSucceed();
                     }
                     if ($this->getStatus('isInbound')) {
                         $this->getNode()->incConnectionsInboundSucceed();
                     }
                     if (!$this->debug && $node->getBridgeServer() && $this->getStatus('bridgeTargetUri')) {
                         $this->logColor('debug', 'bridge server: ' . $this->getStatus('bridgeServerUri'), 'yellow');
                         $this->logColor('debug', 'bridge target: ' . $this->getStatus('bridgeTargetUri'), 'yellow');
                         $actions = array();
                         $action = new ClientAction(ClientAction::CRITERION_AFTER_ID_SUCCESSFULL);
                         $action->setName('bridge_server_init_ssl');
                         $action->functionSet(function ($action, $client) {
                             $this->logColor('debug', 'init ssl because of bridge server', 'green');
                             $client->sendSslInit();
                         });
                         $actions[] = $action;
                         $action = new ClientAction(ClientAction::CRITERION_AFTER_HAS_SSL);
                         $action->setName('bridge_server_send_connect');
                         $action->functionSet(function ($action, $client) {
                             $this->logColor('debug', 'bridge ssl ok', 'yellow');
                             $client->sendBridgeConnect($client->getStatus('bridgeTargetUri'));
                         });
                         $actions[] = $action;
                         $this->actionsAdd($actions);
                     }
                     $msgHandleReturnValue .= $this->sendIdOk();
                     $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ID OK');
                 } else {
                     $msgHandleReturnValue .= $this->sendQuit();
                     $this->shutdown();
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(1010, $msgName);
                 $this->log('error', static::getErrorMsg(1010));
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(9010, $msgName);
             $this->log('error', static::getErrorMsg(9010));
         }
     } elseif ($msgName == 'id_ok') {
         $this->log('debug', $this->getUri() . ' recv ' . $msgName);
         $this->log('debug', 'actions execute: CRITERION_AFTER_ID_SUCCESSFULL');
         $this->actionsExecute(ClientAction::CRITERION_AFTER_ID_SUCCESSFULL);
         if ($this->getStatus('isChannelPeer')) {
             $this->consoleMsgAdd('New incoming channel connection from ' . $this->getUri() . '.', true, true, true);
         }
         if ($this->getStatus('isChannelPeer') || $this->getStatus('isChannelLocal')) {
             if ($this->getServer() && $this->getServer()->getKernel()) {
                 $contact = $this->getServer()->getKernel()->getAddressbook()->contactGetByNodeId($this->getNode()->getIdHexStr());
                 if ($contact) {
                     $text = 'You talked to ';
                     $text .= $this->getNode()->getIdHexStr() . ' (' . $contact->getUserNickname() . ')';
                     $text .= ' once before.';
                     $this->consoleMsgAdd($text, true, false);
                 } else {
                     $this->consoleMsgAdd('You never talked to ' . $this->getNode()->getIdHexStr() . ' before.', true, false);
                     $this->consoleMsgAdd('Verify the public keys with you conversation partner on another channel.', true, false);
                     $this->consoleMsgAdd('Public keys fingerprints:', true, false);
                     $this->consoleMsgAdd('  Yours: ' . $this->getLocalNode()->getSslKeyPubFingerprint(), true, false);
                     $this->consoleMsgAdd('  Peers: ' . $this->getNode()->getSslKeyPubFingerprint(), true, false);
                 }
             }
         }
     } elseif ($msgName == 'node_find') {
         if ($this->getStatus('hasId')) {
             $rid = '';
             $num = static::NODE_FIND_NUM;
             $nodeId = '';
             $hashcash = '';
             if (array_key_exists('rid', $msgData)) {
                 $rid = $msgData['rid'];
             }
             if (array_key_exists('num', $msgData)) {
                 $num = $msgData['num'];
             }
             if (array_key_exists('nodeId', $msgData)) {
                 $nodeId = $msgData['nodeId'];
             }
             if (array_key_exists('hashcash', $msgData)) {
                 $hashcash = $msgData['hashcash'];
             }
             $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid);
             if ($rid) {
                 if ($hashcash && $this->hashcashVerify($hashcash, $this->getNode()->getIdHexStr(), static::HASHCASH_BITS_MIN)) {
                     if ($nodeId) {
                         $node = new Node();
                         $node->setIdHexStr($nodeId);
                         if ($node->isEqual($this->getLocalNode())) {
                             $this->log('debug', 'node find: find myself');
                             $msgHandleReturnValue .= $this->sendNodeFound($rid);
                         } elseif (!$node->isEqual($this->getNode()) && ($onode = $this->getTable()->nodeFind($node))) {
                             $this->log('debug', 'node find: find in table');
                             $msgHandleReturnValue .= $this->sendNodeFound($rid, array($onode));
                         } else {
                             $this->log('debug', 'node find: closest to "' . $node->getIdHexStr() . '"');
                             $nodes = $this->getTable()->nodeFindClosest($node, $num);
                             foreach ($nodes as $cnodeId => $cnode) {
                                 if ($cnode->isEqual($this->getNode())) {
                                     unset($nodes[$cnodeId]);
                                     break;
                                 }
                             }
                             $msgHandleReturnValue .= $this->sendNodeFound($rid, $nodes);
                         }
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(4000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 $this->log('error', static::getErrorMsg(9000));
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(1000, $msgName);
         }
     } elseif ($msgName == 'node_found') {
         if ($this->getStatus('hasId')) {
             $rid = '';
             $nodes = array();
             $hashcash = '';
             if (array_key_exists('rid', $msgData)) {
                 $rid = $msgData['rid'];
             }
             if (array_key_exists('nodes', $msgData)) {
                 $nodes = $msgData['nodes'];
             }
             if (array_key_exists('hashcash', $msgData)) {
                 $hashcash = $msgData['hashcash'];
             }
             if ($rid) {
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid);
                 $request = $this->requestGetByRid($rid);
                 if ($request) {
                     if ($hashcash && $this->hashcashVerify($hashcash, $this->getNode()->getIdHexStr(), static::HASHCASH_BITS_MAX)) {
                         $this->requestRemove($request);
                         $nodeId = $request['data']['nodeId'];
                         $nodesFoundIds = $request['data']['nodesFoundIds'];
                         $distanceOld = $request['data']['distance'];
                         $uri = '';
                         $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid . ' nodes: ' . count($nodes));
                         if ($nodes) {
                             // Find the smallest distance.
                             foreach ($nodes as $nodeArId => $nodeAr) {
                                 $nodeArId = '';
                                 $nodeArSslPubKey = '';
                                 $nodeArBridgeServer = false;
                                 $nodeArBridgeClient = false;
                                 $nodeArBridgeDst = array();
                                 $node = new Node();
                                 if (isset($nodeAr['id'])) {
                                     $nodeArId = $nodeAr['id'];
                                 }
                                 if (isset($nodeAr['uri'])) {
                                     $node->setUri($nodeAr['uri']);
                                 }
                                 if (isset($nodeAr['sslKeyPub']) && $nodeAr['sslKeyPub']) {
                                     $nodeArSslPubKey = base64_decode($nodeAr['sslKeyPub']);
                                 }
                                 if (isset($nodeAr['bridgeServer'])) {
                                     $nodeArBridgeServer = $nodeAr['bridgeServer'];
                                 }
                                 if (isset($nodeAr['bridgeClient'])) {
                                     $nodeArBridgeClient = $nodeAr['bridgeClient'];
                                 }
                                 if (isset($nodeAr['bridgeDst'])) {
                                     # TODO
                                     $nodeArBridgeDst = $nodeAr['bridgeDst'];
                                 }
                                 $node->setBridgeServer($nodeArBridgeServer);
                                 $node->setBridgeServer($nodeArBridgeClient);
                                 $node->setTimeLastSeen(time());
                                 $distanceNew = $this->getLocalNode()->distanceHexStr($node);
                                 $this->log('debug', 'node found: ' . $nodeArId . ', do=/' . $distanceOld . '/ dn=/' . $distanceNew . '/');
                                 if ($nodeArId) {
                                     $node->setIdHexStr($nodeArId);
                                     if ($nodeArSslPubKey) {
                                         if (Node::genIdHexStr($nodeArSslPubKey) == $nodeArId) {
                                             if ($node->setSslKeyPub($nodeArSslPubKey)) {
                                                 if (!$this->getLocalNode()->isEqual($node)) {
                                                     if (!in_array($node->getIdHexStr(), $nodesFoundIds)) {
                                                         $nodesFoundIds[] = $nodeAr['id'];
                                                         if (count($nodesFoundIds) > static::NODE_FIND_MAX_NODE_IDS) {
                                                             array_shift($nodesFoundIds);
                                                         }
                                                         if ($nodeAr['id'] == $nodeId) {
                                                             $this->log('debug', 'node found: find completed');
                                                             $uri = '';
                                                         } else {
                                                             if ($distanceOld != $distanceNew) {
                                                                 $distanceMin = Node::idMinHexStr($distanceOld, $distanceNew);
                                                                 if ($distanceMin == $distanceNew) {
                                                                     // Is smaller then $distanceOld.
                                                                     $distanceOld = $distanceNew;
                                                                     $uri = $node->getUri();
                                                                 }
                                                             }
                                                         }
                                                         $this->getTable()->nodeEnclose($node);
                                                     } else {
                                                         $this->log('debug', 'node found: already known');
                                                     }
                                                 } else {
                                                     $this->log('debug', 'node found: myself, node equal');
                                                 }
                                             } else {
                                                 $this->log('debug', 'node found: public key invalid');
                                             }
                                         } else {
                                             $this->log('debug', 'node found: ID does not match public key');
                                         }
                                     } else {
                                         $this->log('debug', 'node found: no public key set');
                                     }
                                 } else {
                                     $this->log('debug', 'node found: no node id set');
                                 }
                             }
                         }
                         $this->log('debug', 'actions execute: CRITERION_AFTER_NODE_FOUND');
                         $this->actionsExecute(ClientAction::CRITERION_AFTER_NODE_FOUND);
                         if ((string) $uri) {
                             // Further search at the nearest node.
                             $this->log('debug', 'node found: uri (' . (string) $uri . ') ok');
                             $clientActions = array();
                             $action = new ClientAction(ClientAction::CRITERION_AFTER_ID_SUCCESSFULL);
                             $action->functionSet(function ($action, $client) use($nodeId, $distanceOld, $nodesFoundIds) {
                                 $client->sendNodeFind($nodeId, $distanceOld, $nodesFoundIds);
                             });
                             $clientActions[] = $action;
                             $this->getServer()->connect($uri, $clientActions);
                         }
                     } else {
                         $msgHandleReturnValue .= $this->sendError(4000, $msgName);
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid . ' end');
             } else {
                 $msgHandleReturnValue .= $this->sendError(9000, $msgName);
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(1000, $msgName);
         }
     } elseif ($msgName == 'msg') {
         if ($this->getStatus('hasId')) {
             if ($this->getMsgDb()) {
                 $rid = '';
                 $version = 0;
                 $id = '';
                 $srcNodeId = '';
                 $srcSslKeyPub = '';
                 $dstNodeId = '';
                 $subject = '';
                 $body = '';
                 $password = '';
                 $checksum = '';
                 $relayCount = 0;
                 $timeCreated = 0;
                 $hashcash = '';
                 if (array_key_exists('rid', $msgData)) {
                     $rid = $msgData['rid'];
                 }
                 if (array_key_exists('version', $msgData)) {
                     $version = (int) $msgData['version'];
                 }
                 if (array_key_exists('id', $msgData)) {
                     $id = $msgData['id'];
                 }
                 if (array_key_exists('srcNodeId', $msgData)) {
                     $srcNodeId = $msgData['srcNodeId'];
                 }
                 if (array_key_exists('srcSslKeyPub', $msgData)) {
                     $srcSslKeyPub = base64_decode($msgData['srcSslKeyPub']);
                 }
                 if (array_key_exists('dstNodeId', $msgData)) {
                     $dstNodeId = $msgData['dstNodeId'];
                 }
                 if (array_key_exists('body', $msgData)) {
                     $body = $msgData['body'];
                 }
                 if (array_key_exists('password', $msgData)) {
                     $password = $msgData['password'];
                 }
                 if (array_key_exists('checksum', $msgData)) {
                     $checksum = $msgData['checksum'];
                 }
                 if (array_key_exists('relayCount', $msgData)) {
                     $relayCount = (int) $msgData['relayCount'];
                 }
                 if (array_key_exists('timeCreated', $msgData)) {
                     $timeCreated = (int) $msgData['timeCreated'];
                 }
                 if (array_key_exists('hashcash', $msgData)) {
                     $hashcash = $msgData['hashcash'];
                 }
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $id);
                 #fwrite(STDOUT, __CLASS__.'->'.__FUNCTION__.' body: '.$body."\n");
                 #$this->log('debug', 'msg '.$id.' body: '.$body);
                 $status = 1;
                 // New
                 if ($this->getMsgDb()->getMsgById($id)) {
                     $status = 2;
                     // Reject
                 }
                 $srcNode = new Node();
                 $srcNode->setIdHexStr($srcNodeId);
                 $srcNode = $this->getTable()->nodeEnclose($srcNode);
                 #fwrite(STDOUT, __CLASS__.'->'.__FUNCTION__.': srcNode: '.$srcNode->getIdHexStr()."\n");
                 $this->log('debug', 'msg ' . $id . ' srcNode: ' . $srcNode->getIdHexStr());
                 if ($srcNode->getSslKeyPub()) {
                     if ($srcNode->getSslKeyPub() != $srcSslKeyPub) {
                         $status = 3;
                         // Error
                     }
                 } else {
                     if (Node::genIdHexStr($srcSslKeyPub) == $srcNodeId) {
                         if ($srcNode->setSslKeyPub($srcSslKeyPub)) {
                             $srcNode->setDataChanged(true);
                         }
                     } else {
                         $status = 3;
                         // Error
                     }
                 }
                 if ($hashcash && $this->hashcashVerify($hashcash, $this->getNode()->getIdHexStr(), static::HASHCASH_BITS_MAX)) {
                     $msgHandleReturnValue .= $this->sendMsgResponse($rid, $status);
                     if ($status == 1) {
                         $msg = new Msg();
                         $msg->setVersion($version);
                         $msg->setId($id);
                         $msg->setRelayNodeId($this->getNode()->getIdHexStr());
                         $msg->setSrcNodeId($srcNodeId);
                         $msg->setSrcSslKeyPub($srcSslKeyPub);
                         $msg->setDstNodeId($dstNodeId);
                         $msg->setBody($body);
                         $msg->setPassword($password);
                         $msg->setChecksum($checksum);
                         $msg->setRelayCount($relayCount);
                         $msg->setEncryptionMode('D');
                         $msg->setStatus('U');
                         $msg->setTimeCreated($timeCreated);
                         $msg->setTimeReceived(time());
                         if ($msg->getDstNodeId() == $this->getLocalNode()->getIdHexStr()) {
                             $msg->setDstSslPubKey($this->getLocalNode()->getSslKeyPub());
                             $msg->setSsl($this->getSsl());
                             try {
                                 if ($msg->decrypt()) {
                                     #fwrite(STDOUT, 'msg '.$id.': decrypt ok'."\n");
                                     $this->log('debug', 'msg ' . $id . ' decrypt ok');
                                     if (!$msg->getIgnore()) {
                                         #fwrite(STDOUT, 'msg '.$id.': not ignore'."\n");
                                         $this->log('debug', 'msg ' . $id . ' not ignore');
                                         $this->log('debug', 'msg ' . $id . ' subject: ' . $msg->getSubject());
                                         $this->getServer()->imapMailAdd($msg);
                                         $this->getServer()->consoleMsgAdd('You got mail.', true, true, true);
                                     } else {
                                         #fwrite(STDOUT, 'msg '.$id.': ignore'."\n");
                                         $this->log('debug', 'msg ' . $id . ' ignore');
                                     }
                                 } else {
                                     #fwrite(STDOUT, 'msg '.$id.': decrypt failed B'."\n");
                                     $this->log('debug', 'msg ' . $id . ' decrypt failed B');
                                 }
                             } catch (Exception $e) {
                                 #fwrite(STDOUT, 'msg '.$id.': decrypt failed A: '.$e->getMessage()."\n");
                                 $this->log('debug', 'msg ' . $id . ' decrypt failed A: ' . $e->getMessage());
                             }
                         } else {
                             #fwrite(STDOUT, 'msg '.$id.': msg not for me'."\n");
                             $this->log('debug', 'msg ' . $id . ' not for me');
                         }
                         $this->getMsgDb()->msgAdd($msg);
                         // Add all messages.
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(4000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(3090, $msgName);
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(1000, $msgName);
         }
     } elseif ($msgName == 'msg_response') {
         if ($this->getStatus('hasId')) {
             $rid = '';
             $status = 0;
             if (array_key_exists('rid', $msgData)) {
                 $rid = $msgData['rid'];
             }
             if (array_key_exists('status', $msgData)) {
                 $status = (int) $msgData['status'];
             }
             $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid . ', ' . $status);
             $request = $this->requestGetByRid($rid);
             if ($request) {
                 #ve($request);
                 $msg = $request['data']['msg'];
                 $msg->addSentNode($this->getNode()->getIdHexStr());
                 $msg->setStatus('S');
                 if ($this->getNode()->getIdHexStr() == $msg->getDstNodeId()) {
                     $msg->setStatus('D');
                 }
                 $this->log('debug', 'actions execute: CRITERION_AFTER_MSG_RESPONSE_SUCCESSFULL');
                 $this->actionsExecute(ClientAction::CRITERION_AFTER_MSG_RESPONSE_SUCCESSFULL);
             } else {
                 $msgHandleReturnValue .= $this->sendError(9000, $msgName);
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(1000, $msgName);
         }
         $this->log('debug', 'actions execute: CRITERION_AFTER_MSG_RESPONSE');
         $this->actionsExecute(ClientAction::CRITERION_AFTER_MSG_RESPONSE);
     } elseif ($msgName == 'ssl_init') {
         #ve($this);
         if ($this->getSsl()) {
             if ($this->getStatus('hasId')) {
                 if (!$this->getStatus('hasSslInit')) {
                     $rid = '';
                     $hashcash = '';
                     if (array_key_exists('rid', $msgData)) {
                         $rid = $msgData['rid'];
                     }
                     if (array_key_exists('hashcash', $msgData)) {
                         $hashcash = $msgData['hashcash'];
                     }
                     $this->logColor('debug', 'SSL: init A: ' . $rid, 'green');
                     if ($hashcash && $this->hashcashVerify($hashcash, $this->getNode()->getIdHexStr(), static::HASHCASH_BITS_MIN)) {
                         $this->logColor('debug', 'SSL: init B', 'green');
                         $this->setStatus('hasSslInit', true);
                         $msgHandleReturnValue .= $this->sendSslInit();
                         $msgHandleReturnValue .= $this->sendSslInitResponse($rid, 1);
                         #fwrite(STDOUT, 'ssl init: /'.$msgHandleReturnValue.'/'."\n");
                         #ve($msgHandleReturnValue);
                     } else {
                         $this->resetStatusSsl();
                         #$msgHandleReturnValue .= $this->sendError(4000, $msgName);
                         $msgHandleReturnValue .= $this->sendSslInitResponse($rid, 4000);
                     }
                 }
             } else {
                 $this->resetStatusSsl();
                 #$msgHandleReturnValue .= $this->sendError(1000, $msgName);
                 $msgHandleReturnValue .= $this->sendSslInitResponse(null, 1000);
             }
         } else {
             $this->resetStatusSsl();
             #$msgHandleReturnValue .= $this->sendError(3090, $msgName);
             $msgHandleReturnValue .= $this->sendSslInitResponse(null, 3090);
         }
     } elseif ($msgName == 'ssl_init_response') {
         $rid = '';
         $status = 0;
         if (array_key_exists('rid', $msgData)) {
             $rid = $msgData['rid'];
         }
         if (array_key_exists('status', $msgData)) {
             $status = $msgData['status'];
         }
         $this->logColor('debug', 'SSL: init response: ' . $rid . ' ' . $status, 'green');
         if ($status) {
             if ($status == 1) {
                 // Ok
                 if ($this->getStatus('hasSslInit') && !$this->getStatus('hasSslInitOk')) {
                     $this->logColor('debug', 'SSL: init ok', 'green');
                     $this->setStatus('hasSslInitOk', true);
                     $msgHandleReturnValue .= $this->sendSslTest();
                 } else {
                     $this->logColor('warning', $msgName . ' SSL: you already initialized ssl', 'green');
                     $msgHandleReturnValue .= $this->sendError(2050, $msgName);
                 }
             } else {
                 $this->logColor('warning', $msgName . ' SSL: failed. status = ' . $status, 'green');
                 $this->resetStatusSsl();
                 $msgHandleReturnValue .= $this->sendError(3100, $msgName);
             }
         } else {
             $this->logColor('warning', $msgName . ' SSL: failed, invalid data', 'green');
             $this->resetStatusSsl();
             $msgHandleReturnValue .= $this->sendError(3100, $msgName);
         }
     } elseif ($msgName == 'ssl_test') {
         if ($this->getStatus('hasSslInitOk') && !$this->getStatus('hasSslTest')) {
             $msgData = $this->sslMsgDataPrivateDecrypt($msgData);
             if ($msgData) {
                 $token = '';
                 if (array_key_exists('token', $msgData)) {
                     $token = $msgData['token'];
                 }
                 if ($token) {
                     $this->logColor('debug', 'SSL: test', 'green');
                     $this->setStatus('hasSslTest', true);
                     $msgHandleReturnValue .= $this->sendSslVerify($token);
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                 $this->logColor('warning', $msgName . ' SSL: decryption failed', 'green');
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $logTmp = 'you need to initialize ssl /' . (int) $this->getStatus('hasSslInitOk') . '/';
             $logTmp .= ' /' . (int) $this->getStatus('hasSslTest') . '/';
             $this->logColor('warning', $msgName . ' SSL: ' . $logTmp, 'green');
         }
     } elseif ($msgName == 'ssl_verify') {
         if ($this->getStatus('hasSslTest') && !$this->getStatus('hasSslVerify')) {
             $msgData = $this->sslMsgDataPrivateDecrypt($msgData);
             if ($msgData) {
                 $token = '';
                 if (array_key_exists('token', $msgData)) {
                     $token = $msgData['token'];
                 }
                 if ($token && $this->sslTestToken && $token == $this->sslTestToken) {
                     $this->logColor('debug', 'SSL: verified', 'green');
                     #print __CLASS__.'->'.__FUNCTION__.': '.$msgName.' SSL: verified'."\n";
                     $this->setStatus('hasSslVerify', true);
                     $msgHandleReturnValue .= $this->sendSslPasswordPut();
                 } else {
                     $msgHandleReturnValue .= $this->sendError(2080, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                 $this->logColor('warning', $msgName . ' SSL: decryption failed', 'green');
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $this->logColor('warning', $msgName . ' SSL: you need to initialize ssl', 'green');
         }
     } elseif ($msgName == 'ssl_password_put') {
         if ($this->getStatus('hasSslVerify') && !$this->getStatus('hasSslPasswortPut')) {
             $msgData = $this->sslMsgDataPrivateDecrypt($msgData);
             if ($msgData) {
                 $password = '';
                 if (array_key_exists('password', $msgData)) {
                     $password = $msgData['password'];
                 }
                 if ($password) {
                     $this->logColor('debug', 'SSL: password put', 'green');
                     $this->setStatus('hasSslPasswortPut', true);
                     $this->sslPasswordPeerCurrent = $password;
                     #$this->logColor('debug', 'SSL: peer password: '******'green');
                     $msgHandleReturnValue .= $this->sendSslPasswordTest();
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                 $this->logColor('warning', $msgName . ' SSL: decryption failed', 'green');
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $this->logColor('warning', $msgName . ' SSL: you need to initialize ssl', 'green');
         }
     } elseif ($msgName == 'ssl_password_test') {
         if ($this->getStatus('hasSslPasswortPut') && !$this->getStatus('hasSslPasswortTest')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
             if ($msgData) {
                 $token = '';
                 if (array_key_exists('token', $msgData)) {
                     $token = $msgData['token'];
                 }
                 if ($token) {
                     $this->setStatus('hasSslPasswortTest', true);
                     $msgHandleReturnValue .= $this->sendSslPasswordVerify($token);
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                 $this->logColor('warning', $msgName . ' SSL: decryption failed', 'green');
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $this->logColor('warning', $msgName . ' SSL: you need to initialize ssl', 'green');
         }
     } elseif ($msgName == 'ssl_password_verify') {
         if ($this->getStatus('hasSslPasswortTest')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
             if ($msgData) {
                 $token = '';
                 if (array_key_exists('token', $msgData)) {
                     $token = $msgData['token'];
                 }
                 #print __CLASS__.'->'.__FUNCTION__.': '.$msgName.' SSL: password token: '.$token."\n";
                 if ($token) {
                     $testToken = hash('sha512', $this->sslPasswordToken . '_' . $this->getNode()->getIdHexStr());
                     if ($this->sslPasswordToken && $token == $testToken) {
                         $this->logColor('debug', 'SSL: password verified', 'green');
                         $this->logColor('debug', 'SSL: OK', 'green');
                         $this->setStatus('hasSsl', true);
                         $this->log('debug', 'actions execute: CRITERION_AFTER_HAS_SSL');
                         $this->actionsExecute(ClientAction::CRITERION_AFTER_HAS_SSL);
                     } else {
                         $msgHandleReturnValue .= $this->sendError(2090, $msgName);
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                 $this->logColor('warning', $msgName . ' SSL: decryption failed', 'green');
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $this->logColor('warning', $msgName . ' SSL: you need to initialize ssl', 'green');
         }
         $this->sslTestToken = '';
         $this->sslPasswordToken = '';
     } elseif ($msgName == 'ssl_password_reput') {
         if ($this->getStatus('hasSsl')) {
             if (!$this->getStatus('hasReSslPasswortPut')) {
                 $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
                 if ($msgData) {
                     $password = '';
                     if (array_key_exists('password', $msgData)) {
                         $password = $msgData['password'];
                     }
                     if ($password) {
                         $this->logColor('debug', 're-SSL: password reput 1A', 'green');
                         $this->setStatus('hasReSslPasswortPut', true);
                         $this->sslPasswordPeerNew = $password;
                         #$this->logColor('debug', 'SSL: peer password: '******'green');
                         #$this->logColor('debug', 'SSL: peer password new: '.substr($this->sslPasswordPeerNew, 0, 20), 'green');
                         if (!$this->getStatus('hasSendReSslPasswortPut')) {
                             $this->sslMsgCount = 0;
                             $this->sslPasswordToken = '';
                             $this->sslPasswordLocalNew = '';
                             #$this->sslPasswordPeerNew = '';
                             #$this->setStatus('hasSendReSslPasswortPut', true);
                             #$this->setStatus('hasReSslPasswortTest', false);
                             $this->logColor('debug', 're-SSL: password reput 1B', 'green');
                             $msgHandleReturnValue .= $this->sendSslPasswordReput();
                         }
                         $this->logColor('debug', 're-SSL: password reput 2', 'green');
                         $msgHandleReturnValue .= $this->sendSslPasswordRetest();
                     } else {
                         $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                     $this->logColor('warning', $msgName . ' re-SSL: decryption failed', 'green');
                 }
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $logMsg = $msgName . ' re-SSL: you need to initialize ssl, ';
             $logMsg .= 'hasSsl=/' . (int) $this->getStatus('hasSsl') . '/ ';
             $logMsg .= 'hasReSslPasswortPut=/' . (int) $this->getStatus('hasReSslPasswortPut') . '/';
             $this->logColor('warning', $logMsg, 'green');
         }
     } elseif ($msgName == 'ssl_password_retest') {
         if ($this->getStatus('hasReSslPasswortPut') && !$this->getStatus('hasReSslPasswortTest')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData, $this->sslPasswordLocalNew, $this->sslPasswordPeerNew);
             if ($msgData) {
                 $token = '';
                 if (array_key_exists('token', $msgData)) {
                     $token = $msgData['token'];
                 }
                 if ($token) {
                     $this->logColor('debug', 're-SSL: password retest', 'green');
                     $this->setStatus('hasReSslPasswortTest', true);
                     $msgHandleReturnValue .= $this->sendSslPasswordReverify($token);
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                 $this->logColor('warning', $msgName . ' re-SSL: decryption failed', 'green');
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $logMsg = $msgName . ' re-SSL: you need to initialize ssl, ';
             $logMsg .= 'hasReSslPasswortPut=/' . (int) $this->getStatus('hasReSslPasswortPut') . '/ ';
             $logMsg .= 'hasReSslPasswortTest=/' . (int) $this->getStatus('hasReSslPasswortTest') . '/';
             $this->logColor('warning', $logMsg, 'green');
         }
     } elseif ($msgName == 'ssl_password_reverify') {
         if ($this->getStatus('hasReSslPasswortTest')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData, $this->sslPasswordLocalNew, $this->sslPasswordPeerNew);
             if ($msgData) {
                 $token = '';
                 if (array_key_exists('token', $msgData)) {
                     $token = $msgData['token'];
                 }
                 #print __CLASS__.'->'.__FUNCTION__.': '.$msgName.' re-SSL: password token: '.$token."\n";
                 if ($token) {
                     $testToken = hash('sha512', $this->sslPasswordToken . '_' . $this->getNode()->getSslKeyPubFingerprint());
                     if ($this->sslPasswordToken && $token == $testToken) {
                         $this->logColor('debug', 're-SSL: password verified', 'green');
                         $this->logColor('debug', 're-SSL: OK', 'green');
                         $this->setStatus('hasSendReSslPasswortPut', false);
                         $this->setStatus('hasReSslPasswortPut', false);
                         $this->setStatus('hasReSslPasswortTest', false);
                         $this->sslPasswordLocalCurrent = $this->sslPasswordLocalNew;
                         $this->sslPasswordPeerCurrent = $this->sslPasswordPeerNew;
                         $this->logColor('debug', 'actions execute: CRITERION_AFTER_HAS_RESSL', 'green');
                         $this->actionsExecute(ClientAction::CRITERION_AFTER_HAS_RESSL);
                     } else {
                         $msgHandleReturnValue .= $this->sendError(2090, $msgName);
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2070, $msgName);
                 $this->logColor('warning', $msgName . ' re-SSL: decryption failed', 'green');
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $logMsg = $msgName . ' re-SSL: you need to initialize ssl, ';
             $logMsg .= 'hasReSslPasswortTest=/' . (int) $this->getStatus('hasReSslPasswortTest') . '/';
             $this->logColor('warning', $logMsg, 'green');
         }
         $this->sslPasswordToken = '';
         $this->sslPasswordLocalNew = '';
         $this->sslPasswordLocalNew = '';
     } elseif ($msgName == 'talk_request') {
         if ($this->getStatus('hasSsl')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
             if ($msgData) {
                 $rid = '';
                 $userNickname = '[unknown]';
                 $hashcash = '';
                 if (array_key_exists('rid', $msgData)) {
                     $rid = $msgData['rid'];
                 }
                 if (array_key_exists('userNickname', $msgData) && $msgData['userNickname']) {
                     $userNickname = $msgData['userNickname'];
                 }
                 if (array_key_exists('hashcash', $msgData)) {
                     $hashcash = $msgData['hashcash'];
                 }
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid . ', ' . $userNickname);
                 if ($rid) {
                     if ($hashcash && $this->hashcashVerify($hashcash, $this->getNode()->getIdHexStr(), static::HASHCASH_BITS_MAX)) {
                         if ($this->getServer() && $this->getServer()->kernelHasConsole()) {
                             $this->setStatus('hasTalkRequest', true);
                             $this->consoleTalkRequestAdd($rid, $userNickname);
                         } else {
                             $msgHandleReturnValue .= $this->sendTalkResponse($rid, 4);
                             #$msgHandleReturnValue .= $this->sendQuit();
                             #$this->shutdown();
                             $action = new ClientAction(ClientAction::CRITERION_AFTER_PREVIOUS_ACTIONS);
                             $action->setName('talk_request_after_previous_actions_shutdown');
                             $action->functionSet(function ($action, $client) {
                                 $client->shutdown();
                             });
                             $this->actionAdd($action);
                         }
                     } else {
                         $msgHandleReturnValue .= $this->sendError(4000, $msgName);
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(9000, $msgName);
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(2060, $msgName);
             $this->logColor('warning', $msgName . ' SSL: you need to initialize ssl', 'green');
         }
     } elseif ($msgName == 'talk_response') {
         if ($this->getStatus('hasSsl')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
             if ($msgData) {
                 $rid = '';
                 $status = 0;
                 $userNickname = '[unknown]';
                 if (array_key_exists('rid', $msgData)) {
                     $rid = $msgData['rid'];
                 }
                 if (array_key_exists('status', $msgData)) {
                     $status = (int) $msgData['status'];
                 }
                 if (array_key_exists('userNickname', $msgData) && $msgData['userNickname']) {
                     $userNickname = $msgData['userNickname'];
                 }
                 #$this->log('debug', $this->getUri().' recv '.$msgName.': '.$rid.', '.(int)$status.', '.$userNickname);
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid . ', ' . (int) $status);
                 $request = $this->requestGetByRid($rid);
                 if ($request) {
                     $this->requestRemove($request);
                     $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': request ok (' . $status . ')');
                     //if($status == 0){} // Undefined
                     if ($status == 1) {
                         // Accepted
                         $this->setStatus('hasTalk', true);
                         $this->consoleMsgAdd('Talk request accepted.', true, false, true);
                         $this->consoleMsgAdd('Now talking to "' . $userNickname . '".', true, true);
                         $this->consoleSetModeChannel(true);
                         $this->consoleSetModeChannelClient($this);
                         if ($this->getServer() && $this->getServer()->getKernel()) {
                             // Add to addressbook.
                             $contact = new Contact();
                             $contact->setNodeId($this->getNode()->getIdHexStr());
                             $contact->setUserNickname($userNickname);
                             $this->getServer()->getKernel()->getAddressbook()->contactAdd($contact);
                         }
                     } elseif ($status == 2) {
                         // Declined
                         $this->consoleMsgAdd('Talk request declined.', true, true, true);
                     } elseif ($status == 3) {
                         // Timeout
                         $this->consoleMsgAdd('Talk request timed out.', true, true, true);
                     } elseif ($status == 4) {
                         // No console, standalone server.
                         $this->consoleMsgAdd($this->getUri() . ' has no user interface. Can\'t talk to you.', true, true, true);
                         #$msgHandleReturnValue .= $this->sendQuit();
                         #$this->shutdown();
                         $action = new ClientAction(ClientAction::CRITERION_AFTER_PREVIOUS_ACTIONS);
                         $action->setName('talk_request_after_previous_actions_shutdown');
                         $action->functionSet(function ($action, $client) {
                             $client->sendQuit();
                             $client->shutdown();
                         });
                         $this->actionAdd($action);
                         $this->log('debug', 'actions left: ' . count($this->actions));
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             }
         }
     } elseif ($msgName == 'talk_msg') {
         #$this->log('debug', $this->getUri().' recv '.$msgName);
         if ($this->getStatus('hasSsl')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
             if ($msgData) {
                 $rid = '';
                 $userNickname = '[unknown]';
                 $text = '';
                 $ignore = false;
                 if (array_key_exists('rid', $msgData)) {
                     $rid = $msgData['rid'];
                 }
                 if (array_key_exists('userNickname', $msgData) && $msgData['userNickname']) {
                     $userNickname = $msgData['userNickname'];
                 }
                 if (array_key_exists('text', $msgData)) {
                     $text = $msgData['text'];
                 }
                 if (array_key_exists('ignore', $msgData)) {
                     $ignore = $msgData['ignore'];
                 }
                 #$debugText = '/'.$rid.'/ /'.$userNickname.'/ '.(int)$ignore.' /'.$text.'/';
                 #$this->log('debug', $this->getUri().' recv '.$msgName.': '.$debugText);
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName);
                 if (!$ignore) {
                     $this->consoleTalkMsgAdd($rid, $userNickname, $text);
                 }
             }
         }
     } elseif ($msgName == 'talk_user_nickname_change') {
         #$this->log('debug', $this->getUri().' recv '.$msgName);
         if ($this->getStatus('hasSsl')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
             if ($msgData) {
                 $userNicknameOld = '[unknown]';
                 $userNicknameNew = '';
                 if (array_key_exists('userNicknameOld', $msgData) && $msgData['userNicknameOld']) {
                     $userNicknameOld = $msgData['userNicknameOld'];
                 }
                 if (array_key_exists('userNicknameNew', $msgData)) {
                     $userNicknameNew = $msgData['userNicknameNew'];
                 }
                 if ($this->getServer() && $this->getServer()->getKernel()) {
                     $contact = $this->getServer()->getKernel()->getAddressbook()->contactGetByNodeId($this->getNode()->getIdHexStr());
                     if ($contact) {
                         if (!$userNicknameOld) {
                             $userNicknameOld = $contact->getUserNickname();
                         }
                         if ($userNicknameNew) {
                             $contact->setUserNickname($userNicknameNew);
                             $this->getServer()->getKernel()->getAddressbook()->setDataChanged(true);
                         }
                     }
                 }
                 if ($userNicknameNew) {
                     #$this->log('debug', $this->getUri().' recv '.$msgName.': '.$userNicknameOld.', '.$userNicknameNew);
                     $this->consoleMsgAdd('User "' . $userNicknameOld . '" is now known as "' . $userNicknameNew . '".', true, true, true);
                 }
             }
         }
     } elseif ($msgName == 'talk_close') {
         if ($this->getStatus('hasSsl')) {
             $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
             if ($msgData) {
                 $rid = '';
                 $userNickname = '[unknown]';
                 if (array_key_exists('rid', $msgData)) {
                     $rid = $msgData['rid'];
                 }
                 if (array_key_exists('userNickname', $msgData) && $msgData['userNickname']) {
                     $userNickname = $msgData['userNickname'];
                 }
                 $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $rid . ', ' . $userNickname);
                 $msgHandleReturnValue .= $this->sendQuit();
                 $this->setStatus('hasTalkClose', true);
                 $this->shutdown();
                 $this->consoleMsgAdd('Talk closed by "' . $userNickname . '".', true, true, true);
                 $this->consoleSetModeChannel(false);
                 $this->consoleSetModeChannelClient(null);
             }
         }
     } elseif ($msgName == 'bridge_connect') {
         if ($this->getSettings()->data['node']['bridge']['server']['enabled']) {
             if ($this->getStatus('hasSsl')) {
                 $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
                 if ($msgData) {
                     $targetUri = '';
                     if (array_key_exists('uri', $msgData)) {
                         $targetUri = $msgData['uri'];
                         $targetUri = UriFactory::factory($targetUri);
                     }
                     $this->logColor('debug', $this->getUri() . ' recv ' . $msgName . ': target /' . $targetUri . '/', 'yellow');
                     $client = $this->getServer()->connect($targetUri);
                     if ($client !== null) {
                         $this->logColor('debug', 'bridge connected to target /' . $targetUri . '/', 'yellow');
                         $this->setBridgeClient($client);
                         $client->setBridgeClient($client);
                         $client->setStatus('bridgeTargetUri', $targetUri);
                         $msgHandleReturnValue .= $this->sendBridgeConnectResponse(1);
                     } else {
                         $this->logColor('debug', 'bridge connection to target /' . $targetUri . '/ failed', 'yellow');
                         $msgHandleReturnValue .= $this->sendBridgeConnectResponse(2);
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2060, $msgName);
                 $this->log('warning', static::getErrorMsg(2060));
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(5000, $msgName);
             $this->log('warning', static::getErrorMsg(5000));
         }
     } elseif ($msgName == 'bridge_connect_response') {
         if ($this->getSettings()->data['node']['bridge']['server']['enabled'] || $this->getSettings()->data['node']['bridge']['client']['enabled']) {
             if ($this->getStatus('hasSsl')) {
                 $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
                 if ($msgData) {
                     $status = 0;
                     if (array_key_exists('status', $msgData)) {
                         $status = (int) $msgData['status'];
                     }
                     $this->logColor('debug', $this->getUri() . ' recv ' . $msgName . ': /' . $status . '/', 'yellow');
                     if ($status) {
                         if ($status == 1) {
                             $this->logColor('debug', 'bridge connection ok', 'yellow');
                             $this->bridgeActionsExecute(ClientAction::CRITERION_AFTER_HELLO);
                             $this->bridgeActionsExecute(ClientAction::CRITERION_AFTER_HAS_SSL);
                             /*foreach($this->bridgeActions as $bridgeActionId => $bridgeAction){
                             			$name = $bridgeAction->getName();
                             			$criteria = join(',', $bridgeAction->getCriteria());
                             			$this->logColor('debug', 'bridgeAction: /'.$name.'/ /'.$criteria.'/', 'yellow');
                             			#$this->bridgeActionRemove($bridgeAction);
                             			#$bridgeAction->functionExec($this);
                             		}*/
                         } elseif ($status == 2) {
                             $this->logColor('debug', 'bridge connection failed', 'yellow');
                         } else {
                             $this->logColor('debug', 'bridge connect response unknown status', 'yellow');
                         }
                     } else {
                         $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2060, $msgName);
                 $this->log('warning', static::getErrorMsg(2060));
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(5100, $msgName);
             $this->log('warning', static::getErrorMsg(5100));
         }
     } elseif ($msgName == 'bridge_msg') {
         if ($this->getSettings()->data['node']['bridge']['server']['enabled']) {
             if ($this->getStatus('hasSsl')) {
                 $msgData = $this->sslMsgDataPasswordDecrypt($msgData);
                 if ($msgData) {
                     $data = '';
                     if (array_key_exists('data', $msgData)) {
                         $data = $msgData['data'];
                     }
                     $this->logColor('debug', $this->getUri() . ' recv ' . $msgName . ': /' . $data . '/', 'yellow');
                     $this->logColor('debug', 'bridge server: ' . $this->getStatus('bridgeServerUri'), 'yellow');
                     $this->logColor('debug', 'bridge target: ' . $this->getStatus('bridgeTargetUri'), 'yellow');
                     $this->logColor('debug', 'bridge client: ' . (int) ($this->bridgeClient !== null), 'yellow');
                     # TODO
                     if ($this->bridgeClient) {
                     }
                 } else {
                     $msgHandleReturnValue .= $this->sendError(9000, $msgName);
                 }
             } else {
                 $msgHandleReturnValue .= $this->sendError(2060, $msgName);
                 $this->log('warning', static::getErrorMsg(2060));
             }
         } else {
             $msgHandleReturnValue .= $this->sendError(5200, $msgName);
             $this->log('warning', static::getErrorMsg(5200));
         }
     } elseif ($msgName == 'ping') {
         $rid = '';
         if (array_key_exists('rid', $msgData)) {
             $rid = $msgData['rid'];
         }
         $msgHandleReturnValue .= $this->sendPong($rid);
     } elseif ($msgName == 'pong') {
         $rid = '';
         if (array_key_exists('rid', $msgData)) {
             $rid = $msgData['rid'];
         }
         $this->pongTime = time();
     } elseif ($msgName == 'error') {
         $code = 0;
         $msg = '';
         $name = '';
         if (array_key_exists('msg', $msgData)) {
             $code = (int) $msgData['code'];
         }
         if (array_key_exists('msg', $msgData)) {
             $msg = $msgData['msg'];
         }
         if (array_key_exists('msg', $msgData)) {
             $name = $msgData['name'];
         }
         if ($code >= 2000 && $code <= 3999) {
             // SSL
             $this->logColor('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $code . ', ' . $msg . ', ' . $name, 'green');
         } elseif ($code >= 5000 && $code <= 5999) {
             // Bridge
             $this->logColor('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $code . ', ' . $msg . ', ' . $name, 'yellow');
         } else {
             $this->log('debug', $this->getUri() . ' recv ' . $msgName . ': ' . $code . ', ' . $msg . ', ' . $name);
         }
     } elseif ($msgName == 'quit') {
         $this->shutdown();
     } else {
         $this->log('debug', $this->getUri() . ' recv /' . $msgName . '/: not implemented.');
         $msgHandleReturnValue .= $this->sendError(9020, $msgName);
     }
     return $msgHandleReturnValue;
 }
Exemple #2
0
 /**
  * @expectedException RuntimeException
  * @expectedExceptionCode 203
  */
 public function testDecryptionRuntimeException203()
 {
     $msg = new Msg();
     $msg->setVersion(1);
     $msg->setId('cafed00d-2131-4159-8e11-0b4dbadb1738');
     $msg->setSrcNodeId('cafed00d-2331-4159-8e11-0b4dbadb1738');
     $msg->setSrcSslKeyPub(static::SRC1_SSL_KEY_PUB);
     $msg->setSrcUserNickname('username1');
     $msg->setDstNodeId('cafed00d-2431-4159-8e11-0b4dbadb1738');
     $msg->setDstSslPubKey(static::DST1_SSL_KEY_PUB);
     $msg->setSubject('subj1');
     $msg->setText('text1');
     $msg->setSslKeyPrv(static::SRC1_SSL_KEY_PRV, static::SSL_KEY_PRV_PASS);
     $msg->setIgnore(false);
     $this->assertTrue($msg->encrypt());
     $body = $msg->getBody();
     $timeCreated = $msg->getTimeCreated();
     $password = $msg->getPassword();
     $checksum = $msg->getChecksum();
     $body = base64_decode($body);
     $body = gzdecode($body);
     $body = json_decode($body, true);
     $body['data'] = 'invalid';
     $body = json_encode($body);
     $body = gzencode($body, 9);
     $body = base64_encode($body);
     $msg = new Msg();
     $msg->setVersion(1);
     $msg->setId('cafed00d-2131-4159-8e11-0b4dbadb1738');
     $msg->setSrcNodeId('cafed00d-2331-4159-8e11-0b4dbadb1738');
     $msg->setBody($body);
     $msg->setSrcSslKeyPub(static::SRC1_SSL_KEY_PUB);
     $msg->setDstSslPubKey(static::DST1_SSL_KEY_PUB);
     $msg->setSslKeyPrv(static::DST1_SSL_KEY_PRV, static::SSL_KEY_PRV_PASS);
     $msg->setDstNodeId('cafed00d-2431-4159-8e11-0b4dbadb1738');
     $msg->setTimeCreated($timeCreated);
     $msg->setPassword($password);
     $msg->setChecksum($checksum);
     $msg->decrypt();
 }
Exemple #3
0
 public function testMsgDbDefault()
 {
     $uuid1 = '10000000-1000-4001-8001-1000000000';
     $uuid2 = '20000000-2000-4002-8002-20000000';
     @unlink('test_data/bucket_root.yml');
     $runName = uniqid('', true);
     $prvFileName = 'testfile_cronjob_id_rsa_' . date('Ymd_His') . '_' . $runName . '.prv';
     $pubFileName = 'testfile_cronjob_id_rsa_' . date('Ymd_His') . '_' . $runName . '.pub';
     $settignsFileName = 'testfile_cronjob_settings_' . date('Ymd_His') . '_' . $runName . '.pub';
     file_put_contents('test_data/' . $prvFileName, static::NODE_LOCAL_SSL_KEY_PRV);
     file_put_contents('test_data/' . $pubFileName, static::NODE_LOCAL_SSL_KEY_PUB);
     $settings = new Settings('test_data/' . $settignsFileName);
     $settings->data['datadir'] = 'test_data';
     $settings->data['node']['id'] = Node::genIdHexStr(static::NODE_LOCAL_SSL_KEY_PUB);
     $settings->data['node']['sslKeyPrvPass'] = '******';
     $settings->data['node']['sslKeyPrvPath'] = 'test_data/' . $prvFileName;
     $settings->data['node']['sslKeyPubPath'] = 'test_data/' . $pubFileName;
     $settings->data['node']['bridge']['client']['enabled'] = false;
     #$settings->setDataChanged(true);
     #$settings->save();
     $localNode = new Node();
     $localNode->setIdHexStr($settings->data['node']['id']);
     $localNode->setUri($settings->data['node']['uriLocal']);
     $localNode->setSslKeyPub(file_get_contents($settings->data['node']['sslKeyPubPath']));
     $this->assertEquals(static::NODE_LOCAL_SSL_KEY_PUB, $localNode->getSslKeyPub());
     // @codingStandardsIgnoreStart
     #$this->assertEquals('FC_WwG2GdTmCLSKhpEmJso6pejm9c6oACjX', Node::genSslKeyFingerprint($localNode->getSslKeyPub()));
     $this->assertEquals('FC_6t6Z9dYVWEDfEzGQGDSAteLQsFE8SDwZFK2PoiQuM2ezFUA2yNpBPiT9oBwvFBfzDWZzZF5sxBtcSd', Node::genSslKeyFingerprint($localNode->getSslKeyPub()));
     // @codingStandardsIgnoreEnd
     $nodes = array();
     $nodes[0] = new Node();
     $nodes[0]->setIdHexStr($uuid1 . '00');
     $nodes[0]->setUri('tcp://127.0.0.0:25000');
     $nodes[0]->setSslKeyPub(static::NODE0_SSL_KEY_PUB);
     $nodes[1] = new Node();
     $nodes[1]->setIdHexStr($uuid1 . '01');
     $nodes[1]->setUri('tcp://127.0.0.1:25000');
     $nodes[2] = new Node();
     $nodes[2]->setIdHexStr($uuid1 . '02');
     $nodes[2]->setUri('tcp://127.0.0.2:25000');
     $nodes[2]->setSslKeyPub(static::NODE2_SSL_KEY_PUB);
     $nodes[3] = new Node();
     $nodes[3]->setIdHexStr($uuid1 . '03');
     $nodes[3]->setUri('tcp://127.0.0.3:25000');
     $nodes[4] = new Node();
     $nodes[4]->setIdHexStr($uuid1 . '04');
     $nodes[4]->setUri('tcp://127.0.0.4:25000');
     $nodes[4]->setSslKeyPub(static::NODE4_SSL_KEY_PUB);
     $nodes[5] = new Node();
     $nodes[5]->setIdHexStr($uuid1 . '05');
     $nodes[5]->setUri('tcp://127.0.0.5:25000');
     $nodes[5]->setSslKeyPub(static::NODE5_SSL_KEY_PUB);
     $table = new Table();
     $table->setDatadirBasePath($settings->data['datadir']);
     $table->setLocalNode($localNode);
     $table->nodeEnclose($nodes[0]);
     $table->nodeEnclose($nodes[1]);
     $table->nodeEnclose($nodes[2]);
     #$table->nodeEnclose($nodes[3]); // Test not in table.
     #$table->nodeEnclose($nodes[4]);
     #$table->nodeEnclose($nodes[5]);
     $msgs = array();
     for ($nodeNo = 1000; $nodeNo <= 1011; $nodeNo++) {
         $msg = new Msg();
         $msg->setId($uuid2 . $nodeNo);
         $this->assertEquals($uuid2 . $nodeNo, $msg->getId());
         $msg->setSrcNodeId($settings->data['node']['id']);
         $msg->setSrcSslKeyPub($table->getLocalNode()->getSslKeyPub());
         $msg->setSrcUserNickname($settings->data['user']['nickname']);
         $msg->setText('this is  a test. ' . date('Y-m-d H:i:s'));
         $msg->setSslKeyPrvPath($settings->data['node']['sslKeyPrvPath'], $settings->data['node']['sslKeyPrvPass']);
         $msg->setStatus('O');
         $msg->setDstNodeId($nodes[0]->getIdHexStr());
         $msg->setEncryptionMode('D');
         $msg->setDstSslPubKey($nodes[0]->getSslKeyPub());
         $msgs[$nodeNo] = $msg;
         #fwrite(STDOUT, __METHOD__.' msg setup: '.$nodeNo.''.PHP_EOL);
     }
     $msgs[1001]->setDstNodeId($nodes[1]->getIdHexStr());
     $msgs[1001]->setEncryptionMode('S');
     $msgs[1001]->setDstSslPubKey($table->getLocalNode()->getSslKeyPub());
     $this->assertEquals('S', $msgs[1001]->getEncryptionMode());
     $msgs[1002]->setDstNodeId($nodes[2]->getIdHexStr());
     $msgs[1002]->setEncryptionMode('S');
     $msgs[1002]->setDstSslPubKey($table->getLocalNode()->getSslKeyPub());
     $this->assertEquals('S', $msgs[1002]->getEncryptionMode());
     $msgs[1003]->setDstNodeId($nodes[3]->getIdHexStr());
     $msgs[1003]->setEncryptionMode('S');
     $msgs[1003]->setDstSslPubKey($table->getLocalNode()->getSslKeyPub());
     $this->assertEquals('S', $msgs[1003]->getEncryptionMode());
     $msgs[1004]->setSentNodes(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
     $this->assertEquals(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), $msgs[1004]->getSentNodes());
     $msgs[1005]->setStatus('U');
     $msgs[1006]->setStatus('S');
     $msgs[1007]->setStatus('S');
     $msgs[1007]->setSentNodes(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21));
     $msgs[1008]->setStatus('S');
     $msgs[1008]->setForwardCycles(110);
     $msgs[1008]->setSentNodes(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
     $msgs[1009]->setStatus('S');
     $msgs[1009]->setSentNodes(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, $uuid1 . '00'));
     $msgs[1010]->setRelayNodeId($uuid1 . '01');
     $msgs[1011]->setSrcNodeId($nodes[4]->getIdHexStr());
     $msgs[1011]->setDstNodeId($nodes[5]->getIdHexStr());
     $msgs[1011]->setStatus('U');
     $msgDb = new MsgDb();
     $msgDb->setDatadirBasePath($settings->data['datadir']);
     $cronjobLog = new Logger('cronjob');
     #$cronjobLog->pushHandler(new LoggerStreamHandler('php://stdout', Logger::DEBUG));
     $cronjob = new Cronjob();
     $cronjob->setLog($cronjobLog);
     $cronjob->setMsgDb($msgDb);
     $cronjob->setSettings($settings);
     $cronjob->setTable($table);
     // Encrypt
     foreach ($msgs as $msgId => $msg) {
         #fwrite(STDOUT, __METHOD__.' encrypt: '.$msgId.PHP_EOL);
         $encrypted = false;
         try {
             $encrypted = $msg->encrypt();
         } catch (Exception $e) {
             print 'ERROR: ' . $e->getMessage() . PHP_EOL;
         }
         $this->assertTrue($encrypted);
         $rv = $cronjob->getMsgDb()->msgAdd($msg);
     }
     $this->assertEquals(12, $cronjob->getMsgDb()->getMsgsCount());
     // Init Nodes
     #fwrite(STDOUT, __METHOD__.' init nodes'.PHP_EOL);
     $cronjob->msgDbInitNodes();
     $cronjobMsgs = $cronjob->getMsgDb()->getMsgs();
     #foreach($cronjobMsgs as $msgId => $msg){
     #	$logOut = $msg->getId().', '.$msg->getStatus().', '.$msg->getEncryptionMode();
     #	fwrite(STDOUT, __METHOD__.' cronjobMsgs: '.$logOut.PHP_EOL);
     #}
     $this->assertEquals(12, count($cronjobMsgs));
     $this->assertEquals($msgs[1000], $cronjobMsgs[$uuid2 . '1000']);
     $this->assertEquals($msgs[1001], $cronjobMsgs[$uuid2 . '1001']);
     $this->assertEquals($msgs[1002], $cronjobMsgs[$uuid2 . '1002']);
     $this->assertEquals($msgs[1003], $cronjobMsgs[$uuid2 . '1003']);
     $this->assertEquals($msgs[1004], $cronjobMsgs[$uuid2 . '1004']);
     $this->assertEquals($msgs[1005], $cronjobMsgs[$uuid2 . '1005']);
     $this->assertEquals($msgs[1006], $cronjobMsgs[$uuid2 . '1006']);
     $this->assertEquals($msgs[1007], $cronjobMsgs[$uuid2 . '1007']);
     $this->assertEquals($msgs[1008], $cronjobMsgs[$uuid2 . '1008']);
     $this->assertEquals($msgs[1009], $cronjobMsgs[$uuid2 . '1009']);
     $this->assertEquals($msgs[1010], $cronjobMsgs[$uuid2 . '1010']);
     $this->assertEquals($msgs[1011], $cronjobMsgs[$uuid2 . '1011']);
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1000']->getEncryptionMode());
     $this->assertEquals('S', $cronjobMsgs[$uuid2 . '1001']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1002']->getEncryptionMode());
     $this->assertEquals('S', $cronjobMsgs[$uuid2 . '1003']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1004']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1005']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1006']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1007']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1008']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1009']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1010']->getEncryptionMode());
     $this->assertEquals('D', $cronjobMsgs[$uuid2 . '1011']->getEncryptionMode());
     $updateMsgs = $cronjob->msgDbSendAll();
     /*foreach($updateMsgs as $msgId => $msg){
     			$logOut = '/'.$msg['obj']->getId().'/';
     			$logOut .= ' /'.$msg['obj']->getStatus().'/';
     			$logOut .= ' /'.$msg['obj']->getEncryptionMode().'/'.' '.count($msg['nodes']);
     			fwrite(STDOUT, __METHOD__.' update msg: '.$logOut.PHP_EOL);
     			#ve($msg['nodes']);
     		}*/
     $this->assertEquals(6, count($updateMsgs));
     $this->assertEquals('O', $msgs[1000]->getStatus());
     $this->assertEquals('O', $msgs[1002]->getStatus());
     $this->assertEquals('U', $msgs[1005]->getStatus());
     $this->assertEquals('S', $msgs[1006]->getStatus());
     $this->assertEquals('O', $msgs[1010]->getStatus());
     $this->assertEquals('U', $msgs[1011]->getStatus());
     $this->assertEquals('D', $msgs[1000]->getEncryptionMode());
     $this->assertEquals('D', $msgs[1002]->getEncryptionMode());
     $this->assertEquals('D', $msgs[1005]->getEncryptionMode());
     $this->assertEquals('D', $msgs[1006]->getEncryptionMode());
     $this->assertEquals('D', $msgs[1010]->getEncryptionMode());
     $this->assertEquals('D', $msgs[1011]->getEncryptionMode());
     $this->assertTrue(array_key_exists($uuid2 . '1000', $updateMsgs));
     $this->assertTrue(array_key_exists($uuid2 . '1002', $updateMsgs));
     $this->assertTrue(array_key_exists($uuid2 . '1005', $updateMsgs));
     $this->assertTrue(array_key_exists($uuid2 . '1006', $updateMsgs));
     $this->assertTrue(array_key_exists($uuid2 . '1010', $updateMsgs));
     $this->assertTrue(array_key_exists($uuid2 . '1011', $updateMsgs));
     $this->assertEquals(3, count($updateMsgs[$uuid2 . '1000']['nodes']));
     $this->assertEquals(3, count($updateMsgs[$uuid2 . '1002']['nodes']));
     $this->assertEquals(3, count($updateMsgs[$uuid2 . '1005']['nodes']));
     $this->assertEquals(3, count($updateMsgs[$uuid2 . '1006']['nodes']));
     $this->assertEquals(2, count($updateMsgs[$uuid2 . '1010']['nodes']));
     $this->assertEquals(3, count($updateMsgs[$uuid2 . '1011']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '00', $updateMsgs[$uuid2 . '1000']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '01', $updateMsgs[$uuid2 . '1000']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '02', $updateMsgs[$uuid2 . '1000']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '00', $updateMsgs[$uuid2 . '1002']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '01', $updateMsgs[$uuid2 . '1002']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '02', $updateMsgs[$uuid2 . '1002']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '00', $updateMsgs[$uuid2 . '1005']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '01', $updateMsgs[$uuid2 . '1005']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '02', $updateMsgs[$uuid2 . '1005']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '00', $updateMsgs[$uuid2 . '1006']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '01', $updateMsgs[$uuid2 . '1006']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '02', $updateMsgs[$uuid2 . '1006']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '00', $updateMsgs[$uuid2 . '1010']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '02', $updateMsgs[$uuid2 . '1010']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '00', $updateMsgs[$uuid2 . '1011']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '01', $updateMsgs[$uuid2 . '1011']['nodes']));
     $this->assertTrue(array_key_exists($uuid1 . '02', $updateMsgs[$uuid2 . '1011']['nodes']));
 }
Exemple #4
0
 public function testSendMsg()
 {
     list($client1, $client2) = $this->sendGenTestDataDefault();
     // Send Msg before ID should cause an error.
     $msg = new Msg();
     $msg->setVersion(1);
     $msg->setSrcNodeId($client1->getSettings()->data['node']['id']);
     $msg->setSrcSslKeyPub(static::NODE_LOCAL_SSL_KEY_PUB1);
     $msg->setSrcUserNickname('thefox');
     $msg->setDstNodeId($client2->getSettings()->data['node']['id']);
     $msg->setDstSslPubKey(static::NODE_LOCAL_SSL_KEY_PUB2);
     $msg->setSubject('my first subject');
     $msg->setText('hello world! this is a test');
     $msg->setSslKeyPrv(static::NODE_LOCAL_SSL_KEY_PRV1, 'my_password');
     $msg->encrypt();
     $raw = $client1->sendMsg($msg);
     #ve($raw);
     $raw = $client2->dataRecv($raw);
     #ve($raw);
     $json = $this->rawMsgToJson($raw);
     #ve($json);
     $this->assertEquals('error', $json[0]['name']);
     $this->assertEquals(1000, $json[0]['data']['code']);
     $this->sendClientsId($client1, $client2);
     // Send Msg
     $msg = new Msg();
     $msg->setVersion(1);
     #$msg->setId('200b9758-2d34-4152-8ada-fc09fc9c9da0');
     $msg->setSrcNodeId('cafed00d-2131-4159-8e11-0b4dbadb1738');
     $msg->setSrcSslKeyPub(static::NODE_LOCAL_SSL_KEY_PUB1);
     $msg->setSrcUserNickname('thefox');
     $msg->setDstNodeId('cafed00d-2131-4159-8e11-0b4dbadb1739');
     $msg->setDstSslPubKey(static::NODE_LOCAL_SSL_KEY_PUB2);
     $msg->setSubject('my first subject');
     $msg->setText('hello world! this is a test');
     $msg->setSslKeyPrv(static::NODE_LOCAL_SSL_KEY_PRV1, 'my_password');
     $msg->encrypt();
     $raw = $client1->sendMsg($msg);
     $json = $this->rawMsgToJson($raw);
     #ve($json);
     $rid = $json[0]['data']['rid'];
     $this->assertEquals('msg', $json[0]['name']);
     $this->assertEquals('cafed00d-2131-4159-8e11-0b4dbadb1738', $json[0]['data']['srcNodeId']);
     $this->assertEquals('cafed00d-2131-4159-8e11-0b4dbadb1739', $json[0]['data']['dstNodeId']);
     $raw = $client2->dataRecv($raw);
     $json = $this->rawMsgToJson($raw);
     #ve($json);
     $this->assertEquals('msg_response', $json[0]['name']);
     $this->assertEquals($rid, $json[0]['data']['rid']);
     $client1->getServer()->getKernel()->shutdown();
     $client2->getServer()->getKernel()->shutdown();
 }
Exemple #5
0
 public function testGetMsgsForDst()
 {
     $db = new MsgDb();
     $msg = new Msg();
     $msg->setId('76cabb4d-e729-4a50-a792-e223704c2943');
     $db->msgAdd($msg);
     $msg = new Msg();
     $msg->setId('76cabb4d-e729-4a50-a792-e223704c2944');
     $msg->setDstNodeId('76cabb4d-e729-4a50-a792-e223704c2947');
     $db->msgAdd($msg);
     $msg = new Msg();
     $msg->setId('76cabb4d-e729-4a50-a792-e223704c2945');
     $db->msgAdd($msg);
     $msg = new Msg();
     $msg->setId('76cabb4d-e729-4a50-a792-e223704c2946');
     $msg->setDstNodeId('76cabb4d-e729-4a50-a792-e223704c2947');
     $db->msgAdd($msg);
     $node = new Node();
     $node->setIdHexStr('76cabb4d-e729-4a50-a792-e223704c2947');
     $msgs = $db->getMsgsForDst($node);
     $this->assertTrue(is_array($msgs));
     $this->assertTrue(isset($msgs['76cabb4d-e729-4a50-a792-e223704c2944']));
     $this->assertTrue(isset($msgs['76cabb4d-e729-4a50-a792-e223704c2946']));
 }
Exemple #6
0
 private function handleCommandMsg($line)
 {
     #print __CLASS__.'->'.__FUNCTION__.': "'.$line.'"'."\n";
     $line = substr($line, 3);
     #print __CLASS__.'->'.__FUNCTION__.': get table'."\n";
     $table = $this->ipcKernelConnection->execSync('getTable');
     #print __CLASS__.'->'.__FUNCTION__.': get msgDb'."\n";
     #$msgDb = $this->ipcKernelConnection->execSync('getMsgDb');
     $msgs = $this->ipcKernelConnection->execSync('msgDbMsgGetMsgsForDst');
     $msgsByIndex = array_keys($msgs);
     #ve($msgDb);
     #ve($msgs);
     #ve($msgsByIndex);
     /*
     		if(!$msgDb){
     			print __CLASS__.'->'.__FUNCTION__.': get msgDb failed'."\n";
     			return;
     		}*/
     if ($line) {
         $line = substr($line, 1);
         $args = preg_split('/ /', $line);
         #ve($args);
         #print __CLASS__.'->'.__FUNCTION__.': rest "'.$line.'"'."\n";
         #$this->printPs1(true, 'handleCommandMsg A');
         if ($args[0] == 'new' || $args[0] == 'n') {
             if (Uuid::isValid($args[1])) {
                 if ($args[1] != $table->getLocalNode()->getIdHexStr()) {
                     $this->sttyExitIcanonMode();
                     $this->sttyEchoOn();
                     stream_set_blocking(STDIN, 1);
                     print PHP_EOL . 'Subject: ';
                     $subject = strtolower(substr(fgets(STDIN, 100), 0, -1));
                     if (!$subject) {
                         $subject = 'No Subject';
                     }
                     #print "Subject: '".$subject."'\n\n";
                     print PHP_EOL . 'Enter the text to send.' . PHP_EOL;
                     print 'NOTE: end text with  <RETURN>.<RETURN>' . PHP_EOL;
                     $text = '';
                     while (!$this->getExit()) {
                         $line = fgets(STDIN, 1024);
                         #print "line: '".substr($line, 0, -1)."'\n";
                         if (substr($line, 0, -1) == '.') {
                             break;
                         }
                         $text .= $line;
                         #sleep(1);
                     }
                     if (!$this->getExit()) {
                         $text = substr($text, 0, -1);
                         print 'Send msg? [Y/n] ';
                         $answer = strtolower(substr(fgets(STDIN, 100), 0, -1));
                         if (!$answer) {
                             $answer = 'y';
                         }
                         print "Answer: '" . $answer . "'" . PHP_EOL;
                         #print "Text: '".$text."'\n";
                         stream_set_blocking(STDIN, 0);
                         $this->sttyEnterIcanonMode();
                         $this->sttyEchoOff();
                         if ($answer == 'y') {
                             $dstNodeId = $args[1];
                             #$dstNodeId = '42785b21-011b-4093-b61d-000000000001';
                             #$text = 'this is  a test. '.date('Y-m-d H:i:s');
                             $table = $this->ipcKernelConnection->execSync('getTable');
                             $msg = new Msg();
                             $msg->setSrcNodeId($this->settings->data['node']['id']);
                             $msg->setSrcSslKeyPub($table->getLocalNode()->getSslKeyPub());
                             $msg->setSrcUserNickname($this->userNickname);
                             $dstNode = new Node();
                             $dstNode->setIdHexStr($dstNodeId);
                             $msg->setDstNodeId($dstNode->getIdHexStr());
                             if ($oDstNode = $table->nodeFind($dstNode)) {
                                 #print 'found node in table'.PHP_EOL;
                                 $msg->setDstSslPubKey($oDstNode->getSslKeyPub());
                             }
                             #else{ print 'node not found'.PHP_EOL; }
                             $msg->setSubject($subject);
                             $msg->setText($text);
                             $msg->setSslKeyPrvPath($this->settings->data['node']['sslKeyPrvPath'], $this->settings->data['node']['sslKeyPrvPass']);
                             $msg->setStatus('O');
                             $encrypted = false;
                             #print 'DstSslPubKey: '.strlen($msg->getDstSslPubKey()).PHP_EOL;
                             if ($msg->getDstSslPubKey()) {
                                 #print 'use dst key'.PHP_EOL;
                                 $msg->setEncryptionMode('D');
                             } else {
                                 // Encrypt with own public key
                                 // while destination public key is not available.
                                 #print 'use local key'.PHP_EOL;
                                 $msg->setEncryptionMode('S');
                                 $msg->setDstSslPubKey($table->getLocalNode()->getSslKeyPub());
                             }
                             try {
                                 $encrypted = $msg->encrypt();
                                 if ($encrypted) {
                                     $this->ipcKernelConnection->execAsync('msgDbMsgAdd', array($msg));
                                     $this->msgAdd('OK: msg created ' . $msg->getId(), true, true);
                                 } else {
                                     $this->msgAdd('ERROR: could not encrypt message.', true, true);
                                 }
                             } catch (Exception $e) {
                                 $this->msgAdd('ERROR: ' . $e->getMessage(), true, true);
                             }
                             #$this->printPs1(true, 'handleCommandMsg B');
                         } else {
                             print 'Nothing created, nothing sent.' . PHP_EOL;
                             $this->printPs1(true, 'handleCommandMsg C');
                         }
                     }
                 } else {
                     $this->msgAdd();
                     $this->msgAdd('Send a message to yourself?', false, true);
                 }
             } else {
                 $this->msgAdd();
                 $this->msgAdd('ERROR: "' . $args[1] . '" is not a UUID.', false, true);
             }
         } elseif ($args[0] == 'read' || $args[0] == 'r') {
             if (isset($args[1])) {
                 $msg = null;
                 if (Uuid::isValid($args[1])) {
                     if (isset($msgs[$args[1]])) {
                         $msg = $msgs[$args[1]];
                     }
                 } else {
                     $no = (int) $args[1] - 1;
                     if (isset($msgsByIndex[$no])) {
                         $msg = $msgs[$msgsByIndex[$no]];
                     }
                 }
                 if ($msg) {
                     $msg->setDstSslPubKey($table->getLocalNode()->getSslKeyPub());
                     $sslKeyPrvPath = $this->settings->data['node']['sslKeyPrvPath'];
                     $sslKeyPrvPass = $this->settings->data['node']['sslKeyPrvPass'];
                     $msg->setSslKeyPrvPath($sslKeyPrvPath, $sslKeyPrvPass);
                     #ve($msg);
                     $text = null;
                     try {
                         $text = $msg->decrypt();
                     } catch (Exception $e) {
                         $text = null;
                         #print 'ERROR: decrypt: '.$e->getMessage().PHP_EOL;
                     }
                     $dateCreated = new DateTime();
                     $dateCreated->setTimestamp($msg->getTimeCreated());
                     $dateReceived = new DateTime();
                     $dateReceived->setTimestamp($msg->getTimeReceived());
                     $fromLine = '';
                     if ($msg->getSrcUserNickname()) {
                         $fromLine .= $msg->getSrcUserNickname() . ' ';
                     }
                     $fromLine .= '<' . $msg->getSrcNodeId() . '>';
                     $toLine = '';
                     if ($table->getLocalNode()->getIdHexStr() == $msg->getDstNodeId()) {
                         $toLine .= 'Me ';
                     }
                     $toLine .= '<' . $msg->getDstNodeId() . '>';
                     $this->msgAdd();
                     if (!$text) {
                         $this->msgAdd('WARNING: could not decrypt text. Only meta data available.', false, false);
                     }
                     $this->msgAdd('----- MESSAGE BEGIN -----');
                     $this->msgAdd('Subject: ' . $msg->getSubject(), false, false);
                     $this->msgAdd('From: ' . $fromLine, false, false);
                     $this->msgAdd('To: ' . $toLine, false, false);
                     $this->msgAdd('Msg ID: ' . $msg->getId(), false, false);
                     $this->msgAdd('Status: ' . $msg->getStatusText(), false, false);
                     $this->msgAdd('Created:  ' . $dateCreated->format('Y-m-d H:i:s'), false, false);
                     $this->msgAdd('Received: ' . $dateReceived->format('Y-m-d H:i:s'), false, false);
                     if ($text) {
                         $this->msgAdd();
                         $this->msgAdd($text, false, false);
                         $msg->setStatus('R');
                         $this->ipcKernelConnection->execAsync('msgDbMsgUpdate', array($msg));
                     }
                     $this->msgAdd('----- MESSAGE END -----', false, true);
                 } else {
                     $this->msgAdd();
                     $this->msgAdd('ERROR: could not read msg "' . $args[1] . '".', false, true);
                 }
             } else {
                 $this->msgAdd();
                 $this->msgAdd('ERROR: you must specify a msg number or ID.', false, true);
             }
         }
     } else {
         $format = '%3d %1s %36s %s %s';
         $this->msgAdd();
         $this->msgAdd('  # N FROM                                 CRATED              RECEIVED', false, true);
         $no = 0;
         foreach ($msgs as $msgId => $msg) {
             $no++;
             $dateCreated = new DateTime();
             $dateCreated->setTimestamp($msg->getTimeCreated());
             $dateReceived = new DateTime();
             $dateReceived->setTimestamp($msg->getTimeReceived());
             $line = sprintf($format, $no, $msg->getStatus() == 'U' ? '*' : ' ', $msg->getSrcNodeId(), $dateCreated->format('Y-m-d H:i:s'), $dateReceived->format('Y-m-d H:i:s'));
             $this->msgAdd($line, false, false);
         }
         $this->msgAdd('END OF LIST', false, true);
     }
 }
Exemple #7
0
 public function mailNew($event, $from, $rcpt, $mail)
 {
     #fwrite(STDOUT, 'mail new: /'.$from.'/ a/'.join('/ /', $rcpt).'/'."\n");
     #$this->log->debug('mailNew: '.$event->getTrigger().' /'.$from.'/');
     $settings = $this->getSettings();
     $table = $this->ipcKernelConnection->execSync('getTable');
     $text = $mail->getBody();
     foreach ($rcpt as $dstNodeId) {
         $dstNodeId = substr($dstNodeId, 0, strpos($dstNodeId, '@'));
         #fwrite(STDOUT, 'to: /'.$dstNodeId.'/'."\n");
         $msg = new Msg();
         $msg->setSrcNodeId($settings->data['node']['id']);
         $msg->setSrcSslKeyPub($table->getLocalNode()->getSslKeyPub());
         $msg->setSrcUserNickname($settings->data['user']['nickname']);
         $dstNode = new Node();
         $dstNode->setIdHexStr($dstNodeId);
         $msg->setDstNodeId($dstNode->getIdHexStr());
         if ($oDstNode = $table->nodeFind($dstNode)) {
             #print 'found node in table'.PHP_EOL;
             $msg->setDstSslPubKey($oDstNode->getSslKeyPub());
         }
         #else{ print 'node not found'.PHP_EOL; }
         $msg->setSubject($mail->getSubject());
         $msg->setText($text);
         $msg->setSslKeyPrvPath($settings->data['node']['sslKeyPrvPath'], $settings->data['node']['sslKeyPrvPass']);
         $msg->setStatus('O');
         $encrypted = false;
         #print 'DstSslPubKey: '.strlen($msg->getDstSslPubKey()).PHP_EOL;
         if ($msg->getDstSslPubKey()) {
             #print 'use dst key'.PHP_EOL;
             $msg->setEncryptionMode('D');
         } else {
             // Encrypt with own public key
             // while destination public key is not available.
             #print 'use local key'.PHP_EOL;
             $msg->setEncryptionMode('S');
             $msg->setDstSslPubKey($table->getLocalNode()->getSslKeyPub());
         }
         try {
             $encrypted = $msg->encrypt();
             if ($encrypted) {
                 $this->ipcKernelConnection->execAsync('msgDbMsgAdd', array($msg));
                 $this->log->debug('OK: msg created ' . $msg->getId());
             } else {
                 $this->log->error('Could not encrypt message.');
             }
         } catch (Exception $e) {
             $this->log->error('ERROR: ' . $e->getMessage());
         }
     }
 }