Example #1
0
// remoteCmdOutput runs the given command on a remote server at the given hostname as the given user.
func remoteCmdOutput(username, hostname, cmd string, privateKey []byte) (b []byte, err error) {
	p, err := ssh.ParseRawPrivateKey(privateKey)
	if err != nil {
		return b, err
	}
	s, err := ssh.NewSignerFromKey(p)
	if err != nil {
		return b, err
	}
	pub := ssh.PublicKeys(s)
	clientConfig := &ssh.ClientConfig{
		User: username,
		Auth: []ssh.AuthMethod{pub},
	}
	client, err := ssh.Dial("tcp", hostname, clientConfig)
	if err != nil {
		return b, errors.New("ERROR: Failed to dial: " + err.Error())
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		return b, errors.New("ERROR: Failed to create session: " + err.Error())
	}
	defer session.Close()
	b, err = session.Output(cmd)
	if err != nil {
		return b, fmt.Errorf("ERROR: Failed to run cmd on host %s: %s", hostname, err.Error())
	}
	return b, nil
}
Example #2
0
func makeSigner(keyname string) (signer ssh.Signer, err error) {
	fp, err := os.Open(keyname)
	if err != nil {
		return
	}
	defer fp.Close()

	buf, err := ioutil.ReadAll(fp)
	if err != nil {
		panic(err)
		return
	}

	key, err := ssh.ParseRawPrivateKey(buf)
	if err != nil {
		panic(err)
		return
	}
	signer, err = ssh.NewSignerFromKey(key)
	if err != nil {
		panic(err)
		return
	}
	return
}
Example #3
0
// addKey parses an SSH private key for execd. It takes in the SSH server configuration and the key to add.
// It returns an error if the key is unsupported by execd.
func addKey(conf *ssh.ServerConfig, block *pem.Block) (err error) {
	var key interface{}

	switch block.Type {
	case "RSA PRIVATE KEY":
		key, err = x509.ParsePKCS1PrivateKey(block.Bytes)
	case "EC PRIVATE KEY":
		key, err = x509.ParseECPrivateKey(block.Bytes)
	case "DSA PRIVATE KEY":
		key, err = ssh.ParseDSAPrivateKey(block.Bytes)
	default:
		return fmt.Errorf("unsupported key type %q", block.Type)
	}
	if err != nil {
		return err
	}

	signer, err := ssh.NewSignerFromKey(key)
	if err != nil {
		return err
	}

	conf.AddHostKey(signer)

	return nil
}
Example #4
0
func testLockAgent(agent Agent, t *testing.T) {
	if err := agent.Add(testPrivateKeys["rsa"], nil, "comment 1"); err != nil {
		t.Errorf("Add: %v", err)
	}
	if err := agent.Add(testPrivateKeys["dsa"], nil, "comment dsa"); err != nil {
		t.Errorf("Add: %v", err)
	}
	if keys, err := agent.List(); err != nil {
		t.Errorf("List: %v", err)
	} else if len(keys) != 2 {
		t.Errorf("Want 2 keys, got %v", keys)
	}

	passphrase := []byte("secret")
	if err := agent.Lock(passphrase); err != nil {
		t.Errorf("Lock: %v", err)
	}

	if keys, err := agent.List(); err != nil {
		t.Errorf("List: %v", err)
	} else if len(keys) != 0 {
		t.Errorf("Want 0 keys, got %v", keys)
	}

	signer, _ := ssh.NewSignerFromKey(testPrivateKeys["rsa"])
	if _, err := agent.Sign(signer.PublicKey(), []byte("hello")); err == nil {
		t.Fatalf("Sign did not fail")
	}

	if err := agent.Remove(signer.PublicKey()); err == nil {
		t.Fatalf("Remove did not fail")
	}

	if err := agent.RemoveAll(); err == nil {
		t.Fatalf("RemoveAll did not fail")
	}

	if err := agent.Unlock(nil); err == nil {
		t.Errorf("Unlock with wrong passphrase succeeded")
	}
	if err := agent.Unlock(passphrase); err != nil {
		t.Errorf("Unlock: %v", err)
	}

	if err := agent.Remove(signer.PublicKey()); err != nil {
		t.Fatalf("Remove: %v", err)
	}

	if keys, err := agent.List(); err != nil {
		t.Errorf("List: %v", err)
	} else if len(keys) != 1 {
		t.Errorf("Want 1 keys, got %v", keys)
	}
}
Example #5
0
File: key.go Project: kgrvamsi/dssh
// GenerateKey generates a new ECDSA keypair suitable for use
// as an ssh host key.
// It can be passed as a parameter to ssh.ServerConfig.AddHostKey
func GenerateKey() (ssh.Signer, error) {
	pk, err := libtrust.GenerateECP521PrivateKey()
	if err != nil {
		return nil, err
	}
	s, err := ssh.NewSignerFromKey(pk.CryptoPrivateKey())
	if err != nil {
		return nil, err
	}
	return s, nil
}
Example #6
0
func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string) error {
	var req []byte
	switch k := s.(type) {
	case *rsa.PrivateKey:
		if len(k.Primes) != 2 {
			return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes))
		}
		k.Precompute()
		req = ssh.Marshal(rsaCertMsg{
			Type:      cert.Type(),
			CertBytes: cert.Marshal(),
			D:         k.D,
			Iqmp:      k.Precomputed.Qinv,
			P:         k.Primes[0],
			Q:         k.Primes[1],
			Comments:  comment,
		})
	case *dsa.PrivateKey:
		req = ssh.Marshal(dsaCertMsg{
			Type:      cert.Type(),
			CertBytes: cert.Marshal(),
			X:         k.X,
			Comments:  comment,
		})
	case *ecdsa.PrivateKey:
		req = ssh.Marshal(ecdsaCertMsg{
			Type:      cert.Type(),
			CertBytes: cert.Marshal(),
			D:         k.D,
			Comments:  comment,
		})
	default:
		return fmt.Errorf("agent: unsupported key type %T", s)
	}

	signer, err := ssh.NewSignerFromKey(s)
	if err != nil {
		return err
	}
	if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
		return errors.New("agent: signer and cert have different public key")
	}

	resp, err := c.call(req)
	if err != nil {
		return err
	}
	if _, ok := resp.(*successAgentMsg); ok {
		return nil
	}
	return errors.New("agent: failure")
}
Example #7
0
func testAgentInterface(t *testing.T, agent Agent, key interface{}, cert *ssh.Certificate) {
	signer, err := ssh.NewSignerFromKey(key)
	if err != nil {
		t.Fatalf("NewSignerFromKey: %v", err)
	}
	// The agent should start up empty.
	if keys, err := agent.List(); err != nil {
		t.Fatalf("RequestIdentities: %v", err)
	} else if len(keys) > 0 {
		t.Fatalf("got %d keys, want 0: %v", len(keys), keys)
	}

	// Attempt to insert the key, with certificate if specified.
	var pubKey ssh.PublicKey
	if cert != nil {
		err = agent.Add(key, cert, "comment")
		pubKey = cert
	} else {
		err = agent.Add(key, nil, "comment")
		pubKey = signer.PublicKey()
	}
	if err != nil {
		t.Fatalf("insert: %v", err)
	}

	// Did the key get inserted successfully?
	if keys, err := agent.List(); err != nil {
		t.Fatalf("List: %v", err)
	} else if len(keys) != 1 {
		t.Fatalf("got %v, want 1 key", keys)
	} else if keys[0].Comment != "comment" {
		t.Fatalf("key comment: got %v, want %v", keys[0].Comment, "comment")
	} else if !bytes.Equal(keys[0].Blob, pubKey.Marshal()) {
		t.Fatalf("key mismatch")
	}

	// Can the agent make a valid signature?
	data := []byte("hello")
	sig, err := agent.Sign(pubKey, data)
	if err != nil {
		t.Fatalf("Sign: %v", err)
	}

	if err := pubKey.Verify(data, sig); err != nil {
		t.Fatalf("key signature Verify: %v", err)
	}
}
Example #8
0
func (c *container) dialSSH() (*ssh.Client, error) {
	key, err := ssh.ParseRawPrivateKey([]byte(c.PrivateKey))
	if err != nil {
		return nil, err
	}
	signer, err := ssh.NewSignerFromKey(key)
	if err != nil {
		return nil, err
	}
	host := c.HostAddr + ":" + c.SSHHostPort
	config := ssh.ClientConfig{
		Config: ssh.Config{Rand: rand.Reader},
		Auth:   []ssh.AuthMethod{ssh.PublicKeys(signer)},
		User:   c.User,
	}
	return ssh.Dial("tcp", host, &config)
}
Example #9
0
// A method for the construction of the configuration
// object necessary for the connection to the host.
func (s *Session) NewConfig(user user) error {

	// get the content of the private key file
	key, err := loadPEM(os.ExpandEnv(tools.Expanduser(user.GetPrivateKey())))
	if err != nil {
		return err
	}

	// parse the key
	parsed, err := ssh.ParseRawPrivateKey(key)
	if err != nil {
		formatter.ColoredPrintln(
			formatter.Red,
			false,
			"Can't parse the private key!\n",
			"Reason is: ", err.Error(),
		)

	}

	// convert into signer
	signer, err := ssh.NewSignerFromKey(parsed)
	if err != nil {
		formatter.ColoredPrintln(
			formatter.Red,
			false,
			"Can't create signer from private key!\n",
			"Reason is: ", err.Error(),
		)

	}

	// Construct the configuration with password authentication
	s.Config = &ssh.ClientConfig{
		User: user.GetUsername(),
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(signer),
		},
	}

	return nil
}
Example #10
0
func TestSSHMux(t *testing.T) {
	key, err := rsa.GenerateKey(rand.Reader, 512)
	if err != nil {
		t.Fatal("GenerateKey", err)
	}

	l, err := net.Listen("tcp", ":0")
	if err != nil {
		t.Fatal("net.Listen", err)
	}

	id, err := ssh.NewSignerFromKey(key)
	if err != nil {
		t.Fatal("NewSignerFromKey(%T)", key, err)
	}

	listener := newSSHListener(l, id)
	dialer := newSSHDialer(id)

	testDialerMux(t, dialer, listener)
}
Example #11
0
func init() {
	var err error

	n := len(testdata.PEMBytes)
	testPrivateKeys = make(map[string]interface{}, n)
	testSigners = make(map[string]ssh.Signer, n)
	testPublicKeys = make(map[string]ssh.PublicKey, n)
	for t, k := range testdata.PEMBytes {
		testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k)
		if err != nil {
			panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err))
		}
		testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t])
		if err != nil {
			panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err))
		}
		testPublicKeys[t] = testSigners[t].PublicKey()
	}

	// Create a cert and sign it for use in tests.
	testCert := &ssh.Certificate{
		Nonce:           []byte{},                       // To pass reflect.DeepEqual after marshal & parse, this must be non-nil
		ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage
		ValidAfter:      0,                              // unix epoch
		ValidBefore:     ssh.CertTimeInfinity,           // The end of currently representable time.
		Reserved:        []byte{},                       // To pass reflect.DeepEqual after marshal & parse, this must be non-nil
		Key:             testPublicKeys["ecdsa"],
		SignatureKey:    testPublicKeys["rsa"],
		Permissions: ssh.Permissions{
			CriticalOptions: map[string]string{},
			Extensions:      map[string]string{},
		},
	}
	testCert.SignCert(rand.Reader, testSigners["rsa"])
	testPrivateKeys["cert"] = testPrivateKeys["ecdsa"]
	testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"])
	if err != nil {
		panic(fmt.Sprintf("Unable to create certificate signer: %v", err))
	}
}
Example #12
0
func (c *Config) populateAuthMethods() error {
	privKeyText, err := ioutil.ReadFile(c.privateKeyFile)
	if err != nil {
		return err
	}

	privKey, err := ssh.ParseRawPrivateKey(privKeyText)
	if err != nil {
		return err
	}

	signer, err := ssh.NewSignerFromKey(privKey)
	if err != nil {
		return err
	}

	c.authMethods = []ssh.AuthMethod{
		ssh.PublicKeys(signer),
	}

	return nil
}
Example #13
0
// Insert adds a private key to the keyring. If a certificate
// is given, that certificate is added as public key.
func (r *keyring) Add(priv interface{}, cert *ssh.Certificate, comment string) error {
	r.mu.Lock()
	defer r.mu.Unlock()
	if r.locked {
		return errLocked
	}
	signer, err := ssh.NewSignerFromKey(priv)

	if err != nil {
		return err
	}

	if cert != nil {
		signer, err = ssh.NewCertSigner(cert, signer)
		if err != nil {
			return err
		}
	}

	r.keys = append(r.keys, privKey{signer, comment})

	return nil
}
Example #14
0
func InitSSH() error {
	if enable, exist := common.Cfg.GetIntProperty("SSH", "Enable"); exist {
		if enable == 0 {
			return nil
		}
	}
	SSHEnable = true
	log.Println("Init SSH.")
	if proxy, exist := common.Cfg.GetProperty("SSH", "Proxy"); exist {
		sshLocalProxy, _ = url.Parse(proxy)
	}
	if enable, exist := common.Cfg.GetIntProperty("SSH", "RemoteResolve"); exist {
		sshResolveRemote = (enable != 0)
	}

	var manager SSH
	RegisteRemoteConnManager(&manager)

	index := 0
	for ; ; index = index + 1 {
		v, exist := common.Cfg.GetProperty("SSH", "Server["+strconv.Itoa(index)+"]")
		if !exist || len(v) == 0 {
			break
		}
		var ssh_conn SSHRawConnection
		if u, err := url.Parse(v); nil == err {
			ssh_conn.Server = u.Host
			if !strings.Contains(u.Host, ":") {
				ssh_conn.Server = net.JoinHostPort(u.Host, "22")
			}
			if u.User == nil {
				log.Printf("Invalid SSH server url:%s, no user found in url.\n", v)
				continue
			} else {
				if pass, exist := u.User.Password(); exist {
					ssh_conn.ClientConfig = &ssh.ClientConfig{
						User: u.User.Username(),
						Auth: []ssh.ClientAuth{
							ssh.ClientAuthPassword(password(pass)),
						},
					}
				} else {
					if identify := u.Query().Get("i"); len(identify) > 0 {
						if content, err := ioutil.ReadFile(identify); nil != err {
							log.Printf("Invalid SSH identify path:%s for reason:%v.\n", identify, err)
							continue
						} else {
							block, _ := pem.Decode([]byte(content))
							if nil == block {
								log.Printf("Invalid pem content for path:%s.\n", identify)
								continue
							}
							clientKeychain := new(keychain)
							if strings.Contains(block.Type, "RSA") {
								rsakey, err := ssh.ParsePrivateKey(block.Bytes)
								if err != nil {
									log.Printf("Invalid RSA private key for %v.\n", err)
									continue
								}
								clientKeychain.add(rsakey)
							} else {
								dsakey, err := ssh.NewSignerFromKey(block.Bytes)
								if err != nil {
									log.Printf("Invalid DSA private key for %v.\n", err)
									continue
								}
								clientKeychain.add(dsakey)
							}

							ssh_conn.ClientConfig = &ssh.ClientConfig{
								User: u.User.Username(),
								Auth: []ssh.ClientAuth{
									ssh.ClientAuthKeyring(clientKeychain),
								},
							}
						}

					} else {
						log.Printf("Invalid SSH server url:%s, no pass/identify found in url.\n", v)
						continue
					}

				}
			}
			if _, err := ssh_conn.GetClientConn(true); nil == err {
				manager.selector.Add(&ssh_conn)
				log.Printf("SSH server %s connected.\n", ssh_conn.Server)
			} else {
				log.Printf("Invalid SSH server url:%s to connect for reason:%v\n", v, err)
			}
		} else {
			log.Printf("Invalid SSH server url:%s for reason:%v\n", v, err)
		}
	}
	if index == 0 {
		return errors.New("No configed SSH server.")
	}

	return nil
}