mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Handle CORS requests (#6289)
This commit is contained in:
committed by
techknowlogick
parent
6fb58a8cdc
commit
34d06f4c6b
120
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
120
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
@@ -25,10 +25,22 @@ import (
|
||||
"math/big"
|
||||
"sync"
|
||||
|
||||
"crypto"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// SignatureFlags represent additional flags that can be passed to the signature
|
||||
// requests an defined in [PROTOCOL.agent] section 4.5.1.
|
||||
type SignatureFlags uint32
|
||||
|
||||
// SignatureFlag values as defined in [PROTOCOL.agent] section 5.3.
|
||||
const (
|
||||
SignatureFlagReserved SignatureFlags = 1 << iota
|
||||
SignatureFlagRsaSha256
|
||||
SignatureFlagRsaSha512
|
||||
)
|
||||
|
||||
// Agent represents the capabilities of an ssh-agent.
|
||||
type Agent interface {
|
||||
// List returns the identities known to the agent.
|
||||
@@ -57,6 +69,26 @@ type Agent interface {
|
||||
Signers() ([]ssh.Signer, error)
|
||||
}
|
||||
|
||||
type ExtendedAgent interface {
|
||||
Agent
|
||||
|
||||
// SignWithFlags signs like Sign, but allows for additional flags to be sent/received
|
||||
SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error)
|
||||
|
||||
// Extension processes a custom extension request. Standard-compliant agents are not
|
||||
// required to support any extensions, but this method allows agents to implement
|
||||
// vendor-specific methods or add experimental features. See [PROTOCOL.agent] section 4.7.
|
||||
// If agent extensions are unsupported entirely this method MUST return an
|
||||
// ErrExtensionUnsupported error. Similarly, if just the specific extensionType in
|
||||
// the request is unsupported by the agent then ErrExtensionUnsupported MUST be
|
||||
// returned.
|
||||
//
|
||||
// In the case of success, since [PROTOCOL.agent] section 4.7 specifies that the contents
|
||||
// of the response are unspecified (including the type of the message), the complete
|
||||
// response will be returned as a []byte slice, including the "type" byte of the message.
|
||||
Extension(extensionType string, contents []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
// ConstraintExtension describes an optional constraint defined by users.
|
||||
type ConstraintExtension struct {
|
||||
// ExtensionName consist of a UTF-8 string suffixed by the
|
||||
@@ -179,6 +211,23 @@ type constrainExtensionAgentMsg struct {
|
||||
Rest []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
// See [PROTOCOL.agent], section 4.7
|
||||
const agentExtension = 27
|
||||
const agentExtensionFailure = 28
|
||||
|
||||
// ErrExtensionUnsupported indicates that an extension defined in
|
||||
// [PROTOCOL.agent] section 4.7 is unsupported by the agent. Specifically this
|
||||
// error indicates that the agent returned a standard SSH_AGENT_FAILURE message
|
||||
// as the result of a SSH_AGENTC_EXTENSION request. Note that the protocol
|
||||
// specification (and therefore this error) does not distinguish between a
|
||||
// specific extension being unsupported and extensions being unsupported entirely.
|
||||
var ErrExtensionUnsupported = errors.New("agent: extension unsupported")
|
||||
|
||||
type extensionAgentMsg struct {
|
||||
ExtensionType string `sshtype:"27"`
|
||||
Contents []byte
|
||||
}
|
||||
|
||||
// Key represents a protocol 2 public key as defined in
|
||||
// [PROTOCOL.agent], section 2.5.2.
|
||||
type Key struct {
|
||||
@@ -260,7 +309,7 @@ type client struct {
|
||||
|
||||
// NewClient returns an Agent that talks to an ssh-agent process over
|
||||
// the given connection.
|
||||
func NewClient(rw io.ReadWriter) Agent {
|
||||
func NewClient(rw io.ReadWriter) ExtendedAgent {
|
||||
return &client{conn: rw}
|
||||
}
|
||||
|
||||
@@ -268,6 +317,21 @@ func NewClient(rw io.ReadWriter) Agent {
|
||||
// unmarshaled into reply and replyType is set to the first byte of
|
||||
// the reply, which contains the type of the message.
|
||||
func (c *client) call(req []byte) (reply interface{}, err error) {
|
||||
buf, err := c.callRaw(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reply, err = unmarshal(buf)
|
||||
if err != nil {
|
||||
return nil, clientErr(err)
|
||||
}
|
||||
return reply, nil
|
||||
}
|
||||
|
||||
// callRaw sends an RPC to the agent. On success, the raw
|
||||
// bytes of the response are returned; no unmarshalling is
|
||||
// performed on the response.
|
||||
func (c *client) callRaw(req []byte) (reply []byte, err error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
@@ -284,18 +348,14 @@ func (c *client) call(req []byte) (reply interface{}, err error) {
|
||||
}
|
||||
respSize := binary.BigEndian.Uint32(respSizeBuf[:])
|
||||
if respSize > maxAgentResponseBytes {
|
||||
return nil, clientErr(err)
|
||||
return nil, clientErr(errors.New("response too large"))
|
||||
}
|
||||
|
||||
buf := make([]byte, respSize)
|
||||
if _, err = io.ReadFull(c.conn, buf); err != nil {
|
||||
return nil, clientErr(err)
|
||||
}
|
||||
reply, err = unmarshal(buf)
|
||||
if err != nil {
|
||||
return nil, clientErr(err)
|
||||
}
|
||||
return reply, err
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (c *client) simpleCall(req []byte) error {
|
||||
@@ -369,9 +429,14 @@ func (c *client) List() ([]*Key, error) {
|
||||
// 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) {
|
||||
return c.SignWithFlags(key, data, 0)
|
||||
}
|
||||
|
||||
func (c *client) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error) {
|
||||
req := ssh.Marshal(signRequestAgentMsg{
|
||||
KeyBlob: key.Marshal(),
|
||||
Data: data,
|
||||
Flags: uint32(flags),
|
||||
})
|
||||
|
||||
msg, err := c.call(req)
|
||||
@@ -681,3 +746,44 @@ func (s *agentKeyringSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature,
|
||||
// The agent has its own entropy source, so the rand argument is ignored.
|
||||
return s.agent.Sign(s.pub, data)
|
||||
}
|
||||
|
||||
func (s *agentKeyringSigner) SignWithOpts(rand io.Reader, data []byte, opts crypto.SignerOpts) (*ssh.Signature, error) {
|
||||
var flags SignatureFlags
|
||||
if opts != nil {
|
||||
switch opts.HashFunc() {
|
||||
case crypto.SHA256:
|
||||
flags = SignatureFlagRsaSha256
|
||||
case crypto.SHA512:
|
||||
flags = SignatureFlagRsaSha512
|
||||
}
|
||||
}
|
||||
return s.agent.SignWithFlags(s.pub, data, flags)
|
||||
}
|
||||
|
||||
// Calls an extension method. It is up to the agent implementation as to whether or not
|
||||
// any particular extension is supported and may always return an error. Because the
|
||||
// type of the response is up to the implementation, this returns the bytes of the
|
||||
// response and does not attempt any type of unmarshalling.
|
||||
func (c *client) Extension(extensionType string, contents []byte) ([]byte, error) {
|
||||
req := ssh.Marshal(extensionAgentMsg{
|
||||
ExtensionType: extensionType,
|
||||
Contents: contents,
|
||||
})
|
||||
buf, err := c.callRaw(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(buf) == 0 {
|
||||
return nil, errors.New("agent: failure; empty response")
|
||||
}
|
||||
// [PROTOCOL.agent] section 4.7 indicates that an SSH_AGENT_FAILURE message
|
||||
// represents an agent that does not support the extension
|
||||
if buf[0] == agentFailure {
|
||||
return nil, ErrExtensionUnsupported
|
||||
}
|
||||
if buf[0] == agentExtensionFailure {
|
||||
return nil, errors.New("agent: generic extension failure")
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
28
vendor/golang.org/x/crypto/ssh/agent/keyring.go
generated
vendored
28
vendor/golang.org/x/crypto/ssh/agent/keyring.go
generated
vendored
@@ -182,6 +182,10 @@ func (r *keyring) Add(key AddedKey) error {
|
||||
|
||||
// Sign returns a signature for the data.
|
||||
func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
|
||||
return r.SignWithFlags(key, data, 0)
|
||||
}
|
||||
|
||||
func (r *keyring) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if r.locked {
|
||||
@@ -192,7 +196,24 @@ func (r *keyring) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
|
||||
wanted := key.Marshal()
|
||||
for _, k := range r.keys {
|
||||
if bytes.Equal(k.signer.PublicKey().Marshal(), wanted) {
|
||||
return k.signer.Sign(rand.Reader, data)
|
||||
if flags == 0 {
|
||||
return k.signer.Sign(rand.Reader, data)
|
||||
} else {
|
||||
if algorithmSigner, ok := k.signer.(ssh.AlgorithmSigner); !ok {
|
||||
return nil, fmt.Errorf("agent: signature does not support non-default signature algorithm: %T", k.signer)
|
||||
} else {
|
||||
var algorithm string
|
||||
switch flags {
|
||||
case SignatureFlagRsaSha256:
|
||||
algorithm = ssh.SigAlgoRSASHA2256
|
||||
case SignatureFlagRsaSha512:
|
||||
algorithm = ssh.SigAlgoRSASHA2512
|
||||
default:
|
||||
return nil, fmt.Errorf("agent: unsupported signature flags: %d", flags)
|
||||
}
|
||||
return algorithmSigner.SignWithAlgorithm(rand.Reader, data, algorithm)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, errors.New("not found")
|
||||
@@ -213,3 +234,8 @@ func (r *keyring) Signers() ([]ssh.Signer, error) {
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// The keyring does not support any extensions
|
||||
func (r *keyring) Extension(extensionType string, contents []byte) ([]byte, error) {
|
||||
return nil, ErrExtensionUnsupported
|
||||
}
|
||||
|
49
vendor/golang.org/x/crypto/ssh/agent/server.go
generated
vendored
49
vendor/golang.org/x/crypto/ssh/agent/server.go
generated
vendored
@@ -128,7 +128,14 @@ func (s *server) processRequest(data []byte) (interface{}, error) {
|
||||
Blob: req.KeyBlob,
|
||||
}
|
||||
|
||||
sig, err := s.agent.Sign(k, req.Data) // TODO(hanwen): flags.
|
||||
var sig *ssh.Signature
|
||||
var err error
|
||||
if extendedAgent, ok := s.agent.(ExtendedAgent); ok {
|
||||
sig, err = extendedAgent.SignWithFlags(k, req.Data, SignatureFlags(req.Flags))
|
||||
} else {
|
||||
sig, err = s.agent.Sign(k, req.Data)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -150,6 +157,43 @@ func (s *server) processRequest(data []byte) (interface{}, error) {
|
||||
|
||||
case agentAddIDConstrained, agentAddIdentity:
|
||||
return nil, s.insertIdentity(data)
|
||||
|
||||
case agentExtension:
|
||||
// Return a stub object where the whole contents of the response gets marshaled.
|
||||
var responseStub struct {
|
||||
Rest []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
if extendedAgent, ok := s.agent.(ExtendedAgent); !ok {
|
||||
// If this agent doesn't implement extensions, [PROTOCOL.agent] section 4.7
|
||||
// requires that we return a standard SSH_AGENT_FAILURE message.
|
||||
responseStub.Rest = []byte{agentFailure}
|
||||
} else {
|
||||
var req extensionAgentMsg
|
||||
if err := ssh.Unmarshal(data, &req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := extendedAgent.Extension(req.ExtensionType, req.Contents)
|
||||
if err != nil {
|
||||
// If agent extensions are unsupported, return a standard SSH_AGENT_FAILURE
|
||||
// message as required by [PROTOCOL.agent] section 4.7.
|
||||
if err == ErrExtensionUnsupported {
|
||||
responseStub.Rest = []byte{agentFailure}
|
||||
} else {
|
||||
// As the result of any other error processing an extension request,
|
||||
// [PROTOCOL.agent] section 4.7 requires that we return a
|
||||
// SSH_AGENT_EXTENSION_FAILURE code.
|
||||
responseStub.Rest = []byte{agentExtensionFailure}
|
||||
}
|
||||
} else {
|
||||
if len(res) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
responseStub.Rest = res
|
||||
}
|
||||
}
|
||||
|
||||
return responseStub, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown opcode %d", data[0])
|
||||
@@ -497,6 +541,9 @@ func ServeAgent(agent Agent, c io.ReadWriter) error {
|
||||
return err
|
||||
}
|
||||
l := binary.BigEndian.Uint32(length[:])
|
||||
if l == 0 {
|
||||
return fmt.Errorf("agent: request size is 0")
|
||||
}
|
||||
if l > maxAgentResponseBytes {
|
||||
// We also cap requests.
|
||||
return fmt.Errorf("agent: request too large: %d", l)
|
||||
|
Reference in New Issue
Block a user