Search code examples
pythonsocketsalarm

signal.alarm Preventing Script Execution


Background: So we were provided this script in class with the objective of opening random unprivileged ports on our Ubuntu VMs. He gave us two TCP examples and asked us to open two more additional TCP ports as well as two UDP ports. We were to accomplish this using the socket library and the Python programming language.

So I initially focused on the problem that he gave us. Using the python terminal this was the final script before I initially executed it knowing that the general concepts would open the ports for a connection on the Linux guest:

#!/usr/bin/env python

import signal
import socket
import sys
import time
import os

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s3 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s4 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s5 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s6 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

def tcp_server() :
    TCP_IP = '127.0.0.1'

    s1.bind((TCP_IP, 6005))
    s2.bind((TCP_IP, 1123))
    s3.bind((TCP_IP, 6009))
    s4.bind((TCP_IP, 1124))
    s5.bind((TCP_IP, 6006))
    s6.bind((TCP_IP, 6007))

    s1.listen(1)
    s2.listen(2)
    s3.listen(3)
    s4.listen(4)

tcp_server() 

def SigAlarmHandler(signal, frame) :
    print("Received alarm TCP server is shutting down")
    sys.exit(0)

signal.signal(signal.SIGALRM, SigAlarmHandler)
signal.alarm(int(sys.argv[1]))

while True :
    pass

When I execute the script on the Ubuntu VM I receive the following error message:

Traceback (most recent call last):
    signal.alarm(int(sys.argv[1]))
IndexError: list index out of range

So I dug and I found these two little nuggets of information.

signal.alarm Python Docs: https://docs.python.org/2/library/signal.html

Unix man page alarm(2) http://unixhelp.ed.ac.uk/CGI/man-cgi?alarm+2

Looking at the man page for the alarm it seems that it is expecting an int type so I am not confident an explicit data conversion is necessary. Although I'm also not confident in the total direction of the script. The professor just gave it to us for bonus. He said he would look at it, but I'm not sure when he will get back to me.

I'm thinking that bit of code is setup that if one of the ports opened is probed the script will terminate. Looking at the man page it seems that if an int greater than 0 is returned the alarm will generate. Triggering the termination of the script. Although with an IndexError and not knowing what index it is referring to I'm unsure of where to narrow in on to resolve the issue.


Solution

  • The most likely explanation is that you are not passing any command line arguments to your script, and that it's sys.argv[1] that is raising the IndexError. Nothing to do with signals or sockets.

    Call your script using ./ScriptName.py 5 and it should work, the alarm will fire after 5 seconds, and your server should exit.

    References in case you're not familiar with sys.argv: