diff options
Diffstat (limited to 'FICS')
-rw-r--r-- | FICS/adminproc.c | 8 | ||||
-rw-r--r-- | FICS/command.c | 13 | ||||
-rw-r--r-- | FICS/comproc.c | 34 | ||||
-rw-r--r-- | FICS/gamedb.c | 37 | ||||
-rw-r--r-- | FICS/playerdb.c | 95 | ||||
-rw-r--r-- | FICS/ratings.c | 34 | ||||
-rw-r--r-- | FICS/utils.c | 17 |
7 files changed, 180 insertions, 58 deletions
diff --git a/FICS/adminproc.c b/FICS/adminproc.c index 04331a4..e670d44 100644 --- a/FICS/adminproc.c +++ b/FICS/adminproc.c @@ -19,6 +19,8 @@ #include <sys/param.h> #include <err.h> +#include <inttypes.h> +#include <stdint.h> #include "adminproc.h" #include "command.h" @@ -367,12 +369,12 @@ PUBLIC int com_anews(int p, param_list param) { FILE *fp = NULL; - char *junkp = NULL; char count[10] = { '\0' }; char filename[MAX_FILENAME_SIZE] = { '\0' }; char junk[MAX_LINE_SIZE] = { '\0' }; + char *junkp = NULL; int found = 0; - long int lval = 0; + int64_t lval = 0; time_t crtime = 0; msnprintf(filename, sizeof filename, "%s/newadminnews.index", news_dir); @@ -382,7 +384,7 @@ com_anews(int p, param_list param) return COM_OK; } -#define SCAN_JUNK "%ld %9s" +#define SCAN_JUNK ("%" SCNd64 " " "%9s") _Static_assert(9 < ARRAY_SIZE(count), "Array too small"); if (param[0].type == 0) { diff --git a/FICS/command.c b/FICS/command.c index 569c27a..301c305 100644 --- a/FICS/command.c +++ b/FICS/command.c @@ -36,6 +36,7 @@ Markus Uhlin 25/03/09 Fixed double free() Markus Uhlin 25/03/11 Fixed memleak Markus Uhlin 25/03/16 Fixed use of 32-bit 'time_t' + Markus Uhlin 25/07/28 Usage of 'int64_t' */ #include "stdinclude.h" @@ -44,6 +45,8 @@ #include <sys/param.h> #include <err.h> +#include <inttypes.h> +#include <stdint.h> #include "command.h" #include "command_list.h" @@ -716,10 +719,10 @@ boot_out(int p, int p1) PUBLIC void rscan_news(FILE *fp, int p, time_t lc) { - char *junkp = NULL; char count[10] = { '\0' }; char junk[MAX_LINE_SIZE] = { '\0' }; - long int lval = 0; + char *junkp = NULL; + int64_t lval = 0; time_t crtime = 0; if (fgets(junk, sizeof junk, fp) == NULL || @@ -728,7 +731,7 @@ rscan_news(FILE *fp, int p, time_t lc) _Static_assert(ARRAY_SIZE(count) > 9, "Unexpected array size"); - if (sscanf(junk, "%ld %9s", &lval, count) != 2) { + if (sscanf(junk, ("%" SCNd64 " " "%9s"), &lval, count) != 2) { warnx("%s: sscanf() error: too few items", __func__); return; } @@ -752,13 +755,13 @@ rscan_news(FILE *fp, int p, time_t lc) PRIVATE void check_news(int p, int admin) { -#define SCAN_JUNK "%ld %9s" +#define SCAN_JUNK ("%" SCNd64 " " "%9s") FILE *fp = NULL; char count[10] = { '\0' }; char filename[MAX_FILENAME_SIZE] = { '\0' }; char junk[MAX_LINE_SIZE] = { '\0' }; char *junkp = NULL; - long int lval = 0; + int64_t lval = 0; time_t crtime = 0; time_t lc = player_lastconnect(p); diff --git a/FICS/comproc.c b/FICS/comproc.c index b3c05a3..06592cc 100644 --- a/FICS/comproc.c +++ b/FICS/comproc.c @@ -45,6 +45,9 @@ array index read/write. Markus Uhlin 25/07/21 com_who: fixed multiplication result converted to larger type. + Markus Uhlin 25/07/24 Fixed use of potentially + dangerous functions. + Markus Uhlin 25/07/29 Usage of 'int64_t'. */ #include "stdinclude.h" @@ -53,6 +56,9 @@ #include <sys/resource.h> #include <err.h> +#include <errno.h> +#include <inttypes.h> +#include <stdint.h> #include "board.h" #include "command.h" @@ -127,17 +133,17 @@ com_more(int p, param_list param) PUBLIC void rscan_news2(FILE *fp, int p, int num) { - char *junkp; char count[10] = { '\0' }; char junk[MAX_LINE_SIZE] = { '\0' }; - long int lval; + char *junkp; + int64_t lval; time_t crtime; if (num == 0) return; if (fgets(junk, sizeof junk, fp) == NULL || feof(fp) || - sscanf(junk, "%ld %9s", &lval, count) != 2) + sscanf(junk, "%" SCNd64 " " "%9s", &lval, count) != 2) return; rscan_news2(fp, p, num - 1); @@ -154,12 +160,12 @@ PUBLIC int com_news(int p, param_list param) { FILE *fp = NULL; - char *junkp = NULL; char count[10] = { '\0' }; char filename[MAX_FILENAME_SIZE] = { '\0' }; char junk[MAX_LINE_SIZE] = { '\0' }; + char *junkp = NULL; int found = 0; - long int lval = 0; + int64_t lval = 0; time_t crtime = 0; snprintf(filename, sizeof filename, "%s/newnews.index", news_dir); @@ -169,7 +175,7 @@ com_news(int p, param_list param) return COM_OK; } -#define SCAN_JUNK "%ld %9s" +#define SCAN_JUNK ("%" SCNd64 " " "%9s") _Static_assert(9 < ARRAY_SIZE(count), "'count' too small"); if (param[0].type == 0) { @@ -590,9 +596,14 @@ com_stats(int p, param_list param) if (connected && parray[p1].registered && (p == p1 || parray[p].adminLevel > 0)) { - char *timeToStr = ctime((time_t *) &parray[p1].timeOfReg); + char timeToStr[30] = { '\0' }; + + errno = 0; + + if (ctime_r(&parray[p1].timeOfReg, timeToStr) == NULL) + warn("%s: ctime_r", __func__); + timeToStr[strcspn(timeToStr, "\n")] = '\0'; - timeToStr[strlen(timeToStr) - 1] = '\0'; pprintf(p, "\n"); onTime = ((time(NULL) - parray[p1].logon_time) + @@ -755,7 +766,7 @@ plogins(int p, char *fname) char ipstr[20] = { '\0' }; char loginName[MAX_LOGIN_NAME + 1] = { '\0' }; int registered = 0; - long int lval = 0; + int64_t lval = 0; time_t tval = 0; uint16_t inout = 0; @@ -767,9 +778,10 @@ plogins(int p, char *fname) _Static_assert(19 < ARRAY_SIZE(ipstr), "'ipstr' too small"); _Static_assert(19 < ARRAY_SIZE(loginName), "'loginName' too small"); +#define SCAN_FMT ("%" SCNu16 " %19s " "%" SCNd64 " " "%d %19s\n") while (!feof(fp)) { - if (fscanf(fp, "%hu %19s %ld %d %19s\n", &inout, loginName, - &lval, ®istered, ipstr) != 5) { + if (fscanf(fp, SCAN_FMT, &inout, loginName, &lval, ®istered, + ipstr) != 5) { fprintf(stderr, "FICS: Error in login info format. " "%s\n", fname); fclose(fp); diff --git a/FICS/gamedb.c b/FICS/gamedb.c index 2656447..19f0dc7 100644 --- a/FICS/gamedb.c +++ b/FICS/gamedb.c @@ -43,6 +43,9 @@ Markus Uhlin 25/04/01 ReadV1GameFmt: guard num half moves. Markus Uhlin 25/04/06 Fixed Clang Tidy warnings. + Markus Uhlin 25/07/28 Fixed use of potentially + dangerous functions. + Markus Uhlin 25/07/29 Usage of 'int64_t'. */ #include "stdinclude.h" @@ -50,7 +53,9 @@ #include <err.h> #include <errno.h> +#include <inttypes.h> #include <limits.h> +#include <stdint.h> #include "command.h" #include "config.h" @@ -563,12 +568,12 @@ EndSym(int g) PUBLIC char * movesToString(int g, int pgn) { + char tmp[160] = { '\0' }; char *serv_loc = SERVER_LOCATION; char *serv_name = SERVER_NAME; - char tmp[160] = { '\0' }; int i, col; int wr, br; - struct tm *tm_ptr = NULL; + struct tm v_tm = {0}; time_t curTime; wr = garray[g].white_rating; @@ -586,14 +591,16 @@ movesToString(int g, int pgn) serv_name, serv_loc); - if ((tm_ptr = localtime(&curTime)) != NULL) { + errno = 0; + + if (localtime_r(&curTime, &v_tm) != NULL) { strftime(tmp, sizeof(tmp), "[Date \"%Y.%m.%d\"]\n" "[Time \"%H:%M:%S\"]\n", - tm_ptr); + &v_tm); mstrlcat(gameString, tmp, sizeof gameString); } else - warn("%s: localtime", __func__); + warn("%s: localtime_r()", __func__); msnprintf(tmp, sizeof tmp, "[Round \"-\"]\n" @@ -668,11 +675,13 @@ movesToString(int g, int pgn) mstrlcat(gameString, tmp, sizeof gameString); mstrlcat(gameString, "--- ", sizeof gameString); - if ((tm_ptr = localtime(&curTime)) != NULL) { - strftime(tmp, sizeof tmp, "%Y.%m.%d %H:%M:%S", tm_ptr); + errno = 0; + + if (localtime_r(&curTime, &v_tm) != NULL) { + strftime(tmp, sizeof tmp, "%Y.%m.%d %H:%M:%S", &v_tm); mstrlcat(gameString, tmp, sizeof gameString); } else - warn("%s: localtime", __func__); + warn("%s: localtime_r()", __func__); if (garray[g].rated) { mstrlcat(gameString, "\nRated ", sizeof gameString); @@ -1276,7 +1285,7 @@ PRIVATE int ReadV1GameFmt(game *g, FILE *fp, const char *file, int version) { int ret[3]; - long int lval; + int64_t lval; _Static_assert(17 < ARRAY_SIZE(g->white_name), "Unexpected array size"); _Static_assert(17 < ARRAY_SIZE(g->black_name), "Unexpected array size"); @@ -1300,7 +1309,7 @@ ReadV1GameFmt(game *g, FILE *fp, const char *file, int version) if (version < 3 && !g->bInitTime) g->bInitTime = g->wInitTime; - if (fscanf(fp, "%ld", &lval) != 1) { + if (fscanf(fp, "%" SCNd64, &lval) != 1) { warnx("%s: %s: failed to get time of start", __func__, file); return -1; } else @@ -1514,7 +1523,7 @@ PRIVATE void WriteGameFile(FILE *fp, int g) { game *gg = &garray[g]; - long int lval; + int64_t lval; player *bp = &parray[gg->black]; player *wp = &parray[gg->white]; @@ -1525,7 +1534,7 @@ WriteGameFile(FILE *fp, int g) gg->bInitTime, gg->bIncrement); lval = gg->timeOfStart; - fprintf(fp, "%ld\n", lval); + fprintf(fp, "%" PRId64 "\n", lval); #ifdef TIMESEAL fprintf(fp, "%d %d\n", @@ -2123,6 +2132,8 @@ pgames(int p, int p1, char *fname) _Static_assert(ARRAY_SIZE(ending) > 99, "'ending' too small"); while (!feof(fp)) { + char tbuf[30] = { '\0' }; + if (fscanf(fp, "%d %1s %d %1s %d %19s %99s %d %d %d %d %99s " "%99s %ld\n", &count, result, &MyRating, MyColor, @@ -2145,7 +2156,7 @@ pgames(int p, int p1, char *fname) count, result, MyRating, MyColor, OppRating, OppName, type, (wt / 600), (wi / 10), eco, ending, - ctime(&t)); + ctime_r(&t, tbuf) != NULL ? &tbuf[0] : ""); } fclose(fp); diff --git a/FICS/playerdb.c b/FICS/playerdb.c index c85ec0c..29e14f4 100644 --- a/FICS/playerdb.c +++ b/FICS/playerdb.c @@ -46,6 +46,9 @@ Markus Uhlin 25/04/02 add_to_list: added an upper limit for the list size. Markus Uhlin 25/04/06 Fixed Clang Tidy warnings. + Markus Uhlin 25/07/28 Restricted file permissions upon + creation. + Markus Uhlin 25/07/30 Usage of 'int64_t'. */ #include "stdinclude.h" @@ -53,6 +56,8 @@ #include <err.h> #include <errno.h> +#include <fcntl.h> +#include <inttypes.h> #include <stdint.h> #include "command.h" @@ -1174,6 +1179,7 @@ player_markdeleted(int p) FILE *fp; char fname[MAX_FILENAME_SIZE]; char fname2[MAX_FILENAME_SIZE]; + int fd; if (!parray[p].registered) // Player must not be registered return -1; @@ -1184,9 +1190,17 @@ player_markdeleted(int p) parray[p].login[0], parray[p].login); xrename(__func__, fname, fname2); - if ((fp = fopen(fname2, "a")) != NULL) { // Touch the file + errno = 0; + fd = open(fname2, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) { + warn("%s: open", __func__); + return -1; + } else if ((fp = fdopen(fd, "a")) != NULL) { // Touch the file fprintf(fp, "\n"); fclose(fp); + } else { + close(fd); } return 0; @@ -1290,6 +1304,7 @@ player_save(int p) { FILE *fp; char fname[MAX_FILENAME_SIZE]; + int fd; if (!player_num_ok_chk(p)) { warnx("%s: invalid player number %d", __func__, p); @@ -1314,8 +1329,15 @@ player_save(int p) snprintf(fname, sizeof fname, "%s/%c/%s", player_dir, parray[p].login[0], parray[p].login); - if ((fp = fopen(fname, "w")) == NULL) { + errno = 0; + fd = open(fname, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) { + warn("%s: Problem opening file %s for write", __func__, fname); + return -1; + } else if ((fp = fdopen(fd, "w")) == NULL) { warn("%s: Problem opening file %s for write", __func__, fname); + close(fd); return -1; } @@ -1601,10 +1623,20 @@ player_ontime(int p) PRIVATE void write_p_inout(int inout, int p, char *file, int maxlines) { - FILE *fp; + FILE *fp; + int fd; + + errno = 0; + fd = open(file, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); - if ((fp = fopen(file, "a")) == NULL) + if (fd < 0) { + warn("%s: open", __func__); + return; + } else if ((fp = fdopen(fd, "a")) == NULL) { + warn("%s: fdopen", __func__); + close(fd); return; + } fprintf(fp, "%d %s %ld %d %s\n", inout, parray[p].name, (long int)time(NULL), parray[p].registered, @@ -1663,7 +1695,7 @@ player_lastconnect(int p) char loginName[MAX_LOGIN_NAME]; int inout, registered; int ret, too_long; - long int lval; + int64_t lval = 0; time_t last = 0; ret = snprintf(fname, sizeof fname, "%s/player_data/%c/%s.%s", @@ -1689,8 +1721,8 @@ player_lastconnect(int p) _Static_assert(19 < ARRAY_SIZE(ipstr), "'ipstr' too small"); - if (fscanf(fp, "%d %19s %ld %d %19s\n", &inout, loginName, - &lval, ®istered, ipstr) != 5) { + if (fscanf(fp, ("%d %19s " "%" SCNd64 " %d %19s\n"), &inout, + loginName, &lval, ®istered, ipstr) != 5) { fprintf(stderr, "FICS: Error in login info format. %s" "\n", fname); fclose(fp); @@ -1711,7 +1743,7 @@ player_lastdisconnect(int p) char loginName[MAX_LOGIN_NAME]; int inout, registered; int ret, too_long; - long int lval; + int64_t lval; time_t last = 0; ret = snprintf(fname, sizeof fname, "%s/player_data/%c/%s.%s", @@ -1732,8 +1764,8 @@ player_lastdisconnect(int p) _Static_assert(19 < ARRAY_SIZE(ipstr), "'ipstr' too small"); - if (fscanf(fp, "%d %19s %ld %d %19s\n", &inout, loginName, - &lval, ®istered, ipstr) != 5) { + if (fscanf(fp, ("%d %19s " "%" SCNd64 " %d %19s\n"), &inout, + loginName, &lval, ®istered, ipstr) != 5) { fprintf(stderr, "FICS: Error in login info format. %s" "\n", fname); fclose(fp); @@ -2573,9 +2605,10 @@ PUBLIC int player_add_message(int top, int fromp, char *message) { FILE *fp; - char fname[MAX_FILENAME_SIZE]; - char messbody[1024]; - char subj[256]; + char fname[MAX_FILENAME_SIZE] = { '\0' }; + char messbody[1024] = { '\0' }; + char subj[256] = { '\0' }; + int fd; time_t t = time(NULL); if (!parray[top].registered) @@ -2588,8 +2621,16 @@ player_add_message(int top, int fromp, char *message) if (lines_file(fname) >= MAX_MESSAGES && parray[top].adminLevel == 0) return -1; - if ((fp = fopen(fname, "a")) == NULL) + errno = 0; + fd = open(fname, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) + return -1; + else if ((fp = fdopen(fd, "a")) == NULL) { + close(fd); return -1; + } + fprintf(fp, "%s at %s: %s\n", parray[fromp].name, strltime(&t), message); fclose(fp); @@ -2752,13 +2793,21 @@ PRIVATE int WriteMsgFile(int p, textlist *Head) { FILE *fp; - char fName[MAX_FILENAME_SIZE]; + char fName[MAX_FILENAME_SIZE] = { '\0' }; + int fd; textlist *Cur; GetMsgFile(p, fName, sizeof fName, __func__); - if ((fp = fopen(fName, "w")) == NULL) + errno = 0; + fd = open(fName, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) + return 0; + else if ((fp = fdopen(fd, "w")) == NULL) { + close(fd); return 0; + } for (Cur = Head; Cur != NULL; Cur = Cur->next) fprintf(fp, "%s", Cur->text); fclose(fp); @@ -3161,7 +3210,8 @@ PUBLIC int player_add_comment(int p_by, int p_to, char *comment) { FILE *fp; - char fname[MAX_FILENAME_SIZE]; + char fname[MAX_FILENAME_SIZE] = { '\0' }; + int fd; time_t t = time(NULL); if (!parray[p_to].registered) @@ -3170,8 +3220,17 @@ player_add_comment(int p_by, int p_to, char *comment) snprintf(fname, sizeof fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p_to].login[0], parray[p_to].login, "comments"); - if ((fp = fopen(fname, "a")) == NULL) + errno = 0; + fd = open(fname, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) { + warn("%s: open", __func__); + return -1; + } else if ((fp = fdopen(fd, "a")) == NULL) { + warn("%s: fdopen", __func__); + close(fd); return -1; + } fprintf(fp, "%s at %s: %s\n", parray[p_by].name, strltime(&t), comment); fclose(fp); diff --git a/FICS/ratings.c b/FICS/ratings.c index e445c51..a719be0 100644 --- a/FICS/ratings.c +++ b/FICS/ratings.c @@ -33,6 +33,10 @@ Markus Uhlin 24/11/28 Added null checks Markus Uhlin 25/03/16 Fixed use of 32-bit 'time_t'. Markus Uhlin 25/04/06 Fixed Clang Tidy warnings. + Markus Uhlin 25/07/28 Fixed missing return-value check + for a 'scanf'-like function. + Markus Uhlin 25/07/28 Restricted file permissions upon + creation. */ #include "stdinclude.h" @@ -40,6 +44,7 @@ #include <err.h> #include <errno.h> +#include <fcntl.h> #include <limits.h> #include <stdint.h> @@ -407,12 +412,20 @@ save_ratings(void) { FILE *fp; char fname[MAX_FILENAME_SIZE] = { '\0' }; + int fd; snprintf(fname, sizeof fname, "%s/newratingsV%d_data", stats_dir, STATS_VERSION); - if ((fp = fopen(fname, "w")) == NULL) { + errno = 0; + fd = open(fname, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) { + warn("%s: can't write ratings data", __func__); + return; + } else if ((fp = fdopen(fd, "w")) == NULL) { warn("%s: can't write ratings data", __func__); + close(fd); return; } @@ -1475,7 +1488,8 @@ UpdateRank(int type, char *addName, statistics *sNew, char *delName) char command[MAX_STRING_LENGTH]; char line[MAX_RANK_LINE] = { '\0' }; char login[MAX_LOGIN_NAME] = { '\0' }; - int comp; + int comp = 0; + int fd = -1; statistics sCur; if (GetRankFileName(RankFile, sizeof RankFile, type) < 0) @@ -1488,9 +1502,17 @@ UpdateRank(int type, char *addName, statistics *sNew, char *delName) snprintf(TmpRankFile, sizeof TmpRankFile, "%s/tmpRank", sdir); - if ((fptemp = fopen(TmpRankFile, "w")) == NULL) { + errno = 0; + fd = open(TmpRankFile, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) { + warn("%s: open", __func__); + fclose(fp); + return; + } else if ((fptemp = fdopen(fd, "w")) == NULL) { warn("%s: unable to open rank file for updating", __func__); fclose(fp); + close(fd); return; } @@ -1567,7 +1589,8 @@ GetRank(FILE *fp, char *target, int countComp) char line[MAX_RANK_LINE] = { '\0' }; char login[MAX_LOGIN_NAME] = { '\0' }; int count = 0; - int nGames, is_computer; + int is_computer = 0; + int nGames = 0; int playerFound = 0; while (fgets(line, sizeof line, fp) != NULL && @@ -1575,8 +1598,7 @@ GetRank(FILE *fp, char *target, int countComp) _Static_assert(ARRAY_SIZE(login) > 19, "'login' too small"); if (sscanf(line, "%19s %*d %d %d", login, &nGames, &is_computer) - != 1) { -// warnx("%s: sscanf() error", __func__); + < 3) { continue; } diff --git a/FICS/utils.c b/FICS/utils.c index cf12871..0e1461a 100644 --- a/FICS/utils.c +++ b/FICS/utils.c @@ -42,12 +42,16 @@ Markus Uhlin 25/07/21 Replaced non-reentrant functions with their corresponding thread safe version. + Markus Uhlin 25/07/28 truncate_file: restricted file + permissions upon creation. */ #include "stdinclude.h" #include "common.h" #include <err.h> +#include <errno.h> +#include <fcntl.h> #include "config.h" #include "network.h" @@ -853,8 +857,17 @@ truncate_file(char *file, int lines) fclose(fp); if (trunc) { - if ((fp = fopen(file, "w")) == NULL) { - warn("%s: fopen", __func__); + int fd; + + errno = 0; + fd = open(file, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR); + + if (fd < 0) { + warn("%s: open", __func__); + return 1; + } else if ((fp = fdopen(fd, "w")) == NULL) { + warn("%s: fdopen", __func__); + close(fd); return 1; } |