*/ function ptcp_error( $text ){ global $PartcpVersion, $ServerData; if ( version_compare( $PartcpVersion, '1.0', '<' ) ){ header( $_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error' ); die( $text ); } $lines[] = "From: {$ServerData['name']}"; $lines[] = 'Message-Type: failure-notice'; $lines[] = "Failure-Description: {$text}"; die( implode( "\n", $lines ) ); } $startTime = microtime( TRUE ); include 'initialize.php'; header('Content-Type: text/plain'); // Throw error, if maintenance mode is active if ( ! empty( $ServerData['maintenance_mode'] ) ){ ptcp_error( _('Maintenance mode is active') ); } // Handle special use cases if ( isset( $argv[1] ) && $argv[1] == 'cron' && posix_geteuid() == 0 && empty( $ServerData['maintenance_mode'] ) ){ // Execute cron tasks, ensure that no other cron process runs in parallel $sem = sem_get( 230608, 1 ); if ( ! $sem || ! sem_acquire( $sem, TRUE ) ){ exit; } foreach ( $ServerData['modules'] as $module ){ $path = "{$BaseDir}/modules/{$module}/cron.php"; if ( file_exists( $path ) ){ include $path; } } sem_release( $sem ); exit; } elseif ( empty( $_POST['message'] ) ){ $_POST['message'] = file_get_contents('php://input'); if ( empty( $_POST['message'] ) ){ // Nothing to process, show contents of this script file readfile( __FILE__ ); exit; } } // Prepare processing $Receipt = new ParTCP_Outgoing_Message( NULL, $localId ); $Receipt->set_date(); $Receipt->set( 'Original-Message', $_POST['message'] ); $Message = new ParTCP_Incoming_Message( $_POST['message'] ); if ( ! empty( $Message->parseError ) ){ $Receipt->set_rejection( 10, _('Message could not be parsed') . ":\n" . $Message->parseError ); die( $Receipt->dump( TRUE ) ); } $id = $Message->get('From'); $retrievePubKey = ! empty( $id ) && ! empty( $Message->get('Signature') ); $remoteId = new ParTCP_Public_Identity( $id ?: '', $retrievePubKey ); if ( empty( $remoteId->pubKey ) && $key = $Message->get('Public-Key') ){ $remoteId->pubKey = $key; } $Receipt->set_remote_id( $remoteId ); if ( ! empty( $Message->decryptionError ) ){ $Receipt->set_rejection( 10, _('Message could not be decrypted') . ":\n" . $Message->decryptionError ); die( $Receipt->dump( TRUE ) ); } // Process message and deliver receipt if ( ! $Message->get('Message-Type') ){ $Receipt->set_rejection( 11, _('Message-Type header is missing') ); die( $Receipt->dump( TRUE ) ); } $mtd = $MtdManager->get_mtd( $Message->get('Message-Type') ); if ( ! empty( $MtdManager->lastError ) ){ ptcp_error( sprintf( _('MTD for %s could not be parsed'), $Message->get('Message-Type') ) . ":\n{$MtdManager->lastError}" ); } if ( empty( $mtd['Name'] ) || $mtd['Type'] != 'request' ){ $Receipt->set_rejection( 12, sprintf( _('Unknown message type \'%s\''), $Message->get('Message-Type') ) ); die( $Receipt->dump( TRUE ) ); } if ( ! $Message->validate_structure( $mtd ) ){ $Receipt->set_rejection( 13, _('Invalid message structure') . ":\n" . implode( "\n", $Message->validationResult ) ); die( $Receipt->dump( TRUE ) ); } $trust = ! empty( $mtd['Elements']['Signature']['trust_embedded_key'] ) || empty( $Message->get('From') ); if ( $Message->get('Signature') && ! $Message->get_signature_status( $trust ) ){ $Receipt->set_rejection( 71, _('Signature could not be verified') . " - {$Message->signatureStatusMessage}" ); die( $Receipt->dump( TRUE ) ); } if ( ! empty( $Message->decryptionError ) ){ $Receipt->set_rejection( 72, _('Elements could not be decrypted') . ":\n" . $Message->decryptionError ); die( $Receipt->dump( TRUE ) ); } $Receipt->set( 'Message-Type', $mtd['Response'] ?? 'receipt' ); $result = ptcp_handle_message( $Message, $Receipt ); if ( $result === FALSE ){ ptcp_error( sprintf( _('No message handler found for \'%s\''), $Message->get('Message-Type') ) ); } if ( version_compare( $PartcpVersion, '1.0', '<' ) ){ $tmpMsg = yaml_parse( $result ); if ( $tmpMsg['Message-Type'] == 'rejection-notice' ){ header( $_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request' ); } elseif ( $tmpMsg['Message-Type'] == 'failure-notice' ){ header( $_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error' ); } die( $result ); } header( 'X-Elapsed-Time: ' . sprintf( '%.3f ms', 1000 * ( microtime( TRUE ) - $startTime ) ) ); echo $result; // end of file process.php