Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of mysql passwords with weird characters in it #2660

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gitlab/base.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fi

# Generate a dbpasswords file
# Note that this does not use ${DATABASE_NAME} since Symfony adds the _test postfix itself
echo "unused:sqlserver:domjudge:domjudge:domjudge:3306" > etc/dbpasswords.secret
echo 'unused:sqlserver:domjudge:domjudge:domjudge_+% #$*)@(!/;,.:3306' > etc/dbpasswords.secret

# Generate APP_SECRET for symfony
# shellcheck disable=SC2164
Expand Down
60 changes: 47 additions & 13 deletions sql/dj_setup_database.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# @configure_input@

# This script allows one to perform DOMjudge database setup actions.
Expand Down Expand Up @@ -29,6 +29,7 @@ Commands:
status check database installation status
genpass generate DB,API,Symfony,admin password files
create-db-users create (empty) database and users
update-password update DB user database to that in 'etc/dbpasswords.secret'
install create database, example contest and users if not existing
bare-install create database, setup defaults if not existing
uninstall remove database users and database, INCLUDING ALL DATA!
Expand All @@ -51,32 +52,47 @@ not have to pass any of the options above.
EOF
}

urlencode()
{
php -r "echo rawurlencode('$1');"
}

# This is global variable to be able to return the output from
# mysql_options() below as an array, which is not possible otherwise.
declare -a _mysql_options

mysql_options()
{
local user pass
_mysql_options=()

# shellcheck disable=SC2153
if [ -n "$DBUSER" ]; then
user="-u $DBUSER"
else
user="${DBA_USER:+-u ${DBA_USER}}"
_mysql_options+=('-u' "$DBUSER")
elif [ -n "$DBA_USER" ]; then
_mysql_options+=('-u' "$DBA_USER")
fi
# shellcheck disable=SC2153
if [ -n "$PASSWD" ]; then
pass="-p$PASSWD"
else
[ -n "$PROMPT_PASSWD" ] && pass="-p"
[ -n "$DBA_PASSWD" ] && pass="-p$DBA_PASSWD"
_mysql_options+=("-p$PASSWD")
elif [ -n "$DBA_PASSWD" ]; then
_mysql_options+=("-p$DBA_PASSWD")
elif [ -n "$PROMPT_PASSWD" ]; then
_mysql_options+=('-p')
fi

[ -z "$USE_SOCKET" ] && port="-P$DBPORT"
echo $user ${pass:+"$pass"} -h "$DBHOST" ${port:+"$port"}
_mysql_options+=('-h' "$DBHOST")

if [ -z "$USE_SOCKET" ]; then
_mysql_options+=("-P$DBPORT")
fi
}

# Wrapper around mysql command to allow setting options, user, etc.
mysql()
{
command mysql $(mysql_options) --silent --skip-column-names "$@"
mysql_options
command mysql "${_mysql_options[@]}" --silent --skip-column-names "$@"
}

# Quick shell hack to get a key from an INI file.
Expand Down Expand Up @@ -127,10 +143,13 @@ symfony_console()
fi

if [ -n "$DBA_USER" ]; then
user=$(urlencode "${DBA_USER}")
host=$(urlencode "${domjudge_DBHOST}")
db=$(urlencode "${domjudge_DBNAME}")
if [ -n "$DBA_PASSWD" ]; then
DATABASE_URL=mysql://${DBA_USER}:${DBA_PASSWD}@${domjudge_DBHOST}:${domjudge_DBPORT}/${domjudge_DBNAME}
DATABASE_URL="mysql://$user:$(urlencode "${DBA_PASSWD}")@$host:${domjudge_DBPORT}/$db"
else
DATABASE_URL=mysql://${DBA_USER}@${domjudge_DBHOST}:${domjudge_DBPORT}/${domjudge_DBNAME}
DATABASE_URL="mysql://$user@$host:${domjudge_DBPORT}/$db"
fi
fi
fi
Expand Down Expand Up @@ -235,6 +254,17 @@ remove_db_users()
verbose "DOMjudge database and user(s) removed."
}

update_password()
{
read_dbpasswords
(
echo "ALTER USER '$domjudge_DBUSER'@'localhost' IDENTIFIED BY '$domjudge_PASSWD';"
echo "FLUSH PRIVILEGES;"
) | mysql
verbose "ALTER USER '$domjudge_DBUSER'@'localhost' IDENTIFIED BY '$domjudge_PASSWD';"
verbose "Database user password updated from credentials file."
}

install_examples()
{
DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-example-data
Expand Down Expand Up @@ -337,6 +367,10 @@ create-db-users)
create_db_users_helper
;;

update-password)
update_password
;;

bare-install|install)
read_dbpasswords
create_db_users
Expand Down
6 changes: 5 additions & 1 deletion webapp/config/load_db_secrets.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php declare(strict_types=1);

Check warning on line 1 in webapp/config/load_db_secrets.php

View workflow job for this annotation

GitHub Actions / phpcs

A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 11 and the first side effect is on line 9.

Check warning on line 1 in webapp/config/load_db_secrets.php

View workflow job for this annotation

GitHub Actions / phpcs

A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 11 and the first side effect is on line 9.

Check warning on line 1 in webapp/config/load_db_secrets.php

View workflow job for this annotation

GitHub Actions / phpcs

A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 11 and the first side effect is on line 9.

Check warning on line 1 in webapp/config/load_db_secrets.php

View workflow job for this annotation

GitHub Actions / phpcs

A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 11 and the first side effect is on line 9.

// This file fetches credentials on the fly from files in etc.
// These settings can later be overridden by Symfony files
Expand Down Expand Up @@ -36,7 +36,11 @@
break;
}

return sprintf('mysql://%s:%s@%s:%d/%s?serverVersion=5.7.0', $user, $pass, $host, $port ?? 3306, $db);
return sprintf(
'mysql://%s:%s@%s:%d/%s?serverVersion=5.7.0',
rawurlencode($user), rawurlencode($pass), rawurlencode($host),
$port ?? 3306, rawurlencode($db)
);
}

function get_app_secret(): string
Expand Down
2 changes: 1 addition & 1 deletion webapp/config/packages/doctrine.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ doctrine:
charset: utf8mb4
collate: utf8mb4_unicode_ci

url: '%env(resolve:DATABASE_URL)%'
url: '%env(DATABASE_URL)%'
profiling_collect_backtrace: '%kernel.debug%'
types:
tinyint: App\Doctrine\DBAL\Types\TinyIntType
Expand Down
Loading