Eric Biggers [Sun, 25 Mar 2018 17:13:26 +0000 (10:13 -0700)]
security: drop and regain privileges in all threads
After enabling pam_fscrypt for "session" and creating a directory
protected with a login protector, I was no longer able to log in as that
user. The problem is that the Go runtime is creating threads after
pam_fscrypt drops privileges, but pam_fscrypt is not re-acquiring
privileges on those threads because the Go wrappers for setreuid(),
setregid(), and setgroups() in the "sys/unix" package are using the raw
syscalls which operate on the calling thread only.
This violates glibc's assumption that all threads have the same uids and
gids, causing it to abort() the process when a later module in the PAM
stack (pam_mail in my case) tries to drop privileges using the glibc
functions.
Fix it by dropping and regaining privileges using the glibc functions
rather than the "sys/unix" functions.
This also avoids any possibility that privileges could be changed in a
thread other than the "main" one for pam_fscrypt, since the Go runtime
does not guarantee which OS-level thread runs what.
It would be nice to also exit all Go worker threads before returning
from pam_fscrypt, but the Go runtime doesn't seem to support that.
Eric Biggers [Sun, 25 Mar 2018 06:21:29 +0000 (23:21 -0700)]
pam: return error when PAM info item is unset
pam_fscrypt is crashing with a segfault in copyIntoSecret() when using
Ctrl-C to interrupt a 'sudo' prompt. It is dereferencing a NULL pointer
that is supposed point to the PAM_AUTHTOK item. The problem is that the
Go code assumes pam_get_item() returns a non-success status if the item
is unset, when actually it sets the data pointer to NULL and returns
PAM_SUCCESS.
Fix it by making pam.Handle.GetItem() return an error in that case.
Joseph Richey [Mon, 12 Feb 2018 05:22:53 +0000 (21:22 -0800)]
travis: use multiple build stages
This change rewrites .travis.yml to use many build stages/jobs. This
allows our build to run faster, as almost all jobs run in containers.
Stage 1: Run on all pushes to all branches
- Job Build: just runs "make" to make sure everything is OK
Stage 2: Run on all PRs and pushes to master
- Job Lint: Makes sure dep, "make gen", "make format", and "make lint"
are all happy.
- Job Build 1: Make sure "go get" and "make" will work. This job will
later run unit tests.
- Job Build 2: Same as Job Build 1, except with another go version.
- Job Integeration: Run integration tests (needs sudo, so needs VM)
Stage 3: Run on releases (if other stages pass)
- Job Deploy: Publishes amd64 binaries to GitHub.
Joseph Richey [Mon, 12 Feb 2018 05:06:32 +0000 (21:06 -0800)]
Makefile: completly rewrite
This change is a complete rewrite of fscrypt's Makefile.
The new build rules can be roughly divided into secions:
Build - bin/fscrypt and bin/pam_fscrypt
Linting - gen (for .proto files), format, lint
Test - test, test-{setup|teardown}, coverage.out
Install - install, uninstall, install-{bin|pam}
Tools - tools and other bin/* needed for the other rules
As before, "make" builds the binary and pam_module, while "make all"
builds and tests everything (except for integration tests), and "make
clean" removes any generated files.
Also note that this new build system:
- Doesn't require input_fail.py
- Properly falis on linter errors
- Builds everything into the bin/ directory (customizable)
- Builds all the vendored tools
Joseph Richey [Mon, 12 Feb 2018 04:39:12 +0000 (20:39 -0800)]
golint: Use fork that respects vendor directory
Ideally, we would just use "golint ./..." to check all our our source
files for lint error. However, this does not work because it will
include all packages in the vendor directory. The pull request at:
https://github.com/golang/lint/pull/325
fixes this issue, so we will use it until the PR has been merged.
Joseph Richey [Mon, 12 Feb 2018 04:31:27 +0000 (20:31 -0800)]
dep: require tools to be vendored
This change ot Gopkg.toml will make it easier to build the linting and
formatting tools. Vendoring their source also makes sure that updates to
these tools do not break the build.
Joseph Richey [Mon, 12 Feb 2018 04:24:21 +0000 (20:24 -0800)]
dep: add dependancies to Gopkg.toml
fscrypt directly depends on 5 repositories (8 packages). This change
adds those dependancies to Gopkg.toml, so that they can be properly
versioned. Note that the golang.org/x repositories do not use semver.
Joseph Richey [Mon, 12 Feb 2018 04:19:36 +0000 (20:19 -0800)]
test: all packages should have tests
The tests added in this change are trivial, but they make sure that
every package has a non-zero number of tests. This is important for
eventually increasing test coverage.
Joseph Richey [Fri, 9 Feb 2018 09:51:44 +0000 (01:51 -0800)]
docs/travis: Remove mention of Argon2
Now that Argon2 is simply and implementation detail of the `crypto`
package, and no a build dependancy, we don't need it in Travis or in the
documenation for building fscrypt.
Joseph Richey [Thu, 8 Feb 2018 10:37:42 +0000 (02:37 -0800)]
crypto: Move from libargon2 -> x/crypto/argon2
Use the golang library for the hashing function instead of the reference
C implementation. This removes the dependancy on libargon2. As we are no
longer doing our own error checking, we also eliminate those tests.
Joseph Richey [Sat, 3 Feb 2018 00:03:30 +0000 (16:03 -0800)]
Change Golang formatter
Moves from goimports to [goreturns](https://github.com/sqs/goreturns).
This should not effect any code that already compiles as goreturns only
adds zero return values, then runs goimports.
This is mainly to help improve ergonomics when dealing with multiple
return types.
Adds maxMemoryBytes as 128MiB and cleans up the helper
functions/variables to make it more clear which values are a number of
bytes, and which values are a number of KiB.
Joseph Richey [Fri, 1 Sep 2017 07:56:44 +0000 (00:56 -0700)]
cmd/fscrypt: Add explanations for keyring failures
Now the user is persented with help when they try to access a keyring
that isn't theirs or try to use fscrypt without a user keyring linked
into the session keyring.
Joseph Richey [Fri, 1 Sep 2017 07:53:07 +0000 (00:53 -0700)]
security: Change user keyring lookup algorithm
Now instead of spawning a seperate thread we alternate between changing
the euid and ruid to both find the keyring and link it to the process
keyring. Note that we also ensure that the user keyring is linked into
the root keyring whenever possible.
Joe Richey [Thu, 31 Aug 2017 01:16:16 +0000 (18:16 -0700)]
cmd/fscrypt: Add --user flag for running as root
The --user flag can now be used to have the targe user (the one whose
keyring and password will be used in fscrypt) be different than the
calling user. Very usefull for things like
Joe Richey [Thu, 31 Aug 2017 01:00:04 +0000 (18:00 -0700)]
actions: context now hold a target user.User
This user is used with policies to interface with the keryings and with
protectors to indicate which user's login passphrase should be used to
protectors of type pam_passphrase.
Joe Richey [Thu, 31 Aug 2017 00:51:05 +0000 (17:51 -0700)]
security: Rewrite of keryings and permissions
The keyring lookup functions no longer read from /proc/keys. Now they
simply spawn a thread, drop privs, and check with GetKeyringID and
KEY_SPEC_USER_KEYRING. See userKeyringID() for more info.
The privileges functions have also been changed. Now the concept of
setting privileges is seperate form the concept of setting up the
keyrings.