1 # Copyright (C) 2008-2009, Eduardo Silva <edsiper@gmail.com>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 def __init__(self
, name
, socket
, parent
):
34 # On child end, re-create it
35 signal
.signal(signal
.SIGCHLD
, self
._child
_exit
)
42 opts
= self
.parent
.opts
.split()
46 self
.c
= {'bin': self
.parent
.bin
, 'opts': opts
}
53 msg
= " Creating '%s' child PID %i" % (self
.name
, pid
)
59 def _child_exit(self
,a
, b
):
61 debug("[-] Exit child '%s'" % self
.name
)
72 if buf
[-4:] == '\r\n\r\n':
77 def parse_request(self
, data
):
78 arr
= data
.split('\r\n')
84 request
= Request(line
)
94 if key
== 'POST_VARS' and len(val
) > 0:
98 request
.add_header(key
, val
)
101 # Post-parse POST data
102 if request
.get('POST_VARS') == '*':
103 init_key
= '\r\nPOST_VARS='
104 len_key
= len(init_key
)
106 post_len
= int(request
.get('CONTENT_LENGTH'))
107 post_data
= data
.find(init_key
)
110 offset_init
= post_data
+ len_key
111 offset_end
= post_data
+ len_key
+ post_len
114 request
.add_header('POST_VARS', data
[offset_init
:offset_end
])
117 debug("[+] Invalid Exit")
121 msg
= "[+] Request Headers\n"
122 for h
in request
.headers
:
123 msg
+= ' ' + h
+ ' = \'' + request
.headers
[h
] + '\'\n'
124 msg
+= "[-] Request End"
129 def start_loop(self
):
130 # Creating epoll for read pipe side
132 remote
, info
= self
._s
.accept()
133 remote_fd
= remote
.fileno()
136 flags
= fcntl
.fcntl(remote_fd
, fcntl
.F_GETFD
)
138 flags |
= fcntl
.FD_CLOEXEC
139 except AttributeError, e
:
142 fcntl
.fcntl(remote_fd
, fcntl
.F_SETFD
, flags
)
144 debug("[+] |%s| Request arrived [PID=%i]" % (self
.name
, os
.getpid()))
146 buf
= self
.read(remote
)
148 request
= self
.parse_request(buf
)
150 if self
.c
['bin'] is None:
151 bin
= request
.resource
155 if self
.c
['opts'] is None and bin
!= request
.resource
:
156 opts
= [request
.resource
]
158 opts
= self
.c
['opts']
159 opts
.append(request
.resource
)
162 print request
.headers
['POST_VARS']
165 os
.dup2(remote
.fileno(), sys
.stdout
.fileno())
167 # Write Post data to STDIN (Pipe)
168 if request
.headers
['REQUEST_METHOD'] == 'POST':
169 # Temporal Pipe > STDIN
170 pipe_r
, pipe_w
= os
.pipe()
171 os
.dup2(pipe_r
, sys
.stdin
.fileno())
172 os
.write(pipe_w
, request
.headers
['POST_VARS'])
174 os
.execve(bin
, opts
, request
.headers
)
176 print "Content-Type: text/plain\r\n\r\n"
178 print "*** INTERNAL ERROR ***"
181 print "Child Executing"
182 print "---------------"
186 print "Palm Enviroment variables"
187 print "-------------------------"
188 for h
in request
.headers
:
189 print h
, "=", request
.headers
[h
]
197 os
.kill(self
._pid
, signal
.SIGKILL
)
200 def __init__(self
, resource
):
201 self
.resource
= resource
205 ret
= str(self
.resource
) + ' ' + str(self
.headers
);
208 def add_header(self
, key
, val
):
209 self
.headers
[key
] = val
212 return self
.headers
[key
]