示例#1
0
文件: server.go 项目: Blystad/deis
func (s *server) insertIdentity(req []byte) error {
	var record struct {
		Type string `sshtype:"17"`
		Rest []byte `ssh:"rest"`
	}
	if err := ssh.Unmarshal(req, &record); err != nil {
		return err
	}

	switch record.Type {
	case ssh.KeyAlgoRSA:
		var k rsaKeyMsg
		if err := ssh.Unmarshal(req, &k); err != nil {
			return err
		}

		priv := rsa.PrivateKey{
			PublicKey: rsa.PublicKey{
				E: int(k.E.Int64()),
				N: k.N,
			},
			D:      k.D,
			Primes: []*big.Int{k.P, k.Q},
		}
		priv.Precompute()

		return s.agent.Add(&priv, nil, k.Comments)
	}
	return fmt.Errorf("not implemented: %s", record.Type)
}
示例#2
0
文件: client.go 项目: Blystad/deis
func parseKey(in []byte) (out *Key, rest []byte, err error) {
	var record struct {
		Blob    []byte
		Comment string
		Rest    []byte `ssh:"rest"`
	}

	if err := ssh.Unmarshal(in, &record); err != nil {
		return nil, nil, err
	}

	var wk wireKey
	if err := ssh.Unmarshal(record.Blob, &wk); err != nil {
		return nil, nil, err
	}

	return &Key{
		Format:  wk.Format,
		Blob:    record.Blob,
		Comment: record.Comment,
	}, record.Rest, nil
}
示例#3
0
文件: client.go 项目: Blystad/deis
// unmarshal parses an agent message in packet, returning the parsed
// form and the message type of packet.
func unmarshal(packet []byte) (interface{}, error) {
	if len(packet) < 1 {
		return nil, errors.New("agent: empty packet")
	}
	var msg interface{}
	switch packet[0] {
	case agentFailure:
		return new(failureAgentMsg), nil
	case agentSuccess:
		return new(successAgentMsg), nil
	case agentIdentitiesAnswer:
		msg = new(identitiesAnswerAgentMsg)
	case agentSignResponse:
		msg = new(signResponseAgentMsg)
	default:
		return nil, fmt.Errorf("agent: unknown type tag %d", packet[0])
	}
	if err := ssh.Unmarshal(packet, msg); err != nil {
		return nil, err
	}
	return msg, nil
}
示例#4
0
文件: client.go 项目: Blystad/deis
// Sign has the agent sign the data using a protocol 2 key as defined
// in [PROTOCOL.agent] section 2.6.2.
func (c *client) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
	req := ssh.Marshal(signRequestAgentMsg{
		KeyBlob: key.Marshal(),
		Data:    data,
	})

	msg, err := c.call(req)
	if err != nil {
		return nil, err
	}

	switch msg := msg.(type) {
	case *signResponseAgentMsg:
		var sig ssh.Signature
		if err := ssh.Unmarshal(msg.SigBlob, &sig); err != nil {
			return nil, err
		}

		return &sig, nil
	case *failureAgentMsg:
		return nil, errors.New("agent: failed to sign challenge")
	}
	panic("unreachable")
}
示例#5
0
文件: server.go 项目: Blystad/deis
func (s *server) processRequest(data []byte) (interface{}, error) {
	switch data[0] {
	case agentRequestV1Identities:
		return &agentV1IdentityMsg{0}, nil
	case agentRemoveIdentity:
		var req agentRemoveIdentityMsg
		if err := ssh.Unmarshal(data, &req); err != nil {
			return nil, err
		}

		var wk wireKey
		if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
			return nil, err
		}

		return nil, s.agent.Remove(&Key{Format: wk.Format, Blob: req.KeyBlob})

	case agentRemoveAllIdentities:
		return nil, s.agent.RemoveAll()

	case agentLock:
		var req agentLockMsg
		if err := ssh.Unmarshal(data, &req); err != nil {
			return nil, err
		}

		return nil, s.agent.Lock(req.Passphrase)

	case agentUnlock:
		var req agentLockMsg
		if err := ssh.Unmarshal(data, &req); err != nil {
			return nil, err
		}
		return nil, s.agent.Unlock(req.Passphrase)

	case agentSignRequest:
		var req signRequestAgentMsg
		if err := ssh.Unmarshal(data, &req); err != nil {
			return nil, err
		}

		var wk wireKey
		if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
			return nil, err
		}

		k := &Key{
			Format: wk.Format,
			Blob:   req.KeyBlob,
		}

		sig, err := s.agent.Sign(k, req.Data) //  TODO(hanwen): flags.
		if err != nil {
			return nil, err
		}
		return &signResponseAgentMsg{SigBlob: ssh.Marshal(sig)}, nil
	case agentRequestIdentities:
		keys, err := s.agent.List()
		if err != nil {
			return nil, err
		}

		rep := identitiesAnswerAgentMsg{
			NumKeys: uint32(len(keys)),
		}
		for _, k := range keys {
			rep.Keys = append(rep.Keys, marshalKey(k)...)
		}
		return rep, nil
	case agentAddIdentity:
		return nil, s.insertIdentity(data)
	}

	return nil, fmt.Errorf("unknown opcode %d", data[0])
}
示例#6
0
func processRequests(conn *ssh.ServerConn, reqs <-chan *ssh.Request) {
	for req := range reqs {
		if req.Type != "tcpip-forward" {
			// accept only tcpip-forward requests
			if req.WantReply {
				req.Reply(false, nil)
			}
			continue
		}
		type channelForwardMsg struct {
			Laddr string
			Lport uint32
		}
		m := &channelForwardMsg{}
		ssh.Unmarshal(req.Payload, m)

		privateBytes, err := ioutil.ReadFile(appConfig.RemotePrivateKeyPath)
		if err != nil {
			log.Fatal(err.Error())
		}

		signer, err := ssh.ParsePrivateKey(privateBytes)
		if err != nil {
			log.Fatal(err.Error())
		}

		config := &ssh.ClientConfig{
			User: appConfig.RemoteSSHUser,
			Auth: []ssh.AuthMethod{
				ssh.PublicKeys(signer),
			},
		}
		sshClientConn, err := ssh.Dial("tcp", appConfig.RemoteSSHAddr, config)
		if err != nil {
			log.Fatal(err.Error())
		}

		type channelOpenForwardMsg struct {
			raddr string
			rport uint32
			laddr string
			lport uint32
		}

		fm := &channelOpenForwardMsg{
			raddr: "localhost",
			rport: m.Lport,
			laddr: "localhost",
			lport: m.Lport,
		}
		channel, reqs, err := conn.Conn.OpenChannel("forwarded-tcpip", ssh.Marshal(fm))
		if err != nil {
			log.Fatal(err.Error())
		}

		go ssh.DiscardRequests(reqs)

		portListener, err := sshClientConn.Listen("tcp", appConfig.RemoteForwardAddress)
		if err != nil {
			log.Fatal(err.Error())
		}

		go func() {
			for {
				sshConn, err := portListener.Accept()
				if err != nil {
					log.Fatal(err.Error())
				}

				// Copy localConn.Reader to sshConn.Writer
				go func(sshConn net.Conn) {
					_, err := io.Copy(sshConn, channel)
					if err != nil {
						log.Println("io.Copy failed: %v", err)
						sshConn.Close()
						return
					}
				}(sshConn)

				// Copy sshConn.Reader to localConn.Writer
				go func(sshConn net.Conn) {
					_, err := io.Copy(channel, sshConn)
					if err != nil {
						log.Println("io.Copy failed: %v", err)
						sshConn.Close()
						return
					}
				}(sshConn)
			}
		}()
		req.Reply(true, nil)
	}
}