Skip to Content.
Sympa Menu

idok-commit - [idok-commit] idok commit r46 - trunk/python/pydok/test

idok-commit AT lists.psi.ch

Subject: Commit emails of the iDok project

List archive

[idok-commit] idok commit r46 - trunk/python/pydok/test


Chronological Thread 
  • From: "AFS account Roman Geus" <geus AT savannah.psi.ch>
  • To: idok-commit AT lists.psi.ch
  • Subject: [idok-commit] idok commit r46 - trunk/python/pydok/test
  • Date: Fri, 14 Mar 2008 16:02:41 +0100
  • List-archive: <https://lists.web.psi.ch/pipermail/idok-commit/>
  • List-id: Commit emails of the iDok project <idok-commit.lists.psi.ch>

Author: geus
Date: Fri Mar 14 16:02:40 2008
New Revision: 46

Log:
Improved rebustness of idok_upload_cgi.py: implemented proper quoting of
URLs, html attributes and CLI command strings, implemented validation of all
input parameters

Modified:
trunk/python/pydok/test/idok_upload_cgi.py

Modified: trunk/python/pydok/test/idok_upload_cgi.py
==============================================================================
--- trunk/python/pydok/test/idok_upload_cgi.py (original)
+++ trunk/python/pydok/test/idok_upload_cgi.py Fri Mar 14 16:02:40 2008
@@ -30,7 +30,8 @@
* Fallback to basic authentication
"""

-import cgi, os, sys, tempfile, urllib, StringIO
+import cgi, os, re, sys, tempfile, urllib, StringIO
+from xml.sax.saxutils import escape, quoteattr

# Enable HTML formatted stack traces
import cgitb; cgitb.enable()
@@ -76,7 +77,13 @@
clienthandler = ClientHandler_i(IDOK, file_buf)
clienthandler_servant = clienthandler._this()
cli_service = IDOK.cli_factory_service.create(clienthandler_servant)
- cli_service.sendCommand(command)
+ buf = StringIO.StringIO()
+ if type(command) == type([]):
+ for arg in command:
+ buf.write('"%s" ' % arg.replace('"', r'\"'))
+ else:
+ buf.write(command)
+ cli_service.sendCommand(buf.getvalue())
return file_buf.getvalue()

def idok_get_subdirs(url):
@@ -104,9 +111,9 @@
if idx == -1:
idx = pathname.rfind(":")
if base_url[-1] == "/":
- return base_url + pathname[idx+1:]
+ return base_url + urllib.quote(pathname[idx+1:])
else:
- return base_url + "/" + pathname[idx+1:]
+ return base_url + "/" + urllib.quote(pathname[idx+1:])

def generate_self_url(output_mode, page, repository, folder):
"Return url to the idok_upload_cgi.py with GET parameters"
@@ -116,17 +123,41 @@
urllib.quote_plus(folder),
urllib.quote_plus(repository))

+def validate_params(repository=None, folder=None, output_mode=None,
+ callback=None, new_folder=None, page=None):
+ "Validate CGI parameters"
+ if folder is not None:
+ if not
re.match(r"$|(?:[^./][^/]*|\.[^./][^/]*|\.\.[^/]+)(?:/[^./][^/]*|/\.[^./][^/]*|/\.\.[^/]+)*$",
folder):
+ raise ValueError("folder=%s" % folder)
+ if repository is not None:
+ if not re.match(r"[a-zA-Z]\w*/[a-zA-Z]\w*$", repository):
+ raise ValueError("repository=%s" % repository)
+ if output_mode not in [None, "standalone", "js", "iframe"]:
+ raise ValueError("output_mode=%s" % output_mode)
+ if callback is not None:
+ if not re.match(r"[a-zA-Z]\w*$", repository):
+ raise ValueError("callback=%s" % callback)
+ if new_folder is not None:
+ if not re.match(r"(?:[^./][^/]*|\.[^./][^/]*|\.\.[^/]+)$",
new_folder):
+ raise ValueError("new_folder=%s" % new_folder)
+ if page not in [None, "folder", "upload"]:
+ raise ValueError("page=%s" % page)
+
def page_choose_folder(form):
"Handle page for choosing or creating the destination folder"
output_mode = form.getfirst("output_mode", "standalone")
repository = form.getfirst("repository", DEFAULT_REPOSITORY)
folder = form.getfirst("folder", "")
new_folder = form.getfirst("new_folder")
+ validate_params(output_mode=output_mode,
+ repository=repository,
+ folder=folder,
+ new_folder=new_folder)
url = BASE_URL + urllib.pathname2url(repository) + "/" +
urllib.pathname2url(folder)
# Create new folder if requested
if new_folder:
- new_url = url + "/" + new_folder
- idok_cli('mkdir -m "Folder created by pydok" "%s"' % new_url)
+ new_url = url + "/" + urllib.quote(new_folder)
+ idok_cli(["mkdir", "-m", "Created by idok_upload_cgi.py", new_url])
fo = StringIO.StringIO()
fo.write('<h1>Upload to iDok</h1>')
fo.write('<h2>Step 1 - Choose destination folder</h2>')
@@ -143,10 +174,10 @@
# Create new folder form
fo.write('<form action="idok_upload_cgi.py" method="post">')
fo.write('<p>Create new subfolder: <input name="new_folder" type="text"
size="30" maxlength="30"><input type="submit" value=" Create "></p>')
- fo.write('<input type="hidden" name="output_mode" value="%s">' %
output_mode)
+ fo.write('<input type="hidden" name="output_mode" value=%s>' %
quoteattr(output_mode))
fo.write('<input type="hidden" name="page" value="folder">')
- fo.write('<input type="hidden" name="repository" value="%s">' %
repository)
- fo.write('<input type="hidden" name="folder" value="%s">' % folder)
+ fo.write('<input type="hidden" name="repository" value=%s>' %
quoteattr(repository))
+ fo.write('<input type="hidden" name="folder" value=%s>' %
quoteattr(folder))
fo.write('</form>')
# Link to sub folders
dir_entries = idok_get_subdirs(url)
@@ -159,15 +190,15 @@
else:
subfolder = folder + "/" + entry
subfolder_url = generate_self_url(output_mode, "folder",
repository, subfolder)
- fo.write('<li><a href="%s">%s</a></li>' % (subfolder_url, entry))
+ fo.write('<li><a href="%s">%s</a></li>' % (subfolder_url,
escape(entry)))
fo.write('</ul>')
# Continue button
fo.write('<form action="idok_upload_cgi.py" method="post">')
fo.write('<p><input type="submit" value="Continue"></p>')
- fo.write('<input type="hidden" name="output_mode" value="%s">' %
output_mode)
+ fo.write('<input type="hidden" name="output_mode" value=%s>' %
quoteattr(output_mode))
fo.write('<input type="hidden" name="page" value="upload">')
- fo.write('<input type="hidden" name="repository" value="%s">' %
repository)
- fo.write('<input type="hidden" name="folder" value="%s">' % folder)
+ fo.write('<input type="hidden" name="repository" value=%s>' %
quoteattr(repository))
+ fo.write('<input type="hidden" name="folder" value=%s>' %
quoteattr(folder))
fo.write('</form>')
print "Content-Type: text/html; charset=utf-8"
print
@@ -185,13 +216,16 @@
callback = form.getfirst("callback")
repository = form.getfirst("repository", DEFAULT_REPOSITORY)
folder = form.getfirst("folder", "")
+ validate_params(output_mode=output_mode,
+ callback=callback,
+ repository=repository,
+ folder=folder)
dest_folder_url = BASE_URL + urllib.pathname2url(repository) + "/" +
urllib.pathname2url(folder)
-
fo = StringIO.StringIO()
fo.write("<h1>Upload to iDok</h1>")
fo.write('<h2>Step 2 - Choose file to upload</h2>')
fo.write('<p>Files will be uploaded to <a href="%s"
target="_blank">%s</a></p>' %
- (dest_folder_url, dest_folder_url))
+ (dest_folder_url, escape(dest_folder_url)))
# Choose file form
fo.write("""<form action="idok_upload_cgi.py" method="post"
enctype="multipart/form-data">
<p>Choose a file to upload:
@@ -199,10 +233,10 @@
</p>
<p><input type="submit" value=" Upload "></p>
""")
- fo.write('<input type="hidden" name="output_mode" value="%s">' %
output_mode)
+ fo.write('<input type="hidden" name="output_mode" value=%s>' %
quoteattr(output_mode))
fo.write('<input type="hidden" name="page" value="upload">')
- fo.write('<input type="hidden" name="repository" value="%s">' %
repository)
- fo.write('<input type="hidden" name="folder" value="%s">' % folder)
+ fo.write('<input type="hidden" name="repository" value=%s>' %
quoteattr(repository))
+ fo.write('<input type="hidden" name="folder" value=%s>' %
quoteattr(folder))
fo.write("</form>")
# Perform upload
if form.has_key("upload_file"):
@@ -223,23 +257,22 @@
temp_file_name = fileitem.file.name

file_size = os.stat(temp_file_name).st_size
- command = 'put -m "Imported by idok_upload_cgi.py" %s %s' % \
- (temp_file_name, dest_url)
try:
- output = idok_cli(command)
+ output = idok_cli(["put", "-m", "Imported by
idok_upload_cgi.py",
+ temp_file_name, dest_url])
fo.write("<h2>iDok CLI service output</h2>")
- fo.write("<pre>%s</pre>" % output)
+ fo.write("<pre>%s</pre>" % escape(output))
fo.write('<p>Local file <i>%s</i> uploaded to <a
href="%s">%s</a> (%d bytes)</p>' % \
- (fileitem.filename, dest_url, dest_url, file_size))
+ (escape(fileitem.filename), dest_url, dest_url,
file_size))
if output_mode == "iframe":
output_mode = "location"
except ServiceException, se:
fo.write("<h2>iDok CLI service output</h2>")
- fo.write("<p><b>iDok CLI service returned the following
error</b>: %s</p>" % se.userMessage)
+ fo.write("<p><b>iDok CLI service returned the following
error</b>: %s</p>" % escape(se.userMessage))
if se.detailedMessage:
- fo.write("<h3>Detailed message</h3><pre>%s</pre>" %
se.detailedMessage)
+ fo.write("<h3>Detailed message</h3><pre>%s</pre>" %
escape(se.detailedMessage))
if se.stackTrace:
- fo.write("<h3>Stack trace</h3><pre>%s</pre>" %
se.stackTrace)
+ fo.write("<h3>Stack trace</h3><pre>%s</pre>" %
escape(se.stackTrace))
if tempf:
# Close and remove the temporary file
tempf.close()
@@ -276,6 +309,7 @@
"Main CGI function"
form = MyFieldStorage()
page = form.getfirst("page", "folder")
+ validate_params(page=page)
if page == "upload":
page_upload(form)
else:



  • [idok-commit] idok commit r46 - trunk/python/pydok/test, AFS account Roman Geus, 03/14/2008

Archive powered by MHonArc 2.6.19.

Top of Page