예제 #1
0
파일: server.go 프로젝트: faradayio/vault-1
func parseECDSACert(req []byte) (*AddedKey, error) {
	var k ecdsaCertMsg
	if err := ssh.Unmarshal(req, &k); err != nil {
		return nil, err
	}

	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
	if err != nil {
		return nil, err
	}
	cert, ok := pubKey.(*ssh.Certificate)
	if !ok {
		return nil, errors.New("agent: bad ECDSA certificate")
	}

	// An ECDSA publickey as marshaled by ecdsaPublicKey.Marshal() in keys.go
	var ecdsaPub struct {
		Name string
		ID   string
		Key  []byte
	}
	if err := ssh.Unmarshal(cert.Key.Marshal(), &ecdsaPub); err != nil {
		return nil, err
	}

	priv, err := unmarshalECDSA(ecdsaPub.ID, ecdsaPub.Key, k.D)
	if err != nil {
		return nil, err
	}

	return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
}
예제 #2
0
파일: server.go 프로젝트: CNDonny/scope
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(AddedKey{PrivateKey: &priv, Comment: k.Comments})
	}
	return fmt.Errorf("not implemented: %s", record.Type)
}
예제 #3
0
func (s *sshServer) handleRequests(channel ssh.Channel, in <-chan *ssh.Request) error {
	env := make(map[string]string)

	for req := range in {
		switch req.Type {
		default:
			log.Printf("unrecognized ssh request type=%q payload=%s wantreply=%t", req.Type, req.Payload, req.WantReply)
			req.Reply(false, nil) // unhandled; tell them so

		case "env":
			var e envReq
			if err := ssh.Unmarshal(req.Payload, &e); err != nil {
				req.Reply(false, nil)
				return err
			}
			req.Reply(true, nil)
			env[string(e.Key)] = string(e.Val)

		case "exec":
			var e execReq
			if err := ssh.Unmarshal(req.Payload, &e); err != nil {
				req.Reply(false, nil)
				return err
			}
			req.Reply(true, nil)

			var cmdbuf bytes.Buffer
			for k, v := range env {
				cmdbuf.WriteString(k)
				cmdbuf.WriteByte('=')
				cmdbuf.WriteString(v)
				cmdbuf.WriteByte(' ')
			}
			cmdbuf.Write(e.Command)

			log.Printf("Running command %q", cmdbuf.String())
			cmd := &packer.RemoteCmd{Command: cmdbuf.String()}
			cmd.Stdout = channel
			cmd.Stderr = channel.Stderr()
			var rc int
			if err := s.comm.Start(cmd); err != nil {
				rc = 255 // TODO: What is a better choice here?
			} else {
				cmd.Wait()
				rc = cmd.ExitStatus
			}
			channel.CloseWrite()
			channel.SendRequest("exit-status", false, []byte{0, 0, 0, byte(rc)})
			channel.Close()
		}
	}

	return nil
}
예제 #4
0
파일: ssh_key.go 프로젝트: CarloQ/gogs
// SSHNativeParsePublicKey extracts the key type and length using the golang SSH library.
// NOTE: ed25519 is not supported.
func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
	fields := strings.Fields(keyLine)
	if len(fields) < 2 {
		return "", 0, fmt.Errorf("not enough fields in public key line: %s", string(keyLine))
	}

	raw, err := base64.StdEncoding.DecodeString(fields[1])
	if err != nil {
		return "", 0, err
	}

	pkey, err := ssh.ParsePublicKey(raw)
	if err != nil {
		if strings.Contains(err.Error(), "ssh: unknown key algorithm") {
			return "", 0, ErrKeyUnableVerify{err.Error()}
		}
		return "", 0, fmt.Errorf("ssh.ParsePublicKey: %v", err)
	}

	// The ssh library can parse the key, so next we find out what key exactly we have.
	switch pkey.Type() {
	case ssh.KeyAlgoDSA:
		rawPub := struct {
			Name       string
			P, Q, G, Y *big.Int
		}{}
		if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
			return "", 0, err
		}
		// as per https://bugzilla.mindrot.org/show_bug.cgi?id=1647 we should never
		// see dsa keys != 1024 bit, but as it seems to work, we will not check here
		return "dsa", rawPub.P.BitLen(), nil // use P as per crypto/dsa/dsa.go (is L)
	case ssh.KeyAlgoRSA:
		rawPub := struct {
			Name string
			E    *big.Int
			N    *big.Int
		}{}
		if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
			return "", 0, err
		}
		return "rsa", rawPub.N.BitLen(), nil // use N as per crypto/rsa/rsa.go (is bits)
	case ssh.KeyAlgoECDSA256:
		return "ecdsa", 256, nil
	case ssh.KeyAlgoECDSA384:
		return "ecdsa", 384, nil
	case ssh.KeyAlgoECDSA521:
		return "ecdsa", 521, nil
	case "ssh-ed25519": // TODO replace with ssh constant when available
		return "ed25519", 256, nil
	}
	return "", 0, fmt.Errorf("Unsupported key length detection for type: %s", pkey.Type())
}
예제 #5
0
파일: client.go 프로젝트: CodyGuo/gosftp
// decodeClient decodes a response packet's raw data into its corresponding
// message structure.
func decodeClient(packet []byte) (interface{}, error) {
	var msg interface{}
	switch packet[0] {
	case fxpPacketVersion:
		msg = new(fxpVersionMsg)
	case fxpPacketStatus:
		msg = new(fxpStatusResp)
	case fxpPacketHandle:
		msg = new(fxpHandleResp)
	case fxpPacketData:
		msg = new(fxpDataResp)
	case fxpPacketName:
		msg = new(fxpNameResp)
	case fxpPacketAttrs:
		msg = new(fxpAttrsResp)
	case fxpPacketExtendedReply:
		msg = new(fxpExtendedResp)
	default:
		return nil, UnexpectedMessageError{0, packet[0]}
	}
	if err := ssh.Unmarshal(packet, msg); err != nil {
		return nil, err
	}
	return msg, nil
}
func (sess *session) handlePtyRequest(request *ssh.Request) {
	logger := sess.logger.Session("handle-pty-request")

	var ptyRequestMessage ptyRequestMsg

	err := ssh.Unmarshal(request.Payload, &ptyRequestMessage)
	if err != nil {
		logger.Error("unmarshal-failed", err)
		if request.WantReply {
			request.Reply(false, nil)
		}
		return
	}

	sess.Lock()
	defer sess.Unlock()

	sess.allocPty = true
	sess.ptyRequest = ptyRequestMessage
	sess.env["TERM"] = ptyRequestMessage.Term

	if request.WantReply {
		request.Reply(true, nil)
	}
}
func (sess *session) handleSignalRequest(request *ssh.Request) {
	logger := sess.logger.Session("handle-signal-request")

	type signalMsg struct {
		Signal string
	}
	var signalMessage signalMsg

	err := ssh.Unmarshal(request.Payload, &signalMessage)
	if err != nil {
		logger.Error("unmarshal-failed", err)
		if request.WantReply {
			request.Reply(false, nil)
		}
		return
	}

	sess.Lock()
	defer sess.Unlock()

	cmd := sess.command

	if cmd != nil {
		signal := signals.SyscallSignals[ssh.Signal(signalMessage.Signal)]
		err := sess.runner.Signal(cmd, signal)
		if err != nil {
			logger.Error("process-signal-failed", err)
		}
	}

	if request.WantReply {
		request.Reply(true, nil)
	}
}
예제 #8
0
파일: socket.go 프로젝트: agriffis/envy
func handleSSHChannel(newChan ssh.NewChannel, session *Session) {
	ch, reqs, err := newChan.Accept()
	if err != nil {
		log.Println("handle channel failed:", err)
		return
	}
	exitCh := make(chan int)
	go func() {
		status := struct{ Status uint32 }{uint32(<-exitCh)}
		_, err = ch.SendRequest("exit-status", false, ssh.Marshal(&status))
		assert(err)
		ch.Close()
	}()
	for req := range reqs {
		go func(req *ssh.Request) {
			if req.WantReply {
				req.Reply(true, nil)
			}
			switch req.Type {
			case "exec":
				var payload = struct{ Value string }{}
				ssh.Unmarshal(req.Payload, &payload)
				line := strings.Trim(payload.Value, "\n")
				var args []string
				if line != "" {
					args = strings.Split(line, " ")
				}
				RunCmd(args, ch, ch, ch.Stderr(), exitCh, session)
			}
		}(req)
	}
}
예제 #9
0
func (s *server) insertIdentity(req []byte) error {
	var record struct {
		Type string `sshtype:"17|25"`
		Rest []byte `ssh:"rest"`
	}

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

	var addedKey *AddedKey
	var err error

	switch record.Type {
	case ssh.KeyAlgoRSA:
		addedKey, err = parseRSAKey(req)
	case ssh.KeyAlgoDSA:
		addedKey, err = parseDSAKey(req)
	case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
		addedKey, err = parseECDSACert(req)
	case ssh.CertAlgoRSAv01:
		addedKey, err = parseRSACert(req)
	case ssh.CertAlgoDSAv01:
		addedKey, err = parseDSACert(req)
	case ssh.CertAlgoECDSA256v01, ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01:
		addedKey, err = parseECDSACert(req)
	default:
		return fmt.Errorf("agent: not implemented: %q", record.Type)
	}

	if err != nil {
		return err
	}
	return s.agent.Add(*addedKey)
}
예제 #10
0
func (sshClient *sshClient) handleNewPortForwardChannel(newChannel ssh.NewChannel) {
	defer sshClient.channelHandlerWaitGroup.Done()

	// http://tools.ietf.org/html/rfc4254#section-7.2
	var directTcpipExtraData struct {
		HostToConnect       string
		PortToConnect       uint32
		OriginatorIPAddress string
		OriginatorPort      uint32
	}

	err := ssh.Unmarshal(newChannel.ExtraData(), &directTcpipExtraData)
	if err != nil {
		sshClient.rejectNewChannel(newChannel, ssh.Prohibited, "invalid extra data")
		return
	}

	// Intercept TCP port forwards to a specified udpgw server and handle directly.
	// TODO: also support UDP explicitly, e.g. with a custom "direct-udp" channel type?
	isUDPChannel := sshClient.sshServer.support.Config.UDPInterceptUdpgwServerAddress != "" &&
		sshClient.sshServer.support.Config.UDPInterceptUdpgwServerAddress ==
			fmt.Sprintf("%s:%d",
				directTcpipExtraData.HostToConnect,
				directTcpipExtraData.PortToConnect)

	if isUDPChannel {
		sshClient.handleUDPChannel(newChannel)
	} else {
		sshClient.handleTCPChannel(
			directTcpipExtraData.HostToConnect, int(directTcpipExtraData.PortToConnect), newChannel)
	}
}
예제 #11
0
func (h *sshHandler) handleEnv(req *ssh.Request) {
	var pair EnvVar
	ssh.Unmarshal(req.Payload, &pair)
	envvar := fmt.Sprintf("%s=%s", pair.Name, pair.Value)
	h.Env = append(h.Env, envvar)
	req.Reply(true, nil)
}
func (handler *DirectTcpipChannelHandler) HandleNewChannel(logger lager.Logger, newChannel ssh.NewChannel) {
	type channelOpenDirectTcpipMsg struct {
		TargetAddr string
		TargetPort uint32
		OriginAddr string
		OriginPort uint32
	}
	var directTcpipMessage channelOpenDirectTcpipMsg

	err := ssh.Unmarshal(newChannel.ExtraData(), &directTcpipMessage)
	if err != nil {
		newChannel.Reject(ssh.ConnectionFailed, "Failed to parse open channel message")
		return
	}

	destination := fmt.Sprintf("%s:%d", directTcpipMessage.TargetAddr, directTcpipMessage.TargetPort)
	conn, err := handler.dialer.Dial("tcp", destination)
	if err != nil {
		newChannel.Reject(ssh.ConnectionFailed, err.Error())
		return
	}

	channel, requests, err := newChannel.Accept()
	go ssh.DiscardRequests(requests)

	wg := &sync.WaitGroup{}

	wg.Add(2)
	go helpers.CopyAndClose(logger.Session("to-target"), wg, conn, channel)
	go helpers.CopyAndClose(logger.Session("to-channel"), wg, channel, conn)

	wg.Wait()
}
func (sess *session) handleExecRequest(request *ssh.Request) {
	logger := sess.logger.Session("handle-exec-request")

	type execMsg struct {
		Command string
	}
	var execMessage execMsg

	err := ssh.Unmarshal(request.Payload, &execMessage)
	if err != nil {
		logger.Error("unmarshal-failed", err)
		if request.WantReply {
			request.Reply(false, nil)
		}
		return
	}

	if scpRegex.MatchString(execMessage.Command) {
		logger.Info("handling-scp-command", lager.Data{"Command": execMessage.Command})
		sess.executeSCP(execMessage.Command, request)
	} else {
		logger.Info("executeShell", lager.Data{"request": request, "command": execMessage.Command})
		sess.executeShell(request, "-c", execMessage.Command)
	}
}
예제 #14
0
파일: server.go 프로젝트: aledbf/builder
// cleanExec cleans the exec string.
func cleanExec(pay []byte) string {
	e := &ExecCmd{}
	ssh.Unmarshal(pay, e)
	// TODO: Minimal escaping of values in command. There is probably a better
	// way of doing this.
	r := strings.NewReplacer("$", "", "`", "'")
	return r.Replace(e.Value)
}
예제 #15
0
파일: server.go 프로젝트: faradayio/vault-1
func parseEd25519Key(req []byte) (*AddedKey, error) {
	var k ed25519KeyMsg
	if err := ssh.Unmarshal(req, &k); err != nil {
		return nil, err
	}
	priv := ed25519.PrivateKey(k.Priv)
	return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil
}
예제 #16
0
파일: adapter.go 프로젝트: arizvisa/packer
func newEnvRequest(raw *ssh.Request) (*envRequest, error) {
	r := new(envRequest)
	r.Request = raw

	if err := ssh.Unmarshal(raw.Payload, &r.Payload); err != nil {
		return nil, err
	}

	return r, nil
}
예제 #17
0
파일: client.go 프로젝트: CodyGuo/gosftp
// init starts the SFTP protocol by negotiating the protocol version to use and
// starts the response handler in a goroutine.
func (s *Client) init() error {
	msg := fxpInitMsg{
		Version: 3,
	}
	if err := s.writePacket(ssh.Marshal(msg)); err != nil {
		return err
	}
	packet, err := s.readOnePacket()
	if err != nil {
		return err
	}
	resp, err := decodeClient(packet)
	if err != nil {
		return err
	}
	switch resp := resp.(type) {
	case *fxpVersionMsg:
		if resp.Version != 3 {
			return errors.New("only version 3 of Client protocol supported")
		}
	default:
		return errors.New("invalid packet received during initialization")
	}
	vers := resp.(*fxpVersionMsg)
	s.exts = make(map[string]extension)
	if len(vers.Ext) > 0 {
		exts := vers.Ext
		for len(exts) > 0 {
			ew := extensionWire{}
			if err := ssh.Unmarshal(exts, &ew); err != nil {
				return err
			}
			if len(exts) < 2 {
				break
			}
			exts = ew.Rest

			e := extension{
				Name: ew.Name,
				Data: ew.Data,
			}
			// OpenSSH's sftp-server implementation specifies that
			// the data portion of an extension is an ASCII-encoded
			// version number. This is not part of the SFTP
			// specification, however.
			if n, err := strconv.Atoi(ew.Data); err == nil {
				e.version = n
			}
			s.exts[e.Name] = e
		}
	}
	go s.mainLoop()

	return nil
}
예제 #18
0
파일: server.go 프로젝트: faradayio/vault-1
func parseRSACert(req []byte) (*AddedKey, error) {
	var k rsaCertMsg
	if err := ssh.Unmarshal(req, &k); err != nil {
		return nil, err
	}

	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
	if err != nil {
		return nil, err
	}

	cert, ok := pubKey.(*ssh.Certificate)
	if !ok {
		return nil, errors.New("agent: bad RSA certificate")
	}

	// An RSA publickey as marshaled by rsaPublicKey.Marshal() in keys.go
	var rsaPub struct {
		Name string
		E    *big.Int
		N    *big.Int
	}
	if err := ssh.Unmarshal(cert.Key.Marshal(), &rsaPub); err != nil {
		return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
	}

	if rsaPub.E.BitLen() > 30 {
		return nil, errors.New("agent: RSA public exponent too large")
	}

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

	return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
}
예제 #19
0
func ParseRequest(req *ssh.Request) (*Request, error) {
	var raw struct {
		Value []byte
	}
	err := ssh.Unmarshal(req.Payload, &raw)
	if err != nil {
		return nil, err
	}

	return ParseRequestValue(raw.Value)
}
예제 #20
0
func (chsvr *sshSessionChannelServer) handleSubsystem(req *ssh.Request) error {
	defer func() {
		err1 := chsvr.ch.CloseWrite()
		err2 := chsvr.ch.Close()
		fmt.Fprintf(sshServerDebugStream, "ssh server subsystem request complete, err: %v %v\n", err1, err2)
	}()

	subsystemReq := &sshSubsystemRequest{}
	if err := ssh.Unmarshal(req.Payload, subsystemReq); err != nil {
		return rejectRequestUnmarshalError(req, subsystemReq, err)
	}

	// reply to the ssh client

	// no idea if this is actually correct spec-wise.
	// just enough for an sftp server to start.
	if subsystemReq.Name != "sftp" {
		return req.Reply(false, nil)
	}

	req.Reply(true, nil)

	if !chsvr.svr.useSubsystem {
		// use the openssh sftp server backend; this is to test the ssh code, not the sftp code,
		// or is used for comparison between our sftp subsystem and the openssh sftp subsystem
		cmd := exec.Command(*testSftp, "-e", "-l", "DEBUG") // log to stderr
		cmd.Stdin = chsvr.ch
		cmd.Stdout = chsvr.ch
		cmd.Stderr = sftpServerDebugStream
		if err := cmd.Start(); err != nil {
			return err
		}
		return cmd.Wait()
	}

	sftpServer, err := NewServer(
		chsvr.ch,
		chsvr.ch,
		WithDebug(sftpServerDebugStream),
	)
	if err != nil {
		return err
	}

	// wait for the session to close
	runErr := sftpServer.Serve()
	exitStatus := uint32(1)
	if runErr == nil {
		exitStatus = uint32(0)
	}

	_, exitStatusErr := chsvr.ch.SendRequest("exit-status", false, ssh.Marshal(sshSubsystemExitStatus{exitStatus}))
	return exitStatusErr
}
예제 #21
0
파일: forward.go 프로젝트: boazy/sshmux
// ChannelForward establishes a secure channel forward (ssh -W) to the server
// requested by the user, assuming it is a permitted host.
func (s *Server) ChannelForward(session *Session, newChannel ssh.NewChannel) {
	var msg channelOpenDirectMsg
	ssh.Unmarshal(newChannel.ExtraData(), &msg)
	address := fmt.Sprintf("%s:%d", msg.RAddr, msg.RPort)

	permitted := false
	for _, remote := range session.Remotes {
		if remote == address {
			permitted = true
			break
		}
	}

	if !permitted {
		log.Printf("Disallowed access to %s for user %s", address, session.User.Name)
		newChannel.Reject(ssh.Prohibited, "remote host access denied for user")
		return
	}

	// Log the selection
	if s.Selected != nil {
		if err := s.Selected(session, address); err != nil {
			newChannel.Reject(ssh.Prohibited, "access denied")
			return
		}
	}

	conn, err := net.Dial("tcp", address)
	if err != nil {
		newChannel.Reject(ssh.ConnectionFailed, fmt.Sprintf("error: %v", err))
		return
	}

	channel, reqs, err := newChannel.Accept()

	go ssh.DiscardRequests(reqs)
	var closer sync.Once
	closeFunc := func() {
		channel.Close()
		conn.Close()
	}

	go func() {
		io.Copy(channel, conn)
		closer.Do(closeFunc)
	}()

	go func() {
		io.Copy(conn, channel)
		closer.Do(closeFunc)
	}()
}
예제 #22
0
파일: client.go 프로젝트: ably-forks/flynn
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
}
예제 #23
0
파일: server.go 프로젝트: faradayio/vault-1
func parseECDSAKey(req []byte) (*AddedKey, error) {
	var k ecdsaKeyMsg
	if err := ssh.Unmarshal(req, &k); err != nil {
		return nil, err
	}

	priv, err := unmarshalECDSA(k.Curve, k.KeyBytes, k.D)
	if err != nil {
		return nil, err
	}

	return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil
}
예제 #24
0
파일: utils.go 프로젝트: ziyan/gatewaysshd
func UnmarshalForwardRequest(payload []byte) (*ForwardRequest, error) {
	request := &ForwardRequest{}

	if err := ssh.Unmarshal(payload, request); err != nil {
		return nil, err
	}

	// TODO: check host
	if request.Port > 65535 {
		return nil, ErrInvalidForwardRequest
	}

	return request, nil
}
예제 #25
0
func (sess *session) handleSubsystemRequest(request *ssh.Request) {
	logger := sess.logger.Session("handle-subsystem-request")
	logger.Info("starting")
	defer logger.Info("finished")

	type subsysMsg struct {
		Subsystem string
	}
	var subsystemMessage subsysMsg

	err := ssh.Unmarshal(request.Payload, &subsystemMessage)
	if err != nil {
		logger.Error("unmarshal-failed", err)
		if request.WantReply {
			request.Reply(false, nil)
		}
		return
	}

	if subsystemMessage.Subsystem != "sftp" {
		logger.Info("unsupported-subsystem", lager.Data{"subsystem": subsystemMessage.Subsystem})
		if request.WantReply {
			request.Reply(false, nil)
		}
		return
	}

	lagerWriter := helpers.NewLagerWriter(logger.Session("sftp-server"))
	sftpServer, err := sftp.NewServer(sess.channel, sess.channel, sftp.WithDebug(lagerWriter))
	if err != nil {
		logger.Error("sftp-new-server-failed", err)
		if request.WantReply {
			request.Reply(false, nil)
		}
		return
	}

	if request.WantReply {
		request.Reply(true, nil)
	}

	logger.Info("starting-server")
	go func() {
		defer sess.destroy()
		err = sftpServer.Serve()
		if err != nil {
			logger.Error("sftp-serve-error", err)
		}
	}()
}
예제 #26
0
파일: server.go 프로젝트: faradayio/vault-1
func parseDSACert(req []byte) (*AddedKey, error) {
	var k dsaCertMsg
	if err := ssh.Unmarshal(req, &k); err != nil {
		return nil, err
	}
	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
	if err != nil {
		return nil, err
	}
	cert, ok := pubKey.(*ssh.Certificate)
	if !ok {
		return nil, errors.New("agent: bad DSA certificate")
	}

	// A DSA publickey as marshaled by dsaPublicKey.Marshal() in keys.go
	var w struct {
		Name       string
		P, Q, G, Y *big.Int
	}
	if err := ssh.Unmarshal(cert.Key.Marshal(), &w); err != nil {
		return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
	}

	priv := &dsa.PrivateKey{
		PublicKey: dsa.PublicKey{
			Parameters: dsa.Parameters{
				P: w.P,
				Q: w.Q,
				G: w.G,
			},
			Y: w.Y,
		},
		X: k.X,
	}

	return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
}
예제 #27
0
파일: server.go 프로젝트: faradayio/vault-1
func parseEd25519Cert(req []byte) (*AddedKey, error) {
	var k ed25519CertMsg
	if err := ssh.Unmarshal(req, &k); err != nil {
		return nil, err
	}
	pubKey, err := ssh.ParsePublicKey(k.CertBytes)
	if err != nil {
		return nil, err
	}
	priv := ed25519.PrivateKey(k.Priv)
	cert, ok := pubKey.(*ssh.Certificate)
	if !ok {
		return nil, errors.New("agent: bad ED25519 certificate")
	}
	return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
}
예제 #28
0
func (s *session) handleExec(req *ssh.Request) error {
	cmd := execRequest{}
	if err := ssh.Unmarshal(req.Payload, &cmd); err != nil {
		return err
	}

	args, err := shellArgs([]byte(cmd.Command))
	if err != nil {
		return err
	}

	if err := s.exec(args); err != nil {
		log.Println("handleExec:", err)
		return fmt.Errorf("%s: %s", err, cmd.Command)
	}
	return nil
}
예제 #29
0
파일: utils.go 프로젝트: ziyan/gatewaysshd
func UnmarshalTunnelData(payload []byte) (*TunnelData, error) {
	data := &TunnelData{}

	if err := ssh.Unmarshal(payload, data); err != nil {
		return nil, err
	}

	// TODO: check host
	if data.Port > 65535 {
		return nil, ErrInvalidTunnelData
	}

	if data.OriginPort > 65535 {
		return nil, ErrInvalidTunnelData
	}

	return data, nil
}
예제 #30
0
파일: server.go 프로젝트: faradayio/vault-1
func parseDSAKey(req []byte) (*AddedKey, error) {
	var k dsaKeyMsg
	if err := ssh.Unmarshal(req, &k); err != nil {
		return nil, err
	}
	priv := &dsa.PrivateKey{
		PublicKey: dsa.PublicKey{
			Parameters: dsa.Parameters{
				P: k.P,
				Q: k.Q,
				G: k.G,
			},
			Y: k.Y,
		},
		X: k.X,
	}

	return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
}