コード例 #1
0
ファイル: batch.c プロジェクト: patcon/eVACS
int resolve_polling_place_code(PGconn *conn,const char *polling_place_name)
{
    return(SQL_singleton_int(conn,
                             "SELECT code FROM polling_place "
                             "WHERE UPPER(name) = UPPER('%s');",
                             polling_place_name));
}
コード例 #2
0
ファイル: batch.c プロジェクト: patcon/eVACS
int resolve_electorate_code(PGconn *conn,const char *electorate_name)
{
    return(SQL_singleton_int(conn,
                             "SELECT code FROM electorate "
                             "WHERE UPPER(name) = UPPER('%s');",
                             electorate_name));
}
コード例 #3
0
ファイル: batch.c プロジェクト: darg0001/evoting-systems
/* DDS3.6: Get Entered Papers 
   from v2B */
struct batch *get_entered_batch(PGconn *conn, 
				unsigned int batch_number)
     /*
       Return all preferences for the given batch number
     */

{
	PGresult *result;
	struct batch *head=NULL, *tmp=NULL;
	struct predefined_batch *batch;
	char *electorate_name;
	unsigned int num_papers,electorate_code;

	/* get electorate code */
	batch = resolve_batch_source(conn, batch_number);
	electorate_code = batch->electorate_code;

	/* get electorate name in order to access that Electorates
	   preference table */
	electorate_name = resolve_electorate_name(conn,electorate_code);

	num_papers = (unsigned int )SQL_singleton_int(conn,
				      "SELECT COUNT(*) "
				      "FROM %s_paper "
				      "WHERE batch_number = %u;",
				      electorate_name, batch_number);

	/* build the batch structure */
	tmp = malloc(sizeof(*tmp) + (sizeof(tmp->papers[0]) * num_papers));

	tmp->b.batch_number = batch_number;

	result = SQL_query(conn,
			   "SELECT size, committed "
			   "FROM batch "
			   "WHERE number = %u;", batch_number);

	tmp->b.batch_size = atoi(PQgetvalue(result, 0, 0));
	tmp->b.num_papers = num_papers;

	if (*PQgetvalue(result,0,1) == 't')
		tmp->b.committed = true;
	else
		tmp->b.committed = false;

        /* papers and sub-structures inserted into tmp */
	if (num_papers > 0)
	        get_papers_for_batch(conn, tmp, electorate_name);

	tmp->next = NULL;
	head = tmp;

	
	PQclear(result);
	free(electorate_name);
        return head;
}
コード例 #4
0
ファイル: batch.c プロジェクト: darg0001/evoting-systems
int get_batch_size(PGconn *conn, 
		   unsigned int batch_number) 
{
	int batch_size;
	
	batch_size=SQL_singleton_int(conn,
				     "SELECT size FROM batch "
				     "WHERE number = %u;",
				     batch_number);
	return(batch_size);
}
コード例 #5
0
ファイル: batch.c プロジェクト: darg0001/evoting-systems
/* DDSv2C: Get Paper  */
struct paper *get_paper(PGconn *conn, 
			unsigned int batch_number, 
			unsigned int paper_index)

{
	struct paper *ret;
	unsigned int paper_id, electorate_code;
	char *electorate_name, *paper_table_name;
	struct predefined_batch *batch;

	/* get electorate code */
	batch = resolve_batch_source(conn, batch_number);
	assert(batch);
	electorate_code = batch->electorate_code;

	/* get electorate name in order to access that Electorates
	   paper and entry tables */
	electorate_name = resolve_electorate_name(conn,electorate_code);
	paper_table_name = sprintf_malloc("%s_paper",electorate_name);
	
	
	/* find the (internal database) paper_id */
	paper_id = SQL_singleton_int(conn,
				     "SELECT id "
				     "FROM %s "
				     "WHERE batch_number = %u "
				     "AND index = %u;",
				     paper_table_name, 
				     batch_number, paper_index);

	ret = malloc(sizeof(*ret));

	if (paper_id ==(unsigned int) -1) {
	  /* new paper  */
	    ret->p.index = paper_index;
	    ret->p.supervisor_tick = false;
	    ret->entries = NULL;
	} else {
	        ret = malloc(sizeof(*ret));
	        ret->entries = get_entries_for_paper(conn, paper_id,
						     electorate_name);
	}

	free(electorate_name);
	free(paper_table_name);
	free(batch);
	
	return ret;
}
コード例 #6
0
ファイル: batch.c プロジェクト: patcon/eVACS
/* DDSv2C: Get Paper  */
struct paper *get_paper(unsigned int batch_number, unsigned int paper_index)

{
    PGconn *conn = connect_db_host(DATABASE_NAME, SERVER_ADDRESS);
    struct paper *ret;
    unsigned int paper_id, electorate_code;
    char *electorate_table_name;
    struct predefined_batch *batch;

    /* get electorate code */
    batch = resolve_batch_source(conn, batch_number);
    electorate_code = batch->electorate_code;

    /* get electorate name in order to access that Electorates
       preference table */
    electorate_table_name = resolve_electorate_name(conn,electorate_code);


    /* find the (internal database) paper_id */
    paper_id = SQL_singleton_int(conn,
                                 "SELECT id "
                                 "FROM paper "
                                 "WHERE batch_number = %u "
                                 "AND index = %u;",
                                 batch_number, paper_index);

    ret = malloc(sizeof(*ret));

    if (paper_id ==(unsigned int) -1) {
        /* new paper  */
        ret->p.index = paper_index;
        ret->p.supervisor_tick = false;
        ret->entries = NULL;
    } else {
        ret = malloc(sizeof(*ret));
        ret->entries = get_entries_for_paper(conn, paper_id,
                                             electorate_table_name);
    }

    free(electorate_table_name);
    PQfinish(conn);

    return ret;
}
コード例 #7
0
ファイル: batch.c プロジェクト: darg0001/evoting-systems
extern void update_active_entries(PGconn *conn, 
			   unsigned int batch_number,
			   unsigned int paper_index,
			   int preferred_entry_to_replace,
			   const char *electorate_name)
{
	int temp;
	unsigned int num_entries,match_code,entry_to_replace;
	int paper_id;
	
	paper_id = SQL_singleton_int(conn,
				     "SELECT id "
				     "FROM %s_paper "
				     "WHERE batch_number = %u "
				     "AND index = %u; ",
				     electorate_name,
				     batch_number,paper_index);
	num_entries= (unsigned int)
		SQL_singleton_int(conn,
				  "SELECT MAX(e.index) "
				  "FROM %s_entry e,%s_paper p "
				  "WHERE p.batch_number = %u "
				  "AND e.paper_id = p.id "
				  "AND p.id = %u; ",
				  electorate_name,electorate_name,
				  batch_number,paper_id);
	
	/* if only 1 or two entries, make new entry active */
	if (num_entries < 3) {
		entry_to_replace = num_entries;
                if (entry_to_replace == 1) {

                  temp = (unsigned int)
                    SQL_singleton_int(conn,
                                      "SELECT MAX(e.index) "
                                      "FROM %s_entry e, %s_paper p "
                                      "WHERE p.batch_number = %u "
                                      "AND e.paper_id = p.id "
                                      "AND e.operator_id = '%s';",
                                      electorate_name, electorate_name,
                                      batch_number, get_operator_id());
                  if (temp == 2) {
                    entry_to_replace = temp;
                  }
                }
	} else {
		/* returns either matching active entry OR 
		 3 = both matched, 4 = neither matched*/
		match_code = 
			match_active_entries(conn,
					     (char *)electorate_name,
					     paper_id);
		if (match_code == 1 || match_code == 2) {
			/* only one active entry matched;  replace the other */
			entry_to_replace=(3-match_code);
		} else {
			if (strncmp(get_operator_id(),"super",5) ==0) {
			/* user is SUPER and either both or neither matched: */
			/* replace 1st active entry (arbitrary choice) */
	              if (preferred_entry_to_replace < 0)
                        entry_to_replace = (unsigned int)
                          (-1 * preferred_entry_to_replace);
                      else
                        entry_to_replace = (unsigned int)
                          preferred_entry_to_replace;
			} else {
				/* normal user and both or neither matched: */
				/* leave active entries unchanged */
				entry_to_replace = 0;
			}
		}
	}
        if (preferred_entry_to_replace < 0) {
          /*
            When preferred_entry_to_replace is less than zero, then
            abs(preferred_entry_to_be_replace) is to be used as the
            entry index.
          */

	  /* SIPL 2011-09-26 Add parentheses to adjust the "order" of
	     evaluation.  In fact, it makes no difference because
	     of two's complement arithmetic.  But it is now consistent
	     with the previous similar assignment statement. */
	  entry_to_replace = (unsigned int) (-1 * preferred_entry_to_replace);
        }

	/* do the replacement if required */
	if (entry_to_replace > 0) 
		replace_active_entry(conn, batch_number, paper_index,
				     electorate_name, 
				     paper_id, entry_to_replace, 
				     num_entries);
}
コード例 #8
0
ファイル: batch.c プロジェクト: darg0001/evoting-systems
void append_entry(PGconn *conn,
		  struct entry *newentry,
		  unsigned int batch_number,
		  unsigned int paper_index)
     /*
       Insert the entry into the database.
     */
{	
	char *electorate_name, *entry_table_name, *paper_table_name;
        int  paper_id=-1;
        int temp;
	unsigned int i,entry_index;
	/* SIPL 2011-09-26 Increase array size by one to allow
	   space for null at end, to cope with the case where there
	   really are PREFNUM_MAX preferences in the vote. */
	char pref_string[DIGITS_PER_PREF * PREFNUM_MAX + 1];
	char *pref_ptr, *p;
	struct predefined_batch *batch;

	/* get electorate code */
        batch =resolve_batch_source(conn, batch_number);
	electorate_name = resolve_electorate_name(conn, batch->electorate_code);
	if (batch->electorate_code < 0)
		bailout("append_entry could not find batch number %u.\n",
			batch_number);

	/* get electorate name in order to access that Electorates'
	   paper and entry tables */
	paper_table_name = sprintf_malloc("%s_paper",electorate_name);	
	entry_table_name = sprintf_malloc("%s_entry",electorate_name);

	/* Start the transaction */
	begin(conn);

	/* check paper exists */
	paper_id = SQL_singleton_int(conn,
				     "SELECT id "
				     "FROM %s_paper "
				     "WHERE batch_number = %u "
				     "AND index = %u; ",
				     electorate_name,
				     batch_number,paper_index);

	/* Insert new paper if necessary */
	if (paper_id < 0) {
	        SQL_command(conn,
			    "INSERT INTO "
			    "%s(batch_number,index) "
			    "VALUES(%u,%u);",
			    paper_table_name,batch_number,paper_index);
		entry_index = 1;
		paper_id = 
			SQL_singleton_int(conn,"SELECT CURRVAL('%s_id_seq');",
					  paper_table_name);

	}
	else {
	        /* Get last (archived) entry index for this paper */
	        entry_index = SQL_singleton_int(conn,
						"SELECT MAX(index) FROM %s "
						"WHERE paper_id = %d;",
						entry_table_name, paper_id);
		if (entry_index < 0)
		        entry_index = 1;   /* It must be the first one */
		else
		        entry_index++;

	}
	
        if (entry_index == 1) {

          /* Check for the case there this is actually entry_index=2, and
             where there is no entry_index=1.
          */

          temp = (unsigned int)
            SQL_singleton_int(conn,
                              "SELECT MAX(e.index) "
                              "FROM %s_entry e, %s_paper p "
                              "WHERE p.batch_number = %u "
                              "AND e.paper_id     = p.id "
                              "AND e.operator_id  = '%s';",
                              electorate_name, electorate_name,
                              batch_number,    get_operator_id());
          if (temp == 2) {
            /* This paper's belongs to entry index 2, not 1. */
            entry_index = 2;
          }
        }

	/* Format the preferences into a string */
	pref_string[0]='\0';
	pref_ptr = &pref_string[0];
	for (i=0;i<newentry->e.num_preferences;i++) {
		p = sprintf_malloc("%02u%02u%02u",
				   newentry->preferences[i].prefnum,
				   newentry->preferences[i].group_index,
				   newentry->preferences[i].db_candidate_index
				   );
		strcpy(pref_ptr,p);
		pref_ptr +=  (sizeof(char)*(DIGITS_PER_PREF));
		free(p);
	}	
        /* Insert new entry into archive */
	SQL_command(conn,
		    "INSERT INTO %s(index,operator_id,"
		    "paper_id,num_preferences,paper_version,preference_list) "
		    "VALUES(%u,'%s',%u,%u,%u,'%s');",
		    entry_table_name, entry_index,
		    newentry->e.operator_id,
		    paper_id,newentry->e.num_preferences,
		    newentry->e.paper_version_num,
		    &pref_string[0]);

	/* update active entries */
	update_active_entries(conn,
			      batch_number,
			      paper_index,
			      1, // arbitrary, could be 2
			     (const char *)  electorate_name);

	free(electorate_name);
	free(paper_table_name);
	free(entry_table_name);
	free(batch);
	/* Complete the transaction */
	commit(conn);
}
コード例 #9
0
ファイル: batch.c プロジェクト: patcon/eVACS
void append_entry(PGconn *conn,struct entry *newentry,
                  unsigned int batch_number,unsigned int paper_index,
                  unsigned int paper_version)
/*
  Insert the entry into the database.
*/
{
    char *table_name,*oi;
    int electorate_code;
    int paper_id,entry_index=1,i;

    /* get electorate code */
    electorate_code = SQL_singleton_int(conn,
                                        "SELECT electorate_code "
                                        "FROM batch "
                                        "WHERE number = %u;",
                                        batch_number);
    if (electorate_code < 0)
        bailout("append_entry could not find batch number %u.\n",
                batch_number);

    /* get electorate name in order to access that Electorates
       preference table */
    table_name = resolve_electorate_name(conn,electorate_code);

    /* Start the transaction */
    begin(conn);

    /* Check paper exists */
    paper_id = SQL_singleton_int(conn,
                                 "SELECT id FROM paper WHERE index = %u "
                                 "AND batch_number = %u;",
                                 paper_index,batch_number);

    /* Insert new paper if necessary */
    if (paper_id < 0) {
        SQL_command(conn,
                    "INSERT INTO "
                    "paper(batch_number,index) "
                    "VALUES(%u,%u);",batch_number,paper_index);
        entry_index = 1;
        paper_id = get_seq_currval(conn,"paper_id_seq");

    }
    else {
        /* Get last entry index for this paper */
        entry_index = SQL_singleton_int(conn,
                                        "SELECT MAX(index) FROM entry "
                                        "WHERE paper_id = %d;",
                                        paper_id);
        if (entry_index < 0)
            entry_index = 1;   /* It must be the first one */
        else
            entry_index++;

    }

    /* Insert new entry */
    SQL_command(conn,
                "INSERT INTO entry(index,operator_id,"
                "paper_id,num_preferences,paper_version) "
                "VALUES(%u,'%s',%u,%u,%u);",
                entry_index,oi=eq_malloc(newentry->e.operator_id),
                paper_id,newentry->e.num_preferences,paper_version);
    free(oi);
    /* Insert the preferences */
    for (i=0; i<newentry->e.num_preferences; i++) {
        SQL_command(conn,
                    "INSERT INTO %s "
                    "VALUES(CURRVAL('entry_id_seq'),%u,%u,%u);",
                    table_name,
                    newentry->preferences[i].group_index,
                    newentry->preferences[i].db_candidate_index,
                    newentry->preferences[i].prefnum);
    }
    /* Complete the transaction */
    commit(conn);
}
コード例 #10
0
ファイル: authenticate.c プロジェクト: patcon/eVACS
/* DDS3.2.3: Authenticate */
int main(int argc, char *argv[])
{
	struct http_vars *vars;
	struct barcode_hash_entry *bcentry;
	struct barcode bc;
	char bchash[HASH_BITS+1];
	struct electorate *elecs, *i;
	PGconn *conn;
	int ppcode;

	/* Our own failure function */
	set_cgi_bailout();

	/* Can be called on slave as well as master */
	conn = connect_db_port("evacs", get_database_port());
	if (!conn) bailout("Could not open database connection\n");

	/* Copy barcode ascii code from POST arguments */
	vars = cgi_get_arguments();
	strncpy(bc.ascii, http_string(vars, "barcode"), sizeof(bc.ascii)-1);
	bc.ascii[sizeof(bc.ascii)-1] = '\0';
	http_free(vars);

	/* Extract data and checksum from ascii */
	if (!bar_decode_ascii(&bc))
		cgi_error_response(ERR_BARCODE_MISREAD);

	/* Hash the barcode to look up in the table */
	gen_hash(bchash, bc.data, sizeof(bc.data));

	bcentry = get_bhash_table(conn, bchash);
	if (!bcentry) {
		PQfinish(conn);
		fprintf(stderr, "Barcode `%s' not found\n", bc.ascii);
		cgi_error_response(ERR_BARCODE_AUTHENTICATION_FAILED);
	}

	/* DDS3.2.4: Check Unused */
	if (bcentry->used) {
		PQfinish(conn);
		fprintf(stderr, "Barcode `%s' already used\n", bc.ascii);
		cgi_error_response(ERR_BARCODE_USED);
	}

	ppcode = SQL_singleton_int(conn,"SELECT polling_place_code "
				   "FROM server_parameter;");
	if (ppcode < 0) {
		PQfinish(conn);
		cgi_error_response(ERR_SERVER_INTERNAL);
	}

	if (ppcode != bcentry->ppcode) {
		PQfinish(conn);
		cgi_error_response(ERR_BARCODE_PP_INCORRECT);
	}

	elecs = get_electorates(conn);
	for (i = elecs; i; i = i->next) {
		if (i->code == bcentry->ecode) {
			/* Found it! */
			vars = create_response(conn, i);
			free_electorates(elecs);
			PQfinish(conn);
			cgi_good_response(vars);
		}
	}

	/* Should never happen */
	free_electorates(elecs);
	PQfinish(conn);
	bailout("Barcode electorate %u not found\n", bcentry->ecode);
}
コード例 #11
0
/* DDS3.2.26: Commit Vote */
int main(int argc, char *argv[])
{
	struct http_vars *vars;
	const char *keystrokes;
	/* SIPL 2011-09-23 Addressed potential for buffer overflow.
	   The array size was 10.  Now increased to 26,
	   to allow for up to 11 values in the rotation. */
	char rot_string[26]="{";
	char *rot_ptr=&rot_string[1],*r;
	struct preference_set prefs;
	struct rotation rot;
	struct electorate *elec;
	struct barcode bc;
	int c;
	enum error err;
	unsigned int i;
	PGconn *conn;
	

	fprintf(stderr,"commit_vote:Starting commit\n");
	/* Tell the other functions to use our bailout code */
	set_cgi_bailout();
	fprintf(stderr,"commit_vote:Set bailout\n");
	fprintf(stderr,"commit_vote:get_database_port() will return %s\n",get_database_port());
	
	conn = connect_db_port("evacs", get_database_port());
	
	fprintf(stderr,"commit_vote:Got port: %s\n",get_database_port());
	/* Don't free this: we keep pointers into it */
	vars = cgi_get_arguments();
	fprintf(stderr,"commit_vote:Got args\n");
	
	/* Unwrap CGI variables */
	strncpy(bc.ascii, http_string(vars, "barcode"), sizeof(bc.ascii)-1);
	bc.ascii[sizeof(bc.ascii)-1] = '\0';
	if (!bar_decode_ascii(&bc))
		cgi_error_response(ERR_BARCODE_MISREAD);

	fprintf(stderr,"commit_vote:unwrapped CGI vars\n");
	
	elec = find_electorate(&bc);
	fprintf(stderr,"commit_vote:found electorate\n");

	keystrokes = http_string(vars, "keystrokes");
	fprintf(stderr,"commit_vote:got keystrokes\n");
	prefs = unwrap_vote(http_string(vars, "vote"));
	fprintf(stderr,"commit_vote:unwrapped vote\n");
	rot = decode_rotation(vars, elec->num_seats);
	
	fprintf(stderr,"commit_vote:Decoded Rotation OK\n");
	/* determine the paper version from the rotation */
	for (i=0; i<elec->num_seats; i++) {
		r=sprintf_malloc("%u,",rot.rotations[i]);
		strcpy(rot_ptr,r);
		rot_ptr+=(2*sizeof(char));
		free(r);
	}
	rot_ptr-=(sizeof(char));
	strcpy(rot_ptr,(const char *)"}");

	fprintf(stderr,"commit_vote:rotation string: '%s'\n",&rot_string[0]);

	prefs.paper_version =SQL_singleton_int(conn,
					 "SELECT rotation_num FROM robson_rotation_%u "
					 "WHERE rotation = '%s';",elec->num_seats, rot_string
		);
	
	fprintf(stderr,"commit_vote:rotation number: '%u'\n",prefs.paper_version);
	
	/* Sanity check - there must be a rotation which matches */
	if (prefs.paper_version < 1)
		cgi_error_response(ERR_SERVER_INTERNAL);

	fprintf(stderr,"commit_vote:reconstructing vote\n");

	/* Determine the initial cursor position */
	c = get_cursor(vars);
	
	/* Compare vote they gave with reconstructed voter keystrokes */
	if (!reconstruct_and_compare(&rot, keystrokes, &prefs, c)) {
		fprintf(stderr,"%s: Reconstructed keystrokes do not match\n",
			am_i_master() ? "master" : "slave");
		cgi_error_response(ERR_RECONSTRUCTION_FAILED);
	}

	/* Do the actual verification and commit */
	fprintf(stderr,"commit_vote:doing actual commit\n");
	
	err = save_and_verify(conn, &prefs, &bc, elec, vars);
	fprintf(stderr,"commit_vote:commit complete\n");

	
	/* Cleanup */
	http_free(vars);
	PQfinish(conn);

	/* This will be an OK response if err = ERR_OK */
	cgi_error_response(err);

	return(0);
}