예제 #1
0
        internal GenericAPI(RoamingNetwork RoamingNetwork,
                            String HTTPServerName = DefaultHTTPServerName,
                            IPPort HTTPServerPort = null,
                            String URIPrefix      = "",
                            Func <String, Stream> GetRessources = null,

                            String ServiceName                = DefaultHTTPServerName,
                            EMailAddress APIEMailAddress      = null,
                            PgpPublicKeyRing APIPublicKeyRing = null,
                            PgpSecretKeyRing APISecretKeyRing = null,
                            String APIPassphrase              = null,
                            EMailAddressList APIAdminEMail    = null,
                            SMTPClient APISMTPClient          = null,

                            DNSClient DNSClient = null,
                            String LogfileName  = DefaultLogfileName)

            : this(RoamingNetwork,
                   new HTTPServer(DefaultServerName : DefaultHTTPServerName).AttachTCPPorts(HTTPServerPort != null ? HTTPServerPort : DefaultHTTPServerPort),
                   URIPrefix,
                   GetRessources,

                   ServiceName,
                   APIEMailAddress,
                   APIPublicKeyRing,
                   APISecretKeyRing,
                   APIPassphrase,
                   APIAdminEMail,
                   APISMTPClient,

                   LogfileName)

        {
        }
예제 #2
0
        /// <summary>
        /// Create an instance of the OCPI HTTP API for Charge Point Operators
        /// using a newly created HTTP server.
        /// </summary>
        public CPOAPI(RoamingNetwork    RoamingNetwork,
                      String            HTTPServerName    = DefaultHTTPServerName,
                      IPPort            HTTPServerPort    = null,
                      String            URIPrefix         = "",

                      String            ServiceName       = DefaultHTTPServerName,
                      EMailAddress      APIEMailAddress   = null,
                      PgpSecretKeyRing  APISecretKeyRing  = null,
                      String            APIPassphrase     = null,
                      EMailAddressList  APIAdminEMail     = null,
                      SMTPClient        APISMTPClient     = null,

                      DNSClient         DNSClient         = null,
                      String            LogfileName       = DefaultLogfileName)
            : base(RoamingNetwork,
                   HTTPServerName,
                   HTTPServerPort != null ? HTTPServerPort : DefaultHTTPServerPort,
                   URIPrefix,
                   ResourceName => typeof(CPOAPI).Assembly.GetManifestResourceStream("org.GraphDefined.WWCP.OCPIv2_1.HTTPAPI.CPOAPI.HTTPRoot." + ResourceName),

                   ServiceName,
                   APIEMailAddress,
                   null,//OpenPGP.ReadPublicKeyRing(typeof(CPOAPI).Assembly.GetManifestResourceStream("org.GraphDefined.WWCP.OCPIv2_1.HTTPAPI.GenericAPI.HTTPRoot.robot@offenes-jena_pubring.gpg")),
                   APISecretKeyRing,
                   APIPassphrase,
                   APIAdminEMail,
                   APISMTPClient,

                   DNSClient,
                   LogfileName)
        {
            RegisterCPOURITemplates();
        }
예제 #3
0
        /// <summary>
        /// Initialize the OCPI HTTP server using IPAddress.Any, http port 8080 and maybe start the server.
        /// </summary>
        internal GenericAPI(RoamingNetwork RoamingNetwork,
                            HTTPServer HTTPServer,
                            String URIPrefix = "/ext/OCPI",
                            Func <String, Stream> GetRessources = null,

                            String ServiceName                = DefaultHTTPServerName,
                            EMailAddress APIEMailAddress      = null,
                            PgpPublicKeyRing APIPublicKeyRing = null,
                            PgpSecretKeyRing APISecretKeyRing = null,
                            String APIPassphrase              = null,
                            EMailAddressList APIAdminEMail    = null,
                            SMTPClient APISMTPClient          = null,

                            String LogfileName = DefaultLogfileName)

        {
            #region Initial checks

            if (RoamingNetwork == null)
            {
                throw new ArgumentNullException("RoamingNetwork", "The given parameter must not be null!");
            }

            if (HTTPServer == null)
            {
                throw new ArgumentNullException("HTTPServer", "The given parameter must not be null!");
            }

            if (URIPrefix.IsNullOrEmpty())
            {
                throw new ArgumentNullException("URIPrefix", "The given parameter must not be null or empty!");
            }

            if (!URIPrefix.StartsWith("/"))
            {
                URIPrefix = "/" + URIPrefix;
            }

            #endregion

            #region Init data

            this._HTTPServer    = HTTPServer;
            this._GetRessources = GetRessources;
            this._URIPrefix     = URIPrefix;

            this._ServiceName      = ServiceName;
            this._APIEMailAddress  = APIEMailAddress;
            this._APIPublicKeyRing = APIPublicKeyRing;
            this._APISecretKeyRing = APISecretKeyRing;
            this._APIPassphrase    = APIPassphrase;
            this._APIAdminEMail    = APIAdminEMail;
            this._APISMTPClient    = APISMTPClient;

            this._DNSClient = HTTPServer.DNSClient;

            #endregion

            RegisterURITemplates();
        }
예제 #4
0
        /// <summary>
        /// Create an instance of the OCPI HTTP API for Charge Point Operators
        /// using a newly created HTTP server.
        /// </summary>
        public CPOAPI(RoamingNetwork RoamingNetwork,
                      String HTTPServerName = DefaultHTTPServerName,
                      IPPort HTTPServerPort = null,
                      String URIPrefix      = "",

                      String ServiceName                = DefaultHTTPServerName,
                      EMailAddress APIEMailAddress      = null,
                      PgpSecretKeyRing APISecretKeyRing = null,
                      String APIPassphrase              = null,
                      EMailAddressList APIAdminEMail    = null,
                      SMTPClient APISMTPClient          = null,

                      DNSClient DNSClient = null,
                      String LogfileName  = DefaultLogfileName)

            : base(RoamingNetwork,
                   HTTPServerName,
                   HTTPServerPort != null ? HTTPServerPort : DefaultHTTPServerPort,
                   URIPrefix,
                   ResourceName => typeof(CPOAPI).Assembly.GetManifestResourceStream("org.GraphDefined.WWCP.OCPIv2_1.HTTPAPI.CPOAPI.HTTPRoot." + ResourceName),

                   ServiceName,
                   APIEMailAddress,
                   null,//OpenPGP.ReadPublicKeyRing(typeof(CPOAPI).Assembly.GetManifestResourceStream("org.GraphDefined.WWCP.OCPIv2_1.HTTPAPI.GenericAPI.HTTPRoot.robot@offenes-jena_pubring.gpg")),
                   APISecretKeyRing,
                   APIPassphrase,
                   APIAdminEMail,
                   APISMTPClient,

                   DNSClient,
                   LogfileName)

        {
            RegisterCPOURITemplates();
        }
예제 #5
0
        /// <summary>
        /// Create a new e-mail envelop based on the given
        /// e-mail builder data.
        /// </summary>
        /// <param name="MailBuilder">An e-mail builder.</param>
        public EMailEnvelop(AbstractEMailBuilder MailBuilder)
        {
            MailBuilder.EncodeBodyparts();

                              // ToDo: Deep cloning!
            this._MailFrom  = new EMailAddressList(MailBuilder.From);
            this._RcptTo    = new EMailAddressList(MailBuilder.To);
            this._Mail      = new EMail(MailBuilder);
        }
예제 #6
0
 /// <summary>
 /// Create a new e-mail envelop based on the given sender
 /// and receiver addresses and the e-mail builder data.
 /// </summary>
 /// <param name="MailFrom">The sender(s) of the e-mail.</param>
 /// <param name="RcptTo">The receiver(s) of the e-mail.</param>
 /// <param name="EMail">An e-mail.</param>
 /// <param name="RemoteSocket">The remote socket of the incoming SMTP connection.</param>
 public EMailEnvelop(EMailAddressList  MailFrom,
                     EMailAddressList  RcptTo,
                     EMail             EMail,
                     IPSocket          RemoteSocket  = null)
 {
     this._MailFrom      = MailFrom;
     this._RcptTo        = RcptTo;
     this._Mail          = EMail;
     this._RemoteSocket  = RemoteSocket;
 }
예제 #7
0
        /// <summary>
        /// Create an instance of the Open Charging Cloud API.
        /// </summary>
        /// <param name="ServiceName">The name of the service.</param>
        /// <param name="HTTPServerName">The default HTTP servername, used whenever no HTTP Host-header had been given.</param>
        /// <param name="LocalHostname">The HTTP hostname for all URIs within this API.</param>
        /// <param name="LocalPort">A TCP port to listen on.</param>
        /// <param name="ExternalDNSName">The offical URL/DNS name of this service, e.g. for sending e-mails.</param>
        /// <param name="URLPathPrefix">A common prefix for all URLs.</param>
        ///
        /// <param name="ServerCertificateSelector">An optional delegate to select a SSL/TLS server certificate.</param>
        /// <param name="ClientCertificateValidator">An optional delegate to verify the SSL/TLS client certificate used for authentication.</param>
        /// <param name="ClientCertificateSelector">An optional delegate to select the SSL/TLS client certificate used for authentication.</param>
        /// <param name="AllowedTLSProtocols">The SSL/TLS protocol(s) allowed for this connection.</param>
        ///
        /// <param name="APIEMailAddress">An e-mail address for this API.</param>
        /// <param name="APIPassphrase">A GPG passphrase for this API.</param>
        /// <param name="APIAdminEMails">A list of admin e-mail addresses.</param>
        /// <param name="APISMTPClient">A SMTP client for sending e-mails.</param>
        ///
        /// <param name="SMSAPICredentials">The credentials for the SMS API.</param>
        /// <param name="SMSSenderName">The (default) SMS sender name.</param>
        /// <param name="APIAdminSMS">A list of admin SMS phonenumbers.</param>
        ///
        /// <param name="TelegramBotToken">The Telegram API access token of the bot.</param>
        ///
        /// <param name="CookieName">The name of the HTTP Cookie for authentication.</param>
        /// <param name="UseSecureCookies">Force the web browser to send cookies only via HTTPS.</param>
        /// <param name="Language">The main language of the API.</param>
        /// <param name="NewUserSignUpEMailCreator">A delegate for sending a sign-up e-mail to a new user.</param>
        /// <param name="NewUserWelcomeEMailCreator">A delegate for sending a welcome e-mail to a new user.</param>
        /// <param name="ResetPasswordEMailCreator">A delegate for sending a reset password e-mail to a user.</param>
        /// <param name="PasswordChangedEMailCreator">A delegate for sending a password changed e-mail to a user.</param>
        /// <param name="MinUserNameLength">The minimal user name length.</param>
        /// <param name="MinRealmLength">The minimal realm length.</param>
        /// <param name="PasswordQualityCheck">A delegate to ensure a minimal password quality.</param>
        /// <param name="SignInSessionLifetime">The sign-in session lifetime.</param>
        ///
        /// <param name="ServerThreadName">The optional name of the TCP server thread.</param>
        /// <param name="ServerThreadPriority">The optional priority of the TCP server thread.</param>
        /// <param name="ServerThreadIsBackground">Whether the TCP server thread is a background thread or not.</param>
        /// <param name="ConnectionIdBuilder">An optional delegate to build a connection identification based on IP socket information.</param>
        /// <param name="ConnectionThreadsNameBuilder">An optional delegate to set the name of the TCP connection threads.</param>
        /// <param name="ConnectionThreadsPriorityBuilder">An optional delegate to set the priority of the TCP connection threads.</param>
        /// <param name="ConnectionThreadsAreBackground">Whether the TCP connection threads are background threads or not (default: yes).</param>
        /// <param name="ConnectionTimeout">The TCP client timeout for all incoming client connections in seconds (default: 30 sec).</param>
        /// <param name="MaxClientConnections">The maximum number of concurrent TCP client connections (default: 4096).</param>
        ///
        /// <param name="SkipURLTemplates">Skip URI templates.</param>
        /// <param name="DisableNotifications">Disable external notifications.</param>
        /// <param name="DisableLogfile">Disable the log file.</param>
        /// <param name="LoggingPath">The path for all logfiles.</param>
        /// <param name="LogfileName">The name of the logfile for this API.</param>
        /// <param name="DNSClient">The DNS client of the API.</param>
        /// <param name="Autostart">Whether to start the API automatically.</param>
        public OpenChargingCloudCSOAPI(String ServiceName         = "GraphDefined Open Charging Cloud CSO API",
                                       String HTTPServerName      = "GraphDefined Open Charging Cloud CSO API",
                                       HTTPHostname?LocalHostname = null,
                                       IPPort?LocalPort           = null,
                                       String ExternalDNSName     = null,
                                       HTTPPath?URLPathPrefix     = null,
                                       String HTMLTemplate        = null,
                                       JObject APIVersionHashes   = null,

                                       ServerCertificateSelectorDelegate ServerCertificateSelector    = null,
                                       RemoteCertificateValidationCallback ClientCertificateValidator = null,
                                       LocalCertificateSelectionCallback ClientCertificateSelector    = null,
                                       SslProtocols AllowedTLSProtocols = SslProtocols.Tls12,

                                       EMailAddress APIEMailAddress    = null,
                                       String APIPassphrase            = null,
                                       EMailAddressList APIAdminEMails = null,
                                       SMTPClient APISMTPClient        = null,

                                       Credentials SMSAPICredentials         = null,
                                       String SMSSenderName                  = null,
                                       IEnumerable <PhoneNumber> APIAdminSMS = null,

                                       String TelegramBotToken = null,

                                       HTTPCookieName?CookieName = null,
                                       Boolean UseSecureCookies  = true,
                                       Languages?Language        = null,
                                       NewUserSignUpEMailCreatorDelegate NewUserSignUpEMailCreator     = null,
                                       NewUserWelcomeEMailCreatorDelegate NewUserWelcomeEMailCreator   = null,
                                       ResetPasswordEMailCreatorDelegate ResetPasswordEMailCreator     = null,
                                       PasswordChangedEMailCreatorDelegate PasswordChangedEMailCreator = null,
                                       Byte?MinLoginLength    = null,
                                       Byte?MinRealmLength    = null,
                                       Byte?MinUserNameLength = null,
                                       PasswordQualityCheckDelegate PasswordQualityCheck = null,
                                       TimeSpan?SignInSessionLifetime = null,

                                       String ServerThreadName                 = null,
                                       ThreadPriority ServerThreadPriority     = ThreadPriority.AboveNormal,
                                       Boolean ServerThreadIsBackground        = true,
                                       ConnectionIdBuilder ConnectionIdBuilder = null,
                                       ConnectionThreadsNameBuilder ConnectionThreadsNameBuilder         = null,
                                       ConnectionThreadsPriorityBuilder ConnectionThreadsPriorityBuilder = null,
                                       Boolean ConnectionThreadsAreBackground = true,
                                       TimeSpan?ConnectionTimeout             = null,
                                       UInt32 MaxClientConnections            = TCPServer.__DefaultMaxClientConnections,

                                       TimeSpan?MaintenanceEvery       = null,
                                       Boolean DisableMaintenanceTasks = false,

                                       Boolean SkipURLTemplates     = false,
                                       Boolean DisableNotifications = false,
                                       Boolean DisableLogfile       = false,
                                       String DatabaseFile          = DefaultOpenChargingCloudAPIDatabaseFile,
                                       String LoggingPath           = null,
                                       String LogfileName           = DefaultOpenChargingCloudAPILogFile,
                                       DNSClient DNSClient          = null,
                                       Boolean Autostart            = false)

            : base(ServiceName ?? "GraphDefined Open Charging Cloud CSO API",
                   HTTPServerName ?? "GraphDefined Open Charging Cloud CSO API",
                   LocalHostname,
                   LocalPort,
                   ExternalDNSName,
                   URLPathPrefix,
                   HTMLTemplate,
                   APIVersionHashes,

                   ServerCertificateSelector,
                   ClientCertificateValidator,
                   ClientCertificateSelector,
                   AllowedTLSProtocols,

                   APIEMailAddress,
                   APIPassphrase,
                   APIAdminEMails,
                   APISMTPClient,

                   SMSAPICredentials,
                   SMSSenderName ?? "Open Charging Cloud",
                   APIAdminSMS,

                   TelegramBotToken,

                   CookieName ?? HTTPCookieName.Parse("OpenChargingCloudCSOAPI"),
                   UseSecureCookies,
                   Language,
                   NewUserSignUpEMailCreator,
                   NewUserWelcomeEMailCreator,
                   ResetPasswordEMailCreator,
                   PasswordChangedEMailCreator,
                   MinLoginLength,
                   MinRealmLength,
                   MinUserNameLength,
                   PasswordQualityCheck,
                   SignInSessionLifetime,

                   ServerThreadName,
                   ServerThreadPriority,
                   ServerThreadIsBackground,
                   ConnectionIdBuilder,
                   ConnectionThreadsNameBuilder,
                   ConnectionThreadsPriorityBuilder,
                   ConnectionThreadsAreBackground,
                   ConnectionTimeout,
                   MaxClientConnections,

                   MaintenanceEvery,
                   DisableMaintenanceTasks,

                   SkipURLTemplates,
                   DisableNotifications,
                   DisableLogfile,
                   DatabaseFile ?? DefaultOpenChargingCloudCSOAPIDatabaseFile,
                   LoggingPath ?? "default",
                   LogfileName ?? DefaultOpenChargingCloudCSOAPILogFile,
                   DNSClient,
                   false)

        {
            //RegisterURLTemplates();

            if (Autostart)
            {
                Start();
            }
        }
예제 #8
0
        internal GenericAPI(RoamingNetwork        RoamingNetwork,
                            String                HTTPServerName          = DefaultHTTPServerName,
                            IPPort                HTTPServerPort          = null,
                            String                URIPrefix               = "",
                            Func<String, Stream>  GetRessources           = null,

                            String                ServiceName             = DefaultHTTPServerName,
                            EMailAddress          APIEMailAddress         = null,
                            PgpPublicKeyRing      APIPublicKeyRing        = null,
                            PgpSecretKeyRing      APISecretKeyRing        = null,
                            String                APIPassphrase           = null,
                            EMailAddressList      APIAdminEMail           = null,
                            SMTPClient            APISMTPClient           = null,

                            DNSClient             DNSClient               = null,
                            String                LogfileName             = DefaultLogfileName)
            : this(RoamingNetwork,
                   new HTTPServer(DefaultServerName: DefaultHTTPServerName).AttachTCPPorts(HTTPServerPort != null ? HTTPServerPort : DefaultHTTPServerPort),
                   URIPrefix,
                   GetRessources,

                   ServiceName,
                   APIEMailAddress,
                   APIPublicKeyRing,
                   APISecretKeyRing,
                   APIPassphrase,
                   APIAdminEMail,
                   APISMTPClient,

                   LogfileName)
        {
        }
예제 #9
0
        /// <summary>
        /// Initialize the OCPI HTTP server using IPAddress.Any, http port 8080 and maybe start the server.
        /// </summary>
        internal GenericAPI(RoamingNetwork        RoamingNetwork,
                            HTTPServer            HTTPServer,
                            String                URIPrefix               = "/ext/OCPI",
                            Func<String, Stream>  GetRessources           = null,

                            String                ServiceName             = DefaultHTTPServerName,
                            EMailAddress          APIEMailAddress         = null,
                            PgpPublicKeyRing      APIPublicKeyRing        = null,
                            PgpSecretKeyRing      APISecretKeyRing        = null,
                            String                APIPassphrase           = null,
                            EMailAddressList      APIAdminEMail           = null,
                            SMTPClient            APISMTPClient           = null,

                            String                LogfileName             = DefaultLogfileName)
        {
            #region Initial checks

            if (RoamingNetwork == null)
                throw new ArgumentNullException("RoamingNetwork", "The given parameter must not be null!");

            if (HTTPServer == null)
                throw new ArgumentNullException("HTTPServer", "The given parameter must not be null!");

            if (URIPrefix.IsNullOrEmpty())
                throw new ArgumentNullException("URIPrefix", "The given parameter must not be null or empty!");

            if (!URIPrefix.StartsWith("/"))
                URIPrefix = "/" + URIPrefix;

            #endregion

            #region Init data

            this._HTTPServer              = HTTPServer;
            this._GetRessources           = GetRessources;
            this._URIPrefix               = URIPrefix;

            this._ServiceName             = ServiceName;
            this._APIEMailAddress         = APIEMailAddress;
            this._APIPublicKeyRing        = APIPublicKeyRing;
            this._APISecretKeyRing        = APISecretKeyRing;
            this._APIPassphrase           = APIPassphrase;
            this._APIAdminEMail           = APIAdminEMail;
            this._APISMTPClient           = APISMTPClient;

            this._DNSClient               = HTTPServer.DNSClient;

            #endregion

            RegisterURITemplates();
        }
예제 #10
0
        public void ProcessArrow(TCPConnection TCPConnection)
        {
            #region Start

            //TCPConnection.WriteLineToResponseStream(ServiceBanner);
            TCPConnection.NoDelay = true;

            Byte Byte;
            var  MemoryStream     = new MemoryStream();
            var  EndOfSMTPCommand = EOLSearch.NotYet;
            var  ClientClose      = false;
            var  ServerClose      = false;
            var  MailClientName   = "";

            #endregion

            try
            {
                var MailFroms = new EMailAddressList();
                var RcptTos   = new EMailAddressList();

                TCPConnection.WriteLineSMTP(SMTPStatusCode.ServiceReady,
                                            _DefaultServerName + " ESMTP Vanaheimr Hermod Mail Transport Service");

                do
                {
                    switch (TCPConnection.TryRead(out Byte, MaxInitialWaitingTimeMS: ReadTimeout))
                    {
                        // 421 4.4.2 mail.ahzf.de Error: timeout exceeded

                        #region DataAvailable

                    case TCPClientResponse.DataAvailable:

                        #region Check for end of SMTP line...

                        if (EndOfSMTPCommand == EOLSearch.NotYet)
                        {
                            // \n
                            if (Byte == 0x0a)
                            {
                                EndOfSMTPCommand = EOLSearch.EoL_Found;
                            }
                            // \r
                            else if (Byte == 0x0d)
                            {
                                EndOfSMTPCommand = EOLSearch.R_Read;
                            }
                        }

                        // \n after a \r
                        else if (EndOfSMTPCommand == EOLSearch.R_Read)
                        {
                            if (Byte == 0x0a)
                            {
                                EndOfSMTPCommand = EOLSearch.EoL_Found;
                            }
                            else
                            {
                                EndOfSMTPCommand = EOLSearch.NotYet;
                            }
                        }

                        #endregion

                        MemoryStream.WriteByte(Byte);

                        #region If end-of-line -> process data...

                        if (EndOfSMTPCommand == EOLSearch.EoL_Found)
                        {
                            if (MemoryStream.Length > 0)
                            {
                                var RequestTimestamp = DateTime.Now;

                                #region Check UTF8 encoding

                                var SMTPCommand = String.Empty;

                                try
                                {
                                    SMTPCommand = Encoding.UTF8.GetString(MemoryStream.ToArray()).Trim();

                                    Debug.WriteLine("<< " + SMTPCommand);
                                }
                                catch (Exception e)
                                {
                                    NotifyErrors(TCPConnection,
                                                 RequestTimestamp,
                                                 "",
                                                 SMTPStatusCode.SyntaxError,
                                                 Error: "Protocol Error: Invalid UTF8 encoding!");
                                }

                                #endregion

                                #region Try to parse SMTP commands

                                #region ""

                                if (SMTPCommand == "")
                                {
                                }

                                #endregion

                                #region HELO <MailClientName>

                                else if (SMTPCommand.ToUpper().StartsWith("HELO"))
                                {
                                    if (SMTPCommand.Trim().Length > 5 && SMTPCommand.Trim()[4] == ' ')
                                    {
                                        MailClientName = SMTPCommand.Trim().Substring(5);

                                        // 250 mail.ahzf.de
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, DefaultServerName);
                                    }
                                    else
                                    {
                                        // 501 Syntax: HELO hostname
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.SyntaxError, "Syntax: HELO hostname");
                                    }
                                }

                                #endregion

                                #region EHLO <MailClientName>

                                else if (SMTPCommand.ToUpper().StartsWith("EHLO"))
                                {
                                    if (SMTPCommand.Trim().Length > 5 && SMTPCommand.Trim()[4] == ' ')
                                    {
                                        MailClientName = SMTPCommand.Trim().Substring(5);

                                        // 250-mail.graphdefined.org
                                        // 250-PIPELINING
                                        // 250-SIZE 204800000
                                        // 250-VRFY
                                        // 250-ETRN
                                        // 250-STARTTLS
                                        // 250-AUTH PLAIN LOGIN CRAM-MD5 DIGEST-MD5
                                        // 250-AUTH=PLAIN LOGIN CRAM-MD5 DIGEST-MD5
                                        // 250-ENHANCEDSTATUSCODES
                                        // 250-8BITMIME
                                        // 250 DSN
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok,
                                                                    DefaultServerName,
                                                                    "VRFY",
                                                                    _UseTLS     ? "STARTTLS"         : null,
                                                                    _TLSEnabled ? "AUTH PLAIN LOGIN" : null,
                                                                    "SIZE 204800000",
                                                                    "ENHANCEDSTATUSCODES",
                                                                    "8BITMIME");
                                    }
                                    else
                                    {
                                        // 501 Syntax: EHLO hostname
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.SyntaxError, "Syntax: EHLO hostname");
                                    }
                                }

                                #endregion

                                #region STARTTLS

                                else if (SMTPCommand.ToUpper() == "STARTTLS")
                                {
                                    if (_TLSEnabled)
                                    {
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.BadCommandSequence, "5.5.1 TLS already started");
                                    }

                                    else if (MailClientName.IsNullOrEmpty())
                                    {
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.BadCommandSequence, "5.5.1 EHLO/HELO first");
                                    }

                                    else
                                    {
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.ServiceReady, "2.0.0 Ready to start TLS");

                                        //                                            var _TLSStream = new SslStream(TCPConnection.NetworkStream);
                                        //                                            _TLSStream.AuthenticateAsServer(TLSCert, false, SslProtocols.Tls12, false);
                                        _TLSEnabled = true;
                                    }
                                }

                                #endregion

                                #region AUTH LOGIN|PLAIN|...

                                else if (SMTPCommand.ToUpper().StartsWith("AUTH "))
                                {
                                    if (!_TLSEnabled)
                                    {
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.BadCommandSequence, "5.5.1 STARTTLS first");
                                    }
                                }

                                #endregion

                                #region MAIL FROM: <SenderMailAddress>

                                else if (SMTPCommand.ToUpper().StartsWith("MAIL FROM"))
                                {
                                    var SMTPCommandParts = SMTPCommand.Split(new Char[2] {
                                        ' ', ':'
                                    }, StringSplitOptions.RemoveEmptyEntries);

                                    if (SMTPCommandParts.Length >= 3)
                                    {
                                        var MailFrom = SMTPCommandParts[2];

                                        if (MailFrom[0] == '<' && MailFrom[MailFrom.Length - 1] == '>')
                                        {
                                            MailFrom = MailFrom.Substring(1, MailFrom.Length - 2);
                                        }

                                        MAIL_FROM_FilterResponse _SMTPFilterResponse = null;

                                        var MAIL_FROMFilterLocal = MAIL_FROMFilter;
                                        if (MAIL_FROMFilterLocal != null)
                                        {
                                            _SMTPFilterResponse = MAIL_FROMFilterLocal(MailFrom);
                                        }

                                        if (_SMTPFilterResponse == null)
                                        {
                                            TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, "2.1.0 " + MailFrom + " Sender ok");
                                            MailFroms.Add(EMailAddress.Parse(MailFrom));
                                        }

                                        else if (_SMTPFilterResponse.Forward)
                                        {
                                            TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, "2.1.0 " + MailFrom + " " + _SMTPFilterResponse.Description);
                                            MailFroms.Add(EMailAddress.Parse(MailFrom));
                                        }

                                        else
                                        {
                                            TCPConnection.WriteLineSMTP(SMTPStatusCode.TransactionFailed, "5.7.1 " + _SMTPFilterResponse.Description);
                                        }
                                    }
                                    else
                                    {
                                        // 501 Syntax: EHLO hostname
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.SyntaxError, "Syntax: MAIL FROM: <*****@*****.**>");
                                    }
                                }

                                #endregion

                                #region RCPT TO: <ReceiverMailAddress>

                                else if (SMTPCommand.ToUpper().StartsWith("RCPT TO"))
                                {
                                    var SMTPCommandParts = SMTPCommand.Split(new Char[2] {
                                        ' ', ':'
                                    }, StringSplitOptions.RemoveEmptyEntries);

                                    if (SMTPCommandParts.Length >= 3)
                                    {
                                        var RcptTo = SMTPCommandParts[2];

                                        // telnet: > telnet mx1.example.com smtp
                                        // telnet: Trying 192.0.2.2...
                                        // telnet: Connected to mx1.example.com.
                                        // telnet: Escape character is '^]'.
                                        // server: 220 mx1.example.com ESMTP server ready Tue, 20 Jan 2004 22:33:36 +0200
                                        // client: HELO client.example.com
                                        // server: 250 mx1.example.com
                                        // client: MAIL from: <*****@*****.**>
                                        // server: 250 Sender <*****@*****.**> Ok
                                        //         250 2.1.0 Ok
                                        // client: RCPT to: <*****@*****.**>
                                        // server: 250 Recipient <*****@*****.**> Ok

                                        // server: 554 5.7.1 <*****@*****.**>: Relay access denied

                                        // client: DATA
                                        // server: 354 Ok Send data ending with <CRLF>.<CRLF>
                                        // client: From: [email protected]
                                        // client: To: [email protected]
                                        // client: Subject: Test message
                                        // client:
                                        // client: This is a test message.
                                        // client: .
                                        // server: 250 Message received: [email protected]
                                        // client: QUIT
                                        // server: 221 mx1.example.com ESMTP server closing connection

                                        // MAIL FROM: [email protected]
                                        // 250 2.1.0 [email protected]... Sender ok
                                        //
                                        // RCPT TO: [email protected]
                                        // 250 2.1.0 [email protected]... Recipient ok

                                        if (RcptTo[0] == '<' && RcptTo[RcptTo.Length - 1] == '>')
                                        {
                                            RcptTo = RcptTo.Substring(1, RcptTo.Length - 2);
                                        }

                                        RCPT_TO_FilterResponse _SMTPFilterResponse = null;

                                        var RCPT_TOFilterLocal = RCPT_TOFilter;
                                        if (RCPT_TOFilterLocal != null)
                                        {
                                            _SMTPFilterResponse = RCPT_TOFilterLocal(RcptTo);
                                        }

                                        if (_SMTPFilterResponse == null)
                                        {
                                            TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, "2.1.0 " + RcptTo + " Recipient ok");
                                            RcptTos.Add(EMailAddress.Parse(RcptTo));
                                        }

                                        else if (_SMTPFilterResponse.Forward)
                                        {
                                            TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, "2.1.0 " + RcptTo + " " + _SMTPFilterResponse.Description);
                                            RcptTos.Add(EMailAddress.Parse(RcptTo));
                                        }

                                        else
                                        {
                                            TCPConnection.WriteLineSMTP(SMTPStatusCode.TransactionFailed, "5.7.1 " + _SMTPFilterResponse.Description);
                                        }
                                    }
                                    else
                                    {
                                        // 501 Syntax: EHLO hostname
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.SyntaxError, "Syntax: RCPT TO: <*****@*****.**>");
                                    }
                                }

                                #endregion

                                #region DATA

                                else if (SMTPCommand.ToUpper().StartsWith("DATA"))
                                {
                                    if (MailFroms.Count == 0 || RcptTos.Count == 0)
                                    {
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.BadCommandSequence, "Bad command sequence!");
                                    }

                                    else
                                    {
                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.StartMailInput, "Ok Send data ending with <CRLF>.<CRLF>");

                                        #region Read all e-mail lines...

                                        var MailText = new List <String>();
                                        var MailLine = "";

                                        do
                                        {
                                            MailLine = TCPConnection.ReadLine();

                                            // "." == End-of-EMail...
                                            if (MailLine != null && MailLine != ".")
                                            {
                                                MailText.Add(MailLine);
                                                Debug.WriteLine("<<< " + MailLine);
                                            }
                                        } while (MailLine != ".");

                                        #endregion

                                        #region Try to parse the incoming e-mail...

                                        EMail IncomingMail = null;

                                        try
                                        {
                                            IncomingMail = EMail.Parse(MailText);
                                        }
                                        catch (Exception)
                                        { }

                                        if (IncomingMail == null)
                                        {
                                            TCPConnection.WriteLineSMTP(SMTPStatusCode.TransactionFailed, "The e-mail could not be parsed!");

                                            Debug.WriteLine("[" + DateTime.Now + "] Incoming e-mail could not be parsed!");
                                            Debug.WriteLine(MailText.AggregateWith(Environment.NewLine));
                                        }

                                        #endregion

                                        #region Generate a MessageId... if needed!

                                        var _MessageId = IncomingMail.MessageId;

                                        if (_MessageId == null)
                                        {
                                            _MessageId   = MessageId.Parse(Guid.NewGuid().ToString() + "@" + _DefaultServerName);
                                            IncomingMail = EMail.Parse(new String[] { "Message-Id: " + _MessageId + Environment.NewLine }.Concat(MailText));
                                        }

                                        #endregion

                                        TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, "Message received: " + _MessageId);

                                        var OnNotificationLocal = OnNotification;
                                        if (OnNotificationLocal != null)
                                        {
                                            OnNotificationLocal(new EMailEnvelop(MailFrom:      MailFroms,
                                                                                 RcptTo:        RcptTos,
                                                                                 EMail:         IncomingMail,
                                                                                 RemoteSocket:  TCPConnection.RemoteSocket));
                                        }
                                    }
                                }

                                #endregion

                                #region RSET

                                else if (SMTPCommand.ToUpper() == "RSET")
                                {
                                    TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, "2.0.0 Ok");
                                    MailClientName = "";
                                    MailFroms.Clear();
                                    RcptTos.Clear();
                                }

                                #endregion

                                #region NOOP

                                else if (SMTPCommand.ToUpper() == "NOOP")
                                {
                                    TCPConnection.WriteLineSMTP(SMTPStatusCode.Ok, "2.0.0 Ok");
                                }

                                #endregion

                                #region VRFY

                                else if (SMTPCommand.ToUpper().StartsWith("VRFY"))
                                {
                                    TCPConnection.WriteLineSMTP(SMTPStatusCode.CannotVerifyUserWillAttemptDelivery, "2.0.0 Send some mail. I'll try my best!");
                                    MailClientName = "";
                                    MailFroms.Clear();
                                    RcptTos.Clear();
                                }

                                #endregion

                                #region QUIT

                                else if (SMTPCommand.ToUpper() == "QUIT")
                                {
                                    TCPConnection.WriteLineSMTP(SMTPStatusCode.ServiceClosingTransmissionChannel, "2.0.0 closing connection");
                                    ClientClose = true;
                                }

                                #endregion

                                #region else error...

                                else
                                {
                                    TCPConnection.WriteLineSMTP(SMTPStatusCode.CommandUnrecognized, "2.0.0 I don't understand how to handle '" + SMTPCommand + "'!");

                                    NotifyErrors(TCPConnection,
                                                 RequestTimestamp,
                                                 SMTPCommand.Trim(),
                                                 SMTPStatusCode.BadCommandSequence,
                                                 Error: "Invalid SMTP command!");
                                }

                                #endregion

                                #endregion
                            }

                            MemoryStream.SetLength(0);
                            MemoryStream.Seek(0, SeekOrigin.Begin);
                            EndOfSMTPCommand = EOLSearch.NotYet;
                        }

                        #endregion

                        break;

                        #endregion

                        #region CanNotRead

                    case TCPClientResponse.CanNotRead:
                        ServerClose = true;
                        break;

                        #endregion

                        #region ClientClose

                    case TCPClientResponse.ClientClose:
                        ClientClose = true;
                        break;

                        #endregion

                        #region Timeout

                    case TCPClientResponse.Timeout:
                        ServerClose = true;
                        break;

                        #endregion
                    }
                } while (!ClientClose && !ServerClose);
            }

            #region Process exceptions

            catch (IOException ioe)
            {
                if (ioe.Message.StartsWith("Unable to read data from the transport connection"))
                {
                }
                else if (ioe.Message.StartsWith("Unable to write data to the transport connection"))
                {
                }

                else
                {
                    //if (OnError != null)
                    //    OnError(this, DateTime.Now, ConnectionIdBuilder(newTCPConnection.RemoteIPAddress, newTCPConnection.RemotePort), ioe, MemoryStream);
                }
            }

            catch (Exception e)
            {
                //if (OnError != null)
                //    OnError(this, DateTime.Now, ConnectionIdBuilder(newTCPConnection.RemoteIPAddress, newTCPConnection.RemotePort), e, MemoryStream);
            }

            #endregion

            #region Close the TCP connection

            try
            {
                TCPConnection.Close((ClientClose) ? ConnectionClosedBy.Client : ConnectionClosedBy.Server);
            }
            catch (Exception)
            { }

            #endregion
        }
예제 #11
0
 /// <summary>
 /// Create a new e-mail envelop based on the given sender
 /// and receiver addresses and the e-mail builder data.
 /// </summary>
 /// <param name="MailFrom">The sender(s) of the e-mail.</param>
 /// <param name="RcptTo">The receiver(s) of the e-mail.</param>
 /// <param name="MailBuilder">An e-mail builder.</param>
 /// <param name="RemoteSocket">The remote socket of the incoming SMTP connection.</param>
 public EMailEnvelop(EMailAddressList      MailFrom,
                     EMailAddressList      RcptTo,
                     AbstractEMailBuilder  MailBuilder,
                     IPSocket              RemoteSocket  = null)
 {
     this._RemoteSocket  = RemoteSocket;
     this._MailFrom      = MailFrom;
     this._RcptTo        = RcptTo;
     this._Mail          = new EMail(MailBuilder);
 }
예제 #12
0
 /// <summary>
 /// Create a new e-mail envelop based on the given e-mail.
 /// </summary>
 /// <param name="EMail">An e-mail.</param>
 public EMailEnvelop(EMail EMail)
 {
     this._MailFrom  = new EMailAddressList(EMail.From);
     this._RcptTo    = new EMailAddressList(EMail.To);
     this._Mail      = EMail;
 }
예제 #13
0
파일: EMail.cs 프로젝트: Vanaheimr/Hermod
        /// <summary>
        /// Create a new e-mail based on the given e-mail builder.
        /// </summary>
        /// <param name="MailBuilder">An e-mail builder.</param>
        public EMail(AbstractEMailBuilder MailBuilder)
            : this(MailBuilder.
                       EncodeBodyparts().
                       // Copy only everything which is not related to the e-mail body!
                       MailHeaders.Where(header => !header.Key.ToLower().StartsWith("content")).
                       Concat(MailBuilder.Body.MailHeaders))
        {
            //ToDo: Do a real deep-copy here!
            Body  = MailBuilder.Body;

            //ToDo: Work-aroung for PGP/GPG!
            this.From = MailBuilder.From;
            this.To   = MailBuilder.To;
            this.Cc   = MailBuilder.Cc;
        }
예제 #14
0
파일: EMail.cs 프로젝트: Vanaheimr/Hermod
        private EMail(IEnumerable<KeyValuePair<String, String>> MailHeader)
        {
            _Header = new List<KeyValuePair<String, String>>(MailHeader);

            foreach (var KVP in _Header)
            {

                switch (KVP.Key.ToLower())
                {

                    case "from":       this.From       = EMailAddress.    Parse(KVP.Value); break;
                    case "to":         this.To         = EMailAddressList.Parse(KVP.Value); break;
                    case "cc":         this.Cc         = EMailAddressList.Parse(KVP.Value); break;
                    case "bcc":        this.Bcc        = EMailAddressList.Parse(KVP.Value); break;
                    case "replyto":    this.ReplyTo    = EMailAddressList.Parse(KVP.Value); break;
                    case "subject":    this.Subject    =                        KVP.Value ; break;
                    case "date":       this.Date       = DateTime.        Parse(KVP.Value); break;
                    case "message-id": this.MessageId  = MessageId.       Parse(KVP.Value); break;

                }

            }
        }