2024-04-01 13:02:08 -04:00
using System ;
using System.IO ;
using System.Net.Mail ;
using System.Windows.Forms ;
using System.Globalization ;
using System.Text.RegularExpressions ;
using System.Collections.Generic ;
2024-05-24 22:29:09 -04:00
using System.Security.Cryptography ;
2024-04-01 13:02:08 -04:00
namespace SendEmail
{
2024-05-24 22:29:09 -04:00
class Program
2024-04-01 13:02:08 -04:00
{
#region Global Variables
2024-05-24 22:29:09 -04:00
// File Explorer Path
// C:\Users\[USER]\AppData\Local\Send2Email
2024-04-01 13:02:08 -04:00
public static string appPath = Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) + "\\Send2Email\\" ;
2024-05-24 22:29:09 -04:00
// My Pictures Path
// C:\Users\[USER]\My Pictures
2024-04-01 13:02:08 -04:00
public static string picPath = Environment . GetFolderPath ( Environment . SpecialFolder . MyPictures ) ;
2024-05-24 22:29:09 -04:00
// Variables to be loaded from config file
2024-04-01 13:02:08 -04:00
public static string configName = "cfg" ;
public static string configFileExt = "json" ;
public static string configFileName = configName + "." + configFileExt ;
public static string smtp_host ;
public static int smtp_port ;
public static string smtp_user ;
public static string smtp_pass ;
public static string mail_from ;
public static string mail_subject ;
public static string mail_body ;
public static string mail_delivery ;
public static string file_extensions ;
2024-05-24 22:29:09 -04:00
// Encryption keys (8 bytes for DES)
public static string key_secret = "8byteKey" ;
2024-05-24 23:39:48 -04:00
public static string key_public ; // Moved to config file
2024-04-01 13:02:08 -04:00
#endregion
#region Main Method
[STAThread]
2024-05-24 22:29:09 -04:00
static void Main ( )
2024-04-01 13:02:08 -04:00
{
2024-05-24 22:29:09 -04:00
// Set up the basic requirements for a WinForms application
2024-04-01 13:02:08 -04:00
Application . SetHighDpiMode ( HighDpiMode . SystemAware ) ;
Application . EnableVisualStyles ( ) ;
Application . SetCompatibleTextRenderingDefault ( false ) ;
2024-05-24 22:29:09 -04:00
bool cont = Form3 . LoadConfig ( ) ; // Load Configuration method
if ( cont ) // If Config exists
2024-04-01 13:02:08 -04:00
{
2024-05-24 22:29:09 -04:00
if ( string . IsNullOrEmpty ( smtp_pass ) ) // Check if password is empty
{
// Run first time setup
Application . Run ( new Form3 ( ) ) ;
}
else
{
Application . Run ( new Form1 ( ) ) ; // Open Form1 (Main Window)
}
2024-04-01 13:02:08 -04:00
}
2024-05-24 22:29:09 -04:00
else // If Config Doesn't Exist
2024-04-01 13:02:08 -04:00
{
2024-05-24 22:29:09 -04:00
// Display an error message before closing the application
2024-04-01 13:02:08 -04:00
MessageBox . Show ( "A critical error has occurred. Configuration file is missing. Send2Email will not function without this configuration file. Please contact IT to resolve this issue." ) ;
2024-05-24 22:29:09 -04:00
Application . Exit ( ) ; // Exit the application
}
}
#endregion
#region Encryption Methods
public static string Encrypt ( string input )
{
try
{
string textToEncrypt = input ;
string ToReturn = "" ;
byte [ ] secretkeyByte = System . Text . Encoding . UTF8 . GetBytes ( key_secret ) ;
byte [ ] publickeybyte = System . Text . Encoding . UTF8 . GetBytes ( key_public ) ;
byte [ ] inputbyteArray = System . Text . Encoding . UTF8 . GetBytes ( textToEncrypt ) ;
using ( DESCryptoServiceProvider des = new DESCryptoServiceProvider ( ) )
{
des . Mode = CipherMode . CBC ;
des . Padding = PaddingMode . PKCS7 ;
des . Key = publickeybyte ;
des . IV = secretkeyByte ;
using ( MemoryStream ms = new MemoryStream ( ) )
{
using ( CryptoStream cs = new CryptoStream ( ms , des . CreateEncryptor ( ) , CryptoStreamMode . Write ) )
{
cs . Write ( inputbyteArray , 0 , inputbyteArray . Length ) ;
cs . FlushFinalBlock ( ) ;
ToReturn = Convert . ToBase64String ( ms . ToArray ( ) ) ;
}
}
}
return ToReturn ;
}
catch ( Exception ex )
{
throw new Exception ( ex . Message , ex . InnerException ) ;
}
}
public static string Decrypt ( string input )
{
try
{
string textToDecrypt = input ;
string ToReturn = "" ;
byte [ ] privatekeyByte = System . Text . Encoding . UTF8 . GetBytes ( key_secret ) ;
byte [ ] publickeybyte = System . Text . Encoding . UTF8 . GetBytes ( key_public ) ;
byte [ ] inputbyteArray = Convert . FromBase64String ( textToDecrypt . Replace ( " " , "+" ) ) ;
using ( DESCryptoServiceProvider des = new DESCryptoServiceProvider ( ) )
{
des . Mode = CipherMode . CBC ;
des . Padding = PaddingMode . PKCS7 ;
des . Key = publickeybyte ;
des . IV = privatekeyByte ;
using ( MemoryStream ms = new MemoryStream ( ) )
{
using ( CryptoStream cs = new CryptoStream ( ms , des . CreateDecryptor ( ) , CryptoStreamMode . Write ) )
{
cs . Write ( inputbyteArray , 0 , inputbyteArray . Length ) ;
cs . FlushFinalBlock ( ) ;
ToReturn = System . Text . Encoding . UTF8 . GetString ( ms . ToArray ( ) ) ;
}
}
}
return ToReturn ;
}
catch ( Exception ae )
{
throw new Exception ( ae . Message , ae . InnerException ) ;
2024-04-01 13:02:08 -04:00
}
}
#endregion
#region Email Methods
#region IsValidEmail
2024-05-24 22:29:09 -04:00
// Checks if the email address entered is valid.
public static bool IsValidEmail ( string email )
2024-04-01 13:02:08 -04:00
{
2024-05-24 22:29:09 -04:00
if ( string . IsNullOrWhiteSpace ( email ) ) // Null strings aren't valid so return false
2024-04-01 13:02:08 -04:00
return false ;
try
{
// Normalize the domain
2024-05-24 22:29:09 -04:00
email = Regex . Replace ( email , @"(@)(.+)$" , DomainMapper , RegexOptions . None , TimeSpan . FromMilliseconds ( 200 ) ) ;
2024-04-01 13:02:08 -04:00
// Examines the domain part of the email and normalizes it.
string DomainMapper ( Match match )
{
// Use IdnMapping class to convert Unicode domain names.
var idn = new IdnMapping ( ) ;
// Pull out and process domain name (throws ArgumentException on invalid)
string domainName = idn . GetAscii ( match . Groups [ 2 ] . Value ) ;
return match . Groups [ 1 ] . Value + domainName ;
}
}
catch ( RegexMatchTimeoutException )
{
return false ;
}
catch ( ArgumentException )
{
return false ;
}
try
{
2024-05-24 22:29:09 -04:00
return Regex . IsMatch ( email , @"^[^@\s]+@[^@\s]+\.[^@\s]+$" , RegexOptions . IgnoreCase , TimeSpan . FromMilliseconds ( 250 ) ) ;
2024-04-01 13:02:08 -04:00
}
catch ( RegexMatchTimeoutException )
{
return false ;
}
}
#endregion
#region Attachments
2024-05-24 22:29:09 -04:00
// Checks files in Windows Pictures folder
// returns filepaths with matching extensions
2024-04-01 13:02:08 -04:00
public static string [ ] Attachments ( )
{
string [ ] extensions ;
2024-05-24 22:29:09 -04:00
List < string > output = new List < string > ( ) ; // Holds the output
2024-04-01 13:02:08 -04:00
try
{
extensions = file_extensions . Split ( "," ) ;
for ( int e = 0 ; e < extensions . Length ; e + + )
{
2024-05-24 22:29:09 -04:00
extensions [ e ] = extensions [ e ] . Trim ( ' ' ) ; // Remove any whitespace
2024-04-01 13:02:08 -04:00
}
}
catch ( Exception ex )
{
MessageBox . Show ( "Error parsing extension " + ex + "\r\nUsing default values.\r\njpg, jpeg, png, gif, bmp, tif, pdf" ) ;
string [ ] fill = { "jpg" , "jpeg" , "tif" , "gif" , "bmp" , "pdf" } ;
extensions = fill ;
}
2024-05-24 22:29:09 -04:00
string [ ] files = Directory . GetFiles ( picPath ) ; // Get array of all files in Pictures folder
2024-04-01 13:02:08 -04:00
2024-05-24 22:29:09 -04:00
for ( int i = 0 ; i < files . Length ; i + + ) // Loop through all files
2024-04-01 13:02:08 -04:00
{
2024-05-24 22:29:09 -04:00
string file = files [ i ] ; // current file
for ( int j = 0 ; j < extensions . Length ; j + + ) // Loop through all extensions for each file
2024-04-01 13:02:08 -04:00
{
string footer = file . Substring ( file . Length - extensions [ j ] . Length ) ;
2024-05-24 22:29:09 -04:00
// If the file ends with an extension from our extensions array
2024-04-01 13:02:08 -04:00
if ( footer . ToString ( ) = = extensions [ j ] . ToString ( ) )
{
2024-05-24 22:29:09 -04:00
output . Add ( files [ i ] ) ; // Add it to the output
2024-04-01 13:02:08 -04:00
}
}
}
2024-05-24 22:29:09 -04:00
return output . ToArray ( ) ; // Return a list of all attachments
2024-04-01 13:02:08 -04:00
}
#endregion
#region Send Email
2024-05-24 22:29:09 -04:00
public static void Send ( string sendTo )
2024-04-01 13:02:08 -04:00
{
2024-05-24 22:29:09 -04:00
string [ ] getAttachments = Attachments ( ) ; // Gets all valid attachment files in Pictures folder
2024-04-01 13:02:08 -04:00
try
{
2024-05-24 22:29:09 -04:00
System . Net . Mail . Attachment attachment ; // Create attachment variable
MailMessage mail = new MailMessage ( ) ; // Create mail variable
SmtpClient SmtpServer = new SmtpClient ( smtp_host ) ; // Create SmtpClient
2024-04-01 13:02:08 -04:00
2024-05-24 22:29:09 -04:00
// Load smtp/email settings from Configuration file
2024-04-01 13:02:08 -04:00
SmtpServer . Port = smtp_port ;
mail . From = new MailAddress ( mail_from ) ;
mail . Subject = mail_subject ;
mail . Body = mail_body ;
2024-05-24 22:29:09 -04:00
mail . To . Add ( sendTo . ToString ( ) ) ; // Get sendTo email from user input
2024-04-01 13:02:08 -04:00
2024-05-24 22:29:09 -04:00
for ( int i = 0 ; i < getAttachments . Length ; i + + ) // Loop through each attachment
2024-04-01 13:02:08 -04:00
{
2024-05-24 22:29:09 -04:00
attachment = new System . Net . Mail . Attachment ( getAttachments [ i ] ) ; // Set the attachment variable
mail . Attachments . Add ( attachment ) ; // Attach the new attachment to the email
2024-04-01 13:02:08 -04:00
}
2024-05-24 22:29:09 -04:00
SmtpServer . Credentials = new System . Net . NetworkCredential ( smtp_user , smtp_pass ) ; // Login to SMTP
SmtpServer . EnableSsl = true ; // Use SSL Encryption
2024-04-01 13:02:08 -04:00
2024-05-24 22:29:09 -04:00
SmtpServer . Send ( mail ) ; // Send our mail variable
MessageBox . Show ( mail_delivery + sendTo ) ; // Popup informs user where the email was sent
2024-04-01 13:02:08 -04:00
}
2024-05-24 22:29:09 -04:00
catch ( Exception ex ) // If the Try fails the catch will output this error message.
2024-04-01 13:02:08 -04:00
{
MessageBox . Show ( "A critical error has occured please contact IT \r\n" + ex . ToString ( ) ) ;
}
}
#endregion
#endregion
}
}