Merge pull request #35 from future-architect/fix_to_no_password_in_config
Fix no password in config
This commit is contained in:
		
							
								
								
									
										52
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								README.md
									
									
									
									
									
								
							@@ -315,9 +315,7 @@ subjectPrefix = "[vuls]"
 | 
			
		||||
[default]
 | 
			
		||||
#port        = "22"
 | 
			
		||||
#user        = "username"
 | 
			
		||||
#password    = "password"
 | 
			
		||||
#keyPath     = "/home/username/.ssh/id_rsa"
 | 
			
		||||
#keyPassword = "password"
 | 
			
		||||
 | 
			
		||||
[servers]
 | 
			
		||||
 | 
			
		||||
@@ -325,9 +323,7 @@ subjectPrefix = "[vuls]"
 | 
			
		||||
host         = "172.31.4.82"
 | 
			
		||||
#port        = "22"
 | 
			
		||||
#user        = "root"
 | 
			
		||||
#password    = "password"
 | 
			
		||||
#keyPath     = "/home/username/.ssh/id_rsa"
 | 
			
		||||
#keyPassword = "password"
 | 
			
		||||
#cpeNames = [
 | 
			
		||||
#  "cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
 | 
			
		||||
#]
 | 
			
		||||
@@ -395,9 +391,7 @@ You can customize your configuration using this template.
 | 
			
		||||
    [default]
 | 
			
		||||
    #port        = "22"
 | 
			
		||||
    #user        = "username"
 | 
			
		||||
    #password    = "password"
 | 
			
		||||
    #keyPath     = "/home/username/.ssh/id_rsa"
 | 
			
		||||
    #keyPassword = "password"
 | 
			
		||||
    ```
 | 
			
		||||
    Items of the default section will be used if not specified.
 | 
			
		||||
 | 
			
		||||
@@ -409,9 +403,7 @@ You can customize your configuration using this template.
 | 
			
		||||
    host         = "172.31.4.82"
 | 
			
		||||
    #port        = "22"
 | 
			
		||||
    #user        = "root"
 | 
			
		||||
    #password    = "password"
 | 
			
		||||
    #keyPath     = "/home/username/.ssh/id_rsa"
 | 
			
		||||
    #keyPassword = "password"
 | 
			
		||||
    #cpeNames = [
 | 
			
		||||
    #  "cpe:/a:rubyonrails:ruby_on_rails:4.2.1",
 | 
			
		||||
    #]
 | 
			
		||||
@@ -440,9 +432,15 @@ Prepare subcommand installs required packages on each server.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$ vuls prepare -help
 | 
			
		||||
prepare:
 | 
			
		||||
        prepare [-config=/path/to/config.toml] [-debug]
 | 
			
		||||
prepare
 | 
			
		||||
                        [-config=/path/to/config.toml] [-debug]
 | 
			
		||||
                        [-ask-sudo-password]
 | 
			
		||||
                        [-ask-key-password]
 | 
			
		||||
 | 
			
		||||
  -ask-key-password
 | 
			
		||||
        Ask ssh privatekey password before scanning
 | 
			
		||||
  -ask-sudo-password
 | 
			
		||||
        Ask sudo password of target servers before scanning
 | 
			
		||||
  -config string
 | 
			
		||||
        /path/to/toml (default "$PWD/config.toml")
 | 
			
		||||
  -debug
 | 
			
		||||
@@ -456,6 +454,7 @@ prepare:
 | 
			
		||||
# Usage: Scan
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
$ vuls scan -help
 | 
			
		||||
scan:
 | 
			
		||||
        scan
 | 
			
		||||
@@ -467,8 +466,14 @@ scan:
 | 
			
		||||
                [-report-slack]
 | 
			
		||||
                [-report-mail]
 | 
			
		||||
                [-http-proxy=http://192.168.0.1:8080]
 | 
			
		||||
                [-ask-sudo-password]
 | 
			
		||||
                [-ask-key-password]
 | 
			
		||||
                [-debug]
 | 
			
		||||
                [-debug-sql]
 | 
			
		||||
  -ask-key-password
 | 
			
		||||
        Ask ssh privatekey password before scanning
 | 
			
		||||
  -ask-sudo-password
 | 
			
		||||
        Ask sudo password of target servers before scanning
 | 
			
		||||
  -config string
 | 
			
		||||
        /path/to/toml (default "$PWD/config.toml")
 | 
			
		||||
  -cve-dictionary-url string
 | 
			
		||||
@@ -496,6 +501,21 @@ scan:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## ask-key-password option 
 | 
			
		||||
 | 
			
		||||
| SSH key password |  -ask-key-password ||
 | 
			
		||||
|:-----------------|:-------------------||
 | 
			
		||||
| empty password   |                 -  ||
 | 
			
		||||
| with password    |           required | or use ssh-agent |
 | 
			
		||||
 | 
			
		||||
## ask-sudo-password option
 | 
			
		||||
 | 
			
		||||
| sudo password on target servers | -ask-sudo-password ||
 | 
			
		||||
|:-----------------|:-------------------||
 | 
			
		||||
| NOPASSWORD       |                 -  | defined as NOPASSWORD in /etc/sudoers on target servers |
 | 
			
		||||
| with password    |           required ||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## example
 | 
			
		||||
 | 
			
		||||
Run go-cve-dictionary as server mode before scanning.
 | 
			
		||||
@@ -505,9 +525,10 @@ $ go-cve-dictionary server
 | 
			
		||||
 | 
			
		||||
### Scan all servers defined in config file
 | 
			
		||||
```
 | 
			
		||||
$ vuls scan --report-slack --report-mail --cvss-over=7
 | 
			
		||||
$ vuls scan --report-slack --report-mail --cvss-over=7 -ask-sudo-password -ask-key-password
 | 
			
		||||
```
 | 
			
		||||
With this sample command, it will ..
 | 
			
		||||
- Ask sudo password and ssh key passsword before scanning
 | 
			
		||||
- Scan all servers defined in config file
 | 
			
		||||
- Send scan results to slack and email
 | 
			
		||||
- Only Report CVEs that CVSS score is over 7
 | 
			
		||||
@@ -518,7 +539,9 @@ With this sample command, it will ..
 | 
			
		||||
$ vuls scan server1 server2
 | 
			
		||||
```
 | 
			
		||||
With this sample command, it will ..
 | 
			
		||||
- Scan only 2 servers. (server1, server2)
 | 
			
		||||
- Use SSH Key-Based authentication with empty password (without -ask-key-password option)
 | 
			
		||||
- Sudo with no password (without -ask-sudo-password option)
 | 
			
		||||
- Scan only 2 servers (server1, server2)
 | 
			
		||||
- Print scan result to terminal
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
@@ -594,6 +617,11 @@ Use Systemd, Upstart or supervisord, daemontools...
 | 
			
		||||
- How to Enable Automatic-Update of Vunerability Data.  
 | 
			
		||||
Use job scheduler like Cron (with -last2y option).
 | 
			
		||||
 | 
			
		||||
- How to Enable Automatic-Scan.  
 | 
			
		||||
Use job scheduler like Cron.  
 | 
			
		||||
Set NOPASSWORD option in /etc/sudoers on target servers.  
 | 
			
		||||
Use SSH Key-Based Authentication with empty password or ssh-agent.
 | 
			
		||||
 | 
			
		||||
- How to cross compile
 | 
			
		||||
    ```bash
 | 
			
		||||
    $ cd /path/to/your/local-git-reporsitory/vuls
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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,11 @@ 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]
 | 
			
		||||
			[-ask-sudo-password]
 | 
			
		||||
			[-ask-key-password]
 | 
			
		||||
			[-debug]
 | 
			
		||||
 | 
			
		||||
`
 | 
			
		||||
}
 | 
			
		||||
@@ -68,6 +75,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 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 +99,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.askKeyPassword,
 | 
			
		||||
		"ask-key-password",
 | 
			
		||||
		false,
 | 
			
		||||
		"Ask ssh privatekey password before scanning",
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(
 | 
			
		||||
		&p.askSudoPassword,
 | 
			
		||||
		"ask-sudo-password",
 | 
			
		||||
		false,
 | 
			
		||||
		"Ask sudo 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)
 | 
			
		||||
@@ -45,14 +45,28 @@ func (c TOMLLoader) Load(pathToToml string) (err error) {
 | 
			
		||||
	Conf.Default = d
 | 
			
		||||
	servers := make(map[string]ServerInfo)
 | 
			
		||||
 | 
			
		||||
	if keyPass != "" {
 | 
			
		||||
		d.KeyPassword = keyPass
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if sudoPass != "" {
 | 
			
		||||
		d.Password = sudoPass
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	i := 0
 | 
			
		||||
	for name, v := range conf.Servers {
 | 
			
		||||
 | 
			
		||||
		if 0 < len(v.KeyPassword) || 0 < len(v.Password) {
 | 
			
		||||
			log.Warn("[Depricated] password and keypassword in config file are unsecure. Remove them immediately for a security reason. They will be removed in a future release.")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s := ServerInfo{ServerName: name}
 | 
			
		||||
		s.User = v.User
 | 
			
		||||
		if s.User == "" {
 | 
			
		||||
			s.User = d.User
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//  s.Password = sudoPass
 | 
			
		||||
		s.Password = v.Password
 | 
			
		||||
		if s.Password == "" {
 | 
			
		||||
			s.Password = d.Password
 | 
			
		||||
@@ -76,6 +90,7 @@ func (c TOMLLoader) Load(pathToToml string) (err error) {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//  s.KeyPassword = keyPass
 | 
			
		||||
		s.KeyPassword = v.KeyPassword
 | 
			
		||||
		if s.KeyPassword == "" {
 | 
			
		||||
			s.KeyPassword = d.KeyPassword
 | 
			
		||||
 
 | 
			
		||||
@@ -129,6 +129,7 @@ func (o *redhat) installYumPluginSecurity() error {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	o.log.Info("Installing yum-plugin-security...")
 | 
			
		||||
	cmd := util.PrependProxyEnv("yum install -y yum-plugin-security")
 | 
			
		||||
	if r := o.ssh(cmd, sudo); !r.isSuccess() {
 | 
			
		||||
		return fmt.Errorf(
 | 
			
		||||
@@ -139,7 +140,6 @@ func (o *redhat) installYumPluginSecurity() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *redhat) installYumChangelog() error {
 | 
			
		||||
	o.log.Info("Installing yum-plugin-security...")
 | 
			
		||||
 | 
			
		||||
	if o.Family == "centos" {
 | 
			
		||||
		var majorVersion int
 | 
			
		||||
@@ -164,6 +164,7 @@ func (o *redhat) installYumChangelog() error {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		o.log.Infof("Installing %s...", packName)
 | 
			
		||||
		cmd = util.PrependProxyEnv("yum install -y " + packName)
 | 
			
		||||
		if r := o.ssh(cmd, sudo); !r.isSuccess() {
 | 
			
		||||
			return fmt.Errorf(
 | 
			
		||||
@@ -458,7 +459,10 @@ func (o *redhat) parseYumCheckUpdateLine(line string) (models.PackageInfo, error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *redhat) getChangelog(packageNames string) (stdout string, err error) {
 | 
			
		||||
	command := "echo N | "
 | 
			
		||||
	command := ""
 | 
			
		||||
	if o.ServerInfo.User == "root" {
 | 
			
		||||
		command = "yes no | "
 | 
			
		||||
	}
 | 
			
		||||
	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
 | 
			
		||||
}
 | 
			
		||||
@@ -225,7 +226,8 @@ func sshConnect(c conf.ServerInfo) (client *ssh.Client, err error) {
 | 
			
		||||
 | 
			
		||||
	var auths = []ssh.AuthMethod{}
 | 
			
		||||
	if auths, err = addKeyAuth(auths, c.KeyPath, c.KeyPassword); err != nil {
 | 
			
		||||
		logrus.Fatalf("Failed to add keyAuth. err: %s", err)
 | 
			
		||||
		logrus.Fatalf("Failed to add keyAuth. %s@%s:%s err: %s",
 | 
			
		||||
			c.User, c.Host, c.Port, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.Password != "" {
 | 
			
		||||
@@ -237,12 +239,10 @@ func sshConnect(c conf.ServerInfo) (client *ssh.Client, err error) {
 | 
			
		||||
		User: c.User,
 | 
			
		||||
		Auth: auths,
 | 
			
		||||
	}
 | 
			
		||||
	//  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))
 | 
			
		||||
	}
 | 
			
		||||
	err = backoff.RetryNotify(func() error {
 | 
			
		||||
		if client, err = ssh.Dial("tcp", c.Host+":"+c.Port, config); err != nil {
 | 
			
		||||
@@ -309,3 +309,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