Documentation ¶
Index ¶
- Constants
- Variables
- func EncodePublicKey(key interface{}, comment string) (string, error)
- func GenerateKey() []byte
- func GenerateNonce(size int) ([]byte, error)
- func JoinPublicKeys(keys []ssh.PublicKey) []byte
- func OAuth2Token(tokenPb *protocol.OauthToken) (*oauth2.Token, error)
- func OAuthTokenPb(token *oauth2.Token) (*protocol.OauthToken, error)
- func RandAsciiBytes(n int) []byte
- func ToHostCA(public CAPublic) *protocol.HostCA
- func ToUserCA(public CAPublic) *protocol.UserCA
- func Unquote(s string) string
- func UpdateSSHD(filePath string) error
- type AESGCM
- type Authz
- type CACertPair
- type CAPublic
- type CAType
- type CertManager
- func (m *CertManager) HostCAs() []CAPublic
- func (m *CertManager) RootCAPublicKeys() []ssh.PublicKey
- func (m *CertManager) SignHostCert(request *CertSignRequest) ([]byte, error)
- func (m *CertManager) SignUserCert(request *CertSignRequest) ([]byte, error)
- func (m *CertManager) UserCAPublicKeys() []ssh.PublicKey
- func (m *CertManager) UserCAs() []CAPublic
- type CertMetadata
- type CertSignRequest
- type GoogleAuth
- type GrantAll
- type PSKStore
- type SimpleAuth
Constants ¶
const ( KeySize = 32 NonceSize = 12 )
Variables ¶
var ( ErrInvalidSerial = errors.New("Serial should be something meaningful, not 0") ErrInvalidStartTime = errors.New("Cannot sign for certs with time in the past") ErrEndBeforeStartTime = errors.New("End Time cannot be before start time") ErrEmptyID = errors.New("Empty ID supplied") ErrValidityTooLong = errors.New("The Validity for certs is too long") )
var ( ErrEncrypt = errors.New("secret: encryption failed") ErrDecrypt = errors.New("secret: decryption failed") ErrKeyNotFound = errors.New("keylookup: key not found") )
var ( DefaultServer = "localhost:50051" ClientID = defaultClientID ClientSecret = defaultClientSecret )
Functions ¶
func EncodePublicKey ¶
ssh one-line format (for lack of a better term) consists of three text fields: { key_type, data, comment } data is base64 encoded binary which consists of tuples of length (4 bytes) and data of the length described previously. For RSA keys, there should be three tuples which should be: { key_type, public_exponent, modulus }
func GenerateNonce ¶
GenerateNonce creates a new random nonce.
func JoinPublicKeys ¶
JoinPublickeys encodes the public key and joins them in a single bytearray
func OAuth2Token ¶
func OAuth2Token(tokenPb *protocol.OauthToken) (*oauth2.Token, error)
Convert from Protobuf Oauth2 Token to *oauth2.Token
func OAuthTokenPb ¶
func OAuthTokenPb(token *oauth2.Token) (*protocol.OauthToken, error)
This package is used for oauth2 3-legged authentication and conversion work Convert Oauth token to protobuf version
func RandAsciiBytes ¶
A helper function create and fill a slice of length n with characters from a-zA-Z0-9_-. It panics if there are any problems getting random bytes.
func UpdateSSHD ¶
Types ¶
type AESGCM ¶
type AESGCM struct {
// contains filtered or unexported fields
}
Initialize the AESGCM with a PSK store, this can be anything from a local instance or something that reads from a HSM or memory, the logic for getting the key securely will be in the PSKStore implmentation
func InitAESGCM ¶
type Authz ¶
Authz is a bare minimum Authorization interface that just checks if any of the requested principals are actually valid for the user The service should only grant the access to the principals the user should have access to. If there is no overlap with the existing principals the result is empty and with an error for more details for the service to log for administrators or to send to the users Any other authorization backends can be added by implementing this interface
type CACertPair ¶
type CAPublic ¶
type CAPublic struct { Id int `json:"id"` ValidFrom time.Time `json:"valid_from"` ValidUntil time.Time `json:"valid_until"` PublicKey []byte }
CAPublic is the public data that we want to return the user
type CertManager ¶
type CertManager struct {
// contains filtered or unexported fields
}
I have doubts about this approach the passwords are stored in plaintext in memory but the actual certs are read on demand, and not kept in memory so any kind of overflow attack needs a filesystem access too while this may leak the CA Passwords, as long as the certs are read on demand, and forgotten immediately, I think this should be relatively safe. This can be an interface to read from different stores for secrets, but that needs a lot more testing right now TODO: refactor to use CACertPair structure
func NewCertManagerWithParameters ¶
func NewCertManagerWithParameters(certsDir string, region string, roleArn string, paramsPrefix string) (*CertManager, error)
NewCertManagerwithParameters looks for files ending ca_(user|host)_(identifier) and ca_(user|host)_(identifier).pub in the certsDirectory, the comment field is read from the corresponding public key file the comment in the public key file contains how long the certificate is valid for the identifier is used to lookup the passphrase in the parameter store with _(identifier) appended to paramsPrefix TODO: this should be implementing an interface so that this file doesn't remain dirty with aws deps
func NewCertManagerWithPasswords ¶
func NewCertManagerWithPasswords(rootCAPath string, rootCAPassword string, userCAPath string, userCAPassword string) (*CertManager, error)
NewCertmanagerwithPasswords just reads the files and decrypts them with corresponding passwords
func (*CertManager) HostCAs ¶
func (m *CertManager) HostCAs() []CAPublic
func (*CertManager) RootCAPublicKeys ¶
func (m *CertManager) RootCAPublicKeys() []ssh.PublicKey
these return array because we have to overlap multiple root and user keys when we need to rotate the keys in future it makes sense to make the API exposed to users be a little more flexible
func (*CertManager) SignHostCert ¶
func (m *CertManager) SignHostCert(request *CertSignRequest) ([]byte, error)
func (*CertManager) SignUserCert ¶
func (m *CertManager) SignUserCert(request *CertSignRequest) ([]byte, error)
func (*CertManager) UserCAPublicKeys ¶
func (m *CertManager) UserCAPublicKeys() []ssh.PublicKey
func (*CertManager) UserCAs ¶
func (m *CertManager) UserCAs() []CAPublic
type CertMetadata ¶
type CertMetadata struct { Id int `json:"id"` ValidFrom time.Time `json:"valid_from"` ValidUntil time.Time `json:"valid_until"` }
CertMetadata is included in the comment for public key
type CertSignRequest ¶
type CertSignRequest struct { PubKey []byte ValidFrom time.Time ValidUntil time.Time Id string Serial uint64 Principals []string // include the criticalOptions and Extensions too ssh.Permissions }
CertSignRequest is intended to be usable from other go libraries easily with the start and end times to be in time.Time. Since the upstream service is likely only seeing the bytes for a public key, the parsing is done here too
type GoogleAuth ¶
type GoogleAuth struct { ClientId string ClientSecret string // Whether to use a webserver UseWebServer bool // If we are listening to a webserver, what port WebServerPort int // Domain to restrict users to Domain string // Where to save the token TokenCachePath string Token *oauth2.Token }
this only does Google Auth because that's what we need right now I don't think it's trivial to add other authentication protocols so until we need to, I'm sticking with Google Auth
func (*GoogleAuth) Authenticate ¶
func (u *GoogleAuth) Authenticate() (*oauth2.Token, error)
func (*GoogleAuth) ValidateToken ¶
Validate the token to avoid the "Confused Deputy Problem" https://www.ietf.org/mail-archive/web/unbearable/current/msg00135.html Classic paper:
type PSKStore ¶
lets figure out the methods we need first and what we'll do with it the idea is that the clients will lookup the PSK with different mechanisms depending on the deployment requirements the same code is shared with the server but it looks them up from different sources
type SimpleAuth ¶
type SimpleAuth struct { Principals []string `json:"principals" yaml:"principals"` // these users can get the root-everywhere if they request for it // allowing to sign in with full sudo AdminUsers []string `json:"admin_users" yaml:"admin_users"` // Users -> Principals map AccessMap map[string][]string `json:"access_map" yaml:"access_map"` }
func NewSimpleAuthFromBuffer ¶
func NewSimpleAuthFromBuffer(content []byte) (*SimpleAuth, error)
func NewSimpleAuthFromFile ¶
func NewSimpleAuthFromFile(filePath string) (*SimpleAuth, error)
func (SimpleAuth) Authorized ¶
func (s SimpleAuth) Authorized(user string, principals []string) ([]string, error)
func (SimpleAuth) IsAdmin ¶
func (s SimpleAuth) IsAdmin(user string) bool
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
Package protocol is a generated protocol buffer package.
|
Package protocol is a generated protocol buffer package. |