CS502 Project 3

Macro Shell

Due date: Thursday, Jul 21st by 11:59pm



The main purpose of this project is to give you a basic introduction to OS support for sockets, while building upon some of your previous OS knowledge. You will write a basic remote shell in which a user specifies an arbitrary shell command to be executed, and it is sent over socket connection and executed on a remote server.

You will write a server and a client:

The server will authenticate the client through a simple password mechanism. You can hard-code your password in both your server and your client, if you wish.


The samples code on the course web page contains some samples that may be useful. In particular:

To get help information about specific Unix commands, use the "man" command. For instance, entering "man tcsh" will display the manual page entry for the tcsh. If you specify a number after the word "man", it looks in the indicated section number.

The following system calls for setting up your sockets may be helpful (you do not necessarily need to use them all):

The following system calls for the "shell" part and communication through the sockets may be helpful (you do not necessarily need to use them all):

In particular, dup2() makes a new file descriptor be the copy of an old file descriptor (closing the new file descriptor first, if necessary). You can use dup2() to make stdout (STDOUT_FILENO) a copy of the connected socket. This will close the stdout (to the display, by default) and make it instead the socket, causing all output to go down the socket.

While you will use a simple clear-text password for security, for added security, a "real" server would likely use be chroot() to change the root directory of the process. For example, many anonymous ftp servers use chroot() to make the top directory level /home/ftp or something similar. Thus, a malicious user is unable to compromise the system. Unfortunately for this project, chroot() requires root privilege to run, making it unavailable to the common user. However, if you are developing on your own system (say, a Linux box), I encourage you to explore using chroot() (do a "man 2 chroot" for more information). However, do make sure the version you hand in can run on the CCC machines.


Here are some examples. The server:

claypool 94 ccc1% ./server -h
macro shell server
usage: server [flags], where flags are:
        -p #    port to serve on (default is 6013)
        -d dir  directory to serve out of (default is /home/claypool/msh)
        -h      this help message

claypool 95 ccc1% ./server
./server activating.
        port: 6013
         dir: /home/claypool/msh
Socket created! Accepting connections.

Connection request received.
forked child
received password
password ok
command: ls
executing command...

Connection request received.
forked child
received password
password ok
command: ls -l
executing command...

Connection request received.
forked child
received password
password ok
command: cat Makefile
executing command...

The client from the same session:

claypool 49 capricorn% ./msh -h
macro shell client
usage: msh [flags] < command >, where flags are:
        {-c < command >}  command to execute remotely
        {-s < host >}     host server is on
        [-p #]          port server is on (default is 6013)
        [-h]            this help message

claypool 41 ccc5% ./msh -c "ls" -s ccc1

claypool 42 ccc5% ./msh -c "ls -l" -s ccc1
total 37
-rw-r-----   1 claypool users         212 Jul  7 22:19 Makefile
-rw-r-----   1 claypool users         997 Jul  1 09:27 client.c
-rwxrwx---   1 claypool users        6918 Jul  9 00:04 msh
-rw-r-----   1 claypool users        3790 Jul  9 00:03 msh.c
-rw-r-----   1 claypool users        5374 Jul  8 23:50 index.html
-rwxrwx---   1 claypool users        7919 Jul  9 00:09 server
-rw-r-----   1 claypool users        4383 Jul  9 00:09 server.c
-rw-r-----   1 claypool users         240 Jul  7 22:19 server.h
-rw-r-----   1 claypool users        2638 Jul  1 09:36 sock.c
-rw-r-----   1 claypool users         614 Jul  1 09:27 sock.h

claypool 43 ccc5% ./msh -c "cat Makefile" -s ccc1


CC = gcc

all: server msh

server: server.c server.h
        $(CC) -o server server.c

msh: msh.c server.h
        $(CC) -o msh msh.c

sock.o: sock.c sock.h
        $(CC) -c sock.c

        /bin/rm -f msh server core *.o *~


A useful program for maintaining large programs that have been broken into many software modules is make. The program uses a file, usually named Makefile, that resides in the same directory as the source code. This file describes how to compile a number of targets specified. To use, simply type "make" at the command line. WARNING: The operation line(s) for a target MUST begin with a TAB (do not use spaces). See the man page for make and gcc for additional information.

# Makefile for the macro shell program

CC = gcc

all: msh server

server: server.c 
	$(CC) $(CFLAGS) server.c server.o -o server $(LIBFLAGS)

msh: msh.c 
	$(CC) $(CFLAGS) msh.c msh.o -o msh $(LIBFLAGS)

	/bin/rm -rf *.o core msh server

Hand In

Answer the following questions when you turn in your project:

  1. Would it be advantageous to make your server multithreaded? Why or why not?
  2. Would it be advantageous to make your client multithreaded? Why or why not?
  3. If someone else were to write their own client, say one with a GUI, that wanted to communicate with your server, what would they need to know? Be specific.
  4. What are some possible security holes in your server implementation. Describe as many as you can think of.

Please include a README file giving some project information. The main information I'd like you to have from the documentation standard is: author, date, project id, language, OS dependencies, description and building information. Do note, however, that this information does not take the place of normal comments in your code! These comments are to make it easier to assess a grade if there are difficulties in the program.

Here is a sample of the information you should have:

Author:                         Mark Claypool
Date:                           7/15/05
Project ID:                     Project 3
CS Class:                       CS502
Programming Language:           C
OS/Hardware dependencies:       Unix, gcc

Problem Description:            This program implements a distributed shell
                                that does blah, blah, blah

How to build the program:       "make"

To hand in project 3:

  1. Be sure the answers to the Questions are in a file called "questions.txt" in the directory with your project code.

  2. Then, make a tar-ball to submit your files:

       cd my-dir-with-proj3
       rm all-files-not-to-be-turned-in
       cd ..
       tar cvf login-name-proj3.tar my-dir-with-proj3

  3. Attach them to an email them to me with the subject "cs502 project 3"

Return to the cs3013/502 Home Page

Send all questions to claypool at cs.wpi.edu.