*/ class ParTCP_Core_Messages { static function handle_help_request( $message, $receipt ){ global $MtdManager; $receipt->set( 'Message-Type', 'help' ); if ( ! $message->get('Help-Topic') ){ $topics = $MtdManager->get_mtd_list(); if ( empty( $topics ) ){ $receipt->set( 'Help-Content', _('No message type definitions found') ); return $receipt->dump( TRUE ); } sort( $topics ); $receipt->set( 'Help-Content', $topics ); return $receipt->dump( TRUE ); } $receipt->set( 'Help-Topic', $message->get('Help-Topic') ); $mtd = $MtdManager->get_mtd( $message->get('Help-Topic') ); $receipt->set( 'Help-Content', $mtd ?: _('Sorry, there is no help for that topic') ); return $receipt->dump( TRUE ); } static function handle_ping( $message, $receipt ){ $message->get_signature_status(); $receipt->set( 'Message-Type', 'echo' ); $receipt->set( 'Verification-Result', $message->signatureStatusMessage ); if ( $message->is_encrypted('Decryption-Request') ){ $receipt->set( "Decryption-Result", $message->get('Decryption-Request') ?? FALSE ); } if ( $message->get('Encryption-Request') ){ $receipt->set( "Encryption-Result", $message->get('Encryption-Request'), TRUE ); } $receipt->set_public_key(); return $receipt->dump( TRUE ); } static function handle_envelope( $message, $receipt ){ global $MtdManager, $ServerData; $content = $message->get('Content'); if ( substr( $content, -4 ) == "\n---" ){ $content = substr( $content, 0, -4 ); } $localId = new ParTCP_Private_Identity( $ServerData['name'] ); foreach ( explode( "\n---\n", $content ) as $part ){ if ( trim( $part ) == '' ){ continue; } $innerMessage = new ParTCP_Incoming_Message( $part ); $id = $innerMessage->get('From'); $remoteId = new ParTCP_Public_Identity( $id ? $id : '' ); if ( empty( $remoteId->pubKey ) && $key = $innerMessage->get('Public-Key') ){ $remoteId->pubKey = $key; } $innerReceipt = new ParTCP_Outgoing_Message( $remoteId, $localId ); if ( ! empty( $innerMessage->parseError ) ){ $innerReceipt->set_rejection( 10, _('Message could not be parsed') ); $result[] = $innerReceipt->dump( TRUE ); continue; } $innerReceipt->set_date(); $innerReceipt->set( 'Message-Type', 'receipt' ); $innerReceipt->set( 'Original-Message', $part ); if ( ! $innerMessage->get('Message-Type') ){ $innerReceipt->set_rejection( 11, _('Message-Type header is missing') ); $result[] = $innerReceipt->dump( TRUE ); continue; } $mtd = $MtdManager->get_mtd( $innerMessage->get('Message-Type') ); if ( empty( $mtd['Name'] ) || $mtd['Type'] != 'request' ){ $innerReceipt->set_rejection( 12, sprintf( _('Unknown message type \'%s\''), $innerMessage->get('Message-Type') ) ); $result[] = $innerReceipt->dump( TRUE ); continue; } if ( ! empty( $MtdManager->lastError ) ){ ptcp_error( sprintf( _('MTD for %s could not be parsed'), $innerMessage->get('Message-Type') ) . ":\n{$MtdManager->lastError}" ); } if ( ! $innerMessage->validate_structure( $mtd ) ){ $innerReceipt->set_rejection( 13, _('Invalid message structure') . ":\n" . implode( "\n", $innerMessage->validationResult ) ); $result[] = $innerReceipt->dump( TRUE ); continue; } $innerResult = ptcp_handle_message( $innerMessage, $innerReceipt ); if ( $innerResult === FALSE ){ ptcp_error( sprintf( _('No message handler found for \'%s\''), $innerMessage->get('Message-Type') ) ); } $result[] = $innerResult; } $receipt->set( 'Message-Type', 'envelope' ); $receipt->set( 'Original-Message', NULL ); $receipt->set( 'Content', implode( "\n---\n", $result ), $message->is_encrypted('Content') && $message->get('From') ); return $receipt->dump( TRUE ); } static function handle_participant_details_request( $message, $receipt ){ global $ServerData; list ( $ptcpId, $server ) = explode( '@', $message->get('Participant-Id') ) + [ '', '' ]; if ( $server != '' && $server != $ServerData['name'] ){ $receipt->set_rejection( 41, _('Participant not hosted on this machine') ); return $receipt->dump( TRUE ); } $info = ptcp_get_id_data( $ptcpId, $message ); if ( ! $info ){ $receipt->set_rejection( 42, sprintf( _('Unknown participant %s'), $ptcpId ) ); return $receipt->dump( TRUE ); } $info['credential'] = empty( $info['credential'] ) ? NULL : '*****'; if ( $message->get_signature_status() ){ $attributes = $message->get('Attributes'); $encrypt = $message->get('Encryption'); if ( $attributes && ! empty( $info['attributes'] ) ){ $info['attributes'] = array_intersect_key( $info['attributes'], array_flip( $attributes ) ); } $encrypt = is_null( $encrypt ) ? TRUE : (bool) $encrypt; $receipt->set( 'Participant-Data', $info, $encrypt ); } else { unset( $info['attributes'] ); $receipt->set( 'Participant-Data', $info ); } return $receipt->dump( TRUE ); } static function handle_key_list_request( $message, $receipt ){ global $ServerData; $ptcpIds = $message->get('Participants'); if ( count( $ptcpIds ) > 999 ){ $receipt->set_rejection( 22, _('Maximum number of participants exceeded') ); return $receipt->dump( TRUE ); } $result = []; foreach ( $ptcpIds as $ptcpId ){ $identity = new ParTCP_Public_Identity( $ptcpId ); $result[] = [ 'id' => $ptcpId, 'public_key' => $identity->pubKey ]; } $receipt->set('Original-Message'); $receipt->set( 'Message-Type', 'key-list' ); $receipt->set( 'Keys', $result ); return $receipt->dump( TRUE ); } static function handle_list_request( $message, $receipt ){ global $FileSystem; $path = $message->get('Path'); if ( ! $FileSystem->exists( $path ) ){ $receipt->set_rejection( 41, _('Path not found') ); return $receipt->dump( TRUE ); } $listing = $FileSystem->get_listing( $path, '[^_]*' ); $receipt->set( 'Message-Type', 'listing' ); $receipt->set( 'Listing', is_array( $listing ) ? array_values( $listing ) : [] ); return $receipt->dump( TRUE ); } } // end of file core_messages.class.php