passlist

package module
v1.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 14, 2024 License: GPL-3.0 Imports: 12 Imported by: 2

README

PassList

Golang GoDoc Go Report Issues Size Tag License View examples


Purpose

Sometimes there is a need to password-protect your web-server, either in whole or just some parts of it. That's were this little package comes in. It offers to simply integrate the popular BasicAuth mechanism into your own web-server.

Note: To be on the safe side your web-server should use HTTPS instead of plain old HTTP to avoid the chance of someone eavesdropping on the username/password transmission.

Installation

You can use Go to install this package for you:

go get -u github.com/mwat56/passlist

Then in your application you add

import "github.com/mwat56/passlist"

and use the provided functions (discussed below) as you see fit.

Usage

Authentication

PassList provides an easy way to handle HTTP Basic Authentication by simply calling the package's Wrap() function and implementing the TAuthDecider interface which only requires the single function or method

NeedAuthentication(aRequest *http.Request) bool

That function may decide on whatever means necessary whether to grant access (returning true) or deny it (returning false).

For your ease there are two TAuthDecider implementations provided: TAuthSkipper (which generally returns false) and TAuthNeeder (which generally returns true). Just instantiate one of those - or, of course, your own implementation - and pass it to the Wrap() function.

HTTP handler

To use this module as socalled middleware there's a function which you can call to wrap your existing HTTP handler thus allowing automatic authentication:

func Wrap(aNext http.Handler,
    aRealm, aPasswdFile string,
    aAuthDecider IAuthDecider) http.Handler

The arguments mean:

  • aNext: The handler to be called after successful authentication; you will use the return value of Wrap() instead after you called this function.

  • aRealm: The name of the host/domain to protect (this can be any string you like); it will be shown by most browsers when the username/password is requested.

  • aPasswdFile: The name of the password file that holds all the username/password pairs to use when authentication is actually required.

  • aAuthDecider: A deciding function we talked about above.

So, in short: implement the IAuthDecider interface and call passlist.Wrap(…), and you're done.

The user/password list

The package provides a TPassList class with methods to work with a username/password list. It's fairly well documented, so it shouldn't be too hard to use it on your own if you don't like the automatic handling provided by Wrap(). You can create a new instance by either calling passlist.LoadPasswords(aFilename string) (which, as its name says, tries to load the given password file at once), or you call passlist.NewList(aFilename string) (which leaves it to you when to actually read the password file by calling the TPassList object's Load() method).

This library provides a couple of functions you can use in your own program to maintain your own password list without having to use the TPassList class directly.

  • AddUser(aUser, aFilename string) reads a password for aUser from the commandline and adds it to aFilename.
  • CheckUser(aUser, aFilename string) reads a password for aUser from the commandline and compares it with the one stored in aFilename.
  • DeleteUser(aUser, aFilename string) removes the entry for aUser from the password list stored in aFilename.
  • ListUsers(aFilename string) reads aFilename and lists all users stored in that file.
  • UpdateUser(aUser, aFilename string) reads a password for aUser from the commandline and updates the entry in the password list in aFilename.

Note: All these functions do not return to the caller but terminate the respective program with error code 0 (zero) if successful, or 1 (one) otherwise.

Access denial

There's an additional convenience function called passlist.Deny() which sends an "Unauthorised" notice to the remote host in case the remote user couldn't be authenticated; this function is called internally whenever your TAuthDecider required authentication and wasn't given valid credentials from the remote user.

To further improve the safety of the passwords they are peppered before hashing and storing them. The default pepper value can be read by calling

pepper := passlist.Pepper()

And the pepper value can be changed by calling

myPepper := "This is my common 'pepper' value for the user passwords"
passlist.SetPepper(myPepper)

Note: Changing the pepper value after storing user/password pairs will invalidate all existing userlist entries!

Please refer to the source code documentation for further details ot the TPassList class.

In the package's ./app folder you'll find the passlist.go program which implements the maintenance of password files with the following options:

-add string
	<username> name of the user to add to the file (prompting for the password)
-chk string
	<username> name of the user whose pass to check (prompting for the password)
-del string
	<username> name of the user to remove from the file
-file string
	<filename> name of the passwordfile to use (default "pwaccess.db")
-lst list all current usernames from the list
-q    whether to be quiet or not (suppress screen output)
-upd string
	<username> name of the user to update in the file (prompting for the password)

Libraries

The following external libraries are used building PassList:

  • bcrypt supplementary Go cryptography library.

Licence

Copyright © 2019, 2024  M.Watermann, 10247 Berlin, Germany
                All rights reserved
            EMail : <support@mwat.de>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

You should have received a copy of the GNU General Public License along with this program. If not, see the GNU General Public License for details.


GFDL

Documentation

Overview

Package passlist provides a `BasicAuth` middleware plugin for Go web-servers.

Copyright © 2019, 2023 M.Watermann, 10247 Berlin, Germany
                All rights reserved
            EMail : <support@mwat.de>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

You should have received a copy of the GNU General Public License along with this program. If not, see the [GNU General Public License](http://www.gnu.org/licenses/gpl.html) for details.

Index

Constants

This section is empty.

Variables

View Source
var (
	// `Verbose` determines whether or not to print some output
	// when executing the commandline functions.
	Verbose = true
)

Functions

func AddUser added in v1.2.0

func AddUser(aUser, aFilename string)

`AddUser()` reads a password for `aUser` from the commandline and adds it to `aFilename`.

NOTE: This function does not return but terminates the program with error code `0` (zero) if successful, or `1` (one) otherwise.

Parameters:

  • `aUser`: The username to add to the password file.
  • `aFilename`: The name of the password file to use.

func CheckUser added in v1.2.0

func CheckUser(aUser, aFilename string)

`CheckUser()` reads a password for `aUser` from the commandline and compares it with the one stored in `aFilename`.

NOTE: This function does not return but terminates the program with error code `0` (zero) if successful, or `1` (one) otherwise.

Parameters:

  • `aUser`: The username to check with the password file.
  • `aFilename`: The name of the password file to use.

func DeleteUser added in v1.2.0

func DeleteUser(aUser, aFilename string)

`DeleteUser()` removes the entry for `aUser` from the password list `aFilename`.

NOTE: This function does not return but terminates the program with error code `0` (zero) if successful, or `1` (one) otherwise.

Parameters:

  • `aUser`: The username to delete from the password file.
  • `aFilename`: The name of the password file to use.

func Deny

func Deny(aRealm string, aWriter http.ResponseWriter)

`Deny()` sends an "Unauthorised" notice to the remote host.

Parameters:

  • `aRealm`: The symbolic name of the host/domain to protect.
  • `aWriter`: Used by an HTTP handler to construct an HTTP response.

func ListUsers added in v1.2.0

func ListUsers(aFilename string)

`ListUsers()` reads `aFilename` and lists all users stored in there.

NOTE: This function does not return but terminates the program with error code `0` (zero) if successful, or `1` (one) otherwise.

Parameters:

  • `aFilename`: The name of the password file to use.

func Pepper added in v1.1.0

func Pepper() string

Pepper returns the value used for peppering passwords.

Returns:

  • `string`: The uses pepper.

func SetPepper added in v1.1.0

func SetPepper(aPepper string)

`SetPepper()` changes the value used for peppering passwords.

If the given `aPepper` value is an empty string it is ignored and the current pepper value remains unchanged.

Parameters:

  • `aPepper`: The new pepper value to use.

func UpdateUser added in v1.2.0

func UpdateUser(aUser, aFilename string)

`UpdateUser()` reads a password for `aUser` from the commandline and updates the entry in the password list `aFilename`.

NOTE: This function does not return but terminates the program with error code `0` (zero) if successful, or `1` (one) otherwise.

Parameters:

  • `aUser`: The username to update in the password file.
  • `aFilename`: The name of the password file to use.

func Wrap

func Wrap(aNext http.Handler, aRealm, aPasswdFile string, aAuthDecider IAuthDecider) http.Handler

`Wrap ()`returns a handler function that includes authentication, wrapping the given `aNext` and calling it internally.

Parameters:

  • `aNext`: The handler to be called after successful authentication.
  • `aRealm`: The symbolic name of the domain/host to protect.
  • `aPasswdFile`: The name of the password file to use.
  • `aAuthDecider`:

Types

type IAuthDecider added in v1.4.0

type IAuthDecider interface {
	// `NeedAuthentication()` returns `true` if authentication
	// is required, or `false` otherwise.
	//
	// Parameters:
	//   - `aRequest` holds the URL to check.
	//
	// Returns:
	//   - `bool`: `true` if authentication is required. or `false` otherwise.
	NeedAuthentication(aRequest *http.Request) bool
}

`IAuthDecider` is an interface aiming to decide whether a given URL needs authentication or not.

type TAuthNeeder

type TAuthNeeder struct{}

`TAuthNeeder` provides an `IAuthDecider` implementation always returning `true`.

func (TAuthNeeder) NeedAuthentication

func (an TAuthNeeder) NeedAuthentication(aRequest *http.Request) bool

`NeedAuthentication()` returns `true` thus requiring authentication for any URL.

Parameters:

  • `aRequest`: holds the URL to check.

Returns:

  • `bool`: `true` (always).

type TAuthSkipper

type TAuthSkipper struct{}

`TAuthSkipper` provides an `IAuthDecider` implementation always returning `false`.

func (TAuthSkipper) NeedAuthentication

func (as TAuthSkipper) NeedAuthentication(aRequest *http.Request) bool

`NeedAuthentication()` returns `false` thus skipping any authentication.

Parameters:

  • `aRequest` holds the URL to check.

Returns:

  • `bool`: `false` (always).

type TPassList

type TPassList tPassList

TPassList holds the list of username/password values.

func LoadPasswords

func LoadPasswords(aFilename string) (*TPassList, error)

`LoadPasswords()` reads the given `aFilename` returning a `TUserList` instance filled with data read from the password file and a possible error condition.

This function reads one line at a time of the password file skipping both empty lines and comments (identified by `#` or `;` at a line's start).

Parameters:

  • `aFilename`: The name of the password file to use for [Load] and [Store].

Returns:

  • `*TPassList`: A new `TUserList` instance
  • `error`: A possible error during processing the request.

func NewList

func NewList(aFilename string) *TPassList

`NewList()` returns a new `TUserList` instance.

Parameters:

  • `aFilename` The name of the password file to use for [Load] and [Store].

Returns:

  • `*TPassList`: A new `TUserList` instance

func (*TPassList) Add

func (ul *TPassList) Add(aUser, aPassword string) error

`Add()` inserts `aUser` with `aPassword` into the list.

Before storing `aPassword` it gets peppered and hashed.

Parameters:

  • `aUser`: The new user's name to use.
  • `aPassword`: The user's password to store.

Returns:

  • `error`: A possible error during processing the request.

func (*TPassList) Clear

func (ul *TPassList) Clear() *TPassList

`Clear()` empties the internal data structure.

Returns:

  • `*TPassList`: The cleaned list.

func (*TPassList) Exists

func (ul *TPassList) Exists(aUser string) bool

`Exists()` returns `true` if `aUser` exists in the list, or `false` if not found.

Parameters:

  • `aUser`: The username to lookup.

Returns:

  • `bool`: `true` if the user as was found, or `false` otherwise.

func (*TPassList) Find

func (ul *TPassList) Find(aUser string) (string, bool)

`Find()` returns the hashed password of `aUser` and `true`, or an empty string and `false` if not found.

Parameters:

  • `aUser`: The username to lookup.

Returns:

  • `string`: The user's password hash.
  • `bool`: `true` if the user as was found, or `false` otherwise.

func (*TPassList) IsAuthenticated

func (ul *TPassList) IsAuthenticated(aRequest *http.Request) error

`IsAuthenticated()` checks `aRequest` for authentication data, returning `nil` for successful authentication, or an `error` otherwise.

On success the username/password are stored in the `aRequest.URL.User` structure to allow for other handlers checking its existence and act accordingly.

Parameters:

  • `aRequest` The HTTP request received by a server.

Returns:

  • `error`: A possible error during processing the request.

func (*TPassList) Len

func (ul *TPassList) Len() int

`Len()` returns the number of entries in the user list.

Returns:

  • `int`: The list's number of entries.

func (*TPassList) List

func (ul *TPassList) List() (rList []string)

`List()` returns a list of all usernames in the list.

Returns:

  • `[]string`: The users stored in this list.

func (*TPassList) Load

func (ul *TPassList) Load() error

`Load()` reads the password file named in `[LoadPasswords]` or `[NewList]` replacing any older list's contents with that file's.

Returns:

  • `error`: A possible error during processing the request.

func (*TPassList) Matches

func (ul *TPassList) Matches(aUser, aPassword string) bool

`Matches()` checks whether `aPassword` of `aUser` matches the stored password.

Parameters:

  • `aUser`: The username to lookup.
  • `aPassword`: The (unhashed) password to check.

Returns:

  • `string`: The user's password hash.
  • `bool`: `true` if a match was found, or `false` otherwise.

func (*TPassList) Remove

func (ul *TPassList) Remove(aUser string) *TPassList

`Remove()` deletes `aUser` from the list.

Parameters:

  • `aUser`: The username to remove.

Returns:

  • `*TPassList`: The updated list.

func (*TPassList) Store

func (ul *TPassList) Store() (int, error)

`Store()` writes the list to a file, truncating the file if it already exists.

The method uses the filename given to the LoadPasswords or NewList function.

Returns:

  • `int`: The number of bytes written.
  • `error`: A possible error during processing the request.

func (*TPassList) String

func (ul *TPassList) String() string

`String()` returns the list as a single, LF-separated string.

Returns:

  • `string`: A stringified representation of the list.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL