using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Configuration;
using System.Security;
using System.Security.Permissions;

namespace Bezpieczeństwo
{
    public partial class Form1 : Form
    {
        string connString =
                @"Data Source = (local)\SQLEXPRESS;Integrated Security = true";

        public Form1()
        {
            InitializeComponent();
        }
        
        private void button1_Click(object sender, EventArgs e)
        {            
            SqlConnectionStringBuilder connStrBuilder = new SqlConnectionStringBuilder();
            connStrBuilder.DataSource = @"(local)\SQLEXPRESS";
            connStrBuilder.IntegratedSecurity = true;
            connStrBuilder.InitialCatalog = "Northwind";
            connStrBuilder.UserID = "Admin";
            connStrBuilder.Password = "P@ssw0rd";    
            connStrBuilder.Encrypt = true;
            connStrBuilder.ConnectTimeout = 2;            
            connStrBuilder.TrustServerCertificate = true;
            
            using (SqlConnection conn = new SqlConnection(connStrBuilder.ConnectionString))
            {
                try
                {
                    conn.Open();
                    MessageBox.Show("Pomyślnie uzyskano szyfrowane połączenie z serwerem: "
                        + conn.DataSource);
                }                    
                catch (SqlException se)
                {
                    MessageBox.Show(se.Message);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ConnectionStringSettingsCollection settings = 
                ConfigurationManager.ConnectionStrings;

            if (settings != null)              
                MessageBox.Show(settings[0].ConnectionString, "ConnectionString");
            else
                MessageBox.Show("Odczytanie wartości ConnectionString nie powiodło się",
                    "ConnectionString");
        }

        private bool RSA(bool szyfruj = true)
        {
            try
            {
                Configuration config = 
                    ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);

                ConnectionStringsSection section = 
                    config.GetSection("connectionStrings") as ConnectionStringsSection;

                if (szyfruj && !section.SectionInformation.IsProtected)
                {
                    section.SectionInformation.
                        ProtectSection("RsaProtectedConfigurationProvider");
                }
                else if (!szyfruj && section.SectionInformation.IsProtected)
                {
                    section.SectionInformation.UnprotectSection();
                }
                else return false;

                config.Save();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (!RSA())
                MessageBox.Show("Zaszyfrowanie pliku konfiguracyjnego nie powiodło się");
            else
                MessageBox.Show("Plik konfiguracyjny został pomyślnie zaszyfrowany");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (!RSA(false))
                MessageBox.Show("Odszyfrowanie pliku konfiguracyjnego nie powiodło się");
            else
                MessageBox.Show("Plik konfiguracyjny został pomyślnie odszyfrowany");
        }
                
        private void button5_Click(object sender, EventArgs e)
        {
            //MessageBox.Show(AppDomain.CurrentDomain.IsFullyTrusted.ToString());         

            // Ustalenie uprawnień
            PermissionSet permissions = new PermissionSet(PermissionState.None);
            permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));                                      
            
            // Tworzenie obiektu Application Domain
            AppDomainSetup appDomainSetup = new AppDomainSetup();
            appDomainSetup.ApplicationBase = 
                AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            AppDomain domain = 
                AppDomain.CreateDomain("NoSql", null, appDomainSetup, permissions);

            // Utworzenie instancji klasy SqlConnCAS w piaskownicy 'domain'
            // z ograniczonym poziomem zaufania
            Type helperType = typeof(SqlConnCAS);
            SqlConnCAS helper = (SqlConnCAS)domain.
                CreateInstanceAndUnwrap(helperType.Assembly.FullName,
                helperType.FullName);
            
            try
            {                    
                helper.sqlConn(connString);
                MessageBox.Show("Nawiązano komunikację z bazą danych");
            }
            catch (SecurityException se)
            {
                MessageBox.Show(se.Message);
            }            
        }

    private void button6_Click(object sender, EventArgs e)
    {                                    
        // Uprawnienia do uruchomienia aplikacji
        PermissionSet permissions = new PermissionSet(PermissionState.None);
        permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

        // Ustalenie uprawnień niezbędnych do nawiązania komunikacji ze źródłem danych            
        SqlClientPermission sqlPermission = new SqlClientPermission(PermissionState.None);
        sqlPermission.Add(connString, "", KeyRestrictionBehavior.AllowOnly);
        permissions.AddPermission(sqlPermission);
            
        AppDomainSetup appDomainSetup = new AppDomainSetup();
        appDomainSetup.ApplicationBase =
            AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
        AppDomain domain =
            AppDomain.CreateDomain("Sql", null, appDomainSetup, permissions);

        Type helperType = typeof(SqlConnCAS);
        SqlConnCAS helper = (SqlConnCAS)domain.
            CreateInstanceAndUnwrap(helperType.Assembly.FullName,
            helperType.FullName);

        try
        {
            helper.sqlConn(connString);
            MessageBox.Show("Nawiązano komunikację z bazą danych");
        }
        catch (SecurityException se)
        {
            MessageBox.Show(se.Message);
        } 
           
        string UnAllowedConnString =
            @"Data Source = (local)\SQLEXPRESS;Initial Catalog = Northwind;"
            + "Integrated Security = true";
        try
        {
            helper.sqlConn(UnAllowedConnString);
            MessageBox.Show("Nawiązano komunikację z bazą danych");
        }
        catch (SecurityException se)
        {
            MessageBox.Show(se.Message);
        } 
    }
}

    public partial class SqlConnCAS : MarshalByRefObject
    {
        public void sqlConn(string connectionString)
        {
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
            }
        }
    }
}
