mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=10303
This commit is contained in:
parent
089f44cd0d
commit
36333729f8
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
require_once("docutil.php");
|
||||||
|
page_head("Controlling account creation");
|
||||||
|
echo "
|
||||||
|
Under normal circumstances BOINC projects are open
|
||||||
|
for participation by anybody who wants to contribute their computer
|
||||||
|
to the project.
|
||||||
|
There may be times, however, when a project needs
|
||||||
|
to limit the creation of new accounts.
|
||||||
|
BOINC offers two alternatives.
|
||||||
|
|
||||||
|
<h2>Disabling account creation</h2>
|
||||||
|
|
||||||
|
To disable all account creation,
|
||||||
|
edit the project configuration file config.xml and add to it the element:
|
||||||
|
<pre>
|
||||||
|
<disable_account_creation>1</disable_account_creation>
|
||||||
|
</pre>
|
||||||
|
This disables account creation via any mechanism
|
||||||
|
(the client, the web, or account managers).
|
||||||
|
You can momentarily remove this element while you create accounts.
|
||||||
|
|
||||||
|
<h2>Restricting account creation via 'invitation codes'</h2>
|
||||||
|
<p>
|
||||||
|
It is also possible to restrict account creation to only those
|
||||||
|
who present a secret 'invitation code'.
|
||||||
|
In this case an account can only be created via the web pages,
|
||||||
|
not via the client or an account manager.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To use this mechanism you need to add to the file html/project/project.inc
|
||||||
|
a definition for a PHP pre-processor symbol INVITE_CODES
|
||||||
|
containing the allowed invitation codes.
|
||||||
|
A simple example is:
|
||||||
|
<pre>
|
||||||
|
define('INVITE_CODES', '/xyzzy/');
|
||||||
|
</pre>
|
||||||
|
This allows account creation only if the user enters the invitation code
|
||||||
|
'xyzzy' (without any quotes).
|
||||||
|
The pattern in INVITE_CODES is compared to the user's input as a
|
||||||
|
<a href=http://us2.php.net/manual/en/reference.pcre.pattern.syntax.php>Perl-Compatible Regular Expression (PCRE)</a>,
|
||||||
|
so don't forget the enclosing slashes.
|
||||||
|
A more complicated example is:
|
||||||
|
<pre>
|
||||||
|
define('INVITE_CODES', '/yohoho|blunderbuss|!grog4U/');
|
||||||
|
</pre>
|
||||||
|
In a PCRE vertical bars separate alternatives,
|
||||||
|
so this pattern just allows someone to create an account
|
||||||
|
if they enter any of the words 'yohoho', 'blunderbuss', or '!grog4U'.
|
||||||
|
More complex pattern matching is possible, though not required.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The security of this mechanism depends on how
|
||||||
|
you distribute the invitation codes.
|
||||||
|
If you write the code on the whiteboard in your lab then only
|
||||||
|
someone with access to that room can use it.
|
||||||
|
If you send it out to a mailing list then only members of that list can use it
|
||||||
|
(until someone shares it with someone else who is not on the list).
|
||||||
|
The goal here is not strict security so much as a way for a new project
|
||||||
|
to limit account creation to a restricted set of users
|
||||||
|
while the project is getting started.
|
||||||
|
";
|
||||||
|
page_tail();
|
||||||
|
?>
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
require_once("docutil.php");
|
||||||
|
page_head("Advanced validator framework");
|
||||||
|
|
||||||
|
echo "
|
||||||
|
To make a validator program using the advanced framework, link validator.C
|
||||||
|
with two application-specific functions:
|
||||||
|
<pre>",
|
||||||
|
htmlspecialchars("
|
||||||
|
int check_set(
|
||||||
|
vector<RESULT> results, DB_WORKUNIT& wu, int& canonicalid,
|
||||||
|
double& credit, bool& retry
|
||||||
|
);
|
||||||
|
"),
|
||||||
|
"</pre>
|
||||||
|
<ul>
|
||||||
|
<li><b>check_set()</b> takes a set of results (all with outcome=SUCCESS).
|
||||||
|
It reads and compares their output files.
|
||||||
|
If there is a quorum of matching results,
|
||||||
|
it selects one of them as the canonical result, returning its ID.
|
||||||
|
In this case it also returns the credit to
|
||||||
|
be granted for correct results for this workunit.
|
||||||
|
|
||||||
|
<li>
|
||||||
|
If, when an output file for a result has a nonrecoverable error
|
||||||
|
(e.g. the directory is there but the file isn't,
|
||||||
|
or the file is present but has invalid contents),
|
||||||
|
then it must set the result's outcome (in memory, not database)
|
||||||
|
to outcome=RESULT_OUTCOME_VALIDATE_ERROR and validate_state=VALIDATE_STATE_INVALID.
|
||||||
|
<p>
|
||||||
|
Note: use BOINC's
|
||||||
|
<a href=backend_util.php>back-end utility functions</a>
|
||||||
|
to get file pathnames
|
||||||
|
and to distinguish recoverable and nonrecoverable file-open errors.
|
||||||
|
<li>
|
||||||
|
If a canonical result is found, check_set() must set the
|
||||||
|
validate_state field of each non-ERROR result
|
||||||
|
(in memory, not database) to either validate_state=VALIDATE_STATE_VALID
|
||||||
|
or validate_state=VALIDATE_STATE_INVALID.
|
||||||
|
|
||||||
|
<li>
|
||||||
|
If a recoverable error occurs while reading output files
|
||||||
|
(e.g. a directory wasn't visible due to NFS mount failure)
|
||||||
|
then check_set() should return retry=true.
|
||||||
|
This tells the validator to arrange for this WU to be
|
||||||
|
processed again in a few hours.
|
||||||
|
<li>
|
||||||
|
check_set() should return nonzero if a major error occurs.
|
||||||
|
This tells the validator to write an error message and exit.
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<pre>",
|
||||||
|
htmlspecialchars("
|
||||||
|
int check_pair(RESULT& new_result, RESULT& canonical_result, bool& retry);
|
||||||
|
"),
|
||||||
|
"</pre>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>check_pair()</b> compares a new result to the canonical result.
|
||||||
|
In the absence of errors,
|
||||||
|
it sets the new result's validate_state to either VALIDATE_STATE_INVALID or
|
||||||
|
VALIDATE_STATE_VALID.
|
||||||
|
<li>
|
||||||
|
If it has a nonrecoverable error reading an output file of either result,
|
||||||
|
or if the new result's output file is invalid,
|
||||||
|
it must set the new result's outcome (in memory, not database)
|
||||||
|
to VALIDATE_ERROR.
|
||||||
|
<li>
|
||||||
|
If it has a recoverable error while reading an output file of either result,
|
||||||
|
it returns retry=true,
|
||||||
|
which causes the validator to arrange for the WU to be examined
|
||||||
|
again in a few hours.
|
||||||
|
<li>
|
||||||
|
check_pair() should return nonzero if a major error occurs.
|
||||||
|
This tells the validator to write an error message and exit.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Neither function should delete files or access the BOINC database.
|
||||||
|
<p>
|
||||||
|
A more detailed description is <a href=validate_logic.txt>here</a>.
|
||||||
|
";
|
||||||
|
page_tail();
|
||||||
|
?>
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once("docutil.php");
|
||||||
|
page_head("Simple validator framework");
|
||||||
|
echo "
|
||||||
|
To create a validator using the simple framework,
|
||||||
|
you must supply three functions:
|
||||||
|
"; block_start(); echo "
|
||||||
|
extern int init_result(RESULT& result, void*& data);
|
||||||
|
"; block_end(); echo "
|
||||||
|
This takes a result, reads its output file(s),
|
||||||
|
parses them into a memory structure,
|
||||||
|
and returns (via the 'data' argument) a pointer to this structure.
|
||||||
|
It returns:
|
||||||
|
<ul>
|
||||||
|
<li> Zero on success,
|
||||||
|
<li> ERR_OPENDIR if there was a transient error,
|
||||||
|
e.g. the output file is on a network volume that is not available.
|
||||||
|
The validator will try this result again later.
|
||||||
|
<li> Any other return value indicates a permanent error.
|
||||||
|
Example: an output file is missing, or has a syntax error.
|
||||||
|
The result will be marked as invalid.
|
||||||
|
</ul>
|
||||||
|
"; block_start(); echo "
|
||||||
|
extern int compare_results(
|
||||||
|
RESULT& r1, void* data`, RESULT& r2, void* data2, bool& match
|
||||||
|
);
|
||||||
|
"; block_end(); echo "
|
||||||
|
This takes two results and their associated memory structures.
|
||||||
|
It returns (via the 'match' argument) true if the two results
|
||||||
|
are equivalent (within the tolerances of the application).
|
||||||
|
"; block_start(); echo "
|
||||||
|
extern int cleanup_result(RESULT& r, void* data);
|
||||||
|
"; block_end(); echo "
|
||||||
|
This frees the structure pointed to by data, if it's non-NULL.
|
||||||
|
<p>
|
||||||
|
You must link these functions with the files
|
||||||
|
validator.C, validate_util.C, and validate_util2.C.
|
||||||
|
The result is your custom validator.
|
||||||
|
|
||||||
|
<h3>Example</h3>
|
||||||
|
Here's an example in which the output file
|
||||||
|
contains an integer and a double.
|
||||||
|
Two results are considered equivalent if the integer is equal
|
||||||
|
and the doubles differ by no more than 0.01.
|
||||||
|
<p>
|
||||||
|
This example uses utility functions
|
||||||
|
get_output_file_path() and try_fopen(),
|
||||||
|
which are documented <a href=backend_util.php>here</a>.
|
||||||
|
"; block_start(); echo "
|
||||||
|
struct DATA {
|
||||||
|
int i;
|
||||||
|
double x;
|
||||||
|
};
|
||||||
|
|
||||||
|
int init_result(RESULT& result, void*& data) {
|
||||||
|
FILE* f;
|
||||||
|
string path;
|
||||||
|
int i, n, retval;
|
||||||
|
double x;
|
||||||
|
|
||||||
|
retval = get_output_file_path(result, path);
|
||||||
|
if (retval) return retval;
|
||||||
|
retval = try_fopen(path.c_str(), f, \"r\");
|
||||||
|
if (retval) return retval;
|
||||||
|
n = fscanf(f, \"%d %f\", &i, &x);
|
||||||
|
if (n != 2) return ERR_XML_PARSE;
|
||||||
|
DATA* dp = new DATA;
|
||||||
|
dp->i = i;
|
||||||
|
dp->x = x;
|
||||||
|
data = (void*) dp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compare_results2(
|
||||||
|
RESULT& r1, void* _data1, RESULT& r2, void* _data2, bool& match
|
||||||
|
) {
|
||||||
|
DATA* data1 = (DATA*)_data1;
|
||||||
|
DATA* data2 = (DATA*)_data2;
|
||||||
|
match = true;
|
||||||
|
if (data1->i != data2->i) match = false;
|
||||||
|
if (fabs(data1->x - data2->x) > 0.01) match = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cleanup_result(RESULT& r, void* data) {
|
||||||
|
if (data) free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
"; block_end(); echo "
|
||||||
|
";
|
||||||
|
page_tail();
|
||||||
|
?>
|
Loading…
Reference in New Issue