mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-10-20 08:14:24 +00:00
Fix protocol input validation
This commit is contained in:
@@ -75,6 +75,9 @@ func fixReturnChecksum(packet []byte) {
|
||||
return
|
||||
}
|
||||
ipHdr := header.IPv6(packet)
|
||||
if !ipHdr.IsValid(len(packet)) {
|
||||
return
|
||||
}
|
||||
recomputeTransportChecksum(ipHdr.TransportProtocol(), ipHdr.Payload(), ipHdr.SourceAddressSlice(), ipHdr.DestinationAddressSlice())
|
||||
}
|
||||
}
|
||||
@@ -86,6 +89,10 @@ func recomputeTransportChecksum(protocol tcpip.TransportProtocolNumber, transpor
|
||||
return
|
||||
}
|
||||
tcpHdr := header.TCP(transport)
|
||||
dataOffset := int(tcpHdr.DataOffset())
|
||||
if dataOffset < header.TCPMinimumSize || dataOffset > len(transport) {
|
||||
return
|
||||
}
|
||||
tcpHdr.SetChecksum(0)
|
||||
payloadChecksum := checksum.Checksum(tcpHdr.Payload(), 0)
|
||||
pseudoChecksum := header.PseudoHeaderChecksum(header.TCPProtocolNumber, source, destination, uint16(len(transport)))
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"github.com/sagernet/sing-box/transport/v2rayhttp"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
@@ -184,11 +186,22 @@ func (n *Inbound) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
destination := M.ParseSocksaddr(hostPort).Unwrap()
|
||||
|
||||
if hijacker, isHijacker := writer.(http.Hijacker); isHijacker {
|
||||
conn, _, err := hijacker.Hijack()
|
||||
conn, reader, err := hijacker.Hijack()
|
||||
if err != nil {
|
||||
n.badRequest(ctx, request, E.New("hijack failed"))
|
||||
return
|
||||
}
|
||||
if cacheLen := reader.Reader.Buffered(); cacheLen > 0 {
|
||||
cache := buf.NewSize(cacheLen)
|
||||
_, err = cache.ReadFullFrom(reader.Reader, cacheLen)
|
||||
if err != nil {
|
||||
cache.Release()
|
||||
conn.Close()
|
||||
n.badRequest(ctx, request, E.Cause(err, "read cache"))
|
||||
return
|
||||
}
|
||||
conn = bufio.NewCachedConn(conn, cache)
|
||||
}
|
||||
n.newConnection(ctx, false, &naiveConn{Conn: conn}, userName, source, destination)
|
||||
} else {
|
||||
n.newConnection(ctx, true, &naiveH2Conn{
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@@ -35,13 +36,14 @@ var (
|
||||
|
||||
type MultiInbound struct {
|
||||
inbound.Adapter
|
||||
ctx context.Context
|
||||
router adapter.ConnectionRouterEx
|
||||
logger logger.ContextLogger
|
||||
listener *listener.Listener
|
||||
service shadowsocks.MultiService[int]
|
||||
users []option.ShadowsocksUser
|
||||
tracker adapter.SSMTracker
|
||||
ctx context.Context
|
||||
router adapter.ConnectionRouterEx
|
||||
logger logger.ContextLogger
|
||||
listener *listener.Listener
|
||||
service shadowsocks.MultiService[int]
|
||||
usersAccess sync.RWMutex
|
||||
users []option.ShadowsocksUser
|
||||
tracker adapter.SSMTracker
|
||||
}
|
||||
|
||||
func newMultiInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*MultiInbound, error) {
|
||||
@@ -123,6 +125,8 @@ func (h *MultiInbound) SetTracker(tracker adapter.SSMTracker) {
|
||||
}
|
||||
|
||||
func (h *MultiInbound) UpdateUsers(users []string, uPSKs []string) error {
|
||||
h.usersAccess.Lock()
|
||||
defer h.usersAccess.Unlock()
|
||||
err := h.service.UpdateUsersWithPasswords(common.MapIndexed(users, func(index int, user string) int {
|
||||
return index
|
||||
}), uPSKs)
|
||||
@@ -137,6 +141,15 @@ func (h *MultiInbound) UpdateUsers(users []string, uPSKs []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *MultiInbound) userName(userIndex int) string {
|
||||
h.usersAccess.RLock()
|
||||
defer h.usersAccess.RUnlock()
|
||||
if userIndex >= len(h.users) {
|
||||
return ""
|
||||
}
|
||||
return h.users[userIndex].Name
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
func (h *MultiInbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
||||
err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
|
||||
@@ -163,7 +176,7 @@ func (h *MultiInbound) newConnection(ctx context.Context, conn net.Conn, metadat
|
||||
if !loaded {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
user := h.users[userIndex].Name
|
||||
user := h.userName(userIndex)
|
||||
if user == "" {
|
||||
user = F.ToString(userIndex)
|
||||
} else {
|
||||
@@ -186,7 +199,7 @@ func (h *MultiInbound) newPacketConnection(ctx context.Context, conn N.PacketCon
|
||||
if !loaded {
|
||||
return os.ErrInvalid
|
||||
}
|
||||
user := h.users[userIndex].Name
|
||||
user := h.userName(userIndex)
|
||||
if user == "" {
|
||||
user = F.ToString(userIndex)
|
||||
} else {
|
||||
|
||||
@@ -186,16 +186,22 @@ func (t *DNSTransport) createResolver(directDialer func() N.Dialer, resolver *dn
|
||||
myDialer = dialer.NewResolveDialer(t.ctx, myDialer, false, "", t.endpoint.queryOptions, 0)
|
||||
}
|
||||
if isHTTPScheme {
|
||||
if serverURL.Hostname() == "" {
|
||||
return nil, E.New("missing host in resolver address: ", resolver.Addr)
|
||||
}
|
||||
serverAddr := M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
|
||||
switch serverURL.Scheme {
|
||||
case "https":
|
||||
if serverAddr.Port == 0 {
|
||||
serverAddr.Port = 443
|
||||
}
|
||||
tlsConfig := common.Must1(tls.NewClient(t.ctx, t.logger, serverAddr.AddrString(), option.OutboundTLSOptions{
|
||||
tlsConfig, err := tls.NewClient(t.ctx, t.logger, serverAddr.AddrString(), option.OutboundTLSOptions{
|
||||
Enabled: true,
|
||||
ALPN: []string{http2.NextProtoTLS, "http/1.1"},
|
||||
}))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "create TLS config for resolver ", resolver.Addr)
|
||||
}
|
||||
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.Header{}, serverAddr, tlsConfig), nil
|
||||
case "http":
|
||||
if serverAddr.Port == 0 {
|
||||
|
||||
@@ -361,7 +361,7 @@ func validateTaildropFileName(name string) error {
|
||||
|
||||
var (
|
||||
taildropExtensionSuffix = regexp.MustCompile(`(\.[a-zA-Z0-9]{0,3}[a-zA-Z][a-zA-Z0-9]{0,3})*$`)
|
||||
taildropNumberSuffix = regexp.MustCompile(` \([0-9]+\)`)
|
||||
taildropNumberSuffix = regexp.MustCompile(` \([0-9]+\)$`)
|
||||
)
|
||||
|
||||
func nextFileName(name string) string {
|
||||
|
||||
@@ -55,7 +55,7 @@ func (t *Endpoint) SendTaildropFile(ctx context.Context, peerStableID string, fi
|
||||
if !peer.Valid() {
|
||||
return E.New("taildrop: peer not found: ", peerStableID)
|
||||
}
|
||||
if peer.Hostinfo().OS() == "tvOS" {
|
||||
if !peer.Hostinfo().Valid() || peer.Hostinfo().OS() == "tvOS" {
|
||||
return E.New("taildrop: peer cannot receive files")
|
||||
}
|
||||
if self.User() != peer.User() && !nodeBackend.PeerHasCap(peer, tailcfg.PeerCapabilityFileSharingTarget) {
|
||||
@@ -187,7 +187,7 @@ func (t *Endpoint) taildropTargets() (canShareFiles bool, targets map[string]boo
|
||||
}
|
||||
targets = make(map[string]bool)
|
||||
for _, peer := range nodeBackend.Peers() {
|
||||
if !peer.Valid() || peer.Hostinfo().OS() == "tvOS" {
|
||||
if !peer.Valid() || !peer.Hostinfo().Valid() || peer.Hostinfo().OS() == "tvOS" {
|
||||
continue
|
||||
}
|
||||
if self.User() != peer.User() && !nodeBackend.PeerHasCap(peer, tailcfg.PeerCapabilityFileSharingTarget) {
|
||||
|
||||
@@ -334,6 +334,9 @@ func (s *Server) authenticate(ctx gliderssh.Context, conn gossh.ConnMetadata) (*
|
||||
func (s *Server) evaluatePolicy(policy *tailcfg.SSHPolicy, sshUser string, node tailcfg.NodeView, userProfile tailcfg.UserProfile, srcIP netip.Addr) (*sshConnInfo, error) {
|
||||
now := time.Now()
|
||||
for _, rule := range policy.Rules {
|
||||
if rule == nil {
|
||||
continue
|
||||
}
|
||||
if rule.RuleExpires != nil && now.After(*rule.RuleExpires) {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user