write a warning in the template about password replacement.

for new factions, put the generated password into the template.
normalize and secure password generation.
This commit is contained in:
Enno Rehling 2019-01-12 21:26:48 +01:00
parent 2477349092
commit f96e88e3e0
10 changed files with 60 additions and 32 deletions

View File

@ -6015,6 +6015,9 @@ msgstr "Eigentümer"
msgid "nr_template" msgid "nr_template"
msgstr "Vorlage für den nächsten Zug:" msgstr "Vorlage für den nächsten Zug:"
msgid "template_password_notice"
msgstr "Achtung: Hier muss das Passwort Deiner Partei eingefügt werden."
msgctxt "skill" msgctxt "skill"
msgid "espionage" msgid "espionage"
msgstr "Spionage" msgstr "Spionage"

View File

@ -5323,6 +5323,9 @@ msgstr "Owner"
msgid "nr_template" msgid "nr_template"
msgstr "Template for the next turn:" msgstr "Template for the next turn:"
msgid "template_password_notice"
msgstr "Attention: Enter your faction's password here."
msgctxt "skill" msgctxt "skill"
msgid "espionage" msgid "espionage"
msgstr "espionage" msgstr "espionage"

View File

@ -205,10 +205,11 @@ static int unused_faction_id(void)
return id; return id;
} }
void faction_genpassword(faction *f) { char *faction_genpassword(faction *f, char *buffer) {
const char * password = itoa36(rng_int()); password_generate(buffer, 8);
faction_setpassword(f, password_hash(password, PASSWORD_DEFAULT)); faction_setpassword(f, password_hash(buffer, PASSWORD_DEFAULT));
ADDMSG(&f->msgs, msg_message("changepasswd", "value", password)); ADDMSG(&f->msgs, msg_message("changepasswd", "value", buffer));
return buffer;
} }
faction *addfaction(const char *email, const char *password, faction *addfaction(const char *email, const char *password,

View File

@ -150,7 +150,7 @@ extern "C" {
const char *faction_getemail(const struct faction *self); const char *faction_getemail(const struct faction *self);
void faction_setemail(struct faction *self, const char *email); void faction_setemail(struct faction *self, const char *email);
void faction_genpassword(struct faction *f); char *faction_genpassword(struct faction *f, char *buffer);
void faction_setpassword(struct faction *self, const char *pwhash); void faction_setpassword(struct faction *self, const char *pwhash);
const char *faction_getpassword(const struct faction *f); const char *faction_getpassword(const struct faction *f);
bool valid_race(const struct faction *f, const struct race *rc); bool valid_race(const struct faction *f, const struct race *rc);

View File

@ -1276,6 +1276,7 @@ report_template(const char *filename, report_context * ctx, const char *bom)
stream strm = { 0 }, *out = &strm; stream strm = { 0 }, *out = &strm;
char buf[4096]; char buf[4096];
sbstring sbs; sbstring sbs;
const char *password = "password";
if (F == NULL) { if (F == NULL) {
perror(filename); perror(filename);
@ -1287,12 +1288,17 @@ report_template(const char *filename, report_context * ctx, const char *bom)
swrite(bom, 1, strlen(bom), out); swrite(bom, 1, strlen(bom), out);
} }
newline(out); sprintf(buf, "; %s\n", LOC(lang, "nr_template"));
rps_nowrap(out, LOC(lang, "nr_template")); rps_nowrap(out, buf);
newline(out);
newline(out);
sprintf(buf, "%s %s \"password\"", LOC(lang, parameters[P_FACTION]), itoa36(f->no)); if (ctx->password) {
password = ctx->password;
}
else {
sprintf(buf, "; %s\n", LOC(lang, "template_password_notice"));
rps_nowrap(out, buf);
}
sprintf(buf, "%s %s \"%s\"", LOC(lang, parameters[P_FACTION]), itoa36(f->no), password);
rps_nowrap(out, buf); rps_nowrap(out, buf);
newline(out); newline(out);
newline(out); newline(out);

View File

@ -71,6 +71,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "util/log.h" #include "util/log.h"
#include "util/macros.h" #include "util/macros.h"
#include "util/path.h" #include "util/path.h"
#include "util/password.h"
#include "util/strings.h" #include "util/strings.h"
#include "util/translation.h" #include "util/translation.h"
#include <stream.h> #include <stream.h>
@ -1480,7 +1481,7 @@ void report_warnings(faction *f, int now)
* this function may also update ctx->last and ctx->first for potential * this function may also update ctx->last and ctx->first for potential
* lighthouses and travelthru reports * lighthouses and travelthru reports
*/ */
void prepare_report(report_context *ctx, faction *f) void prepare_report(report_context *ctx, faction *f, const char *password)
{ {
region *r; region *r;
static int config; static int config;
@ -1496,6 +1497,7 @@ void prepare_report(report_context *ctx, faction *f)
rule_lighthouse_units = config_get_int("rules.lighthouse.unit_capacity", 0) != 0; rule_lighthouse_units = config_get_int("rules.lighthouse.unit_capacity", 0) != 0;
} }
ctx->password = password;
ctx->f = f; ctx->f = f;
ctx->report_time = time(NULL); ctx->report_time = time(NULL);
ctx->addresses = NULL; ctx->addresses = NULL;
@ -1597,13 +1599,14 @@ int write_reports(faction * f)
struct report_context ctx; struct report_context ctx;
const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf, 0 }; const unsigned char utf8_bom[4] = { 0xef, 0xbb, 0xbf, 0 };
report_type *rtype; report_type *rtype;
char buffer[PASSWORD_MAXSIZE], *password = NULL;
if (noreports) { if (noreports) {
return false; return false;
} }
if (f->lastorders == 0) { if (f->lastorders == 0) {
faction_genpassword(f); password = faction_genpassword(f, buffer);
} }
prepare_report(&ctx, f); prepare_report(&ctx, f, password);
get_addresses(&ctx); get_addresses(&ctx);
log_debug("Reports for %s", factionname(f)); log_debug("Reports for %s", factionname(f));
for (rtype = report_types; rtype != NULL; rtype = rtype->next) { for (rtype = report_types; rtype != NULL; rtype = rtype->next) {

View File

@ -77,9 +77,10 @@ extern "C" {
struct region *first, *last; struct region *first, *last;
void *userdata; void *userdata;
time_t report_time; time_t report_time;
const char *password;
} report_context; } report_context;
void prepare_report(report_context *ctx, struct faction *f); void prepare_report(report_context *ctx, struct faction *f, const char *password);
void finish_reports(report_context *ctx); void finish_reports(report_context *ctx);
void get_addresses(report_context * ctx); void get_addresses(report_context * ctx);

View File

@ -338,11 +338,11 @@ static void test_newbie_password_message(CuTest *tc) {
f = test_create_faction(NULL); f = test_create_faction(NULL);
f->age = 5; f->age = 5;
f->flags = 0; f->flags = 0;
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertIntEquals(tc, 0, f->flags&FFL_PWMSG); CuAssertIntEquals(tc, 0, f->flags&FFL_PWMSG);
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "changepasswd")); CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "changepasswd"));
f->age=2; f->age=2;
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertIntEquals(tc, FFL_PWMSG, f->flags&FFL_PWMSG); CuAssertIntEquals(tc, FFL_PWMSG, f->flags&FFL_PWMSG);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd"));
finish_reports(&ctx); finish_reports(&ctx);
@ -365,7 +365,7 @@ static void test_prepare_travelthru(CuTest *tc) {
test_create_unit(f2, r3); test_create_unit(f2, r3);
u = test_create_unit(f, r1); u = test_create_unit(f, r1);
travelthru_add(r2, u); travelthru_add(r2, u);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, r3, ctx.last); CuAssertPtrEquals(tc, r3, ctx.last);
CuAssertPtrEquals(tc, f, ctx.f); CuAssertPtrEquals(tc, f, ctx.f);
@ -375,7 +375,7 @@ static void test_prepare_travelthru(CuTest *tc) {
finish_reports(&ctx); finish_reports(&ctx);
CuAssertIntEquals(tc, seen_none, r2->seen.mode); CuAssertIntEquals(tc, seen_none, r2->seen.mode);
prepare_report(&ctx, f2); prepare_report(&ctx, f2, NULL);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
CuAssertIntEquals(tc, seen_neighbour, r2->seen.mode); CuAssertIntEquals(tc, seen_neighbour, r2->seen.mode);
CuAssertIntEquals(tc, seen_unit, r3->seen.mode); CuAssertIntEquals(tc, seen_unit, r3->seen.mode);
@ -399,7 +399,7 @@ static void test_get_addresses(CuTest *tc) {
test_create_unit(f, r); test_create_unit(f, r);
test_create_unit(f1, r); test_create_unit(f1, r);
test_create_unit(f2, r); test_create_unit(f2, r);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r, ctx.first); CuAssertPtrEquals(tc, r, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
get_addresses(&ctx); get_addresses(&ctx);
@ -427,7 +427,7 @@ static void test_get_addresses_fstealth(CuTest *tc) {
u = test_create_unit(f1, r); u = test_create_unit(f1, r);
set_factionstealth(u, f2); set_factionstealth(u, f2);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r, ctx.first); CuAssertPtrEquals(tc, r, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
get_addresses(&ctx); get_addresses(&ctx);
@ -470,7 +470,7 @@ static void test_get_addresses_travelthru(CuTest *tc) {
u = test_create_unit(f4, r1); u = test_create_unit(f4, r1);
set_level(u, SK_STEALTH, 1); set_level(u, SK_STEALTH, 1);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
get_addresses(&ctx); get_addresses(&ctx);
@ -516,14 +516,14 @@ void test_prepare_lighthouse_capacity(CuTest *tc) {
u2->building = b; u2->building = b;
set_level(u2, SK_PERCEPTION, 3); set_level(u2, SK_PERCEPTION, 3);
CuAssertPtrEquals(tc, NULL, inside_building(u2)); CuAssertPtrEquals(tc, NULL, inside_building(u2));
prepare_report(&ctx, u1->faction); prepare_report(&ctx, u1->faction, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode); CuAssertIntEquals(tc, seen_lighthouse, r2->seen.mode);
finish_reports(&ctx); finish_reports(&ctx);
prepare_report(&ctx, u2->faction); prepare_report(&ctx, u2->faction, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
@ -532,7 +532,7 @@ void test_prepare_lighthouse_capacity(CuTest *tc) {
/* lighthouse capacity is # of units, not people: */ /* lighthouse capacity is # of units, not people: */
config_set_int("rules.lighthouse.unit_capacity", 1); config_set_int("rules.lighthouse.unit_capacity", 1);
prepare_report(&ctx, u2->faction); prepare_report(&ctx, u2->faction, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
@ -567,7 +567,7 @@ static void test_prepare_lighthouse(CuTest *tc) {
u = test_create_unit(f, r1); u = test_create_unit(f, r1);
u->building = b; u->building = b;
set_level(u, SK_PERCEPTION, 3); set_level(u, SK_PERCEPTION, 3);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
@ -613,7 +613,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc)
u->building = b; u->building = b;
region_set_owner(b->region, f, 0); region_set_owner(b->region, f, 0);
CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, NULL)); CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, NULL));
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
@ -632,14 +632,14 @@ static void test_prepare_report(CuTest *tc) {
f = test_create_faction(NULL); f = test_create_faction(NULL);
r = test_create_region(0, 0, NULL); r = test_create_region(0, 0, NULL);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, NULL, ctx.first); CuAssertPtrEquals(tc, NULL, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_none, r->seen.mode); CuAssertIntEquals(tc, seen_none, r->seen.mode);
finish_reports(&ctx); finish_reports(&ctx);
test_create_unit(f, r); test_create_unit(f, r);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r, ctx.first); CuAssertPtrEquals(tc, r, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r->seen.mode); CuAssertIntEquals(tc, seen_unit, r->seen.mode);
@ -648,7 +648,7 @@ static void test_prepare_report(CuTest *tc) {
r = test_create_region(2, 0, 0); r = test_create_region(2, 0, 0);
CuAssertPtrEquals(tc, r, regions->next); CuAssertPtrEquals(tc, r, regions->next);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, regions, ctx.first); CuAssertPtrEquals(tc, regions, ctx.first);
CuAssertPtrEquals(tc, r, ctx.last); CuAssertPtrEquals(tc, r, ctx.last);
CuAssertIntEquals(tc, seen_none, r->seen.mode); CuAssertIntEquals(tc, seen_none, r->seen.mode);
@ -667,7 +667,7 @@ static void test_seen_neighbours(CuTest *tc) {
r2 = test_create_region(1, 0, 0); r2 = test_create_region(1, 0, 0);
test_create_unit(f, r1); test_create_unit(f, r1);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
@ -694,7 +694,7 @@ static void test_seen_travelthru(CuTest *tc) {
travelthru_add(r2, u); travelthru_add(r2, u);
CuAssertPtrEquals(tc, r1, f->first); CuAssertPtrEquals(tc, r1, f->first);
CuAssertPtrEquals(tc, r3, f->last); CuAssertPtrEquals(tc, r3, f->last);
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
@ -772,7 +772,7 @@ static void test_report_far_vision(CuTest *tc) {
CuAssertPtrEquals(tc, r1, f->first); CuAssertPtrEquals(tc, r1, f->first);
CuAssertPtrEquals(tc, r2, f->last); CuAssertPtrEquals(tc, r2, f->last);
report_context ctx; report_context ctx;
prepare_report(&ctx, f); prepare_report(&ctx, f, NULL);
CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, r1, ctx.first);
CuAssertPtrEquals(tc, NULL, ctx.last); CuAssertPtrEquals(tc, NULL, ctx.last);
CuAssertIntEquals(tc, seen_unit, r1->seen.mode); CuAssertIntEquals(tc, seen_unit, r1->seen.mode);

View File

@ -42,3 +42,12 @@ int password_verify(const char * pwhash, const char * passwd) {
} }
return (strcmp(passwd, pwhash) == 0) ? VERIFY_OK : VERIFY_FAIL; return (strcmp(passwd, pwhash) == 0) ? VERIFY_OK : VERIFY_FAIL;
} }
void password_generate(char *password, size_t length) {
char salt[BCRYPT_HASHSIZE];
assert(BCRYPT_HASHSIZE - 7 > length);
bcrypt_gensalt(4, salt);
memcpy(password, salt + 7, length);
password[length] = 0;
}

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
typedef enum cryptalgo_t { typedef enum cryptalgo_t {
PASSWORD_PLAINTEXT, PASSWORD_PLAINTEXT,
PASSWORD_BCRYPT PASSWORD_BCRYPT
@ -16,3 +17,4 @@ extern int bcrypt_workfactor;
int password_verify(const char *hash, const char *passwd); int password_verify(const char *hash, const char *passwd);
const char * password_hash(const char *passwd, cryptalgo_t algo); const char * password_hash(const char *passwd, cryptalgo_t algo);
bool password_is_implemented(cryptalgo_t algo); bool password_is_implemented(cryptalgo_t algo);
void password_generate(char *password, size_t length);