public function testSerialize() { #fwrite(STDOUT, 'start'."\n"); #fwrite(STDOUT, 'node'."\n"); $node = new Node(); $node->setIdHexStr('cafed00d-2131-4159-8e11-0b4dbadb1738'); #fwrite(STDOUT, 'tcp client'."\n"); $client = new TcpClient(); $client->setId(21); $client->setUri('tcp://127.0.0.1:25000'); $client->setNode($node); #fwrite(STDOUT, 'ser'."\n"); $client = unserialize(serialize($client)); #ve($client); $this->assertEquals(21, $client->getId()); $this->assertEquals('tcp://127.0.0.1:25000', (string) $client->getUri()); $this->assertEquals($node, $client->getNode()); #fwrite(STDOUT, 'end'."\n"); }
protected function execute(InputInterface $input, OutputInterface $output) { #$this->executePre($input, $output); #$bytesizeFormatter = new Binary(); #$bytesize = new ByteSize($bytesizeFormatter); $bytesize = new ByteSize(); if ($input->hasOption('name') && $input->getOption('name')) { print PhpChat::NAME; } elseif ($input->hasOption('name_lc') && $input->getOption('name_lc')) { print strtolower(PhpChat::NAME); } elseif ($input->hasOption('version_number') && $input->getOption('version_number')) { print PhpChat::VERSION; } elseif ($input->hasOption('connections') && $input->getOption('connections')) { print 'Live Connections' . PHP_EOL . PHP_EOL; $this->executePre($input, $output); $this->log = new Logger($this->getName()); #$this->log->pushHandler(new StreamHandler('php://stdout', Logger::DEBUG)); $this->log->pushHandler(new StreamHandler($this->getLogfilePath(), Logger::DEBUG)); $this->initIpcKernelConnection(); $color = new Color(); $startTime = time(); $time = time(); $seconds = 0; $oldClients = array(); $clientsIdMax = 0; $tcols = (int) exec('tput cols'); $tlines = (int) exec('tput lines'); #print 'cols: '.$tcols.PHP_EOL; #print 'lines: '.$tlines.PHP_EOL; $baseLines = 5; print ' Traffic IN: N/A' . PHP_EOL; print ' Traffic OUT: N/A' . PHP_EOL; #print ' Traffic AVG: N/A'.PHP_EOL; print ' Clients: N/A' . PHP_EOL; #sleep(1); #print '---A'.PHP_EOL; print '' . PHP_EOL; #sleep(1); #print '---B'.PHP_EOL; print ' ' . PHP_EOL; #sleep(1); Console::cursorJumpToColumn(1); #sleep(1); Console::cursorUp($baseLines); #sleep(1); while (!$this->getExit()) { #$this->log->debug('run'); if (!$this->ipcKernelConnection->run()) { $this->log->info('Connection to kernel process end unexpected.'); $this->setExit(1); } $update = false; if ($time != time()) { $time = time(); $seconds++; $tcols = (int) exec('tput cols'); $tlines = (int) exec('tput lines'); $update = true; } $update = true; if ($update) { $clientsInfo = $this->ipcKernelConnection->execSync('serverClientsInfo'); $clientsId = $clientsInfo['clientsId']; $clientsChanged = 0; foreach ($clientsInfo['clients'] as $newClientId => $newClient) { if (isset($oldClients[$newClientId])) { $oldClient = $oldClients[$newClientId]; $changed = false; foreach (static::$CONNECTION_INFO_FIELDS as $fieldName) { if ($oldClient[$fieldName] != $newClient[$fieldName]) { $this->log->debug('update ' . $newClientId . ': ' . $fieldName . '=' . (int) $newClient[$fieldName]); $oldClients[$newClientId][$fieldName] = $newClient[$fieldName]; $oldClients[$newClientId]['lastUpdate'] = time(); } } if ($changed) { $clientsChanged++; } } else { $this->log->debug('new client: ' . $newClientId); $oldClients[$newClientId] = array('lastUpdate' => time(), 'hasId' => $newClient['hasId'], 'hasTalkRequest' => $newClient['hasTalkRequest'], 'hasTalk' => $newClient['hasTalk'], 'hasTalkClose' => $newClient['hasTalkClose'], 'hasShutdown' => $newClient['hasShutdown'], 'isChannelPeer' => $newClient['isChannelPeer'], 'isChannelLocal' => $newClient['isChannelLocal'], 'isOutbound' => $newClient['isOutbound'], 'isInbound' => $newClient['isInbound'], 'isBridgeServer' => $newClient['isBridgeServer'], 'isBridgeClient' => $newClient['isBridgeClient'], 'shutdown' => 0, 'status' => '.'); } } foreach ($oldClients as $oldClientId => $oldClient) { if (!isset($clientsInfo['clients'][$oldClientId]) || $oldClient['hasShutdown']) { if (!$oldClients[$oldClientId]['shutdown']) { $this->log->debug('update ' . $oldClientId . ': shutdown=1'); $oldClients[$oldClientId]['shutdown'] = time(); $oldClients[$oldClientId]['lastUpdate'] = time(); } } if ($oldClient['isOutbound']) { $oldClients[$oldClientId]['status'] = 'o'; } if ($oldClient['isInbound']) { $oldClients[$oldClientId]['status'] = 'i'; } if ($oldClient['isChannelPeer'] || $oldClient['isChannelLocal']) { $oldClients[$oldClientId]['status'] = 'c'; } if ($oldClient['isBridgeServer'] || $oldClient['isBridgeClient']) { $oldClients[$oldClientId]['status'] = 'b'; } if ($oldClient['hasTalkRequest']) { $oldClients[$oldClientId]['status'] = 't'; } if ($oldClient['hasTalk']) { $oldClients[$oldClientId]['status'] = 'T'; } if ($oldClient['hasTalkClose']) { $oldClients[$oldClientId]['status'] = 'X'; } if ($oldClient['shutdown']) { #$this->log->debug('client '.$oldClientId.' has shutdown: '.(time() - $oldClient['shutdown'])); $oldClients[$oldClientId]['status'] = 'x'; if ($oldClient['shutdown'] <= time() - 5) { unset($oldClients[$oldClientId]); } } } $oldClientsLen = count($oldClients); Console::cursorJumpToColumn(15); #sleep(1); print $bytesize->format($clientsInfo['traffic']['in']); #sleep(1); Console::lineClearRight(); #sleep(1); print Console::cursorDown(); #sleep(1); Console::cursorJumpToColumn(15); #sleep(1); print $bytesize->format($clientsInfo['traffic']['out']); #sleep(1); Console::lineClearRight(); #sleep(1); print Console::cursorDown(); #sleep(1); Console::cursorJumpToColumn(11); #sleep(1); print $oldClientsLen . ' / ' . $clientsId; #sleep(1); Console::lineClearRight(); #sleep(1); print Console::cursorDown(); #sleep(1); /*Console::cursorJumpToColumn(15); #sleep(1); $trafficTotal = bcadd($clientsInfo['traffic']['in'], $clientsInfo['traffic']['out']); print $bytesize->format(bcdiv($trafficTotal, time() - $clientsInfo['timeCreated'])).'/s'; #print time() - $clientsInfo['timeCreated']; #sleep(1); Console::lineClearRight(); #sleep(1); print Console::cursorDown(); #sleep(1);*/ print Console::cursorDown(); #sleep(1); Console::cursorJumpToColumn(2); #sleep(1); #print PHP_EOL.' '; #sleep(1); $line = 0; $lineClients = 0; foreach ($oldClients as $oldClientId => $oldClient) { #$this->log->debug('client '.$oldClientId.' print: '.(time() - $oldClient['lastUpdate'])); $output = $oldClient['status']; if ($oldClient['lastUpdate'] >= time() - 2) { $output = $color($oldClient['status'])->bg_green; } elseif ($oldClient['lastUpdate'] <= time() - 60) { #$output = $color($oldClient['status'])->dark; $output = $color($oldClient['status'])->bg_blue; } print $output; $lineClients++; if ($lineClients >= $tcols - 2) { $lineClients = 0; $line++; print PHP_EOL . ' '; } } Console::screenClearToBottom(); #sleep(1); print PHP_EOL; #sleep(1); Console::cursorJumpToColumn(1); #sleep(1); Console::cursorUp($line + $baseLines); #sleep(1); } usleep(static::LOOP_USLEEP); } #sleep(1); Console::cursorUp(); #sleep(1); Console::screenClearToBottom(); #sleep(1); $this->executePost(); $this->log->info('exit'); } else { $settings = $this->getSettings(); $localNode = new Node(); $localNode->setIdHexStr($settings->data['node']['id']); $localNode->setUri($settings->data['node']['uriLocal']); $localNode->setSslKeyPub(file_get_contents($settings->data['node']['sslKeyPubPath'])); $trafficIn = $bytesize->format($settings->data['node']['traffic']['in']); $trafficIn .= ' (' . $settings->data['node']['traffic']['in'] . ' byte)'; $trafficOut = $bytesize->format($settings->data['node']['traffic']['out']); $trafficOut .= ' (' . $settings->data['node']['traffic']['out'] . ' byte)'; print '--------' . PHP_EOL; print 'Informations about local node:' . PHP_EOL; print ' Version: ' . PhpChat::NAME . '/' . PhpChat::VERSION . ' (release ' . PhpChat::RELEASE . ')' . PHP_EOL; print ' ID: ' . $localNode->getIdHexStr() . PHP_EOL; print ' Public key fingerprint: ' . $localNode->getSslKeyPubFingerprint() . PHP_EOL; print ' Last public IP: ' . $settings->data['node']['uriPub'] . PHP_EOL; print ' Listen IP:Port: ' . $settings->data['node']['uriLocal'] . PHP_EOL; print ' Traffic IN: ' . $trafficIn . PHP_EOL; print ' Traffic OUT: ' . $trafficOut . PHP_EOL; print ' Nickname: ' . $settings->data['user']['nickname'] . PHP_EOL; print ' SSL version: ' . OPENSSL_VERSION_TEXT . PHP_EOL; print '--------' . PHP_EOL; print ' Pub Key Base64:' . PHP_EOL . base64_encode($localNode->getSslKeyPub()) . PHP_EOL; print '--------' . PHP_EOL; } #$this->executePost(); }
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; }
public function testCreateGuzzleHttpClient() { $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'] = true; $localNode = new Node(); $localNode->setIdHexStr($settings->data['node']['id']); $localNode->setUri($settings->data['node']['uriLocal']); $localNode->setSslKeyPub(file_get_contents($settings->data['node']['sslKeyPubPath'])); $table = new Table(); $table->setDatadirBasePath($settings->data['datadir']); $table->setLocalNode($localNode); $nodesNewDb = new NodesNewDb('test_data/testfile_cronjob_nodesnewdb2.yml'); $nodesNewDb->nodeAddConnect('tcp://192.168.241.21', false); $nodesNewDb->nodeAddConnect('tcp://192.168.241.22', true); $nodesNewDb->nodeAddFind('cafed00d-2131-4159-8e11-0b4dbadb1742', false); $nodesNewDb->nodeAddFind('cafed00d-2131-4159-8e11-0b4dbadb1743', true); $cronjobLog = new Logger('cronjob'); #$cronjobLog->pushHandler(new LoggerStreamHandler('php://stdout', Logger::DEBUG)); $cronjob = new Cronjob(); $cronjob->setLog($cronjobLog); $cronjob->setSettings($settings); $cronjob->setTable($table); $cronjob->setNodesNewDb($nodesNewDb); $httpClient = $cronjob->createGuzzleHttpClient(); #fwrite(STDOUT, 'client: '.get_class($httpClient).''.PHP_EOL); #\Doctrine\Common\Util\Debug::dump($httpClient); $this->assertTrue(is_object($httpClient)); $url = 'http://www.example.com/'; $response = null; try { #fwrite(STDOUT, 'get url: '.$url.''.PHP_EOL); $request = $httpClient->get($url); #fwrite(STDOUT, 'request: '.get_class($request).''.PHP_EOL); $response = $request->send(); #fwrite(STDOUT, 'response: '.get_class($response).''.PHP_EOL); } catch (Exception $e) { #fwrite(STDOUT, 'url failed, "'.$url.'": '.$e->getMessage().PHP_EOL); } /*if($response){ fwrite(STDOUT, 'response: '.$response->getStatusCode().PHP_EOL); fwrite(STDOUT, 'content-type: '.$response->getHeader('content-type').PHP_EOL); } else{ fwrite(STDOUT, 'response failed'.PHP_EOL); }*/ }
public function nodesNewEnclose() { $this->log->debug('nodes new enclose'); if ($this->ipcKernelConnection) { $this->setTable($this->ipcKernelConnection->execSync('getTable')); } if ($this->ipcKernelConnection) { $this->nodesNewDb = $this->ipcKernelConnection->execSync('getNodesNewDb', array(), 10); } $settingsBridgeClient = $this->settings->data['node']['bridge']['client']['enabled']; $nodes = array(); foreach ($this->nodesNewDb->getNodes() as $nodeId => $node) { #$this->log->debug('node: '.$nodeId.' '.(int)$node['bridgeServer']); if ($node['type'] == 'connect') { if ($node['connectAttempts'] >= 10) { $this->log->debug('node remove: ' . $nodeId); #$nodes[] = array('type' => 'remove', 'node' => null); if ($this->ipcKernelConnection) { $this->ipcKernelConnection->execAsync('nodesNewDbNodeRemove', array($nodeId)); } else { $this->nodesNewDb->nodeRemove($nodeId); } } else { $nodeObj = new Node(); $nodeObj->setUri($node['uri']); $nodeObj->setBridgeServer($node['bridgeServer']); if ($settingsBridgeClient) { if ($nodeObj->getBridgeServer()) { $nodes[] = array('type' => 'connect', 'node' => $nodeObj); $this->nodesNewEncloseServerConnect($nodeObj, $nodeId); } else { $this->log->debug('node remove: ' . $nodeId); $nodes[] = array('type' => 'remove', 'node' => $nodeObj); if ($this->ipcKernelConnection) { $this->ipcKernelConnection->execAsync('nodesNewDbNodeRemove', array($nodeId)); } else { $this->nodesNewDb->nodeRemove($nodeId); } } } else { $nodes[] = array('type' => 'connect', 'node' => $nodeObj); $this->nodesNewEncloseServerConnect($nodeObj, $nodeId); } } } elseif ($node['type'] == 'find') { $nodeObj = new Node(); $nodeObj->setIdHexStr($node['id']); $nodeObj->setBridgeServer($node['bridgeServer']); if ($this->table->nodeFind($nodeObj)) { $this->log->debug('node remove: ' . $nodeId); #$nodes[] = array('type' => 'remove', 'node' => $nodeObj); if ($this->ipcKernelConnection) { $this->ipcKernelConnection->execAsync('nodesNewDbNodeRemove', array($nodeId)); } else { $this->nodesNewDb->nodeRemove($nodeId); } } elseif ($node['findAttempts'] >= 5) { $this->log->debug('node remove: ' . $nodeId); #$nodes[] = array('type' => 'remove', 'node' => $nodeObj); if ($this->ipcKernelConnection) { $this->ipcKernelConnection->execAsync('nodesNewDbNodeRemove', array($nodeId)); } else { $this->nodesNewDb->nodeRemove($nodeId); } } else { $this->log->debug('node find: ' . $node['id']); $nodes[] = array('type' => 'find', 'node' => $nodeObj); if ($this->ipcKernelConnection) { $this->ipcKernelConnection->execAsync('serverNodeFind', array($node['id'])); $this->ipcKernelConnection->execAsync('nodesNewDbNodeIncFindAttempt', array($nodeId)); } else { $this->nodesNewDb->nodeIncFindAttempt($nodeId); } } } } /*foreach($nodes as $nodeId => $node){ $logTmp = '/'.(int)is_object($node['node']).'/ /'.(int)$node['node']->getBridgeServer().'/'; fwrite(STDOUT, 'node: '.$node['type'].' '.$logTmp.PHP_EOL); }*/ return $nodes; // Return only for tests. }
public function testSerialize() { $node = new Node(); $node->setIdHexStr('cafed00d-2131-4159-8e11-0b4dbadb1738'); $client = new Client(); $client->setId(21); $client->setUri('tcp://127.0.0.1:25000'); $client->setNode($node); $client = unserialize(serialize($client)); #ve($client); $this->assertEquals(21, $client->getId()); $this->assertEquals('tcp://127.0.0.1:25000', (string) $client->getUri()); $this->assertEquals($node, $client->getNode()); }
/** * @group large */ public function testNodeEnclose4() { #fwrite(STDOUT, 'testNodeEnclose4'.PHP_EOL); $runName = uniqid('', true); $fileName = 'testfile_table_table_' . date('Ymd_His') . '_' . $runName . '.yml'; $NODES = 100; Bucket::$SIZE_MAX = 20; $localNode = new Node(); $localNode->setIdHexStr('12000001-2002-4004-8008-100000000001'); $table = new Table('test_data/' . $fileName); $table->setDatadirBasePath('test_data'); $table->setLocalNode($localNode); $table->load(); $nodeNoBegin = 100000000002; $nodeNoEnd = $nodeNoBegin + $NODES; for ($nodeNo = $nodeNoBegin; $nodeNo < $nodeNoEnd; $nodeNo++) { #fwrite(STDOUT, __METHOD__.' node setup: '.$nodeNo.''.PHP_EOL); timeStop('node setup ' . $nodeNo); $node = new Node(); $node->setIdHexStr('12000001-2002-4004-8008-' . $nodeNo); $table->nodeEnclose($node); } fwrite(STDOUT, 'save' . PHP_EOL); $table->save(); $nodeNum = $table->getNodesNum(); fwrite(STDOUT, 'nodes: ' . $nodeNum . '' . PHP_EOL); #$this->assertEquals(160, $nodeNum); $this->assertTrue(true); $finder = new Finder(); $files = $finder->in('test_data')->depth(0)->name('node_*.yml')->files(); #$this->assertEquals(160, count($files)); $this->clean(); }
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'])); }
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); } }
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()); } } }
public function testNodeEnclose5() { $runName = uniqid('', true); $fileName = 'testfile_table_nodeenclose5_' . date('Ymd_His') . '_' . $runName . '.yml'; $localNode = new Node(); $localNode->setIdHexStr('11000001-2002-4004-8008-100000000006'); $table = new Table('test_data/' . $fileName); $table->setDatadirBasePath('test_data'); $table->setLocalNode($localNode); $node1 = new Node(); $node1->setIdHexStr('11000001-2002-4004-8008-100000000001'); $node1->setUri('tcp://192.168.241.1:25000'); $node2 = new Node(); $node2->setIdHexStr('11000001-2002-4004-8008-100000000002'); $node2->setUri('tcp://192.168.241.2:25000'); $node3 = new Node(); $node3->setUri('tcp://192.168.241.1:25000'); $node4 = new Node(); $node4->setIdHexStr('11000001-2002-4004-8008-100000000003'); $node4->setUri('tcp://192.168.241.2:25000'); $table->nodeEnclose($node1); $table->nodeEnclose($node2); $node = $table->nodeEnclose($node3); $this->assertEquals('00000000-0000-4000-8000-000000000000', $node->getIdHexStr()); $this->assertEquals('tcp://192.168.241.1:25000', (string) $node->getUri()); $node = $table->nodeEnclose($node4); $this->assertEquals('11000001-2002-4004-8008-100000000003', $node->getIdHexStr()); $this->assertEquals('tcp://192.168.241.2:25000', (string) $node->getUri()); $this->assertEquals('', (string) $node2->getUri()); $table->save(); }
public function testUpdate() { $node_a = new Node(); $node_a->setIdHexStr('11111111-1111-4111-8111-111111111100'); $node_a->setUri('tcp://192.168.241.24:25000'); $node_b = new Node(); $node_b->setIdHexStr('11111111-1111-4111-8111-111111111101'); $node_b->setUri('tcp://192.168.241.25:25000'); $node_b->setBridgeServer(true); $node_b->setBridgeClient(true); $node_a->update($node_b); $this->assertEquals('11111111-1111-4111-8111-111111111100', $node_a->getIdHexStr()); $this->assertEquals('tcp://192.168.241.24:25000', (string) $node_a->getUri()); $this->assertFalse($node_a->getBridgeServer()); $this->assertFalse($node_a->getBridgeClient()); $this->assertFalse($node_a->getDataChanged()); $node_b->setTimeLastSeen(time()); $node_a->update($node_b); $this->assertEquals('11111111-1111-4111-8111-111111111100', $node_a->getIdHexStr()); $this->assertEquals('tcp://192.168.241.25:25000', (string) $node_a->getUri()); $this->assertTrue($node_a->getBridgeServer()); $this->assertTrue($node_a->getBridgeClient()); $this->assertTrue($node_a->getDataChanged()); }