aboutsummaryrefslogtreecommitdiffstats
path: root/FICS
diff options
context:
space:
mode:
Diffstat (limited to 'FICS')
-rw-r--r--FICS/addgroup.cpp21
-rw-r--r--FICS/addgroup.h1
-rw-r--r--FICS/fics_addplayer.c14
-rw-r--r--FICS/ficsmain.c7
-rw-r--r--FICS/playerdb.c40
-rw-r--r--FICS/prep_dir_for_privdrop.cpp6
6 files changed, 72 insertions, 17 deletions
diff --git a/FICS/addgroup.cpp b/FICS/addgroup.cpp
index 59547d0..52c6639 100644
--- a/FICS/addgroup.cpp
+++ b/FICS/addgroup.cpp
@@ -140,6 +140,27 @@ group_exists(const char *name)
return false;
}
+bool
+is_valid_group_name(const char *name)
+{
+ const char legal_index[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789_-";
+ const size_t name_min = 2;
+ const size_t name_max = 30;
+
+ if (name == nullptr || strcmp(name, "") == 0)
+ return false;
+ else if (strlen(name) < name_min || strlen(name) > name_max)
+ return false;
+ for (const char *cp = name; *cp != '\0'; cp++) {
+ if (strchr(legal_index, *cp) == nullptr)
+ return false;
+ }
+ return true;
+}
+
int
read_the_group_permissions_file(const char *path)
{
diff --git a/FICS/addgroup.h b/FICS/addgroup.h
index e5b1906..3642969 100644
--- a/FICS/addgroup.h
+++ b/FICS/addgroup.h
@@ -11,6 +11,7 @@ int fics_addgroup(const char *);
bool get_group_id(const char *, int *);
bool get_next_line_from_file(FILE *, char **); // uses 'new[]'
bool group_exists(const char *);
+bool is_valid_group_name(const char *);
int read_the_group_permissions_file(const char *);
__FICS_END_DECLS
diff --git a/FICS/fics_addplayer.c b/FICS/fics_addplayer.c
index 18d42c4..b5ca47f 100644
--- a/FICS/fics_addplayer.c
+++ b/FICS/fics_addplayer.c
@@ -29,6 +29,9 @@
Markus Uhlin 24/05/25 Added command-line option 'a'
Markus Uhlin 25/03/23 Output restart notice if the
player is admin.
+ Markus Uhlin 25/11/02 Require root privileges if the
+ FICS prefix compares to anything
+ else than '/home'.
*/
#include "stdinclude.h"
@@ -42,6 +45,7 @@
#include "fics_getsalt.h"
#include "ficsmain.h"
#include "playerdb.h"
+#include "prep_dir_for_privdrop.h"
#include "settings.h"
#include "utils.h"
@@ -136,6 +140,16 @@ main(int argc, char *argv[])
settings_init();
settings_read_conf(FICS_SETTINGS);
+ if (strncmp(FICS_PREFIX, "/home", 5) == 0) {
+ if (is_super_user())
+ errx(1, "Do not run as root");
+ } else {
+ if (!is_super_user())
+ errx(1, "Need root privileges");
+ else if (drop_root_privileges(FICS_PREFIX) == -1)
+ errx(1, "Privdrop failed");
+ }
+
player_init(0);
p = player_new();
diff --git a/FICS/ficsmain.c b/FICS/ficsmain.c
index bf5aafb..36055b8 100644
--- a/FICS/ficsmain.c
+++ b/FICS/ficsmain.c
@@ -298,9 +298,12 @@ main(int argc, char *argv[])
settings_init();
settings_read_conf(FICS_SETTINGS);
- if (is_super_user()) {
- if (strncmp(FICS_PREFIX, "/home", 5) == 0)
+ if (strncmp(FICS_PREFIX, "/home", 5) == 0) {
+ if (is_super_user())
errx(1, "Do not run as root");
+ } else {
+ if (!is_super_user())
+ errx(1, "Need root privileges");
else if (read_the_group_permissions_file("/etc/group") != 0)
errx(1, "Failed to read the group permissions file");
else if (fics_addgroup(settings_get("sysgroup")) != 0)
diff --git a/FICS/playerdb.c b/FICS/playerdb.c
index 2b8ef04..2fbc975 100644
--- a/FICS/playerdb.c
+++ b/FICS/playerdb.c
@@ -49,6 +49,8 @@
Markus Uhlin 25/07/28 Restricted file permissions upon
creation.
Markus Uhlin 25/07/30 Usage of 'int64_t'.
+ Markus Uhlin 25/11/02 Added overflow checks for array
+ indices.
*/
#include "stdinclude.h"
@@ -1085,8 +1087,8 @@ player_read(int p, char *name)
char line[MAX_LINE_SIZE] = { '\0' };
char *attr, *value;
char *resolvedPath = NULL;
- int len = 0;
int version = 0;
+ size_t len = 0;
parray[p].login = stolower(xstrdup(name)); // free on error?
@@ -2072,17 +2074,25 @@ player_decline_offers(int p, int p1, int offerType)
}
while ((offer = player_find_pendfrom(p, p1, offerType)) >= 0) {
+ if (offer >= (int)ARRAY_SIZE(parray[0].p_from_list)) {
+ warnx("%s: 'offer' too large", __func__);
+ break;
+ }
+
type = parray[p].p_from_list[offer].type;
p2 = parray[p].p_from_list[offer].whofrom;
p2Name = parray[p2].name;
- part = parray[p].partner;
- if (part >= 0 && parray[part].partner != p)
+ if ((part = parray[p].partner) >= (int)ARRAY_SIZE(parray)) {
+ errx(1, "%s: 'part' (%d) too large", __func__,
+ part);
+ } else if (part >= 0 && parray[part].partner != p)
part = -1;
- p2part = parray[p2].partner;
-
- if (p2part >= 0 && parray[p2part].partner != p2)
+ if ((p2part = parray[p2].partner) >= (int)ARRAY_SIZE(parray)) {
+ errx(1, "%s: 'p2part' (%d) too large", __func__,
+ p2part);
+ } else if (p2part >= 0 && parray[p2part].partner != p2)
p2part = -1;
switch (type) {
@@ -2185,17 +2195,25 @@ player_withdraw_offers(int p, int p1, int offerType)
}
while ((offer = player_find_pendto(p, p1, offerType)) >= 0) {
+ if (offer >= (int)ARRAY_SIZE(parray[0].p_to_list)) {
+ warnx("%s: 'offer' too large", __func__);
+ break;
+ }
+
type = parray[p].p_to_list[offer].type;
p2 = parray[p].p_to_list[offer].whoto;
p2Name = parray[p2].name;
- part = parray[p].partner;
- if (part >= 0 && parray[part].partner != p)
+ if ((part = parray[p].partner) >= (int)ARRAY_SIZE(parray)) {
+ errx(1, "%s: 'part' (%d) too large", __func__,
+ part);
+ } else if (part >= 0 && parray[part].partner != p)
part = -1;
- p2part = parray[p2].partner;
-
- if (p2part >= 0 && parray[p2part].partner != p2)
+ if ((p2part = parray[p2].partner) >= (int)ARRAY_SIZE(parray)) {
+ errx(1, "%s: 'p2part' (%d) too large", __func__,
+ p2part);
+ } else if (p2part >= 0 && parray[p2part].partner != p2)
p2part = -1;
switch (type) {
diff --git a/FICS/prep_dir_for_privdrop.cpp b/FICS/prep_dir_for_privdrop.cpp
index 85d3dfb..4d4478c 100644
--- a/FICS/prep_dir_for_privdrop.cpp
+++ b/FICS/prep_dir_for_privdrop.cpp
@@ -117,10 +117,8 @@ prep_dir_for_privdrop(const char *path)
fs::recursive_directory_iterator dir_it(v_path);
uid_t uid = 0;
gid_t gid = 0;
- constexpr mode_t dir_mode = (S_IRUSR|S_IWUSR|
- S_IRGRP|S_IWGRP|S_IROTH);
- constexpr mode_t file_mode = (S_IRUSR|S_IWUSR|S_IRGRP|
- S_IROTH);
+ constexpr mode_t dir_mode = (S_IRWXU|S_IRGRP|S_IXGRP);
+ constexpr mode_t file_mode = (S_IRUSR|S_IWUSR|S_IRGRP);
if (get_uid_and_gid(uid, gid) == -1) {
throw std::runtime_error("failed to get uid/gid");