grim/hgkeeper
Clone
Summary
Browse
Changes
Graph
Remove the mercurial 6.1 pin from the container image
22 months ago, Gary Kramlich
653b933ba715
Remove the mercurial 6.1 pin from the container image
package
access
import
(
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
log
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh"
)
const
(
keysDir
=
"keys"
)
var
(
usernames
map
[
string
]
string
keys
map
[
string
]
ssh
.
PublicKey
keysLock
sync
.
Mutex
)
func
refreshKeys
()
error
{
keysLock
.
Lock
()
defer
keysLock
.
Unlock
()
keys
=
map
[
string
]
ssh
.
PublicKey
{}
usernames
=
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
}
counter
:=
0
// 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
{
if
!
strings
.
HasSuffix
(
err
.
Error
(),
"ssh: no key found"
)
{
log
.
Warnf
(
"failed to parse key file for user %s: %v"
,
username
,
err
)
}
continue
}
fingerprint
:=
ssh
.
FingerprintSHA256
(
pubkey
)
if
duppedname
,
found
:=
usernames
[
fingerprint
];
found
{
log
.
Warnf
(
"duplicate key found for user %s. existing key was for %s."
,
username
,
duppedname
,
)
}
usernames
[
fingerprint
]
=
username
keys
[
fingerprint
]
=
pubkey
counter
++
}
log
.
Infof
(
"loaded %d keys for user %q"
,
counter
,
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
:=
usernames
[
fingerprint
]
if
!
found
{
return
""
,
fmt
.
Errorf
(
"user not found"
)
}
return
username
,
nil
}
func
UsernameFromPubkey
(
pubkey
ssh
.
PublicKey
)
(
string
,
error
)
{
return
UsernameFromFingerprint
(
ssh
.
FingerprintSHA256
(
pubkey
))
}
func
PubkeyFromFingerprint
(
fingerprint
string
)
(
string
,
error
)
{
pubkey
,
found
:=
keys
[
fingerprint
]
if
!
found
{
return
""
,
fmt
.
Errorf
(
"PubKey not found"
)
}
str
:=
string
(
ssh
.
MarshalAuthorizedKey
(
pubkey
))
return
str
,
nil
}