From 6c8bb6e0adc5797e0e239e65e68157fb4f54250e Mon Sep 17 00:00:00 2001 From: mvl22 Date: Tue, 17 Sep 2013 17:45:02 +0100 Subject: [PATCH] Refactor to components --- 1-install-base.sh | 273 +++++++++++++++++++++++++++++++++++ 2-install-bob.sh | 92 ++++++++++++ run.sh | 352 +--------------------------------------------- 3 files changed, 369 insertions(+), 348 deletions(-) create mode 100644 1-install-base.sh create mode 100644 2-install-bob.sh diff --git a/1-install-base.sh b/1-install-base.sh new file mode 100644 index 0000000..4d37a29 --- /dev/null +++ b/1-install-base.sh @@ -0,0 +1,273 @@ +#!/bin/bash +# Tested on SLES 12.0 with SDK installed +# This script is idempotent - it can be safely re-run without destroying existing data + + +# Installation of the base system (LAMP stack with SSL, Auth) + + +# Basic system software +zypper -n install -l findutils-locate man wget + +# Ensure we have Git +zypper -n install -l git-core + +# NTP +zypper -n install -l ntp +if ! grep -qe "${timeServer1}" /etc/ntp.conf ; then + echo "server ${timeServer1}" >> /etc/ntp.conf + echo "server ${timeServer2}" >> /etc/ntp.conf + echo "server ${timeServer3}" >> /etc/ntp.conf +fi +/etc/init.d/ntp restart + +# Install LAMP stack +zypper -n install -l apache2 apache2-devel mysql mysql-client php5 php5-suhosin php5-mysql apache2-mod_php5 +# Check versions using: +# /usr/sbin/httpd2 -v (2.2.21) +# /usr/bin/mysql -V (5.5.25) +# /usr/bin/php -v (5.3.8) + +# Start services +#!# SUSE doesn't complain if they are already started, but ideally these should check first +/etc/init.d/apache2 start +/etc/init.d/mysql start +# Can check run levels 3 & 5 are started, with: +# sudo /sbin/chkconfig -a apache2 +# sudo /sbin/chkconfig -a mysql + +# Secure MySQL, by setting the root password if no password is currently set; see: http://linuxtitbits.blogspot.co.uk/2011/01/checking-mysql-connection-status.html +set +e +mysql -u root --password='' -e ';' 2>/dev/null +dbstatus=`echo $?` +set -e +if [ $dbstatus -eq 0 ]; then + mysqladmin -u root password "${mysqlRootPassword}" +fi + +# Define the Apache layout norms for the distribution +apacheConfDirectory=/etc/apache2 +apacheVhostsConfigDirectory=/etc/apache2/vhosts.d +apacheDefaultDocumentRoot=/srv/www/htdocs +apacheLogFilesDirectory=/var/log/apache2 +apacheVhostsRoot=/srv/www/vhosts +apacheModulesDirectory=/usr/lib64/apache2 +apacheUser=wwwrun +apacheGroup=www +apacheSslKeyDirectory=/etc/apache2/ssl.key +apacheSslCrtDirectory=/etc/apache2/ssl.crt + +# Create a null vhost if it doesn't exist already, and restart +nullVhostFile="${apacheVhostsConfigDirectory}/000-null-vhost.conf" +if [ ! -r ${nullVhostFile} ]; then + cat > ${nullVhostFile} << EOF +# This is a null vhost which any unauthorised CNAMES fired at the machine will pick up + + ServerAdmin webmaster@example.com + ServerName localhost + DocumentRoot ${apacheDefaultDocumentRoot} + CustomLog ${apacheLogFilesDirectory}/null-host.example.com-access_log combined + ErrorLog ${apacheLogFilesDirectory}/null-host.example.com-error_log + HostnameLookups Off + UseCanonicalName Off + ServerSignature Off + + Options -Indexes + AllowOverride None + Order allow,deny + Allow from all + + +EOF +fi +sudo /etc/init.d/apache2 restart + +# Copy in the SSL key and certificate files if not already present +# For testing, create a self-signed key without a password using: +# openssl req -nodes -new -x509 -keyout vote.example.com.key -out vote.example.com.crt +if [ ! -r "${apacheSslKeyDirectory}/${domainName}.key" ] ; then + if [ ! -r "${sslCertificateKey}" ] ; then + echo "ERROR: The setup SSL key file is not present" + exit 1 + fi + cp -pr "${sslCertificateKey}" "${apacheSslKeyDirectory}/${domainName}.key" +fi +if [ ! -r "${apacheSslCrtDirectory}/${domainName}.crt" ] ; then + if [ ! -r "${sslCertificateCrt}" ] ; then + echo "ERROR: The setup SSL certificate file is not present" + exit 1 + fi + cp -pr "${sslCertificateCrt}" "${apacheSslCrtDirectory}/${domainName}.crt" +fi + +# Also add support for an optional SSL chain file +apacheSslCertificateChainDirective='' +if [ "${sslCertificateChain}" ] ; then + if [ ! -r "${apacheSslCrtDirectory}/${domainName}.chain.crt" ] ; then + if [ ! -r "${sslCertificateChain}" ] ; then + echo "ERROR: The setup SSL chain file is not present" + exit 1 + fi + cp -pr "${sslCertificateChain}" "${apacheSslCrtDirectory}/${domainName}.chain.crt" + fi + apacheSslCertificateChainDirective="SSLCertificateChainFile ${apacheSslCrtDirectory}/${domainName}.chain.crt" +fi + +# Add authentication support, either Raven or Basic Auth +# For Raven, see: https://raven.cam.ac.uk/project/apache/INSTALL +authModuleDirective='' +if [ "${ravenAuth}" == 'true' ] ; then + + # Compile the Ucam-webauth Apache module if required + if [ ! -r ${apacheModulesDirectory}/mod_ucam_webauth.so ]; then + latestUcamwebauthVersion='2.0.0' + cd /tmp + wget https://raven.cam.ac.uk/project/apache/files/mod_ucam_webauth-${latestUcamwebauthVersion}.tar.gz + tar zxf mod_ucam_webauth-${latestUcamwebauthVersion}.tar.gz + cd mod_ucam_webauth-${latestUcamwebauthVersion}/ + /usr/sbin/apxs2 -c -i -lcrypto mod_ucam_webauth.c + cd /tmp + rm -rf mod_ucam_webauth-${latestUcamwebauthVersion}/ + cd "${SCRIPTDIRECTORY}" + fi + + # Install Raven public key if not already present + if [ ! -r ${apacheConfDirectory}/webauth_keys/pubkey2 ]; then + mkdir -p ${apacheConfDirectory}/webauth_keys/ + wget -P ${apacheConfDirectory}/webauth_keys/ https://raven.cam.ac.uk/project/keys/pubkey2 + fi + + # Generate a cookie key for Raven auth; see: http://www.howtogeek.com/howto/30184/ + randpw(){ < /dev/urandom tr -dc A-Za-z0-9 | head -c${1:-16};echo;} + cookieKey=`randpw` + + # Define a directive to include the module in the Apache configuration + authModuleDirective=$'\n# Raven\n' + authModuleDirective+=$'LoadModule ucam_webauth_module /usr/lib64/apache2/mod_ucam_webauth.so\n' + authModuleDirective+='AAKeyDir '"${apacheConfDirectory}/webauth_keys/"$'\n' + authModuleDirective+='AACookieKey "'"${cookieKey}"$'"\n' + authModuleDirective+='AAClockSkew 30' + + # Generate the auth config + authConfig='AuthType Ucam-WebAuth + AADescription "Online voting" + AAForceInteract On' +else + # Create an auth file; users need to be added manually + authFile="${apacheVhostsConfigDirectory}/${domainName}.htpasswd" + if [ ! -r ${authFile} ]; then + touch $authFile + echo "Add users here by running: sudo /usr/bin/htpasswd2 ${authFile} username" >> ${authFile} + fi + + # Generate the auth config + authConfig='AuthName "Online voting" + AuthType Basic + AuthUserFile "'"${authFile}"'"' +fi + +# Create a vhost for the website if it doesn't exist already, and restart +vhostFile="${apacheVhostsConfigDirectory}/${domainName}.conf" +documentRoot="${apacheVhostsRoot}/${domainName}" +if [ ! -r ${vhostFile} ]; then + cat > ${vhostFile} << EOF +## Voting website + +# General server configuration +${authModuleDirective} + +# Lock down PHP environment +php_admin_value output_buffering 0 +php_admin_value expose_php 0 +php_admin_value file_uploads 0 + + +# Voting website (HTTPS) +Listen 443 +NameVirtualHost *:443 + + ServerAdmin ${serverAdmin} + ServerName ${domainName} + DocumentRoot ${documentRoot} + CustomLog /var/log/apache2/${domainName}_SSL-access_log combined + ErrorLog /var/log/apache2/${domainName}_SSL-error_log + HostnameLookups Off + UseCanonicalName Off + ServerSignature Off + + Options -Indexes + AllowOverride None + Order allow,deny + Allow from all + + + # SSL + SSLEngine on + SSLCertificateFile ${apacheSslCrtDirectory}/${domainName}.crt + SSLCertificateKeyFile ${apacheSslKeyDirectory}/${domainName}.key + ${apacheSslCertificateChainDirective} + + # Authentication + + ${authConfig} + Require valid-user + + + SetHandler AALogout + + + # Deny technical files being retrieved via a browser + + deny from all + + + deny from all + + + + +# Voting website (HTTP) +NameVirtualHost *:80 + + ServerAdmin ${serverAdmin} + ServerName ${domainName} + DocumentRoot ${documentRoot} + CustomLog /var/log/apache2/${domainName}-access_log combined + ErrorLog /var/log/apache2/${domainName}-error_log + HostnameLookups Off + UseCanonicalName Off + ServerSignature Off + + Options -Indexes + AllowOverride None + Order allow,deny + Allow from all + + + # Redirect all traffic to the SSL vhost (at which point authentication will occur) + Redirect permanent / https://${domainName}/ + + +EOF +fi + +# Create a group for web editors, who can edit the files +if ! grep -i "^${webEditorsGroup}\b" /etc/group > /dev/null 2>&1 ; then + groupadd "${webEditorsGroup}" +fi + +# Add the current user to the web editors' group, if not already in it +currentActualUser=`who am i | awk '{print $1}'` +if ! groups ${currentActualUser} | grep "\b${webEditorsGroup}\b" > /dev/null 2>&1 ; then + usermod -A "${webEditorsGroup}" "${currentActualUser}" +fi + +# Create the document root and let the web group write to it +mkdir -p "${documentRoot}" +chown nobody."${webEditorsGroup}" "${documentRoot}" +chmod g+ws "${documentRoot}" +umask 0002 + +# Restart the webserver +sudo /etc/init.d/apache2 restart + diff --git a/2-install-bob.sh b/2-install-bob.sh new file mode 100644 index 0000000..be6fc3f --- /dev/null +++ b/2-install-bob.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# Tested on SLES 12.0 with SDK installed +# This script is idempotent - it can be safely re-run without destroying existing data + + +# Installation of the voting component (BOB) + + +# Add the BOB software (the native voting component, without any setup management) +if [ ! -d ${documentRoot}/bob ] ; then + cd "${documentRoot}" + git clone https://github.com/cusu/bob.git +fi + +# Create a database binding +mysql="mysql -u root -p${mysqlRootPassword} -h localhost" + +# Use the database version of the boostrap file rather than the manual bootstap file +if [ -r "${documentRoot}"/bob/index-dbconfig.php ]; then + mv "${documentRoot}"/bob/index-dbconfig.php "${documentRoot}"/bob/index.php +fi + +# Add the database credentials to the bootstrap file (replace the lines matching on the left with the whole config string on the right) +sed -i \ +-e "s/.*'dbDatabase'.*/\$config['dbDatabase'] = '${bobDbDatabase}';/" \ +-e "s/.*'dbUsername'.*/\$config['dbUsername'] = '${bobDbUsername}';/" \ +-e "s/.*'dbSetupUsername'.*/\$config['dbSetupUsername'] = '${bobDbSetupUsername}';/" \ + "${documentRoot}"/bob/index.php + +# Put the password into the password file +echo -n "${bobDbPassword}" > "${documentRoot}"/bob/dbpass + +# Create the voting database +${mysql} -e "CREATE DATABASE IF NOT EXISTS ${bobDbDatabase} DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;" + +# Create database user privileges (which will create the users if they do not exist); see: https://github.com/cusu/bob/blob/master/BOB.php#L1436 +${mysql} -e "GRANT SELECT,INSERT,UPDATE ON ${bobDbDatabase}.* TO '${bobDbUsername}'@'localhost' IDENTIFIED BY '${bobDbPassword}';" +${mysql} -e "GRANT SELECT,CREATE ON ${bobDbDatabase}.* TO '${bobDbSetupUsername}'@'localhost' IDENTIFIED BY '${bobDbPassword}';" + +# Set up the instances table +cat > /tmp/instances.sql << \EOF +CREATE TABLE IF NOT EXISTS `instances` ( + `id` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'Generated globally-unique ID', + `title` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'Title of this ballot', + `urlMoreInfo` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'URL for more info about the ballot', + `afterVoteMessageHtml` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'An extra message, if any, which people will see when they have voted', + `emailReturningOfficer` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'E-mail address of Returning Officer / mailbox', + `emailTech` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'E-mail address of Technical Administrator', + `officialsUsernames` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'Usernames of Returning Officer + Sysadmins', + `randomisationInfo` enum('','Candidate order has been automatically randomised','Candidate order has been automatically alphabetised','Candidates have been entered by the Returning Officer in the order shown') collate utf8_unicode_ci default NULL COMMENT 'Candidate ordering/randomisation', + `adminDuringElectionOK` int(1) default '0' COMMENT 'Whether the administrator can access admin pages during the election', + `organisationName` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'Organisation name', + `organisationUrl` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'Organisation URL', + `organisationLogoUrl` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'URL of organisation''s logo', + `headerLocation` varchar(255) collate utf8_unicode_ci default '/style/prepended.html' COMMENT 'Header house style file', + `footerLocation` varchar(255) collate utf8_unicode_ci default '/style/appended.html' COMMENT 'Footer house style file', + `electionInfo` text collate utf8_unicode_ci NOT NULL COMMENT 'Election info: Number of positions being elected; Position title; Names of candidates; each block separated by one line break', + `referendumThresholdPercent` int(3) default '10' COMMENT 'Percentage of voters who must cast a vote in a referendum for the referendum to be countable', + `ballotStart` datetime NOT NULL COMMENT 'Start date/time of the ballot', + `ballotEnd` datetime NOT NULL COMMENT 'End date/time of the ballot', + `ballotViewable` datetime NOT NULL COMMENT 'Date/time when the cast votes can be viewed', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; +EOF +${mysql} ${bobDbDatabase} < /tmp/instances.sql +rm /tmp/instances.sql + +# Add a sample ballot +cat > /tmp/sampleballot.sql << EOF + +# Create the instance +DELETE FROM instances WHERE id = 'testelection' LIMIT 1; +INSERT INTO instances VALUES ( + 'testelection', 'Test election', NULL, NULL, '${serverAdmin}', '${serverAdmin}', '${sampleBallotUsername}', 'Candidate order has been automatically randomised', '0', 'My organisation', NULL, NULL, '', '', +'1 +President +BLAIR, Tony +THATCHER, Margaret +', '10', '2013-09-01', '2013-09-02', '2013-09-02' +); + +# Create the votes table +CREATE TABLE IF NOT EXISTS testelection_votes (token VARCHAR(32) collate utf8_unicode_ci NOT NULL PRIMARY KEY, v1p1 TINYINT(4), v1p2 TINYINT(4)) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci; + +# Create the voter table and insert one voter +CREATE TABLE IF NOT EXISTS testelection_voter (username VARCHAR(16) collate utf8_unicode_ci NOT NULL PRIMARY KEY, voted TINYINT(4) DEFAULT 0, forename VARCHAR(255) collate utf8_unicode_ci, surname VARCHAR(255) collate utf8_unicode_ci, unit VARCHAR(255) collate utf8_unicode_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci; +INSERT IGNORE INTO testelection_voter VALUES ('${sampleBallotUsername}', 0, 'Forename', 'Surname', 'My college'); + +EOF +${mysql} ${bobDbDatabase} < /tmp/sampleballot.sql +rm /tmp/sampleballot.sql + diff --git a/run.sh b/run.sh index a4cd31b..23d1198 100644 --- a/run.sh +++ b/run.sh @@ -8,7 +8,6 @@ # 2) Run yast (as root), and go to Software -> Add-On Products, then add the local path - # Narrate echo "# BOBGUI installation $(date)" @@ -43,352 +42,9 @@ touch ${setupLogFile} echo "# BOBGUI installation in progress, follow log file with: tail -f ${setupLogFile}" echo "# BOBGUI installation $(date)" >> ${setupLogFile} -# Basic system software -zypper -n install -l findutils-locate man wget - -# Ensure we have Git -zypper -n install -l git-core - -# NTP -zypper -n install -l ntp -if ! grep -qe "${timeServer1}" /etc/ntp.conf ; then - echo "server ${timeServer1}" >> /etc/ntp.conf - echo "server ${timeServer2}" >> /etc/ntp.conf - echo "server ${timeServer3}" >> /etc/ntp.conf -fi -/etc/init.d/ntp restart - -# Install LAMP stack -zypper -n install -l apache2 apache2-devel mysql mysql-client php5 php5-suhosin php5-mysql apache2-mod_php5 -# Check versions using: -# /usr/sbin/httpd2 -v (2.2.21) -# /usr/bin/mysql -V (5.5.25) -# /usr/bin/php -v (5.3.8) - -# Start services -#!# SUSE doesn't complain if they are already started, but ideally these should check first -/etc/init.d/apache2 start -/etc/init.d/mysql start -# Can check run levels 3 & 5 are started, with: -# sudo /sbin/chkconfig -a apache2 -# sudo /sbin/chkconfig -a mysql - -# Secure MySQL, by setting the root password if no password is currently set; see: http://linuxtitbits.blogspot.co.uk/2011/01/checking-mysql-connection-status.html -set +e -mysql -u root --password='' -e ';' 2>/dev/null -dbstatus=`echo $?` -set -e -if [ $dbstatus -eq 0 ]; then - mysqladmin -u root password "${mysqlRootPassword}" -fi - -# Define the Apache layout norms for the distribution -apacheConfDirectory=/etc/apache2 -apacheVhostsConfigDirectory=/etc/apache2/vhosts.d -apacheDefaultDocumentRoot=/srv/www/htdocs -apacheLogFilesDirectory=/var/log/apache2 -apacheVhostsRoot=/srv/www/vhosts -apacheModulesDirectory=/usr/lib64/apache2 -apacheUser=wwwrun -apacheGroup=www -apacheSslKeyDirectory=/etc/apache2/ssl.key -apacheSslCrtDirectory=/etc/apache2/ssl.crt - -# Create a null vhost if it doesn't exist already, and restart -nullVhostFile="${apacheVhostsConfigDirectory}/000-null-vhost.conf" -if [ ! -r ${nullVhostFile} ]; then - cat > ${nullVhostFile} << EOF -# This is a null vhost which any unauthorised CNAMES fired at the machine will pick up - - ServerAdmin webmaster@example.com - ServerName localhost - DocumentRoot ${apacheDefaultDocumentRoot} - CustomLog ${apacheLogFilesDirectory}/null-host.example.com-access_log combined - ErrorLog ${apacheLogFilesDirectory}/null-host.example.com-error_log - HostnameLookups Off - UseCanonicalName Off - ServerSignature Off - - Options -Indexes - AllowOverride None - Order allow,deny - Allow from all - - -EOF -fi -sudo /etc/init.d/apache2 restart - -# Copy in the SSL key and certificate files if not already present -# For testing, create a self-signed key without a password using: -# openssl req -nodes -new -x509 -keyout vote.example.com.key -out vote.example.com.crt -if [ ! -r "${apacheSslKeyDirectory}/${domainName}.key" ] ; then - if [ ! -r "${sslCertificateKey}" ] ; then - echo "ERROR: The setup SSL key file is not present" - exit 1 - fi - cp -pr "${sslCertificateKey}" "${apacheSslKeyDirectory}/${domainName}.key" -fi -if [ ! -r "${apacheSslCrtDirectory}/${domainName}.crt" ] ; then - if [ ! -r "${sslCertificateCrt}" ] ; then - echo "ERROR: The setup SSL certificate file is not present" - exit 1 - fi - cp -pr "${sslCertificateCrt}" "${apacheSslCrtDirectory}/${domainName}.crt" -fi - -# Also add support for an optional SSL chain file -apacheSslCertificateChainDirective='' -if [ "${sslCertificateChain}" ] ; then - if [ ! -r "${apacheSslCrtDirectory}/${domainName}.chain.crt" ] ; then - if [ ! -r "${sslCertificateChain}" ] ; then - echo "ERROR: The setup SSL chain file is not present" - exit 1 - fi - cp -pr "${sslCertificateChain}" "${apacheSslCrtDirectory}/${domainName}.chain.crt" - fi - apacheSslCertificateChainDirective="SSLCertificateChainFile ${apacheSslCrtDirectory}/${domainName}.chain.crt" -fi - -# Add authentication support, either Raven or Basic Auth -# For Raven, see: https://raven.cam.ac.uk/project/apache/INSTALL -authModuleDirective='' -if [ "${ravenAuth}" == 'true' ] ; then - - # Compile the Ucam-webauth Apache module if required - if [ ! -r ${apacheModulesDirectory}/mod_ucam_webauth.so ]; then - latestUcamwebauthVersion='2.0.0' - cd /tmp - wget https://raven.cam.ac.uk/project/apache/files/mod_ucam_webauth-${latestUcamwebauthVersion}.tar.gz - tar zxf mod_ucam_webauth-${latestUcamwebauthVersion}.tar.gz - cd mod_ucam_webauth-${latestUcamwebauthVersion}/ - /usr/sbin/apxs2 -c -i -lcrypto mod_ucam_webauth.c - cd /tmp - rm -rf mod_ucam_webauth-${latestUcamwebauthVersion}/ - cd "${SCRIPTDIRECTORY}" - fi - - # Install Raven public key if not already present - if [ ! -r ${apacheConfDirectory}/webauth_keys/pubkey2 ]; then - mkdir -p ${apacheConfDirectory}/webauth_keys/ - wget -P ${apacheConfDirectory}/webauth_keys/ https://raven.cam.ac.uk/project/keys/pubkey2 - fi - - # Generate a cookie key for Raven auth; see: http://www.howtogeek.com/howto/30184/ - randpw(){ < /dev/urandom tr -dc A-Za-z0-9 | head -c${1:-16};echo;} - cookieKey=`randpw` - - # Define a directive to include the module in the Apache configuration - authModuleDirective=$'\n# Raven\n' - authModuleDirective+=$'LoadModule ucam_webauth_module /usr/lib64/apache2/mod_ucam_webauth.so\n' - authModuleDirective+='AAKeyDir '"${apacheConfDirectory}/webauth_keys/"$'\n' - authModuleDirective+='AACookieKey "'"${cookieKey}"$'"\n' - authModuleDirective+='AAClockSkew 30' - - # Generate the auth config - authConfig='AuthType Ucam-WebAuth - AADescription "Online voting" - AAForceInteract On' -else - # Create an auth file; users need to be added manually - authFile="${apacheVhostsConfigDirectory}/${domainName}.htpasswd" - if [ ! -r ${authFile} ]; then - touch $authFile - echo "Add users here by running: sudo /usr/bin/htpasswd2 ${authFile} username" >> ${authFile} - fi - - # Generate the auth config - authConfig='AuthName "Online voting" - AuthType Basic - AuthUserFile "'"${authFile}"'"' -fi - -# Create a vhost for the website if it doesn't exist already, and restart -vhostFile="${apacheVhostsConfigDirectory}/${domainName}.conf" -documentRoot="${apacheVhostsRoot}/${domainName}" -if [ ! -r ${vhostFile} ]; then - cat > ${vhostFile} << EOF -## Voting website - -# General server configuration -${authModuleDirective} - -# Lock down PHP environment -php_admin_value output_buffering 0 -php_admin_value expose_php 0 -php_admin_value file_uploads 0 - - -# Voting website (HTTPS) -Listen 443 -NameVirtualHost *:443 - - ServerAdmin ${serverAdmin} - ServerName ${domainName} - DocumentRoot ${documentRoot} - CustomLog /var/log/apache2/${domainName}_SSL-access_log combined - ErrorLog /var/log/apache2/${domainName}_SSL-error_log - HostnameLookups Off - UseCanonicalName Off - ServerSignature Off - - Options -Indexes - AllowOverride None - Order allow,deny - Allow from all - - - # SSL - SSLEngine on - SSLCertificateFile ${apacheSslCrtDirectory}/${domainName}.crt - SSLCertificateKeyFile ${apacheSslKeyDirectory}/${domainName}.key - ${apacheSslCertificateChainDirective} - - # Authentication - - ${authConfig} - Require valid-user - - - SetHandler AALogout - - - # Deny technical files being retrieved via a browser - - deny from all - - - deny from all - - - - -# Voting website (HTTP) -NameVirtualHost *:80 - - ServerAdmin ${serverAdmin} - ServerName ${domainName} - DocumentRoot ${documentRoot} - CustomLog /var/log/apache2/${domainName}-access_log combined - ErrorLog /var/log/apache2/${domainName}-error_log - HostnameLookups Off - UseCanonicalName Off - ServerSignature Off - - Options -Indexes - AllowOverride None - Order allow,deny - Allow from all - - - # Redirect all traffic to the SSL vhost (at which point authentication will occur) - Redirect permanent / https://${domainName}/ - - -EOF -fi - -# Create a group for web editors, who can edit the files -if ! grep -i "^${webEditorsGroup}\b" /etc/group > /dev/null 2>&1 ; then - groupadd "${webEditorsGroup}" -fi - -# Add the current user to the web editors' group, if not already in it -currentActualUser=`who am i | awk '{print $1}'` -if ! groups ${currentActualUser} | grep "\b${webEditorsGroup}\b" > /dev/null 2>&1 ; then - usermod -A "${webEditorsGroup}" "${currentActualUser}" -fi - -# Create the document root and let the web group write to it -mkdir -p "${documentRoot}" -chown nobody."${webEditorsGroup}" "${documentRoot}" -chmod g+ws "${documentRoot}" -umask 0002 - -# Restart the webserver -sudo /etc/init.d/apache2 restart - -# Add the BOB software (the native voting component, without any setup management) -if [ ! -d ${documentRoot}/bob ] ; then - cd "${documentRoot}" - git clone https://github.com/cusu/bob.git -fi - -# Create a database binding -mysql="mysql -u root -p${mysqlRootPassword} -h localhost" - -# Use the database version of the boostrap file rather than the manual bootstap file -if [ -r "${documentRoot}"/bob/index-dbconfig.php ]; then - mv "${documentRoot}"/bob/index-dbconfig.php "${documentRoot}"/bob/index.php -fi - -# Add the database credentials to the bootstrap file (replace the lines matching on the left with the whole config string on the right) -sed -i \ --e "s/.*'dbDatabase'.*/\$config['dbDatabase'] = '${bobDbDatabase}';/" \ --e "s/.*'dbUsername'.*/\$config['dbUsername'] = '${bobDbUsername}';/" \ --e "s/.*'dbSetupUsername'.*/\$config['dbSetupUsername'] = '${bobDbSetupUsername}';/" \ - "${documentRoot}"/bob/index.php - -# Put the password into the password file -echo -n "${bobDbPassword}" > "${documentRoot}"/bob/dbpass - -# Create the voting database -${mysql} -e "CREATE DATABASE IF NOT EXISTS ${bobDbDatabase} DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;" - -# Create database user privileges (which will create the users if they do not exist); see: https://github.com/cusu/bob/blob/master/BOB.php#L1436 -${mysql} -e "GRANT SELECT,INSERT,UPDATE ON ${bobDbDatabase}.* TO '${bobDbUsername}'@'localhost' IDENTIFIED BY '${bobDbPassword}';" -${mysql} -e "GRANT SELECT,CREATE ON ${bobDbDatabase}.* TO '${bobDbSetupUsername}'@'localhost' IDENTIFIED BY '${bobDbPassword}';" - -# Set up the instances table -cat > /tmp/instances.sql << \EOF -CREATE TABLE IF NOT EXISTS `instances` ( - `id` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'Generated globally-unique ID', - `title` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'Title of this ballot', - `urlMoreInfo` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'URL for more info about the ballot', - `afterVoteMessageHtml` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'An extra message, if any, which people will see when they have voted', - `emailReturningOfficer` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'E-mail address of Returning Officer / mailbox', - `emailTech` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'E-mail address of Technical Administrator', - `officialsUsernames` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'Usernames of Returning Officer + Sysadmins', - `randomisationInfo` enum('','Candidate order has been automatically randomised','Candidate order has been automatically alphabetised','Candidates have been entered by the Returning Officer in the order shown') collate utf8_unicode_ci default NULL COMMENT 'Candidate ordering/randomisation', - `adminDuringElectionOK` int(1) default '0' COMMENT 'Whether the administrator can access admin pages during the election', - `organisationName` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'Organisation name', - `organisationUrl` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'Organisation URL', - `organisationLogoUrl` varchar(255) collate utf8_unicode_ci default NULL COMMENT 'URL of organisation''s logo', - `headerLocation` varchar(255) collate utf8_unicode_ci default '/style/prepended.html' COMMENT 'Header house style file', - `footerLocation` varchar(255) collate utf8_unicode_ci default '/style/appended.html' COMMENT 'Footer house style file', - `electionInfo` text collate utf8_unicode_ci NOT NULL COMMENT 'Election info: Number of positions being elected; Position title; Names of candidates; each block separated by one line break', - `referendumThresholdPercent` int(3) default '10' COMMENT 'Percentage of voters who must cast a vote in a referendum for the referendum to be countable', - `ballotStart` datetime NOT NULL COMMENT 'Start date/time of the ballot', - `ballotEnd` datetime NOT NULL COMMENT 'End date/time of the ballot', - `ballotViewable` datetime NOT NULL COMMENT 'Date/time when the cast votes can be viewed', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -EOF -${mysql} ${bobDbDatabase} < /tmp/instances.sql -rm /tmp/instances.sql - -# Add a sample ballot -cat > /tmp/sampleballot.sql << EOF - -# Create the instance -DELETE FROM instances WHERE id = 'testelection' LIMIT 1; -INSERT INTO instances VALUES ( - 'testelection', 'Test election', NULL, NULL, '${serverAdmin}', '${serverAdmin}', '${sampleBallotUsername}', 'Candidate order has been automatically randomised', '0', 'My organisation', NULL, NULL, '', '', -'1 -President -BLAIR, Tony -THATCHER, Margaret -', '10', '2013-09-01', '2013-09-02', '2013-09-02' -); - -# Create the votes table -CREATE TABLE IF NOT EXISTS testelection_votes (token VARCHAR(32) collate utf8_unicode_ci NOT NULL PRIMARY KEY, v1p1 TINYINT(4), v1p2 TINYINT(4)) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci; - -# Create the voter table and insert one voter -CREATE TABLE IF NOT EXISTS testelection_voter (username VARCHAR(16) collate utf8_unicode_ci NOT NULL PRIMARY KEY, voted TINYINT(4) DEFAULT 0, forename VARCHAR(255) collate utf8_unicode_ci, surname VARCHAR(255) collate utf8_unicode_ci, unit VARCHAR(255) collate utf8_unicode_ci) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci; -INSERT IGNORE INTO testelection_voter VALUES ('${sampleBallotUsername}', 0, 'Forename', 'Surname', 'My college'); -EOF -${mysql} ${bobDbDatabase} < /tmp/sampleballot.sql -rm /tmp/sampleballot.sql +# Install the base system +source ./1-install-base.sh +# Install the voting component (BOB) +source ./2-install-bob.sh