Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic support for credential stores #32

Merged
merged 27 commits into from
Dec 13, 2023
Merged

Add basic support for credential stores #32

merged 27 commits into from
Dec 13, 2023

Commits on Dec 9, 2023

  1. protocol: add protocol functionality for credential stores

    We'd like to add support for credential handling in Lawn.  Add a
    generic, URL-like structure called a Store that supports CRUD operations
    and the data types to support it, as well as various credential-specific
    datastructures.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 9, 2023
    Configuration menu
    Copy the full SHA
    0c33e31 View commit details
    Browse the repository at this point in the history
  2. client: add a way to fetch the internal configuration

    This is useful for our credential client wrappers.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 9, 2023
    Configuration menu
    Copy the full SHA
    2ba5867 View commit details
    Browse the repository at this point in the history

Commits on Dec 10, 2023

  1. Provide basic interfaces around credentials

    It's helpful to provide some basic interfaces around credentials.  They
    each have a secret, plus optionally a username, one or more URLs or URL
    patterns associated with them, and additional metadata.  We also have a
    form of inquiring about these credentials via a credential request.
    
    Add various APIs around accessing these in a useful way using the
    primitives provided by the protocol.
    
    As part of this, add client and protocol handler methods that return the
    ID of a message we've sent, since when we're performing certain types of
    authentication, we need the ID of the last message to help chain
    commands together.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    
    protocol: allow sending a message and returning the ID
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    4cc8f3e View commit details
    Browse the repository at this point in the history
  2. Add a parser for the Git credential protocol

    The Git credential protocol is relatively simple.  Add a parser for it
    that can handle a credential request or response.
    
    Add two possible extensions for Lawn-specific data: the authentication
    type and the service that this is for.  Normally, the default service
    will be `git`, but users may want to store credentials using this
    protocol for other services.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    c40ca75 View commit details
    Browse the repository at this point in the history
  3. Add a manager for various stores

    Now that we have the client pieces for talking to a generic store, let's
    implement a manager for a generic store and a set of traits that can be
    used to implement one.  Add a parser for store paths, which can be
    tricky to handle, as well as some basic tests for it.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    291c98c View commit details
    Browse the repository at this point in the history
  4. config: add configuration for credential backends

    Add the config file entries for credentials, including a backend type
    for using `git credential`.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    b292823 View commit details
    Browse the repository at this point in the history
  5. store: add credential store support

    Add credential stores as a kind of store.  In addition, add several
    helper functions for credential stores and a credential store backend
    using `git credential`.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    bc35066 View commit details
    Browse the repository at this point in the history
  6. server: implement support for stores

    Implement the server code for handling stores, including credential
    stores.  Adjust the continuation code to handle the new types of
    continuations.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    7f64614 View commit details
    Browse the repository at this point in the history
  7. tests: add basic tests for Git credential backend

    Let's add some basic tests for our Git credential backend by speaking
    the protocol from the client side to a test script in Ruby that mimics
    `git credential`.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    9086c6a View commit details
    Browse the repository at this point in the history
  8. Make TemplateContext owned

    In the future, we'll want to provide additional data stored in this
    structure, notably additional environment variables required by the
    signin code for some credential helpers.  Having three separate
    lifetimes is already a little silly, so let's make this data structure
    own its data to avoid adding a fourth lifetime.
    
    This will also be useful in the future for query code, where we'll want
    to be able to store a context in the server for a longer period of time.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    d879f36 View commit details
    Browse the repository at this point in the history
  9. server: create a shared state

    We'll want to have some shared state across multiple different server
    connections, and in order to do that, let's create a structure for that
    purpose and put an `Arc` of it into the regular server state.  In
    addition, move the configuration into it, since that is shared across
    multiple different connection instances.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    a4a0fe2 View commit details
    Browse the repository at this point in the history
  10. lawn/server: log panics from processing message

    We don't expect panics to occur during normal processing of messages,
    but they can nevertheless occur during development.  To help in the
    debugging of tests and identifying problems if a panic really does occur
    in actual usage, let's print the panic message to the log if that should
    happen.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    d8955f8 View commit details
    Browse the repository at this point in the history
  11. template: add server context environment

    We already have a client and server environment.  However, in some
    cases, such as some credential backends, we need to preserve environment
    variables to be passed to those backends when running commands.  This
    can be useful to allow a user to log in once, get an environment
    variable back, and then pass that environment variable into other calls
    to that backend.  Notably, this will be useful for a future 1Password
    credential helper, among others.
    
    Let's add a server context environment which can be used to pass these
    specific environment variables and which will keep them independent from
    the main server environment variable state.  Add a template context
    builder which can be used to easily instantiate just the required values
    as well.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    9f8e5ac View commit details
    Browse the repository at this point in the history
  12. credential: add a memory backend

    Add a backend which allows storing credentials in memory and optionally
    allows authentication.  This exists primarily for tests, but it is also
    valuable for general credential caching.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    9ce5d47 View commit details
    Browse the repository at this point in the history
  13. credential: allow looking up an arbitrary object

    We'd like to be able to look up an arbitrary credential object by path,
    so let's add an enum for the possibilities and return a suitable object
    if found.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    357b09b View commit details
    Browse the repository at this point in the history
  14. lawn-constants/error: allow converting io::Error references to Error

    When we need an errno value, we don't want to require the caller to
    consume the entire `io::Error` if they want to hold onto it.  Accept
    references to `io::Error` as well to make this easier to use.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    40216d0 View commit details
    Browse the repository at this point in the history
  15. credential: keep shared state for memory backend

    The memory backend's data is stored in a credential store whose data is
    destroyed at latest at the end of the client session.  This is
    unhelpful, because it means that every separate command-line invocation
    of the Lawn client will have its own state, which makes things like
    using credential helpers not work.
    
    To fix this, let's use our special shared credential state, and convert
    it to handle arbitrary data.  Then, insert our vaults into the store
    once the backend is created and re-use them for subsequent sessions, so
    that our data is persisted across sessions as long as the server is
    running.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    676c8d1 View commit details
    Browse the repository at this point in the history
  16. Add tools for working with script syntax

    Lawn is designed to be flexible and scriptable.  To make it easy to
    script commands, let's add a script syntax based off the IMAP message
    syntax.
    
    Our deserializer doesn't use Serde because Serde assumes that we can
    distinctly determine the type inside of an `Option` based on context.
    However, we cannot do that because all of our data is serialized as
    strings, so without knowing the type of the data, it's not possible to
    distinguish the hexadecimal integer `0xff` from the text or byte strings
    with that same value.  This is fine for scripting, where most of the
    time we're working with strings anyway, but makes decoding a bit more
    difficult.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    eac939f View commit details
    Browse the repository at this point in the history
  17. error: add a trait for reporting of error values

    We'll want to report error values in our scripting commands using a
    standard, machine-readable approach.  Let's add a trait for accessing
    that information in a helpful way.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    2e12115 View commit details
    Browse the repository at this point in the history
  18. Add basic scripting support for credentials

    When working with the memory backend, we need functionality to create
    vaults and directories.  Also, in general, it's helpful to have
    scripting support, which allows users to interact with credentials from
    the command line.  To make these possible, let's add some basic
    scripting support.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    1b9e824 View commit details
    Browse the repository at this point in the history
  19. Implement command line interface for credentials

    Add some basic command line functionality, including a script interface
    and a Git credential helper.  For now, always insert the item in the
    first vault in the list, but in the future, we'll allow putting it in an
    arbitrary location.
    
    As part of this, declare that we support the appropriate capability.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    01b2103 View commit details
    Browse the repository at this point in the history
  20. server: require that only valid auth be used for store elements

    Accept only authentication methods that have been negotiated as
    capabilities.  To make this easier, declare auth=PLAIN and
    auth=keyboard-interactive as capabilities.  Add a test for this case as
    well.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    eeef0e4 View commit details
    Browse the repository at this point in the history
  21. protocol: document stores and credentials

    Document the new store functionality and specifically the credential
    type of store.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    723abb0 View commit details
    Browse the repository at this point in the history
  22. Makefile: ignore the manual-strip Clippy lint

    This requires a newer MSRV than we're supporting, so don't complain
    about it.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    e278a39 View commit details
    Browse the repository at this point in the history
  23. Clippy: avoid using try_into when into will work

    Switch to using `into` where possible and convert the no-longer-needed
    `match` statement into an if-else.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    e36b0d0 View commit details
    Browse the repository at this point in the history
  24. Clippy: use first instead of get(0)

    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 10, 2023
    Configuration menu
    Copy the full SHA
    90aabae View commit details
    Browse the repository at this point in the history

Commits on Dec 12, 2023

  1. lawn: add PATH appropriately to tests

    On FreeBSD and NetBSD, Ruby, which is used in our test fixture, is
    located in a different location (`/usr/local/bin` on FreeBSD and
    `/usr/pkg/bin`).  Let's change our `PATH` such that it inherits the
    system one, just with our helper directory in front, so we'll always
    find the correct binaries.
    
    Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
    bk2204 committed Dec 12, 2023
    Configuration menu
    Copy the full SHA
    8c8d32a View commit details
    Browse the repository at this point in the history