oops… » « HP
e agora para algo completamente rush
19/Fev/2008 @ 05:40 Informática

Ando aqui de volta do Linux + qmail MySQL + WIndows + MS SQL SERVER + IIS + ASP.NET
A ideia é a partir de uma página em Windows, ASP.NET e IIS, criar (e apagar, etc.) contas de email num servidor Linux a correr qmail.

Já está quase tudo montado, embora a granel (a versão final não vos mostro :P)

  • No servidor Linux, instala-se o qmail + vpopmail com autenticação por MySQL e Courier-IMAP com autenticação por vpopmail. Fica criada a seguinte tabela:mysql> select * from vpopmail;
    pw_name | pw_domain | pw_passwd | pw_uid | pw_gid | pw_gecos | pw_dir | pw_shell |
    (...)
  • Agora no nosso desktop onde temos o Visual Studio, instalamos o MySQL .NET da CoreLab (150 USD) e no servidor, o Microsoft Data Access Components (MDAC) ≥ 2.6 e o .NET Framework ≥ 2.0. Isto permite-nos em qualquer das linguagens aceder directamente a uma base de dados MySQL em ASP.NET
    No Visual Studio ficamos com novas ferramentas:

  • Agora o código em C#, muita tosco e sem segurança, mas que dá para testar:
    protected void tButton_Click(object sender, EventArgs e)
    {
    // Ligar ao MS SQL SERVER do servidor Windows
    SqlConnection MyConnection = new SqlConnection("Server=192.168.1.31;" + "DataBase=vpopmail;" + "User ID=sa;" + "Password=segredo;");
    try
    {
    MyConnection.Open();
    SqlCommand cmd = new SqlCommand("INSERT INTO vpopmail (pw_name, pw_domain) VALUES ('" + tName.Text + "', 'foobar.lan')", MyConnection);
    cmd.ExecuteNonQuery();
    }catch (Exception MyException)
    {
    Response.Write("Connection Error: SQL code: " + MyException.Message);
    }
    MyConnection.Close();
    InsertRow();
    }
    public void InsertRow()
    {
    string myConnectionString;
    myConnectionString = "";
    if (myConnectionString == "")
    {
    myConnectionString = "User Id=vpopmail;Host=192.168.1.4;Database=vpopmail;Password=segredo";
    }
    // Ligar ao MySQL do servidor Linux
    MySqlConnection myConn = new MySqlConnection(myConnectionString);
    string myInsertQuery = "INSERT INTO vpopmail(pw_name, pw_domain, pw_passwd, pw_gecos, pw_shell, pw_clear_passwd) Values('" + tName.Text + "', 'foobar.lan'), '" + tName.Text + "', '1048576000')";
    MySqlCommand myCommand = new MySqlCommand(myInsertQuery);
    myCommand.Connection = myConn;
    myConn.Open();
    try
    {
    myCommand.ExecuteNonQuery();
    }
    catch (Exception MyException)
    {
    Response.Write("Connection Error: MySQL code: " + MyException.Message);
    }
    myConn.Close();
    }
  • Com isto, fica inserido no MS SQL SERVER o username e o domínio e no MySQL do Linux é preenchida a tabela vpopmail. Por exemplo, se inserirmos no formulário de registo o username manel e a password 123qwe, ficamos com:mysql> select * from vpopmail where pw_name='manel';
    +---------+-----------+-----------+--------+--------+----------+--------+----------+
    | pw_name | pw_domain | pw_passwd | pw_uid | pw_gid | pw_gecos | pw_dir | pw_shell | +---------+-----------+-----------+--------+--------+----------+--------+----------+
    | manel | foobar.lan | | 0 | 0 | manel | | NOQUOTA | | | | |---------+-----------+-----------+--------+--------+----------+--------+----------+
    1 row in set (0.00 sec)
  • Aqui há gato, dirá o leitor. Onde está a password e o directório dos emails ? A password não está no MySQL e o directório do manel não existe:

    $ pwd
    /home/vpopmail/domains/foobar.lan

    $ ll
    total 6
    drwx—— 3 vpopmail vchkpw 4096 Feb 18 21:10 augusto
    drwx—— 3 vpopmail vchkpw 4096 Feb 12 08:04 gamito
    drwx—— 3 vpopmail vchkpw 4096 Feb 18 18:41 jac
    drwx—— 3 vpopmail vchkpw 4096 Feb 12 05:39 mario
    drwx—— 3 vpopmail vchkpw 4096 Feb 18 18:22 mariogamito
    drwx—— 3 vpopmail vchkpw 4096 Feb 11 09:34 postmaster

    Calma, o vpopmail está configurado para uma vez tendo, no mínimo, o username e o domínio no MySQL, quando o utilizador aceder a primeira vez ao email, é criado o directório e fica com a password que der no login. Vamos enviar-lhe uma mensagem e depois lê-la:

    $ telnet mail.foobar.lan 25
    Trying 192.168.1.4…
    Connected to mail.foobar.lan (192.168.1.4).
    Escape character is ‘^]’.
    220 mail.foobar.lan ESMTP
    EHLO mail.foobar.lan
    250-mail.foobar.lan
    250-PIPELINING
    250 8BITMIME
    MAIL FROM: root@foobar.lan
    250 ok
    RCPT TO: manel@foobar.lan
    250 ok
    DATA
    354 go ahead
    Ola Manel
    .
    250 ok 1203373765 qp 23380
    quit
    221 mail.foobar.lan
    Connection closed by foreign host.

    Agora, o Manel vai lê-la:

    $ telnet mail.foobar.lan 110
    Trying 192.168.1.4…
    Connected to mail.foobar.lan (192.168.1.4).
    Escape character is ‘^]’.
    +OK <23395.1203373858@mail.foobar.lan>
    user manel@foobar.lan
    +OK
    pass segredo
    +OK
    list
    +OK
    1 818
    .
    retr 1
    +OK
    Return-Path:
    Delivered-To: manel@foobar.lan
    Received: (qmail 20501 invoked by uid 510); 18 Feb 2008 22:33:19 -0000
    Received: from 192.168.1.31 by cruzador (envelope-from , uid 0) with qmail-scanner-2.01
    (f-prot: 4.6.7/3.16.15. spamassassin: 3.2.3.
    Clear:RC:1(192.168.1.31):.
    Processed in 0.014554 secs); 18 Feb 2008 22:33:19 -0000
    Received: from unknown (HELO ?192.168.1.31?) (192.168.1.31)
    by 0 with SMTP; 18 Feb 2008 22:33:18 -0000
    Message-ID: <47B153CB.5070301@foobar.lan>
    Date: Tue, 18 Feb 2008 22:33:39 +0000
    To: manel@foobar.lan
    Content-Type: text/plain; charset=ISO-8859-1; format=flowed
    Content-Transfer-Encoding: 7bit

    Ola Manel
    .
    quit
    +OK
    Connection closed by foreign host.

    É necessário chamar código em PHP a partir do MySQL do servidor Linux para fazer o hash da password:

    <?php
    function randltr() {
    $retval = 'a';
    $rand = rand() % 64;
    if ($rand < 26) $retval = $rand + 'a';
    if ($rand > 25) $retval = $rand - 26 + 'A';
    if ($rand > 51) $retval = $rand - 52 + '0';
    if ($rand == 62) $retval = ';';
    if ($rand == 63) $retval = '.';
    return($retval);
    }
    function mkpasswd3(&$clearpass, &$crypted) {
    srand ((double)microtime()*1000000);
    $salt = '$1$';
    for ($i = 0; $i < 5; $i++) $salt .= randltr();
    $salt .= '0';
    $crypted = crypt($clearpass, $salt);
    if (strlen($crypted) > 0) return(true);
    return(false);
    }
    ?>
    // Obter a password:
    <?php
    $clearpass = 'testtest'
    $crypted = '';
    if (mkpasswd3($clearpass, $crypted)) printf("%s -> %s\n", $clearpass, $crypted);
    else echo("Ohoh");
    ?>

    Vejamos de novo a base de dados e o filesystem:mysql> select * from vpopmail where pw_name='manel';
    +---------+-----------+-----------+--------+--------+----------+--------+
    | pw_name | pw_domain | pw_passwd | pw_uid | pw_gid | pw_gecos | pw_dir | pw_shell |
    +---------+-----------+-----------+--------+--------+----------+--------+
    | manel | foobar.lan |$1$r0vwJd43$C5hLXh8oGxfHIoQyinjOx/ | 0 | 0 | manel | /home/vpopmail/(...)new| NOQUOTA | |
    +---------+-----------+-----------+--------+--------+----------+--------+ 1 row in set (0.00 sec)

    Agora, o file system:

    $ pwd
    /home/vpopmail/domains/foobar.lan/gamito/Maildir/new

    $ ls
    1202803579.20504.cruzador

    Já está :)

Claro que isto ainda está tudo às três pancadas só para testes, mas já dá para terem uma ideia.

-MG
rss não há pás de carvão neste artigo, atira-lhe uma
atira-lhe uma pá de carvão

Nota: Todos os comentários são moderados.