version 0.2 of the MySQL module

Karjala karjala_lists at karjala.org
Mon Jul 3 17:32:52 UTC 2006


Supports "can_retrieve_cleartext" when encrypted passwords are disabled

Tested with GAIM and Pandion, works with both encrypted and unencrypted 
passwords.

I noticed two things:

1) DJabberd will not accept passwords to be sent cleartext over 
unencrypted connections. Is that true?

2) Second, the buddy groups I create with non-english characters in 
their names, appear garbled on the client, as if they're being encoded 
to unicode a second time. Maybe that's a problem with the old version of 
Perl I have (5.8.4), although that's the standard Debian Perl. I don't 
have this problem with jabberd 1.4, and in case this problem can be 
solved (I've seen it a number of times in my programs, it happens when 
you try to concatenate or interpolate a string that Perl thinks it's not 
unicode. It's fixable. Do you have the same problem? I have it with 
greek group names)


Brad Fitzpatrick wrote:
> Nice.
>
> Can you make it support "can_retrieve_cleartext" when encrypted passwords
> are disabled?
>
> Because as is, your module only supports the weakest type of auth, which
> requires users passwords to going flying about, and a lot of Jabber
> clients complain loudly about that.
>
> If you're able to give DJabberd the plaintext password, though, it will do
> all the challenge/response type stuff so clients don't complain.
>
> - Brad
>

-------------- next part --------------
package DJabberd::Authen::MySQL;
use strict;
use base 'DJabberd::Authen';

use DJabberd::Log;
our $logger = DJabberd::Log->get_logger;
use DBI;
sub log {
    $logger;
}

=head1 NAME

DJabberd::Authen::MySQL - A MySQL authentication module for DJabberd

=head1 VERSION

Version 0.20

=head1 SYNOPSIS

	<VHost mydomain.com>

		[...]

		<Plugin DJabberd::Authen::MySQL>
			DBName		mydbname
			DBHost		192.168.12.35	# optional
			DBPort		6723			# optional
			DBUserName	adbuser
			DBPassword	somepass
			DBTable		djusers
			DBUsernameColumn	djusername
			DBPasswordColumn	djpassword
			DBEncryptedPassword	0		# optional
			DBWhere		canjabber = 1		# optional
		</Plugin>
	</VHost>

=cut

sub set_config_dbname {
    my ($self, $dbname) = @_;
    $self->{'mysql_dbname'} = $dbname;
}

sub set_config_dbusername {
    my ($self, $dbusername) = @_;
    $self->{'mysql_dbusername'} = $dbusername;
}

sub set_config_dbpassword {
    my ($self, $dbpassword) = @_;
    $self->{'mysql_dbpassword'} = $dbpassword;
}

sub set_config_dbhost {
    my ($self, $dbhost) = @_;
    $self->{'mysql_dbhost'} = $dbhost;
}

sub set_config_dbport {
    my ($self, $dbport) = @_;
    $self->{'mysql_dbport'} = $dbport;
}

sub set_config_dbtable {
    my ($self, $dbtable) = @_;
    $self->{'mysql_table'} = $dbtable;
}

sub set_config_dbusernamecolumn {
    my ($self, $dbusernamecolumn) = @_;
    $self->{'mysql_usernamecolumn'} = $dbusernamecolumn;
}

sub set_config_dbpasswordcolumn {
    my ($self, $dbpasswordcolumn) = @_;
    $self->{'mysql_passwordcolumn'} = $dbpasswordcolumn;
}

sub set_config_dbencryptedpassword {
    my ($self, $dbencryptedpassword) = @_;
    $self->{'mysql_encryptedpassword'} = $dbencryptedpassword;
}

sub set_config_dbwhere {
    my ($self, $dbwhere) = @_;
    $self->{'mysql_where'} = $dbwhere;
}

sub finalize {
    my $self = shift;
	my $dsn = "DBI:mysql:database=$self->{'mysql_dbname'}";
	if (defined $self->{'mysql_dbhost'}) { $dsn .= ";host=$self->{'mysql_dbhost'}"; }
	if (defined $self->{'mysql_dbport'}) { $dsn .= ";port=$self->{'mysql_dbport'}"; }
	my $dbh = DBI->connect($dsn, $self->{'mysql_dbusername'}, $self->{'mysql_dbpassword'}, { RaiseError => 1 });
	$self->{'mysql_dbh'} = $dbh;
}

sub can_retrieve_cleartext {
	my $self = shift;
	return $self->{'mysql_encryptedpassword'} ? 0 : 1;
}

sub get_password {
	my ($self, $cb, %args) = @_;

	my $user = $args{'username'};
	my $dbh = $self->{'mysql_dbh'};

	my $sql_username = "select $self->{'mysql_usernamecolumn'}, $self->{'mysql_passwordcolumn'} from $self->{'mysql_table'} where $self->{'mysql_usernamecolumn'} = ".$dbh->quote($user);
	my $sql_where = (defined $self->{'mysql_where'} ? " and $self->{'mysql_where'}" : "");

	my ($username, $password) = $dbh->selectrow_array("$sql_username $sql_where");
	if (defined $username) {
		$cb->set($password);
		return;
	}
	$cb->decline;
}

sub check_cleartext {
    my ($self, $cb, %args) = @_;
    my $username = $args{username};
    my $password = $args{password};
    my $conn = $args{conn};
    unless ($username =~ /^\w+$/) {
        $cb->reject;
        return;
    }


	my $dbh = $self->{'mysql_dbh'};
	my $sql_username = "select $self->{'mysql_usernamecolumn'} from $self->{'mysql_table'} where $self->{'mysql_usernamecolumn'} = ".$dbh->quote($username);
	my $sql_password = " and $self->{'mysql_passwordcolumn'} = ".($self->{'mysql_encryptedpassword'} ? "PASSWORD(".$dbh->quote($password).")" : $dbh->quote($password));
	my $sql_where = (defined $self->{'mysql_where'} ? " and $self->{'mysql_where'}" : "");

	if (defined(($dbh->selectrow_array("$sql_username $sql_password $sql_where"))[0])) {
		$cb->accept;
		$logger->debug("User '$username' successfully logged in");
		return 1;
	} else {
		$cb->reject();
		if (defined(($dbh->selectrow_array("$sql_username $sql_where"))[0])) { # if user exists
			$logger->info("User '$username' denied, password error");
			return 0;
		} else {
			$logger->info("User '$username' denied, does not exist in database");
		    return 1;
		}
	}
}

1;


More information about the Djabberd mailing list