summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Bird <nathan@acceleration.net>2013-11-01 10:22:08 -0400
committerNathan Bird <nathan@acceleration.net>2013-11-01 10:22:08 -0400
commit3481af83d7f0f298bec38e933df3991558b62184 (patch)
tree90a18389cb94f545156e703ae00839fab2f6e86b
parentd55b7b3f6866df1b76f8dd88c944d633b62a37e2 (diff)
downloadtftpy-3481af83d7f0f298bec38e933df3991558b62184.tar.gz
Fixing #11: server accept leading '/' in uploads
Some devices, when uploading, always have a leading '/' that led to the joined path being outside the server's root directory causing "bad file path" TftpExceptions. The only way to work around this is if the remote client knew the full path on this server (unnecessarily tight coupling). This patch removes the leading '/' so that all paths are relative to the server's root directory. To help preserve backwards compatibility there is an exception to the above rule that if the client's specified path starts with the server's root directory then accept it.
-rw-r--r--tftpy/TftpStates.py23
1 files changed, 20 insertions, 3 deletions
diff --git a/tftpy/TftpStates.py b/tftpy/TftpStates.py
index 6f71685..1ea6c31 100644
--- a/tftpy/TftpStates.py
+++ b/tftpy/TftpStates.py
@@ -249,9 +249,26 @@ class TftpServerState(TftpState):
log.debug("Requested filename is %s", pkt.filename)
- # Make sure that the path to the file is contained in the server's
- # root directory.
- full_path = os.path.join(self.context.root, pkt.filename)
+ # Build the filename on this server and ensure it is contained
+ # in the specified root directory.
+ #
+ # Filenames that begin with server root are accepted. It's
+ # assumed the client and server are tightly connected and this
+ # provides backwards compatibility.
+ #
+ # Filenames otherwise are relative to the server root. If they
+ # begin with a '/' strip it off as otherwise os.path.join will
+ # treat it as absolute (regardless of whether it is ntpath or
+ # posixpath module
+ if pkt.filename.startswith(self.context.root):
+ full_path = pkt.filename
+ else:
+ full_path = os.path.join(
+ self.context.root, pkt.filename.lstrip('/'))
+
+ # Use abspath to eliminate any remaining relative elements
+ # (e.g. '..') and ensure that is still within the server's
+ # root directory
self.full_path = os.path.abspath(full_path)
log.debug("full_path is %s", full_path)
if self.full_path.startswith(self.context.root):