mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-30 22:11:07 +00:00 
			
		
		
		
	resolves git conflicts from #3896 (credit to @belak, in case github doesn't keep original author during squash) Co-Authored-By: Matti Ranta <techknowlogick@gitea.io>
		
			
				
	
	
		
			83 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			83 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package ssh
 | |
| 
 | |
| import (
 | |
| 	"io"
 | |
| 	"io/ioutil"
 | |
| 	"net"
 | |
| 	"path"
 | |
| 	"sync"
 | |
| 
 | |
| 	gossh "golang.org/x/crypto/ssh"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	agentRequestType = "auth-agent-req@openssh.com"
 | |
| 	agentChannelType = "auth-agent@openssh.com"
 | |
| 
 | |
| 	agentTempDir    = "auth-agent"
 | |
| 	agentListenFile = "listener.sock"
 | |
| )
 | |
| 
 | |
| // contextKeyAgentRequest is an internal context key for storing if the
 | |
| // client requested agent forwarding
 | |
| var contextKeyAgentRequest = &contextKey{"auth-agent-req"}
 | |
| 
 | |
| // SetAgentRequested sets up the session context so that AgentRequested
 | |
| // returns true.
 | |
| func SetAgentRequested(ctx Context) {
 | |
| 	ctx.SetValue(contextKeyAgentRequest, true)
 | |
| }
 | |
| 
 | |
| // AgentRequested returns true if the client requested agent forwarding.
 | |
| func AgentRequested(sess Session) bool {
 | |
| 	return sess.Context().Value(contextKeyAgentRequest) == true
 | |
| }
 | |
| 
 | |
| // NewAgentListener sets up a temporary Unix socket that can be communicated
 | |
| // to the session environment and used for forwarding connections.
 | |
| func NewAgentListener() (net.Listener, error) {
 | |
| 	dir, err := ioutil.TempDir("", agentTempDir)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	l, err := net.Listen("unix", path.Join(dir, agentListenFile))
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return l, nil
 | |
| }
 | |
| 
 | |
| // ForwardAgentConnections takes connections from a listener to proxy into the
 | |
| // session on the OpenSSH channel for agent connections. It blocks and services
 | |
| // connections until the listener stop accepting.
 | |
| func ForwardAgentConnections(l net.Listener, s Session) {
 | |
| 	sshConn := s.Context().Value(ContextKeyConn).(gossh.Conn)
 | |
| 	for {
 | |
| 		conn, err := l.Accept()
 | |
| 		if err != nil {
 | |
| 			return
 | |
| 		}
 | |
| 		go func(conn net.Conn) {
 | |
| 			defer conn.Close()
 | |
| 			channel, reqs, err := sshConn.OpenChannel(agentChannelType, nil)
 | |
| 			if err != nil {
 | |
| 				return
 | |
| 			}
 | |
| 			defer channel.Close()
 | |
| 			go gossh.DiscardRequests(reqs)
 | |
| 			var wg sync.WaitGroup
 | |
| 			wg.Add(2)
 | |
| 			go func() {
 | |
| 				io.Copy(conn, channel)
 | |
| 				conn.(*net.UnixConn).CloseWrite()
 | |
| 				wg.Done()
 | |
| 			}()
 | |
| 			go func() {
 | |
| 				io.Copy(channel, conn)
 | |
| 				channel.CloseWrite()
 | |
| 				wg.Done()
 | |
| 			}()
 | |
| 			wg.Wait()
 | |
| 		}(conn)
 | |
| 	}
 | |
| }
 |