#! /usr/bin/perl
# -*- indent-tabs-mode: nil; -*-
# vim:ft=perl:et:sw=4
# $Id: upgrade_sympa_password.pl.in 12677 2016-02-13 03:22:57Z sikeda $

# Sympa - SYsteme de Multi-Postage Automatique
#
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 GIP RENATER
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

use lib split(/:/, $ENV{SYMPALIB} || ''), '/usr/local/libdata/perl5/site_perl';
use strict;
use warnings;

use Conf;
use Sympa::DatabaseManager;
use Sympa::Tools::Password;
use Sympa::User;

die "Crypt::CipherSaber not installed ; cannot crypt passwords"
    unless $Crypt::CipherSaber::VERSION;
die 'Error in configuration'
    unless Conf::load(Conf::get_sympa_conf(), 'no_db');
my $sdm = Sympa::DatabaseManager->instance
    or die 'Can\'t connect to database';

print "Recoding password using MD5 fingerprint.\n";

my $sth = $sdm->do_query(q{SELECT email_user, password_user from user_table});
unless ($sth) {
    die 'Unable to prepare SQL statement';
}

my $total     = 0;
my $total_md5 = 0;

while (my $user = $sth->fetchrow_hashref('NAME_lc')) {
    my $clear_password;

    # Ignore empty passwords
    next
        unless defined $user->{'password_user'}
            and length $user->{'password_user'};

    if ($user->{'password_user'} =~ /^[0-9a-f]{32}/) {
        printf "Password from %s already encoded as md5 fingerprint\n",
            $user->{'email_user'};
        $total_md5++;
        next;
    }

    if ($user->{'password_user'} =~ /^crypt.(.*)$/) {
        $clear_password = Sympa::Tools::Password::decrypt_password(
            $user->{'password_user'});
    } else {    ## Old style cleartext passwords
        $clear_password = $user->{'password_user'};
    }

    $total++;

    ## Updating Db
    unless (
        $sdm->do_prepared_query(
            q{UPDATE user_table
              SET password_user = ?
              WHERE email_user = ?},
            Sympa::User::password_fingerprint($clear_password),
            $user->{'email_user'}
        )
        ) {
        die 'Unable to execute SQL statement';
    }
}
$sth->finish();

printf
    "Updating password storage in table user_table using md5 for %d users.\n",
    $total;
if ($total_md5) {
    printf
        "Found in table user %d password stored using md5, did you run Sympa before upgrading ?\n",
        $total_md5;
}

printf "Total password re-encoded using md5: %d\n", $total;

exit 0;

__END__

=encoding utf-8

=head1 NAME

upgrade_sympa_password, upgrade_sympa_password.pl -
Upgrading password in database

=head1 DESCRIPTION

Version later than 5.4 uses MD5 hash instead of
symetric encryption to store password.

This require to rewrite paassword in database. This upgrade IS NOT
REVERSIBLE.

=head1 HISTORY

As of Sympa 3.1b.7, passwords may be stored into user table with encrypted
form by reversible RC4.

Sympa 5.4 or later uses MD5 one-way hash function to encode user passwords.

=cut
