Saturday, December 10, 2011

Chrome Socks Proxy using SSH Tunnel

If you’re familiar with using a SOCKS proxy while browsing the internet you may have found out that Chrome will not work with a SOCKS5 proxy such as created when you create a SSH tunnel.

This is because chrome assumes the SOCKS proxy is a SOCKS4 proxy when it is SOCKS5.

A workaround is to have chrome read the proxy configuration from a script.
The configuration script is a javascript file with a function called FindProxyForUrl() that will be called for every HTTP URL to proxy.
Here is an example:


/**
* .pac files are for automated proxy configuration
* This is a fix for chrome to use SOCKS5 as it assumes SOCKS4
*/
function FindProxyForURL(url, host)
{
// no proxy for localhost
if (host.match('localhost') return false;
// proxy for other hosts
return "SOCKS5 localhost:8111";
}


Make sure your port number is the port that the socks proxy is bound to.

Save this script as ssh-tunnel.pac or similar and in chrome go to:
Options -> Under the Hood -> Network -> Change Proxy Settings

Chrome uses the same network settings as IE. So you will see the system window open and choose:
LAN settings -> Use Automatic Configuration Script

Enter the path to the ssh-tunnel.pac file you created.
Now reload the webpage in Chrome.

Creating an SSH tunnel.
If you’re not familiar with creating an SSH Socks5 proxy visit:
Windows SSH as Proxy
Linux SSH as Proxy


Tuesday, December 6, 2011

PHP Command Line Telnet Client

A while ago I wrote a single line PHP Command line client.

while (1) {  fputs(STDOUT, "\n\-PHP$ "); eval(trim(fgets(STDIN))); }

Recently I needed to test an XMPP server and found out that Windows7 does not have telnet enabled by default. Usually I'd just use putty as it supports telnet also but wondered if I could just do this from the command line via PHP. Well here it is, a PHP command line telnet client.

echo "PHP Telnet Client. (c) 2011 Fiji Web Design, http://www.fijiwebdesign.com.\n";

$opts = getopt("h:p:") or die("Invalid options. Please supply -h [host] -p [port]");

$host = $opts['h'];
$port = $opts['p'];

$fp = fsockopen($host, $port) or die("Could not connect to host ($host) on port ($port)");
echo "Connected to server...\n";

stream_set_blocking($fp, 0);

while (1) {

  $input = (fgets(STDIN));
  fwrite($fp, $input) or die('Could not write to server');
  sleep(1); // let server respond

  $out = '';
  while($buf = fread($fp, 2028)) {
    $out .= $buf;
  }

  if ($out != '') echo $out;

}


Now that isn't one line like the PHP command line client. Also, if you are on windows and a version of PHP lower then 5.3, you will not have the getopt() function. To solve this here is a substitute for getopt().

if (!function_exists('getopt')) {

  function getopt($opts) {
      $argv = $_SERVER["argv"];
      $result = false;
      $opts_array = explode(':', $opts);
      foreach($opts_array as $opt) {
          $key = array_search('-' . $opt, $argv);
          if($key && !in_array($argv[$key+1], $opts_array)) {
              $result[$opt] = trim($argv[$key+1]);
          } elseif($key) {
              $result[$opt] = '';
          }
      }
      return $result;
  }

}

Save the PHP code to a file, I call it telnet.php. Then open the shell and navigate to the directory which has telnet.php and type in:

php telnet.php -h [hostname] -p [port]

For example:

php telnet.php -h google.com -p 80

This will open a connection to google.com on the http port. Then you can type in your HTTP headers:

GET / HTTP/1.1
HOST: google.com

Then press enter twice, because HTTP requires that you send a newline to terminate the HTTP headers. Google.com should respond with the headers and HTML of the Google website.

You can telnet into any listening TCP port so for instance you can test XMPP servers.

php telnet.php -h talk.google.com -p 5222

Then send your XMPP stanzas.

Or even telnet into an email server and send or retrieve emails.

Notes


The socket connection to the server your are telneting to is currently non-blocking while the read from STDIN is currently blocking. This causes the response from the server to not show until you hit enter (send \n) a few times. It would be better design to have both streams non-blocking and do a socket_select() call but the current works for now and does not require socket_select() support which I believe requires php built with sockets support. The current implementation should work without that support but does use up a lot of CPU with the while(1) loop.

Sending email from PHP on Windows

I'm assuming you've installed Xampp or WAMP on your local windows machine. If not please visit the XAMPP website. WAMP and XAMPP will install the full windows equivalent of the LAMP (Linux Apache MySQL PHP/Perl/Python) stack on your Windows Machine, and offer a GUI to manage it. Here I'll talk about sending email from windows specifically on XAMPP, but you can follow this for WAMP or your own PHP setup.

I'm also assuming you're trying to send email through the PHP function "mail()".

Unlike Linux, Windows is not distributed with a default mail transfer agent (MTA). Linux flavors usually come with sendmail, which acts as a local MTA.

In order to have PHP send email, your windows machine should be able to send email, and have PHP configured to send email through it. So first you need to get your machine to send email.

You can either install an MTA locally (not recommended since sending emails is a complicated by spam detection mechanisms built into the protocol).
http://www.google.com/Top/Computers/Software/Internet/Servers/Mail/
http://en.wikipedia.org/wiki/List_of_mail_servers

Or use a free MTA such as hotmail.com or gmail.com. You need an account.

To use a free MTA, you need to specify the MTA host, port, user and password. Luckily there are also sendmail like programs for windows and one is included with Xampp that makes this easy.

You will just need to configure PHP to use the sendmail binary provided by Xampp, to send emails. To do this edit the PHP configuration file, php.ini. You can find this in xampp by opening the control panel, clicking "explore" and going to the folder "php". The full path should be something like:

c:/xampp/php/php.ini

Look for:
;sendmail_path = "\"C:\xampp\sendmail\sendmail.exe\" -t"

and remove the ";" from the beginning of that line, to enable that configuration directive.

Now your PHP is configured to use the sendmail program that comes with Xampp for win.

You now need to configure your sendmail program to send email to your SMTP server.

So open up the sendmail.ini in the "sendmail" folder.
c:\xampp\sendmail\sendmail.ini

Create a new account configuration. Example for gmail:

# Gmail example
account Gmail
tls on
tls_certcheck off
host smtp.gmail.com
from myuser@gmail.com
auth on
user myuser@gmail.com
password mypassword

Substitute myuser and mypassword for your details.

Now you need to make this account the default by editing the last line in the file to:

# Set a default account
account default : Gmail

You will then need to restart the apache service. You can do this from the Xampp control panel. (stop/start). This reloads the configuration for PHP.

Now you should be able to send email.