├── C# source files
├── icon.ico
├── packages.config
├── App.config
├── App.xaml
├── App.xaml.cs
├── LoginConfirmedPopup.xaml
├── EmailIsSentPopup.xaml
├── ErrorPopup.xaml
├── ErrorPopup.xaml.cs
├── LoginConfirmedPopup.xaml.cs
├── C-Mail 2.0.sln
├── EmailIsSentPopup.xaml.cs
├── EncryptionPasswordPopup.xaml
├── AddAttachmentPopup.xaml.cs
├── AddAttachmentPopup.xaml
├── InboxWindow.xaml
├── LoginPopup.xaml
├── EncryptionPasswordPopup.xaml.cs
├── MainWindow.xaml
├── LoginPopup.xaml.cs
├── MainWindow.xaml.cs
├── EncryptionClass.cs
├── InboxWindow.xaml.cs
├── C-Mail 2.0.csproj
└── Program.cs
├── README.md
├── LICENSE
└── Error Codes.txt
/C# source files/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/m-rtijn/C-Mail/HEAD/C# source files/icon.ico
--------------------------------------------------------------------------------
/C# source files/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/C# source files/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/C# source files/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/C# source files/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace C_Mail_2._0
10 | {
11 | ///
12 | /// Interaction logic for App.xaml
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | C-Mail
2 | ======
3 |
4 | An email client in C# using WPF
5 |
6 | Usage
7 | =====
8 |
9 | Before doing anything, be sure to log in. To send an email, click on "Send email" and fill in the recipient's address, subject and the body of the email. If you want you can also add an attachment and CC.
10 |
11 | To receive email, click "Refresh", this will show the last email you have received.
12 |
13 | List of supported hosts
14 | =======================
15 |
16 | - Gmail
17 | - Yahoo mail
18 | - Hotmail (.com and .nl)
19 |
--------------------------------------------------------------------------------
/C# source files/LoginConfirmedPopup.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/C# source files/EmailIsSentPopup.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/C# source files/ErrorPopup.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/C# source files/ErrorPopup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace C_Mail_2._0
16 | {
17 | ///
18 | /// Interaction logic for ErrorPopup.xaml
19 | ///
20 | public partial class ErrorPopup : Window
21 | {
22 | public ErrorPopup()
23 | {
24 | InitializeComponent();
25 | }
26 |
27 | private void CloseButton_Click(object sender, RoutedEventArgs e)
28 | {
29 | Close();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/C# source files/LoginConfirmedPopup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace C_Mail_2._0
16 | {
17 | ///
18 | /// Interaction logic for LoginConfirmedPopup.xaml
19 | ///
20 | public partial class LoginConfirmedPopup : Window
21 | {
22 | public LoginConfirmedPopup()
23 | {
24 | InitializeComponent();
25 | }
26 |
27 | private void CloseButton_Click(object sender, RoutedEventArgs e)
28 | {
29 | Close();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/C# source files/C-Mail 2.0.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.21005.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "C-Mail 2.0", "C-Mail 2.0.csproj", "{6E2641B1-A692-4A3D-8399-498EDAA2B913}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {6E2641B1-A692-4A3D-8399-498EDAA2B913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {6E2641B1-A692-4A3D-8399-498EDAA2B913}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {6E2641B1-A692-4A3D-8399-498EDAA2B913}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {6E2641B1-A692-4A3D-8399-498EDAA2B913}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/C# source files/EmailIsSentPopup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace C_Mail_2._0
16 | {
17 | ///
18 | /// Interaction logic for EmailIsSentPopup.xaml
19 | ///
20 | public partial class EmailIsSentPopup : Window
21 | {
22 | public EmailIsSentPopup()
23 | {
24 | InitializeComponent();
25 | }
26 |
27 | ///
28 | /// Closes this window.
29 | ///
30 | ///
31 | ///
32 | private void CloseButton_Click(object sender, RoutedEventArgs e)
33 | {
34 | Close();
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/C# source files/EncryptionPasswordPopup.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Tijndagamer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/C# source files/AddAttachmentPopup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace C_Mail_2._0
16 | {
17 | ///
18 | /// Interaction logic for AddAttachmentPopup.xaml
19 | ///
20 | public partial class AddAttachmentPopup : Window
21 | {
22 | public static string AttachmentPath;
23 | public AddAttachmentPopup()
24 | {
25 | InitializeComponent();
26 | }
27 |
28 | private void CloseButton_Click(object sender, RoutedEventArgs e)
29 | {
30 | Close();
31 | }
32 |
33 | private void EnterButton_Click(object sender, RoutedEventArgs e)
34 | {
35 | AttachmentPath = AttachmentFilepathTextBox.Text;
36 | Close();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/C# source files/AddAttachmentPopup.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Error Codes.txt:
--------------------------------------------------------------------------------
1 | Error 20001: Something went wrong when sending the Message in SendEmail()
2 | Solution: There may be some internet connection troubles
3 |
4 | Error 30001: splitFromAddress[1] does not exists.
5 | Solution: The given email address does not contain an "@", please check your email address again
6 |
7 | Error 30002: reached default in switch(splitFromAddres[1])
8 | Solution: Sorry, your host is not supported, please open a new issue to request the addition of this host. Please add in this issue the SMTP host, STMP port, POP3 host and POP3 port
9 |
10 | Error 30003: One of the given arguments is null or empty.
11 | Solution: Check again if you have filled in ALL the TextBoxes, and the PasswordBox (except for CC)
12 |
13 | Error 40001:
14 | Solution: Something went wrong in the EnryptionClass.Encrypt method
15 |
16 | Error 40002:
17 | Solution: Wrong encryption password given
18 |
19 | Error 50001: Something went wrong when writing the encrypted credentials to a file
20 | Solution: Please open a new issue, tagged as "bug", and explain what you did before the error occured
21 |
22 | Error 50001: Something went wrong when reading the encrypted credentials from a file
23 | Solution: Please open a new issue, tagged as "bug", and explain what you did before the error occured
24 |
25 | Error 60002: Wrong Address and/or FromPass
26 | Solution: Be sure the filled in login credentials are the correct ones and be sure to have an active internet connection
27 |
28 | Error 60003: EmailHostPOP(FromAddress) returned false
29 | Solution: The filled in FromAddress does not contain an "@" (Paired with error 60005) or your host is not supported (Paired with error 60004)
30 |
31 | Error 60004: reached default in switch(splitFromAddres[1])
32 | Solution: Sorry, your host is not supported, please open a new issue to request the addition of this host. Please add in this issue the SMTP host, STMP port, POP3 host and POP3 port
33 |
34 | Error 60005: splitFromAddress[1] does not exists.
35 | Solution: The filled in FromAddress does not contain an "@"
36 |
37 | Error 70001:
38 | Solution: There are no (new) emails in your inbox, or POP3 acts annoying again.
39 |
--------------------------------------------------------------------------------
/C# source files/InboxWindow.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/C# source files/LoginPopup.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/C# source files/EncryptionPasswordPopup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 |
15 | namespace C_Mail_2._0
16 | {
17 | ///
18 | /// Interaction logic for EncryptionPasswordPopup.xaml
19 | ///
20 | public partial class EncryptionPasswordPopup : Window
21 | {
22 | public EncryptionPasswordPopup()
23 | {
24 | InitializeComponent();
25 | }
26 |
27 | ///
28 | /// Closes this window
29 | ///
30 | ///
31 | ///
32 | private void CloseButton_Click(object sender, RoutedEventArgs e)
33 | {
34 | Close();
35 | }
36 |
37 | ///
38 | /// Reads and decrypts stored login credentials using ReadCredentialsFromFile(string Path, string EncryptionPassword)
39 | ///
40 | ///
41 | ///
42 | private void LoginButton_Click(object sender, RoutedEventArgs e)
43 | {
44 | // Assign EncryptionPassword
45 | string EncryptionPassword = EncryptionPasswordPasswordBox.Password;
46 |
47 | // Decrypt and read the data
48 | try
49 | {
50 | Program.ReadCredentialsFromFile("Credentials", EncryptionPassword);
51 | }
52 | catch(Exception exception)
53 | {
54 | // Create the ErrorMessage
55 | string ErrorMessage = "ERROR 50002:" + "\n" + exception.ToString();
56 |
57 | // Show the ErrorMessage to the user
58 | Program.ErrorPopupCall(ErrorMessage);
59 |
60 | // Stop executing this method
61 | return;
62 | }
63 |
64 | // If the login is succesfull, show the popup
65 | if (!(string.IsNullOrEmpty(Program.FromAddress)) && !(string.IsNullOrEmpty(Program.FromPass)))
66 | {
67 | Program.LoggedInPopupCall();
68 | }
69 |
70 | // Close this window
71 | Close();
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/C# source files/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/C# source files/LoginPopup.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 | using System.IO;
15 |
16 | namespace C_Mail_2._0
17 | {
18 | ///
19 | /// Interaction logic for LoginPopup.xaml
20 | ///
21 | public partial class LoginPopup : Window
22 | {
23 | public static bool RememberDetailsCheckBoxState = false;
24 | public LoginPopup()
25 | {
26 | InitializeComponent();
27 | }
28 |
29 | private void CloseButton_Click(object sender, RoutedEventArgs e)
30 | {
31 | Close();
32 | }
33 |
34 | private void LoginButton_Click(object sender, RoutedEventArgs e)
35 | {
36 | // Assign the variables
37 | Program.FromAddress = FromAddressTextBox.Text;
38 | Program.FromPass = FromPasswordPasswordBox.Password;
39 | string EncryptionPassword = EncryptionPasswordPasswordBox.Password;
40 |
41 | // Save the details if the user wants so
42 | if (RememberDetailsCheckBoxState == true)
43 | {
44 | try
45 | {
46 | Program.WriteCredentialsToFile(Program.FromAddress, Program.FromPass, "Credentials", EncryptionPassword);
47 | }
48 | catch(Exception exception)
49 | {
50 | // Create the ErrorMessage
51 | string ErrorMessage = "ERROR 50001:" + "\n" + exception.ToString();
52 |
53 | // Show the ErrorMessage to the user
54 | Program.ErrorPopupCall(ErrorMessage);
55 |
56 | // Stop executing this method
57 | return;
58 | }
59 | }
60 |
61 | // If the login is succesfull, show the popup
62 | if (!(string.IsNullOrEmpty(Program.FromAddress)) && !(string.IsNullOrEmpty(Program.FromPass)))
63 | {
64 | Program.LoggedInPopupCall();
65 | }
66 |
67 | // Close the window
68 | Close();
69 | }
70 | private void HandleCheck(object sender, RoutedEventArgs e)
71 | {
72 | RememberDetailsCheckBoxState = true;
73 |
74 | // Show the EncryptionPasswordLabel and PasswordBox
75 | EncryptionPasswordLabel.Visibility = Visibility.Visible;
76 | EncryptionPasswordPasswordBox.Visibility = Visibility.Visible;
77 | }
78 | private void HandleUncheck(object sender, RoutedEventArgs e)
79 | {
80 | RememberDetailsCheckBoxState = false;
81 |
82 | // Hide the EncryptionPasswordLabel and PasswordBox
83 | EncryptionPasswordLabel.Visibility = Visibility.Hidden;
84 | EncryptionPasswordPasswordBox.Visibility = Visibility.Hidden;
85 | }
86 | private void FromAddressTextBox_TextChanged(object sender, RoutedEventArgs e)
87 | {
88 |
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/C# source files/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 | using System.Net;
16 | using System.Net.Mail;
17 | using System.Threading;
18 | using System.IO;
19 | using System.Diagnostics;
20 |
21 | namespace C_Mail_2._0
22 | {
23 | ///
24 | /// Interaction logic for MainWindow.xaml
25 | ///
26 | public partial class MainWindow : Window
27 | {
28 |
29 | public MainWindow()
30 | {
31 | InitializeComponent();
32 | }
33 |
34 | // Button and Textbox methods
35 |
36 | private void ToAddressTextBox_TextChanged(object sender, TextChangedEventArgs e)
37 | {
38 |
39 | }
40 |
41 | private void SubjectTextBox_TextChanged(object sender, TextChangedEventArgs e)
42 | {
43 |
44 | }
45 |
46 | private void BodyTextBox_TextChanged(object sender, TextChangedEventArgs e)
47 | {
48 |
49 | }
50 |
51 | ///
52 | /// Exits the program when clicked
53 | ///
54 | ///
55 | ///
56 | private void CloseButton_Click(object sender, RoutedEventArgs e)
57 | {
58 | Close();
59 | }
60 |
61 | ///
62 | /// When the AddAttachmentButton is clicked, show the AddAttachmentpopup
63 | ///
64 | ///
65 | ///
66 | private void AddAttachmentButton_Click(object sender, RoutedEventArgs e)
67 | {
68 | // Create a new instance of the AddAttachmentPopup
69 | AddAttachmentPopup popup = new AddAttachmentPopup();
70 |
71 | // Show the popup
72 | popup.Show();
73 | }
74 |
75 | ///
76 | /// Logs in.
77 | ///
78 | ///
79 | ///
80 | private void LoginButton_Click(object sender, RoutedEventArgs e)
81 | {
82 | // If the credentials are saved, open those, else open the login popup
83 | if (File.Exists("Credentials") == true)
84 | {
85 | // Ask the Encryption password using the EncryptionPasswordPopup
86 | EncryptionPasswordPopup popup = new EncryptionPasswordPopup();
87 |
88 | //Show the popup
89 | popup.Show();
90 | }
91 | else
92 | {
93 | // Create a new instance of the LoginPopup class
94 | LoginPopup loginPopup = new LoginPopup();
95 |
96 | // Show the popup
97 | loginPopup.Show();
98 | }
99 | }
100 |
101 | ///
102 | /// Prepares variables to call SendEmail to and the email
103 | ///
104 | ///
105 | ///
106 | private void SendButton_Click(object sender, RoutedEventArgs e)
107 | {
108 | if (!(string.IsNullOrEmpty(Program.FromAddress)))
109 | {
110 | string ToAddress, Subject, Body, CC, S_Attachment;
111 |
112 | // Assign the variables
113 | ToAddress = ToAddressTextBox.Text;
114 | Subject = SubjectTextBox.Text;
115 | Body = BodyTextBox.Text;
116 | CC = CCAddressTextBox.Text;
117 | S_Attachment = AddAttachmentPopup.AttachmentPath;
118 |
119 | // Call SendEmail to send the email
120 | Program.SendEmail(ToAddress, Program.FromAddress, Program.FromPass, Subject, Body, CC, S_Attachment);
121 |
122 | // Close this window
123 | Close();
124 | }
125 | else
126 | {
127 | Program.ErrorPopupCall("Be sure to log in!");
128 | }
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/C# source files/EncryptionClass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Security.Cryptography;
7 | using System.IO;
8 |
9 | namespace C_Mail_2._0
10 | {
11 | class EncryptionClass
12 | {
13 | // Okay I'm sorry I have no idea how this works, I just copy pasted it from StackOverflow because I can't
14 | // find a decent tutorial I understand. I did add the try/catch
15 | private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2");
16 |
17 | private const int keysize = 256;
18 |
19 | public static string Encrypt(string Plaintext, string Password)
20 | {
21 | try
22 | {
23 | byte[] plainTextBytes = Encoding.UTF8.GetBytes(Plaintext);
24 | using (PasswordDeriveBytes password = new PasswordDeriveBytes(Password, null))
25 | {
26 | byte[] keyBytes = password.GetBytes(keysize / 8);
27 | using (RijndaelManaged symmetricKey = new RijndaelManaged())
28 | {
29 | symmetricKey.Mode = CipherMode.CBC;
30 | using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
31 | {
32 | using (MemoryStream memoryStream = new MemoryStream())
33 | {
34 | using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
35 | {
36 | cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
37 | cryptoStream.FlushFinalBlock();
38 | byte[] cipherTextBytes = memoryStream.ToArray();
39 | return Convert.ToBase64String(cipherTextBytes);
40 | }
41 | }
42 | }
43 | }
44 | }
45 | }
46 | catch (Exception exception)
47 | {
48 | // Create the ErrorMessage
49 | string ErrorMessage = "ERROR 40001:" + "\n" + exception.ToString();
50 |
51 | // Show the ErrorMessage to the user
52 | Program.ErrorPopupCall(ErrorMessage);
53 |
54 | // Stop executing this method
55 | return "";
56 | }
57 | }
58 |
59 | public static string Decrypt(string EncryptedText, string Password)
60 | {
61 | try
62 | {
63 | byte[] cipherTextBytes = Convert.FromBase64String(EncryptedText);
64 | using (PasswordDeriveBytes password = new PasswordDeriveBytes(Password, null))
65 | {
66 | byte[] keyBytes = password.GetBytes(keysize / 8);
67 | using (RijndaelManaged symmetricKey = new RijndaelManaged())
68 | {
69 | symmetricKey.Mode = CipherMode.CBC;
70 | using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
71 | {
72 | using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
73 | {
74 | using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
75 | {
76 | byte[] plainTextBytes = new byte[cipherTextBytes.Length];
77 | int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
78 | return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
79 | }
80 | }
81 | }
82 | }
83 | }
84 | }
85 | catch (Exception exception)
86 | {
87 | // Create the ErrorMessage
88 | string ErrorMessage = "ERROR 40002:" + "\n" + exception.ToString();
89 |
90 | // Show the ErrorMessage to the user
91 | Program.ErrorPopupCall(ErrorMessage);
92 |
93 | // Stop executing this method
94 | return "";
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/C# source files/InboxWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 | using System.IO;
15 | using System.Diagnostics;
16 | using System.Net.Mail;
17 | using S22.Imap;
18 |
19 | namespace C_Mail_2._0
20 | {
21 | ///
22 | /// Interaction logic for InboxWindow.xaml
23 | ///
24 | public partial class InboxWindow : Window
25 | {
26 | public InboxWindow()
27 | {
28 | InitializeComponent();
29 | }
30 |
31 | // Button _Click methods
32 |
33 | private void SendEmailButton_Click(object sender, RoutedEventArgs e)
34 | {
35 | // Create a new instance of MainWindow class
36 | MainWindow SendMail = new MainWindow();
37 |
38 | // Show it
39 | SendMail.Show();
40 | }
41 |
42 | private void ExitButton_Click(object sender, RoutedEventArgs e)
43 | {
44 | Environment.Exit(0);
45 | }
46 |
47 | ///
48 | /// Opens a new tab in your default browser where you can report your issue when the button is clicked
49 | ///
50 | ///
51 | ///
52 | private void ReportAnIssueButton_Click(object sender, RoutedEventArgs e)
53 | {
54 | Process.Start("https://github.com/Tijndagamer/C-Mail/issues/new");
55 | }
56 |
57 | ///
58 | /// Shows the newest email in your inbox
59 | ///
60 | ///
61 | ///
62 | private void RefreshButton_Click(object sender, RoutedEventArgs e)
63 | {
64 | if (!(string.IsNullOrEmpty(Program.FromAddress)))
65 | {
66 | // Create a new list to store all the messages in
67 | List Messages = new List();
68 |
69 | // Get all the unseen messages
70 | Messages = Program.GetAllMessages(Program.FromAddress, Program.FromPass);
71 |
72 | // Get the messagecount
73 | int MessageCount = Messages.Count;
74 |
75 | try
76 | {
77 | // Show the sender of the last received email
78 | FromTextBox.Text = Messages[MessageCount - 1].From.ToString();
79 |
80 | // Show the subject of the last received email
81 | SubjectTextBox.Text = Messages[MessageCount - 1].Subject.ToString();
82 |
83 | // Show the body of the last received email
84 | EmailBodyTextBox.Text = Messages[MessageCount - 1].Body.ToString();
85 | }
86 | catch (Exception exception)
87 | {
88 | // Create the error message
89 | string ErrorMessage = "ERROR 70001" + "\n" + exception.ToString();
90 |
91 | // Show the error message
92 | Program.ErrorPopupCall(ErrorMessage);
93 |
94 | // Stop executing this method
95 | return;
96 | }
97 | }
98 | else
99 | {
100 | Program.ErrorPopupCall("Be sure to log in!");
101 | }
102 | }
103 |
104 | private void LoginButton_Click(object sender, RoutedEventArgs e)
105 | {
106 | // If the credentials are saved, open those, else open the login popup
107 | if (File.Exists("Credentials") == true)
108 | {
109 | // Ask the Encryption password using the EncryptionPasswordPopup
110 | EncryptionPasswordPopup popup = new EncryptionPasswordPopup();
111 |
112 | //Show the popup
113 | popup.Show();
114 | }
115 | else
116 | {
117 | // Create a new instance of the LoginPopup class
118 | LoginPopup loginPopup = new LoginPopup();
119 |
120 | // Show the popup
121 | loginPopup.Show();
122 | }
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/C# source files/C-Mail 2.0.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {6E2641B1-A692-4A3D-8399-498EDAA2B913}
8 | WinExe
9 | Properties
10 | C_Mail_2._0
11 | C-Mail
12 | v4.5
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | false
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | en
28 | C-Mail
29 | Tijndagamer
30 | 0
31 | 1.0.0.%2a
32 | false
33 | true
34 |
35 |
36 | AnyCPU
37 | true
38 | full
39 | false
40 | bin\Debug\
41 | DEBUG;TRACE
42 | prompt
43 | 4
44 | true
45 |
46 |
47 | AnyCPU
48 | pdbonly
49 | true
50 | bin\Release\
51 | TRACE
52 | prompt
53 | 4
54 |
55 |
56 | false
57 |
58 |
59 | AE0BDF6089500312BA5E80F89A996A035F55BF56
60 |
61 |
62 | Martijn.pfx
63 |
64 |
65 | icon.ico
66 |
67 |
68 |
69 | packages\S22.Imap.3.6.0.0\lib\net40\S22.Imap.dll
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | 4.0
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | MSBuild:Compile
89 | Designer
90 |
91 |
92 | Designer
93 | MSBuild:Compile
94 |
95 |
96 | Designer
97 | MSBuild:Compile
98 |
99 |
100 | Designer
101 | MSBuild:Compile
102 |
103 |
104 | Designer
105 | MSBuild:Compile
106 |
107 |
108 | Designer
109 | MSBuild:Compile
110 |
111 |
112 | Designer
113 | MSBuild:Compile
114 |
115 |
116 | Designer
117 | MSBuild:Compile
118 |
119 |
120 | MSBuild:Compile
121 | Designer
122 |
123 |
124 | AddAttachmentPopup.xaml
125 |
126 |
127 | App.xaml
128 | Code
129 |
130 |
131 | EmailIsSentPopup.xaml
132 |
133 |
134 |
135 | EncryptionPasswordPopup.xaml
136 |
137 |
138 | ErrorPopup.xaml
139 |
140 |
141 | InboxWindow.xaml
142 |
143 |
144 | LoginConfirmedPopup.xaml
145 |
146 |
147 | LoginPopup.xaml
148 |
149 |
150 | MainWindow.xaml
151 | Code
152 |
153 |
154 |
155 |
156 |
157 |
158 | Code
159 |
160 |
161 | True
162 | True
163 | Resources.resx
164 |
165 |
166 | True
167 | Settings.settings
168 | True
169 |
170 |
171 | ResXFileCodeGenerator
172 | Resources.Designer.cs
173 |
174 |
175 |
176 | SettingsSingleFileGenerator
177 | Settings.Designer.cs
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 | False
187 | Microsoft .NET Framework 4.5 %28x86 and x64%29
188 | true
189 |
190 |
191 | False
192 | .NET Framework 3.5 SP1 Client Profile
193 | false
194 |
195 |
196 | False
197 | .NET Framework 3.5 SP1
198 | false
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
215 |
--------------------------------------------------------------------------------
/C# source files/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using System.IO;
8 | using System.Diagnostics;
9 | using System.Net;
10 | using System.Net.Mail;
11 | using S22.Imap;
12 |
13 | // This is where the magic happens
14 |
15 | namespace C_Mail_2._0
16 | {
17 | class Program
18 | {
19 | // Global variables
20 | private static string Host = "";
21 | private static int Port = 0;
22 | public static string FromAddress, FromPass;
23 |
24 | //####################
25 | //#Popup call methods#
26 | //####################
27 |
28 | ///
29 | /// Shows the EmailIsSentPopup popup
30 | ///
31 | public static void EmailIsSentPopupCall()
32 | {
33 | // Create a new instance of the class
34 | EmailIsSentPopup popup = new EmailIsSentPopup();
35 |
36 | // Show the popup
37 | popup.Show();
38 |
39 | // Make the popup active
40 | popup.Activate();
41 | }
42 |
43 | ///
44 | /// Shows an error popup, not the best thing to see...
45 | ///
46 | /// The error message
47 | public static void ErrorPopupCall(string ErrorMessage)
48 | {
49 | // Create a new instance of the ErrorPopup class
50 | ErrorPopup Error = new ErrorPopup();
51 |
52 | // Add the content of the ErrorLabel
53 | Error.ErrorLabel.Content = ErrorMessage;
54 |
55 | // Show the error
56 | Error.Show();
57 |
58 | // Make the error popup active
59 | Error.Activate();
60 | }
61 |
62 | public static void LoggedInPopupCall()
63 | {
64 | // Create a new instance of LoginConfirmedPopup
65 | LoginConfirmedPopup popup = new LoginConfirmedPopup();
66 |
67 | // Show the popup
68 | popup.Show();
69 | }
70 |
71 | //####################
72 | //#Send email methods#
73 | //####################
74 |
75 | ///
76 | /// Sends an email
77 | ///
78 | /// The address of the recipient of the email
79 | /// The address of the sender of the email
80 | /// The password of the sender of the email
81 | /// The subject of the email
82 | /// The body of the email
83 | public static void SendEmail(string ToAddress, string FromAddress, string FromPass, string Subject, string Body, string CC, string S_Attachment)
84 | {
85 | // First check if all the TextBoxes are filled in and then check the host.
86 | if (CheckArguments(ToAddress, FromAddress, FromPass, Subject, Body) == true && CheckEmailHost(FromAddress) == true)
87 | {
88 | // Create a new instance of the SmtpClient class
89 | SmtpClient smtpClient = new SmtpClient
90 | {
91 | // Set the host
92 | Host = Host,
93 |
94 | // Set the port
95 | Port = Port,
96 |
97 | // Enable SSL
98 | EnableSsl = true,
99 |
100 | // Assign the delivery method
101 | DeliveryMethod = SmtpDeliveryMethod.Network,
102 |
103 | // Assign the credentials
104 | Credentials = new NetworkCredential(FromAddress, FromPass),
105 |
106 | // Set the timeout
107 | Timeout = 20000
108 | };
109 |
110 | // Create a new MailMessage, called Message, and add the properties
111 | MailMessage Message = new MailMessage(FromAddress, ToAddress, Subject, Body);
112 |
113 | // If there's something in the CC tab, add it to Message
114 | if (!(string.IsNullOrEmpty(CC)))
115 | {
116 | // First convert string CC to MailAddress CC
117 | MailAddress Copy = new MailAddress(CC);
118 |
119 | // Add the Copy to the message
120 | Message.CC.Add(Copy);
121 | }
122 |
123 | // If there's something in the S_Attachment, add it to Message
124 | if (!(string.IsNullOrEmpty(S_Attachment)))
125 | {
126 | // Create a new Attachment
127 | Attachment File = new Attachment(S_Attachment);
128 |
129 | // Add it to Message
130 | Message.Attachments.Add(File);
131 | }
132 |
133 | // Send the message
134 | try
135 | {
136 | smtpClient.Send(Message);
137 | }
138 | catch (Exception exception)
139 | {
140 | // Create the ErrorMessage
141 | string ErrorMessage = "ERROR 20001:" + "\n" + exception.ToString();
142 |
143 | // Show the ErrorMessage to the user
144 | ErrorPopupCall(ErrorMessage);
145 |
146 | // Cleanup
147 | Message.Dispose();
148 |
149 | // Stop executing this method
150 | return;
151 | }
152 |
153 | // Cleanup
154 | Message.Dispose();
155 |
156 | // Call this method to notify the user that the message has been sent
157 | EmailIsSentPopupCall();
158 | }
159 | else
160 | {
161 | // If not, stop the execution of this method.
162 | return;
163 | }
164 | }
165 |
166 | ///
167 | /// Checks the host and if the enterd FromAddress is actually an address.
168 | ///
169 | /// The address of the sender of the email
170 | private static bool CheckEmailHost(string FromAddress)
171 | {
172 | // First split the FromAddress between the @
173 | string[] splitFromAddress = FromAddress.Split('@');
174 |
175 | // Then check if the splitFromAddress[1] exists
176 | if (splitFromAddress.Length == 2)
177 | {
178 | // This switch checks which host it is, and assigns the Host and Port variables to the corresponding Host and Port
179 | switch (splitFromAddress[1])
180 | {
181 | case "gmail.com":
182 | Host = "smtp.gmail.com";
183 | Port = 587;
184 | return true;
185 | case "yahoo.com":
186 | Host = "smtp.mail.yahoo.com";
187 | Port = 465;
188 | return true;
189 | case "hotmail.com":
190 | Host = "smtp.live.com";
191 | Port = 587;
192 | return true;
193 | case "hotmail.nl":
194 | Host = "smtp.live.com";
195 | Port = 587;
196 | return true;
197 | default:
198 | ErrorPopupCall("ERROR 30002" + "\n" + "Description: reached default in switch(splitFromAddres[1])");
199 | return false;
200 | }
201 | }
202 | else
203 | {
204 | ErrorPopupCall("ERROR 30001" + "\n" + "Description: splitFromAddress[1] does not exist.");
205 | return false;
206 | }
207 | }
208 |
209 | ///
210 | /// Checks if all the arguments are not null nor empty
211 | ///
212 | ///
213 | ///
214 | ///
215 | ///
216 | ///
217 | ///
218 | private static bool CheckArguments(string ToAddress, string FromAddress, string FromPass, string subject, string body)
219 | {
220 | // Check for all arguments if they're null or empty, of they all aren't null or empty return true else return false and an error message
221 | if (!(string.IsNullOrEmpty(FromAddress)) && !(string.IsNullOrEmpty(ToAddress)) && !(string.IsNullOrEmpty(FromPass)) && !(string.IsNullOrEmpty(subject)) && !(string.IsNullOrEmpty(body)))
222 | {
223 | return true;
224 | }
225 | else
226 | {
227 | ErrorPopupCall("ERROR 30003" + "\n" + "Description: one of the given arguments is null or empty.");
228 | return false;
229 | }
230 | }
231 |
232 | //#######################
233 | //#Receive email methods#
234 | //#######################
235 |
236 | ///
237 | /// Retrieves all the unseen messages from the server
238 | ///
239 | /// User's email address
240 | /// User's password
241 | /// All the retrieved messages
242 | public static List GetAllMessages(string FromAddress, string FromPass)
243 | {
244 | // Check the host
245 | if (CheckEmailHostIMAP(FromAddress) == true && !(string.IsNullOrEmpty(FromPass)))
246 | {
247 | try
248 | {
249 | // Create a new ImapClient
250 | ImapClient client = new ImapClient(Host, Port, FromAddress, FromPass, AuthMethod.Login, true);
251 |
252 | // Get the uids
253 | IEnumerable uids = client.Search(SearchCondition.All());
254 |
255 | // Get the messages
256 | IEnumerable Messages = client.GetMessages(uids);
257 |
258 | // Convert to list
259 | List MessagesList = Messages.ToList();
260 |
261 | // Return them
262 | return MessagesList;
263 | }
264 | catch (Exception exception)
265 | {
266 | // Create the error message
267 | string ErrorMessage = "ERROR 60002" + "\n" + exception.ToString();
268 |
269 | // Show the error message
270 | Program.ErrorPopupCall(ErrorMessage);
271 |
272 | // Make an empty list to return
273 | List Stop = new List();
274 |
275 | // Stop executing this method
276 | return Stop;
277 | }
278 | }
279 | else
280 | {
281 | // Create the error message
282 | string ErrorMessage = "ERROR 60003" + "\n" + "EmailHostIMAP(FromAddress) returned false";
283 |
284 | // Show the error message
285 | Program.ErrorPopupCall(ErrorMessage);
286 |
287 | // Make an empty list to return
288 | List Stop = new List();
289 |
290 | // Stop executing this method
291 | return Stop;
292 | }
293 | }
294 |
295 | ///
296 | /// Checks the host for the IMAP protocol used for the inbox
297 | ///
298 | ///
299 | private static bool CheckEmailHostIMAP(string FromAddress)
300 | {
301 | // Create splitFromAddress array to store the splitted FromAddress in
302 | string[] splitFromAddress;
303 |
304 | // First split the FromAddress between the @
305 | try
306 | {
307 | splitFromAddress = FromAddress.Split('@');
308 | }
309 | catch (Exception exception)
310 | {
311 | // Create the error message
312 | string ErrorMessage = "ERROR 60006" + "\n" + "FromAddress is empty." + exception.ToString();
313 |
314 | // Show the error message
315 | Program.ErrorPopupCall(ErrorMessage);
316 |
317 | return false;
318 | }
319 |
320 | // Then check if the splitFromAddress[1] exists
321 | if (splitFromAddress.Length == 2)
322 | {
323 | // This switch checks which host it is, and assigns the Host and Port variables to the corresponding Host and Port
324 | switch (splitFromAddress[1])
325 | {
326 | case "gmail.com":
327 | Host = "imap.gmail.com";
328 | Port = 993;
329 | return true;
330 | case "yahoo.com":
331 | Host = "imap.mail.yahoo.com";
332 | Port = 993;
333 | return true;
334 | case "hotmail.com":
335 | Host = "imap-mail.outlook.com";
336 | Port = 993;
337 | return true;
338 | case "hotmail.nl":
339 | Host = "imap-mail.outlook.com";
340 | Port = 993;
341 | return true;
342 | default:
343 | ErrorPopupCall("ERROR 60004" + "\n" + "Description: reached default in switch(splitFromAddres[1])");
344 | return false;
345 | }
346 | }
347 | else
348 | {
349 | ErrorPopupCall("ERROR 60005" + "\n" + "Description: splitFromAddress[1] does not exists.");
350 | return false;
351 | }
352 | }
353 |
354 | //#############################
355 | //#Writing and Reading methods#
356 | //#############################
357 |
358 | ///
359 | /// First encrypts, and then saves the login credentials to a file
360 | ///
361 | /// The FromAddress to be encrypted
362 | /// The FromPass to be encrypted
363 | /// The path of the file
364 | /// The password used for the encryption
365 | public static void WriteCredentialsToFile(string FromAddress, string FromPass, string Path, string EncryptionPassword)
366 | {
367 | // Declare variables
368 | string EncryptedFromAddress, EncryptedFromPass;
369 |
370 | // Create a new instance of the FileStream class
371 | FileStream fileStream = File.OpenWrite(Path);
372 |
373 | // Create a new instance of he BinaryWriter class
374 | BinaryWriter writer = new BinaryWriter(fileStream);
375 |
376 | // Encrypt the FromAddress and Frompass
377 | EncryptedFromAddress = EncryptionClass.Encrypt(FromAddress, EncryptionPassword);
378 | EncryptedFromPass = EncryptionClass.Encrypt(FromPass, EncryptionPassword);
379 |
380 | // Write the credentials to the file
381 | writer.Write(EncryptedFromAddress);
382 | writer.Write(EncryptedFromPass);
383 |
384 | // Close the BinaryWriter
385 | writer.Close();
386 | }
387 |
388 | ///
389 | /// Reads and decrypts the FromAddress and Frompass from the file where they're saved
390 | ///
391 | ///
392 | /// The password used for the encryption
393 | public static void ReadCredentialsFromFile(string Path, string EncryptionPassword)
394 | {
395 | // Create a new instance of the FileStream class
396 | FileStream fileStream = File.OpenRead(Path);
397 |
398 | // Create a new instance of the BinaryReader class
399 | BinaryReader reader = new BinaryReader(fileStream);
400 |
401 | // Read the file
402 | string EncryptedFromAddress = reader.ReadString();
403 | string EncryptedFromPass = reader.ReadString();
404 |
405 | // Create an array to store the decrypted data in
406 | string[] DecryptedData = new string[2];
407 |
408 | // Decrypt the FromAddress and FromPass
409 | DecryptedData[0] = EncryptionClass.Decrypt(EncryptedFromAddress, EncryptionPassword);
410 | DecryptedData[1] = EncryptionClass.Decrypt(EncryptedFromPass, EncryptionPassword);
411 |
412 | // Assign the variables
413 | FromAddress = DecryptedData[0];
414 | FromPass = DecryptedData[1];
415 | }
416 | }
417 | }
--------------------------------------------------------------------------------