No password in config file
This commit is contained in:
21
commands/cmdutil.go
Normal file
21
commands/cmdutil.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/howeyc/gopass"
|
||||
)
|
||||
|
||||
func getPasswd(prompt string) (string, error) {
|
||||
for {
|
||||
fmt.Print(prompt)
|
||||
pass, err := gopass.GetPasswdMasked()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to read password")
|
||||
}
|
||||
if 0 < len(pass) {
|
||||
return string(pass[:]), nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -111,9 +111,7 @@ subjectPrefix = "[vuls]"
|
||||
[default]
|
||||
#port = "22"
|
||||
#user = "username"
|
||||
#password = "password"
|
||||
#keyPath = "/home/username/.ssh/id_rsa"
|
||||
#keyPassword = "password"
|
||||
|
||||
[servers]
|
||||
{{- $names:= .Names}}
|
||||
@@ -122,9 +120,7 @@ subjectPrefix = "[vuls]"
|
||||
host = "{{$ip}}"
|
||||
#port = "22"
|
||||
#user = "root"
|
||||
#password = "password"
|
||||
#keyPath = "/home/username/.ssh/id_rsa"
|
||||
#keyPassword = "password"
|
||||
#cpeNames = [
|
||||
# "cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
|
||||
#]
|
||||
|
||||
@@ -34,6 +34,9 @@ type PrepareCmd struct {
|
||||
debug bool
|
||||
configPath string
|
||||
|
||||
askSudoPassword bool
|
||||
askKeyPassword bool
|
||||
|
||||
useUnattendedUpgrades bool
|
||||
}
|
||||
|
||||
@@ -55,7 +58,10 @@ func (*PrepareCmd) Synopsis() string {
|
||||
// Usage return usage
|
||||
func (*PrepareCmd) Usage() string {
|
||||
return `prepare:
|
||||
prepare [-config=/path/to/config.toml] [-debug]
|
||||
prepare
|
||||
[-config=/path/to/config.toml] [-debug]
|
||||
[-ask-sudo-password]
|
||||
[-ask-key-password]
|
||||
|
||||
`
|
||||
}
|
||||
@@ -68,6 +74,20 @@ func (p *PrepareCmd) SetFlags(f *flag.FlagSet) {
|
||||
defaultConfPath := os.Getenv("PWD") + "/config.toml"
|
||||
f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")
|
||||
|
||||
f.BoolVar(
|
||||
&p.askKeyPassword,
|
||||
"ask-key-password",
|
||||
false,
|
||||
"Ask ssh privatekey password of target servers before scanning",
|
||||
)
|
||||
|
||||
f.BoolVar(
|
||||
&p.askSudoPassword,
|
||||
"ask-sudo-password",
|
||||
false,
|
||||
"Ask sudo password of target servers before scanning",
|
||||
)
|
||||
|
||||
f.BoolVar(
|
||||
&p.useUnattendedUpgrades,
|
||||
"use-unattended-upgrades",
|
||||
@@ -78,14 +98,30 @@ func (p *PrepareCmd) SetFlags(f *flag.FlagSet) {
|
||||
|
||||
// Execute execute
|
||||
func (p *PrepareCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||
logrus.Infof("Start Preparing (config: %s)", p.configPath)
|
||||
var keyPass, sudoPass string
|
||||
var err error
|
||||
if p.askKeyPassword {
|
||||
prompt := "SSH key password: "
|
||||
if keyPass, err = getPasswd(prompt); err != nil {
|
||||
logrus.Error(err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
}
|
||||
if p.askSudoPassword {
|
||||
prompt := "sudo password: "
|
||||
if sudoPass, err = getPasswd(prompt); err != nil {
|
||||
logrus.Error(err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
}
|
||||
|
||||
err := c.Load(p.configPath)
|
||||
err = c.Load(p.configPath, keyPass, sudoPass)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error loading %s, %s", p.configPath, err)
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
|
||||
logrus.Infof("Start Preparing (config: %s)", p.configPath)
|
||||
target := make(map[string]c.ServerInfo)
|
||||
for _, arg := range f.Args() {
|
||||
found := false
|
||||
|
||||
@@ -45,12 +45,15 @@ type ScanCmd struct {
|
||||
cvssScoreOver float64
|
||||
httpProxy string
|
||||
|
||||
useYumPluginSecurity bool
|
||||
useUnattendedUpgrades bool
|
||||
|
||||
// reporting
|
||||
reportSlack bool
|
||||
reportMail bool
|
||||
|
||||
askSudoPassword bool
|
||||
askKeyPassword bool
|
||||
|
||||
useYumPluginSecurity bool
|
||||
useUnattendedUpgrades bool
|
||||
}
|
||||
|
||||
// Name return subcommand name
|
||||
@@ -71,6 +74,8 @@ func (*ScanCmd) Usage() string {
|
||||
[-report-slack]
|
||||
[-report-mail]
|
||||
[-http-proxy=http://192.168.0.1:8080]
|
||||
[-ask-sudo-password]
|
||||
[-ask-key-password]
|
||||
[-debug]
|
||||
[-debug-sql]
|
||||
`
|
||||
@@ -111,6 +116,20 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
|
||||
f.BoolVar(&p.reportSlack, "report-slack", false, "Slack report")
|
||||
f.BoolVar(&p.reportMail, "report-mail", false, "Email report")
|
||||
|
||||
f.BoolVar(
|
||||
&p.askSudoPassword,
|
||||
"ask-sudo-password",
|
||||
false,
|
||||
"Ask sudo password of target servers before scanning",
|
||||
)
|
||||
|
||||
f.BoolVar(
|
||||
&p.askKeyPassword,
|
||||
"ask-key-password",
|
||||
false,
|
||||
"Ask ssh privatekey password of target servers before scanning",
|
||||
)
|
||||
|
||||
f.BoolVar(
|
||||
&p.useYumPluginSecurity,
|
||||
"use-yum-plugin-security",
|
||||
@@ -129,14 +148,30 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
|
||||
|
||||
// Execute execute
|
||||
func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||
var keyPass, sudoPass string
|
||||
var err error
|
||||
if p.askKeyPassword {
|
||||
prompt := "SSH key password: "
|
||||
if keyPass, err = getPasswd(prompt); err != nil {
|
||||
logrus.Error(err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
}
|
||||
if p.askSudoPassword {
|
||||
prompt := "sudo password: "
|
||||
if sudoPass, err = getPasswd(prompt); err != nil {
|
||||
logrus.Error(err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Infof("Start scanning (config: %s)", p.configPath)
|
||||
err := c.Load(p.configPath)
|
||||
err = c.Load(p.configPath, keyPass, sudoPass)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error loading %s, %s", p.configPath, err)
|
||||
return subcommands.ExitUsageError
|
||||
}
|
||||
|
||||
logrus.Infof("Start scanning (config: %s)", p.configPath)
|
||||
target := make(map[string]c.ServerInfo)
|
||||
for _, arg := range f.Args() {
|
||||
found := false
|
||||
|
||||
@@ -24,6 +24,6 @@ type JSONLoader struct {
|
||||
}
|
||||
|
||||
// Load load the configuraiton JSON file specified by path arg.
|
||||
func (c JSONLoader) Load(path string) (err error) {
|
||||
func (c JSONLoader) Load(path, sudoPass, keyPass string) (err error) {
|
||||
return fmt.Errorf("Not implement yet")
|
||||
}
|
||||
|
||||
@@ -18,16 +18,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package config
|
||||
|
||||
// Load loads configuration
|
||||
func Load(path string) error {
|
||||
|
||||
//TODO if path's suffix .toml
|
||||
func Load(path, keyPass, sudoPass string) error {
|
||||
var loader Loader
|
||||
loader = TOMLLoader{}
|
||||
|
||||
return loader.Load(path)
|
||||
return loader.Load(path, keyPass, sudoPass)
|
||||
}
|
||||
|
||||
// Loader is interface of concrete loader
|
||||
type Loader interface {
|
||||
Load(string) error
|
||||
Load(string, string, string) error
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ type TOMLLoader struct {
|
||||
}
|
||||
|
||||
// Load load the configuraiton TOML file specified by path arg.
|
||||
func (c TOMLLoader) Load(pathToToml string) (err error) {
|
||||
func (c TOMLLoader) Load(pathToToml, keyPass, sudoPass string) (err error) {
|
||||
var conf Config
|
||||
if _, err := toml.DecodeFile(pathToToml, &conf); err != nil {
|
||||
log.Error("Load config failed", err)
|
||||
@@ -53,10 +53,7 @@ func (c TOMLLoader) Load(pathToToml string) (err error) {
|
||||
s.User = d.User
|
||||
}
|
||||
|
||||
s.Password = v.Password
|
||||
if s.Password == "" {
|
||||
s.Password = d.Password
|
||||
}
|
||||
s.Password = sudoPass
|
||||
|
||||
s.Host = v.Host
|
||||
|
||||
@@ -76,10 +73,7 @@ func (c TOMLLoader) Load(pathToToml string) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
s.KeyPassword = v.KeyPassword
|
||||
if s.KeyPassword == "" {
|
||||
s.KeyPassword = d.KeyPassword
|
||||
}
|
||||
s.KeyPassword = keyPass
|
||||
|
||||
s.CpeNames = v.CpeNames
|
||||
if len(s.CpeNames) == 0 {
|
||||
|
||||
@@ -458,7 +458,7 @@ func (o *redhat) parseYumCheckUpdateLine(line string) (models.PackageInfo, error
|
||||
}
|
||||
|
||||
func (o *redhat) getChangelog(packageNames string) (stdout string, err error) {
|
||||
command := "echo N | "
|
||||
command := ""
|
||||
if 0 < len(config.Conf.HTTPProxy) {
|
||||
command += util.ProxyEnv()
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/k0kubun/pp"
|
||||
cve "github.com/kotakanbe/go-cve-dictionary/models"
|
||||
)
|
||||
|
||||
@@ -110,8 +109,6 @@ func InitServers(localLogger *logrus.Entry) (err error) {
|
||||
Log = localLogger
|
||||
if servers, err = detectServersOS(); err != nil {
|
||||
err = fmt.Errorf("Failed to detect the type of OS. err: %s", err)
|
||||
} else {
|
||||
Log.Debugf("%s", pp.Sprintf("%s", servers))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -137,7 +137,8 @@ func sshExec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (re
|
||||
// set pipefail option.
|
||||
// http://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another
|
||||
cmd = fmt.Sprintf("set -o pipefail; %s", cmd)
|
||||
logger.Debugf("Command: %s", strings.Replace(cmd, "\n", "", -1))
|
||||
logger.Debugf("Command: %s",
|
||||
strings.Replace(maskPassword(cmd, c.Password), "\n", "", -1))
|
||||
|
||||
var client *ssh.Client
|
||||
client, err = sshConnect(c)
|
||||
@@ -189,7 +190,7 @@ func sshExec(c conf.ServerInfo, cmd string, sudo bool, log ...*logrus.Entry) (re
|
||||
|
||||
logger.Debugf(
|
||||
"SSH executed. cmd: %s, status: %#v\nstdout: \n%s\nstderr: \n%s",
|
||||
cmd, err, result.Stdout, result.Stderr)
|
||||
maskPassword(cmd, c.Password), err, result.Stdout, result.Stderr)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -240,7 +241,7 @@ func sshConnect(c conf.ServerInfo) (client *ssh.Client, err error) {
|
||||
// log.Debugf("config: %s", pp.Sprintf("%v", config))
|
||||
|
||||
notifyFunc := func(e error, t time.Duration) {
|
||||
logrus.Warnf("Failed to ssh %s@%s:%s. err: %s, Retrying in %s...",
|
||||
logrus.Warnf("Failed to ssh %s@%s:%s err: %s, Retrying in %s...",
|
||||
c.User, c.Host, c.Port, e, t)
|
||||
logrus.Debugf("sshConInfo: %s", pp.Sprintf("%v", c))
|
||||
}
|
||||
@@ -309,3 +310,8 @@ func parsePemBlock(block *pem.Block) (interface{}, error) {
|
||||
return nil, fmt.Errorf("rtop: unsupported key type %q", block.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// ref golang.org/x/crypto/ssh/keys.go#ParseRawPrivateKey.
|
||||
func maskPassword(cmd, sudoPass string) string {
|
||||
return strings.Replace(cmd, fmt.Sprintf("echo %s", sudoPass), "echo *****", -1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user