Thursday, November 6, 2008

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.

Friday, October 24, 2008

Upload document in .NET C#

Very simply, there are two parts to this, storing in inside DB and retrieving for display. This program works for C# + MS SQL. Before everything I assume that you created a table inside the database with a field picture with datatype image.

Part I: Storing in Database
a.) setup an input file with the name UploadFile.
<input id="UploadFile" type="file" runat="server">

b.) setup a button with the name btnUpload
<asp:imagebutton id="btnUpload" onclick="btnUpload_Click" runat="server" height="29" width="150" imageurl="images/buttons/upload_long.jpg"></asp:imagebutton>

c.) setup code behide for the button to be
if (Page.IsValid) {
String userId = Session["authenticated_userid"].ToString();
Stream imgStream = UploadFile.PostedFile.InputStream;
int imgLen = UploadFile.PostedFile.ContentLength;
byte[] imgBinaryData = new byte[imgLen];
int n = imgStream.Read(imgBinaryData, 0, imgLen);
DB.userTableAdapter aAdapter = new // you need to set this up in your own DB.xsd

DB.userTableAdapter();
int rowsAffected = aAdapter.UpdatePicture(imgBinaryData, int.Parse(userId));
if (rowsAffected > 0) {

Response.Redirect("home.aspx"); // go back to same page
}
}


Part II: Retrieving stored image from DB
1.) Create a file call getImage.aspx and inside Page Load

protected void Page_Load(object sender, EventArgs e) {
String userId = Session["authenticated_userId"].ToString(); // get your own identified
DB.userTableAdapter aAdapter = new DB.userTableAdapter();
byte [] temp = aAdapter.GetPicture(int.Parse(userId));

if (temp == null) // in case we find nothing in db {
Stream s = File.OpenRead(Server.MapPath("images\\portrait.jpg"));
temp = new byte[s.Length];
s.Read(temp, 0, (int)s.Length);
Response.BinaryWrite(temp);
s.Dispose();
s.Close();
}
Response.BinaryWrite(temp);
}


2.) Wherever you want to show you image, just call the image as per normal
i.e. <img src="http://www.blogger.com/getImage.aspx" />

Done! Enjoy.

ASP.NET (C#) unable to ENTER to submit form

The best way to solve this is to do the following

1. Create a login function. i.e.
protected void login() {
// get database connection
// get variables from form
// check if correct, set session variable, redirect
// else, display error, return to form
}

2. In page load, use the following code:
If (Page.IsPostBack()) {
login();
}

Viola! Weird bug in ASP.NET i read. But yah, Page.IsPostBack fixes it all.