grim/hgkeeper
Clone
Summary
Browse
Changes
Graph
Rework the way we setup the access code a little bit so it's easier to refresh
2019-09-12, Gary Kramlich
d13c14d4fadb
Rework the way we setup the access code a little bit so it's easier to refresh
package
access
import
(
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
log
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
)
const
(
keysDir
=
"keys"
)
var
(
keys
map
[
string
]
string
keysLock
sync
.
Mutex
)
func
refreshKeys
(
adminRepoPath
string
)
error
{
keysLock
.
Lock
()
defer
keysLock
.
Unlock
()
keys
=
map
[
string
]
string
{}
keysPath
:=
filepath
.
Join
(
adminRepoPath
,
keysDir
)
if
_
,
err
:=
os
.
Stat
(
keysPath
);
err
!=
nil
{
if
os
.
IsNotExist
(
err
)
{
log
.
Error
(
"keys directory not found, no one will be to access hgkeeper"
)
return
nil
}
}
entries
,
err
:=
ioutil
.
ReadDir
(
keysPath
)
if
err
!=
nil
{
return
err
}
for
_
,
entry
:=
range
entries
{
if
entry
.
Mode
().
IsRegular
()
{
filename
:=
filepath
.
Join
(
keysPath
,
entry
.
Name
())
loadSshKey
(
filename
,
entry
.
Name
())
}
}
return
nil
}
func
loadSshKey
(
filename
,
username
string
)
{
buffer
,
err
:=
ioutil
.
ReadFile
(
filename
)
if
err
!=
nil
{
log
.
Warnf
(
"failed to read keyfile for user %s: %v"
,
username
,
err
)
return
}
// iterate through the file reading one ssh public key at a time
for
len
(
buffer
)
>
0
{
var
pubkey
ssh
.
PublicKey
pubkey
,
_
,
_
,
buffer
,
err
=
ssh
.
ParseAuthorizedKey
(
buffer
)
if
err
!=
nil
{
log
.
Warnf
(
"failed to parse key file for user %s: %v"
,
username
,
err
)
return
}
fingerprint
:=
ssh
.
FingerprintSHA256
(
pubkey
)
keys
[
fingerprint
]
=
username
}
}
// UsernameFromFingerprint looks up a username from an SSH key's fingerprint
// and returns the username if found, or err if not found.
func
UsernameFromFingerprint
(
fingerprint
string
)
(
string
,
error
)
{
keysLock
.
Lock
()
defer
keysLock
.
Unlock
()
username
,
found
:=
keys
[
fingerprint
]
if
!
found
{
return
""
,
fmt
.
Errorf
(
"user not found"
)
}
return
username
,
nil
}
func
UsernameFromPubkey
(
pubkey
ssh
.
PublicKey
)
(
string
,
error
)
{
return
UsernameFromFingerprint
(
ssh
.
FingerprintSHA256
(
pubkey
))
}