View Issue Details

IDProjectCategoryView StatusLast Update
0000337Main CAcert Websitecertificate issuingpublic2013-01-14 20:33
ReporterSourcerer Assigned ToSourcerer  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Fixed in Version2007 
Summary0000337: Race condition in the Database
DescriptionFirst we insert the half-finished row into the database:
The problem is that the Communication Module is running asynchronously, and can read the record already when the CSR isn´t written to the file yet, and before the CSR_NAME in the table is set properly.
Now the nasty problem is that we have a couple of dependencies here:
We first need the insert_id to create the filename.
We need the filename to write the CSR to the file
We need the file to be loaded by the Communication Module
The Communication Module needs the record in the table (and acts upon it as soon as it finds it).
For Perl, the CounterFile provides a flexible, rock-solid counter which would solve that problem, but PHP doesn´t have something like that yet.

                        $query = "insert into `emailcerts` set `CN`='$defaultemail', `keytype`='NS',
                                                `memid`='".$_SESSION['profile']['id']."',
                                                `created`=FROM_UNIXTIME(UNIX_TIMESTAMP()),
                                                `codesign`='".$_SESSION['_config']['codesign']."',
                                                `rootcert`='".$_SESSION['_config']['rootcert']."'";
                        mysql_query($query);
                        $emailid = mysql_insert_id();
                        if(is_array($addys))
                        foreach($addys as $addy)
                                mysql_query("insert into `emaillink` set `emailcertsid`='$emailid', `emailid`='$addy'");
                        $CSRname = $_SESSION['_config']['filepath']."/csr/client-$emailid.csr";
                        $fp = fopen($CSRname, "w");
                        fputs($fp, $emails);
                        fclose($fp);
                        mysql_query("update `emailcerts` set `csr_name`='$CSRname' where `id`='$emailid'");
TagsNo tags attached.
Reviewed by
Test Instructions

Activities

duane

2006-09-27 02:03

developer   ~0000689

locking the table from read/writes should solve this regardless of language.

Sourcerer

2006-11-28 02:57

administrator   ~0000739

I have implemented the following solution in the new CommModule:

At first the row is inserted with an empty csr_filename.
The Row-ID is used to generate the filename.
The file is written to the filename.
When everything is ok, the row is updated, and the csr_filename is inserted.

The CommModule waits for rows that have the csr_filename not null.

The same concept is done in the other direction with the crt_filename.

This way, it is a safe and secure solution.

The necessary updates are included in the CommModule. Do you want the updates seperated, so that we can do that update now, seperately from the CommModule?

Sourcerer

2007-07-30 21:18

administrator   ~0000885

Has been fixed.

Issue History

Date Modified Username Field Change
2006-09-27 01:55 Sourcerer New Issue
2006-09-27 02:03 duane Note Added: 0000689
2006-11-27 13:19 duane Status new => needs work
2006-11-27 13:19 duane Assigned To => Sourcerer
2006-11-28 02:57 Sourcerer Note Added: 0000739
2007-07-30 21:18 Sourcerer Status needs work => closed
2007-07-30 21:18 Sourcerer Note Added: 0000885
2007-07-30 21:18 Sourcerer Resolution open => fixed
2007-07-30 21:18 Sourcerer Fixed in Version => production
2013-01-14 20:33 Werner Dworak Fixed in Version => 2007