Wednesday, December 05, 2007

xdebug on centos

these instructions are from : http://tech.nigel.in/

So for those of you who need to install Xdebug, here is what you need to do.
  1. You need to have PHP 5 and PECL installed and working with Apache already.
  2. You need to install PHP's devel package. This is needed for the command phpize to work. Note that you need to have the CentosPlus repository enabled for this. So from the terminal as root run the command:
    yum install php-devel
  3. Next you need to have GCC and GCC C++ compilers installed. The only way to install Xdebug on linux as of time of writing this is to compile the extension yourself. The good thing is that this turns out to be is really easy. Note that you also need Autoconf and Automake packages. Once again from the terminal as root run the command:
    yum install gcc gcc-c++ autoconf automake
  4. Next its time to get the Xdebug package for php itself, and compile and install it. That is as simple as typing the following command as root:
    pecl install Xdebug
  5. Now you need to configure your PHP to load the extension. On Centos, extensions are loaded from a folder most likely to be located at /etc/php.d In this folder you are most likely a bunch of .ini files corresponding to what ever extensions you have installed for use with PHP. You now need to create a file called xdebug.ini here as root. Next add the following lines to the file:
    ; Enable Xdebug extension module
    extension=xdebug.so

    ; Configure the extension [See Xdebug documentation for options to add here]
    xdebug.remote_enable=
    xdebug. .....
  6. Restart Apache with service httpd restart and check the output of phpinfo() to see the if Xdebug is loaded and configured correctly.

Friday, November 30, 2007

replace a whole word with different text

The following examples replaces the whole word unidad with lección in a po file.
perl -p -i.bak -e 's/\bunidad\b/lección/g' wwwroot/app/locale/es_mx/LC_MESSAGES/default.po

the /b is used to match a "word boundary"

Tuesday, November 27, 2007

Behind the pesky HDMI cable

http://www.freedom-to-tinker.com/?p=1005
talks about the DHCP protocol used by HDMI compatible devices, and of course how it can be broken.

Wednesday, October 31, 2007

nginx as a reverse proxy to your web server

I'm experimenting with setting up nginx as a reverse proxy to a web server. The idea is to let nginx handle images, css and forward all php traffic to the regular apache web server.

This is a good article: http://www.guindilla.eu/blog/2006/12/31/deployement-nginx-reverse-proxy-my-network/

Wednesday, October 10, 2007

vpn to a PPTP network from Ubuntu (Feisty 7.04)

I couldn't use the NetworkManager to connect to the vpn. So I used pptpconfig directly for this purpose. Installing this is a little tricky as you have to add a couple of repositories to your /etc/apt/sources.list and the information is a bit scattered across the web.

After installation, you may have to meddle with some settings inside pptpconfig so that the handshake between your client and the vpn server succeeds. My steps may not work for you as it depends on how the peer (other side) is configured as well.

These are the steps I took to both install and connect with pptpconfig. (I have Ubuntu Feisty 7.04 kernel version 2.6.20.3)
---------------------------------------------------------------------------------------------
I enabled universe and used the following on my /etc/apt/sources.list:

deb http://quozl.linux.org.au/pptp/pptpconfig ./

i removed all others referring to the old repository http://quozl.netrek.org

with that, there were no errors shown on subsequent install steps, and pptpconfig was correctly installed.

these are the install steps:

sudo apt-get update
sudo apt-get install pptpconfig

I had to meddle a bit with the tunnel settings to get it to connect. Under 'Encryption' tab in pptpconfig, I enabled the following:

Require Microsoft Point-to-Point Encryption (MPPE)
Refuse 128-bit Encryption
Refuse Stateless Encryption
Refuse to Authenticate with EAP

On the 'Routing' tab, I had to add a route (using Edit Network Routes) to the office network. Since it has a 192.168.10.0 address, I used the following:

Network: 192.168.10.0/24
Name: whatever

I could then successfully start and access hosts within the office network.

Friday, September 07, 2007

Gmail Contact List

I was searching the net for a way to get the gmail contact list and came across libgmail
The demo is pretty sweet, after untarring the package, just type >
python libgmail.py
and it will log you in and present you with your list of gmail folders to choose from.
Since there was no option for getting the contact list, i thought of putting that in by following the general mechanism used for getting the emails. But I was pleasantly surprised to find a getContacts() method in the lib that was not exposed in the demo.

So I added that as the last option to the package, so it looks like this:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
STANDARD_FOLDERS = [U_INBOX_SEARCH, U_STARRED_SEARCH,
U_ALL_SEARCH, U_DRAFTS_SEARCH,
U_SENT_SEARCH, U_SPAM_SEARCH]

// add this right after STANDARD_FOLDERS def (around line 61 in libgmail.py)
CONTACT_LIST = ["contacts"]
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// around line 1609
searches = STANDARD_FOLDERS + ga.getLabelNames() + CONTACT_LIST
name = None
while 1:
try:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// around line 1622
name = None
if name in STANDARD_FOLDERS:
result = ga.getMessagesByFolder(name, True)
elif name not in CONTACT_LIST:
result = ga.getMessagesByLabel(name, True)
else:
contacts = ga.getContacts()
print "No contacts: %d" % contacts.getCount()
for entry in contacts.getAllContacts():
print " %s %s" % (entry.getName(), entry.getEmail())
result = []
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


This will print your contacts when you pick the last option (after the folder names)
I have submitted the change to libgmail folks - hope they put it in the official package.

There is also an alternate hack to get some script that has your contacts if you're already logged in. Just hit this url: http://video.google.com/data/contacts?out=js&max=500&psort=Affinity courtsey Garett Rogers.

Thursday, September 06, 2007

installing memcached on Ubuntu

Dependency:
1. get libevent src package libevent-1.3d.tar.gz from http://www.monkey.org/~provos/libevent
2. untar it - tar xvzf libevent-1.3d.tar.gz
3. build it by running these 2 commands:
./configure
make
4. install it by becoming root and running this command: (be sure to be in the same directory where the package was un-tarred)
make install

Memcached (the daemon):
1. get memcached from http://www.danga.com/memcached/
2. untar it - tar xvzf memcached-1.2.2.tar.gz
3. build it by running these 2 commands:
./configure
make
4. install it by becoming root and running this command: (be sure to be in the same directory where the package was un-tarred)
make install

Starting the daemon:
1. export LD_LIBRARY_PATH=/usr/local/lib
2. memcached -d -u root

Memcache (the client for php):
1. install pear package manager:
become root and run: apt-get install php-pear
2. as root, make a symlink as follows: (replace php5 with php4 if you're using php4)
ln -s /usr/include/php5 /usr/include/php
3. as root run this comand to install the client:
pecl install Memcache
4. edit your php.ini and add extension=memcache.so under extensions
5. restart apache

Use the cache in your php code:
$memcache = memcache_connect('localhost', 11211);
if ($memcache) {
$memcache->set("str_key", "String to store in memcached");
$memcache->set("num_key", 123);

$object = new StdClass;
$object->attribute = 'test';
$memcache->set("obj_key", $object);

$array = Array('assoc'=>123, 345, 567);
$memcache->set("arr_key", $array);

pr($memcache->get('str_key'));
var_dump($memcache->get('num_key'));
var_dump($memcache->get('obj_key'));
}
else {
echo "Connection to memcached failed";
}

Thursday, August 23, 2007

PHP large file uploads

There are several upload limits you need to worry about in PHP. They are configurable in the php.ini file. The post_max_size is devious, as if a user uploads an image larger than this size, php will transfer no POST data to your script. If you look in the php log (generally set to /var/log/messages) you will see a line like this:

POST Content-Length of 66605360 bytes exceeds the limit of 8388608 bytes in Unknown on line 0

http://p2p.wrox.com/topic.asp?TOPIC_ID=23740 describes how to signal an error to the user, in this case.

There is an added complication if you use cake. Normally in cake, the same controller/action is used for both rendering the form and on form submit. The action identifies whether it should render the form or act on the submit based on the form data. If the form data is available it processes it, else it will pass back the form.

Since the only way we can figure out that the upload didn't work is by checking if the POST data is empty, we can't use this design for our controller/action in cake. What we could do is use different actions for rendering the form and submitting it. In the action for submit, we can check $this->data and alert the user if that is empty.

Here are the 2 example actions (file : app/controllers/profiles_controller.php)

// This function was written as a work-around for detecting failures in large POST
// requests - if the POST data is bigger than the php ini setting 'post_max_size',
// php will not transfer any POST data to the controller action, but if we use the same
// controller action for rendering the form as well as on form submit, we can't
// differentiate between the two.
function basics() {
if (!$this->data) {
$this->Session->setFlash("Couldn't upload the image, please choose a smaller image");
}
else {
$this->basic();
}
$this->redirect(array('controller'=>'profiles', 'action'=>'basic'), null, true);
}

function basic() {

// regular logic follows ...

}


Make sure the form app/views/profiles/basic.ctp directs the action to /profile/basics) :

create('User', array('type' => 'post', 'enctype' => 'multipart/form-data', 'url'=>'/profiles/basics')); ?>

Thursday, August 02, 2007

analyzing browser traffic


Today I played around with tcpdump/wireshark/curl to analyze/replay some HTTP traffic sent by my browser to usps - in particular I was analyzing the form data that was submitted in their 'tracking confirmation' service.

I first set tcpdump on the desktop to capture traffic going to port 80, and then hit the 'submit' button on the tracking service page on usps. After I got the data from the service, I quit from tcpdump (Ctrl+C) and then looked at the generated raw dump (file) with wireshark.



Wireshark showed me the post data used in the form, and I used curl to replay the data back to the usps web server, and it returned me the html including my delivery confirmation data.

Since the tracking codes seem rather sequential, one can imagine an attack where a script runs many requests against the usps server and obtains a mega list of information about package delivery.

Here are the steps:
1. run tcpdump on the desktop:
tcpdump -a -x -i eth0 tcp dst port 80 -s 1024 -w /home/user/tcp.dump
2. enter the tracking number and hit 'Go' button at http://trkcnfrm1.smi.usps.com
3. after the browser has retrieved the data, quit tcpdump (Ctrl+C) on the command line
4. analyze the raw file (/home/user/tcp.dump) using wireshark
5. look for the HTTP packets, on one you will see the post data that looks like this:
origTrackNum=0307+0020+0000+8347+7000&Go+to+Track+and+Confirm+Label+%2F+Receipt+Number+Page.x=19&Go+to+Track+and+Confirm+Label+%2F+Receipt+Number+Page.y=7&Go+to+Track+and+Confirm+Label+%2F+Receipt+Number+Page=Go

6. to replay the data, run curl with this data as post data against the host found in the HTTP header (in wireshark) as follows (don't forget to enclose the post data within quotes):

curl -d 'origTrackNum=0307+0020+0000+8347+7000&Go+to+Track+and+Confirm+Label+%2F+Receipt+Number+Page.x=19&Go+to+Track+and+Confirm+Label+%2F+Receipt+Number+Page.y=7&Go+to+Track+and+Confirm+Label+%2F+Receipt+Number+Page=Go' http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do

7. observe the html that the server returns (which has the delivery confirmation details)

Sunday, March 04, 2007

WRT54GL router looses MAC address upon reboot?

My WRT54GL router had stopped working today morning and I had to restart it. After that I didn't get the DNS servers and as a result couldn't connect to the Internet.

I have to clone my PC's MAC to the router so that the cable company allows me access to the Internet. Upon accessing the router admin page, I realized that this setting had reverted. Once I cloned the MAC again, I could get a DNS server and connect to the Internet.

I was surprised by this behavior - I know the router has problems under heavy traffic (probably that is why it stopped working in the first place) but I would have assumed that the settings were in some NVRAM and was safe from poer cycles.

At some point I should try the open source firmware for this router. Since it has a Linux kernel released under GPL, there is a lot of cool stuff that can be done to improve it.

Tuesday, January 30, 2007

Linux system calls - how they work

Very nice article here - by Alessandro Rubini

Thursday, January 18, 2007

the simplest Linux kernel module

I just wrote the simplest possible kernel module. Here it is (hello_world.c):

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE ("GPL");

static int __init hello (void) {
printk (KERN_ALERT "Hello World!\n");
return 0;
}

static void goodbye (void) {
printk (KERN_ALERT "Good Bye!\n");
}

module_init(hello);
module_exit(goodbye);

This is taken from the Network Security Tools, excellent book for hackers. You can build the module by 1) creating a Makefile with this line: obj-m +=hello_world.o
2) running make -C /usr/src/linux-`uname -r` SUBDIRS=$PWD modules

The module will be called hello_world.ko and you can load it by becoming root and doing

insmod ./hello_world.ko

This should print "Hello World" if you're doing this from a console (not X), but if you're using X, you should see this message logged in /var/log/messages

You can unload the module by doing (as root)

rmmod hello_world

Again, if you're on X, the "good bye" message will be in /var/log/messages
Now I just have to find the time to get a proper kdbg patch...