|
Post by Marti-Pair Furxheir S.H. on Dec 28, 2015 12:32:11 GMT -6
Hi everyone,
We have this bill (48RZ11) submitted to a referendum:
I propose that the electoral commission get together so I can explain the procedure for how the votes are handled, and as such, so that it can certify it's reliability.
How do I propose to do that?
Over the next few days, I will explain here, publicly, how the voting form works. It will be some work, but I will do it. ANYONE will be able to object to the reliability and I will reply to those objections.
Then, I will ask the King to nominate the Electoral Commission (3 judges and I) so that we can, all 4 of us, unanimously vote in this thread on the reliability of the voting form.
Just a note, there is something weird in computer program debugging: if you explain a piece of software to someone who knows NOTHING about it, bugs will pop-out in front of your eyes because you explain using your comprehension of the software, but to explain the actual software and as such, bugs pop out.
As a result, I will NOT pre-certify the code, but rather use the exercise to ensure it does what I think it does. Actual PHP code will be posted here, starting tomorrow morning!
|
|
Dr. Txec dal Nordselvă
Puisne (Associate) Justice of the Uppermost Court
Fraichetz dels punts, es non dels mürs
Posts: 4,063
Talossan Since: 9-23-2012
|
Post by Dr. Txec dal Nordselvă on Dec 28, 2015 23:27:49 GMT -6
Ok well this should be interesting.
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 29, 2015 4:31:14 GMT -6
Ok well this should be interesting. I sure hope so... it will be the first time in Talossan history that massive lines of code will be seen by someone other than myself!
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 29, 2015 4:37:18 GMT -6
Here is the source code, in full (except for my email address: ). Some old sections in comments kept for historical reasons are also ommited: code in comments are ignored.
<?
include("dbconnection.inc"); include('dbheader.html'); include('cosa_members.inc.php');
extract($_POST);
$province_result = mysql_query( "select * from Province order by ProvinceNumber");
?>
<a href="vote.php" class="btn btn-primary">Refresh</a>
<?
$current_data_result = mysql_query( "select * from CurrentData"); $ElectionActive = mysql_result($current_data_result,0,"ElectionActive");
$clark = mysql_result( $current_data_result,0,"CurrentClark"); $cosa = mysql_result( $current_data_result,0,"CurrentCosa");
if ( !$ElectionActive ){
if ( $clark > 2 ){ $cosa++; echo '<div class="alert alert-error"><h3>This is a preview ballot</h3><p>This ballot is just a preview of the upcoming election ballot. It is not currently accepting votes</p></div>'; } else{ echo '<div class="alert alert-error"><h3>The election is not currently active</h3><p>This ballot is not currently accepting votes</p></div>'; }
}
function GenerateConfirmationEmailBody($row){
global $province_result, $cosa;
$content .= '<h2>'.$cosa .'th Cosa Election Vote Confirmation.</h2>'; $content .= '<p>Your vote has been received, confirmed and entered into the Database system.</p>';
$content .= '<fieldset>'; $content .= '<h3>Part 1: Information Required to Vote</h3>';
$content .= '<p>Your Name: '. $row['Name'] .'</p> '; $content .= '<p>Your Citizen Number: ' . $row['Number'].'</p> ';
$province = mysql_result($province_result,$row["Province"],"ProvinceName"); $content .= '<p>Your Province: ' .$province .'</p> ';
$content .= '<p>Your Security Code (PSC): '. $row['psc'].'</p> ';;
$content .= '<p>You can login to the database system using your citizen number and PSC to confirm that your vote was properly entered at: <a href="http://www.talossa.ca/files/validatevote.php">http://www.talossa.ca/files/validatevote.php</a>.</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 2: How to Vote</h3>';
$content .= '<p>Nothing to confirm in Part 2</p>' ; $content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 3: Cosa Election</h3>';
$content .= '<p><br />Party Vote: '. $_POST['party']. '</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 4: Confidentiality</h3>';
$content .= '<p>Is your vote public ? '. $_POST['secret'].' </p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>';
/******************************************************************* Referendums *******************************************************************/
if ( $_POST['NumberOfReferendums'] > 0 ){ $content .= "<h3>Part 5: Referendums</h3>"; }
$i = 0; while ( $i < $_POST['NumberOfReferendums'] ) {
$content .= '<p>Bill '. $_POST['BillCosa'][$i].'RZ'. $_POST['BillNumber'][$i]. ': '. $_POST['referendum'][$i].'</p>';
$i++; }
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 6: Senatorial Election</h3>';
$content .= '<p>Name of the person you want as Senator for '. $province. ': '. $_POST['senatevote'] .'</p>';
$content .= '<p>PLEASE NOTE: Fiova Senate Elections are conducted by the Provincial SoS. If you are from Fiova, your vote will be ignored</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 7: Provincial Election</h3>';
$content .= '<p>Provincial Vote: '.$_POST['provincialvote'].'</p>';
$content .= '</fieldset><br />';
$content .= '<p>This Email was generated on '. date('Y-m-d H:i:s'). '</p>';
return $content;
}
function EmailReceipt($cit){
if ( $cit['Email'] != ''){
$body = GenerateConfirmationEmailBody($cit); SendEmail($cit,'Your Vote Confirmation for the Talossa Election, '. utf8_decode($cit['Name']), $body );
echo '<h1>Message has been sent</h1>';
echo $body;
}
}
/* if ( IsLoggedIn() ){
$user = GetCitizen(GetCurrentUser());
echo '<p>Hello '. $user['Name'].'</p>';
}
*/
$CosaNumber = $cosa;
if ( $_POST['save'] >0 && $ElectionActive){ echo "<h1>Result page</h1>";
$editor_result = mysql_query( "select * from Citizens where number=". intval($_POST['citnumber']));
$voter = mysql_fetch_assoc($editor_result);
if ( $voter['Number'] > 0 && intval($voter['Active']) == 1 && substr(trim($voter['psc']),0,8) == substr(trim($_POST['psc']),0,8) ){
$secret = $_POST['secret'] != 'Yes'; // Yes for Public if ( $_POST['votemethod'] == 'witt' || $_POST['votemethod'] == 'wittpsc' ){ $secret = 0; }
if ( $_POST['party'] != ''){
$values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['party']) ; $values['method'] = $_POST['votemethod']; $values['crdate'] = time(); $values['citizen'] = GetCurrentUser(); $values['ipaddress'] = $_SERVER['REMOTE_ADDR']; $values['useragent'] = $_SERVER['HTTP_USER_AGENT']; mysql_query(INSERTquery('ElectionVote', $values)); echo mysql_error(); echo '<br>';
$i = 0; while ( $i < $_POST['NumberOfReferendums'] ) {
$values = array(); $values['secret'] = $secret; $values['Citizen'] = $voter['Number']; $values['CosaNumber'] = $_POST['BillCosa'][$i]; $values['CosaVoted'] = $CosaNumber; $values['Vote'] = $_POST['referendum'][$i]; $values['BillNumber'] = $_POST['BillNumber'][$i]; mysql_query( INSERTquery('ReferendumVote', $values)); echo mysql_error(); echo '<br>'; $i++; }
if ( $_POST['senatevote'] != ''){ $values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['senatevote']) ; $values['ProvinceNumber'] = strtoupper($voter['Province']) ; mysql_query(INSERTquery('SenateElectionVote', $values)); echo mysql_error(); echo '<br>';
}
if ( $_POST['provincialvote'] != ''){ $values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['provincialvote']) ; $values['ProvinceNumber'] = strtoupper($voter['Province']) ; mysql_query(INSERTquery('ProvinceElectionVote', $values)); echo mysql_error(); echo '<br>';
}
EmailReceipt($voter);
include('dbfooter.html');
exit();
} else{ echo '<div class="alert alert-error">You did not select a party</div>'; }
} else{ echo '<div class="alert alert-error">There was a problem with your vote</div>';
echo '<h3>More details</h3>';
if ( $voter['Number'] < 1 ){ echo '<div class="alert alert-error">Your citizen file could not be loaded. Did you enter your citizen number?</div>'; } if ( $voter['Active'] != 1){ echo '<div class="alert alert-error">According to our files, you do not have the right to vote. This might be an error.</div>'; }
if ( substr(trim($voter['psc']),0,8) != substr(trim($_POST['psc']),0,8) ){ echo '<div class="alert alert-error">the PSC your entered is not valid.</div>'; }
$mail .= 'A citizen failed the validation. ';
$mail .= nl2br(print_R( $voter, true));
$mail .= nl2br(print_R( $_POST, true)); $mail .= nl2br(print_R( $_SERVER, true));
$cit['Email'] = '[my email address]'; $cit['Name'] = 'Marti-Pair Furxhéir';
SendEmail($cit,'There was a failed vote in the database from, '. utf8_decode($voter['Name']), $mail );
}
//mysql_db_query(); } else { mysql_connect(localhost, $DB_user, $DB_password);
echo '<h3>'.$cosa .'th Cosa Election Vote Form</h3>'; echo '<h3><i>Papel Electoral per la '.$cosa .'-l:t Cosa</i></h3>'; echo '<form method="post" action="vote.php" class="form form-horizontal">'; echo '<input type="hidden" NAME="save" value="1" >' ;
echo '<fieldset>'; echo '<h3>Part 1: Identification</h3>'; echo '<h3><i>Pärts 1: Identificaziun</i></h3>';
if ( $user['Name'] != ''){ echo '<div class="alert alert-info">You are logged in and as such, pre-authenticated</div>'; echo BootstrapTextValue('Your Name:', 'Name', $user); echo BootstrapTextValue('Your Citizen Number / Númerul da Citaxhién:', 'Number', $user); } else{ echo BootstrapTextField('Citizen Number / <i>Númerul da Citaxhién</i>:', 'citnumber', $_POST); echo BootstrapTextField('Security Code (PSC) / <i>Coda da Sigürità Perziunal</i>:', 'psc', $_POST); } echo '</fieldset>';
echo '<fieldset>'; echo '<h3>Part 2: How to Vote</h3>'; echo '<h3><i>Pärts 2: Come Votarh</i></h3>';
if ( InSosOffice()){
echo Bootstrapfield('How did you vote', "<select NAME=\"votemethod\" size=\"1\" >\n<option selected>manual</option>\n<option>db</option>\n <option selected>psc</option>\n <option selected>witt</option>\n <option selected>mail</option>\n <option selected>wittpsc</option>\n <option selected>wittmsg</option>\n </select>\n ") ;
echo '<div class="alert-info alert">Select "psc" if the voter sent his or her vote by email</div>';
} else{ echo '<input type="hidden" name="votemethod" value="psc" />'; echo '<p>Nothing to fill here</p>'; echo '<p><i>Níþil à complätsarh aicì</i></p>';
} echo '</fieldset>';
echo '<fieldset>';
echo '<h3>Part 3: Cosa Election</h3>'; echo '<h3><i>Pärts 3: Eleziun per la Cosa</i></h3>';
echo '<div class="alert alert-info"><p>Enter the Initials of the party you want to vote for.</p><p>You can vote for a non-registered party, but unless that part later registers, you risk having your vote discarded.</p>
<p><i>Complätsetz els iniziais del parti per qet voi veletz votarh.
Voi pevetz votarh per \'n parti inenrexhistrat, mas salva q\'acest parti enrexhistradra pü schpeit, voi
rischetz qe voastra vota estadra dropada.</i></p>
</div>';
echo BootstrapTextField('Party Vote:', 'party', $_POST);
echo '<p><br />If you do not wish to vote for a party, but do not wish either to lose your citizenship, indicate "PRESENT" for the Party Vote.</p>';
echo '<p><br /><i>Schi voi non veletz ni votarh pr\'iens parti, ni pierdarh voastra citaxhienità, inidicarh \'n vota da “PRESINT” per la Vota pr\'iens Parti.</i></p>';
$res = mysql_query('SELECT * FROm RegisteredParties WHERE CosaNumber='. $cosa); if ( $res && mysql_num_rows($res) > 0 ){ echo '<h3>Registered Parties</h3>'; echo '<table class="table table-bordered">'; echo '<tr><th>Initials</th><th>Name</th><th>Statement</th><th>Leader(s)</th></tr>';
while ( $row = mysql_fetch_assoc($res)){
echo '<tr>';
echo '<td>'. $row['PartyInitials'].'</td>'; echo '<td>'. $row['PartyName'].'</td>'; echo '<td>'. $row['Statement'].'</td>'; echo '<td>'. $row['leaders'].'</td>';
echo '</tr>';
} echo '</table>';
}
echo '</fieldset>';
echo '<fieldset>'; echo '<h3>Part 4: Confidentiality</h3>';
echo '<h3><i>Pärts 4: Intimatità</i></h3>';
echo Bootstrapfield('Do you want your vote to be public <br><i>¿Veletz-voi qe voastra vota estadra püblíc?</i>', "<select NAME=\"secret\" size=\"1\" >\n<option selected>No</option>\n<option>Yes</option>\n </select>\n ") ;
echo '<div class="alert-info alert"><p>Select "Yes" if the voter posted on Wittenberg</p><p><i>Selectetz “Üc” schi el voteir posteva sür Wittenberg</i></p></div>';
echo '</fieldset>';
echo '<fieldset>';
/******************************************************************* Referendums *******************************************************************/
$PreviousCosa = $cosa-1;
$Referendum = mysql_query( "select * From BillReferendum,Bills where BillReferendum.CosaVoted=".$cosa." AND BillReferendum.CosaNumber = Bills.CosaNumber AND BillReferendum.BillNumber=Bills.BillNumber ORDER BY Bills.CosaNumber,Bills.BillNumber");
$num = mysql_numrows($Referendum );
if ( $num > 0 ) { echo "<h3>Part 5: Referendums</h3>"; echo '<h3><i>Pärts 5: Referendüms</i></p>'; echo '<div class="alert alert-info"><p>The following bills requiring a referendum were adopted by the Ziu during the last Cosâ.</p> <p><i>Els proxhets sovinds qi resquirent \'n referendüm estevent adoptats par el Ziu dürant la Cosa lasta.</i></p></div>'; }
$r = 0; echo "<input type=\"hidden\" NAME=\"NumberOfReferendums\" value=\"$num\" >" ; while ( $r < $num ) {
printf("<h3>Referendum number %d</h3>\n", $r+1); printf("<h3><i>Referendüm númerul %d</i></h3>\n", $r+1);
$BillNumber = mysql_result($Referendum,$r,"Bills.BillNumber"); $BillTitle = mysql_result($Referendum,$r,"BillTitle"); $CosaOfBill = mysql_result($Referendum,$r,"BillReferendum.CosaNumber"); echo Bootstrapfield( sprintf("\n%dth Cosâ RZ%d:", $CosaOfBill, $BillNumber), '<div class="static-text">'. sprintf("<a href=\"bills.php?cosa=$CosaOfBill&bill=$BillNumber\" target=\"_blank\">%s </a>\n",stripslashes(stripslashes($BillTitle)) ).'</div>');
echo GetReferendums50WordStatements($CosaOfBill, $BillNumber);
echo Bootstrapfield('Your vote<br /><i>Voastra vota</i>', "<select NAME=\"referendum[$r]\" size=\"1\" >\n<option>Për</option>\n<option>Contrâ</option>\n <option selected>Abstain</option>\n </select>\n ") ; echo '<input type="hidden" NAME="BillNumber['.$r.']" value="'.$BillNumber.'" >' ; echo '<input type="hidden" NAME="BillCosa['.$r.']" value="'.$CosaOfBill.'" >' ;
echo "<br><br>"; $r++; }
echo '</fieldset>';
echo '<fieldset>';
echo '<h3>Part 6: Senate Election</h3>'; echo '<h3><i>Pärts 6: Eleziun per el Senäts</i></h3>';
$res = mysql_query('SELECT * FROM senatorendorsement,Province WHERE cosa='.$cosa.' AND province=provincenumber ORDER BY province,party'); echo mysql_error(); if ( mysql_num_rows($res) > 0 ){ echo '<h4>Senate Endorsements by political parties</h4>'; echo '<table class="table table-bordered">'; echo '<tr><th>Province</th><th>Party</th><th>Endorsement</th></tr>'; while ($row = mysql_fetch_assoc($res)){ echo '<tr>'; echo '<td>'. $row['ProvinceName'] .'</td>'; echo '<td>'. $row['party'] .'</td>'; echo '<td>'. GetCitizenNameLinked($row['candidate']) .'</td>';
echo '</tr>'; }
echo '</table>';
} echo BootstrapTextField('Senate Vote<br><i>Vota per el Senäts</i>:', 'senatevote', $_POST); echo '</fieldset>';
echo '<fieldset>';
echo '<h3>Part 7: Provincial Election</h3>'; echo '<h3><i>Pärts 7: Eleziun Provincial</i></h3>';
echo BootstrapTextField('Provincial Vote<br /><i>Vota provincial</i>:', 'provincialvote', $_POST); echo '</fieldset>';
echo Bootstrapfield('', ' <input type="submit" name="Submit" value="Submit" class="btn btn-primary">');
echo '</form>';
}
include('dbfooter.html');
?>
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 29, 2015 4:39:50 GMT -6
First comments:
1 ) This isn't some of my cleanest code. I wrote most of the content back in 2002, and then only tweaked it without any refactoring (rewriting). Unlike other sections, this code actually scares me: if I mess up and just a SINGLE person thinks they have voted and they didn't, the election results are invalid.
2 ) The code is mainly in 5 sections: - The very top, we have the initialization section - Then, we have a few functions - Then, we have the authentication section - Right after we have the vote storing section - Finally, we have the form section
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 29, 2015 5:02:16 GMT -6
Part 1:: The initialization section
include("dbconnection.inc"); include('dbheader.html'); include('cosa_members.inc.php');
extract($_POST);
$province_result = mysql_query( "select * from Province order by ProvinceNumber");
?>
<a href="vote.php" class="btn btn-primary">Refresh</a>
<?
$current_data_result = mysql_query( "select * from CurrentData"); $ElectionActive = mysql_result($current_data_result,0,"ElectionActive");
$clark = mysql_result( $current_data_result,0,"CurrentClark"); $cosa = mysql_result( $current_data_result,0,"CurrentCosa");
if ( !$ElectionActive ){
if ( $clark > 2 ){ $cosa++; echo '<div class="alert alert-error"><h3>This is a preview ballot</h3><p>This ballot is just a preview of the upcoming election ballot. It is not currently accepting votes</p></div>'; } else{ echo '<div class="alert alert-error"><h3>The election is not currently active</h3><p>This ballot is not currently accepting votes</p></div>'; }
}
Part by part:
include("dbconnection.inc"); include('dbheader.html'); include('cosa_members.inc.php');
We include our various tools:
dbconnection.inc contains the database username and password, as well as a few general functions like "InSoSOffice()" which returns true if the user is in the SoS Office. dbheadder.html is the top of the page (the black bar at the top), with the left column menu. cosa_members.inc.php contains a few more functions. I am not sure it is useful in this page, but back in 2002, I was including it EVERYWHERE.
extract($_POST);
Ok, this is the most controversial part of the page, and honestly, if I was auditing the page, I would stop right there and yell at an outrage! extract takes an array, such as $array['name'] = 'Marti-Pair'; and makes each element of that array into it's own variable, so that in the above example, we would have $name = 'Marti-Pair';
Doing and extract on $_POST is suicide, but yet, it was needed, and here is why:
In the past (2002), when you had a form in PHP, the variables from that form were available globally. If you had a field "vote" you had a variable called $vote with the value typed by the user. This was WONDERFUL. It made PHP so easy!
But in the time between 2004 and my return, the PHP community realized that any hacker could then initialize a variable using a form! If you were relying on a variable being empty before you set it, anyone could set it up by just posting it to you script and many, many, many sites were hacked this way!
As such, this feature (called register_global) was REMOVED from PHP and when I restored my database in 2013, NOTHING worked for that specific reason.
So, I have 2 choices:
1 ) I stop using all of the global variables, and instead, use $_POST['nameofvariable'], and that way, I know that all of my non $_POST or $_GET variables are CLEAN or 2 ) I use extract to simulate the old behavior.
But here is the thing: I am not using extract($_GET) or extract($_REQUEST), only extract ($_POST), which makes it a little harder to spoof, and all of my global variables are initialized
Many of my clients actually have the warning in PHP that warns that a variable is not initialized set an error, because more and more this is recommended. I thus NEVER rely on variables being uninitalized, and I wasn't doing so in 2002 when I was also working with C++ and C# at the same time and in those languages, you CANNOT use a non-initialized variable.
But this audit will force me to show you it is the case, which is a GOOD THING. Who knows, I might discover a security issue!
$province_result = mysql_query( "select * from Province order by ProvinceNumber");
Here, I make a mysql query to retrieve a MySQL result array of all of the provinces. This allows me to easily convert a province number (such as 1) into a province name (such as Atatûrk).
?>
<a href="vote.php" class="btn btn-primary">Refresh</a>
<?
Here I just output a button to refresh the page. It's useful when I am typing a few votes in a row....
$current_data_result = mysql_query( "select * from CurrentData"); $ElectionActive = mysql_result($current_data_result,0,"ElectionActive");
$clark = mysql_result( $current_data_result,0,"CurrentClark"); $cosa = mysql_result( $current_data_result,0,"CurrentCosa");
Here, I retrieve from the table CurrentData (which stores stuff like who the current PM is, which Clark are we, etc...), and then, retrieve whether the election is active or now, the current clark and the current Cosa.
Yes, I use the mysql_result. Today, I don't. now use mysql_fetch_asssoc which retrieves the full row in memory. But mysql_result is valid and functional, even if no one really uses it anymore.
The zero by the way is to say "First result", or "skip 0 entries".
if ( !$ElectionActive ){
if ( $clark > 2 ){ $cosa++; echo '<div class="alert alert-error"><h3>This is a preview ballot</h3><p>This ballot is just a preview of the upcoming election ballot. It is not currently accepting votes</p></div>'; } else{ echo '<div class="alert alert-error"><h3>The election is not currently active</h3><p>This ballot is not currently accepting votes</p></div>'; }
}
Here, we check 2 conditions:
If the election is NOT active, we will put an error at the top, either that it is not current active (if we are before the 2nd Clark), or that it is a preview (if we are after the 2nd Clark).
It doesn't change much, but it's there. If it's a preview, we also increase the Cosa number otherwise, we would be showing the ballot from the previous election. (putting ++ after a variable adds 1 to it).
And this is the end of initialization! Number of unitialized variables which might be spoofed: zero.
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 29, 2015 5:17:53 GMT -6
Part 2: The functions:
function GenerateConfirmationEmailBody($row){
global $province_result, $cosa;
$content .= '<h2>'.$cosa .'th Cosa Election Vote Confirmation.</h2>'; $content .= '<p>Your vote has been received, confirmed and entered into the Database system.</p>';
$content .= '<fieldset>'; $content .= '<h3>Part 1: Information Required to Vote</h3>';
$content .= '<p>Your Name: '. $row['Name'] .'</p> '; $content .= '<p>Your Citizen Number: ' . $row['Number'].'</p> ';
$province = mysql_result($province_result,$row["Province"],"ProvinceName"); $content .= '<p>Your Province: ' .$province .'</p> ';
$content .= '<p>Your Security Code (PSC): '. $row['psc'].'</p> ';;
$content .= '<p>You can login to the database system using your citizen number and PSC to confirm that your vote was properly entered at: <a href="http://www.talossa.ca/files/validatevote.php">http://www.talossa.ca/files/validatevote.php</a>.</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 2: How to Vote</h3>';
$content .= '<p>Nothing to confirm in Part 2</p>' ; $content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 3: Cosa Election</h3>';
$content .= '<p><br />Party Vote: '. $_POST['party']. '</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 4: Confidentiality</h3>';
$content .= '<p>Is your vote public ? '. $_POST['secret'].' </p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>';
/******************************************************************* Referendums *******************************************************************/
if ( $_POST['NumberOfReferendums'] > 0 ){ $content .= "<h3>Part 5: Referendums</h3>"; }
$i = 0; while ( $i < $_POST['NumberOfReferendums'] ) {
$content .= '<p>Bill '. $_POST['BillCosa'][$i].'RZ'. $_POST['BillNumber'][$i]. ': '. $_POST['referendum'][$i].'</p>';
$i++; }
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 6: Senatorial Election</h3>';
$content .= '<p>Name of the person you want as Senator for '. $province. ': '. $_POST['senatevote'] .'</p>';
$content .= '<p>PLEASE NOTE: Fiova Senate Elections are conducted by the Provincial SoS. If you are from Fiova, your vote will be ignored</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 7: Provincial Election</h3>';
$content .= '<p>Provincial Vote: '.$_POST['provincialvote'].'</p>';
$content .= '</fieldset><br />';
$content .= '<p>This Email was generated on '. date('Y-m-d H:i:s'). '</p>';
return $content;
}
function EmailReceipt($cit){
if ( $cit['Email'] != ''){
$body = GenerateConfirmationEmailBody($cit); SendEmail($cit,'Your Vote Confirmation for the Talossa Election, '. utf8_decode($cit['Name']), $body );
echo '<h1>Message has been sent</h1>';
echo $body;
}
}
Two functions are defined in that script: GenerateConfirmationEmailBody, which makes the confirmation emmail, and EmailReceipt which actually sends it!
We'll start with the second one:
function EmailReceipt($cit){
if ( $cit['Email'] != ''){
$body = GenerateConfirmationEmailBody($cit); SendEmail($cit,'Your Vote Confirmation for the Talossa Election, '. utf8_decode($cit['Name']), $body );
echo '<h1>Message has been sent</h1>';
echo $body;
}
}
This one is fairly small: we get a parameter, $cit, which is the citizen row, and we check if there is an email set. If not, we can't send a receipt: we don't have an email to send it to!
If we do have one, we call the first function GenerateConfirmationEmailBody, and then call the function SendMail which is defined in CosaMembers.inc.php I believe.
Finally, we confirm the message was sent, and print the message on the screen.
The first problem I see is if a voter doesn't have an email address, we won't even show him his confirmation, but at the same time, if they don't have an email address in the DB, they won't have their PSC and as such, won't be able to vote, so in short, this is a moot point....
The first function:
function GenerateConfirmationEmailBody($row){
global $province_result, $cosa;
In short, we receive the citizen row, and use the global variables province_result and cosa.
Yes, content below is NOT initialized, but it is within a function, which has it's own scope, and as such, this is fine.
$content .= '<h2>'.$cosa .'th Cosa Election Vote Confirmation.</h2>'; $content .= '<p>Your vote has been received, confirmed and entered into the Database system.</p>';
$content .= '<fieldset>'; $content .= '<h3>Part 1: Information Required to Vote</h3>';
$content .= '<p>Your Name: '. $row['Name'] .'</p> '; $content .= '<p>Your Citizen Number: ' . $row['Number'].'</p> ';
$province = mysql_result($province_result,$row["Province"],"ProvinceName"); $content .= '<p>Your Province: ' .$province .'</p> ';
$content .= '<p>Your Security Code (PSC): '. $row['psc'].'</p> ';;
$content .= '<p>You can login to the database system using your citizen number and PSC to confirm that your vote was properly entered at: <a href="http://www.talossa.ca/files/validatevote.php">http://www.talossa.ca/files/validatevote.php</a>.</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 2: How to Vote</h3>';
$content .= '<p>Nothing to confirm in Part 2</p>' ; $content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 3: Cosa Election</h3>';
All of the above is just HTML, with some fields filled in. No security problems that I foresee.
$content .= '<p><br />Party Vote: '. $_POST['party']. '</p>';
This was a new function, so I properly used $_POST['party'] instead of the global variable... This shows you that new code (I didn't use to send a receipt) is better than old code.
It is 100% fine to use $_POST variables as unitialized, because it reminds you that it is from the user, so you need to be careful.
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 4: Confidentiality</h3>';
$content .= '<p>Is your vote public ? '. $_POST['secret'].' </p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>';
And that was the end of the first 4 parts... let's see the referendums now
/******************************************************************* Referendums *******************************************************************/
if ( $_POST['NumberOfReferendums'] > 0 ){ $content .= "<h3>Part 5: Referendums</h3>"; }
$i = 0; while ( $i < $_POST['NumberOfReferendums'] ) {
$content .= '<p>Bill '. $_POST['BillCosa'][$i].'RZ'. $_POST['BillNumber'][$i]. ': '. $_POST['referendum'][$i].'</p>';
$i++; }
$content .= '</fieldset><br />';
We have a field "NumberOfReferendums" which if bigger than 0, will let us print the output of each referendum.
Yes, a hacker with a PSC could put a very, very high number in NumberOfReferendum and then, make the script timeout, but they wouldn't gain anything.
$content .= '<fieldset>'; $content .= '<h3>Part 6: Senatorial Election</h3>';
$content .= '<p>Name of the person you want as Senator for '. $province. ': '. $_POST['senatevote'] .'</p>';
$content .= '<p>PLEASE NOTE: Fiova Senate Elections are conducted by the Provincial SoS. If you are from Fiova, your vote will be ignored</p>';
$content .= '</fieldset><br />';
$content .= '<fieldset>'; $content .= '<h3>Part 7: Provincial Election</h3>';
$content .= '<p>Provincial Vote: '.$_POST['provincialvote'].'</p>';
$content .= '</fieldset><br />';
And then, we output the bottom of the email. I will need to add M-M to the provinces where the SoS doesn't run the election.
$content .= '<p>This Email was generated on '. date('Y-m-d H:i:s'). '</p>';
return $content;
}
Finally, we add a timestamp, and return the content so that we can use the body.
Actual Security issues with this section: zero, provided that all users reaching this part have an email address in the system, which they need to have to get their PSC.
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 29, 2015 5:46:22 GMT -6
Part 3: Processing .
This is the most complex and if there IS a security issue, here it where it will be.
This is the part we really, really, want to look at for certification. The first 2 were just preliminary, and the bottom is just the form itself. Part 3 is there the action is.
/* if ( IsLoggedIn() ){
$user = GetCitizen(GetCurrentUser());
echo '<p>Hello '. $user['Name'].'</p>';
}
*/
$CosaNumber = $cosa;
if ( $_POST['save'] >0 && $ElectionActive){ echo "<h1>Result page</h1>";
$editor_result = mysql_query( "select * from Citizens where number=". intval($_POST['citnumber']));
$voter = mysql_fetch_assoc($editor_result);
if ( $voter['Number'] > 0 && intval($voter['Active']) == 1 && substr(trim($voter['psc']),0,8) == substr(trim($_POST['psc']),0,8) ){
$secret = $_POST['secret'] != 'Yes'; // Yes for Public if ( $_POST['votemethod'] == 'witt' || $_POST['votemethod'] == 'wittpsc' ){ $secret = 0; }
if ( $_POST['party'] != ''){
$values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['party']) ; $values['method'] = $_POST['votemethod']; $values['crdate'] = time(); $values['citizen'] = GetCurrentUser(); $values['ipaddress'] = $_SERVER['REMOTE_ADDR']; $values['useragent'] = $_SERVER['HTTP_USER_AGENT']; mysql_query(INSERTquery('ElectionVote', $values)); echo mysql_error(); echo '<br>';
$i = 0; while ( $i < $_POST['NumberOfReferendums'] ) {
$values = array(); $values['secret'] = $secret; $values['Citizen'] = $voter['Number']; $values['CosaNumber'] = $_POST['BillCosa'][$i]; $values['CosaVoted'] = $CosaNumber; $values['Vote'] = $_POST['referendum'][$i]; $values['BillNumber'] = $_POST['BillNumber'][$i]; mysql_query( INSERTquery('ReferendumVote', $values)); echo mysql_error(); echo '<br>'; $i++; }
if ( $_POST['senatevote'] != ''){ $values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['senatevote']) ; $values['ProvinceNumber'] = strtoupper($voter['Province']) ; mysql_query(INSERTquery('SenateElectionVote', $values)); echo mysql_error(); echo '<br>';
}
if ( $_POST['provincialvote'] != ''){ $values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['provincialvote']) ; $values['ProvinceNumber'] = strtoupper($voter['Province']) ; mysql_query(INSERTquery('ProvinceElectionVote', $values)); echo mysql_error(); echo '<br>';
}
EmailReceipt($voter);
include('dbfooter.html');
exit();
} else{ echo '<div class="alert alert-error">You did not select a party</div>'; }
} else{ echo '<div class="alert alert-error">There was a problem with your vote</div>';
echo '<h3>More details</h3>';
if ( $voter['Number'] < 1 ){ echo '<div class="alert alert-error">Your citizen file could not be loaded. Did you enter your citizen number?</div>'; } if ( $voter['Active'] != 1){ echo '<div class="alert alert-error">According to our files, you do not have the right to vote. This might be an error.</div>'; }
if ( substr(trim($voter['psc']),0,8) != substr(trim($_POST['psc']),0,8) ){ echo '<div class="alert alert-error">the PSC your entered is not valid.</div>'; }
$mail .= 'A citizen failed the validation. ';
$mail .= nl2br(print_R( $voter, true));
$mail .= nl2br(print_R( $_POST, true)); $mail .= nl2br(print_R( $_SERVER, true));
$cit['Email'] = '[my email address]'; $cit['Name'] = 'Marti-Pair Furxhéir';
SendEmail($cit,'There was a failed vote in the database from, '. utf8_decode($voter['Name']), $mail );
}
Let go again, section by section:
/* if ( IsLoggedIn() ){
$user = GetCitizen(GetCurrentUser());
echo '<p>Hello '. $user['Name'].'</p>';
}
*/
In the past, in 2002-2004, you would vote by logging it to the database. The new law however, requires the PSC. This means that I can't let a logged in user just vote using his login, which sad, I would be able to do amazing things but the law is the law, so this section is in comments (between a /* and a */
$CosaNumber = $cosa;
Sometimes, I use $cosa and sometimes, I use $CosaNumber to store the number of the cosa in my script. I wasn't 100% consistent between 2001 and 2004. So what, sue me ;-)
if ( $_POST['save'] >0 && $ElectionActive){ echo "<h1>Result page</h1>";
We check that 1) the form was submitted, and 2) The election is indeed active (as loaded in the first part).
$editor_result = mysql_query( "select * from Citizens where number=". intval($_POST['citnumber']));
$voter = mysql_fetch_assoc($editor_result);
We then load in memory the citizen row. Please note the intval() on the citnumber post which guarantees we do not have an exploit. Editor_result is a remnant from another script and not of importance. The $voter is important and reused.
if ( $voter['Number'] > 0 && intval($voter['Active']) == 1 && substr(trim($voter['psc']),0,8) == substr(trim($_POST['psc']),0,8) ){
We check that:
1 ) The Number of the citizen is bigger than 0 (otherwise, we didn't find him in the DB) 2 ) That citizen is allowed to vote (Active is set to 1. 0 is inactive, 2 is dandelions 3 ) We compare the first 8 characters of the typed PSC with the one we have on file.
Why the first 8? One of the citizens coudn't vote before the 9th character (a - ) wasn't the same value in his language code than on the database. He was typing a -, and I was seeing a -, but with a different code underneath and it prevented him from voting. We don't need more than 8 characters anyway, so this solution was devised.
$secret = $_POST['secret'] != 'Yes'; // Yes for Public
Here is the WEIRD part. I STORE if the person wants his vote Secret or not, but I ASK if the user wants his vote public or not. So, I need to invert the choice: if he says "Yes", it means public, so I store Not Secret. If it's anything else (it's a drop-down, so it has to be No), I store as secret.
if ( $_POST['votemethod'] == 'witt' || $_POST['votemethod'] == 'wittpsc' ){ $secret = 0; }
However, if the method of voting (which can only be specified by a member of the chancery), is set a being a witt vote, or a wittpsc vote, than the vote IS public, since it was posted publicly.
if ( $_POST['party'] != ''){
If no party is speficied, we just put an error, It is required to type something, even if it's just "PRESENT".
$values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['party']) ; $values['method'] = $_POST['votemethod']; $values['crdate'] = time(); $values['citizen'] = GetCurrentUser(); $values['ipaddress'] = $_SERVER['REMOTE_ADDR']; $values['useragent'] = $_SERVER['HTTP_USER_AGENT']; mysql_query(INSERTquery('ElectionVote', $values)); echo mysql_error(); echo '<br>';
Here, we store in the database the ElectionVote, the values stores are:
If the vote is secret The number of the citizen (from the database, not from the form) The CosaNumber The party, but we put it in all uppercase. The method, which is either an hidden field set to psc, for voters, or a drop-down of the available methods is in the SoS office. The current time The citizen number if someone is logged in (this notably stores which SoS member entered the vote in the DB if it was manual) The IP address of the voter The useragent of the voter (the browser information)
Then, INSERTquery, which is a function I use which creates a Mysql insert query with parameter sanitation (protection against hackers), and I output any errors so that the user will see it.
$i = 0; while ( $i < $_POST['NumberOfReferendums'] ) {
$values = array(); $values['secret'] = $secret; $values['Citizen'] = $voter['Number']; $values['CosaNumber'] = $_POST['BillCosa'][$i]; $values['CosaVoted'] = $CosaNumber; $values['Vote'] = $_POST['referendum'][$i]; $values['BillNumber'] = $_POST['BillNumber'][$i]; mysql_query( INSERTquery('ReferendumVote', $values)); echo mysql_error(); echo '<br>'; $i++; }
Then, it's the referendums! We go one by one in each referendum, and store the results: If the vote is secret, the voter number The Cosa Number of the bill (when it was adopted) The Cosa Number of the election (when it is being ratified) The vote The BillNumber And we insert is in the DB and output any errors...
if ( $_POST['senatevote'] != ''){ $values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['senatevote']) ; $values['ProvinceNumber'] = strtoupper($voter['Province']) ; mysql_query(INSERTquery('SenateElectionVote', $values)); echo mysql_error(); echo '<br>';
}
We then do the SAME thing for the Senate vote (if there is one) We store if it is secret The citizen number The Cosa of the election The vote (in all uppercase) The province number And we insert in the DB and output any errors....
if ( $_POST['provincialvote'] != ''){ $values = array(); $values['secret'] = $secret; $values['CitizenNumber'] = $voter['Number']; $values['Cosa'] = $CosaNumber; $values['vote'] = strtoupper($_POST['provincialvote']) ; $values['ProvinceNumber'] = strtoupper($voter['Province']) ; mysql_query(INSERTquery('ProvinceElectionVote', $values)); echo mysql_error(); echo '<br>';
}
When, we do the SAME for the provincial vote. We store if it is secret The citizen number The Cosa of the election The vote (in all uppercase) The province number And we insert in the DB and output any errors....
EmailReceipt($voter);
include('dbfooter.html');
exit();
Then, we call the EmailReceipt function from Part 2, output the footer (which puts the copyright and such), and EXIT. This means we are done!
If the voter has properly voted, this is the end! Yeah!
Now, the error handling:
} else{ echo '<div class="alert alert-error">You did not select a party</div>'; }
This is outputted if no party was selected. Remember the condition above? This is the error that will be printed.
} else{ echo '<div class="alert alert-error">There was a problem with your vote</div>';
echo '<h3>More details</h3>';
if ( $voter['Number'] < 1 ){ echo '<div class="alert alert-error">Your citizen file could not be loaded. Did you enter your citizen number?</div>'; } if ( $voter['Active'] != 1){ echo '<div class="alert alert-error">According to our files, you do not have the right to vote. This might be an error.</div>'; }
if ( substr(trim($voter['psc']),0,8) != substr(trim($_POST['psc']),0,8) ){ echo '<div class="alert alert-error">the PSC your entered is not valid.</div>'; }
If the big 3 part function comparing the citizen Number, the Active and the PSC fails, we will output messages as follows:
1 ) The first is the Number is smaller than 1. 2 ) If the citizen isn't allowed vote 3 ) if the PSC is wrong.
$mail .= 'A citizen failed the validation. ';
$mail .= nl2br(print_R( $voter, true));
$mail .= nl2br(print_R( $_POST, true)); $mail .= nl2br(print_R( $_SERVER, true));
$cit['Email'] = '[my email address]'; $cit['Name'] = 'Marti-Pair Furxhéir';
SendEmail($cit,'There was a failed vote in the database from, '. utf8_decode($voter['Name']), $mail );
}
We then email my own personal gmail account with the data, so I can help the user, and spot anyone trying to guess the PSC of another user. Notably, I could blacklist any IPs of someone trying non-stop with random PSCs.
And this is it!
This section DID use _POST and not a single global variables... if this keeps up, I will remove the extract at the top, it might not be needed after all for this script!
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 29, 2015 5:47:18 GMT -6
And this is it for this morning! The rest will come tomorrow, I hope...
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 30, 2015 5:20:19 GMT -6
Let's now tackle the rest of the file, the form itself.
//mysql_db_query();
That's a comment. Don't know why it's there. I removed it.
} else {
This is the else from the if ( $_POST['save'] >0 && $ElectionActive){ above...
mysql_connect(localhost, $DB_user, $DB_password);
This is a remnant from back when each php file connected manually to the database. Now, it's just a risk since an arbitrary DB_user or DB_oassword could be passed to the script via the extract above.
Fortunately, localhost is hardcoded, so the hackers would need to be on the same server. I have removed that line of code to remove any problems.
echo '<h3>'.$cosa .'th Cosa Election Vote Form</h3>';
Yes, this section is outputted via echo statements. I don't generally code that way anymore: I prefer to put everything in a variable named $content, and outputting it at once. It's not a problem per se, Wordpress is notably built with echo statements all the way. But not doing it allows to set cookies or redirects (which can only be done before anything is outputted), or to trigger an error condition after content was generated and before it is printed on screen.
But it's not a security issue, so let's move along!
echo '<h3><i>Papel Electoral per la '.$cosa .'-l:t Cosa</i></h3>'; echo '<form method="post" action="vote.php" class="form form-horizontal">'; echo '<input type="hidden" NAME="save" value="1" >' ;
echo '<fieldset>'; echo '<h3>Part 1: Identification</h3>'; echo '<h3><i>Pärts 1: Identificaziun</i></h3>';
That part is just the top header, so nothing there extraordinary.
if ( $user['Name'] != ''){ echo '<div class="alert alert-info">You are logged in and as such, pre-authenticated</div>'; echo BootstrapTextValue('Your Name:', 'Name', $user); echo BootstrapTextValue('Your Citizen Number / Númerul da Citaxhién:', '[b]Number[/b]', $user); } else{ echo BootstrapTextField('Citizen Number / <i>Númerul da Citaxhién</i>:', '[b]citnumber[/b]', $_POST); echo BootstrapTextField('Security Code (PSC) / <i>Coda da Sigürità Perziunal</i>:', 'psc', $_POST); } echo '</fieldset>';
Ok, so if we have a $user loaded into memory, we will print his or her name and his or her citizen number. Otherwise, we ask for the citizen number and the PSC.
Oh, but the user loading above is put in comments, so that way, we will always hit the second condition, right?
False. If someone posts a variable $user which is an array and it has a field called 'Name', then the PSC question will not be shown! Is this a security risk?
No, because the form handling still requires the PSC, and as such, doing so would break the script and fail, so we are ok.
But, this is another point in favor of getting rid of the extract at the top.
Second, the new variable name for the citizen number is citnumber (in bold) while the old one was Number (in bold too). This means that the old form will not work at all...
To fix this, I have now put the first half in comments, like this:
/* if ( $user['Name'] != ''){ echo '<div class="alert alert-info">You are logged in and as such, pre-authenticated</div>'; echo BootstrapTextValue('Your Name:', 'Name', $user); echo BootstrapTextValue('Your Citizen Number / Númerul da Citaxhién:', '[b]Number[/b]', $user); } else*/ { echo BootstrapTextField('Citizen Number / <i>Númerul da Citaxhién</i>:', '[b]citnumber[/b]', $_POST); echo BootstrapTextField('Security Code (PSC) / <i>Coda da Sigürità Perziunal</i>:', 'psc', $_POST); } echo '</fieldset>';
Yes, we can have useless braces.
echo '<fieldset>'; echo '<h3>Part 2: How to Vote</h3>'; echo '<h3><i>Pärts 2: Come Votarh</i></h3>';
That's just HTML for display.
if ( InSosOffice()){
echo Bootstrapfield('How did you vote', "<select NAME=\"votemethod\" size=\"1\" >\n<option selected>manual</option>\n<option>db</option>\n <option selected>psc</option>\n <option selected>witt</option>\n <option selected>mail</option>\n <option selected>wittpsc</option>\n <option selected>wittmsg</option>\n </select>\n ") ;
echo '<div class="alert-info alert">Select "psc" if the voter sent his or her vote by email</div>';
} else{ echo '<input type="hidden" name="votemethod" value="psc" />'; echo '<p>Nothing to fill here</p>'; echo '<p><i>Níþil à complätsarh aicì</i></p>';
}
Ok, if the user is in the SoSOffice, we will ask how the user voted, either manually, in the db, on witt, by email, on witt with the psc, or in the wittmsg.
Manually means the SoS entered the vote from another source and should be investigated. This includes for example, if a voter comes to my house, votes verbally, and I know him personally, or any other conditions. If I had a good friend in the Kingdom who voted by phone for example. Normally, there shouldn't be any MManual votes anymore.
psc is when they votes themselves. Witt is on a witt post, mail is by email (with the PSC), wittpsc is if they vote on Witt with their PSC, something we abandonned, and finally wittmsg is when they vote in a private message, a last resort option.
But if the person is NOT in the SoS Office, then a hidden field forces the method to psc.
echo '</fieldset>';
echo '<fieldset>';
echo '<h3>Part 3: Cosa Election</h3>'; echo '<h3><i>Pärts 3: Eleziun per la Cosa</i></h3>';
echo '<div class="alert alert-info"><p>Enter the Initials of the party you want to vote for.</p><p>You can vote for a non-registered party, but unless that part later registers, you risk having your vote discarded.</p>
<p><i>Complätsetz els iniziais del parti per qet voi veletz votarh.
Voi pevetz votarh per \'n parti inenrexhistrat, mas salva q\'acest parti enrexhistradra pü schpeit, voi
rischetz qe voastra vota estadra dropada.</i></p>
</div>';
echo BootstrapTextField('Party Vote:', 'party', $_POST);
echo '<p><br />If you do not wish to vote for a party, but do not wish either to lose your citizenship, indicate "PRESENT" for the Party Vote.</p>';
echo '<p><br /><i>Schi voi non veletz ni votarh pr\'iens parti, ni pierdarh voastra citaxhienità, inidicarh \'n vota da “PRESINT” per la Vota pr\'iens Parti.</i></p>';
This part is simple: it's HTML and a single field asking for the party vote.
$res = mysql_query('SELECT * FROm RegisteredParties WHERE CosaNumber='. $cosa);
if ( $res && mysql_num_rows($res) > 0 ){ echo '<h3>Registered Parties</h3>'; echo '<table class="table table-bordered">'; echo '<tr><th>Initials</th><th>Name</th><th>Statement</th><th>Leader(s)</th></tr>';
while ( $row = mysql_fetch_assoc($res)){
echo '<tr>';
echo '<td>'. $row['PartyInitials'].'</td>'; echo '<td>'. $row['PartyName'].'</td>'; echo '<td>'. $row['Statement'].'</td>'; echo '<td>'. $row['leaders'].'</td>';
echo '</tr>';
} echo '</table>';
}
Here, we load from the database the lost of Registered parties and output the data about them. The URL and the Candidate list will be added here in the next few days.
echo '</fieldset>';
echo '<fieldset>'; echo '<h3>Part 4: Confidentiality</h3>';
echo '<h3><i>Pärts 4: Intimatità</i></h3>';
echo Bootstrapfield('Do you want your vote to be public <br><i>¿Veletz-voi qe voastra vota estadra püblíc?</i>', "<select NAME=\"secret\" size=\"1\" >\n<option selected>No</option>\n<option>Yes</option>\n </select>\n ") ;
echo '<div class="alert-info alert"><p>Select "Yes" if the voter posted on Wittenberg</p><p><i>Selectetz “Üc” schi el voteir posteva sür Wittenberg</i></p></div>';
echo '</fieldset>';
echo '<fieldset>';
This is always pretty straightforward. We ask if the code is public or not, with Not public by default. We remind that if they already voted on Witt, it's useless to say it's private...
/******************************************************************* Referendums *******************************************************************/
$PreviousCosa = $cosa-1;
$Referendum = mysql_query( "select * From BillReferendum,Bills where BillReferendum.CosaVoted=".$cosa." AND BillReferendum.CosaNumber = Bills.CosaNumber AND BillReferendum.BillNumber=Bills.BillNumber ORDER BY Bills.CosaNumber,Bills.BillNumber");
Ok, this query is a little complicated.
We retrieve from the database records from the BillReferendum and the Bills tables.
We only want:
- Referendums voted in the current cosa - Bills which have the same cosanumber and bill number as a Referendum
And we want them shown in order of original Cosa, and then, by BillNumber.
$num = mysql_numrows($Referendum );
if ( $num > 0 ) { echo "<h3>Part 5: Referendums</h3>"; echo '<h3><i>Pärts 5: Referendüms</i></p>'; echo '<div class="alert alert-info"><p>The following bills requiring a referendum were adopted by the Ziu during the last Cosâ.</p> <p><i>Els proxhets sovinds qi resquirent \'n referendüm estevent adoptats par el Ziu dürant la Cosa lasta.</i></p></div>'; }
If there are referendum, we put a header explaining there are referendums.
$r = 0; echo "<input type=\"hidden\" NAME=\"NumberOfReferendums\" value=\"$num\" >" ;
We store the number of referendums, something we use in processing.
while ( $r < $num ) {
printf("<h3>Referendum number %d</h3>\n", $r+1); printf("<h3><i>Referendüm númerul %d</i></h3>\n", $r+1);
$BillNumber = mysql_result($Referendum,$r,"Bills.BillNumber"); $BillTitle = mysql_result($Referendum,$r,"BillTitle"); $CosaOfBill = mysql_result($Referendum,$r,"BillReferendum.CosaNumber"); echo Bootstrapfield( sprintf("\n%dth Cosâ RZ%d:", $CosaOfBill, $BillNumber), '<div class="static-text">'. sprintf("<a href=\"bills.php?cosa=$CosaOfBill&bill=$BillNumber\" target=\"_blank\">%s </a>\n",stripslashes(stripslashes($BillTitle)) ).'</div>');
echo GetReferendums50WordStatements($CosaOfBill, $BillNumber);
echo Bootstrapfield('Your vote<br /><i>Voastra vota</i>', "<select NAME=\"referendum[$r]\" size=\"1\" >\n<option>Për</option>\n<option>Contrâ</option>\n <option selected>Abstain</option>\n </select>\n ") ; echo '<input type="hidden" NAME="BillNumber['.$r.']" value="'.$BillNumber.'" >' ; echo '<input type="hidden" NAME="BillCosa['.$r.']" value="'.$CosaOfBill.'" >' ;
echo "<br><br>"; $r++; }
We then cycle thru each referendum, first with a title, then with a link to the text of the referendum, then, we add the Referendum50WordsStatements, and a drop down for the vote.
We finish it all with hidden fields identifying the referendum.
echo '</fieldset>';
echo '<fieldset>';
echo '<h3>Part 6: Senate Election</h3>'; echo '<h3><i>Pärts 6: Eleziun per el Senäts</i></h3>';
This is the end of the referendum section, and the start of the senator section.
$res = mysql_query('SELECT * FROM senatorendorsement,Province WHERE cosa='.$cosa.' AND province=provincenumber ORDER BY province,party'); echo mysql_error(); if ( mysql_num_rows($res) > 0 ){ echo '<h4>Senate Endorsements by political parties</h4>'; echo '<table class="table table-bordered">'; echo '<tr><th>Province</th><th>Party</th><th>Endorsement</th></tr>'; while ($row = mysql_fetch_assoc($res)){ echo '<tr>'; echo '<td>'. $row['ProvinceName'] .'</td>'; echo '<td>'. $row['party'] .'</td>'; echo '<td>'. GetCitizenNameLinked($row['candidate']) .'</td>';
echo '</tr>'; }
echo '</table>';
}
With this, we print the senate endorsements, and the name of the provinces for them.
echo BootstrapTextField('Senate Vote<br><i>Vota per el Senäts</i>:', 'senatevote', $_POST); echo '</fieldset>';
echo '<fieldset>';
And then, we ask the vote for the Senate.
echo '<h3>Part 7: Provincial Election</h3>'; echo '<h3><i>Pärts 7: Eleziun Provincial</i></h3>';
echo BootstrapTextField('Provincial Vote<br /><i>Vota provincial</i>:', 'provincialvote', $_POST); echo '</fieldset>';
This is the provincial vote section. It's the simpliest, nothing fancy...
echo Bootstrapfield('', ' <input type="submit" name="Submit" value="Submit" class="btn btn-primary">');
echo '</form>';
And we close the form, with the Submit buttom
}
include('dbfooter.html');
?>
And we finish the script with the dbfooter.html!
And this is it!
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 30, 2015 5:24:45 GMT -6
Now that the full audit of that script was done, I have commented out the extract($_POST); from the top!
It's clear it's not needed for this script, and that takes take of the only security issue.
So, in summary:
1 ) To accept a vote, the first 8 letters of the PSC is ABSOLUTELY needed, even for the SoS. I can't even bypass that, and only the voter and the SoS can see the PSC. Not even the Judges on the Electoral Commission see it. 2 ) With the vote comes the IP address, user agent, timestamp, and as such, even if someone gets a hold of a PSC of someone else, he would need a VPN to mask his ip. 3 ) If the PSC doesn't match, I get an email warning me, and as such, I can intervene. I even tried to do so in the last election. 4 ) This also means that if someone creates a script to try all of the PSCs for a citizen, I will know and will be able to intervene. 5 ) A receipt is always sent, unless the user doesn't have an email address in the DB' but if he doesn't, he didn't get his PSC!
|
|
Dr. Txec dal Nordselvă
Puisne (Associate) Justice of the Uppermost Court
Fraichetz dels punts, es non dels mürs
Posts: 4,063
Talossan Since: 9-23-2012
|
Post by Dr. Txec dal Nordselvă on Dec 30, 2015 8:17:33 GMT -6
Very thorough.
|
|
|
Post by Marti-Pair Furxheir S.H. on Dec 30, 2015 9:40:28 GMT -6
Thanks! I will probably do something similar, on a smaller scale, with the election listing script, just to be 100% transparent. But honestly, I feel like what I disclosed should be enough to certify that the automated voting form works the way it is supposed to, and there only the proper voter can vote, and if the SoS can enter a vote, but then, it will be stored that the SoS entered the vote! For example, here is a vote, that was made on Witt (and as such, is public), that was entered by me: You can see my username (since I used my SoS login to enter the vote), my then Ip Address (it changed since), my Browser, the date and time, the method, etc.. If the user voted himself (or herself in this case, a public vote made in the database): My username isn't there, and the IP address is different from mine (obviously I blacked it out) and the useragent is also different. Of course, if you go to : www.talossa.ca/files/election_result.php?cosa=48&sorting=NameWithout being on the Electoral Commission, all you will see is the validation and the votes (or Secret).
|
|
|
Post by Marti-Pair Furxheir S.H. on Jan 6, 2016 4:34:52 GMT -6
Remember, members of the Electoral Commission, that you need to certify this script before February 15th... so ask any questions!
|
|
|
Post by Marti-Pair Furxheir S.H. on Jan 6, 2016 4:53:03 GMT -6
|
|