Why is my TCP connection attempt via PHP acting weird?

0

I'm not sure if this is better here or on SO but since the issue isn't in the programming I figured it applies here (or on U&L or on serverfault, but I guess/hope I'm fine on here).

I want to send TCP commands to an instance of telegram-cli from PHP.

Until now I used: shell_exec('echo "msg user#idXXXXXX message" | nc 127.0.0.1 9007'); and it worked fine. But there are variables and user input involved and even though I do quote my variables I think this is bad OPSEC, so instead I want to use PHP's sockets, but here the issues begin.

The TCP server is started under the user "B" on the server. PHP runs as "www-data". Running the above shell_exec works fine, as user www-data. Being logged in as user A and running the command directly in a bash shell works too. Using bare netcat I can also connect to the socket as user A, that's why I think a permission issue isn't the case here. User A is a normal user without special permissions.

My PHP code:

$fp = fsockopen("127.0.0.1", 9007, $errno, $errstr, 5);
fwrite($fp, 'msg user#idXXXX "message"');

What this does is absolutely nothing.
And here comes the reason why I consider this not appropriate on StackOverflow:

If I try to connect to port 9001 (for testing) instead of 9007 (what tg-cli runs on) after running nc -l 9001 as user A, it works perfectly fine and I can see the message PHP should send on the nc output.

Judging from this the issue must be somewhere outside of my short PHP code, but I have no clue where to look. The connection is established but fwrite is not sending anything.

    $fp = fsockopen("127.0.0.1", 9007, $errno, $errstr, 5);
    if(!$fp){
        echo "$errstr ($errno)"; die();
    }else{
        echo "test"; // THIS IS BEING PRINTED
        fwrite($fp, 'msg user#idXXXXX "message"');
        while(!feof($fp)){
            echo fgets($fp);
        }
        fclose($fp);
    }

This is the entire codeblock in question. The test is being printed, the fwrite is being executed (since PHP enters the while loop) but tg-cli receives nothing. The PHP script then is completely stuck in the while-loop (no output!) until I SIGTERM apache2.

Edit: The output of tg-cli in debug mode when I try to send the message:

*** 1538301112.516826 Accepting incoming connection
*** 1538301112.517262 Read from incoming connection

Edit2: For further permissions testing I ran sudo -u www-data echo 'dialog_list' | nc 127.0.0.1 9007 - with success.

Edit3: I also double-checked with base64 that PHP's fwrite sends exactly what it's supposed to send.

Edit4: I can rule out that the issue lays in the response from the server back to PHP as tg-cli reports that it's reading from the TCP connection but it's not processing it. E.g. when i use shell_exec or nc on the shell it reports that it sent a query to Telegram's datacenter after reading from the TCP stream. This is not the case when using my above PHP code.

Edit5: I've also tried to suffix the TCP command with \n, \r or \n\r but again without success. Could it be that I need to end the command with something specific? None of this is needed when using bare nc or shell_exec() though.

confetti

Posted 2018-09-30T09:45:12.457

Reputation: 1 625

Is the missing comma after fwrite($fp a typo in the question itself or in the original code? – user1686 – 2018-09-30T10:28:48.580

@grawity It was a typo. Fixed that and another one too. – confetti – 2018-09-30T10:29:40.587

does PHP have an fflush and have you tried using it after fwrite? – Jonas Schäfer – 2018-09-30T10:58:55.823

@JonasSchäfer It does. I've tried, no change in behaviour. I feel like the issue must lay something else. I sadly can't see the exact message tg-cli receives so maybe there's an issue during transport? I really don't know why nc would work perfect fine then though. – confetti – 2018-09-30T11:07:06.933

No answers