diff options
author | Nathan Bird <nathan@acceleration.net> | 2013-11-01 10:22:08 -0400 |
---|---|---|
committer | Nathan Bird <nathan@acceleration.net> | 2013-11-01 10:22:08 -0400 |
commit | 3481af83d7f0f298bec38e933df3991558b62184 (patch) | |
tree | 90a18389cb94f545156e703ae00839fab2f6e86b | |
parent | d55b7b3f6866df1b76f8dd88c944d633b62a37e2 (diff) | |
download | tftpy-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.py | 23 |
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): |