Requesting confirmation of what appears to be the case... (New backend StickyNote)
-
It appears that if I’m writing a backend (that is, a new one) I don’t need to directly check authentication credentials unless I have some need to do so in order to figure out where to stick things (e.g. I want to look up a user’s home directory, etc) because the code insists that all of the backed logon functions return ok.
That is, if I am implementing a backing store (e.g. for notes that will run against a Postgres database) I can pick up the user’s login ID and presume it’s ok (without checking the password myself) because it has to have been passed to an email server (e.g. Imap, etc) which has validated the password – and thus I can avoid having to have some part of my back end run with privileges.
Am I reading the code correctly in this regard?
-
Hi tickerguy,
on every request Z-Push checks if the command requires authentication (actually every command except the provisioning requires it) and calls the backend’s Logon function. So if the request got so far that it’s querying the database, the user was able to login with the provided credentials and you don’t have to check it again (unless of course there’s some flaw in the Logon function and the user was able to bypass it).
Manfred
-
@manfred That’s not quite the question…
As I read the code (if I’m reading it correctly on the combined backend) it checks all the Logon functions, and does so in the order they are declared. So once you get past “IMAP”, for example, we know the login is good (that is, the password was verified.) The combined backend only considers a sign-on good if all of the back ends return valid for the Logon function.
The reason this is important in the instant case is that in order to check a password you must run with privileges somewhere. Dovecot does, of course, and I could call IMAP’s authentication checking routine, which the implements whatever system policy underlies it (e.g. PAM, LDAP, etc.) Caldav/Carddav do this, but the Caldav/Carddav server have other reasons to do so (since they’re potentially called directly by user agents on a listening port, as is IMAP.)
But if I know the login is good then I don’t need to do that; that is, I can stash the login id passed as a local to the back end without verifying it and just return true, because someone else (at least one, and perhaps three!) already has. This means I don’t need to write a daemon that runs with privileges since I can safely assume that the username field is valid and has been authenticated; I can thus ignore the password passed entirely and use php’s Postgres library directly rather than defining an IPC protocol of some sort to talk to a note back end that runs with privileges and queries the system’s password store. Since there’s no “notes” extension to Davical that I’m aware of, and thus “Notes” would only be accessed through Exchange, there appears to be no shortcoming to doing it this way, nor any particular security implication either (since the db admin can always get to the calendar tables, for example, directly.)
Unless I’m parsing the code incorrectly this appears to be safe and, in addition, lighter-weight since it’s both one less daemon to run and one less pass through the authentication process.
-
Hi tickerguy,
in your initial post you didn’t mention combined backend and that you’re planing to use another backend’s authentication.
@tickerguy said in Requesting confirmation of what appears to be the case...:
As I read the code (if I’m reading it correctly on the combined backend) it checks all the Logon functions, and does so in the order they are declared. So once you get past “IMAP”, for example, we know the login is good (that is, the password was verified.) The combined backend only considers a sign-on good if all of the back ends return valid for the Logon function.
That’s correct.
@tickerguy said in Requesting confirmation of what appears to be the case...:
The reason this is important in the instant case is that in order to check a password you must run with privileges somewhere. Dovecot does, of course, and I could call IMAP’s authentication checking routine, which the implements whatever system policy underlies it (e.g. PAM, LDAP, etc.) Caldav/Carddav do this, but the Caldav/Carddav server have other reasons to do so (since they’re potentially called directly by user agents on a listening port, as is IMAP.)
But if I know the login is good then I don’t need to do that; that is, I can stash the login id passed as a local to the back end without verifying it and just return true, because someone else (at least one, and perhaps three!) already has. This means I don’t need to write a daemon that runs with privileges since I can safely assume that the username field is valid and has been authenticated; I can thus ignore the password passed entirely and use php’s Postgres library directly rather than defining an IPC protocol of some sort to talk to a note back end that runs with privileges and queries the system’s password store. Since there’s no “notes” extension to Davical that I’m aware of, and thus “Notes” would only be accessed through Exchange, there appears to be no shortcoming to doing it this way, nor any particular security implication either (since the db admin can always get to the calendar tables, for example, directly.)
That’s correct but you have to be aware that your backend relies on other backend’s authentication. And right now the available backends don’t provide information if a user is logged in. There’s only RequestProcessor::isUserAuthenticated() but therefore in case of a combined backend all the used backends must return true for Logon.
If it’s for your own use only, that should be fine.
Are you actually planing to contribute your backend?@tickerguy said in Requesting confirmation of what appears to be the case...:
Unless I’m parsing the code incorrectly this appears to be safe and, in addition, lighter-weight since it’s both one less daemon to run and one less pass through the authentication process.
In my opinion it’s still a risk to rely on another backend’s authentication. If someone manages to bypass the IMAP or another authentication your backend relies on, he’d get access to the postgress database as well.
Is there some web application users are able to access notes now? In such a case I’d advise to use the same login process.Manfred
-
I’m starting work on a backend that I intend to contribute, which will enable “Notes” for those who are using Imap and Davical today (which works for everything except notes.)
The existing “combined” back end solutions that support “all of it” are Linux-slanted and I run FreeBSD around here, and also hate Mysql with a white-hot passion for a host of reasons. I’m more-or-less forced to use it for Cacti but that’s the only reason I have a Mysqld running at all, and some day I’ll re-implement its calls to talk Postgres instead.
What I run here now is IMAP for email (Postfix/Dovecot) and Davical (Caldav and Carddav) for calendars/tasks and contacts, respectively. Both take and verify authentication and both are multi-protocol – they serve both Exchange clients via Z-push and also are connected to directly (e.g. by Thunderbird on PCs.) That leaves notes unimplemented and Evernote keeps tightening the screws on license demands. It would be nice to have support for Notes for mobile devices, in other words, so my middle finger can go up toward the Evernote people. My personal mobile is a BlackBerry DTEK60 which has a Notes client, but as it stands right now it can’t talk to Z-push.
The intent thus is for a backend that is only really useful in the context of someone using Davical and an IMAP server (probably Dovecot.) While I could certainly have the PHP code for the backend make a socket call to a daemon, and have the daemon do the talking to the database (and initialize with privileges, authenticate and then drop them) I can also have the php backend code directly hit Postgres, but if I do that I have no way to interface with the system’s authentication mechanisms since Z-push is not running as root and thus can’t check passwords.
If I’m going to implement something with scope beyond Z-push then it’s awfully tempting to simply use the filesystem directory structure and stick a dot directory under the user’s home for “Notes”; if the underlying process has privilege it can authenticate, setuid() to that user and then work that way. On a system running ZFS (which my systems do) this has myriad advantages including the ability of the admin to set up time-based rolling snapshots which makes accidental deletes a non-event. However, that means bugs in that code are an underlying system security risk to the system as a whole.
So my thought process at this point is to not do that, but instead implement a backend that can sync notes tied to a Postgres database via php’s interface. In turn that led me to question whether that new backend actually needs to validate passwords (because if it does then it either has to call something on the system that can do that, such as IMAP, or I have to write code outside of Z-push’s PHP that has privilege, does that, and then drops same, which involves implementing an entire second layer that is otherwise not necessary.) If it doesn’t need to validate passwords because in order to actually pass data the other backends have already done so (and “cleared” the presented user’s credentials) then that layer can be omitted and yet in the context of Z-push it remains secure (well, at least as secure as is the other backend’s authentication, such as Dovecot or whatever.)
-
Everything you say is logical. Yes, in your use case you can have Logon() return true and you are good to go.
This might become an issue when you contribute it, because the way Z-Push Backends work you could just use a backend alone. People using your notes backend need to know what they are doing, because if auth breaks (or any backend you rely on) your data could be exposed easily.I would say: Happy coding! :thumbsup:
You could still contribute it and then put some explicit notes in the readme.Cheers,
Sebastian -
Thanks… that’s what I assumed.
Frankly I can’t imagine someone putting up a Z-push deployment only for Notes. It’d work of course but I can’t get my arms around the reason someone would undertake that. And whether you actually sync a category or not (assuming your mobile allows you to choose; my BlackBerry does) if the combined backend’s config file declares a subsidiary backend it’s validated.
I’ll proceed on the above then and if/when I get to where it looks reasonably able to be contributed I’ll make sure the README notes the constraint, and perhaps stick something in the config.php file that has to be changed from how it comes (or it’ll blow up, as is done with IMAP’s config file) directly below a similar and pointed warning :)
-
@tickerguy said in Requesting confirmation of what appears to be the case...:
Frankly I can’t imagine someone putting up a Z-push deployment only for Notes
I had this kind of convictions as well, but even after years users still surprise me with things they try to do (and expect to work).
So, better safe than sorry! :grimacing: -
Am I correct in assuming that until I create a “pull request” if I send up code with a push from here on the branch people can look at and play with it, but I am not saying that I believe it’s suitable for inclusion?
-
@tickerguy said in Requesting confirmation of what appears to be the case...:
Am I correct in assuming that until I create a “pull request” if I send up code with a push from here on the branch people can look at and play with it, but I am not saying that I believe it’s suitable for inclusion?
That’s correct.
-
An early (working) version of the code is now up at ZP-1284 (https://jira.z-hub.io/browse/ZP-1284?jql=) if anyone would care to give it a shot.
-
A number of cleanup deltas have been pushed back to this if anyone would like to play with it… it appears to be stable now when used “in anger” (on the road, etc.)
-
It’s been about a month now, has been running flawlessly here since the last set of changes, and I’ve created a pull request as a consequence… no code changes since roughly a month ago.