예제 #1
0
        /// <summary>
        /// 网页快照尺寸,Full Screenshot则设置Size.Empty
        /// </summary>
        /// <param name="size"></param>
        internal static void xSnapshot(WebBrowser browser, Size size, string saveFileDirectory, Guid?fileID = null)
        {
            browser.ScrollBarsEnabled = false;
            browser.Size = new Size(Screen.PrimaryScreen.WorkingArea.Width, 10240);
            var arg = (ScriptingContext)browser.ObjectForScripting;

            if (fileID == null)
            {
                fileID = CryptoManaged.MD5Hash(arg.RequestUrl.OriginalString);
            }
            string savePath = Path.Combine(saveFileDirectory, string.Format("{0}.png", fileID));

            try
            {
                var js = new StringBuilder();
                js.AppendFormat("document.body.setAttribute('_CurrentSnapshot', '{0}');", fileID);
                js.Append(@"    window.addEventListener('load', function () {
        window.scrollTo(0, document.documentElement.offsetHeight);
    });
");
                xInvoke(browser, js.ToString());
                browser.Size = size == Size.Empty ? browser.Document.Body.ScrollRectangle.Size : size;
                using (var img = new Bitmap(browser.Width, browser.Height))
                {
                    NativeMethods.DrawTo(browser.ActiveXInstance, img, Color.White);
                    img.Save(savePath, System.Drawing.Imaging.ImageFormat.Png);
                    App.LogInfo("xSnapshot {0} {1}", browser.Url, savePath);
                }
            }
            catch (Exception ex)
            {
                App.LogError(ex, "xSnapshot {0} {1}", browser.Url, savePath);
            }
        }
예제 #2
0
        public static void SetCookieSafety(HttpContext context, DateTime?expires = null)
        {
            var col = context.Items[CookieValueName] as SessionStateItemCollection;

            if (col == null || !col.Dirty)
            {
                return;
            }

            var cookieID = CookieID;

            cookieID.Value = Guid.NewGuid().ToString("N");
            SetCookie(context, cookieID);

            col[CookieIDName] = cookieID.Value;
            var crypto = new CryptoManaged(CryptoKey, cookieID.Value);

            using (var stream = new MemoryStream())
                using (var br = new BinaryWriter(stream, Encoding.UTF8))
                {
                    col.Serialize(br);
                    stream.Position = 0L;
                    SetCookie(context, new HttpCookie(CookieValueName)
                    {
                        HttpOnly = true,
                        Value    = Convert.ToBase64String(crypto.Encrypt(stream).ToArray())
                    }, expires: expires);
                }
        }
예제 #3
0
        private Uri[] GetServerBalance(AgentHubConfig config)
        {
            var serverBalance = new List <Uri>();

            if (config.AsServerNode)
            {
                //创建本地服务节点
                Uri serverUrl;
                xHttpServer.Start(@"C:\Packages\azure", out serverUrl);
                Console.Out.WriteLine("服务端节点{0}开启...", serverUrl);
                serverBalance.Add(serverUrl);
            }
            else
            {
                if (config.EnableSsl)
                {
                    //默认服务端
                    if (!this.CatchExec(() => CryptoManaged.TrustCert(App.GetResourceStream("System.Agent.Resource.XineV2.pfx"), "xineapp"), "导入证书"))
                    {
                        config.EnableSsl = false;
                        Console.Out.WriteWarning("导入证书失败,将不启用加密通讯。");
                    }
                }
                //服务端分配域名
                string domain = Configuration.ConfigurationManager.AppSettings["Agent-Server"] ?? "azure.xineapp.com";
                var    client = new HttpClient(new Uri(string.Format("http://{0}/Let.ashx", domain)));
                var    res    = client.GetResponse();
                var    q      = from t in res.GetResponseText().Split('#')
                                where !string.IsNullOrEmpty(t)
                                select new Uri(string.Format("{0}://{1}/Go.ashx", config.EnableSsl ? Uri.UriSchemeHttps : Uri.UriSchemeHttp, t));
                serverBalance.AddRange(q);
                Console.Out.WriteLine("连接服务器{0}...", q.First());
            }
            return(serverBalance.ToArray());
        }
예제 #4
0
        /// <summary>
        /// 创建HttpTunnel
        /// </summary>
        /// <param name="proxyClient"></param>
        /// <param name="cmd"></param>
        /// <returns></returns>
        /// <exception cref="System.Net.TunnelStateMissingException"></exception>
        private HttpClient CreateTunnel(TunnelCommand cmd, TcpClient proxyClient)
        {
            var tunnel = new HttpClient((Uri)xHttpServer.GetRandom(this.ServerBalance));

            switch (cmd)
            {
            case TunnelCommand.KeepAlive:
                tunnel.KeepAlive = false;
                break;

            default:
                tunnel.KeepAlive = true;
                break;
            }
            tunnel.SendReceiveTimeout = xHttpHandler.Timeout * 1000;
            var cred = this.Credential;

            tunnel.Headers[xHttpHandler.AgentAuth] = CryptoManaged.MD5Hex(string.Format("{0}:{1}", cred.UserName, cred.Password));
            if (proxyClient != null)
            {
                var state = this.GetClientState(proxyClient);
                tunnel.Headers[xHttpHandler.AgentSock]   = state.UniqueID.ToString("N");
                tunnel.Headers[xHttpHandler.AgentDirect] = state.ToString();
            }
            var rRemoteID = this.ReverseRemoteID;

            if (rRemoteID != null)
            {
                tunnel.Headers[xHttpHandler.AgentReverse] = string.Format("{0}#{1}", _clientID.ToString("N"), rRemoteID.Value.ToString("N"));
            }
            tunnel.Form[xHttpHandler.AgentCommand] = ((int)cmd).ToString();
            return(tunnel);
        }
예제 #5
0
        public void ChangePassword(ChangePasswordParameter param)
        {
            using (var context = base.CreateUserContext())
            {
                EmailAuth  emailAuth  = null;
                MobileAuth mobileAuth = null;
                if (param.AuthCode != null)
                {
                    Guid emailAuthCode;
                    if (Guid.TryParse(param.AuthCode, out emailAuthCode))
                    {
                        emailAuth = this.CheckUserEmailAuth(context, emailAuthCode);
                    }
                    else
                    {
                        string[] mobileAuthCode = param.AuthCode.Split(',');
                        if (mobileAuthCode.Length != 2)
                        {
                            throw new InvalidInvokeException("参数错误");
                        }
                        mobileAuth     = this.CheckUserMobileAuth(context, mobileAuthCode[0], int.Parse(mobileAuthCode[1]));
                        param.UserName = mobileAuth.UserName;
                    }
                }

                var id = this.SignIn(new SignInParameter()
                {
                    AppID    = param.AppID,
                    UserName = param.UserName,
                    Password = param.OldPassword
                });
                if (!id.IsAuthenticated)
                {
                    throw new InvalidInvokeException("账户不存在或密码错误");
                }

                using (var scope = DbScope.Create())
                {
                    scope.BeginTransaction();

                    param.NewPassword = CryptoManaged.MD5Hex(param.NewPassword);
                    context.Accounts.Update(t => t.RowID == id.UserID, t => new Account()
                    {
                        Password = param.NewPassword
                    });
                    if (emailAuth != null)
                    {
                        emailAuth.Status = (int)ActivationStatus.Activated;
                    }
                    if (mobileAuth != null)
                    {
                        mobileAuth.Status = (int)ActivationStatus.Activated;
                    }
                    context.SaveChanges();

                    scope.Complete();
                }
            }
        }
예제 #6
0
        public void UdpDirectSend(HttpContext context, UdpClient proxyClient, IPEndPoint remoteIpe)
        {
            context.Server.ScriptTimeout = Timeout;
            HttpRequest  Request  = context.Request;
            HttpResponse Response = context.Response;

            Response.AppendHeader(HttpResponseHeader.Connection.ToString(), "keep-alive");

            var httpFile = Request.Files[AgentDirect];

            if (httpFile == null)
            {
                this.ResponseForbidden(context);
            }
            Stream inStream = httpFile.InputStream;

#if DEBUG
            Guid checksum;
            if (!Guid.TryParse(Request.Form[AgentChecksum], out checksum))
            {
                this.ResponseForbidden(context);
            }
            var mem = new MemoryStream();
            inStream.FixedCopyTo(mem, httpFile.ContentLength);
            mem.Position = 0L;
            Guid checkKey = CryptoManaged.MD5Hash(mem);
            if (checksum != checkKey)
            {
                this.ResponseForbidden(context);
            }
            mem.Position = 0L;
            inStream     = mem;
#endif
            bool succeed = false;
            int  length  = (int)inStream.Length;
            try
            {
                var reader = new BinaryReader(inStream);
                proxyClient.Send(reader.ReadBytes(length), length, remoteIpe);
                succeed = true;
                App.LogInfo("UdpDirectSend to {0} {1}bytes.", remoteIpe, length);
            }
            catch (ObjectDisposedException ex)
            {
#if DEBUG
                App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace));
#endif
            }
            catch (SocketException ex)
            {
                TunnelExceptionHandler.Handle(ex, proxyClient.Client, "UdpDirectSend");
            }
            if (Response.IsClientConnected)
            {
                Response.Write(Convert.ToByte(succeed));
            }
        }
예제 #7
0
        private void DirectSend(HttpContext context, TcpClient proxyClient)
        {
            context.Server.ScriptTimeout = Timeout;
            HttpRequest  Request  = context.Request;
            HttpResponse Response = context.Response;

            //优化性能
            Response.AppendHeader(HttpResponseHeader.Connection.ToString(), "keep-alive");

            var httpFile = Request.Files[AgentDirect];

            if (httpFile == null)
            {
                this.ResponseForbidden(context);
            }
            Stream inStream = httpFile.InputStream;

#if DEBUG
            Guid checksum;
            if (!Guid.TryParse(Request.Form[AgentChecksum], out checksum))
            {
                this.ResponseForbidden(context);
            }
            var mem = new MemoryStream();
            inStream.FixedCopyTo(mem, httpFile.ContentLength);
            mem.Position = 0L;
            Guid checkKey = CryptoManaged.MD5Hash(mem);
            if (checksum != checkKey)
            {
                this.ResponseForbidden(context);
            }
            mem.Position = 0L;
            inStream     = mem;
#endif
            bool succeed = false;
            if (proxyClient.Connected)
            {
                var proxyStream = proxyClient.GetStream();
                int length      = (int)inStream.Length;
                try
                {
                    inStream.FixedCopyTo(proxyStream, length);
                    succeed = true;
#if DEBUG
                    App.LogInfo("DirectSend to {0} {1}bytes.", proxyClient.Client.RemoteEndPoint, length);
#endif
                }
                catch (IOException ex)
                {
                    TunnelExceptionHandler.Handle(ex, proxyClient.Client, "DirectSend");
                }
            }
            if (Response.IsClientConnected)
            {
                Response.Write(Convert.ToByte(succeed));
            }
        }
예제 #8
0
        private void ReverseDirectSend(HttpContext context, ref Guid agentSock)
        {
            context.Server.ScriptTimeout = Timeout;
            HttpRequest  Request  = context.Request;
            HttpResponse Response = context.Response;

            Response.AppendHeader(HttpResponseHeader.Connection.ToString(), "keep-alive");

            var httpFile = Request.Files[AgentDirect];

            if (httpFile == null)
            {
                this.ResponseForbidden(context);
            }
            Stream inStream = httpFile.InputStream;

#if DEBUG
            Guid checksum;
            if (!Guid.TryParse(Request.Form[AgentChecksum], out checksum))
            {
                this.ResponseForbidden(context);
            }
            var mem = new MemoryStream();
            inStream.FixedCopyTo(mem, httpFile.ContentLength);
            mem.Position = 0L;
            Guid checkKey = CryptoManaged.MD5Hash(mem);
            if (checksum != checkKey)
            {
                this.ResponseForbidden(context);
            }
            mem.Position = 0L;
            inStream     = mem;
#endif
            bool succeed   = false;
            var  dataQueue = OnlineUsers.GetReverseQueue(agentSock, true);
            if (dataQueue.Connected)
            {
                int length = (int)inStream.Length;
                if (length > 0)
                {
                    dataQueue.Push(inStream);
                }
                dataQueue.WaitHandle.Set();
                succeed = true;
#if DEBUG
                App.LogInfo("ReverseDirectSend to {0} {1}bytes.", dataQueue.RemoteEndPoint, length);
#endif
            }
            if (Response.IsClientConnected)
            {
                Response.Write(Convert.ToByte(succeed));
            }
        }
예제 #9
0
 public Guid Send(string fileName, byte[] fileData)
 {
     using (var svc = new InfrastructureServiceClient())
     {
         svc.Invoke(t => t.SaveFile(new SaveFileParameter()
         {
             AppID    = this.AppID,
             FileName = fileName,
             FileData = fileData
         }));
     }
     return(CryptoManaged.MD5Hash(new MemoryStream(fileData)));
 }
예제 #10
0
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="param"></param>
        public void SignUp(SignUpParameter param)
        {
            string orgPwd = param.Password;

            param.Password = CryptoManaged.MD5Hex(param.Password);
            using (var scope = DbScope.Create())
                using (var context = base.CreateUserContext())
                {
                    scope.BeginTransaction();

                    if (this.IsUserNameExists(new IsUserNameExistsParameter()
                    {
                        AppID = param.AppID,
                        UserName = param.UserName
                    }))
                    {
                        throw new InvalidInvokeException(SignUpErrorCode.AccountExist.ToDescription());
                    }

                    var dataObj = new Account();
                    EntityMapper.Map <SignUpParameter, Account>(param, dataObj);
                    dataObj.RowID      = Guid.NewGuid();
                    dataObj.CreateDate = DateTime.Now;
                    context.Accounts.Add(dataObj);
                    context.SaveChanges();

                    if (param.SmsCode != default(int))
                    {
                        VerifyMobile(new VerifyMobileParameter()
                        {
                            Mobile  = param.Mobile,
                            SmsCode = param.SmsCode
                        });
                    }

                    scope.Complete();

                    if (!string.IsNullOrEmpty(param.Email))
                    {
                        this.SendAuthEmail(new SendAuthEmailParameter()
                        {
                            AppID  = param.AppID,
                            UserID = dataObj.RowID,
                            Email  = param.Email,
                            Kind   = AuthEmailKind.SignUp
                        });
                    }
                }
        }
예제 #11
0
        static void _transfer_Completed(object sender, TransferEventArgs e)
        {
            var    trans          = (FileTransfer)sender;
            var    header         = JsonConvert.DeserializeObject <JsonHeader>(e.Config.State.ToString());
            string sourceFilePath = string.Format(@"{0}{1}\{2}{3}", InfrastructureRepository.RootPath, trans.DirectoryPath, header.FileKey, Path.GetExtension(e.Config.FileName));

            if (header.FileKey != CryptoManaged.MD5HashFile(sourceFilePath).ToString())
            {
                File.Delete(sourceFilePath);
                return;
            }
            var repository = new InfrastructureRepository();

            repository.SaveFile(header.FileKey, e.Config.FileName, sourceFilePath);
        }
예제 #12
0
        static xHttpHandler()
        {
            ushort.TryParse(ConfigurationManager.AppSettings["Agent-MaxDevice"], out MaxDevice);
            Host = ConfigurationManager.AppSettings["Agent-Host"];
            var q = from t in (ConfigurationManager.AppSettings["Agent-BlockPorts"] ?? string.Empty).Split(',')
                    where !string.IsNullOrEmpty(t)
                    select ushort.Parse(t);

            BlockPorts = q.ToArray();
            CryptoKey  = ConfigurationManager.AppSettings["Agent-CryptoKey"];
            var q2 = from t in (ConfigurationManager.AppSettings["Agent-Credentials"] ?? string.Empty).Split(',')
                     where !string.IsNullOrEmpty(t)
                     select CryptoManaged.MD5Hex(t);

            OnlineUsers = new xUserManager(q2.ToArray());
        }
예제 #13
0
        public override void OnEntry(MethodExecutionArgs args)
        {
            string hashKey = args.Arguments.Count > 0 ? CryptoManaged.MD5Hex(JsonConvert.SerializeObject(args.Arguments, Formatting.None)) : string.Empty;
            string key     = string.Format("{0}.{1}{2}", args.Method.DeclaringType.Name, args.Method.Name, hashKey);
            object result  = Cache[key];

            if (result != null)
            {
                args.FlowBehavior = FlowBehavior.Return;
                args.ReturnValue  = result;
            }
            else
            {
                args.MethodExecutionTag = key;
            }
            base.OnEntry(args);
        }
예제 #14
0
        private static bool TryGetPath(SaveFileParameter param, out Guid checksum, out string path)
        {
            checksum = CryptoManaged.MD5Hash(new MemoryStream(param.FileData));
            path     = string.Format(@"{0}{1}\{2}{3}", InfrastructureRepository.RootPath, param.AppID.ToString("N"), checksum, Path.GetExtension(param.FileName));
            var        file = new FileInfo(path);
            FileStream x    = null;

            try
            {
                return(!(file.Exists && CryptoManaged.MD5Hash(x = file.OpenRead()) == checksum));
            }
            finally
            {
                if (x != null)
                {
                    x.Close();
                }
            }
        }
예제 #15
0
        void IHttpClient.DownloadFile(Uri fileUrl, out string fileName)
        {
            var client = (IHttpClient)this;

            fileName = fileUrl.OriginalString;
            int i = fileName.LastIndexOf("?");

            if (i != -1)
            {
                fileName = fileName.Remove(i);
            }
            fileName = CryptoManaged.MD5Hex(fileUrl.OriginalString) + Path.GetExtension(fileName);
            string localPath    = client.SaveFileDirectory + fileName;
            var    waitDuration = client.RetryWaitDuration;

            try
            {
                if (!App.Retry(() =>
                {
                    this.SetRequest(fileUrl);
                    this.DownloadFile(localPath);
                    var file = new FileInfo(localPath);
                    return(file.Exists && file.Length > 0L);
                }, client.RetryCount.GetValueOrDefault(1), waitDuration.HasValue ? (int)waitDuration.Value.TotalMilliseconds : 0))
                {
                    throw new DownloadException(string.Empty)
                          {
                              RemoteUrl = fileUrl,
                              LocalPath = localPath
                          };
                }
                ;
            }
            catch (Exception ex)
            {
                throw new DownloadException(string.Empty, ex)
                      {
                          RemoteUrl = fileUrl,
                          LocalPath = localPath
                      };
            }
        }
예제 #16
0
        public TransferConfig(string filePath, uint chunkLength = 0)
        {
            Contract.Requires(!string.IsNullOrEmpty(filePath));
            var file = new FileInfo(filePath);

            if (!file.Exists)
            {
                throw new FileNotFoundException(string.Empty, filePath);
            }

            this.FilePath   = file.FullName;
            this.FileLength = file.Length;
            using (var stream = file.OpenRead())
            {
                this.Checksum = CryptoManaged.MD5Hash(stream);
            }
            ushort chunkSize = (ushort)(this.FileLength / Math.Max(MinChunkLength, chunkLength));

            this.ChunkCount = chunkSize;
            this.FileName   = file.Name;
        }
예제 #17
0
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public SSOIdentity SignIn(SignInParameter param)
        {
            if (param.Password.Length < 32)
            {
                param.Password = CryptoManaged.MD5Hex(param.Password);
            }

            using (var context = base.CreateUserContext())
            {
                var q = from t in context.Accounts
                        where t.AppID == param.AppID &&
                        t.UserName == param.UserName && t.Password == param.Password
                        select new SSOIdentity
                {
                    UserID          = t.RowID,
                    UserName        = t.UserName,
                    Token           = Guid.NewGuid().ToString("N"),
                    IssueDate       = DateTime.Now,
                    IsAuthenticated = true
                };
                var result = q.DefaultIfEmpty(new SSOIdentity()
                {
                    UserName        = param.UserName,
                    IsAuthenticated = false
                }).Single();
                if (param.LogSignIn)
                {
                    var log = new SignInLog();
                    log.UserName   = param.UserName;
                    log.ClientIP   = param.ClientIP;
                    log.Platform   = param.Platform;
                    log.SignInDate = DateTime.Now;
                    log.IsSuccess  = result.IsAuthenticated;
                    context.SignInLogs.Add(log);
                    context.SaveChanges();
                }
                return(result);
            }
        }
예제 #18
0
        public static void UploadFile(HttpContext context, string savePath)
        {
            HttpRequest  Request  = context.Request;
            HttpResponse Response = context.Response;

            var httpFile = Request.Files[0];

            if (httpFile == null)
            {
                Response.StatusCode = 400;  //Bad Request
                Response.End();
            }
            string rangeFilename = CryptoManaged.MD5Hex(httpFile.FileName + httpFile.ContentLength);
            var    file          = new FileInfo(Path.Combine(Path.GetDirectoryName(savePath), rangeFilename));

            Response.AddHeader("Content-Length", (file.Exists ? file.Length : 0L).ToString());
            long offset;

            if (!long.TryParse(Request.Headers["Range"], out offset) || file.Length != offset)
            {
                Response.StatusCode = 416;  //Requested range not satisfiable
                Response.End();
            }

            using (var stream = file.Open(file.Exists ? FileMode.Append : FileMode.CreateNew, FileAccess.Write, FileShare.Write))
            {
                int length = httpFile.ContentLength;

                Response.AddHeader("Content-Range", "bytes " + offset.ToString() + "-" + length.ToString() + "/" + length.ToString());
                Response.StatusCode = 206;
                stream.Position     = offset;
                httpFile.InputStream.FixedCopyTo(stream, length, per =>
                {
                    stream.Flush();
                    return(Response.IsClientConnected);
                });
            }
            Response.End();
        }
예제 #19
0
 public object DoEntry(object arg)
 {
     this.CatchExec(() => SecurityPolicy.App2Fw("Agent", App.CombinePath("Agent.exe")), "防火墙例外");
     if (!this.CatchExec(() => CryptoManaged.TrustCert(App.GetResourceStream("System.Agent.Resource.CA.crt")), "导入Http证书"))
     {
         Console.Out.WriteWarning("导入Http证书失败。");
     }
     try
     {
         var config = AgentHubConfig.AppConfig;
         Console.Out.WriteLine("加载配置{0}成功...", AgentHubConfig.AppConfigPath);
         //创建隧道客户端
         foreach (var tunnel in config.TunnelList)
         {
             string remoteMsg = string.Empty;
             Guid?  remoteID  = null;
             string mode      = tunnel.Item2;
             int    i         = mode.LastIndexOf(@"\");
             if (i != -1)
             {
                 string sRemoteID = mode.Substring(i + 1);
                 remoteMsg = string.Format("ReverseTo={0}", sRemoteID);
                 remoteID  = Guid.Parse(sRemoteID);
                 mode      = mode.Substring(0, i);
             }
             try
             {
                 SocksProxyType runType;
                 if (Enum.TryParse(mode, out runType))
                 {
                     var client = CreateTunnelClient(tunnel.Item1, runType, null, remoteID);
                     Console.Out.WriteTip("隧道 {0}:{1} RunMode={2} {3}\t开启...", client.AgentHost, tunnel.Item1, runType, remoteMsg);
                 }
                 else
                 {
                     var directTo = SocketHelper.ParseEndPoint(mode);
                     var client   = CreateTunnelClient(tunnel.Item1, runType, directTo, remoteID);
                     Console.Out.WriteTip("隧道 {0}:{1} DirectTo={2} {3}\t开启...", client.AgentHost, tunnel.Item1, directTo, remoteMsg);
                 }
             }
             catch (Exception ex)
             {
                 App.LogError(ex, "CreateTunnelClient");
                 Console.Out.WriteError("创建隧道失败,{0}...", ex.Message);
             }
         }
     }
     catch (WebException ex)
     {
         Console.Out.WriteError("凭证验证失败:{0}", ex.Message);
     }
     catch (Exception ex)
     {
         Console.Out.WriteError(ex.Message);
         App.LogError(ex, "Agent");
     }
     finally
     {
         ConsoleNotify.Visible = false;
         Console.ReadLine();
     }
     return(null);
 }
예제 #20
0
 internal string HexPassword(string password)
 {
     return(CryptoManaged.MD5Hex(password));
 }
예제 #21
0
        private string CreateNewUserName(string openID, OAuthKind kind)
        {
            string userName = kind.ToString() + "_" + CryptoManaged.MD5Hash(openID);

            return(userName);
        }
예제 #22
0
        public SSOIdentity OAuth(OAuthParameter param)
        {
            int kind = EnumToValue(param.OAuthKind);

            using (var context = base.CreateUserContext())
            {
                var q = from t in context.OpenOAuths
                        where t.OpenID == param.OpenID &&
                        t.OAuthKind == kind
                        select t;
                var  entity = q.SingleOrDefault();
                Guid userID = Guid.Empty;
                // 验证OAuth返回
                if (string.IsNullOrEmpty(param.UserName))
                {
                    if (entity == null)
                    {
                        return(null);
                    }

                    var q2 = from t in context.Accounts
                             join t2 in context.OpenOAuths on t.RowID equals t2.UserID
                             where t2.OpenID == param.OpenID && t2.OAuthKind == kind
                             select new string[] { t.UserName, t.Password };
                    var args = q2.SingleOrDefault();
                    if (args == null)
                    {
                        throw new InvalidInvokeException("用户不存在");
                    }
                    param.UserName = args[0];
                    param.Password = args[1];
                }
                else
                {
                    // 没有帐号,绑定新帐号
                    if (param.UserName == param.OpenID)
                    {
                        param.UserName = CreateNewUserName(param.OpenID, param.OAuthKind);
                        if (!context.Accounts.Any(t => t.AppID == param.AppID && t.UserName == param.UserName))
                        {
                            this.SignUp(new SignUpParameter()
                            {
                                AppID    = param.AppID,
                                UserName = param.UserName,
                                Password = param.Password
                            });
                            Thread.Sleep(200);
                        }
                        goto signIn;
                    }

                    param.Password = CryptoManaged.MD5Hex(param.Password);
                    var q2 = from t in context.Accounts
                             where t.AppID == param.AppID &&
                             t.UserName == param.UserName && t.Password == param.Password
                             select t.RowID;
                    userID = q2.SingleOrDefault();
                    if (userID == Guid.Empty)
                    {
                        throw new InvalidInvokeException("帐号或密码错误");
                    }

                    var q3 = from t in context.OpenOAuths
                             where t.UserID == userID && t.OAuthKind == kind
                             select t;
                    if (q3.Any())
                    {
                        throw new InvalidInvokeException("已经绑定过其它账户");
                    }
                }
signIn:
                var id = this.SignIn(param);
                if (entity == null)
                {
                    if (id.IsAuthenticated)
                    {
                        userID = id.UserID;
                    }
                    if (userID == Guid.Empty)
                    {
                        throw new InvalidInvokeException("UserID's null");
                    }
                    entity = new OpenOAuth();
                    EntityMapper.Map <OAuthParameter, OpenOAuth>(param, entity);
                    entity.UserID     = userID;
                    entity.CreateDate = DateTime.Now;
                    context.OpenOAuths.Add(entity);
                    context.SaveChanges();
                }
                return(id);
            }
        }
예제 #23
0
        private void UdpDirectSend(object state)
        {
            var controlClient = (TcpClient)state;

            if (!controlClient.Connected)
            {
                return;
            }
            string destIpe = null;

            try
            {
                var currentState = this.GetUdpClientState(controlClient);
                while (controlClient.Connected)
                {
                    try
                    {
                        var    localIpe = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
                        byte[] data     = currentState.Client.Receive(ref localIpe);
                        if (!controlClient.Connected)
                        {
                            break;
                        }
                        if (data.IsNullOrEmpty() || !(data[0] == 0 && data[1] == 0 && data[2] == 0))
                        {
                            this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length);
                            App.LogInfo("Udp Send Discard 非法数据包.");
                            continue;
                        }
                        else if (!currentState.LocalEndPoint.Equals(localIpe))
                        {
                            this.OutWrite("Udp Send Discard {0} {1}bytes.", localIpe, data == null ? -1 : data.Length);
                            App.LogInfo("Udp Send Discard 非法本地端点.");
                            continue;
                        }

                        int offset = 4;
                        if (data[3] == 3)
                        {
                            DnsEndPoint de;
                            Socks4Request.PackOut(data, ref offset, out de);
                            currentState.AddRemoteEndPoint(de);
                            destIpe = string.Format("{0}:{1}", de.Host, de.Port);
                        }
                        else
                        {
                            IPEndPoint ipe;
                            Socks4Request.PackOut(data, ref offset, out ipe);
                            currentState.AddRemoteEndPoint(ipe);
                            destIpe = ipe.ToString();
                        }
                        var tunnel = this.CreateTunnel(TunnelCommand.UdpSend, controlClient);
                        tunnel.Headers[xHttpHandler.AgentDirect] = destIpe;
                        var outStream = new MemoryStream(data, offset, data.Length - offset);
#if DEBUG
                        tunnel.Form[xHttpHandler.AgentChecksum] = CryptoManaged.MD5Hash(outStream).ToString();
                        outStream.Position = 0L;
#endif
                        tunnel.Files.Add(new HttpFileContent(xHttpHandler.AgentDirect, xHttpHandler.AgentDirect, outStream));
                        var response = tunnel.GetResponse();
                        if (response.GetResponseText() != "1")
                        {
                            this.OutWrite("Udp {0} Send {1}\t{2}bytes failure.", currentState.LocalEndPoint, destIpe, outStream.Length);
                            return;
                        }
                        this.OutWrite("Udp {0} Send {1}\t{2}bytes.", currentState.LocalEndPoint, destIpe, outStream.Length);

                        //开始接收数据
                        currentState.SetOnce();
                    }
                    catch (ObjectDisposedException ex)
                    {
#if DEBUG
                        App.LogInfo(string.Format("Predictable objectDisposed exception: {0}", ex.StackTrace));
#endif
                    }
                    catch (WebException ex)
                    {
                        bool isRejected;
                        if (TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe), _output, out isRejected))
                        {
                            controlClient.Client.Close();
                        }
                        if (isRejected)
                        {
                            this.OnServerRejected();
                        }
                    }
                    catch (SocketException ex)
                    {
                        if (ex.SocketErrorCode == SocketError.Interrupted)
                        {
#if DEBUG
                            App.LogInfo(string.Format("Predictable interrupted exception: {0}", ex.Message));
#endif
                            return;
                        }
                        TunnelExceptionHandler.Handle(ex, controlClient.Client, string.Format("UdpDirectSend={0}", destIpe));
                    }
                }
            }
            catch (Exception ex)
            {
                TunnelExceptionHandler.Handle(ex, string.Format("UdpDirectSend={0}", destIpe));
            }
        }
예제 #24
0
        private void DirectSend(object state)
        {
            var  args           = (object[])state;
            var  proxyClient    = (TcpClient)args[0];
            Guid?localAgentSock = null;

            if (args.Length == 2)
            {
                localAgentSock = (Guid)args[1];
            }
            if (!proxyClient.Connected)
            {
                return;
            }
            string destIpe = null;

            try
            {
                var localIpe = (IPEndPoint)proxyClient.Client.LocalEndPoint;
                destIpe = this.GetClientState(proxyClient).ToString();
                var proxyStream = proxyClient.GetStream();
                var outStream   = new MemoryStream();
                while (proxyClient.Connected)
                {
                    try
                    {
                        proxyStream.Read(xHttpHandler.EmptyBuffer, 0, 0);
                        int length;
                        //阻塞解除后做第2道检查,先判断连接状态否则proxyClient.Available会引发ObjectDisposedException
                        if (!proxyClient.Connected || (length = proxyClient.Available) == 0)
                        {
                            //客户端主动关闭
                            this.OutWrite("{0} Passive disconnect {1}.", localIpe, destIpe);
                            proxyClient.Close();
                            break;
                        }
                        outStream.Position = 0L;
                        outStream.SetLength(length);
                        proxyStream.FixedCopyTo(outStream, length);
                        outStream.Position = 0L;
                        var tunnel = this.CreateTunnel(TunnelCommand.Send, proxyClient);
                        if (localAgentSock != null)
                        {
                            tunnel.Headers[xHttpHandler.AgentReverse] = localAgentSock.Value.ToString("N");
                        }
#if DEBUG
                        tunnel.Form[xHttpHandler.AgentChecksum] = CryptoManaged.MD5Hash(outStream).ToString();
                        outStream.Position = 0L;
#endif
                        tunnel.Files.Add(new HttpFileContent(xHttpHandler.AgentDirect, xHttpHandler.AgentDirect, outStream));
                        var response = tunnel.GetResponse();
                        if (response.GetResponseText() != "1")
                        {
                            this.OutWrite("{0} Send {1}\t{2}bytes failure.", localIpe, destIpe, length);
                            continue;
                        }
                        this.OutWrite("{0} Send {1}\t{2}bytes.", localIpe, destIpe, length);
                    }
                    catch (WebException ex)
                    {
                        bool isReject;
                        if (TunnelExceptionHandler.Handle(ex, string.Format("DirectSend={0}", destIpe), _output, out isReject))
                        {
                            proxyClient.Client.Close();
                        }
                        if (isReject)
                        {
                            this.OnServerRejected();
                        }
                    }
                    catch (IOException ex)
                    {
                        var sockEx = ex.InnerException as SocketException;
                        if (sockEx != null)
                        {
                            //由于serverPush关闭后,无法将服务端主动关闭信号转发过来,因此proxyStream.Read()会引发Interrupted的异常;
                            //也就是说错误的原因在于调用Close()后,线程恰好继续向网络缓冲区中读取数据,所以引发SocketException。
                            if (sockEx.SocketErrorCode == SocketError.Interrupted)
                            {
#if DEBUG
                                App.LogInfo(string.Format("Predictable interrupted exception: {0}", sockEx.Message));
#endif
                                return;
                            }
                        }
                        TunnelExceptionHandler.Handle(ex, proxyClient.Client, string.Format("DirectSend={0}", destIpe));
                    }
                    catch (SocketException ex)
                    {
                        TunnelExceptionHandler.Handle(ex, proxyClient.Client, string.Format("DirectSend={0}", destIpe));
                    }
                }
            }
            catch (Exception ex)
            {
                TunnelExceptionHandler.Handle(ex, string.Format("DirectSend={0}", destIpe));
            }
        }