Code refactoring: get_file_mime got into mime.c and all security code moved into a procedure
This commit is contained in:
parent
e03ed1ca2b
commit
345215fa9b
2 changed files with 79 additions and 63 deletions
117
main.c
117
main.c
|
@ -21,10 +21,62 @@
|
||||||
void display_file(const char *, const char *);
|
void display_file(const char *, const char *);
|
||||||
void status (const int, const char *, const char *);
|
void status (const int, const char *, const char *);
|
||||||
void get_file_mime(const char *, char *, const ssize_t);
|
void get_file_mime(const char *, char *, const ssize_t);
|
||||||
|
void drop_privileges(const char *, const char *);
|
||||||
|
|
||||||
int main (int, char **);
|
int main (int, char **);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
drop_privileges(const char *user, const char *path)
|
||||||
|
{
|
||||||
|
struct passwd *pw;
|
||||||
|
/*
|
||||||
|
* use chroot() if an user is specified requires root user to be
|
||||||
|
* running the program to run chroot() and then drop privileges
|
||||||
|
*/
|
||||||
|
if (strlen(user) > 0) {
|
||||||
|
/* is root? */
|
||||||
|
if (getuid() != 0) {
|
||||||
|
syslog(LOG_DAEMON, "chroot requires program to be run as root");
|
||||||
|
err(1, "chroot requires root user");
|
||||||
|
}
|
||||||
|
/* search user uid from name */
|
||||||
|
if ((pw = getpwnam(user)) == NULL) {
|
||||||
|
syslog(LOG_DAEMON, "the user %s can't be found on the system", user);
|
||||||
|
err(1, "finding user");
|
||||||
|
}
|
||||||
|
/* chroot worked? */
|
||||||
|
if (chroot(path) != 0) {
|
||||||
|
syslog(LOG_DAEMON, "the path %s can't be used for chroot", path);
|
||||||
|
err(1, "chroot");
|
||||||
|
}
|
||||||
|
/* drop privileges */
|
||||||
|
if (setuid(pw->pw_uid) != 0) {
|
||||||
|
syslog(LOG_DAEMON, "dropping privileges to user %s (uid=%i) failed",
|
||||||
|
user, pw->pw_uid);
|
||||||
|
err(1, "Can't drop privileges");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
/*
|
||||||
|
* prevent access to files other than the one in path
|
||||||
|
*/
|
||||||
|
if (unveil(path, "r") == -1) {
|
||||||
|
syslog(LOG_DAEMON, "unveil on %s failed", path);
|
||||||
|
err(1, "unveil");
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* prevent system calls other parsing queryfor fread file and
|
||||||
|
* write to stdio
|
||||||
|
*/
|
||||||
|
if (pledge("stdio rpath", NULL) == -1) {
|
||||||
|
syslog(LOG_DAEMON, "pledge call failed");
|
||||||
|
err(1, "pledge");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
status(const int code, const char *file_mime, const char *lang)
|
status(const int code, const char *file_mime, const char *lang)
|
||||||
{
|
{
|
||||||
|
@ -32,26 +84,6 @@ status(const int code, const char *file_mime, const char *lang)
|
||||||
code, file_mime, lang);
|
code, file_mime, lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
get_file_mime(const char *path, char *type, const ssize_t type_size)
|
|
||||||
{
|
|
||||||
char *extension;
|
|
||||||
|
|
||||||
extension = strrchr(path, '.');
|
|
||||||
|
|
||||||
/* look for the MIME in the database */
|
|
||||||
for (int i = 0; i < sizeof(database) / sizeof(struct mimes); i++) {
|
|
||||||
if (strcmp(database[i].extension, extension + 1) == 0) {
|
|
||||||
strlcpy(type, database[i].type, type_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if no MIME have been found, set a default one */
|
|
||||||
if (strlen(type) == 0)
|
|
||||||
strlcpy(type, "text/gemini", type_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
display_file(const char *path, const char *lang)
|
display_file(const char *path, const char *lang)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +134,6 @@ main(int argc, char **argv)
|
||||||
int virtualhost = 0;
|
int virtualhost = 0;
|
||||||
int option;
|
int option;
|
||||||
int start_with_gemini;
|
int start_with_gemini;
|
||||||
struct passwd *pw;
|
|
||||||
char *pos;
|
char *pos;
|
||||||
|
|
||||||
while ((option = getopt(argc, argv, ":d:l:u:v")) != -1) {
|
while ((option = getopt(argc, argv, ":d:l:u:v")) != -1) {
|
||||||
|
@ -123,49 +154,9 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* use chroot() if an user is specified requires root user to be
|
* do chroot if an user is supplied run pledge/unveil if OpenBSD
|
||||||
* running the program to run chroot() and then drop privileges
|
|
||||||
*/
|
*/
|
||||||
if (strlen(user) > 0) {
|
drop_privileges(user, path);
|
||||||
/* is root? */
|
|
||||||
if (getuid() != 0) {
|
|
||||||
syslog(LOG_DAEMON, "chroot requires %s to be run as root", argv[0]);
|
|
||||||
err(1, "chroot requires root user");
|
|
||||||
}
|
|
||||||
/* search user uid from name */
|
|
||||||
if ((pw = getpwnam(user)) == NULL) {
|
|
||||||
syslog(LOG_DAEMON, "the user %s can't be found on the system", user);
|
|
||||||
err(1, "finding user");
|
|
||||||
}
|
|
||||||
/* chroot worked? */
|
|
||||||
if (chroot(path) != 0) {
|
|
||||||
syslog(LOG_DAEMON, "the path %s can't be used for chroot", path);
|
|
||||||
err(1, "chroot");
|
|
||||||
}
|
|
||||||
/* drop privileges */
|
|
||||||
if (setuid(pw->pw_uid) != 0) {
|
|
||||||
syslog(LOG_DAEMON, "dropping privileges to user %s (uid=%i) failed",
|
|
||||||
user, pw->pw_uid);
|
|
||||||
err(1, "Can't drop privileges");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
/*
|
|
||||||
* prevent access to files other than the one in path
|
|
||||||
*/
|
|
||||||
if (unveil(path, "r") == -1) {
|
|
||||||
syslog(LOG_DAEMON, "unveil on %s failed", path);
|
|
||||||
err(1, "unveil");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* prevent system calls other parsing queryfor fread file and
|
|
||||||
* write to stdio
|
|
||||||
*/
|
|
||||||
if (pledge("stdio rpath", NULL) == -1) {
|
|
||||||
syslog(LOG_DAEMON, "pledge call failed");
|
|
||||||
err(1, "pledge");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read 1024 chars from stdin
|
* read 1024 chars from stdin
|
||||||
|
|
25
mimes.c
25
mimes.c
|
@ -1,10 +1,15 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void get_file_mime(const char *, char *, const ssize_t);
|
||||||
|
|
||||||
struct mimes {
|
struct mimes {
|
||||||
char extension[10];
|
char extension[10];
|
||||||
char type [70];
|
char type [70];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct mimes database[] = {
|
struct mimes database[] = {
|
||||||
{"7z", "application/x-7z-compressed"},
|
{"7z", "application/x-7z-compressed"},
|
||||||
{"atom", "application/atom+xml"},
|
{"atom", "application/atom+xml"},
|
||||||
|
@ -110,3 +115,23 @@ struct mimes database[] = {
|
||||||
{"xpi", "application/x-xpinstall"},
|
{"xpi", "application/x-xpinstall"},
|
||||||
{"zip", "application/zip"}
|
{"zip", "application/zip"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
get_file_mime(const char *path, char *type, const ssize_t type_size)
|
||||||
|
{
|
||||||
|
char *extension;
|
||||||
|
|
||||||
|
extension = strrchr(path, '.');
|
||||||
|
|
||||||
|
/* look for the MIME in the database */
|
||||||
|
for (int i = 0; i < sizeof(database) / sizeof(struct mimes); i++) {
|
||||||
|
if (strcmp(database[i].extension, extension + 1) == 0) {
|
||||||
|
strlcpy(type, database[i].type, type_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if no MIME have been found, set a default one */
|
||||||
|
if (strlen(type) == 0)
|
||||||
|
strlcpy(type, "text/gemini", type_size);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue