CGI Programming Project: Dynamic Webpage by CGI

This programming project is intended for readers to practice CGI programming. It combines remote file operations, CGI programming and server-side dynamic Web pages into a single package. The organization of the project is as follows.

(1). User website: On the cs360.eecs.wsu.edu server machine, each user has an account for login. The user’s home directory has apublic_html directory containing an index.html file, which can be accessed from a Web browser on the Internet by the URL

http://cs360.eecs.wsu.edu/~username

The following shows the index.html file of the user kcw.

<!——— index.html file———— >

<html>

<body bgcolor=”#00FFFF”

<H1>Welcome to KCW’s Web Page</H1><P>

<img src=”kcw.jpg” width=100><P>

<FORM METHOD=”POST” ACTION=\

“http://cs360.eecs.wsu.edu/~kcw/cgi-bin/mycgi.bin”>

Enter command: <INPUT NAME=”command”> (mkdir|rmdir|rm|cat|cp|ls)<P>

Enter filename1: <INPUT NAME=”filename1″> <P>

Enter filename2: <INPUT NAME=”filename2″> <P>

Submit command: <INPUT TYPE=”submit” VALUE=”Click to Submit”> <P>

</FORM>

</body>

</html>

Figure 13.15 shows the Web page corresponding to the above index.html file.

Fig. 13.15 HTML form page

(2). HTML Form: The index.html file contains a HTML form.

<FORM METHOD=”POST” ACTION=\

“http://cs360.eecs.wsu.edu/~kcw/cgi-bin/mycgi.bin”>

Enter command: <INPUT NAME=”command”> (mkdir|rmdir|rm|cat|cp|ls)<P>

Enter filename1: <INPUT NAME=”filename1″> <P>

Enter filename2: <INPUT NAME=”filename2″> <P>

Submit command: <INPUT TYPE=”submit” VALUE=”Click to Submit”> <P>

</FORM>

In a HTML form, METHOD specifies how to submit the form inputs, ACTION specifies the Web server and the CGI program to be executed by the Web server. There are two kinds of form submission methods. In the GET method, user inputs are included in the submitted URL, which makes them directly visible and the amount of input data is also limited. For these reasons, GET method is rarely used. In the POST method, user inputs are (URL) encoded and transmitted via data streams, which are more secure and the amount of input data is also unlimited. Therefore, most HTML forms use the POST method. A HTML form allows the user to enter inputs in the prompt boxes. When the user clicks on the Submit button, the inputs will be sent to a Web server for processing. In the example HTML file, the form inputs will be sent to the HTTP server at cs360.eecs.wsu.edu, which will execute the CGI program mycgi.bin in the user’s cgi-bin directory.

(3). CGI Directory and CGI Programs: The HTTPD server is configured to allow user-level CGI. The following diagram shows the user-lever CGI setup.

In the cgi-bin directory, mycgi.c is a C program, which gets and shows user inputs in a submitted HTML form. It echoes user inputs and generates a HTML file containing a FORM, which is sent back to the Web client to display. The following shows the mycgi.c program code.

/************** mycgi.c file *************/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAX 1000 typedef struct{

char *name;

char *value;

}ENTRY;

ENTRY entry[MAX];

extern int getinputs(); // in util.o

int main(int argc, char *argv[])

{

int i, n;

char cwd[128];

n = getinputs();      // get user inputs name=value into entry[ ]

getcwd(cwd, 128);     // get CWD pathname

// generate a HTML file containing a HTML FORM

printf(“Content-type: text/html\n\n”); // NOTE: 2 new line chars

printf(“<html>”);

printf(“<body bgcolor=\”#FFFF00\”); // background color=YELLOW

printf(“<p>pid=%d uid=%d cwd=%s\n”, getpid(), getuid(), cwd);

printf(“<H2>Echo Your Inputs</H2>”);

printf(“You submitted the following name/value pairs:<p>”);

for(i=0; i<=n; i++)

printf(“%s = %s<P>”, entry[i].name, entry[i].value);

printf(“<p>”);

// create a FORM webpage for user to submit again

printf(“——— Send Back a Form Again————– <P>”);

printf(“<FORM METHOD=\”POST\”

ACTION=\”http://cs360.eecs.wsu.edu/~kcw/cgi-bin/mycgi.bin\”>”);

printf(“<font color=\”RED\”>”);

printf(“Enter command : <INPUT NAME=\”command\”> <P>”);

printf(“Enter filenamel: <INPUT NAME=\”filename1\”> <P>”);

printf(“Enter filename2: <INPUT NAME=\”filename2\”> <P>”);

printf(“Submit command: <INPUT TYPE=\”submit\” VALUE=\”Click to \

Submit\”> <P>”);

printf(“</form>”);

printf(“</font>”);

printf(“——————————————– <p>”);

printf(“</body>”);

printf(“</html>”);

}

Figure 13.16 shows the Web page generated by the above CGI program.

(4). CGI Programs: When the HTTPD server receives a CGI request, it forks a child process with UID 80 to execute the CGI program. The form submission method, inputs encoding and input data length are in the environment variables REQUEST_METHOD, CONETENT_TYPE and CONTENT_LENGTH of the process, and the input data are in stdin. The input data are typically URL-encoded. Decoding the inputs into name-value pairs is straightforward but fairly tedious. For this reason, a pre-compiled util.o file is provided. It contains a function

int getinputs()

which decodes user inputs into pairs of name-value strings. The CGI program is generated by the Linux commands

gcc -o mycgi.bin mycgi.c util.o

(5). Dynamic Web Pages: After getting user inputs, the CGI program can process the user inputs to generate output data. In the example program it only echoes the user inputs. Then it generates a HTML file by writing HTML statements as lines to stdout. To qualify the lines as a HTML file, the first line must be

printf(“Content-type: text/html\n\n”);

with 2 new line chars. The rest lines can be any HTML statements. In the example program, it generates a FORM identical to the submitted form, which is used to get new user inputs in the next submission.

(6). SETUID Programs: Normally, a CGI program only uses user inputs to read from a database on the server side to generate a HTML file. For security reasons, it may not allow CGI programs to modify the server side database. In the programming project, we shall allow uses requests to do file operations, such as mkdir, rmdir, cp files, etc. which require writing permissions into the user’s directory. Since the CGI process has a UID=80, it should not be able to write into the user’s directory. There are two options to allow the CGI process to write in the user’s directory. In the first option, the user may set the cgi-bin directory permissions to 0777, but this is undesirable because it would allow anyone to be able to write in its directory. The second option is to make the CGI program a SETUID program by

chmod u+s mycgi.bin

When a process executes a SETUID program, it temporarily assumes the UID of the program owner, allowing it to write in the user’ s directory.

(7). User Requests for File Operations: Since the objective of the project is CGI programming, we only assume the following simple file operations as user requests:

(8). Sample Solution: In the cgi-bin directory, sample.bin is a sample solution of the project. The reader may replace mycgi.bin in the index.html file with sample.bin to test user requests and observe the results.

Source: Wang K.C. (2018), Systems Programming in Unix/Linux, Springer; 1st ed. 2018 edition.

Leave a Reply

Your email address will not be published. Required fields are marked *