예제 #1
0
 bool Handle(ConnectArgument x, out AdapterRef redir)
 {
     redir = null;
     if (parsedRules == null)
     {
         return(false);
     }
     foreach (var r in parsedRules)
     {
         var  abpFilter = r._abp_current_filter;
         bool hit       = false;
         if (abpFilter != null)
         {
             hit = abpFilter(x);
         }
         Match regexMatch = null;
         if (!hit)
         {
             hit = HandleRule(x, r, out regexMatch);
         }
         if (hit && onConnectionHit(r, x, regexMatch, out redir))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #2
0
파일: InConnection.cs 프로젝트: hex11/Naive
 public static ConnectResult RedirectTo(IAdapter adapter, AdapterRef redirectTo)
 {
     return(new ConnectResult(adapter, ConnectResultEnum.Failed)
     {
         Redirected = redirectTo
     });
 }
예제 #3
0
        protected Task HandleIncommingConnection(InConnection inConnection, AdapterRef outRef)
        {
            if (rdns?.Adapter is DnsInAdapter dnsIn)
            {
                try {
                    dnsIn.HandleRdns(inConnection);
                } catch (Exception e) {
                    Logger.exception(e, Logging.Level.Error, "rdns handling");
                }
            }

            return(Controller.HandleInConnection(inConnection, outRef.Adapter as IConnectionHandler));
        }
예제 #4
0
 private Task <DnsResponse> StartResolve(DnsRequestType type, string strName, out bool newTask)
 {
     if (dnsProvider == null)
     {
         throw new Exception("no dns resolver");
     }
     lock (resolvingNames) {
         newTask = false;
         if (resolvingNames.TryGetValue(strName, out var rt))
         {
             // try to return a running task
             if (type == DnsRequestType.A && rt.A != null)
             {
                 return(rt.A);
             }
             if (type == DnsRequestType.AAAA || rt.AAAA != null)
             {
                 return(rt.AAAA);
             }
             if (type == DnsRequestType.AnAAAA)
             {
                 if (rt.A == rt.AAAA)
                 {
                     return(rt.A);
                 }
                 if (rt.A != null && rt.AAAA != null)
                 {
                     return(UnionWarpper(rt));
                 }
             }
         }
         else
         {
             rt = new ResolveTask();
             resolvingNames[strName] = rt;
         }
         var task = Controller.ResolveName(this, AdapterRef.FromAdapter(dnsProvider), new DnsRequest(strName, type));
         if ((type & DnsRequestType.A) != 0 && rt.A == null)
         {
             rt.A = task;
         }
         if ((type & DnsRequestType.AAAA) != 0 && rt.AAAA == null)
         {
             rt.AAAA = task;
         }
         newTask = true;
         return(task);
     }
 }
예제 #5
0
파일: Controller.cs 프로젝트: smeoow/Naive
        public Task HandleInConnection(InConnection inc, AdapterRef outAdapterRef)
        {
            if (outAdapterRef == null)
            {
                throw new ArgumentNullException(nameof(outAdapterRef));
            }
            IConnectionHandler adapter = outAdapterRef.Adapter as IConnectionHandler;

            if (adapter == null)
            {
                if (LoggingLevel <= Logging.Level.Warning)
                {
                    warning($"null out adapter reference ({outAdapterRef})");
                }
            }
            return(HandleInConnection(inc, adapter));
        }
예제 #6
0
 private bool Auth(Socks5Server s)
 {
     if (s.Username.IsNullOrEmpty() && s.Password.IsNullOrEmpty() && _adapter._allowNoAuth)
     {
         return(true);
     }
     foreach (var x in _adapter.users)
     {
         if ((x.name ?? "") == s.Username && (x.passwd ?? "") == s.Password)
         {
             outRef = x.@out ?? _adapter.@out;
             return(true);
         }
     }
     _adapter.Logger.warning("Auth failed: " + _eppair.RemoteEP);
     return(false);
 }
예제 #7
0
파일: Controller.cs 프로젝트: smeoow/Naive
        public async Task <DnsResponse> ResolveName(IAdapter creator, AdapterRef handler, DnsRequest request)
        {
            var cxn = InConnectionDns.Create(creator, request);

            await HandleInConnection(cxn, handler);

            var result = cxn.ConnectResult;

            if (result?.Ok == false)
            {
                if (result.FailedReason != null)
                {
                    throw new Exception(result.FailedReason);
                }
                throw new Exception("name resolving failed.");
            }
            return(result as DnsResponse ?? DnsResponse.Empty(this));
        }
예제 #8
0
 public override void SetConfig(TomlTable toml)
 {
     base.SetConfig(toml);
     _noAuthOut = @out;
     if (users == null)
     {
         _allowNoAuth = true;
     }
     else
     {
         foreach (var x in users)
         {
             if (x.name.IsNullOrEmpty() && x.passwd.IsNullOrEmpty())
             {
                 _allowNoAuth = true;
                 _noAuthOut   = x.@out ?? @out;
                 break;
             }
         }
     }
 }
예제 #9
0
            public SocksInConnection(TcpClient tcp, SocksInAdapter adapter) : base(adapter)
            {
                _eppair   = EPPair.FromSocket(tcp.Client);
                _adapter  = adapter;
                _stream   = adapter.GetMyStreamFromSocket(tcp.Client);
                socks5svr = new Socks5Server(_stream);

                Socks5Server.Methods methods = Socks5Server.Methods.None;
                if (adapter._allowNoAuth)
                {
                    methods |= Socks5Server.Methods.NoAuth;
                }
                if (adapter.users != null)
                {
                    methods |= Socks5Server.Methods.UsernamePassword;
                }
                socks5svr.AcceptMethods = methods;

                outRef = adapter._noAuthOut;

                socks5svr.Auth = Auth;
            }
예제 #10
0
        // returns true if redirected
        private static bool onConnectionHit(Rule rule, ConnectArgument connection, Match regexMatch, out AdapterRef redirect)
        {
            AddrPort dest = connection.Dest;

            redirect = null;
            var destChanged = false;

            if (!rule.new_dest.IsDefault)
            {
                dest        = rule.new_dest;
                destChanged = true;
            }
            if (rule.new_host != null)
            {
                dest.Host   = rule.new_host;
                destChanged = true;
            }
            if (destChanged)
            {
                if (regexMatch != null)
                {
                    for (int i = regexMatch.Groups.Count - 1; i >= 0; i--)
                    {
                        dest.Host = dest.Host.Replace("$" + i, regexMatch.Groups[i].Value);
                    }
                }
                connection.Dest             = dest;
                connection.DestOriginalName = null;
            }
            if (rule.to != null)
            {
                redirect = rule.to;
                return(true);
            }
            return(false);
        }
예제 #11
0
            public LoadedConfig LoadConfig(ConfigFile cf, LoadedConfig newcfg)
            {
                var toml = cf.Content;

                newcfg = newcfg ?? new LoadedConfig();
                if (cf.Path != null)
                {
                    newcfg.FilePath         = cf.Path;
                    newcfg.WorkingDirectory = Path.GetDirectoryName(cf.Path);
                }
                Config    t;
                TomlTable tomlTable;
                var       refs = new List <AdapterRef>();

                try {
                    var tomlSettings = CreateTomlSettings(refs);
                    tomlTable = Toml.ReadString(toml, tomlSettings);
                    t         = tomlTable.Get <Config>();
                } catch (Exception e) {
                    Logger.exception(e, Logging.Level.Error, "TOML Error");
                    return(null);
                }

                newcfg.TomlTable    = tomlTable;
                newcfg.SocketImpl   = t.socket_impl;
                newcfg.LoggingLevel = t.log_level;
                newcfg.Aliases      = t.aliases;
                newcfg.DebugFlags   = t?.debug?.flags ?? new string[0];

                int failedCount = 0;

                if (tomlTable.TryGetValue <TomlTable>("a", out var tableA))
                {
                    foreach (var pair in tableA)
                    {
                        var typeName = pair.Key;
                        if (!(pair.Value is TomlTable table))
                        {
                            Logger.error($"TOML path 'a.{typeName}' is not a TOML table.");
                            continue;
                        }
                        foreach (var innerPair in table)
                        {
                            var name = innerPair.Key;
                            try {
                                var tt      = (TomlTable)innerPair.Value;
                                var adapter = NewRegisteredType(tt, name, typeName);
                                newcfg.Adapters.Add(adapter);
                            } catch (Exception e) {
                                Logger.exception(e, Logging.Level.Error, $"TOML table 'a.{typeName}.{name}':");
                                failedCount++;
                            }
                        }
                    }
                }
                if (t.@in != null)
                {
                    foreach (var item in t.@in)
                    {
                        try {
                            var tt      = item.Value;
                            var name    = "in." + item.Key;
                            var adapter = NewRegisteredInType(tt, name);
                            newcfg.Adapters.Add(adapter);
                        } catch (Exception e) {
                            Logger.exception(e, Logging.Level.Error, $"TOML table 'in.{item.Key}':");
                            failedCount++;
                        }
                    }
                }
                if (t.@out != null)
                {
                    foreach (var item in t.@out)
                    {
                        try {
                            var tt      = item.Value;
                            var name    = "out." + item.Key;
                            var adapter = NewRegisteredOutType(tt, name);
                            newcfg.Adapters.Add(adapter);
                        } catch (Exception e) {
                            Logger.exception(e, Logging.Level.Error, $"TOML table 'out.{item.Key}':");
                            failedCount++;
                        }
                    }
                }
                for (int rIdx = 0; rIdx < refs.Count; rIdx++)
                {
                    AdapterRef r = refs[rIdx];
                    if (r.IsTable == false)
                    {
                        continue;
                    }
                    var tt = r.Ref as TomlTable;
                    try {
                        string name = null;
                        if (tt.TryGetValue("name", out string n))
                        {
                            name = n;
                        }
                        if (name == null)
                        {
                            int i = 0;
                            do
                            {
                                name = $"_{tt["type"].Get<string>()}_" + ((i++ == 0) ? "" : i.ToString());
                            } while (newcfg.Adapters.Any(x => x.Name == name));
                        }
                        var adapter = NewRegisteredOutType(tt, name);
                        r.Adapter = adapter;
                        newcfg.Adapters.Add(adapter);
                    } catch (Exception e) {
                        Logger.exception(e, Logging.Level.Error, $"TOML inline table:");
                        failedCount++;
                    }
                }
                bool notExistAndNeed(string name) =>
                newcfg.Adapters.Any(x => x.Name == name) == false
                /* && refs.Any(x => x.IsName && x.Ref as string == name) */;

                if (notExistAndNeed("direct"))
                {
                    newcfg.Adapters.Add(new DirectOutAdapter()
                    {
                        Name = "direct"
                    });
                }
                if (notExistAndNeed("fail"))
                {
                    newcfg.Adapters.Add(new FailAdapter()
                    {
                        Name = "fail"
                    });
                }
                foreach (var r in refs)
                {
                    if (r.IsName)
                    {
                        r.Adapter = FindAdapter <IAdapter>(newcfg, r.Ref as string, -1);
                    }
                }
                newcfg.Adapters.Sort((a, b) => a.Name.CompareTo(b.Name));
                newcfg.FailedCount = failedCount;
                return(newcfg);
            }
예제 #12
0
 private static TomlSettings CreateTomlSettings(List <AdapterRef> refs)
 {
     return(TomlSettings.Create(cfg => cfg
                                .AllowNonstandard(true)
                                .ConfigureType <IPEndPoint>(type => type
                                                            .WithConversionFor <TomlString>(convert => convert
                                                                                            .ToToml(custom => custom.ToString())
                                                                                            .FromToml(tmlString => Utils.CreateIPEndPoint(tmlString.Value))))
                                .ConfigureType <AddrPort>(type => type
                                                          .WithConversionFor <TomlString>(convert => convert
                                                                                          .ToToml(custom => custom.ToString())
                                                                                          .FromToml(tmlString => AddrPort.Parse(tmlString.Value))))
                                .ConfigureType <AdapterRef>(type => type
                                                            .WithConversionFor <TomlString>(convert => convert
                                                                                            .ToToml(custom => custom.Ref.ToString())
                                                                                            .FromToml(tmlString => {
         var a = new AdapterRef {
             IsName = true, Ref = tmlString.Value
         };
         refs.Add(a);
         return a;
     }))
                                                            .WithConversionFor <TomlTable>(convert => convert
                                                                                           .FromToml(tml => {
         var a = new AdapterRef {
             IsTable = true, Ref = tml
         };
         refs.Add(a);
         return a;
     })))
                                .ConfigureType <AdapterRefOrArray>(type => type
                                                                   .WithConversionFor <TomlString>(convert => convert
                                                                                                   .FromToml(tmlString => {
         var str = tmlString.Value;
         if (str.Contains('|'))
         {
             var splits = str.Split('|');
             var aarr = new AdapterRef[splits.Length];
             for (int i = 0; i < splits.Length; i++)
             {
                 var a = new AdapterRef {
                     IsName = true, Ref = splits[i]
                 };
                 refs.Add(a);
                 aarr[i] = a;
             }
             return new AdapterRefOrArray {
                 obj = aarr
             };
         }
         else
         {
             return new AdapterRefOrArray {
                 obj = tmlString.Get <AdapterRef>()
             };
         }
     }))
                                                                   .WithConversionFor <TomlTable>(convert => convert
                                                                                                  .FromToml(tmlTable => {
         var a = new AdapterRefOrArray {
             obj = tmlTable.Get <AdapterRef>()
         };
         return a;
     }))
                                                                   .WithConversionFor <TomlArray>(convert => convert
                                                                                                  .FromToml(tmlTable => {
         var a = new AdapterRefOrArray {
             obj = tmlTable.Get <AdapterRef[]>()
         };
         return a;
     }))
                                                                   .WithConversionFor <TomlTableArray>(convert => convert
                                                                                                       .FromToml(tmlTable => {
         var a = new AdapterRefOrArray {
             obj = tmlTable.Get <AdapterRef[]>()
         };
         return a;
     })))
                                .ConfigureType <StringOrArray>(type => type
                                                               .WithConversionFor <TomlString>(convert => convert
                                                                                               .FromToml(tmlString => {
         return new StringOrArray {
             obj = tmlString.Get <string>()
         };
     }))
                                                               .WithConversionFor <TomlTable>(convert => convert
                                                                                              .FromToml(tmlTable => {
         return new StringOrArray {
             obj = tmlTable.Get <string>()
         };
     }))
                                                               .WithConversionFor <TomlArray>(convert => convert
                                                                                              .FromToml(tmlArray => {
         return new StringOrArray {
             obj = tmlArray.Get <string[]>()
         };
     })))
                                ));
 }
예제 #13
0
파일: InConnection.cs 프로젝트: hex11/Naive
 public void RedirectTo(AdapterRef redirectedName)
 {
     Redirected = redirectedName;
 }