From: Jan E. <je...@co...> - 2007-06-23 15:54:27
|
(This mail is duplicated separately to the pam-mount-user and dav-linuxfs (no Cc) because not everyone is cross-subscribed. Mostly davfs anyway, and just an info for pam_mount.) Hello everyone, today I took a look at davfs2 and why it does not work with pam_mount. Let's note that pam_mount passes the password to /bin/mount over (/bin/mount's) stdin descriptor. mount then passes it on to /sbin/mount.davfs2. The problem lies in mount.davfs2, which asks for a username first. There does not seem to be a way to pass the username as an argument, which would be the required thing. Want a hint? Look at mount.cifs. (-o user) (On top, cifs supports -o password as a last resort to passing-in via stdin.) Then there is the issue that users experienced truncation of input. Yes, the following line in davfs2 is the culprit: args->p_user = ne_strndup(s, len - 1); args->username = ne_strndup(s, len - 1); and perhaps other ones. Do not ever assume a line is always terminated with \n, because _it is not_. pam_mount sends the password without an \n. After all, /bin/mount reads _only_ a password, and nothing more, so that's established protocol. As for the matter, try something like HX_chomp() [1]. What also catched my eye is that davfs2 uses getpass(). The manpage for that says it is obsolete. The manpage also says this opens /dev/tty for asking for a password, which does not quite fly with PAM either. Thanks, Jan [1] https://dev.computergmbh.de/svn/libHX/trunk/src/string.c -- |
From: Werner B. <wer...@on...> - 2007-06-23 21:07:07
|
I am still missing arguments why not to use the standard way to pass credentials to davfs2: the secrets file. Please tell me. After all: there will rarely be cases where the login password is the same as the webdav password. So editing the secrets file is not an extra effort. > Do not ever assume a line is always terminated > with \n, because _it is not_. pam_mount sends the password without an > \n. After all, /bin/mount reads _only_ a password, and nothing more, so > that's established protocol. I will change this. But I would be interested in some documentation about this 'established protocol'. (pam_mount is just an application, not a protocol). What was the need to introduce lines that are not terminated by a new line? getpass(): There seems to be some confusion in the documentation (man page : The GNU C Library Reference Manual). But I agree that trying to get the real tty is problematic. So I will return to the handmade code that reads from stdin. Cheers Werner |
From: Jan E. <je...@co...> - 2007-06-23 21:47:48
|
On Jun 23 2007 23:06, Werner Baumann wrote: > > I am still missing arguments why not to use the standard way to > pass credentials to davfs2: the secrets file. Please tell me. After > all: there will rarely be cases where the login password is the > same as the webdav password. Users wanting to use pam_mount with davfs2 know that their regular PAM password will be used for any mounting. Hence, they have their webdav one set accordingly. > So editing the secrets file is not an extra effort. Users cannot edit the files in /etc/davfs2. >> Do not ever assume a line is always terminated >> with \n, because _it is not_. pam_mount sends the password without an >> \n. After all, /bin/mount reads _only_ a password, and nothing more, so >> that's established protocol. > > I will change this. But I would be interested in some documentation > about this 'established protocol'. (pam_mount is just an > application, not a protocol). What was the need to introduce lines > that are not terminated by a new line? Right... I am referring to samba-3.0.25a/source/client/mount.cifs.c:get_password_from_file(). Apparently, it allows for an \n to be present, but it is known to also accept input that is just the bare password without any \n. util-linux-2.12r+git20070530/mount/lomount.c:xgetpass() does the same (accepting either \n or no \n). The 'protocol' is described in mount(8), though it does not say anything special about newline in single-key mode. davfs however, always strips a character. > getpass(): There seems to be some confusion in the documentation > (man page : The GNU C Library Reference Manual). But I agree that > trying to get the real tty is problematic. So I will return to the > handmade code that reads from stdin. Don't worry too much about that. lomount also uses getpass :-/ Jan -- |
From: Werner B. <wer...@on...> - 2007-06-24 09:51:45
|
Jan Engelhardt wrote: > Users wanting to use pam_mount with davfs2 know that their regular > PAM password will be used for any mounting. Hence, they have their > webdav one set accordingly. I would not give away the login password to the administrator of some WebDAV server I don't even know. So what kind of WebDAV server are you talking about? Let me guess: some administrator installs a WebDAV server in the LAN as replacement for NFS or CIFS? But note: davfs2 is not intended as a network file system like NFS or CIFS and is not suitable for this. A WebDAV server is not a file server. The WebDAV protocol does not match the file system interface. davfs2 *tries* to map a WebDAV-resource into a file system. But there is no 1:1-mapping, some tweaking and faking is necessary and there will always be some shortcomings. Thats why it seems very impropable to me, that one reasonable has the same password for login and for WebDAV-access. > Users cannot edit the files in /etc/davfs2. Users can't edit the pam_mount configuration files either (I hope so!). The administrator has to set up this for the user, including credentials. So you want root to mount a WebDAV-resource on behalf of the user, but you don't like to tell root the WebDAV credentials. You prefer to tell your login password to the WebDAV administrator instead. I would prefer it the other way round. A possible solution might be: davfs2 allows root to configure a different secrets file in /etc/davfs2/davfs2.conf. This may be different for every mount-point and the secrets file can be under control of the owning user. Currently this is not possible, but it would be an easy change. I will have to think about any security related implications of this. > Right... I am referring to > samba-3.0.25a/source/client/mount.cifs.c:get_password_from_file(). > Apparently, it allows for an \n to be present, but it is known to > also accept input that is just the bare password without any \n. > > util-linux-2.12r+git20070530/mount/lomount.c:xgetpass() does the same > (accepting either \n or no \n). The 'protocol' is described in > mount(8), though it does not say anything special about newline in > single-key mode. O.k. 'established protocol' means 'some others do it also'. I agree that davfs2 should check any input for errors or non-standard behaviour. But, as you are redirecting standard input, you might as well delimit your input with a newline character, instead of trusting on davfs2 to check for this. I am not sure, whether it is really o.k. to treat a missing newline *always* as lazy programming and *not* as an input *error*. But I am sure: all applications that read from stdin are able to treat with a trailing newline, because this is what they usally get. > Don't worry too much about that. lomount also uses getpass :-/ As I understand (I did not test it), getpass() will block, if it finds a real terminal but there is no input from this terminal. lomount only uses getpass when it is sure that the input will come from a terminal. So I think I should change this. Cheers Werner |
From: Jan E. <je...@co...> - 2007-06-24 10:40:40
|
On Jun 24 2007 11:51, Werner Baumann wrote: > Jan Engelhardt wrote: >> Users wanting to use pam_mount with davfs2 know that their regular >> PAM password will be used for any mounting. Hence, they have their >> webdav one set accordingly. > > I would not give away the login password to the administrator of some WebDAV > server I don't even know. So what kind of WebDAV server are you talking about? > Let me guess: some administrator installs a WebDAV server in the LAN as > replacement for NFS or CIFS? What do I knew why users need davfs. Perhaps something like https://ourwebserver.company.com/. > But note: davfs2 is not intended as a network file system like NFS or CIFS and > is not suitable for this. A WebDAV server is not a file server. But people take it like one. https://mediacenter.gmx.de/ is supposed to do DAV. > The WebDAV protocol does not match the file system interface. > davfs2 *tries* to map a WebDAV-resource into a file system. But > there is no 1:1-mapping, some tweaking and faking is necessary and > there will always be some shortcomings. Thats why it seems very > impropable to me, that one reasonable has the same password for > login and for WebDAV-access. No news here, VFAT has similar limitations. >> Users cannot edit the files in /etc/davfs2. > > Users can't edit the pam_mount configuration files either (I hope > so!). The administrator has to set up this for the user, including > credentials. So you want root to mount a WebDAV-resource on behalf > of the user, but you don't like to tell root the WebDAV > credentials. You prefer to tell your login password to the WebDAV > administrator instead. I would prefer it the other way round. That's not my decision, users want it that way. They like SSO and single passwords. (All hard to remember!) And I'd rather much prefer having the same pw on the login box as the DAV server, so as to not keep _additional_ secret phrases _on the filesystem_. > I am not sure, whether it is really o.k. to treat a missing newline > *always* as lazy programming and *not* as an input *error*. But I > am sure: all applications that read from stdin are able to treat > with a trailing newline, because this is what they usally get. They have to treat both cases, because they _cannot_ know. That said, some even have to cope with additional cases like \r\n$ (Windows), in which case ne_strdup(... - 1) is wrong again. Jan -- |
From: Jan E. <je...@co...> - 2007-06-24 12:02:09
|
Here's the patch... - For regular use: properly strips off \n - For pam_mount: adds -o username=XYZ, required so that - davfs2 does not ask for the username (since we only pass the password) (cifs also has -o username, in case the server username is different) --- src/mount_davfs.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) Index: davfs2-1.2.1/src/mount_davfs.c =================================================================== --- davfs2-1.2.1.orig/src/mount_davfs.c +++ davfs2-1.2.1/src/mount_davfs.c @@ -1007,6 +1007,16 @@ static void parse_config(dav_args *args) DBG_ARGS; } +static inline char *HX_chomp(char *s) +{ + char *p = s + strlen(s) - 1; + while(p >= s) { + if(*p != '\n' && *p != '\r') + break; + *p-- = '\0'; + } + return s; +} /* Reads the secrets file and asks the user interactivly for credentials if necessary. The user secrets file is parsed after the system wide secrets @@ -1023,17 +1033,19 @@ static void parse_secrets(dav_args *args char *s = NULL; size_t n = 0; - ssize_t len = 0; + ssize_t len = 0, len2; if (args->askauth && args->useproxy && args->p_user == NULL) { printf(_("Please enter the username to authenticate with proxy\n" "%s or hit enter for none.\nUsername: "), args->p_host); len = getline(&s, &n, stdin); - if (len < 1) + if (len < 0) abort(); - if (len > 1) { - args->p_user = ne_strndup(s, len - 1); - memset(s, '\0', len - 1); + HX_chomp(s); + len2 = strlen(s); + if (len2 > 1) { + args->p_user = ne_strdup(s); + memset(s, '\0', len); } free(s); s = NULL; @@ -1054,11 +1066,13 @@ static void parse_secrets(dav_args *args printf(_("Please enter the username to authenticate with server\n" "%s or hit enter for none.\nUsername: "), url); len = getline(&s, &n, stdin); - if (len < 1) + if (len < 0) abort(); + HX_chomp(s); + len2 = strlen(s); if (len > 1) { - args->username = ne_strndup(s, len - 1); - memset(s, '\0', len - 1); + args->username = ne_strndup(s, len); + memset(s, '\0', len); } free(s); } @@ -1364,6 +1378,7 @@ static void get_options(dav_args *args, AUTO, NOAUTO, DEFAULTS, + USERNAME, END }; char *suboptions[] = { @@ -1394,6 +1409,7 @@ static void get_options(dav_args *args, [AUTO] = "auto", [NOAUTO] = "noauto", [DEFAULTS] = "defaults", + [USERNAME] = "username", [END] = NULL }; @@ -1413,6 +1429,10 @@ static void get_options(dav_args *args, if (args->conf != NULL) free(args->conf); args->conf = ne_strdup(argument); + case USERNAME: + args->p_user = ne_strdup(argument); + args->username = ne_strdup(argument); + break; case UID: pwd = getpwnam(argument); if (pwd == NULL) { |
From: Werner B. <wer...@on...> - 2007-06-24 14:40:28
|
AS I told, I will change this: - check username input from stdin for missing newline and treat it appropriately - replace getpass by code that reads from stdin (not the real tty) and also checks for newline - maybe: allow root to configure an different secrets-file that will belong to the owner of the file system (so root can mount on behalve of a user without knowing the password, that is only known to gmx). Concerning the username option: The commandline option -o is restricted to what is needed by mount and fstab (with the one exception of an alternative configuration file). Everything else (and it is a lot) goes in davfs2.conf and secrets. I can't see a reason to change this. Just complaining "I want to put the username into the pam_mount configuration file and not into the davfs2 secrets file", does not look like an argument. Cheers Werner |
From: Jan E. <je...@co...> - 2007-06-24 15:51:18
|
Hi, On Jun 24 2007 16:39, Werner Baumann wrote: > > Concerning the username option: The commandline option -o is > restricted to what is needed by mount and fstab (with the one > exception of an alternative configuration file). Everything else > (and it is a lot) goes in davfs2.conf and secrets. I can't see a > reason to change this. Just complaining "I want to put the username > into the pam_mount configuration file and not into the davfs2 > secrets file", does not look like an argument. I am not complaining; I apologize if it sounded like. I am rather focused on getting stuff to work rather than whether or not a newline is always to be expected. Anyway, I just wanted to make davfs work with pam_mount by recurring user demand. The username option is actually all that is needed, because the password code, by means of getpass(), already trims \n. > "I want to put the username into the pam_mount configuration file and > not into the davfs2 secrets file", does not look like an argument. In most cases, there is no username in the pam_mount config file. Thanks, Jan -- |
From: Werner B. <wer...@on...> - 2007-06-24 16:27:26
|
Jan Engelhardt wrote: > The username option is actually all that is needed, because the > password code, by means of getpass(), already trims \n. Does that mean getpass() does not block, but gets the password from mount/pam_mount? In this case there would be no need to change this soon. As pam_mount does not send the username over stdin, the missing newline will not be a problem for username. So this changes may be delayed. So the only point would be: Are your users willing to put the username in the davfs2 secrets file, as expected by davfs2? Please show me the scenario where this is really a problem. It should be realistic and it should not be a WebDAV-servers that replaces NFS. As mentioned, there is a reason, why there is no '-o username='. Why should I change the userinterface of davfs2, including the documentation, only because somebody is too lazy to edit three lines in /etc/davfs2/secrets? Cheers Werner P.S.: Typical use cases for davfs2 are described in README. To use a WebDAV resource all that is needed: - root makes an entry in fstab - the user edits her personal secrets file - some broken servers may need editing of davfs2.conf The resource can be mounted either by some clicking in Gnome/Nautilus/KDE/..., or by just typing 'mount <mountpint>. |
From: Jan E. <je...@co...> - 2007-06-24 17:55:36
|
On Jun 24 2007 18:27, Werner Baumann wrote: > Jan Engelhardt wrote: >> The username option is actually all that is needed, because the >> password code, by means of getpass(), already trims \n. > > Does that mean getpass() does not block, but gets the password from > mount/pam_mount? It works, yes, 1077 if (args->askauth && args->username != NULL && args->password == NULL) { (gdb) 1078 printf(_("Please enter the password to authenticate user %s with " (gdb) 1080 args->password = getpass(_("Password: ")); (gdb) 1081 if (args->password != NULL && strlen(args->password) == 0) { (gdb) p args->password $2 = 0x8067390 "SECRET" `ps afx`: 3286 tty1 Ss+ 0:00 /bin/login -- 3303 ? Ss 0:00 \_ /bin/mount -t davfs https://dev.computergmbh.de// 3304 ? T 0:03 \_ /sbin/mount.davfs https://dev.computergmbh.de `l /proc/3304/fd`: total 0 dr-x------ 2 root root 0 Jun 24 19:26 . dr-xr-xr-x 6 root root 0 Jun 24 19:26 .. lr-x------ 1 root root 64 Jun 24 19:26 0 -> pipe:[209505] lrwx------ 1 root root 64 Jun 24 19:26 1 -> /dev/tty1 l-wx------ 1 root root 64 Jun 24 19:26 2 -> pipe:[209506] and glibc/misc/getpass.c: in = fopen ("/dev/tty", "w+c"); if (in == NULL) { in = stdin; out = stderr; } So what goes: pam_mount pipes to mount, the mount process just forks again to mount.davfs, which inherites pam_mount's file descriptor (pipe:[209505]), triggering the non-tty read in glibc. (Which seems a fragile behavior, and replacing getpass() seems an idea.) I have come across a different point however, davfs now stops for issuer: myself subject: myself identity: devbox.locallan fingerprint: 58:17:3c:b2:fd:77:bf:aa:2b:42:28:b3:f7:c4:d4:23:c1:9a:6f:90 You only should accept this certificate, if you can verify the fingerprint! The server might be faked or there might be a man-in-the-middle-attack. Accept certificate for this session? [y,N] It is to be noted that opening /dev/tty might work, but also may not succeed at all, since PAM is also used in X. For this case, I'd suggest adding an option to: - go ahead when the certificate chain is fully trusted (default) - go ahead even when the certificate is self-signed > In this case there would be no need to change this soon. As pam_mount > does not send the username over stdin, the missing newline will not be a > problem for username. So this changes may be delayed. That is correct. > So the only point would be: > Are your users willing to put the username in the davfs2 secrets file, as > expected by davfs2? > Please show me the scenario where this is really a problem. It should be > realistic and it should not be a WebDAV-servers that replaces NFS. > > As mentioned, there is a reason, why there is no '-o username='. Why > should I change the userinterface of davfs2, including the > documentation, only because somebody is too lazy to edit three lines in > /etc/davfs2/secrets? Even if they possibly wanted, it can be quite tedious for the administrator. I've been to systems with 2000 users and more. The users themselves cannot edit any davfs secrets file, since /etc belongs to root, and /home/$USER is not possibly mounted yet. > P.S.: Typical use cases for davfs2 are described in README. To use a WebDAV > resource all that is needed: > - root makes an entry in fstab > - the user edits her personal secrets file > - some broken servers may need editing of davfs2.conf > > The resource can be mounted either by some clicking in Gnome/Nautilus/KDE/..., > or by just typing 'mount <mountpint>. Yeah. There's always some un-typical users :) Jan -- |
From: Werner B. <wer...@on...> - 2007-06-24 20:35:44
|
Thanks for spell checking. As tomorrow will be Monday it will take some days, but it will be included in the next release. Newline and getpass: As it works it seems not urgent. I will change it some day but I am not sure whether it will be in the next release. (propably yes) Certificates: It's an old discussion and I'm stur: davfs2 will not use unverified certificates. But the problem is solved. Users may verifiy the certificate in their own way, save it on disk and tell davfs2 to use it without further checking. It is described in the davfs2.conf man page., option servercert. There is a general problem with user interaction. davfs2 will prompt the user only as long as it is not in daemon mode. With pam_mount this is still more restricted (the same holds for automatic mount at boot time). But everthing can be configured, so that there is no need to ask the user anything. But davfs2 is not samba and not nfs. It has to deal with different problems, so configuration is different. In my opinion davfs2 therefore needs configuration files and can't handle everthing via command line. Jan Engelhardt wrote: > Even if they possibly wanted, it can be quite tedious for the > administrator. I've been to systems with 2000 users and more. > The users themselves cannot edit any davfs secrets file, since /etc > belongs to root, and /home/$USER is not possibly mounted yet. > How comes davfs2 into this? Wants the administrator to allow every user to mount the same webdav resource? Why not mount it once and set permissions for all users? Wants he to allow every user to mount another webdav resource? So he will propably use some script to configure this. He might include the secrets file in this script. But as he is responsible for 2000 user accounts, he certainly will not allow to use the login password for gmx-access. /home/$USER: Why should it be necessary to mount a webdav resource before the home directory is mounted. I can't imagine, except the webdav resource is the home directory. Don't blame davfs2 for the disaster. Cheers Werner |
From: Jan E. <je...@co...> - 2007-06-24 20:50:40
|
On Jun 24 2007 22:35, Werner Baumann wrote: >> Even if they possibly wanted, it can be quite tedious for the >> administrator. I've been to systems with 2000 users and more. >> The users themselves cannot edit any davfs secrets file, since /etc >> belongs to root, and /home/$USER is not possibly mounted yet. >> > How comes davfs2 into this? Wants the administrator to allow every > user to mount the same webdav resource? Why not mount it once and set > permissions for all users? What it says in the readme: When davfs2 mounts a resource, it authenticates with the server using the username and password it got from the mounting user. All requests to the server are done on behalf of this WebDAV user. Note that smb and cifs (without unix extensions) acts exactly the same, putting the uid of the mounting user for all files in struct stat. So one mount per user basically. This also raises security because not the whole /home is mounted. If the box is rooted, only the home directories (for example) of the users currently logged in are mounted and subject to tampering. With NFS this even gets worse. Imagine a local LAN (schools is a prominent example), where /home is exported by NFS to diskless clients. The problem? Anyone with his own laptop can mount it because s/he is root on that machine. Without password. Bad. (And NFSv4/Kerberos is not trivial at all.) [Conclusion: Use cifs/ccgfs in favor of NFS.] (That was just a small excursion into pam_mount, not specifically a dav thing.) > Wants he to allow every user to mount > another webdav resource? So he will propably use some script to > configure this. He might include the secrets file in this script. But > as he is responsible for 2000 user accounts, he certainly will not > allow to use the login password for gmx-access. I can't come up with examples; you'd have to ask the users that actually had a use case for pam_mount-with-davfs. -- > /home/$USER: Why should it be necessary to mount a webdav resource > before the home directory is mounted. I can't imagine, except the > webdav resource is the home directory. Don't blame davfs2 for the > disaster. -- When davfs comes into play, the _chances_ that $HOME is on a davfs are of course much reduced, and it's more like a subdirectory somewhere else. I have not needed davfs so far, so it's hard to imagine any "legitimate" use case, sorry. Jan -- |