Monday, November 24, 2008

Dumping output of a program

In perl, if you want to do a dump of a program, say SSH. You do the following

system ("SSH 192.168.1.102 1> /dev/null 2> /dev/null");

Basically 1> /dev/null means dump all the output of the program to /dev/null
and 2> /dev/null means dump all the error output to /dev/null

Monday, November 17, 2008

Research on Netstat

I am basically trying to check if there is a vncviewer connecting to a vncserver through SSH.

So my first stop was really to play around with netstat. And I found a very interesting behaviour when vncviewer is connecting to a vncserver through an SSH tunnel.

Setup:

I started port forwarding: SSH -L 10001:localhost:5900
Then. with the command: netstat -t grep

Observations:
1.) When RECV-Q is = 0, it means there is no user activity in SSH
2.) When RECV-Q is > 0, it means there is user activity
3.) When SEND-Q is = 0 or > 1504, it means SSH connection is active and host is alive.
4.) When SEND-Q is = 1504, it means SSH connection is active, but host is dead.

Sunday, November 16, 2008

PHP Session Manipulation

Today on linuxquestion somebody asked something about PHP's session variable. Which I thought was quite interesting. The question goes: "Can we actually manipulate the PHP session information on the server? If so how?"

Well this question actually brings two more questions in my mind instantly:
1.) Is PHP session information stored only on the server?
We can't actually manipulate PHP information that resides on the server, it is just not really possible security wise. But what we can do is manipulate it in such a way that we can resume it even after it dies when garbage collector destroys it.

2.) How is PHP Session stored on the server? On disk or in memory?
The first time you call session_start(), PHP basically generates a new session ID and creates an empty file to store session variables. PHP also sends a cookie back to the client that contains the session ID.

There are a couple of techniques to session resumption.
1.) Cookies - Store session information into cookie as it is being stored on the session variable. That way, when we resume our session after we close the browser window, we can first of all check if there was a cookie set, and if there is, read that cookie information to the session and start.

2.) Database - Store session information into database as it is being stored on the session variable. Similar to the cookie approach, but this is preferred because it is really permanent and it does not rely on the client's cookie function (some client disable cookies on their browser).

3.) Mixture of Cookies + Database. Cookies is faster than database but database is more persistent than a cookie. Therefore, a mixture of this techniques allows for a persistent and fast session resumption.

Saturday, November 15, 2008

Firefox Flex Error

In Flex, when you build files normally, you have to take note of the folder you copied your files from. If you are running into errors about debuggers in firefox, that means you copied the wrong files to the server you are running your program from. You should have copied files from the bin-release folder and not the bin-debug folder.

To build files into your bin-release folder you have to choose the "Build Release" option inside Flex. This will essentailyl ask Flex to build a release for real usage and not for debugging purposes.

Whitespaces in flex

In flex, using textarea with the htmlText property, you will realise that if you have paragraph tags, it will show up correctly but we plenty of whitespaces. You can get around this by setting the condenceWhite property to true. This way, all whitespaces would be removed and the document would look more well-formed like a real html document.

Flex's Error #2048: Security sandbox violation

I was running the flex application within the C:\ path while it was trying to access documents using web services from http://localhost:4076. It immediately threw an error. After much googling I found that the main reason is Flex do not allow a program to access information from outside the domain it was called from.

To get around this problem, you have three choices:
  1. Add a crossdomain.xml file to the server with the data.
  2. Upload your SWF file to the same server as the data service.
  3. Create a proxy on your server that calls the data service, and put your SWF file on the same server as the proxy.

The simplest method is to create a crossdomain.xml file. The instructions are:

A crossdomain.xml file is an XML file that provides a way for a server to indicate that its data and documents are available to SWF files served from certain domains, or from all domains. The crossdomain.xml file must be in the web root of the server that the Flex application is contacting. For more information about configuring crossdomain.xml files, see the technote on the Macromedia website: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_14213.

Tuesday, November 11, 2008

How to check if VNCClient is connecting to VNCServer

I was having the problem of the vncserver having too many 'alive' connections because vncclients were being killed abruptly and there is no build in methodology for vncserver that kills the vncserver if nobody is connecting to it. I was toying around with TCPKeepAlive and stuffs, but that didn't really work out fine.

One of the ways to do so if you have access to both the VNCServer and VNCClient codes is to use the ping-pong approach. In the sense that the VNCClient will constantly contact the VNCServer to tell him that it exist. If it does not for after a predefined time limit, you can take for granted that there is either a network problem of VNCClient is not listening to the server anymore. Building it is really quite simple:

1.) create a program call "vncinform" on the remote server. Basically it receives a request from a unique identifier (i.e. an ip address). and update the timestamp of a file.

2.) modify the vncviwer to call "vncinform" remotely using ssh. For example SSH vncinform 192.168.1.102. This basically tells the host that the host is active by updating the timestamp.

3.) on the end of the vncserver, create a cron job to kill the vncserver session if the timestamp for a particular host is more than a predefined amount of time.

Done!

Monday, November 10, 2008

php.ini file upload size

I was looking around so many tutorials and it kept saying php.ini php.ini php.ini. But where do you get a php.ini file? Well, simple create one yourself, and be happy to know that it is only 2 lines of codes.

I am writing the php.ini file for file upload size. (by default php sets it at 2MB).

So basically these are the steps:
1.) Open Notepad
2.) Type this in:
post_max_size = 10000000
upload_max_filesize = 10000000

10000000 = 10 MB
3.) Save, upload this file to the server, into the folder where your upload script resides.

DONE!

.htaccess won't work with some of the shared hosting companies, so my method is the way to go :)

if you want .htaccess may work for some:
php_value memory_limit 150M
php_value post_max_size 100M
php_value upload_max_filesize 50M
php_value max_execution_time 600

Thursday, November 6, 2008

Collapsing/ Hiding rows in a table

Hiding rows on a table based on a link on a row. Nothing much to talk about, except that this is actually quite an interesting piece of code. Simple but yet complex. Oxymoron i know, but anyhow note that the span tag has an id which corresponds to the row number of the row to height. It is also important to note that there should not be anything other than the value between the span tags. Most things such as styles can be controlled directly using CSS.

<script type="text/javascript">
var hide= true;
function toggleRows(tableId, rowId, tag){
tbl = document.getElementById(tableId);
navispan = document.getElementById(rowId);
var len = tbl.rows.length; if(tag.innerHTML.substring(0,4) == "Show") {
navispan.innerHTML = tag.innerHTML.substring(5); hide= false;
} else {
navispan.innerHTML = "Show " + tag.innerHTML; hide= true;
}
var vStyle = (hide)? "none":"";
tbl.rows[rowId].style.display = vStyle;
}</script>
<style>
.header {
text-align:left; width:100px;
}
.bodyText {
width:150x;
}
</style>
</head>
<body>
Click here to hide/show
<span id="0" onClick='toggleRows("myTable",0, this)' style='cursor:pointer;color:#cc0000'>Aaron</span>
<span id="1" onClick='toggleRows("myTable",1, this)' style='cursor:pointer;color:#cc0000'>Jason</span> <span id="2" onClick='toggleRows("myTable",2, this)' style='cursor:pointer;color:#cc0000'>Adam</span>
<br /><br />

<table id="myTable" style="width:400px; border:0px;">
<tbody>
<tr>
<td class="header"> <span onClick='toggleRows("myTable",0, this)' style='cursor:pointer;color:#cc0000'>Aaron</span> </td>
<td class="bodyText"> This annotation Sucks </td>
<td class="bodyText"> This annotation is good </td>
</tr> <tr>
<td class="header"> <span onClick='toggleRows("myTable",1, this)' style='cursor:pointer;color:#cc0000'>Jason</span> </td>
<td class="bodyText"> </td> <td class="bodyText"> This annotation cannot make it. </td> </tr> <tr>
<td class="header"> <span onClick='toggleRows("myTable",2, this)' style='cursor:pointer;color:#cc0000'>Adam</span> </td>
<td class="bodyText"> I love this phrase </td> <td class="bodyText"> This phrase is dumb. </td> </tr>
</tbody>
</table>

Getting output from a remote program using PERL + SSH

Basically what I was trying to do is establish an ssh connection, get a port that is open on that server, and return it back to the connecting server. What you will need is really two portions of a code, first off, a program on the server that returns the port, it can be as simple as print "PORT=21"; then secondly you need the code shown below that calls the remote program above:

my @remote_stdout = split("\n", `ssh $user\@$host '"<cmd>"'`);
if($? != 0) {
warn ":ERROR: could not establish ssh connection with '$host' host";
} else {
my $last_stdout_line = pop @remote_stdout;
my $remote_command_result;
if(defined $last_stdout_line and ($last_stdout_line =~ m/^PORT=(\d+)$/)) {
$remote_command_result = $1;
}
if(defined $remote_command_result) {
warn ":Port Found: $remote_command_result";
} else {
warn ":ERROR: no results";
}
}

Establish SSH Tunnel and run VNCViewer using Perl

Using perl, I was trying to run SSH Tunnel first and then run VNCViewer through this tunnel. Of course it was not so simple as to just doing the following in perl:

#!/usr/bin/perl
system("ssh -l -L 10000:localhost:5901 ");
system("vncviewer localhost:10000");

If you try to do the above, it won't work! This is because the process gets stuck on the first line while in SSH. Basically if the tunnel is active, it can't possibly run the next command which is to launch vncviewer. But if the tunnel is terminated, so that we can run vncviewer, vncviewer won't work because there is no more binding on port 10000.

We need to use perls' build in fork function. Similar to running programs using the trailing & command in C. My implementation (thanks to estabroo from LQ) is as follows:

$pid = fork();
if ($pid == 0) {
system("ssh -l -L 10000:localhost:5901 ");
exit(0);
} elsif ($pid > 0) {
sleep(5);
system("vncviewer localhost:10000");
} else {
print "fork failed\n";
}

Basically what this does is, fork the process, execute SSH, wait for login and exit, sleep for 5 seconds, run the child process vncviewer. Done :)

Running VNCViewer using SSH Port Fowarding

I would like to start an SSH tunnel and then run vncviewer to connect the port. But as we all know, vncviewer pretty much sends everything in clear over the network, we have to introduce some 'security' to it. One common way is using SSH. In linux, its as simple as just two lines:

ssh -l -L 10000:localhost:5901
vncviewer localhost:10000
*in order for this work, you need to have vncserver already setup and serving on port 5901.

That's it! What it is tryinng to do is. Listen locally on port 10000 and forward any incoming connection to port 5901 of the remotehost. Localhost here pretty much refers to the remote host. It does not make any difference if you were to run the command as, it should still work:

ssh -l -L 10000::5901

Done. I will be posting shortly on how I did this in perl.

Perl script for vncpasswd

VNCpasswd is a program used by vncserver's to set the authentication cookie (what we call a password) using the rfbauthentication protocol. The main reason why you want to specify a password file for a VNC server connection is really because you don't want anybody else to be able to connect to the VNC port and have access to control your screen.

But the problem with VNCpasswd is that it requires users to input by prompt and I would like to automate this process of password encryption using VNCpasswd. How do we do it then? We have to create a perl script wrapper around the xvnc.

VNCpasswd itself was written using C++. I downloaded the source codes of VNCpasswd using the following command:


apt-get source xvnc4viewer

Basically, inside the unix/ folder, you can find all source codes for vncpasswd, vncviewer, vnconnect etc. Looking into vncpasswd, you will realise vncpasswd use a few common functions inside the common/rfb folder, namely 'd3des.c' and 'Password.cxx'. Looking into the codes of Password.cxx, you will realise that the vncpasswd basically uses DES with a plain text key of {23, 82, 107, 6, 35, 78, 88, 7}.

Logically, I thought that it was easy to do so. And I should be able to to technically perform the same operation using the built-in Perl DES library. My code for this were as follows:

#!/usr/bin/perl
use Crypt::DES;
my $key = pack ('C8', 23,82,107,6,35,78,88,7);
my $cipher = Crypt::DES->new ($key);
$ciphertext = $cipher-$gt;encrypt('password');
$plaintext = $cipher-$gt;decrypt($ciphertext);
print "$plaintext is encrypted to become $ciphertext";

Simple enough, but the above codes didn't somehow match the codes that were given when i simply executte `vncpasswd password`. After much playing around, I decided to drop this approach. I am not sure if vncpasswd uses triple DES instead, either that or they created their own version of DES with slight differences.

Anyhow, I moved on and found that x11vnc actually allows you to create password using the -storepasswd option. In the following format:
x11vnc -storepassword

Viola! Problem 'technically' solved. Well, I can't create a wrapper for this. But since x11vnc solves my problem, why should I bother writting another perl script that performs the same functions? I rather spend my time optimizing my codes..

Make your screen stay when you click popup

When we use javascript to start a popup for example, most of the time we do so by executing the following script:

<a href="#" onclick="javascript:win.. ">Click</a>

The reason why we have # here is because we want the cursor to show up so that on mouse over, the user knows that the link is 'clickable'. But by doing this, it will cause the page to reload. So how do we show the cursor but yet not cause the page to reload without.

The anwer is, don't use #, use CSS.

<p onClick="javascript:win.." style='cursor:pointer'>Click</p>

Problem Solve!

Saturday, November 1, 2008

Javascript Popup with Custom Controls in GridView ASP.NET

Prior to the earlier posting which describes how to use a custom control, the following codes describe how to use a custom control to launch a javascript function. In this case, to start a popup window by clicking on a link from the gridview table.

The codes are as follows:
<asp:TemplateField>
<HeaderTemplate>Manage</HeaderTemplate>
<ItemTemplate>
<asp:HyperLink NavigateUrl='<%# DataBinder.Eval(Container,"DataItem.class_id", "javascript:window.open(\"classstudents.aspx?id={0}\",\"mywindow\",\"menubar=1,resizable=1,width=400,height=500\");") %>' Text="Manage" runat="server" Target="myBuffer"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>

The steps as usual are:
1. Create the objectdatasource
2. Creat the grdiview
3. Bind the objectdatasource to the gridview
4. Insert a TemplateColumn (when you select the grid and click edit column)
5. The templatecolumn should contain something liek the code above.
6. Done!

Take note that for javascript to work, it should be contained with a single quote. And if you need to display the quotes in javascript within asp.net, the escape character for asp.net C# is a backslash /

ASP.NET Custom Controls inside Gridview

The gridview is one of asp.net's most versatile function. Best used if you need to perform operations like create read, updated, remove (CRUD). Datalist would be good for CRUD as well. Simply because its as easy as just clicking around with minimal programming involved. Rule of the thumb is:

CRUD: gridview, datalist
CRUD: detailsview (used really for 1 page paging purpsoe)
CR: listview, repeater

But adding a custom control i.e. placing your own dropdownlist inside a gridview can be tricky. Its not as simple as just binding an object as per normal. The codes are as follows:

<asp:TemplateField>
<HeaderTemplate>Active?</HeaderTemplate>

<ItemTemplate>
<asp:Label id="lblClass" runat="server" Text='<%# returnYesNoValue(DataBinder.Eval(Container,"DataItem.active", "{0}")) %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList id="ddlActive" SelectedValue='<%# Bind("active") %>' runat="server">
<asp:ListItem Value="1">Yes</asp:ListItem>
<asp:ListItem Value="0">No</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<HeaderStyle BorderStyle="None" />
<ItemStyle BorderStyle="None" />
</asp:TemplateField>

Steps:
1. Create an objectdatasource and link it with the a query from an XSD datafile.
2. Create a gridview and link it with the objectdatasource
3. Insert bound fileds and then insert the template fields
4. Go into the HTML code and then key in the codes above for the template area
5. As you can see its 'label' for viewmode and 'dropdownlist' for editmode
6. Make sure you bind the records with the value from db, and everything should work automatically.