psychoone7 / pyftpdlib

Automatically exported from code.google.com/p/pyftpdlib
Other
0 stars 0 forks source link

Connects to directory outside of specified root (or home directory) #258

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Connect with Cyberduck (FTP client) with path as '/'
2. Change directory without error (even when 'e' is not a specified permission)

What is the expected output?
It should connect me to the user's home directory and not let me change 
directory.

What do you see instead?
It connects me to root '/'.  This problem only exists with some FTP clients 
while others connect to the proper place and deny changing directories.

What version of pyftpdlib are you using? 1.2.0
On what operating system?  CentOS 6.4
Which Python version? 2.6.6

Please provide any additional information below.

Original issue reported on code.google.com by bmgarns on 7 May 2013 at 4:06

GoogleCodeExporter commented 9 years ago
I don't get it.
Note that by using AbstractedFS the client sees "/" but the real filesystem 
directory is different (e.g. "/home/user").
Anyway, please try to be more clear.

Original comment by g.rodola on 7 May 2013 at 5:27

GoogleCodeExporter commented 9 years ago
Here's the lines in my code:

authorizer = DummyAuthorizer()
authorizer.add_user('user','pass','/home/user',perm='lwm')
handler.abstracted_fs = UnixFilesystem

When connecting with Fetch or command line FTP from a Mac, I see the directory 
contents of '/home/user' and cannot change directories.  When I connect with 
Cyberduck, I see the directory contents of '/' and can change into any 
directory I want.

When I remove the "handler.abstracted_fs = UnixFilesystem" line, then in 
Cyberduck I see the directory contents of '/home/user', but I can still change 
directory into any directory that is listed below '/home/user'.

Does that help?

Original comment by bmgarns on 7 May 2013 at 6:37

GoogleCodeExporter commented 9 years ago
> When connecting with Fetch or command line FTP from a Mac, I see the 
directory contents of '/home/user' and cannot change directories.  

What does it mean "cannot change directories". What's the server response?

Original comment by g.rodola on 8 May 2013 at 2:25

GoogleCodeExporter commented 9 years ago
The response when I try to change directories from command line or Fetch is:

550 Not enough privileges.

Original comment by bmgarns on 8 May 2013 at 8:54

GoogleCodeExporter commented 9 years ago
Well, ain't that clear? You don't have enough permissions.
In detail you're missing the "e" permission. 
When specifying the user instead of:

authorizer.add_user('user','pass','/home/user',perm='lwm')

...do:

authorizer.add_user('user','pass','/home/user',perm='lwme')

...or if you want to assign full write permissions:

authorizer.add_user('user','pass','/home/user',perm='elradfmwM')

I'm going to close this out as invalid.

Original comment by g.rodola on 9 May 2013 at 9:16

GoogleCodeExporter commented 9 years ago
"Well, ain't that clear? You don't have enough permissions.
In detail you're missing the "e" permission."

I think that *is* the behaviour that the OP wants/expects (not being able to 
change directory). From what I can tell the bug report seems to be that (for 
some reason) 'Cyberduck' isn't enforcing this lack-of-permissions.

Original comment by gc...@loowis.durge.org on 9 May 2013 at 9:37

GoogleCodeExporter commented 9 years ago
The "550 Not enough privileges" response is correct, but Cyberduck is not being 
restricted by those permissions.  Those permissions should be implemented in 
the server side, so the client is limited to them.  Cyberduck may have a bug, 
but it is not the client's responsibility to enforce rules that should be 
controlled and enforced at the server side.  I'm not sure I understand how this 
is not a bug in pyftpdlib...

Original comment by bmgarns on 10 May 2013 at 2:31

GoogleCodeExporter commented 9 years ago
I have another user that is connecting to my implementation of pyftpdlib, and 
he can change directory all over in the ftp root (even though I've not provided 
that right to them).  I need to be able to restrict them from changing 
directories in their program or in Cyberduck.

I hope that makes sense...thank you!

Original comment by bmgarns on 10 May 2013 at 2:33

GoogleCodeExporter commented 9 years ago
At this point I'm not sure what you think is a bug with pyftpdlib or what 
pyftpdlib should do differently.

Is it that Cyberduck ignores the 550 reply?

It's likely I'm misinterpreting what you write (the fact that it's 4:00 AM in 
the morning might not help either =)).
Andrew, perhaps you have a better understanding of the issue at hand?

Original comment by g.rodola on 10 May 2013 at 2:37

GoogleCodeExporter commented 9 years ago
If I connect with Cyberduck, it shows me the contents of the ftp root.  In
the server, I have only specified 'lwm' permissions.  With those
permissions stated, if I understand things correctly, I should not be able
to display the contents of a sub directory.  However, in Cyberduck, it does
display the contents of any directory below the ftp root.  Looking at the
ftp log, a 550 is never even sent to Cyberduck from the server.  It's
almost like Cyberduck gets connected and finds a hole where it is no longer
limited by the permissions specified.

Does that help?

Original comment by bmgarns on 10 May 2013 at 2:46

GoogleCodeExporter commented 9 years ago
If it helps, and you have a mac, I can provide you with a dummy account to 
connect to my server and you can see what I'm talking about.  I can also 
provide you with the code I've written.  Thank you!

Original comment by bmgarns on 10 May 2013 at 2:47

GoogleCodeExporter commented 9 years ago
Ok, perhaps I'm getting it now. 
With 'l' permission bit set you are allowed to list directories (also *sub* 
directories), therefore it is expected that pyftpdlib lets you do that, even if 
you don't have the 'e' (change dir) permission bit set.

That is not a bug.

I should see the server log in order to be sure, but what Cyberduck might be 
(successfully) doing is "LIST sub/directory".  
On the other hand, if it were to submit "CWD sub/directory" it would get 550.

If you want to allow directory listing for a specific directory only then you 
have to use override_perm() method (I'll provide a code sample if you have 
problems).

Original comment by g.rodola on 10 May 2013 at 3:01

GoogleCodeExporter commented 9 years ago
Ah...ok.  That sounds right.  In that case, I didn't realize that the 'l'
included sub directories.  Is that the way a normal FTP server works?

Original comment by bmgarns on 10 May 2013 at 3:04

GoogleCodeExporter commented 9 years ago
When it comes to permissions I don't know other servers with this level of 
granularity.

But bear in mind that by using DummyAuthorizer you're dealing with a *virtual* 
user, that's why you need to specify permissions in the first place.

Other FTP servers are usually configured for using *real* users and the 
permissions (in respect to a certain filesystem path) are automatically 
inherited from the operating system. Basically you don't have to "configure" 
permissions at all.
If you want that same behavior with pyftpdlib you have to use UnixAuthorizer 
class.

Original comment by g.rodola on 10 May 2013 at 3:21

GoogleCodeExporter commented 9 years ago
I tried that first actually, but it allowed users to walk all over the
general filesystem because normally users have rights to several different
areas in the filesystem.  However, in this case, I need to restrict the
users to the ftp root directory.

Original comment by bmgarns on 10 May 2013 at 3:41

GoogleCodeExporter commented 9 years ago
If you want to "chroot jail" your users in their home directory but still take 
advantage of the UnixAuthorizer (which uses /etc/shadow and actually 
impersonate users by changing server process PID) then you may want to use 
UnixAuthorizer and AbstractedFS class for the filesystem.

Original comment by g.rodola on 10 May 2013 at 3:47

GoogleCodeExporter commented 9 years ago
"With 'l' permission bit set you are allowed to list directories (also *sub* 
directories), therefore it is expected that pyftpdlib lets you do that, even if 
you don't have the 'e' (change dir) permission bit set.

That is not a bug.

I should see the server log in order to be sure, but what Cyberduck might be 
(successfully) doing is "LIST sub/directory".  
On the other hand, if it were to submit "CWD sub/directory" it would get 550."

I can certainly see why this behaviour would be surprising to bmgarns, 
especially as it seems different FTP clients implement "list subdirectory" in 
different ways!

Giampaolo: you say "list directories (also *sub* directories)" - from what 
bmgarns is saying it sounds like with 'l' permission you can also list parent 
directories too?

I think it would definitely be worth adding a note to the documentation 
mentioning this (and the fact that not all FTP clients work in the same way) 
and/or providing a code sample (if it's not too difficult) that indeed 
restricts which directories you can LIST.

Original comment by gc...@loowis.durge.org on 10 May 2013 at 9:04

GoogleCodeExporter commented 9 years ago
> Giampaolo: you say "list directories (also *sub* directories)" - 
> from what bmgarns is saying it sounds like with 'l' permission 
> you can also list parent directories too?

Not by using AbstractedFS since that emulates a UNIX chroot jail where the user
cannot escape its home directory ("/home/user" will be seen as "/" by client).

I will provide an example on how to restrict access to certain directories only 
by using override_perm().

Original comment by g.rodola on 10 May 2013 at 3:52

GoogleCodeExporter commented 9 years ago
Where might one find your example?  I'm interested...

Thanks!

Original comment by bmgarns on 16 May 2013 at 4:16

GoogleCodeExporter commented 9 years ago
See issue 259 (but for the home dir you can't do it right now).

Original comment by g.rodola on 16 May 2013 at 8:48