예제 #1
0
        private static void SendCallback(IAsyncResult ar)
        {
            var chanel    = (Chanel)ar.AsyncState;
            var bytesSent = chanel.ChanelHandler.EndSend(ar);

            Console.WriteLine("client disconected: " + SocketLogger.ChanelInfo(chanel));

            chanel.ChanelHandler.Shutdown(SocketShutdown.Both);
            chanel.ChanelHandler.Close();
        }
예제 #2
0
파일: Startup.cs 프로젝트: Gtsz/Daylily
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            var webSocketOptions = new WebSocketOptions()
            {
                KeepAliveInterval = TimeSpan.FromSeconds(120),
                ReceiveBufferSize = 4 * 1024
            };

            app.UseWebSockets(webSocketOptions);

            async Task WebSocket(HttpContext context, Func <Task> next)
            {
                if (context.Request.Path == "/ws")
                {
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        SocketLogger.WebSocket = await context.WebSockets.AcceptWebSocketAsync();

                        await SocketLogger.Response();
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                    }
                }
                else
                {
                    await next();
                }
            }

            app.Use(WebSocket);
            Logger.Raw("Websocket控制台已启动。");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseStaticFiles();
            //app.UseHttpsRedirection();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
예제 #3
0
        private static void AcceptCallback(IAsyncResult ar)
        {
            allDone.Set();

            var listener     = (Socket)ar.AsyncState;
            var clientSocket = listener.EndAccept(ar);

            var chanel = new Chanel(clientSocket);

            Console.WriteLine("client connected: " + SocketLogger.ChanelInfo(chanel));

            clientSocket.BeginReceive(chanel.Buffer, 0, Chanel.BufferSize, 0, new AsyncCallback(ReadCallback), chanel);
        }
예제 #4
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="clientSocket">Referance to socket.</param>
        /// <param name="server">Referance to FTP server.</param>
        /// <param name="sessionID">Session ID which is assigned to this session.</param>
        /// <param name="logWriter">Log writer.</param>
        public FTP_Session(Socket clientSocket, FTP_Server server, string sessionID, SocketLogger logWriter)
        {
            m_pSocket   = new BufferedSocket(clientSocket);
            m_pServer   = server;
            m_SessionID = sessionID;
            //		m_pLogWriter       = logWriter;
            m_SessionStartTime = DateTime.Now;
            m_LastDataTime     = DateTime.Now;

            m_pSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
            m_pSocket.Activity += new EventHandler(OnSocketActivity);

            // Start session proccessing
            StartSession();
        }
예제 #5
0
        /// <summary>
        /// Closes connection to Pop33 server.
        /// </summary>
        public void Disconnect()
        {
            if (socketStream != null)
            {
                // Send QUIT
                socketStream.Write(Encoding.ASCII.GetBytes("QUIT"), 0, 4);
                socketStream.Close();
            }


            if (m_pLogger != null)
            {
                m_pLogger.Flush();
            }
            m_pLogger = null;

            m_pSocket       = null;
            m_Connected     = false;
            m_Authenticated = false;
        }
예제 #6
0
        /*		/// <summary>
		/// Starts disconnecting SMTP client.
		/// </summary>
		public void BeginDisconnect()
		{
			if(!m_Connected){
				throw new Exception("You must connect first");
			}
		}*/

        /// <summary>
        /// Disconnects smtp client from server.
        /// </summary>
        public void Disconnect()
        {
            try
            {
                if (m_pSocket != null && m_pSocket.Connected)
                {
                    m_pSocket.WriteLine("QUIT");

                    m_pSocket.Shutdown(SocketShutdown.Both);
                }
            }
            catch {}

            m_pSocket = null;
            m_Connected = false;
            m_Supports_Size = false;
            m_Supports_Bdat = false;
            m_Supports_Login = false;
            m_Supports_CramMd5 = false;

            if (m_pLogger != null)
            {
                m_pLogger.Flush();
                m_pLogger = null;
            }
        }
예제 #7
0
        /// <summary>
        /// Connects to sepcified host.
        /// </summary>
        /// <param name="localEndpoint">Sets local endpoint. Pass null, to use default.</param>
        /// <param name="host">Host name or IP address.</param>
        /// <param name="port">Port where to connect.</param>
        /// <param name="ssl">Specifies if to connected via SSL. Default SMTP port is 25 and SSL port is 465.</param>
        public void Connect(IPEndPoint localEndpoint, string host, int port, bool ssl)
        {
            m_pSocket = new SocketEx();
            if (localEndpoint != null)
            {
                m_pSocket.Bind(localEndpoint);
            }

            // Create logger
            if (SessionLog != null)
            {
                m_pLogger = new SocketLogger(m_pSocket.RawSocket, SessionLog);
                m_pLogger.SessionID = Guid.NewGuid().ToString();
                m_pSocket.Logger = m_pLogger;
            }

            if (host.IndexOf("@") == -1)
            {
                m_pSocket.Connect(host, port, ssl);
            }
            else
            {
                //---- Parse e-domain -------------------------------//
                string domain = host;

                // eg. Ivx <*****@*****.**>
                if (domain.IndexOf("<") > -1 && domain.IndexOf(">") > -1)
                {
                    domain = domain.Substring(domain.IndexOf("<") + 1,
                                              domain.IndexOf(">") - domain.IndexOf("<") - 1);
                }

                if (domain.IndexOf("@") > -1)
                {
                    domain = domain.Substring(domain.LastIndexOf("@") + 1);
                }

                if (domain.Trim().Length == 0)
                {
                    if (m_pLogger != null)
                    {
                        m_pLogger.AddTextEntry("Destination address '" + host + "' is invalid, aborting !");
                    }
                    throw new Exception("Destination address '" + host + "' is invalid, aborting !");
                }

                //--- Get MX record -------------------------------------------//
                Dns_Client dns = new Dns_Client();
                Dns_Client.DnsServers = m_pDnsServers;
                DnsServerResponse dnsResponse = dns.Query(domain, QTYPE.MX);

                bool connected = false;
                switch (dnsResponse.ResponseCode)
                {
                    case RCODE.NO_ERROR:
                        DNS_rr_MX[] mxRecords = dnsResponse.GetMXRecords();

                        // Try all available hosts by MX preference order, if can't connect specified host.
                        foreach (DNS_rr_MX mx in mxRecords)
                        {
                            try
                            {
                                if (m_pLogger != null)
                                {
                                    m_pLogger.AddTextEntry("Connecting with mx record to: " + mx.Host);
                                }
                                m_pSocket.Connect(mx.Host, port, ssl);
                                connected = true;
                                break;
                            }
                            catch (Exception x)
                            {
                                // Just skip and let for to try next host.									
                                if (m_pLogger != null)
                                {
                                    m_pLogger.AddTextEntry("Failed connect to: " + mx.Host + " error:" +
                                                           x.Message);
                                }
                            }
                        }

                        // None of MX didn't connect
                        if (mxRecords.Length > 0 && !connected)
                        {
                            throw new Exception("Destination email server is down");
                        }

                        /* Rfc 2821 5
						 If no MX records are found, but an A RR is found, the A RR is treated as
						 if it was associated with an implicit MX RR, with a preference of 0,
						 pointing to that host.
						*/
                        if (!connected)
                        {
                            // Try to connect with A record
                            IPAddress[] ipEntry = null;
                            try
                            {
                                if (m_pLogger != null)
                                {
                                    m_pLogger.AddTextEntry("No mx record, trying to get A record for: " +
                                                           domain);
                                }
                                ipEntry = Dns_Client.Resolve(domain);
                            }
                            catch
                            {
                                if (m_pLogger != null)
                                {
                                    m_pLogger.AddTextEntry("Invalid domain,no MX or A record: " + domain);
                                }
                                throw new Exception("Invalid domain,no MX or A record: " + domain);
                            }

                            try
                            {
                                if (m_pLogger != null)
                                {
                                    m_pLogger.AddTextEntry("Connecting with A record to:" + domain);
                                }
                                m_pSocket.Connect(domain, port, ssl);
                            }
                            catch
                            {
                                if (m_pLogger != null)
                                {
                                    m_pLogger.AddTextEntry("Failed connect to:" + domain);
                                }
                                throw new Exception("Destination email server is down");
                            }
                        }
                        break;

                    case RCODE.NAME_ERROR:
                        if (m_pLogger != null)
                        {
                            m_pLogger.AddTextEntry("Invalid domain,no MX or A record: " + domain);
                        }
                        throw new Exception("Invalid domain,no MX or A record: " + domain);

                    case RCODE.SERVER_FAILURE:
                        if (m_pLogger != null)
                        {
                            m_pLogger.AddTextEntry("Dns server unvailable.");
                        }
                        throw new Exception("Dns server unvailable.");
                }
            }

            /*
			 * Notes: Greeting may be single or multiline response.
			 *		
			 * Examples:
			 *		220<SP>SMTP server ready<CRLF> 
			 * 
			 *		220-SMTP server ready<CRLF>
			 *		220-Addtitional text<CRLF>
			 *		220<SP>final row<CRLF>
			 * 
			*/

            // Read server response
            string responseLine = m_pSocket.ReadLine(1000);
            while (!responseLine.StartsWith("220 "))
            {
                // If lisne won't start with 220, then its error response
                if (!responseLine.StartsWith("220"))
                {
                    throw new Exception(responseLine);
                }

                responseLine = m_pSocket.ReadLine(1000);
            }

            m_Connected = true;
        }
예제 #8
0
        //---- SMTP implementation ----//

        #region function SendMessageToServer

        private bool SendMessageToServer(string[] to, string reverse_path, Stream message)
        {
            // Get email from to string
            for (int i = 0; i < to.Length; i++)
            {
                to[i] = (new LumiSoft.Net.Mime.Parser.eAddress(to[i])).Email;
            }

            ArrayList defectiveEmails = new ArrayList();

            Socket         so     = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            BufferedSocket socket = new BufferedSocket(so);

            SocketLogger logger = null;

            if (m_LogCmds && this.SessionLog != null)
            {
                logger           = new SocketLogger(so, this.SessionLog);
                logger.SessionID = socket.GetHashCode().ToString();
                socket.Logger    = logger;
            }

            try{
                string reply         = "";
                bool   supports_SIZE = false;
                bool   supports_8BIT = false;
                bool   supports_BDAT = false;
                #region connect to server
                if (m_UseSmartHost)
                {
                    socket.Connect(new IPEndPoint(System.Net.Dns.Resolve(m_SmartHost).AddressList[0], m_Port));
                }
                else
                {
                    //---- Parse e-domain -------------------------------//
                    string domain = to[0];

                    // eg. Ivx <*****@*****.**>
                    if (domain.IndexOf("<") > -1 && domain.IndexOf(">") > -1)
                    {
                        domain = domain.Substring(domain.IndexOf("<") + 1, domain.IndexOf(">") - domain.IndexOf("<") - 1);
                    }

                    if (domain.IndexOf("@") > -1)
                    {
                        domain = domain.Substring(domain.LastIndexOf("@") + 1);
                    }

                    if (domain.Trim().Length == 0)
                    {
                        if (logger != null)
                        {
                            logger.AddTextEntry("Destination address '" + to[0] + "' is invalid, aborting !");
                        }
                        return(false);
                    }

                    //System.Net.Dns.
                    //--- Get MX record -------------------------------------------//
                    DnsEx dns = new DnsEx();
                    DnsEx.DnsServers = m_DnsServers;
                    DnsServerResponse dnsResponse = dns.Query(domain, QTYPE.MX);

                    switch (dnsResponse.ResponseCode)
                    {
                    case RCODE.NO_ERROR:
                        MX_Record[] mxRecords = dnsResponse.GetMXRecords();

                        // Try all available hosts by MX preference order, if can't connect specified host.
                        foreach (MX_Record mx in mxRecords)
                        {
                            try{
                                if (logger != null)
                                {
                                    logger.AddTextEntry("Connecting with mx record to: " + mx.Host);
                                }
                                socket.Connect(new IPEndPoint(System.Net.Dns.Resolve(mx.Host).AddressList[0], m_Port));
                                break;
                            }
                            catch {                                    // Just skip and let for to try next host.
                                if (logger != null)
                                {
                                    logger.AddTextEntry("Failed connect to: " + mx.Host);
                                }
                            }
                        }

                        /* Rfc 2821 5
                         * If no MX records are found, but an A RR is found, the A RR is treated as
                         * if it was associated with an implicit MX RR, with a preference of 0,
                         * pointing to that host.
                         *
                         */
                        if (mxRecords.Length == 0)
                        {
                            // Try to connect with A record
                            IPHostEntry ipEntry = null;
                            try{
                                if (logger != null)
                                {
                                    logger.AddTextEntry("No mx record, trying to get A record for: " + domain);
                                }
                                ipEntry = System.Net.Dns.Resolve(domain);
                            }
                            catch {
                                if (logger != null)
                                {
                                    logger.AddTextEntry("Invalid domain,no MX or A record: " + domain);
                                }
                                OnError(SMTP_ErrorType.InvalidEmailAddress, to, "email domain <" + domain + "> is invalid");

                                defectiveEmails.AddRange(to);

                                if (logger != null)
                                {
                                    logger.Flush();
                                }
                                return(false);
                            }

                            try{
                                if (logger != null)
                                {
                                    logger.AddTextEntry("Connecting with A record to:" + domain);
                                }
                                socket.Connect(new IPEndPoint(ipEntry.AddressList[0], m_Port));
                            }
                            catch {
                                if (logger != null)
                                {
                                    logger.AddTextEntry("Failed connect to:" + domain);
                                }
                            }
                        }
                        break;

                    case RCODE.NAME_ERROR:
                        if (logger != null)
                        {
                            logger.AddTextEntry("Invalid domain,no MX or A record: " + domain);
                        }
                        OnError(SMTP_ErrorType.InvalidEmailAddress, to, "email domain <" + domain + "> is invalid");

                        defectiveEmails.AddRange(to);

                        if (logger != null)
                        {
                            logger.Flush();
                        }
                        return(false);

                    case RCODE.SERVER_FAILURE:
                        if (logger != null)
                        {
                            logger.AddTextEntry("Dns server unvailable.");
                        }
                        OnError(SMTP_ErrorType.UnKnown, to, "Dns server unvailable.");

                        defectiveEmails.AddRange(to);

                        if (logger != null)
                        {
                            logger.Flush();
                        }
                        return(false);
                    }
                }

                if (!socket.Connected)
                {
                    OnError(SMTP_ErrorType.UnKnown, to, "Unable connect to server !");

                    if (logger != null)
                    {
                        logger.Flush();
                    }
                    return(false);
                }

                #endregion
                #region Get 220 reply from server

                /* NOTE: reply may be multiline
                 * 220 xx ready
                 *  or
                 * 220-someBull
                 * 200 xx
                 */

                // Server must reply 220 - Server OK
                reply = socket.ReadLine();
                if (!IsReplyCode("220", reply))
                {
                    OnError(SMTP_ErrorType.UnKnown, to, reply);
                    socket.SendLine("QUIT");

                    if (logger != null)
                    {
                        logger.Flush();
                    }
                    return(false);
                }
                else
                {
                    // 220-xxx<CRLF>
                    // 220 aa<CRLF> - means end
                    // reply isn't complete, get more
                    while (reply.IndexOf("220 ") == -1)
                    {
                        reply += socket.ReadLine();
                    }
                }

                #endregion


                #region cmd EHLO/HELO

                // Send greeting to server
                socket.SendLine("EHLO " + m_HostName);

                reply = socket.ReadLine();
                if (!IsReplyCode("250", reply))
                {
                    // EHLO failed, mayby server doesn't support it, try HELO
                    socket.SendLine("HELO " + m_HostName);
                    reply = socket.ReadLine();
                    if (!IsReplyCode("250", reply))
                    {
                        OnError(SMTP_ErrorType.UnKnown, to, reply);
                        socket.SendLine("QUIT");

                        defectiveEmails.AddRange(to);

                        if (logger != null)
                        {
                            logger.Flush();
                        }
                        return(false);
                    }
                    //	else{
                    //		supports_ESMTP = false;
                    //	}
                }
                else
                {
                    // 250-xxx<CRLF>
                    // 250 aa<CRLF> - means end
                    // reply isn't complete, get more
                    while (reply.IndexOf("250 ") == -1)
                    {
                        reply += socket.ReadLine();
                    }

                    // Check if SIZE argument is supported
                    if (reply.ToUpper().IndexOf("SIZE") > -1)
                    {
                        supports_SIZE = true;
                    }

                    // Check if 8BITMIME argument is supported
                    if (reply.ToUpper().IndexOf("8BITMIME") > -1)
                    {
                        supports_8BIT = true;
                    }

                    // Check if CHUNKING argument is supported
                    if (reply.ToUpper().IndexOf("CHUNKING") > -1)
                    {
                        supports_BDAT = true;
                    }
                }

                #endregion

                // If server doesn't support 8bit mime, check if message is 8bit.
                // If is we MAY NOT send this message or loss of data

                /*		if(!supports_8BIT){
                 *                      if(Is8BitMime(message)){
                 *                              OnError(SMTP_ErrorType.NotSupported,to,"Message is 8-Bit mime and server doesn't support it.");
                 *                              socket.SendLine("QUIT");
                 *
                 *                              if(logger != null){
                 *                                      logger.Flush();
                 *                              }
                 *                              return false;
                 *                      }
                 *              }*/


                #region cmd AUTH

                if (this.m_Username != null && m_Username.Length > 0 && m_Password != null && m_Password.Length > 0)
                {
                    if (reply.ToUpper().IndexOf("AUTH") > -1)
                    {
                        if (reply.ToUpper().IndexOf("LOGIN") > -1)
                        {
                            socket.SendLine("AUTH LOGIN");
                            reply = socket.ReadLine();
                            if (!IsReplyCode("334", reply))
                            {
                                OnError(SMTP_ErrorType.NotAuthenticated, to, "Failed to authenticate");
                                socket.SendLine("QUIT");

                                if (logger != null)
                                {
                                    logger.Flush();
                                }
                                return(false);
                            }

                            socket.SendLine(Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(m_Username.ToCharArray())));
                            reply = socket.ReadLine();
                            if (!IsReplyCode("334", reply))
                            {
                                OnError(SMTP_ErrorType.NotAuthenticated, to, "Failed to authenticate");
                                socket.SendLine("QUIT");

                                if (logger != null)
                                {
                                    logger.Flush();
                                }
                                return(false);
                            }

                            socket.SendLine(Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(m_Password.ToCharArray())));
                            reply = socket.ReadLine();
                            if (!IsReplyCode("235", reply))
                            {
                                OnError(SMTP_ErrorType.NotAuthenticated, to, "Failed to authenticate");
                                socket.SendLine("QUIT");

                                if (logger != null)
                                {
                                    logger.Flush();
                                }
                                return(false);
                            }
                        }
//						if(reply.ToUpper().IndexOf("CRAM-MD5") > -1)
//						{
//							socket.SendLine("AUTH CRAM-MD5");
//							reply = socket.ReadLine();
//							if (IsReplyCode("334",auth))
//							{
//								socket.SendLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(m_Username.ToCharArray())));
//								socket.SendLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(m_Password.ToCharArray())));
//							}
//						}
                    }
                    else
                    {
                        //server did not support AUTH
                    }
                }

                #endregion

                #region cmd MAIL
                // NOTE: Syntax:{MAIL FROM:<*****@*****.**> [SIZE=msgSize]<CRLF>}

                // Send Mail From
                if (supports_SIZE)
                {
                    socket.SendLine("MAIL FROM:<" + reverse_path + "> SIZE=" + (message.Length - message.Position));
                }
                else
                {
                    socket.SendLine("MAIL FROM:<" + reverse_path + ">");
                }

                reply = socket.ReadLine();
                if (!IsReplyCode("250", reply))
                {
                    // To Do: Check if size exceeded error:

                    OnError(SMTP_ErrorType.UnKnown, to, reply);
                    socket.SendLine("QUIT");

                    defectiveEmails.AddRange(to);

                    if (logger != null)
                    {
                        logger.Flush();
                    }
                    return(false);
                }

                #endregion

                #region cmd RCPT
                // NOTE: Syntax:{RCPT TO:<*****@*****.**><CRLF>}

                bool isAnyValidEmail = false;
                foreach (string rcpt in to)
                {
                    // Send Mail To
                    socket.SendLine("RCPT TO:<" + rcpt + ">");

                    reply = socket.ReadLine();
                    if (!IsReplyCode("250", reply))
                    {
                        // Is unknown user
                        if (IsReplyCode("550", reply))
                        {
                            OnError(SMTP_ErrorType.InvalidEmailAddress, new string[] { rcpt }, reply);
                        }
                        else
                        {
                            OnError(SMTP_ErrorType.UnKnown, new string[] { rcpt }, reply);
                        }

                        defectiveEmails.Add(rcpt);
                    }
                    else
                    {
                        isAnyValidEmail = true;
                    }
                }

                // If there isn't any valid email - quit.
                if (!isAnyValidEmail)
                {
                    socket.SendLine("QUIT");

                    if (logger != null)
                    {
                        logger.Flush();
                    }
                    return(false);
                }
                //---------------------------------------------//

                #endregion


                #region cmd DATA

                if (!supports_BDAT)
                {
                    // Notify Data Start
                    socket.SendLine("DATA");

                    reply = socket.ReadLine();
                    if (!IsReplyCode("354", reply))
                    {
                        OnError(SMTP_ErrorType.UnKnown, to, reply);
                        socket.SendLine("QUIT");

                        defectiveEmails.AddRange(to);

                        if (logger != null)
                        {
                            logger.Flush();
                        }
                        return(false);
                    }

                    //------- Do period handling -----------------------------------------//
                    // If line starts with '.', add additional '.'.(Read rfc for more info)
                    MemoryStream msgStrmPeriodOk = Core.DoPeriodHandling(message, true, false);
                    //--------------------------------------------------------------------//

                    // Check if message ends with <CRLF>, if not add it. -------//
                    if (msgStrmPeriodOk.Length >= 2)
                    {
                        byte[] byteEnd = new byte[2];
                        msgStrmPeriodOk.Position = msgStrmPeriodOk.Length - 2;
                        msgStrmPeriodOk.Read(byteEnd, 0, 2);

                        if (byteEnd[0] != (byte)'\r' && byteEnd[1] != (byte)'\n')
                        {
                            msgStrmPeriodOk.Write(new byte[] { (byte)'\r', (byte)'\n' }, 0, 2);
                        }
                    }
                    msgStrmPeriodOk.Position = 0;
                    //-----------------------------------------------------------//

                    //---- Send message --------------------------------------------//
                    long totalSent   = 0;
                    long totalLength = msgStrmPeriodOk.Length;
                    while (totalSent < totalLength)
                    {
                        byte[] dataBuf     = new byte[4000];
                        int    nCount      = msgStrmPeriodOk.Read(dataBuf, 0, dataBuf.Length);
                        int    countSended = socket.Send(dataBuf, 0, nCount, SocketFlags.None);
                        totalSent += countSended;

                        if (countSended != nCount)
                        {
                            msgStrmPeriodOk.Position = totalSent;
                        }

                        OnPartOfMessageIsSent(countSended, totalSent, totalLength);
                    }
                    //-------------------------------------------------------------//
                    msgStrmPeriodOk.Close();

                    // Notify End of Data
                    socket.SendLine(".");

                    reply = socket.ReadLine();
                    if (!IsReplyCode("250", reply))
                    {
                        OnError(SMTP_ErrorType.UnKnown, to, reply);
                        socket.SendLine("QUIT");

                        defectiveEmails.AddRange(to);

                        if (logger != null)
                        {
                            logger.Flush();
                        }
                        return(false);
                    }
                }

                #endregion

                #region cmd BDAT

                if (supports_BDAT)
                {
                    socket.SendLine("BDAT " + (message.Length - message.Position) + " LAST");

                    //---- Send message --------------------------------------------//
                    long totalSent   = 0;
                    long totalLength = message.Length - message.Position;
                    while (totalSent < totalLength)
                    {
                        byte[] dataBuf     = new byte[4000];
                        int    nCount      = message.Read(dataBuf, 0, dataBuf.Length);
                        int    countSended = socket.Send(dataBuf, 0, nCount, SocketFlags.None);
                        totalSent += countSended;

                        if (countSended != nCount)
                        {
                            message.Position = totalSent;
                        }

                        OnPartOfMessageIsSent(countSended, totalSent, totalLength);
                    }
                    //-------------------------------------------------------------//

                    // Get store result
                    reply = socket.ReadLine();
                    if (!reply.StartsWith("250"))
                    {
                        OnError(SMTP_ErrorType.UnKnown, to, reply);
                        socket.SendLine("QUIT");

                        defectiveEmails.AddRange(to);

                        if (logger != null)
                        {
                            logger.Flush();
                        }
                        return(false);
                    }
                }

                #endregion

                #region cmd QUIT

                // Notify server - server can exit now
                socket.SendLine("QUIT");

                //	reply = socket.ReadLine();

                #endregion
            }
            catch (Exception x) {
                OnError(SMTP_ErrorType.UnKnown, to, x.Message);

                defectiveEmails.AddRange(to);

                if (logger != null)
                {
                    logger.Flush();
                }
                return(false);
            }
            //finally{
            // Raise event
            //OnSendJobCompleted(Thread.CurrentThread.GetHashCode().ToString(),to,defectiveEmails);
            OnSendJobCompleted(Thread.CurrentThread.Name, to, defectiveEmails);
            //}

            if (logger != null)
            {
                logger.Flush();
            }

            return(true);
        }
예제 #9
0
		//---- SMTP implementation ----//

		#region function SendMessageToServer

		private bool SendMessageToServer(string[] to,string reverse_path,Stream message)
		{
			// Get email from to string
			for(int i=0;i<to.Length;i++){
				to[i] = (new InfoControl.Net.Mail.Mime.eAddress(to[i])).Email;
			}

			ArrayList defectiveEmails = new ArrayList();

			Socket so = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
			so.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.SendTimeout,15000);
			BufferedSocket socket = new BufferedSocket(so);

			SocketLogger logger = null;
			if(m_LogCmds && this.SessionLog != null){
				logger = new SocketLogger(so,this.SessionLog);
				logger.SessionID = socket.GetHashCode().ToString();
				socket.Logger = logger;
			}

			try{
				string reply = "";	
				bool supports_SIZE  = false;
				bool supports_8BIT  = false;
				bool supports_BDAT  = false;
										
				if(m_UseSmartHost){
					socket.Connect(new IPEndPoint(System.Net.Dns.Resolve(m_SmartHost).AddressList[0],m_Port));					
				}
				else{
					//---- Parse e-domain -------------------------------//
					string domain = to[0];

					// eg. Ivx <*****@*****.**>
					if(domain.IndexOf("<") > -1 && domain.IndexOf(">") > -1){
						domain = domain.Substring(domain.IndexOf("<")+1,domain.IndexOf(">") - domain.IndexOf("<")-1);
					}

					if(domain.IndexOf("@") > -1){
						domain = domain.Substring(domain.LastIndexOf("@") + 1);
					}

					if(domain.Trim().Length == 0){
						if(logger != null){
							logger.AddTextEntry("Destination address '" + to[0] + "' is invalid, aborting !");
						}
						return false;
					}

					//--- Get MX record -------------------------------------------//
					Dns_Client dns = new Dns_Client();
					Dns_Client.DnsServers = m_DnsServers;
					DnsServerResponse dnsResponse = dns.Query(domain,QTYPE.MX);

					switch(dnsResponse.ResponseCode)
					{
						case RCODE.NO_ERROR:
							MX_Record[] mxRecords = dnsResponse.GetMXRecords();

							// Try all available hosts by MX preference order, if can't connect specified host.
							foreach(MX_Record mx in mxRecords){
								try{
									if(logger != null){
										logger.AddTextEntry("Connecting with mx record to: " + mx.Host);
									}
									socket.Connect(new IPEndPoint(System.Net.Dns.Resolve(mx.Host).AddressList[0],m_Port));
									break;
								}
								catch{ // Just skip and let for to try next host.									
									if(logger != null){
										logger.AddTextEntry("Failed connect to: " + mx.Host);
									}
								}
							}

							/* Rfc 2821 5
							 If no MX records are found, but an A RR is found, the A RR is treated as
							 if it was associated with an implicit MX RR, with a preference of 0,
							 pointing to that host.

							*/
							if(mxRecords.Length == 0){
								// Try to connect with A record
								IPHostEntry ipEntry = null;
								try{
									if(logger != null){
										logger.AddTextEntry("No mx record, trying to get A record for: " + domain);
									}
									ipEntry = System.Net.Dns.Resolve(domain);								
								}
								catch{
									if(logger != null){
										logger.AddTextEntry("Invalid domain,no MX or A record: " + domain);
									}
									OnError(SMTP_ErrorType.InvalidEmailAddress,to,"email domain <" + domain + "> is invalid");
								
									defectiveEmails.AddRange(to);

									if(logger != null){
										logger.Flush();
									}
									return false;
								}

								try{
									if(logger != null){
										logger.AddTextEntry("Connecting with A record to:" + domain);
									}
									socket.Connect(new IPEndPoint(ipEntry.AddressList[0],m_Port));
								}
								catch{
									if(logger != null){
										logger.AddTextEntry("Failed connect to:" + domain);
									}
								}
							}
							break;

						case RCODE.NAME_ERROR:
							if(logger != null){
								logger.AddTextEntry("Invalid domain,no MX or A record: " + domain);
							}
							OnError(SMTP_ErrorType.InvalidEmailAddress,to,"email domain <" + domain + "> is invalid");
								
							defectiveEmails.AddRange(to);

							if(logger != null){
								logger.Flush();
							}
							return false;

						case RCODE.SERVER_FAILURE:
							if(logger != null){
								logger.AddTextEntry("Dns server unvailable.");
							}
							OnError(SMTP_ErrorType.UnKnown,to,"Dns server unvailable.");
								
							defectiveEmails.AddRange(to);

							if(logger != null){
								logger.Flush();
							}
							return false;
					}					
				}

				if(!socket.Connected){
					OnError(SMTP_ErrorType.UnKnown,to,"Unable connect to server !");

					if(logger != null){
						logger.Flush();
					}
					return false;
				}
										

				#region Get 220 reply from server 
				/* NOTE: reply may be multiline
				   220 xx ready
				    or
				   220-someBull
				   200 xx
				*/ 

				// Server must reply 220 - Server OK
				reply = socket.ReadLine();				
				if(!IsReplyCode("220",reply)){
					OnError(SMTP_ErrorType.UnKnown,to,reply);
					socket.SendLine("QUIT");

					if(logger != null){
						logger.Flush();
					}
					return false;
				}
				else{
					// 220-xxx<CRLF>
					// 220 aa<CRLF> - means end
					// reply isn't complete, get more
					while(reply.IndexOf("220 ") == -1){
						reply += socket.ReadLine();
					}
				}

				#endregion


				#region cmd EHLO/HELO
	
				// Send greeting to server
				socket.SendLine("EHLO " + m_HostName);

				reply = socket.ReadLine();
				if(!IsReplyCode("250",reply)){
					// EHLO failed, mayby server doesn't support it, try HELO
					socket.SendLine("HELO " + m_HostName);
					reply = socket.ReadLine();
					if(!IsReplyCode("250",reply)){
						OnError(SMTP_ErrorType.UnKnown,to,reply);
						socket.SendLine("QUIT");

						defectiveEmails.AddRange(to);

						if(logger != null){
							logger.Flush();
						}
						return false;
					}
				//	else{
				//		supports_ESMTP = false;
				//	}
				}
				else{
					// 250-xxx<CRLF>
					// 250 aa<CRLF> - means end
					// reply isn't complete, get more
					while(reply.IndexOf("250 ") == -1){
						reply += socket.ReadLine();
					}

					// Check if SIZE argument is supported
					if(reply.ToUpper().IndexOf("SIZE") > -1){
						supports_SIZE = true;
					}

					// Check if 8BITMIME argument is supported
					if(reply.ToUpper().IndexOf("8BITMIME") > -1){
						supports_8BIT = true;
					}
					
					// Check if CHUNKING argument is supported
					if(reply.ToUpper().IndexOf("CHUNKING") > -1){
						supports_BDAT = true;
					}
				}
				
				#endregion
	
                //*** All server today support 8-bit, just skip it.

				// If server doesn't support 8bit mime, check if message is 8bit.
				// If is we MAY NOT send this message or loss of data
		/*		if(!supports_8BIT){
					if(Is8BitMime(message)){
						OnError(SMTP_ErrorType.NotSupported,to,"Message is 8-Bit mime and server doesn't support it.");
						socket.SendLine("QUIT");

						if(logger != null){
							logger.Flush();
						}
						return false;	
					}
				}*/


				#region cmd AUTH
	
				if (this.m_Username != null && m_Username.Length > 0 && m_Password != null && m_Password.Length > 0){
					if(reply.ToUpper().IndexOf("AUTH") > -1){
						if(reply.ToUpper().IndexOf("LOGIN") > -1){
							socket.SendLine("AUTH LOGIN");
							reply = socket.ReadLine();
							if(!IsReplyCode("334",reply)){
								OnError(SMTP_ErrorType.NotAuthenticated,to,"Failed to authenticate");
								socket.SendLine("QUIT");

								if(logger != null){
									logger.Flush();
								}
								return false;
							}

							socket.SendLine(Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(m_Username.ToCharArray())));
							reply = socket.ReadLine();
							if(!IsReplyCode("334",reply)){
								OnError(SMTP_ErrorType.NotAuthenticated,to,"Failed to authenticate");
								socket.SendLine("QUIT");

								if(logger != null){
									logger.Flush();
								}
								return false;
							}

							socket.SendLine(Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(m_Password.ToCharArray())));
							reply = socket.ReadLine();
							if(!IsReplyCode("235",reply)){
								OnError(SMTP_ErrorType.NotAuthenticated,to,"Failed to authenticate");
								socket.SendLine("QUIT");

								if(logger != null){
									logger.Flush();
								}
								return false;
							}
						}
//						if(reply.ToUpper().IndexOf("CRAM-MD5") > -1)
//						{
//							socket.SendLine("AUTH CRAM-MD5");
//							reply = socket.ReadLine();
//							if (IsReplyCode("334",auth))
//							{
//								socket.SendLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(m_Username.ToCharArray())));
//								socket.SendLine(Convert.ToBase64String(Encoding.ASCII.GetBytes(m_Password.ToCharArray())));
//							}
//						}
					}
					else{
						//server did not support AUTH
					}
				}

				#endregion

				#region cmd MAIL
				// NOTE: Syntax:{MAIL FROM:<*****@*****.**> [SIZE=msgSize]<CRLF>}
								
				// Send Mail From
				if(supports_SIZE){
					socket.SendLine("MAIL FROM:<" + reverse_path + "> SIZE=" + (message.Length - message.Position));
				}
				else{
					socket.SendLine("MAIL FROM:<" + reverse_path + ">");
				}

				reply = socket.ReadLine();
				if(!IsReplyCode("250",reply)){
					// To Do: Check if size exceeded error:

					OnError(SMTP_ErrorType.UnKnown,to,reply);
					socket.SendLine("QUIT");

					defectiveEmails.AddRange(to);

					if(logger != null){
						logger.Flush();
					}
					return false;
				}

				#endregion

				#region cmd RCPT
				// NOTE: Syntax:{RCPT TO:<*****@*****.**><CRLF>}
				
				bool isAnyValidEmail = false;
				foreach(string rcpt in to){
					// Send Mail To
					socket.SendLine("RCPT TO:<" + rcpt + ">");

					reply = socket.ReadLine();
					if(!IsReplyCode("250",reply)){
						// Is unknown user
						if(IsReplyCode("550",reply)){							
							OnError(SMTP_ErrorType.InvalidEmailAddress,new string[]{rcpt},reply);
						}
						else{
							OnError(SMTP_ErrorType.UnKnown,new string[]{rcpt},reply);
						}

						defectiveEmails.Add(rcpt);
					}
					else{
						isAnyValidEmail = true;
					}
				}

				// If there isn't any valid email - quit.
				if(!isAnyValidEmail){
					socket.SendLine("QUIT");

					if(logger != null){
						logger.Flush();
					}
					return false;
				}
				//---------------------------------------------//

				#endregion


				#region cmd DATA

				if(!(supports_BDAT && m_UseBDAT)){

					// Notify Data Start
					socket.SendLine("DATA");

					reply = socket.ReadLine();
					if(!IsReplyCode("354",reply)){
						OnError(SMTP_ErrorType.UnKnown,to,reply);
						socket.SendLine("QUIT");

						defectiveEmails.AddRange(to);

						if(logger != null){
							logger.Flush();
						}
						return false;
					}
								
					//------- Do period handling -----------------------------------------//
					// If line starts with '.', add additional '.'.(Read rfc for more info)
					MemoryStream msgStrmPeriodOk = Core.DoPeriodHandling(message,true,false);
					//--------------------------------------------------------------------//
					
					// Check if message ends with <CRLF>, if not add it. -------//
					if(msgStrmPeriodOk.Length >= 2){
						byte[] byteEnd = new byte[2];
						msgStrmPeriodOk.Position = msgStrmPeriodOk.Length - 2;
						msgStrmPeriodOk.Read(byteEnd,0,2);

						if(byteEnd[0] != (byte)'\r' && byteEnd[1] != (byte)'\n'){
							msgStrmPeriodOk.Write(new byte[]{(byte)'\r',(byte)'\n'},0,2);
						}
					}
					msgStrmPeriodOk.Position = 0;
					//-----------------------------------------------------------//

					//---- Send message --------------------------------------------//
					long totalSent   = 0;
					long totalLength = msgStrmPeriodOk.Length; 
					while(totalSent < totalLength){
						byte[] dataBuf = new byte[4000];
						int nCount = msgStrmPeriodOk.Read(dataBuf,0,dataBuf.Length);
						int countSended = socket.Send(dataBuf,0,nCount,SocketFlags.None);					
						totalSent += countSended;

						if(countSended != nCount){
							msgStrmPeriodOk.Position = totalSent;
						}

						OnPartOfMessageIsSent(countSended,totalSent,totalLength);
					}
					//-------------------------------------------------------------//
					msgStrmPeriodOk.Close();
			
					// Notify End of Data
					socket.SendLine(".");

					reply = socket.ReadLine();
					if(!IsReplyCode("250",reply)){
						OnError(SMTP_ErrorType.UnKnown,to,reply);
						socket.SendLine("QUIT");

						defectiveEmails.AddRange(to);

						if(logger != null){
							logger.Flush();
						}
						return false;
					}
				}

				#endregion

				#region cmd BDAT

				if(supports_BDAT && m_UseBDAT){
					socket.SendLine("BDAT " + (message.Length - message.Position) + " LAST");

					//---- Send message --------------------------------------------//
					long totalSent   = 0;
					long totalLength = message.Length - message.Position;
					while(totalSent < totalLength){
						byte[] dataBuf = new byte[4000];
						int nCount = message.Read(dataBuf,0,dataBuf.Length);
						int countSended = socket.Send(dataBuf,0,nCount,SocketFlags.None);					
						totalSent += countSended;

						if(countSended != nCount){
							message.Position = totalSent;
						}

						OnPartOfMessageIsSent(countSended,totalSent,totalLength);
					}
					//-------------------------------------------------------------//

					// Get store result
					reply = socket.ReadLine();
					if(!reply.StartsWith("250")){
						OnError(SMTP_ErrorType.UnKnown,to,reply);
						socket.SendLine("QUIT");

						defectiveEmails.AddRange(to);

						if(logger != null){
							logger.Flush();
						}
						return false;
					}
				}

				#endregion

				#region cmd QUIT

				// Notify server - server can exit now
				socket.SendLine("QUIT");

			//	reply = socket.ReadLine();

				#endregion
				
			}
			catch(Exception x){
				OnError(SMTP_ErrorType.UnKnown,to,x.Message);

				defectiveEmails.AddRange(to);

				if(logger != null){
					logger.Flush();
				}
				return false;
			}
			finally{
				// Raise event
				OnSendJobCompleted(Thread.CurrentThread.GetHashCode().ToString(),to,defectiveEmails);
			}

			if(logger != null){
				logger.Flush();
			}

			return true;
		}
예제 #10
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="socket"></param>
		protected override void InitNewSession(Socket socket)
		{
			SocketLogger logger = new SocketLogger(socket,this.SessionLog);
			FTP_Session session = new FTP_Session(socket,this,Guid.NewGuid().ToString(),logger);
		}
예제 #11
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, DaylilyCore daylily)
        {
            foreach (var frontend in daylily.Frontends)
            {
                if (frontend is CoolQFrontend cqFrontend && daylily.Dispatcher is CoolQDispatcher cqDispatcher)
                {
                    //cqFrontend.PrivateMessageReceived += (sender, e) => { };
                    //cqFrontend.DiscussMessageReceived+= (sender, e) => { };
                    //cqFrontend.GroupMessageReceived += (sender, e) => { };
                    cqFrontend.Requested += (sender, e) =>
                    {
                        daylily.EventDispatcher?.Event_Received(sender, new EventEventArgs(e.ParsedObject));
                    };
                    cqFrontend.Noticed += (sender, e) =>
                    {
                        daylily.EventDispatcher?.Event_Received(sender, new EventEventArgs(e.ParsedObject));
                    };
                    //cqFrontend.EventReceived += (sender, e) =>
                    //{
                    //    daylily.EventDispatcher?.Event_Received(sender, e);
                    //};
                }

                frontend.MessageReceived += (sender, e) =>
                {
                    daylily.MessageDispatcher?.Message_Received(sender, new MessageEventArgs(e.ParsedObject));
                };
                frontend.ErrorOccured += (sender, e) => { };
            }

            var webSocketOptions = new WebSocketOptions()
            {
                KeepAliveInterval = TimeSpan.FromSeconds(120),
                ReceiveBufferSize = 4 * 1024
            };

            app.UseWebSockets(webSocketOptions);

            async Task WebSocket(HttpContext context, Func <Task> next)
            {
                if (context.Request.Path == "/ws")
                {
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        SocketLogger.WebSocket = await context.WebSockets.AcceptWebSocketAsync();

                        await SocketLogger.Response();
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                    }
                }
                else
                {
                    await next();
                }
            }

            app.Use(WebSocket);
            Logger.Raw("Websocket控制台已启动。");

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseStaticFiles();
            //app.UseHttpsRedirection();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
예제 #12
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="logger">Socket logger.</param>
 /// <param name="firstLogPart">Specifies if first log part of multipart log.</param>
 /// <param name="lastLogPart">Specifies if last log part (logging ended).</param>
 public Log_EventArgs(SocketLogger logger, bool firstLogPart, bool lastLogPart)
 {
     m_pLoggger = logger;
     m_FirstLogPart = firstLogPart;
     m_LastLogPart = lastLogPart;
 }
예제 #13
0
파일: Startup.cs 프로젝트: lsahi/Daylily
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            var webSocketOptions = new WebSocketOptions()
            {
                KeepAliveInterval = TimeSpan.FromSeconds(120),
                ReceiveBufferSize = 4 * 1024
            };

            app.UseWebSockets(webSocketOptions);

            async Task WebSocket(HttpContext context, Func <Task> next)
            {
                if (context.Request.Path == "/ws")
                {
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        SocketLogger.WebSocket = await context.WebSockets.AcceptWebSocketAsync();

                        await SocketLogger.Response();
                    }
                    else
                    {
                        context.Response.StatusCode = 400;
                    }
                }
                else
                {
                    await next();
                }
            }

            app.Use(WebSocket);

            Logger.Raw("Websocket控制台已启动。");
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                //app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseStaticFiles();
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            Bot.Console.Startup.RunConsole();
            PluginManager.LoadAllPlugins(new[] { "" });

            if (CoolQDispatcher.PrivateDisabledList == null)
            {
                CoolQDispatcher.PrivateDisabledList =
                    new System.Collections.Concurrent.ConcurrentDictionary <long, System.Collections.Generic.List <string> >();
            }
            if (CoolQDispatcher.DiscussDisabledList == null)
            {
                CoolQDispatcher.DiscussDisabledList =
                    new System.Collections.Concurrent.ConcurrentDictionary <long, System.Collections.Generic.List <string> >();
            }
            if (CoolQDispatcher.GroupDisabledList == null)
            {
                CoolQDispatcher.GroupDisabledList =
                    new System.Collections.Concurrent.ConcurrentDictionary <long, System.Collections.Generic.List <string> >();
            }

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
예제 #14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="socket"></param>
 protected override void InitNewSession(Socket socket)
 {
     SocketLogger logger  = new SocketLogger(socket, this.SessionLog);
     SMTP_Session session = new SMTP_Session(socket, this, logger);
 }
예제 #15
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="socket"></param>
 protected override void InitNewSession(Socket socket)
 {
     SocketLogger logger  = new SocketLogger(socket, this.SessionLog);
     FTP_Session  session = new FTP_Session(socket, this, Guid.NewGuid().ToString(), logger);
 }
예제 #16
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="logger">Socket logger.</param>
 /// <param name="firstLogPart">Specifies if first log part of multipart log.</param>
 /// <param name="lastLogPart">Specifies if last log part (logging ended).</param>
 public Log_EventArgs(SocketLogger logger, bool firstLogPart, bool lastLogPart)
 {
     m_pLoggger     = logger;
     m_FirstLogPart = firstLogPart;
     m_LastLogPart  = lastLogPart;
 }
예제 #17
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="socket"></param>
		protected override void InitNewSession(Socket socket)
		{
			SocketLogger logger = new SocketLogger(socket,this.SessionLog);
			Pop3Session session = new Pop3Session(socket,this,logger);
		}