diff --git a/0001-01_bin_dir.diff-from-Debian.patch b/0001-01_bin_dir.diff-from-Debian.patch new file mode 100644 index 0000000..cd1d440 --- /dev/null +++ b/0001-01_bin_dir.diff-from-Debian.patch @@ -0,0 +1,21 @@ +From ba58ad8363c9e9225e432b01254eae2be3453438 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:14:05 +0200 +Subject: [PATCH 01/14] 01_bin_dir.diff from Debian + +--- + configure.ajaxterm.bin | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/configure.ajaxterm.bin b/configure.ajaxterm.bin +index 4d1f5a9..875b12d 100644 +--- a/configure.ajaxterm.bin ++++ b/configure.ajaxterm.bin +@@ -1,2 +1,3 @@ + #!/bin/sh +-PYTHONPATH=%(lib)s exec %(lib)s/ajaxterm.py $@ ++PYTHONPATH=/usr/share/ajaxterm ++exec $PYTHONPATH/ajaxterm.py $@ +-- +1.7.3.1 + diff --git a/0001-Create-etc.patch b/0001-Create-etc.patch new file mode 100644 index 0000000..63b6db6 --- /dev/null +++ b/0001-Create-etc.patch @@ -0,0 +1,24 @@ +From 309e643b66e9b15f005109360c87f425c459e7b0 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 18:09:25 +0200 +Subject: [PATCH] Create /etc + +--- + configure.makefile | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/configure.makefile b/configure.makefile +index c866804..aed7ca6 100644 +--- a/configure.makefile ++++ b/configure.makefile +@@ -4,6 +4,7 @@ build: + install: + install -d "%(bin)s" + install -d "%(lib)s" ++ install -d "%(etc)s" + install ajaxterm.bin "%(bin)s/ajaxterm" + install -m 644 ajaxterm.css ajaxterm.html ajaxterm.js qweb.py sarissa.js sarissa_dhtml.js utf8-escape.js "%(lib)s" + install -m 644 ajaxterm.conf "%(etc)s" +-- +1.7.3.1 + diff --git a/0002-02_initd.diff-from-Debian.patch b/0002-02_initd.diff-from-Debian.patch new file mode 100644 index 0000000..19528eb --- /dev/null +++ b/0002-02_initd.diff-from-Debian.patch @@ -0,0 +1,50 @@ +From 41ea31a4b52add3023b9126b1d6278a3c23d2b22 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:14:30 +0200 +Subject: [PATCH 02/14] 02_initd.diff from Debian + +--- + configure | 8 -------- + configure.makefile | 2 -- + 2 files changed, 0 insertions(+), 10 deletions(-) + +diff --git a/configure b/configure +index 45391f4..fbaff03 100755 +--- a/configure ++++ b/configure +@@ -21,12 +21,4 @@ man=os.path.join(o.prefix,"share/man/man1") + file("ajaxterm.bin","w").write(file("configure.ajaxterm.bin").read()%locals()) + file("Makefile","w").write(file("configure.makefile").read()%locals()) + +-if os.path.isfile("/etc/gentoo-release"): +- file("ajaxterm.initd","w").write(file("configure.initd.gentoo").read()%locals()) +-elif os.path.isfile("/etc/fedora-release") or os.path.isfile("/etc/redhat-release"): +- file("ajaxterm.initd","w").write(file("configure.initd.redhat").read()%locals()) +-else: +- file("ajaxterm.initd","w").write(file("configure.initd.debian").read()%locals()) +- + os.system("chmod a+x ajaxterm.bin") +-os.system("chmod a+x ajaxterm.initd") +diff --git a/configure.makefile b/configure.makefile +index 6bd8085..b3c678f 100644 +--- a/configure.makefile ++++ b/configure.makefile +@@ -5,7 +5,6 @@ install: + install -d "%(bin)s" + install -d "%(lib)s" + install ajaxterm.bin "%(bin)s/ajaxterm" +- install ajaxterm.initd "%(etc)s/init.d/ajaxterm" + install -m 644 ajaxterm.css ajaxterm.html ajaxterm.js qweb.py sarissa.js sarissa_dhtml.js "%(lib)s" + install -m 755 ajaxterm.py "%(lib)s" + gzip --best -c ajaxterm.1 > ajaxterm.1.gz +@@ -14,7 +13,6 @@ install: + + clean: + rm ajaxterm.bin +- rm ajaxterm.initd + rm ajaxterm.1.gz + rm Makefile + +-- +1.7.3.1 + diff --git a/0002-Fix-permissions-on-manfile.patch b/0002-Fix-permissions-on-manfile.patch new file mode 100644 index 0000000..e69868c --- /dev/null +++ b/0002-Fix-permissions-on-manfile.patch @@ -0,0 +1,25 @@ +From ed60fd28185aacb7cb87d101daa62dca280fa735 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 19:00:06 +0200 +Subject: [PATCH] Fix permissions on manfile + +--- + configure.makefile | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/configure.makefile b/configure.makefile +index aed7ca6..ca27732 100644 +--- a/configure.makefile ++++ b/configure.makefile +@@ -12,7 +12,7 @@ install: + ln -s /etc/ajaxterm.conf "%(lib)s"/ajaxterm_config.js + gzip --best -c ajaxterm.1 > ajaxterm.1.gz + install -d "%(man)s" +- install ajaxterm.1.gz "%(man)s" ++ install -pm 0644 ajaxterm.1.gz "%(man)s" + + clean: + rm ajaxterm.bin +-- +1.7.3.1 + diff --git a/0003-03_fix_man.diff-from-Debian.patch b/0003-03_fix_man.diff-from-Debian.patch new file mode 100644 index 0000000..1dc04ee --- /dev/null +++ b/0003-03_fix_man.diff-from-Debian.patch @@ -0,0 +1,42 @@ +From a15c2fdf9fe2bdeb552d14026c7dfc664db10413 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:15:01 +0200 +Subject: [PATCH 03/14] 03_fix_man.diff from Debian + +--- + ajaxterm.1 | 12 ++++++------ + 1 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/ajaxterm.1 b/ajaxterm.1 +index 46f2acb..8d0a942 100644 +--- a/ajaxterm.1 ++++ b/ajaxterm.1 +@@ -1,4 +1,4 @@ +-.TH ajaxterm "1" "May 2006" "ajaxterm 0.5" "User commands" ++.TH ajaxterm "1" "Jul 2006" "ajaxterm 0.7" "User commands" + .SH NAME + ajaxterm \- Web based terminal written in python + +@@ -8,14 +8,14 @@ javascript for client side. + It can use almost any web browser and even works through firewalls. + + .SH USAGE +-\fBajaxterm.py\fR [options] ++\fBajaxterm\fR [options] + + .SH OPTIONS + A summary of the options supported by \fBajaxterm\fR is included below. +- \fB-h, --help\fR show this help message and exit +- \fB-pPORT, --port=PORT\fR Set the TCP port (default: 8022) +- \fB-cCMD, --command=CMD\fR set the command (default: /bin/login or ssh localhost) +- \fB-l, --log\fR log requests to stderr (default: quiet mode) ++ \fB-h, \--help\fR show this help message and exit ++ \fB-pPORT, \--port=PORT\fR Set the TCP port (default: 8022) ++ \fB-cCMD, \--command=CMD\fR set the command (default: /bin/login or ssh localhost) ++ \fB-l, \--log\fR log requests to stderr (default: quiet mode) + + .SH AUTHOR + Antony Lesuisse +-- +1.7.3.1 + diff --git a/0003-Remove-shebang-line.patch b/0003-Remove-shebang-line.patch new file mode 100644 index 0000000..3e16925 --- /dev/null +++ b/0003-Remove-shebang-line.patch @@ -0,0 +1,22 @@ +From 7fa9b9aeba7cea832db688199c955baf57397841 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 19:01:18 +0200 +Subject: [PATCH] Remove shebang line + +--- + qweb.py | 2 -- + 1 files changed, 0 insertions(+), 2 deletions(-) + +diff --git a/qweb.py b/qweb.py +index 1541035..ef9ecaf 100644 +--- a/qweb.py ++++ b/qweb.py +@@ -1,5 +1,3 @@ +-#!/usr/bin/env python +-# + # vim:set et ts=4 fdc=0 fdn=2 fdl=0: + # + # There are no blank lines between blocks beacause i use folding from: +-- +1.7.3.1 + diff --git a/0004-04_use-default-python.diff-from-Debian.patch b/0004-04_use-default-python.diff-from-Debian.patch new file mode 100644 index 0000000..37e63d7 --- /dev/null +++ b/0004-04_use-default-python.diff-from-Debian.patch @@ -0,0 +1,22 @@ +From 416891118e1770b2370238855f39babb3e22477f Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:15:27 +0200 +Subject: [PATCH 04/14] 04_use-default-python.diff from Debian + +--- + qweb.py | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/qweb.py b/qweb.py +index 20c5092..c658a6b 100644 +--- a/qweb.py ++++ b/qweb.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python2.3 ++#!/usr/bin/env python + # + # vim:set et ts=4 fdc=0 fdn=2 fdl=0: + # +-- +1.7.3.1 + diff --git a/0005-05_ssh-port.diff-from-Debian.patch b/0005-05_ssh-port.diff-from-Debian.patch new file mode 100644 index 0000000..06b3acf --- /dev/null +++ b/0005-05_ssh-port.diff-from-Debian.patch @@ -0,0 +1,75 @@ +From 8bbdcc6e084b59027cac6f2463968af1f33b1793 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:16:14 +0200 +Subject: [PATCH 05/14] 05_ssh-port.diff from Debian + +--- + ajaxterm.py | 15 ++++++++++----- + 1 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/ajaxterm.py b/ajaxterm.py +index 8b3af37..63b0444 100755 +--- a/ajaxterm.py ++++ b/ajaxterm.py +@@ -367,9 +367,10 @@ class SynchronizedMethod: + return r + + class Multiplex: +- def __init__(self,cmd=None): ++ def __init__(self,cmd=None,serverport=None): + signal.signal(signal.SIGCHLD, signal.SIG_IGN) + self.cmd=cmd ++ self.serverport=serverport + self.proc={} + self.lock=threading.RLock() + self.thread=threading.Thread(target=self.loop) +@@ -403,7 +404,10 @@ class Multiplex: + cmd+=['-oPreferredAuthentications=keyboard-interactive,password'] + cmd+=['-oNoHostAuthenticationForLocalhost=yes'] + cmd+=['-oLogLevel=FATAL'] +- cmd+=['-F/dev/null','-l',login,'localhost'] ++ cmd+=['-F/dev/null'] ++ if self.serverport: ++ cmd+=['-p %s'%self.serverport] ++ cmd+=['-l', login, 'localhost'] + else: + os._exit(0) + env={} +@@ -473,7 +477,7 @@ class Multiplex: + pass + + class AjaxTerm: +- def __init__(self,cmd=None,index_file='ajaxterm.html'): ++ def __init__(self,cmd=None,index_file='ajaxterm.html',serverport=None): + self.files={} + for i in ['css','html','js']: + for j in glob.glob('*.%s'%i): +@@ -481,7 +485,7 @@ class AjaxTerm: + self.files['index']=file(index_file).read() + self.mime = mimetypes.types_map.copy() + self.mime['.html']= 'text/html; charset=UTF-8' +- self.multi = Multiplex(cmd) ++ self.multi = Multiplex(cmd,serverport) + self.session = {} + def __call__(self, environ, start_response): + req = qweb.QWebRequest(environ, start_response,session=None) +@@ -528,6 +532,7 @@ def main(): + parser.add_option("-P", "--pidfile",dest="pidfile",default="/var/run/ajaxterm.pid",help="set the pidfile (default: /var/run/ajaxterm.pid)") + parser.add_option("-i", "--index", dest="index_file", default="ajaxterm.html",help="default index file (default: ajaxterm.html)") + parser.add_option("-u", "--uid", dest="uid", help="Set the daemon's user id") ++ parser.add_option("-s", "--serverport", dest="serverport", help="Use a different port than 22 to connect to the ssh server") + (o, a) = parser.parse_args() + if o.daemon: + pid=os.fork() +@@ -553,7 +558,7 @@ def main(): + sys.exit(0) + else: + print 'AjaxTerm at http://localhost:%s/' % o.port +- at=AjaxTerm(o.cmd,o.index_file) ++ at=AjaxTerm(o.cmd,o.index_file,o.serverport) + # f=lambda:os.system('firefox http://localhost:%s/&'%o.port) + # qweb.qweb_wsgi_autorun(at,ip='localhost',port=int(o.port),threaded=0,log=o.log,callback_ready=None) + try: +-- +1.7.3.1 + diff --git a/0006-06_fix-IOError.diff-from-Debian.patch b/0006-06_fix-IOError.diff-from-Debian.patch new file mode 100644 index 0000000..7c82761 --- /dev/null +++ b/0006-06_fix-IOError.diff-from-Debian.patch @@ -0,0 +1,25 @@ +From 86a9366721a7736f9be28871b303d350bda1bd2c Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:16:49 +0200 +Subject: [PATCH 06/14] 06_fix-IOError.diff from Debian + +--- + ajaxterm.py | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/ajaxterm.py b/ajaxterm.py +index 63b0444..fe1fc6c 100755 +--- a/ajaxterm.py ++++ b/ajaxterm.py +@@ -419,7 +419,7 @@ class Multiplex: + else: + fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) + # python bug http://python.org/sf/1112949 on amd64 +- fcntl.ioctl(fd, struct.unpack('i',struct.pack('I',termios.TIOCSWINSZ))[0], struct.pack("HHHH",h,w,0,0)) ++ fcntl.ioctl(fd, termios.TIOCSWINSZ, struct.pack("HHHH",h,w,0,0)) + self.proc[fd]={'pid':pid,'term':Terminal(w,h),'buf':'','time':time.time()} + return fd + def die(self): +-- +1.7.3.1 + diff --git a/0007-07_use_psyco.diff-from-Debian.patch b/0007-07_use_psyco.diff-from-Debian.patch new file mode 100644 index 0000000..cd8b468 --- /dev/null +++ b/0007-07_use_psyco.diff-from-Debian.patch @@ -0,0 +1,47 @@ +From 22dd3fa44e3bcd83d6358cd8dea329509e79471b Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:18:03 +0200 +Subject: [PATCH 07/14] 07_use_psyco.diff from Debian + +--- + ajaxterm.py | 6 ++++++ + qweb.py | 6 ++++++ + 2 files changed, 12 insertions(+), 0 deletions(-) + +diff --git a/ajaxterm.py b/ajaxterm.py +index fe1fc6c..a3b928f 100755 +--- a/ajaxterm.py ++++ b/ajaxterm.py +@@ -2,6 +2,12 @@ + + """ Ajaxterm """ + ++try: ++ import psyco ++ psyco.profile() ++except: ++ pass ++ + import array,cgi,fcntl,glob,mimetypes,optparse,os,pty,random,re,signal,select,sys,threading,time,termios,struct,pwd + + os.chdir(os.path.normpath(os.path.dirname(__file__))) +diff --git a/qweb.py b/qweb.py +index c658a6b..34529c2 100644 +--- a/qweb.py ++++ b/qweb.py +@@ -116,6 +116,12 @@ try: + except ImportError: + import StringIO + ++try: ++ import psyco ++ psyco.profile() ++except: ++ pass ++ + #---------------------------------------------------------- + # Qweb Xml t-raw t-esc t-if t-foreach t-set t-call t-trim + #---------------------------------------------------------- +-- +1.7.3.1 + diff --git a/0008-10_hostname-login.diff-from-Debian.patch b/0008-10_hostname-login.diff-from-Debian.patch new file mode 100644 index 0000000..6d56790 --- /dev/null +++ b/0008-10_hostname-login.diff-from-Debian.patch @@ -0,0 +1,33 @@ +From 40c8f7f1907805bce929500a751e2c8ae05a2836 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:18:41 +0200 +Subject: [PATCH 08/14] 10_hostname-login.diff from Debian + +--- + ajaxterm.py | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/ajaxterm.py b/ajaxterm.py +index a3b928f..91d938d 100755 +--- a/ajaxterm.py ++++ b/ajaxterm.py +@@ -15,6 +15,7 @@ os.chdir(os.path.normpath(os.path.dirname(__file__))) + sys.path[0:0]=glob.glob('../../python') + + import qweb ++from socket import gethostname + + class Terminal: + def __init__(self,width=80,height=24): +@@ -403,7 +404,7 @@ class Multiplex: + elif os.getuid()==0: + cmd=['/bin/login'] + else: +- sys.stdout.write("Login: ") ++ sys.stdout.write(gethostname() + " login: ") + login=sys.stdin.readline().strip() + if re.match('^[0-9A-Za-z-_. ]+$',login): + cmd=['ssh'] +-- +1.7.3.1 + diff --git a/0009-15_add-configure-file.diff-from-Debian.patch b/0009-15_add-configure-file.diff-from-Debian.patch new file mode 100644 index 0000000..613bbee --- /dev/null +++ b/0009-15_add-configure-file.diff-from-Debian.patch @@ -0,0 +1,84 @@ +From 28dc99ae657768f1724e0bd3a0f598acf1073407 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:21:19 +0200 +Subject: [PATCH 09/14] 15_add-configure-file.diff from Debian + +--- + ajaxterm.conf | 13 +++++++++++++ + ajaxterm.html | 3 ++- + ajaxterm.js | 8 ++++++++ + configure.makefile | 2 ++ + 4 files changed, 25 insertions(+), 1 deletions(-) + create mode 100644 ajaxterm.conf + +diff --git a/ajaxterm.conf b/ajaxterm.conf +new file mode 100644 +index 0000000..41bd097 +--- /dev/null ++++ b/ajaxterm.conf +@@ -0,0 +1,13 @@ ++// Ajaxterm configuration file ++// ++// This is a javascript snippet ++// ++// Don't forget to restart ajaxterm after editing this file ++ ++ ++// Sets the terminal width (default: 80) ++width=80; ++ ++// Sets the terminal height (default: 25) ++height=25; ++ +diff --git a/ajaxterm.html b/ajaxterm.html +index 9edf759..095e7d6 100644 +--- a/ajaxterm.html ++++ b/ajaxterm.html +@@ -7,9 +7,10 @@ + + + ++ + + +diff --git a/ajaxterm.js b/ajaxterm.js +index 07eca3b..74eeb39 100644 +--- a/ajaxterm.js ++++ b/ajaxterm.js +@@ -4,6 +4,14 @@ ajaxterm.Terminal_ctor=function(id,width,height) { + if(window.ActiveXObject) + ie=1; + var sid=""+Math.round(Math.random()*1000000000); ++ ++ if (width==0) { ++ width=80; ++ } ++ if (height==0) { ++ height=25; ++ } ++ + var query0="s="+sid+"&w="+width+"&h="+height; + var query1=query0+"&c=1&k="; + var buf=""; +diff --git a/configure.makefile b/configure.makefile +index b3c678f..a30dc23 100644 +--- a/configure.makefile ++++ b/configure.makefile +@@ -6,7 +6,9 @@ install: + install -d "%(lib)s" + install ajaxterm.bin "%(bin)s/ajaxterm" + install -m 644 ajaxterm.css ajaxterm.html ajaxterm.js qweb.py sarissa.js sarissa_dhtml.js "%(lib)s" ++ install -m 644 ajaxterm.conf "%(etc)s" + install -m 755 ajaxterm.py "%(lib)s" ++ ln -s /etc/ajaxterm.conf "%(lib)s"/ajaxterm_config.js + gzip --best -c ajaxterm.1 > ajaxterm.1.gz + install -d "%(man)s" + install ajaxterm.1.gz "%(man)s" +-- +1.7.3.1 + diff --git a/0010-20_bugfixes-tweaks-by-blt.diff-from-Debian.patch b/0010-20_bugfixes-tweaks-by-blt.diff-from-Debian.patch new file mode 100644 index 0000000..e007359 --- /dev/null +++ b/0010-20_bugfixes-tweaks-by-blt.diff-from-Debian.patch @@ -0,0 +1,189 @@ +From a83984700c9ff46d467994724dff98f5ab10f5f5 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:33:46 +0200 +Subject: [PATCH 10/14] 20_bugfixes-tweaks-by-blt.diff from Debian + +--- + ajaxterm.js | 5 ++++- + ajaxterm.py | 45 ++++++++++++++++++++++++++++++++++----------- + qweb.py | 26 ++++++++++++++++++++++++++ + 3 files changed, 64 insertions(+), 12 deletions(-) + +diff --git a/ajaxterm.js b/ajaxterm.js +index 74eeb39..4edcb6c 100644 +--- a/ajaxterm.js ++++ b/ajaxterm.js +@@ -1,8 +1,11 @@ + ajaxterm={}; + ajaxterm.Terminal_ctor=function(id,width,height) { + var ie=0; ++ var webkit=0; + if(window.ActiveXObject) + ie=1; ++ if (navigator.userAgent.indexOf("WebKit") >= 0) ++ webkit=1; + var sid=""+Math.round(Math.random()*1000000000); + + if (width==0) { +@@ -242,7 +245,7 @@ ajaxterm.Terminal_ctor=function(id,width,height) { + } + function keydown(ev) { + if (!ev) var ev=window.event; +- if (ie) { ++ if (ie || webkit) { + // s="kd keyCode="+ev.keyCode+" which="+ev.which+" shiftKey="+ev.shiftKey+" ctrlKey="+ev.ctrlKey+" altKey="+ev.altKey; + // debug(s); + o={9:1,8:1,27:1,33:1,34:1,35:1,36:1,37:1,38:1,39:1,40:1,45:1,46:1,112:1, +diff --git a/ajaxterm.py b/ajaxterm.py +index 91d938d..962e685 100755 +--- a/ajaxterm.py ++++ b/ajaxterm.py +@@ -9,6 +9,7 @@ except: + pass + + import array,cgi,fcntl,glob,mimetypes,optparse,os,pty,random,re,signal,select,sys,threading,time,termios,struct,pwd ++from datetime import datetime + + os.chdir(os.path.normpath(os.path.dirname(__file__))) + # Optional: Add QWeb in sys path +@@ -17,6 +18,11 @@ sys.path[0:0]=glob.glob('../../python') + import qweb + from socket import gethostname + ++ ++def debug(str): ++ now = datetime.datetime.now() ++ print "%s - %s" % (now.isoformat(), str) ++ + class Terminal: + def __init__(self,width=80,height=24): + self.width=width +@@ -373,7 +379,23 @@ class SynchronizedMethod: + self.lock.release() + return r + ++class Reaper: ++ WAKEUP_FREQUENCY=5 ++ ++ def __init__(self,multi): ++ self.multi = multi ++ self.thread = threading.Thread(target = self.reaper_thread) ++ self.thread.setDaemon(True) ++ self.thread.start() ++ ++ def reaper_thread(self): ++ while True: ++ time.sleep(Reaper.WAKEUP_FREQUENCY) ++ self.multi.proc_kill_inactive() ++ + class Multiplex: ++ INACTIVE_PROCESS_TIMEOUT=120 # I guess this is the IP max packet lifetime ++ + def __init__(self,cmd=None,serverport=None): + signal.signal(signal.SIGCHLD, signal.SIG_IGN) + self.cmd=cmd +@@ -435,19 +457,19 @@ class Multiplex: + return self.alive + def fds(self): + return self.proc.keys() +- def proc_kill(self,fd): +- if fd in self.proc: +- self.proc[fd]['time']=0 ++ def proc_kill(self, fd): ++ try: ++ os.close(fd) ++ os.kill(self.proc[fd]['pid'],signal.SIGHUP) ++ except (IOError,OSError): ++ pass ++ del self.proc[fd] ++ def proc_kill_inactive(self): + t=time.time() + for i in self.proc.keys(): + t0=self.proc[i]['time'] +- if (t-t0)>120: +- try: +- os.close(i) +- os.kill(self.proc[i]['pid'],signal.SIGTERM) +- except (IOError,OSError): +- pass +- del self.proc[i] ++ if (t-t0)>Multiplex.INACTIVE_PROCESS_TIMEOUT: ++ self.proc_kill(i) + def proc_read(self,fd): + try: + t=self.proc[fd]['term'] +@@ -493,6 +515,7 @@ class AjaxTerm: + self.mime = mimetypes.types_map.copy() + self.mime['.html']= 'text/html; charset=UTF-8' + self.multi = Multiplex(cmd,serverport) ++ self.reaper = Reaper(self.multi) + self.session = {} + def __call__(self, environ, start_response): + req = qweb.QWebRequest(environ, start_response,session=None) +@@ -569,7 +592,7 @@ def main(): + # f=lambda:os.system('firefox http://localhost:%s/&'%o.port) + # qweb.qweb_wsgi_autorun(at,ip='localhost',port=int(o.port),threaded=0,log=o.log,callback_ready=None) + try: +- qweb.QWebWSGIServer(at,ip='localhost',port=int(o.port),threaded=0,log=o.log).serve_forever() ++ qweb.QWebWSGIServer(at,ip='localhost',port=int(o.port),threaded=1,log=o.log).serve_forever() + except KeyboardInterrupt,e: + sys.excepthook(*sys.exc_info()) + at.multi.die() +diff --git a/qweb.py b/qweb.py +index 34529c2..1541035 100644 +--- a/qweb.py ++++ b/qweb.py +@@ -1182,6 +1182,10 @@ class QWebRequest: + self.buffer=[zbuf] + self.response_headers['Content-Encoding']="gzip" + self.response_headers['Content-Length']=str(len(zbuf)) ++ else: ++ datalen = sum(map(len, self.buffer)) ++ self.response_headers['Content-Length']=str(datalen) ++ + headers = self.response_headers.get() + if isinstance(self.SESSION, QWebSession): + headers.extend(self.SESSION.session_get_headers()) +@@ -1257,6 +1261,7 @@ class QWebWSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler): + self.write(buf.getvalue()) + self.wfile_buf=0 + def serve(self,type): ++ self.handleKeepalive() + path_info, parameters, query = urlparse.urlparse(self.path)[2:5] + environ = { + 'wsgi.version': (1,0), +@@ -1287,10 +1292,31 @@ class QWebWSGIHandler(BaseHTTPServer.BaseHTTPRequestHandler): + # Hack to avoid may TCP packets + self.bufferon() + appiter=self.server.wsgiapp(environ, self.start_response) ++ if self.close_connection == 0: ++ appiter.response_headers['Connection']='keep-alive' ++ appiter.response_headers['Keep-Alive']='timeout=10, max=100' ++ + for data in appiter: + self.write(data) + self.bufferoff() + self.bufferoff() ++ def handleKeepalive(self): ++ base_version_number=self.request_version.split("/",1)[1] ++ version_number = base_version_number.split(".") ++ version_number = int(version_number[0]), int(version_number[1]) ++ connection_header = self.headers.get("Connection", "").lower() ++ if version_number == (1,0): ++ if connection_header == "keepalive": ++ self.close_connection = 0 ++ else: ++ self.close_connection = 1 ++ elif version_number == (1,1): ++ if connection_header == "close": ++ self.close_connection=1 ++ else: ++ self.close_connection=0 ++ else: ++ self.close_connection=1 + def do_GET(self): + self.serve('GET') + def do_POST(self): +-- +1.7.3.1 + diff --git a/0011-25_CVE-2009-1629.diff-from-Debian.patch b/0011-25_CVE-2009-1629.diff-from-Debian.patch new file mode 100644 index 0000000..bc41a10 --- /dev/null +++ b/0011-25_CVE-2009-1629.diff-from-Debian.patch @@ -0,0 +1,153 @@ +From 66f2db86bf06d229a48bfa197cf93cb41e59953d Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:38:55 +0200 +Subject: [PATCH 11/14] 25_CVE-2009-1629.diff from Debian + +--- + ajaxterm.js | 17 ++++++++++++++- + ajaxterm.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 74 insertions(+), 8 deletions(-) + +diff --git a/ajaxterm.js b/ajaxterm.js +index 4edcb6c..2579a8f 100644 +--- a/ajaxterm.js ++++ b/ajaxterm.js +@@ -6,7 +6,22 @@ ajaxterm.Terminal_ctor=function(id,width,height) { + ie=1; + if (navigator.userAgent.indexOf("WebKit") >= 0) + webkit=1; +- var sid=""+Math.round(Math.random()*1000000000); ++ var sid=""; ++ ++ for (var i=0; i < 255; i++) { ++ var r = 0; ++ // now get a random number between 0 and 255 ++ // numbers not in the range are intentionally discarded ++ // as it reduces the chance of predicting the seed, by not ++ // using all of the numbers generated by the PRNG ++ do { ++ r = Math.round(Math.random()*1000); ++ } while(r >= 255); ++ r = r.toString(16); ++ if (r.length == 1) ++ r = "0"+r; ++ sid += "%" + r; ++ } + + if (width==0) { + width=80; +diff --git a/ajaxterm.py b/ajaxterm.py +index 962e685..8695590 100755 +--- a/ajaxterm.py ++++ b/ajaxterm.py +@@ -8,8 +8,14 @@ try: + except: + pass + +-import array,cgi,fcntl,glob,mimetypes,optparse,os,pty,random,re,signal,select,sys,threading,time,termios,struct,pwd +-from datetime import datetime ++import array,cgi,fcntl,glob,mimetypes,optparse,os,pty,random,re,signal,select,sys,threading,time,termios,struct,pwd,Cookie ++from datetime import datetime, timedelta ++ ++try: ++ from hashlib import sha1 ++except ImportError: ++ import sha ++ sha1 = sha.new + + os.chdir(os.path.normpath(os.path.dirname(__file__))) + # Optional: Add QWeb in sys path +@@ -517,30 +523,61 @@ class AjaxTerm: + self.multi = Multiplex(cmd,serverport) + self.reaper = Reaper(self.multi) + self.session = {} ++ self.session_ip = {} ++ self.sessions_limit = 20 ++ self.sessions_user_limit = 4 ++ m = sha1() ++ m.update(os.urandom(128)) ++ self.cookie_name = m.hexdigest() + def __call__(self, environ, start_response): + req = qweb.QWebRequest(environ, start_response,session=None) + if req.PATH_INFO.endswith('/u'): ++ req.response_headers['Content-Type']='text/xml' ++ uid="" ++ if self.cookie_name not in req.request_cookies: ++ req.write('') ++ return req ++ uid = req.request_cookies[self.cookie_name].value + s=req.REQUEST["s"] + k=req.REQUEST["k"] + c=req.REQUEST["c"] + w=req.REQUEST.int("w") + h=req.REQUEST.int("h") +- if s in self.session: +- term=self.session[s] ++ ip="unknown" ++ if environ.has_key("REMOTE_ADDR"): ++ ip=environ['REMOTE_ADDR'] ++ if ip == "127.0.0.1" and environ.has_key("HTTP_X_FORWARDED_FOR"): ++ ip=environ["HTTP_X_FORWARDED_FOR"] ++ ++ if (uid+s) in self.session: ++ term=self.session[uid+s] ++ req.response_cookies.load(req.request_cookies[self.cookie_name].OutputString()) ++ req.response_cookies[self.cookie_name]['expires'] = datetime.utcnow()+timedelta(seconds=60) + else: + if not (w>2 and w<256 and h>2 and h<100): + w,h=80,25 +- term=self.session[s]=self.multi.create(w,h) ++ # check if there aren't too many open sessions ++ if len(self.session) < self.sessions_limit: ++ count=0 ++ for i in self.session_ip.keys(): ++ if self.session_ip[i] == ip: ++ count+=1 ++ if count <= self.sessions_user_limit: ++ term=self.session[uid+s]=self.multi.create(w,h) ++ self.session_ip[uid+s]=ip ++ else: ++ req.write('') ++ return req + if k: + self.multi.proc_write(term,k) + time.sleep(0.002) + dump=self.multi.dump(term,c) +- req.response_headers['Content-Type']='text/xml' + if isinstance(dump,str): + req.write(dump) + req.response_gzencode=1 + else: +- del self.session[s] ++ del self.session[uid+s] ++ del self.session_ip[uid+s] + req.write('') + # print "sessions %r"%self.session + else: +@@ -549,9 +586,23 @@ class AjaxTerm: + req.response_headers['Content-Type'] = self.mime.get(os.path.splitext(n)[1].lower(), 'application/octet-stream') + req.write(self.files[n]) + else: ++ if self.cookie_name not in req.request_cookies: ++ self.genSidCookie(req) + req.response_headers['Content-Type'] = 'text/html; charset=UTF-8' + req.write(self.files['index']) + return req ++ def genSidCookie(self, req): ++ m = sha1() ++ m.update(os.urandom(160)) ++ req.response_cookies[self.cookie_name] = m.hexdigest() ++ # try to set httponly if supported (added in 2.6) ++ try: ++ req.response_cookies[self.cookie_name]['httponly'] = 1 ++ except (Cookie.CookieError): ++ pass ++ req.response_cookies[self.cookie_name]['path'] = req.PATH_INFO ++ req.response_cookies[self.cookie_name]['expires'] = datetime.utcnow()+timedelta(seconds=60) ++ return req + + def main(): + parser = optparse.OptionParser() +-- +1.7.3.1 + diff --git a/0012-30_utf8-support.diff-from-Debian.patch b/0012-30_utf8-support.diff-from-Debian.patch new file mode 100644 index 0000000..0c7681f --- /dev/null +++ b/0012-30_utf8-support.diff-from-Debian.patch @@ -0,0 +1,591 @@ +From d4b95f3ed4b8a0f47dab35a2560d76bb66117277 Mon Sep 17 00:00:00 2001 +From: Ruben +Date: Sun, 17 Oct 2010 17:50:39 +0200 +Subject: [PATCH 12/14] 30_utf8-support.diff from Debian + +--- + README.txt | 240 ++++++++++++++++++++++++++-------------------------- + ajaxterm.1 | 2 + + ajaxterm.html | 1 + + ajaxterm.js | 13 +++- + ajaxterm.py | 81 ++++++++---------- + configure.makefile | 2 +- + utf8-escape.js | 80 +++++++++++++++++ + 7 files changed, 251 insertions(+), 168 deletions(-) + create mode 100644 utf8-escape.js + +diff --git a/README.txt b/README.txt +index 4b0ae99..05ae97f 100644 +--- a/README.txt ++++ b/README.txt +@@ -1,120 +1,120 @@ +-= [http://antony.lesuisse.org/qweb/trac/wiki/AjaxTerm Ajaxterm] = +- +-Ajaxterm is a web based terminal. It was totally inspired and works almost +-exactly like http://anyterm.org/ except it's much easier to install (see +-comparaison with anyterm below). +- +-Ajaxterm written in python (and some AJAX javascript for client side) and depends only on python2.3 or better.[[BR]] +-Ajaxterm is '''very simple to install''' on Linux, MacOS X, FreeBSD, Solaris, cygwin and any Unix that runs python2.3.[[BR]] +-Ajaxterm was written by Antony Lesuisse (email: al AT udev.org), License Public Domain. +- +-Use the [/qweb/forum/viewforum.php?id=2 Forum], if you have any question or remark. +- +-== News == +- +- * 2006-10-29: v0.10 allow space in login, cgi launch fix, redhat init +- * 2006-07-12: v0.9 change uid, daemon fix (Daniel Fischer) +- * 2006-07-04: v0.8 add login support to ssh (Sven Geggus), change max width to 256 +- * 2006-05-31: v0.7 minor fixes, daemon option +- * 2006-05-23: v0.6 Applied debian and gentoo patches, renamed to Ajaxterm, default port 8022 +- +-== Download and Install == +- +- * Release: [/qweb/files/Ajaxterm-0.10.tar.gz Ajaxterm-0.10.tar.gz] +- * Browse src: [/qweb/trac/browser/trunk/ajaxterm/ ajaxterm/] +- +-To install Ajaxterm issue the following commands: +-{{{ +-wget http://antony.lesuisse.org/qweb/files/Ajaxterm-0.10.tar.gz +-tar zxvf Ajaxterm-0.10.tar.gz +-cd Ajaxterm-0.10 +-./ajaxterm.py +-}}} +-Then point your browser to this URL : http://localhost:8022/ +- +-== Screenshot == +- +-{{{ +-#!html +-
ajaxterm screenshot
+-}}} +- +-== Documentation and Caveats == +- +- * Ajaxterm only support latin1, if you use Ubuntu or any LANG==en_US.UTF-8 distribution don't forget to "unset LANG". +- +- * If run as root ajaxterm will run /bin/login, otherwise it will run ssh +- localhost. To use an other command use the -c option. +- +- * By default Ajaxterm only listen at 127.0.0.1:8022. For remote access, it is +- strongly recommended to use '''https SSL/TLS''', and that is simple to +- configure if you use the apache web server using mod_proxy.[[BR]][[BR]] +- Using ssl will also speed up ajaxterm (probably because of keepalive).[[BR]][[BR]] +- Here is an configuration example: +- +-{{{ +- Listen 443 +- NameVirtualHost *:443 +- +- +- ServerName localhost +- SSLEngine On +- SSLCertificateKeyFile ssl/apache.pem +- SSLCertificateFile ssl/apache.pem +- +- ProxyRequests Off +- +- Order deny,allow +- Allow from all +- +- ProxyPass /ajaxterm/ http://localhost:8022/ +- ProxyPassReverse /ajaxterm/ http://localhost:8022/ +- +-}}} +- +- * Using GET HTTP request seems to speed up ajaxterm, just click on GET in the +- interface, but be warned that your keystrokes might be loggued (by apache or +- any proxy). I usually enable it after the login. +- +- * Ajaxterm commandline usage: +- +-{{{ +-usage: ajaxterm.py [options] +- +-options: +- -h, --help show this help message and exit +- -pPORT, --port=PORT Set the TCP port (default: 8022) +- -cCMD, --command=CMD set the command (default: /bin/login or ssh localhost) +- -l, --log log requests to stderr (default: quiet mode) +- -d, --daemon run as daemon in the background +- -PPIDFILE, --pidfile=PIDFILE +- set the pidfile (default: /var/run/ajaxterm.pid) +- -iINDEX_FILE, --index=INDEX_FILE +- default index file (default: ajaxterm.html) +- -uUID, --uid=UID Set the daemon's user id +-}}} +- +- * Ajaxterm was first written as a demo for qweb (my web framework), but +- actually doesn't use many features of qweb. +- +- * Compared to anyterm: +- * There are no partial updates, ajaxterm updates either all the screen or +- nothing. That make the code simpler and I also think it's faster. HTTP +- replies are always gzencoded. When used in 80x25 mode, almost all of +- them are below the 1500 bytes (size of an ethernet frame) and we just +- replace the screen with the reply (no javascript string handling). +- * Ajaxterm polls the server for updates with an exponentially growing +- timeout when the screen hasn't changed. The timeout is also resetted as +- soon as a key is pressed. Anyterm blocks on a pending request and use a +- parallel connection for keypresses. The anyterm approch is better +- when there aren't any keypress. +- +- * Ajaxterm files are released in the Public Domain, (except [http://sarissa.sourceforge.net/doc/ sarissa*] which are LGPL). +- +-== TODO == +- +- * insert mode ESC [ 4 h +- * change size x,y from gui (sending signal) +- * vt102 graphic codepage +- * use innerHTML or prototype instead of sarissa +- ++= [http://antony.lesuisse.org/qweb/trac/wiki/AjaxTerm Ajaxterm] = ++ ++Ajaxterm is a web based terminal. It was totally inspired and works almost ++exactly like http://anyterm.org/ except it's much easier to install (see ++comparaison with anyterm below). ++ ++Ajaxterm written in python (and some AJAX javascript for client side) and depends only on python2.3 or better.[[BR]] ++Ajaxterm is '''very simple to install''' on Linux, MacOS X, FreeBSD, Solaris, cygwin and any Unix that runs python2.3.[[BR]] ++Ajaxterm was written by Antony Lesuisse (email: al AT udev.org), License Public Domain. ++ ++Use the [/qweb/forum/viewforum.php?id=2 Forum], if you have any question or remark. ++ ++== News == ++ ++ * 2006-10-29: v0.10 allow space in login, cgi launch fix, redhat init ++ * 2006-07-12: v0.9 change uid, daemon fix (Daniel Fischer) ++ * 2006-07-04: v0.8 add login support to ssh (Sven Geggus), change max width to 256 ++ * 2006-05-31: v0.7 minor fixes, daemon option ++ * 2006-05-23: v0.6 Applied debian and gentoo patches, renamed to Ajaxterm, default port 8022 ++ ++== Download and Install == ++ ++ * Release: [/qweb/files/Ajaxterm-0.10.tar.gz Ajaxterm-0.10.tar.gz] ++ * Browse src: [/qweb/trac/browser/trunk/ajaxterm/ ajaxterm/] ++ ++To install Ajaxterm issue the following commands: ++{{{ ++wget http://antony.lesuisse.org/qweb/files/Ajaxterm-0.10.tar.gz ++tar zxvf Ajaxterm-0.10.tar.gz ++cd Ajaxterm-0.10 ++./ajaxterm.py ++}}} ++Then point your browser to this URL : http://localhost:8022/ ++ ++== Screenshot == ++ ++{{{ ++#!html ++
ajaxterm screenshot
++}}} ++ ++== Documentation and Caveats == ++ ++ * Ajaxterm only support utf8. ++ ++ * If run as root ajaxterm will run /bin/login, otherwise it will run ssh ++ localhost. To use an other command use the -c option. ++ ++ * By default Ajaxterm only listen at 127.0.0.1:8022. For remote access, it is ++ strongly recommended to use '''https SSL/TLS''', and that is simple to ++ configure if you use the apache web server using mod_proxy.[[BR]][[BR]] ++ Using ssl will also speed up ajaxterm (probably because of keepalive).[[BR]][[BR]] ++ Here is an configuration example: ++ ++{{{ ++ Listen 443 ++ NameVirtualHost *:443 ++ ++ ++ ServerName localhost ++ SSLEngine On ++ SSLCertificateKeyFile ssl/apache.pem ++ SSLCertificateFile ssl/apache.pem ++ ++ ProxyRequests Off ++ ++ Order deny,allow ++ Allow from all ++ ++ ProxyPass /ajaxterm/ http://localhost:8022/ ++ ProxyPassReverse /ajaxterm/ http://localhost:8022/ ++ ++}}} ++ ++ * Using GET HTTP request seems to speed up ajaxterm, just click on GET in the ++ interface, but be warned that your keystrokes might be loggued (by apache or ++ any proxy). I usually enable it after the login. ++ ++ * Ajaxterm commandline usage: ++ ++{{{ ++usage: ajaxterm.py [options] ++ ++options: ++ -h, --help show this help message and exit ++ -pPORT, --port=PORT Set the TCP port (default: 8022) ++ -cCMD, --command=CMD set the command (default: /bin/login or ssh localhost) ++ -l, --log log requests to stderr (default: quiet mode) ++ -d, --daemon run as daemon in the background ++ -PPIDFILE, --pidfile=PIDFILE ++ set the pidfile (default: /var/run/ajaxterm.pid) ++ -iINDEX_FILE, --index=INDEX_FILE ++ default index file (default: ajaxterm.html) ++ -uUID, --uid=UID Set the daemon's user id ++}}} ++ ++ * Ajaxterm was first written as a demo for qweb (my web framework), but ++ actually doesn't use many features of qweb. ++ ++ * Compared to anyterm: ++ * There are no partial updates, ajaxterm updates either all the screen or ++ nothing. That make the code simpler and I also think it's faster. HTTP ++ replies are always gzencoded. When used in 80x25 mode, almost all of ++ them are below the 1500 bytes (size of an ethernet frame) and we just ++ replace the screen with the reply (no javascript string handling). ++ * Ajaxterm polls the server for updates with an exponentially growing ++ timeout when the screen hasn't changed. The timeout is also resetted as ++ soon as a key is pressed. Anyterm blocks on a pending request and use a ++ parallel connection for keypresses. The anyterm approch is better ++ when there aren't any keypress. ++ ++ * Ajaxterm files are released in the Public Domain, (except [http://sarissa.sourceforge.net/doc/ sarissa*] which are LGPL). ++ ++== TODO == ++ ++ * insert mode ESC [ 4 h ++ * change size x,y from gui (sending signal) ++ * vt102 graphic codepage ++ * use innerHTML or prototype instead of sarissa ++ +diff --git a/ajaxterm.1 b/ajaxterm.1 +index 8d0a942..29d8250 100644 +--- a/ajaxterm.1 ++++ b/ajaxterm.1 +@@ -20,6 +20,8 @@ A summary of the options supported by \fBajaxterm\fR is included below. + .SH AUTHOR + Antony Lesuisse + ++Adopted to UTF-8 by Sergej Pupykin ++ + This manual page was written for the Debian system by + Julien Valroff (but may be used by others). + +diff --git a/ajaxterm.html b/ajaxterm.html +index 095e7d6..2cc48ef 100644 +--- a/ajaxterm.html ++++ b/ajaxterm.html +@@ -8,6 +8,7 @@ + + + ++ +