venerdì 12 dicembre 2008

Response.Redirect in UpdatePanel Ajax

A volte può capitare di dover utilizzare la funzione Response.Redirect in un UpdatePanel... Spesso, però, questa funzione restituisce un errore. Questo (di solito) significa che in manca una parte della configurazione nel file web.config
Basterà infatti aggiungere

<httpModules>

<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

</httpModules>


e tutto funzionerà.

venerdì 5 dicembre 2008

Svuotare automaticamente le cartelle "Spam" e "Trash" su MDaemon

Accountpruner tool piuttosto potente di MDaemon, ma non sempre è quello piu facile da usare. Tenendolo a mente, qui ci sono alcune righe del mio file \MDaemon\App\midnight.bat che potrebbero essere utili. Questo file batch viene eseguito da MDaemon ogni notte a mezzanotte. (Se questo file non è presente, può tranquillamente essere creato a mano e MDaemon lo eseguirà).

c:\MDaemon\App\AccountPrune.exe /m /d=10 /p=”Spam.IMAP”
c:\MDaemon\App\AccountPrune.exe /m /d=10 /p=”Junk Mail.IMAP”
c:\MDaemon\App\AccountPrune.exe /m /d=10 /p=”Junk E-mail.IMAP”
c:\MDaemon\App\AccountPrune.exe /m /d=2 /p=”Trash.IMAP”
c:\MDaemon\App\AccountPrune.exe /m /d=2 /p=”Deleted Items.IMAP”
c:\MDaemon\App\AccountPrune.exe /m /d=2 /p=”Deleted Messages.IMAP”


Ovviamente se MDaemon è stato installato in un'altra directory, utilizzate nello script il percorso corretto.

Il risultato è che ogni notte a mezzanotte l'accountpruner di MDaemon verificherà in tutte le cartelle “Spam”, “Junk Mail” e “Junk E-Mail” di tutti gli utenti ed eliminerà tutti i messaggi più vecchi di 10 giorni.

Nelle cartelle “Trash”, “Deleted Items” e “Deleted Messages” verranno cancellati i messaggi più vecchi di 2 giorni. Combinando questo con le opzioni proprie dell'Accountpruner per eliminare anche i messaggi contrassegnati come eliminati, si avrà una soluzione completa, anche se il client email usa una cartella trash "dedicata", usa il flag di eliminazione di IMAP o usa entrambi i metodi.

Usare un NAS basato su Windows (NTFS) con VMware ESX

Qui sotto c'è la procedura competa per utilizzare un NAS basato su Windows (NTFS) come NFS per VMware ESX server.

I principali passaggi di questo processo sono:

  1. Installare Windows Services for UNIX (WSFU)

  2. Copiare i file delle password e dei gruppi da ESX Server a Windows

  3. Configurare WSFU in modo che accetti le connessioni da ESX Server

  4. Condividere la cartella di Windows con compatibilità NFS

  5. Configurare l'ESX Server per utilizzare la condivisione Window NFS come Datastore



1. Installare Windows Services for UNIX (WSFU)

Scaricare l'installazione di "Windows Services for UNIX" da:
http://www.microsoft.com/windowsserversystem/sfu/downloads/default.mspx

Installare WSFU sulla macchina che farà da NAS aggiungendo, se non già selezionate, le opzioni:
"NFS" e "Server for NFS"
"Authentication tools for NFS" e "User name mapping"
Dopo l'installazione, aprire la pagina dei servizi di windows e cambiare le impostazioni di "User Name Mapping" in modo da farlo partire automaticamente e startarlo (se non è già in esecuzione)


2. Copiare i file delle password e dei gruppi da ESX Server a Windows

Con un programmma come "WinSCP" o con un procedimento simile, copiare i seguenti file dal server ESX al server su cui è stato appena installato WSFU.
WinSCP è scaricabile da:
http://winscp.net/eng/download.php#download2
Traferire il file /ect/password ed il file /ect/group in C:\SFU (oppure nella cartella dove è stato installato WSFU)


3. Configurare WSFU in modo che accetti le connessioni da ESX Server

Andare su Start, Programmi, Windows Services for UNIX, Services for UNIX Administration
Andare su "User name mappings" e poi su "configuration"
Cliccare "password and group files"
Dalla finestra cercare ed indicare al programma i file di password e gruppi appena copiati.
Cliccare su "Apply" in altro a destra.
Andare su "maps"
Cliccare su "Show User Maps"
Poi "List Windows users" and "List Unix users"
Selezionare un utente amministratore locale sulla sinistra, sulla destra selezionare l'account di root.
Fatto questo, cliccare sul bottone "Add" per mappare i due utenti.
Alla fine cliccare su "Apply" (in alto a destra)



4. Condividere la cartella di Windows con compatibilità NFS

Tasto destro sulla cartella da condividere via NFS (se la cartella è già stata condivisa, probabilmente sarà necessario togliere la condivisione esistente).
Scegliere "Proprietà" e poi "NFS sharing".
Dare un nome alla condivisione, per esempio NFS-VMFS01
Rimuovere la spunta da "Allow anonymous access".
Cliccare "Permission"
Cambiare il tipo di accesso a "Read+Write" e poi mettere la spunta su "Allow root access".


5. Configurare l'ESX Server per utilizzare la condivisione Window NFS come Datastore

Aprire il Virtual Center client e selezionare l'host su cui creare il Datastore
Nella tab "Configure" scegliere "Networking"
Aggiungere una nuova configurazione per VMKernel e selezionare uno vSwitch, infine dare alla nuova interfaccia configurata un indirizzo che sia raggiungibile dal NAS.
Aprire, per questo host, le opzioni di storage.
Cliccare su "Add storage" e selezionare "Network File System".
Nel campo "Server" inserire il nome o l'indirizzo ip del server NAS a cui ci si deve collegare.
Nel campo "Folder"inserire il nome precedentemente assegnato alla condivisione, nell'esempio /NFS-VMFS01.
Infine, inserire il nome del Datastore (a piacimento).

Ora è possibile iniziare a creare le macchine virtuali sul nostro host utilizzando le risorse disco disponibili sul nas.

sabato 8 novembre 2008

Aggiungere utenti in Team Foundation Server

Dopo l'installazione di Team Foundation Server è necessario aggiungere utenti per poter operare sul server. Per impostazione predefinita, l'account utente utilizzato durante l'installazione viene aggiunto di default.

Tutte le edizioni di Team Foundation Server richiedono che gli utenti siano membri di un gruppo di Team Foundation Server a livello di progetto o server. Il livello e il gruppo dipendono dalle funzionalità che si desidera attivare per l'utente. Se ad esempio si desidera che un utente sia in grado di creare un progetto Team, l'utente deve disporre dell'autorizzazione Crea nuovi progetti impostata su Consenti, deve essere assegnato al ruolo di Gestione contenuto in SQL Server Reporting Services e al ruolo di Amministratore per Windows SharePoint Services. Non è tuttavia necessario che sia membro del gruppo di amministratori locali nel computer. Per ulteriori informazioni su utenti e ruoli, vedere l'argomento "Autorizzazioni di Team Foundation Server" nella guida dell'amministratore di Team Foundation Server.


Per aggiungere utenti a Team Foundation Server:
  1. Accedere come amministratore di Team Foundation, aprire Team Explorer e connettersi al server Team Foundation Server a cui si desidera aggiungere un utente.

  2. Scegliere Impostazioni di Team Foundation Server dal menu Team, quindi Appartenenza a gruppo.

  3. Nella finestra di dialogo Gruppi globali scegliere Utenti con licenza Team Foundation, quindi Proprietà.

  4. Nella finestra di dialogo delle proprietà Gruppo Team Foundation Server scegliere Utente o gruppo Windows, quindi Aggiungi.

  5. Nella finestra di dialogo Selezione utenti o gruppi digitare gli account utente che si desidera aggiungere, quindi scegliere OK.

  6. Scegliere Chiudi.


Note
Non è possibile utilizzare la finestra di dialogo del gruppo Sicurezza globale per aggiungere utenti al gruppo. È possibile aggiungere singoli account utente, ma non un account di gruppo.
ProtezionePer eseguire questa procedura, è necessario essere membro del gruppo Administrators di Team Foundation

Con questa procedura, però, l'utente sarà solo in grado di connettersi al server, ma non potrà né accedere a progetti esistenti né crearne di nuovi. Per terminare correttamente la configurazione è possibile ricorrere al programma TFS Admin Tool. È un programma che permette ad un amministratore TFS di aggiungere velocemente utenti alle tre piattaforme utilizzate dal Team Foundation Suite (Team Foundation Server, Sharepoint e SQL Reporting Services) attraverso una singola interfaccia comune. Il programma permette anche di cambiare i permessi assegnati agli utenti e di identificare gli eventuali errori.


Il programma è scritto in C# ed è pubblicato su CodePlex.

    martedì 4 novembre 2008

    Asterisk / Trixbox: ascolto chiamate in corso

    Con Asterisk o Trixbox è possibile ascoltare le chiamate in corso effettuate o ricevute da altri client.

    In "extensions.conf" in un contesto di vostro piacimento inserite questa riga. Se usate Trixbox o @home mettetelo in "extensions_custom.conf "sotto a [from-internal-custom]

    per esempio:

    exten => _61XXX,1,ChanSpy(SIP/${EXTEN:2},q)

    con tante X quante sono le cifre o i caratteri componenti i "nomi" dei vostri interni (in questo caso 3)

    Un bel reload, e poi bastera digitare sulla tastiera del telefono 61206 per ascoltare le telefonate dell’interno 206

    Asterisk / Trixbox: registrazione chiamate

    Con Asterisk o Trixbox è possibile registrare le chiamate effettuate da client.
    Per farlo basta inserire queste righe nel file "extesion.conf" su Asterisk oppure in "exstension_custom.conf" su Trixbox. (PS: su Trixbox è possibile abilitare questa funzione anche da interfaccia grafica)

    exten => _61XXX,1,Monitor(wav,rec${EXTEN:2},m)
    exten => _61XXX,2,ChanSpy(SIP/${EXTEN:2},q)
    exten => _61XXX,3,Hangup

    in /var/spool/asterisk/monitor troveremo le registrazioni in formato wav con nome rec"numinterno"

    E' anche possibile visualizzarle da web facendo un link simbolico della dir in var/www/dove volete

    giovedì 16 ottobre 2008

    Select Distinct su DataSet in Vb.Net

    Le funzioni sotto riportate permettono di effettuare da codice una query con "Select Distinct" su un DataSet.

    FieldNames è un array di string con in campi su cui fare la select distinct.



    Public Function SelectDistinct(ByVal SourceTable As DataTable, _
        ByVal ParamArray FieldNames() As String) As DataTable

        Dim lastValues() As Object
        Dim newTable As DataTable

        If FieldNames Is Nothing OrElse FieldNames.Length = 0 Then
            Throw New ArgumentNullException("FieldNames")
        End If

        lastValues = New Object(FieldNames.Length - 1) {}
        newTable = New DataTable

        For Each field As String In FieldNames
            newTable.Columns.Add(field, SourceTable.Columns(field).DataType)
        Next

        For Each Row As DataRow In SourceTable.Select("", String.Join(", ", FieldNames))
            If Not fieldValuesAreEqual(lastValues, Row, FieldNames) Then
                newTable.Rows.Add(createRowClone(Row, newTable.NewRow(), FieldNames))
                setLastValues(lastValues, Row, FieldNames)
            End If
        Next

        Return newTable
    End Function



    Private Function fieldValuesAreEqual(ByVal lastValues() As Object, _
        ByVal currentRow As DataRow, ByVal fieldNames() As String) As Boolean

        Dim areEqual As Boolean = True

        For i As Integer = 0 To fieldNames.Length - 1
            If lastValues(i) Is Nothing OrElse Not lastValues(i).Equals(currentRow(fieldNames(i))) Then
                areEqual = False
                Exit For
            End If
        Next

        Return areEqual
    End Function



    Private Function createRowClone(ByVal sourceRow As DataRow, _
        ByVal newRow As DataRow, ByVal fieldNames() As String) As DataRow

        For Each field As String In fieldNames
            newRow(field) = sourceRow(field)
        Next

        Return newRow
    End Function



    Private Shared Sub setLastValues(ByVal lastValues() As Object, _
        ByVal sourceRow As DataRow, ByVal fieldNames() As String)

        For i As Integer = 0 To fieldNames.Length - 1
            lastValues(i) = sourceRow(fieldNames(i))
        Next
    End Sub

    lunedì 6 ottobre 2008

    Configurazione Cisco SOHO 97 per NGI con 8 ip statici

    Avendo la necessità di configurare un router Cisco SOHO 97 per un'Adsl di NGI con 8 IP statici, mi sono fatto un giro per internet ma non ho trovato nulla che facesse al caso mio. Mi spiego:

    Degli 8 indirizzi pubblici statici assegnati, in realta solo 5 sono utilizzabili, in quanto il primo, il secondo e l'ultimo della subnet sono indirizzi di "servizio".

    La mia necessita era di riuscire a fare il NAT 1:1 degli indirizzi pubblici su indirizzi privati in modo che da permettere la gestione di quest'ultimi attraverso il mio server PFSense. Praticamente la struttura della rete è questa:

    Router <--> PFSense <--> Rete interna (MZ e DMZ)

    Praticamente, una persona dal "mondo" fa una richiesta all'indirizzo pubblico, il router lo passa al PFSense come indirizzo privato sull'interfaccia WAN del PFSense, il PFSense lo traduce in un indirizzo di un server sull'interfaccia LAN o DMZ.

    Siccome la configurazione del Router mi ha fatto "dannare" un po', la posto di seguito:


    no service pad
    service timestamps debug datetime msec
    service timestamps log datetime msec
    enable secret
    !
    hostname NomeDelRouter
    !
    boot-start-marker
    boot-end-marker
    !
    enable password PasswordDiEnable
    !
    no aaa new-model
    !
    resource policy
    !
    !
    !
    ip cef
    ip domain name ngi.it.
    ip name-server 88.149.128.12
    ip name-server 88.149.128.22
    !
    username UserAR password 0 PasswordAR
    !
    !
    !
    !
    interface Ethernet0
     ip address 192.168.0.254 255.255.255.0
     ip nat inside
    !
    interface ATM0
     no ip address
     ip nat outside
     no ip mroute-cache
     no atm ilmi-keepalive
     dsl operating-mode auto
     hold-queue 224 in
     pvc 8/35
      encapsulation aal5snap
      protocol ppp dialer
      dialer pool-member 1
     !
    !
    interface Dialer0
     ip address negotiated
     ip nat outside
     encapsulation ppp
     dialer pool 1
     dialer-group 1
     ppp pap sent-username UserADSL password 0 PassADSL
    !
    ip route 0.0.0.0 0.0.0.0 Dialer0
    no ip http server
    !
    ip nat inside source static 192.168.0.1 interface Dialer0
    ip nat inside source static 192.168.0.10 IpPubblico1
    ip nat inside source static 192.168.0.11 IpPubblico2
    ip nat inside source static 192.168.0.12 IpPubblico3
    ip nat inside source static 192.168.0.13 IpPubblico4
    ip nat inside source static 192.168.0.14 IpPubblico5
    !
    !
    control-plane
    !
    !
    line con 0
     no modem enable
    line aux 0
    line vty 0 4
     login local
    !
    scheduler max-task-time 5000
    end

    Dove UserAR e PasswordAR sono rispettivamente il nome utente e la password per l'accesso da remoto (console o telnet), UserADSL e PassADSL sono utente e password della connessione.
    192.168.0.254 è l'indirizzo di rete del router.
    192.168.0.1 è l'indirizzo dell'interfaccia WAN del PFSense.
    192.168.0.10-14 sono gli indirizzi su cui natto gli indirizzi pubblici.

    Degno di nota il fatto che NGI, come si vede, non assegna un indirizzo ip statico di punto-punto (interfaccia Dialer0 del router) ma lo da via DHCP, anche se in realtà l'indirizzo assegnato appunto via DHCP sarà sempre il II nel pool di indirizzi assegnato.

    venerdì 26 settembre 2008

    Scompattare con SharpZipLib e VB.net un file zip con sottocartelle

    Routine di scompattazione di un file Zip con l'utilizzo della dll rilasciata da ICSharpCode (IC#Code), open source, che si chiama SharpZipLib (#ZipLib) scaricabile liberamente QUI


    Imports ICSharpCode.SharpZipLib.Zip
    ......
    If File.Exists(fileName) Then

        destPath = fileName.Substring(0, fileName.Length - 4)

        If Not Directory.Exists(destPath) Then
            Directory.CreateDirectory(destPath)
        Else
            For Each s As String In Directory.GetFiles(destPath)
                File.Delete(s)
            Next
        End If

        Dim inStream As New ZipInputStream(File.OpenRead(fileName))
        Dim outStream As FileStream
        Dim entry As ZipEntry
        Dim buff(2047) As Byte
        Dim bytes As Integer

        Do While True
            Try
                entry = inStream.GetNextEntry()
                If entry Is Nothing Then
                    Exit Do
                End If

                If entry.Name.Last() = "/" Then
                    Directory.CreateDirectory(destPath & "\" & _
                    entry.Name.Replace("/", "\"))
                Else
                    Try
                        outStream = File.Create(destPath & _
                        "\" & entry.Name, 2048)
                        Do While True
                            bytes = inStream.Read(buff, 0, 2048)
                            If bytes = 0 Then
                                Exit Do
                            End If
                            outStream.Write(buff, 0, bytes)
                        Loop
                        outStream.Close()
                    Catch
                    End Try
                End If
            Catch
    ex As ZipException
                rtn += ex.Message & vbCrLf
            End Try
        Loop

        inStream.Close()
    Else
        rtn = "File '" & fileName & "' non trovato."
    End If

    giovedì 18 settembre 2008

    Copia ricorsiva di File e Cartelle in VB.Net

    Sembra banale, ma a volte la semplice copia dei file e delle sottodirectory contenute in una cartella può mettere in crisi un programmatore, proprio per la sua banalità.
    Proprio per evitare questo, posto un esempio di copia ricorsiva.

    Private Sub Copia(ByVal PathOrigine As String, _
                ByVal PathDestinazione As String)
        Dim Files() As String

        If PathDestinazione.Chars(PathDestinazione.Length - 1) <>
                Path.DirectorySeparatorChar Then
            PathDestinazione += Path.DirectorySeparatorChar
        End If

        If Not Directory.Exists(PathDestinazione) Then
            Directory.CreateDirectory(PathDestinazione)
        End If

        Files = Directory.GetFileSystemEntries(PathOrigine)

        Dim Elemento As String

        For Each Elemento In Files
            'Sotto cartelle
            If Directory.Exists(Elemento) Then
                Copia(Elemento, PathDestinazione +
                    Path.GetFileName(Elemento))
                ' File nella cartella
            Else
                File.Copy(Elemento, PathDestinazione +
                    Path.GetFileName(Elemento), True)
            End If
        Next Elemento
    End Sub

    martedì 26 agosto 2008

    Assegnare variabile da Select con SQLServer

    A volte può essere utile salvare il risultato di una Select in una variabile, magari per poterla riutilizzare all'interno di un'altra Select senza dover annidare varie query.
    Il comando per fare ciò è molto semplice:

    DECLARE @variabile AS tipovariabile

    SELECT @variabile = Campo FROM Tabella WHERE Condizione

    Si devono solo seguire alcuni accorgimenti:
    • tipovariabile deve essere, ovviamente, dello stesso tipo dei dati contenuti in Campo
    • nel caso in cui la query restituisca più di una riga, la variabile conterrà il valore dell'ultima riga (questo è molto importante, in quanto se ad esempio si trattasse di date e volessimo memorizzare nella variabile la data più recente, effettuando un "ORDER BY Data DESC" otterremo l'effetto contrario in quanto memorizzando l'ultima riga ci troveremmo in realtà la data piu vecchia)
    • non si può usare la clausola TOP

    Update da Select con Sql Server

    Supponiamo di trovarci in questa situazione: dobbiamo aggiornare dei record in database e come dati di partenza abbiamo il risultato di una query. Le soluzioni sono 2: o modifichiamo la tabella a mano (il che con migliaia di record da modificare potrebbe essere un po fastidioso) oppure possiamo usare uno scriptino T-Sql che fa esattamente quello che ci serve (a patto però di avere un campo nella query che ci permetta di effettuare un join con la tabella da aggiornare).
    Il codice è il seguente:

    UPDATE T
        SET T.Campo1a = Q.Campo2a,
        T.Campo1b = Q.Campo2b
    FROM
        (SELECT CampoID, Campo2a, Campo2b
        FROM Tabella WHERE Condizione) Q
    INNER JOIN TabellaDaModificare T
        ON T.CampoID = Q.CampoID


    Dove T è l'alias utilizzato per la tabella da modificare e Q è l'alias della Select.
    Il Join farà in modo che i campi si aggiornino solo dovo apportuno (praticamente è come se gli facessimo fare un "Update ... Where")

    giovedì 14 agosto 2008

    Backup TrixBox

    Mondoarchive è una soluzione di backup per sistemi *nix che crea file .iso con dimensioni di cd oppure dvd contenenti l’intera immagine del disco (un po’ come ghost sotto Windows). È una soluzione estremamente potente in quanto, tra le altre cose, una volta masterizzate le immagini sono bootabili ed autorestoranti. In questo modo, anche se ad esempio il disco del vostro server/pc si rompe, è possibile ripristinare l’installazione senza dover reinstallare tutto.
    Inoltre, lo script di avvio/configurazione permette di scegliere se creare i file di immagine su disco, su chiavette usb, su share samba (cartelle di rete) oppure su ftp.
    Per qualsiasi informazione aggiuntiva, visitate il sito dei realizzatori: http://www.mondorescue.org/
    La procedura descritta qui sotto è ottimizzata per effettuare i backup di Trixbox versione 2.4 e 2.6 e di sistemi Asterisk.

    Installazione
    Come utente root, eseguire i comandi:
    cd ~
    wget http://www.dbtek.it/Repository/install-mondo.tgz
    (o su http://www.astusers.org/install-mondo.tgz)
    tar -xzvf install-mondo.tgz
    chmod +x install-mondo.sh
    ./install-mondo.sh

    Lo script install-mondo.sh scarica tutte le dipendenze, installa mondo backup e crea una configurazione personalizzata per trixbox.
    Finita l’installazione è necessario riavviare il sistema.

    Poi bisogna editare il file /etc/cron.weekly/mondobackup.cron per attivare le opzioni di backup desiderate e configurare il programma. Tutte le istruzioni necessarie sono contenute direttamente all’interno del file sotto forma di commenti (in lingua inglese).

    Per testare il funzionamento della procedura eseguire /etc/cron.weekly/mondobackup.cron

    ATTENZIONE: se si verificano degli errori sul mount di drive samba (condivisioni di rete su Microsoft) e il vostri username o password per la condivisione utilizzano caratteri diversi dalle semplici lettere e numeri dovete inserire prima e dopo la stringa un apice ( ‘ )


    Ripristino di un backup
    Per ripristinare un backup effettuato con Mondo, si possono scegliere diverse alternative:

    Nuke (formatta il disco e ripristina tutto, automaticamente)
    Interactive
    Expert

    Inoltre è possibile provare a ripristinare solo il bootloader (se non si è perso il disco):
    • Far il boot dal CD/DVD di backup e scegliere Expert Mode
    • digitare: mondorestore --mbr
    • scegliere l’opzione 28 e poi
    bash# mount-me
    bash# chroot /mnt/RESTORING
    bash# lilo oppure grub-install ’(hd0)’
    bash# exit
    bash# unmount-me

    Nuke Restore
    Come già detto, questa opzione sovrascrive completamente il disco fisso del sistema, ripristinando automaticamente il backup

    • Fare il boot dal primo CD/DVD di backup
    • Scegliere RESTORE
    • Quando richiesto, inserire i CD/DVD seguenti (se presenti)
    • Controllare che non ci siano errori

    Se si verifica qualche errore, è possible controllare il file /tmp/mondorestore.log.

    Se si vuole vedere passo passo cosa sta facendo il programma, basta premere e per analizzare “on-the-fly” il log.

    Interactive Restore
    L’Interactive Mode permette di ripristinare un sottoinsieme di dati dal backup, e non l’intero sistema, oppure si può utilizzare per ripristinare tutti i file ma senza dover formattare il disco.

    Il ripristino interattivo fornisce l’ “Editing mountlist screen” che permette di impostare diverse geometrie del disco. Per spostarsi tra le partizioni utilizzare le frecce su e giu. Per spostarsi tra i bottoni, invece utilizzare le frecce destra e sinistra.

    Per ripristinare solo una parte dei file, la procedura da seguire è la seguente:
    • Fare il boot dal primo CD/DVD di backup
    • Digitare interactive
    • Rispondere alle domande poste:
    Do you want to partition your devices? no
    Do you want to format them? no
    Do you want to restore everything? no
    Do you want to restore something? yes
    Which path do you want to restore? /mydata (ad esempio)
    Do you want to run LILO to setup your boot sectors? Yes

    Expert Restore
    Per effettuare un restore manuale:
    • Fare il boot dal primo CD/DVD di backup
    • Digitare expert
    • Digitare mondorestore

    Ora dovreste seguire le istruzioni a video per modificare a piacimento il sistema e ripristinare manualmente i file.

    sabato 12 luglio 2008

    Gestione degli errori nelle pagine ASP.Net

    In generale, come vengono gestiti gli errori nelle pagine ASP .NET?

    Un modo è, nel Global.asax, intervenire nell'evento onError e fare un server transfer a pagine apposite per errori, tipicamente errore 500 ed errore 404.
    Sempre in questo evento, magari, ci si può far una mail in modo da essere allertati se il sito non funziona.

    La cosa migliore, però, è creare un HttpModule che intercetta l'evento error:

    C#
    public class ErrorModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.Error += new System.EventHandler(context_Error);
        }

        private void context_Error(object sender, System.EventArgs e)
        {
            Exception exception = HttpContext.Current.Server.GetLastError();
        }

        public void Dispose()
        {
        ...
        }
    }

    VB.Net
    Public Class ErrorModule
        Inherits IHttpModule

        Public Sub Init(ByVal context As HttpApplication)
            AddHandler context.Error, AddressOf Me.context_Error
        End Sub

        Private Sub context_Error(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim exception As Exception = HttpContext.Current.Server.GetLastError
        End Sub

        Public Sub Dispose()
            ...
        End Sub
    End Class

    e quindi registrarlo nel Web.config:

    <system.web>
        <httpModules>
            <add name="ErrorModule" type="ErrorModule" />
        </httpModules>
    </system.web>



    Gli HttpModules sono "il modo migliore" in quanto consentono riusabilità ed è possibile abilitarli o disabilitarli dal Web.config, senza ricompilare. Inoltre usando il Global.asax viene meno la modularità dell'applicazione Web.

    venerdì 20 giugno 2008

    Sostituzione stringhe in campi Text o nText

    Problema: Come posso fare per sostituire una stringa con un'altra in un campo di tipo Text o nText?

    Considerazioni: Se il campo fosse di tipo varchar o nvarchar il problema non si porrebbe, in quanto esiste in SqlServer una funzione (più in generale esiste in T-Sql) che lo fa in modo nativo: la funzione "Replace". Funzione che, però, non lavora sui campi text. Bisogna utilizzare un'altra funzione, che però ha un utilizzo più generico: UpdateText

    Soluzione:
    declare @TestoVecchio varchar(1000)
    set @TestoVecchio = 'Vecchio'

    declare curs cursor local fast_forward
    for
    select
        idriga,
        textptr(Colonna),
        charindex(@TestoVecchio, Colonna)-1
    from
        Tabella
    where
        Colonna
    like
        '%' + @TestoVecchio +'%'


    declare @Testonuovo varchar(1000)
    set @Testonuovo = 'nuovo'

    declare @txtlen int
    set @txtlen = len(@TestoVecchio)


    declare @ptr binary(16)
    declare @pos int
    declare @id int


    open curs

    fetch next from curs into @id, @ptr, @pos

    while @@fetch_status = 0
    begin
        updatetext Tabella.Colonna @ptr @pos @txtlen @Testonuovo

        fetch next from curs into @id, @ptr, @pos
    end

    close curs
    deallocate curs

    Note:
    Tabella è la tabella di riferimento
    Colonna è il campo in cui si deve modificare il testo
    idriga è l'id della tabella (in questo caso è di tipo int, quindi la variabile @id è impostata come int, se fosse di tipo diverso basta cambiare la dichiarazione della variabile @id nel tipo corretto)

    martedì 10 giugno 2008

    Stringhe di connessione a Database per Web.Config

    Database Access
    <connectionstrings>
      <add name="AccessConnectionString"
       connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
       Data Source=|DataDirectory|nomedb.mdb"
       providerName="System.Data.OleDb" />
    </connectionstrings>


    Database ODBC
    <connectionstrings>
      <add name="ODBCConnectionString"
       connectionString="DSN=nomedsn;Uid=sa;Pwd=pwd;
       providerName="System.Data.Odbc” />
    </connectionstrings>


    Database SQLServer
    <connectionstrings>
      <add name="OLEDBConnectionString"
       connectionString="Server=nomeserver;Integrated Security=SSPI;Database=nomedb;"
       providerName="System.Data.SqlClient" />
    </connectionstrings>


    Connessione ad Excel
    <connectionstrings>
      <add name="OLEDBConnectionString"
       connectionString="Provider=Microsoft.Jet.OLEDB.4.0;
       Data Source= nomefile.xls; Extended Properties=Excel 8.0;"; />
    </connectionstrings>


    Connessione a file .csv
    <connectionstrings>
      <add name="OLEDBConnectionString"
       connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=nomefile.csv;
       ExtendedProperties=""Text;HDR=Yes;FMT=Delimited""";/>
    </connectionstrings>



    Inoltre si possono utilizzare le connessioni native verso Oracle.

    mercoledì 4 giugno 2008

    Ajax - Response.Write in un UpdatePanel

    Normalmente l’uso del Response.Write() in un UpdatePanel non è consentito.
    Per ovviare a questo problema, uno stratagemma è quello di inserire un LinkButton esterno all’UpdatePanel e associare a questo controllo il postback generato dall’oggetto interno al pannello.


    HTML
    <asp:UpdatePanel ID="upd" runat="server">
        …
        <asp:Button runat="server" ID="BOTTONE" Text="Clicca" />
        …
        </asp:UpdatePanel>
    <asp:LinkButton ID="ALinkButton" runat="server"></asp:LinkButton>



    CODICE
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        …
        AddHandler Me.ALinkButton.Click, AddressOf FUNZIONE
        Me.BOTTONE.Attributes.Add("onclick", Page.ClientScript.GetPostBackEventReference(Me.ALinkButton, ""))

        If Not Page.IsPostBack Then
            …
        End If
        …
    End Sub

    Protected Sub FUNZIONE(ByVal sender As Object, ByVal e As System.EventArgs)
        …
        Response.Write("Testo")
        …
    End Sub

    martedì 27 maggio 2008

    Validatore GUID

    Lavorando spesso con gli Unique Identifier (noti anche come GUID) avevo la necessità di sapere in qualche modo se la stringa passata ad una funzione fosse effettivamente un GUID oppure qualcosa di diverso. Non trovando una funzione predefinita che lo facesse, me ne sono costruito una utilizzando le Regular Expression:


    Public Function IsGUID(ByVal guid As String) As Boolean
        Dim rtn As Boolean = False
        If Not String.IsNullOrEmpty(guid) Then
            Dim guidRegEx As Regex = New Regex("^(\{{0,1}" & _
               "([0-9a-fA-F]){8}-([0-9a-fA-F])" & _
               "{4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-" & _
               "([0-9a-fA-F]){12}\}{0,1})$")
            rtn = guidRegEx.IsMatch(guid)
        Else
            rtn = False
        End If

        Return rtn
    End Function

    Tag OOXML Word 2007

    Capita, sviluppando un programma, di trovarsi ad avere l'esigenza di salvare dei dati in formati diversi, magari in excel o in word...
    Salvare un testo in word è abbastanza semplice, farlo in word 2007 (.docx) è un po' diverso (alla fine è xml) ma comunque semplice. Dare una formattazione migliore, però, può risultare un po' piu complesso perchè non è sempre semplice trovare i "tag" di formattazione corretti. Per questo motivo ne riporto alcuni qui sotto, con il loro corrispettivo.

    <p>testo</p>
    <w:p><w:r><w:t>TESTO</w:t></w:r></w:p>

    <br />TESTO
    </w:t></w:r><w:br /><w:r><w:t>TESTO

    Grassetto
    <w:r><w:rPr><w:b /></rPr>TESTO</w:r>

    Sottolineato
    <w:r><w:rPr><w:u w:val="single"/></rPr>TESTO</w:r>

    Corsivo
    <w:r><w:rPr><w:i /></rPr>TESTO</w:r>

    Colori
    <w:r><w:rPr><w:color w:val="FF0000" /></rPr>TESTO</w:r>

    domenica 18 maggio 2008

    Sbloccare file bloccati su Team Foundation Server

    Qualche tempo fa ho avuto la necessità, lavorando su Team Foundation Server 2005, di dover sbloccare dei file bloccati da altri utenti (ad esempio perchè erano stati bloccati in un Work Area non più disponibile). Dopo varie ricerche sui Newsgroup Microsoft e sulla documentazione tecnica, sono riuscito a ricostruire una procedura (funzionante) per sbloccarli:

    Per poter sbloccare i file bloccati da altri utenti:

    1. Posizionarsi dal prompt dei comandi nella cartella C:\Programmi\Microsoft Visual Studio 8\Common7\IDE del server TFS

    2. Digitare il comando:
    “tf lock $/NomeProgetto/NomeDelFileDaSbloccare /lock:none /workspace:AreaDiLavoroCHeBlocca;UtenteCheBlocca /server:NomeDelServerTFS

    4. Digitare il comando:
    “tf undo $/NomeProgetto/NomeDelFileDaSbloccare /workspace:AreaDiLavoroCHeBlocca;UtenteCheBlocca /server:NomeDelServerTFS

    venerdì 16 maggio 2008

    Ajax - Animazione FadeIn e FadeOut

    Con l'AjaxToolkit di Microsoft si possono fare tante cose, quella più complicata (a mio avviso) è applicare ad un oggetto un'animazione. Con poche righe, però, si possono creare semplici animazioni ed effetti da applicare ad una nostra WebForm.

    Ad esempio, supponiamo di voler fare in modo che, spostando il mouse sopra un bottone si visualizzi un "tooltip" personalizzato e che sparisca spostandolo via dal bottone. Questi sono i tag e le proprietà per applicare al tooltip i classici effetti di fadeIn e fadeOut, della durata di 0.5 secondi ad un framerate di 20fps:


    <cc1:AnimationExtender ID="AnimationExtender1" runat="server"
    TargetControlID="ImageButton1">
         <Animations>
              <OnMouseOver>
                   <sequence>
                        <StyleAction AnimationTarget="info"
                        Attribute="display" Value="block"/>
                        <FadeIn AnimationTarget="info" Duration=".5"
                        Fps="20" />
                   </sequence>
              </OnMouseOver>
              <OnMouseOut>
                   <sequence>
                        <FadeOut AnimationTarget="info" Duration=".5"
                        Fps="20" />
                        <StyleAction AnimationTarget="info"
                        Attribute="display" Value="none"/>
                   </sequence>
              </OnMouseOut>
         </Animations>
    </cc1:AnimationExtender>



    info è un div che contiente il nostro tooltip. Deve essere costruito in questo modo:

    <div id="info" style="display: none; z-index: 2; opacity: 0;">

    giovedì 15 maggio 2008

    OpenVPN su PFSense: Site to Site

    Ipotizziamo una situazione di questo tipo:

    Ufficio1 LAN: 192.168.0.0/24
    Ufficio2 LAN: 192.168.1.0/24

    Impostare i server PfSense per connettere le due reti.
    Bisognerà configurare un ufficio come server e l’altro come client

    NB: se è gia stato configurato un accesso VPN per i client remoti, non modificare la configurazione esistente ma aggiungere un nuovo tunnel.


    Configurazione Ufficio1
    Configuriamo l’Ufficio1 come server.
    Dal menu “VPN à OpenVPN”, selezionare il tab “Server” e fare click su “+”.

    Utilizzare il protocollo TCP e, se sono stati configurati altri tunnel VPN, usare una porta diversa da quelle utilizzate (nell’esempio è stata utilizzata la 1193). Ovviamente bisognerà creare una regola sul firewall che permetta le connessioni dalla WAN su questa porta. (vedi post precedente sulla Vpn per client remoti)

    “Address pool” deve essere una sottorete indipendente, che non sia usata ne in Ufficio1 ne in Ufficio2.

    In “Remote network” inserire la rete LAN dell’Ufficio2.

    Ora si deve creare la “Shared key”. Fare il login sul server PfSense dell’Ufficio1 in SSH, digitare “8” (la shell) ed utilizzare il seguente comando:

    # openvpn --genkey --secret shared.key

    Questo comando creerà la shared key per questo server OpenVPN. Generata la chiave, copiare il contenuto del file shared.key appena creato nel box Shared Key dell’interfaccia Web e premere “Save”.

    Bisogna copiare la shared key appena generata in modo da utilizzarla sul server nell’Ufficio2.


    Configurazione Ufficio2

    Configuriamo l’ufficio2 come client.

    Dal menu “VPN à OpenVPN”, selezionare il tab “Client” e fare click su “+”.

    Utilizzare “TCP” come protocollo.

    “Server address” deve essere l’IP pubblico dell’Ufficio1.

    “Server port” è la porta di connessione per la VPN impostata sul PfSense dell’Ufficio1 (in questo caso 1193.)

    “Interface IP” deve essere l’indirizzo IP della rete locale.

    “Remote network” è l’indirizzo IP della LAN dell’Ufficio1.

    Incollare la shared key generata nell’Ufficio1 nel box shared key e alla fine cliccare su “Save”.

    A questo punto il tunnel VPN tra le due sedi dovrebbe essere “up and running”.

    OpenVPN su PFSense: Client remoti

    CREAZIONE DEI CERTIFICATI
    Questo step non è necessario se si vuole configurare una Vpn Site-to
    -site

    Creazione dei certificate su Unix/Linux
    Per prima cosa si devono scaricare i sorgenti di OpenVPN da:

    http://openvpn.net/download.html

    Si possono scaricare anche direttamente, usando “fetch” or “wget” se non si vuole/può utilizzare l’interfaccia grafica.
    Scaricati i sorgenti, bisogna scompattarli con il comando “tar -xvzf openvpn-*.tar.gz” e poi posizionarsi nella cartella “easy-rsa”.

    Aprire “vars” ed editare i valori alla fine del file secondo le proprie esigenze in modo da non dover riscrivere tutto ogni volta che si genera un certificato (la generazione prende questi valori come default).

    export KEY_COUNTRY=IT
    export KEY_PROVINCE=FVG
    export KEY_CITY=TRIESTE
    export KEY_ORG="Nome Organizzazione"
    export KEY_EMAIL="
    me@myhost.mydomain"

    Editate queste informazioni, bisogna eseguire alcuni scripts. Quando verrà richiesto di inserire il “Common Name”, inserire l’hostname del server pfsense (si trova in “General Setup” della configurazione del pfsense).

    [/path/easy-rsa]# source ./vars
    [/path/easy-rsa]# ./clean-all
    [/path/easy-rsa]# ./build-ca

    Country Name (2 letter code) [IT]: (premere invio)
    State or Province Name (full name) [FVG]: (premere invio)
    Locality Name (eg, city) [TRIESTE]): (premere invio)
    Organization Name (eg, company) [Nome Ogranizzazione]: (premere invio)
    Organizational Unit Name (eg, section) [ ]:( premere invio o inserire la unit name)
    Common Name (eg, your name or your server's hostname) [ ]:HostnamePFSENSE
    Email Address [me@myhost.mydomain]: (premere invio)

    Nello script seguente bisogna inserire “server” come Common Name. Premere “y” per firmare il certificato.

    [/path/easy-rsa]# ./build-key-server server

    Poi si devono generare i parametri DH:

    [/path /easy-rsa]# ./build-dh

    Infine, i certificati per i client (al posto di client1, client2, ecc si possono inserire i nomi dei client o qualsiasi cosa che identifichi il destinatario del certificato):

    [/path /easy-rsa]# ./build-key client1
    [/path /easy-rsa]#
    ./build-key client2
    [/path /easy-rsa]# ./build-key client3

    Si possono creare quanti certificati client si vogliono. Se si deve successivamente creare un certificato client nuovo, basta farlo con ./build-key client_name. È tassativo usare sempre un nome diverso per ogni certificato. I certificati vanno creati tutti nella stessa cartella, altrimenti non funzioneranno (eventualmente fare il backup della cartella dei certificati, in modo da poterne generare altri senza dover rifare e reinstallare i certificati server).

    Creazione dei certificati su Windows
    Per generare i certificati su macchine windows si possono utilizzare diversi programmi, ma quello piu semplice ed immediato è “My Certificate Wizard” (http://www.openvpn.se/mycert/)

    Si devono generare tre tipi di certificati: Certificate Autorità (CA), server e client.
    NB: è necessario aver installato una versione di OpenVPN

    Generare il certificato della Certificate Authority (CA) e la sua chiave
    Aprire un prompt di dos e posizionarsi in \Program Files\OpenVPN\easyrsa.
    Eseguire il seguente filebatch file per copiare i file di configurazione (il comando sovrascriverà i file vars.bat e openssl.cnf eventualmente presenti nella cartella):

    init-config

    Editare il file vars.bat impostando i seguenti valori senza lasciare alcun valore vuoto:

    export KEY_COUNTRY=IT
    export KEY_PROVINCE=FVG
    export KEY_CITY=TRIESTE
    export KEY_ORG="Nome Organizzazione"
    export KEY_EMAIL="
    me@myhost.mydomain"

    Poi, inizializzare il PKI con i comandi:

    vars
    clean-all
    build-ca

    L’ultimo comando (build-ca) creerà il certificato per la certificate authority (CA) e la sua chiave invocando l’eseguibile openssl che si trova nella cartella bin dell’installazione di OpenVPN. In alcuni sistemi questo path non è riconosciuto come valido, quindi se i seguenti comandi generano un errore di “Invalid command name”, bisogna editare i file .bat sostituendo a “openssl” il percorso completo (ad esempio “C:\Programmi\OpenVPN\bin\openssl”):

    c:\program files\openvpn\easy-rsa\build-ca

    Generating a 1024 bit RSA private key
    ............++++++

    ............++++++
    writing new private key to 'ca.key
    '

    Verrà richiesto l’inserimento dei valori di configurazione del certificato, alcuni gia impostati di default (li prende dal file vars.bat). Per lasciare una campo vuoto, inserire un punto ( “.” ).
    Nel Common Name inserire un valore che richiami il fatto che quello che si sta generando è il certificato per la certificate autorità (ad esempio OpenVPN-CA)

    Generare il certificato per il server e la sua chiave
    Per la generazione del certificato server utilizzare il seguente comando, sempre dal prompt:

    build-key-server server

    Come nello step precedente, molti parametri saranno impostati di default. Quando sarà richiesto il Common Name, inserire "server". Rispondere infine “y” alle domande proposte:

    "Sign the certificate? [y/n]" per firmare il certificato e
    "1 out of 1 certificate requests certified, commit? [y/n]" per avviare la generazione

    Generare i certificati per i client
    Generare i certificati per i client è molto simile al passaggio precedente, solamente si usa un altro comando:

    build-key client1
    build-key client2
    build-key client3

    Se si vuole anche proteggere con password le chiavi, utilizzare il comando build-keypass al posto di build-key.
    Per ogni client è necessario inserire il Common Name appropriato. È tassativo usare sempre un nome diverso per ogni certificato. I certificati vanno creati tutti nella stessa cartella, altrimenti non funzioneranno (eventualmente fare il backup della cartella dei certificati, in modo da poterne generare altri senza dover rifare e reinstallare i certificati server).

    Generare i paramenti Diffie Hellman (DH)
    Per il server OpenVPN devono essere anche generati i parametri Diffie Hellman (DH).

    build-dh

    Generating DH parameters, 1024 bit long safe prime, generator 2
    This is going to take a long time

    .................+...........................................

    ...................+.............+.................+.........
    ......................................

    A questo punto abbiamo generato tutti i file necessari e si trovano tutti nella stessa cartella.

    IMPOSTARE LA VPN PER I CLIENT REMOTI
    Creati i certificati, è possibile configurare OpenVPN per la connessione dei client. Ciccare sul menu VPN à OpenVPN e poi sulla piccola icona “+” del tab “Server” per aggiungere una nuova connessione VPN server.

    Come si può vedere, è impostato come protocollo “TCP”, questo perché è noto che UDP può aver problemi con alcuni router. Il TCP è leggermente più lento, ma per il momento è l’unico che assicura il 100% di compatibilità.

    Abilitare il “Dynamic IP”. In questo modo i client possono connettersi anche senza impostare manualmente un indirizzo ip della rete.

    “Address pool” deve essere una sottorete indipendente che non è utilizzata in alcun segmento di rete esistente. Questo è molto importante, altrimenti si possono provocare conflitti di indirizzi IP e, nel migliore dei casi, comunque la VPN non funzionerebbe.

    Cambiare il “Authentication method” impostando PKI (Public Key Infrastructure).

    A questo punto bisogna incollare il testo dei certificati e delle chiavi negli appositi box. Aprire con un editor di testo i file specificati e copiare il contenuto includendo:

    -----BEGIN CERTIFICATE-----
    &
    -----END CERTIFICATE----

    Dopo aver copiato i certificati e le chiavi, disattivare “LZO-Compression” (eventualmente sarà possibile riabilitarla una volta verificato il funzionamento della VPN). Alla fine cliccare su “SAVE”.
    NB: Per permettere ai client di connettersi anche su altre reti al di fuori della LAN impostata, bisogna inserire una rotta nel campo “Custom options”. Supponendo ad esempio di voler connettersi anche alla DMZ, con indirizzo 192.168.2.0/24, bisogna scrivere:

    push “route 192.168.100.0 255.255.255.0”

    Regole sul firewall
    Per fare in modo che i client si connettano al server OpenVPN, bisogna creare una regola che permetta alle connessioni in entrata sull’interfaccia WAN di accedere alla porta 1194 (o quella impostata per la VPN, se è stata cambiata)

    Scegliere il menu “Firewall > Rules”, cliccare sul tab “WAN” e infine sulla piccola icona “+” per aggiungere una nuova regola.

    Come Protocollo inserire “TCP” oppure “UDP” a seconda del protocollo scelto precedentemente nella definizione del server.

    “Destination port range” è la porta in ascolto del server OpenVPN, di default la 1194.

    Cliccando su “Save” le modifiche verranno salvate.

    CONFIGURAZIONE DEI CLIENT
    Dopo aver configurato il server, è necessario creare i file di configurazione per i client, in modo che possano connettersi da qualsiasi parte del mondo.
    NB: ovviamente, i client devono aver installata una versione client di OpenVPN.

    Creare un file di testo con il nome “nomeclient.ovpn” e inserire il testo di configurazione seguente:

    float
    port 1194
    dev tun
    proto tcp-client
    remote IpPubblicoDiConnessione 1194
    ping 10
    persist-tun
    persist-key
    tls-client
    ca ca.crt
    cert client1.crt
    key client1.key
    ns-cert-type server
    #comp-lzo
    pull
    verb 4


    Eventualmente rimuovere il # se la comprezzione lzo è stata abilitata nella configurazione del server.

    Inoltre è necessario copiare i certificati generati precedentemente nella stessa cartella del file appena creato. I file da copiare sono il certificato della Certificate Autority (CA), il certificato del client e la sua chiave. (Ad esempio “ca.crt”, “client1.crt” e “client1.key”).

    Il procedimento è finito. Per poter urilizzare la VPN basterà cliccare con il tasto destro sul file ovpn e scegliere la voce "Start OpenVPN with this file".