Telnet Response via PHP Sockets

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • b00x

    Telnet Response via PHP Sockets

    Hi,

    I'm trying to develop a script that I can reuse to run remote commands
    on multiple UNIX servers via telnet. I've tried various php scripts
    after googling for a good 5 or so hours, but found no luck.

    I've created a script (suprisingly) similar to the on found an old post
    from 2001
    (http://groups.google.com/group/php.d...a3bb4ff13e6433)

    function getResponse(&$s ocket) {

    //Reading response
    echo "Read response: ";

    while ($buf = socket_read($so cket, 2048)) {
    //$output .= $buf;
    echo $buf;
    }

    echo $output."\n";

    return $output;
    }

    // Create internet socket
    $socket = socket_create(A F_INET, SOCK_STREAM, SOL_TCP);

    // Set 30 second timeout
    socket_set_opti on($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" =>
    30, "usec" =0));

    // Resolve hostname
    $address = gethostbyname($ host);

    // Attempt connection
    socket_connect( $socket, $address, 23);

    echo "Connected! \n";

    // Send telnet Header 1
    socket_write($s ocket, $header1, strlen($header1 ));
    echo "Sent Header 1\n";
    echo getResponse($so cket);

    //Header 2
    socket_write($s ocket, $header2, strlen($header2 ));
    echo "Sent Header 2\n";
    echo getResponse($so cket);

    // Do more stuff here once its working...

    socket_close($s ocket);
    echo "Socket Closed\n";

    echo $output;


    The problem here, is that it doesn't make it past the first
    socket_read(). I've even tried other methods using fread(), etc.

    The same problem occurring is the response is only 2 characters (of
    which are: ²$), and then the connection and script hang on the read
    statement.

    I've tried running this from a browser, from a command-line, but still
    the same result. The only theory I have left, is that it has something
    to do with the fact i'm running the script from a windows machine,
    rather than a *nix one (This is because of availability issues :().

    Can anybody suggest anything? Has anyone had the same problem? Simply
    some proof that it works under *nix would be great.

    Thanks.

    Regards,
    Corey

    Notes: WinXP.Pro.SP2 - Apache/2.2.2 (Win32) PHP/5.1.4.

  • Bent Stigsen

    #2
    Re: Telnet Response via PHP Sockets

    b00x wrote:
    [snip]
    function getResponse(&$s ocket) {
    >
    //Reading response
    echo "Read response: ";
    >
    while ($buf = socket_read($so cket, 2048)) {
    //$output .= $buf;
    echo $buf;
    }
    [snip]
    // Send telnet Header 1
    socket_write($s ocket, $header1, strlen($header1 ));
    echo "Sent Header 1\n";
    echo getResponse($so cket);
    >
    //Header 2
    socket_write($s ocket, $header2, strlen($header2 ));
    echo "Sent Header 2\n";
    echo getResponse($so cket);
    [snip]
    The problem here, is that it doesn't make it past the first
    socket_read(). I've even tried other methods using fread(), etc.
    You are not exactly following protocol. Just sending some generic chunks of
    commands with intermittent reads, might actually work, but I doubt it is
    portable across different telnet servers. Note that telnet don't use
    headers like http. It is a ping pong sequence of commands exchanged to
    negotiate which options to use. One negotiation may lead to another, e.g.
    if you say you are willing to tell what type of terminal you got, then the
    server may subsequently ask for it. Nonetheless, it is still possible to do
    what you do, but it is a bit clunky. I assume you didn't construct the
    content of "$header1" and "$header2", so you may need to verify that all
    the wills, wonts, dos and don'ts match how your telnet-server behaves.

    Your present "getRespons e" will not work. The break-condition for the
    while-loop will only happen in case of timeout, socket error or if the
    connection is closed in the remote end. When there is no data ready on a
    (open) socket, the socket_read will wait until there is, unless it is set
    to non-blocking, but you probably don't want that.

    The same problem occurring is the response is only 2 characters (of
    which are: ²$), and then the connection and script hang on the read
    statement.
    You will have to deal with it, as it is normal behavior. I am not sure about
    the 2 characters though, as I would expect a character of value 255 (IAC)
    to be the first, but the "garbage" you are going to see in the beginning,
    would presumably be negotiation commands as described in the telnet
    protocol, either requests or responses to commands you send.

    About the hang. As it ("getRespons e") is, it will allways hang. In your
    case, the short answer is simply not to read unless you expect something,
    but I suspect that the only safe way to do that is to send, read and
    respond in a proper manner according to protocol, until the server is
    satisfied and sends you the (expected) login-prompt, which would be a cue
    for you to stop reading. When you send username, you can expect a
    password-prompt. When you send the correct password you can expect a
    shell-prompt. As long as you are in sync with what is happening, you
    shouldn't find yourself unnecessarily stuck on a read.

    Things like setting the non-block option or using a short timeout can be
    useful, but only for the purpose to not hang on a read, is messy. Say if
    you didn't get something on the first read and have to read again because
    you really was expecting something, perhaps sleep a while and then try once
    again because you really really was expecting something, ... If you go down
    that road, I think you'll eventually find out that hanging on a read is a
    blessing, not a problem.

    I've tried running this from a browser, from a command-line, but still
    the same result. The only theory I have left, is that it has something
    to do with the fact i'm running the script from a windows machine,
    rather than a *nix one (This is because of availability issues :().
    >
    Can anybody suggest anything? Has anyone had the same problem? Simply
    some proof that it works under *nix would be great.
    PROOF??? O thou of little faith, wherefore didst thou doubt. Behold, for the
    absence of faith in unix brings dire failure. Failure from whence one can
    only cry out "unix, save me!". Praised be unix, its derivatives, and the
    whole internet, hallelujah.
    Well, in other words, I am going to be lazy and simply claim it would work.

    If ssh is available on the servers, you could take a look at the ssh2
    extension for PHP. Nice features and less hassle. There is apparently no
    stable version, but the beta seemed to work fine on Linux(Fedora). I don't
    know how well it works on windows though.
    ref: http://www.php.net/manual/en/ref.ssh2.php


    --
    /Bent

    Comment

    • b00x

      #3
      Re: Telnet Response via PHP Sockets

      Woah!

      That's like the largest response I've ever gotten! Thanks :)

      I think I'll need to spend some time reading the RFC's, rather than
      going off what other people have make in the past, etc. I think most of
      the code I've based this off is for a windows telnet client, or some
      such. In which case, I think I'll look into the further details of Unix
      telnet connections, and SSH aswell. SSH isn't an option (unfortunately)
      for all the servers I need this to work on, but it will have a partial
      role. Maybe I'll do some packet sniffing aswell, and watch the traffic
      and connections to help further understand. Seems my trust in the
      internet's resources has failed me this time - though it still has the
      answer, though hidden more deeply.

      As for nix - your right - ALL HAIL!

      Thanks Bent, I'll be sure to keep this topic updated with progress,
      etc.


      Bent Stigsen wrote:
      b00x wrote:
      [snip]
      function getResponse(&$s ocket) {

      //Reading response
      echo "Read response: ";

      while ($buf = socket_read($so cket, 2048)) {
      //$output .= $buf;
      echo $buf;
      }
      [snip]
      // Send telnet Header 1
      socket_write($s ocket, $header1, strlen($header1 ));
      echo "Sent Header 1\n";
      echo getResponse($so cket);

      //Header 2
      socket_write($s ocket, $header2, strlen($header2 ));
      echo "Sent Header 2\n";
      echo getResponse($so cket);
      [snip]
      The problem here, is that it doesn't make it past the first
      socket_read(). I've even tried other methods using fread(), etc.
      >
      You are not exactly following protocol. Just sending some generic chunks of
      commands with intermittent reads, might actually work, but I doubt it is
      portable across different telnet servers. Note that telnet don't use
      headers like http. It is a ping pong sequence of commands exchanged to
      negotiate which options to use. One negotiation may lead to another, e.g.
      if you say you are willing to tell what type of terminal you got, then the
      server may subsequently ask for it. Nonetheless, it is still possible to do
      what you do, but it is a bit clunky. I assume you didn't construct the
      content of "$header1" and "$header2", so you may need to verify that all
      the wills, wonts, dos and don'ts match how your telnet-server behaves.
      >
      Your present "getRespons e" will not work. The break-condition for the
      while-loop will only happen in case of timeout, socket error or if the
      connection is closed in the remote end. When there is no data ready on a
      (open) socket, the socket_read will wait until there is, unless it is set
      to non-blocking, but you probably don't want that.
      >
      >
      The same problem occurring is the response is only 2 characters (of
      which are: ²$), and then the connection and script hang on the read
      statement.
      >
      You will have to deal with it, as it is normal behavior. I am not sure about
      the 2 characters though, as I would expect a character of value 255 (IAC)
      to be the first, but the "garbage" you are going to see in the beginning,
      would presumably be negotiation commands as described in the telnet
      protocol, either requests or responses to commands you send.
      >
      About the hang. As it ("getRespons e") is, it will allways hang. In your
      case, the short answer is simply not to read unless you expect something,
      but I suspect that the only safe way to do that is to send, read and
      respond in a proper manner according to protocol, until the server is
      satisfied and sends you the (expected) login-prompt, which would be a cue
      for you to stop reading. When you send username, you can expect a
      password-prompt. When you send the correct password you can expect a
      shell-prompt. As long as you are in sync with what is happening, you
      shouldn't find yourself unnecessarily stuck on a read.
      >
      Things like setting the non-block option or using a short timeout can be
      useful, but only for the purpose to not hang on a read, is messy. Say if
      you didn't get something on the first read and have to read again because
      you really was expecting something, perhaps sleep a while and then try once
      again because you really really was expecting something, ... If you go down
      that road, I think you'll eventually find out that hanging on a read is a
      blessing, not a problem.
      >
      >
      I've tried running this from a browser, from a command-line, but still
      the same result. The only theory I have left, is that it has something
      to do with the fact i'm running the script from a windows machine,
      rather than a *nix one (This is because of availability issues :().

      Can anybody suggest anything? Has anyone had the same problem? Simply
      some proof that it works under *nix would be great.
      >
      PROOF??? O thou of little faith, wherefore didst thou doubt. Behold, for the
      absence of faith in unix brings dire failure. Failure from whence one can
      only cry out "unix, save me!". Praised be unix, its derivatives, and the
      whole internet, hallelujah.
      Well, in other words, I am going to be lazy and simply claim it would work.
      >
      If ssh is available on the servers, you could take a look at the ssh2
      extension for PHP. Nice features and less hassle. There is apparently no
      stable version, but the beta seemed to work fine on Linux(Fedora). I don't
      know how well it works on windows though.
      ref: http://www.php.net/manual/en/ref.ssh2.php


      --
      /Bent

      Comment

      Working...