Skip to content

Commit

Permalink
Merge pull request #6 from trekawek/read-only
Browse files Browse the repository at this point in the history
Support optional read-only mode.
  • Loading branch information
tschak909 authored Jul 7, 2024
2 parents caf45f5 + 629d9f9 commit 6907e1f
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ifdef USAGELOG
endif

CFLAGS=$(FLAGS) $(EXFLAGS) $(LOGFLAGS)
OBJS=main.o datagram.o event_common.o log.o session.o endian.o directory.o errortable.o tnfs_file.o chroot.o fileinfo.o stats.o $(EXOBJS)
OBJS=main.o datagram.o event_common.o log.o session.o endian.o directory.o errortable.o tnfs_file.o chroot.o fileinfo.o stats.o auth.o $(EXOBJS)

all: $(OBJS)
$(CC) -o ../bin/$(EXEC) $(OBJS) $(LIBS)
Expand Down
54 changes: 54 additions & 0 deletions src/auth.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "auth.h"
#include "tnfs.h"
#include "tnfs_file.h"

int RW_CMDS[] =
{
TNFS_MKDIR,
TNFS_RMDIR,
TNFS_WRITEBLOCK,
TNFS_UNLINKFILE,
TNFS_CHMODFILE,
TNFS_RENAMEFILE,
-1,
};

int RW_FLAGS =
TNFS_O_WRONLY |
TNFS_O_RDWR |
TNFS_O_APPEND |
TNFS_O_CREAT |
TNFS_O_TRUNC |
TNFS_O_EXCL;

bool read_only;

void auth_init(bool _read_only)
{
read_only = _read_only;
}

bool is_cmd_allowed(uint8_t cmd)
{
if (!read_only)
{
return true;
}
for (int i = 0; RW_CMDS[i] != -1; i++)
{
if (RW_CMDS[i] == cmd)
{
return false;
}
}
return true;
}

bool is_open_allowed(char *filename, int flags)
{
if (!read_only)
{
return true;
}
return (flags & RW_FLAGS) == 0;
}
13 changes: 13 additions & 0 deletions src/auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef _READONLY_H
#define _READONLY_H

#include <stdint.h>
#include <stdbool.h>

void auth_init(bool enable_writes);

bool is_cmd_allowed(uint8_t cmd);

bool is_open_allowed(char *filename, int flags);

#endif
20 changes: 18 additions & 2 deletions src/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ TNFS daemon datagram handler
*/

#include <sys/types.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
Expand All @@ -51,9 +52,11 @@ TNFS daemon datagram handler
#include "directory.h"
#include "tnfs_file.h"
#include "event.h"
#include "auth.h"

int sockfd; /* UDP global socket file descriptor */
int tcplistenfd; /* TCP listening socket file descriptor */
int sockfd; /* UDP global socket file descriptor */
int tcplistenfd; /* TCP listening socket file descriptor */
bool write_support; /* Whether writes should be enabled. */

tnfs_cmdfunc dircmd[NUM_DIRCMDS] =
{&tnfs_opendir, &tnfs_readdir, &tnfs_closedir,
Expand Down Expand Up @@ -378,6 +381,12 @@ void tnfs_decode(struct sockaddr_in *cliaddr, int cli_fd, int rxbytes, unsigned
TNFSMSGLOG(&hdr, "REQUEST cmd=0x%02x %s", hdr.cmd, get_cmd_name(hdr.cmd));
#endif

if (!is_cmd_allowed(hdr.cmd))
{
tnfs_notpermitted(&hdr);
return;
}

/* The MOUNT command is the only one that doesn't need an
* established session (since MOUNT is actually what will
* establish the session) */
Expand Down Expand Up @@ -463,6 +472,13 @@ void tnfs_badcommand(Header *hdr, Session *sess)
tnfs_send(sess, hdr, NULL, 0);
}

void tnfs_notpermitted(Header *hdr)
{
TNFSMSGLOG(hdr, "Command %s is not permitted", get_cmd_name(hdr->cmd));
hdr->status = TNFS_EPERM;
tnfs_send(NULL, hdr, NULL, 0);
}

void tnfs_send(Session *sess, Header *hdr, unsigned char *msg, int msgsz)
{
struct sockaddr_in cliaddr;
Expand Down
1 change: 1 addition & 0 deletions src/datagram.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void tnfs_decode(struct sockaddr_in *cliaddr, int cli_fd,
int rxbytes, unsigned char *rxbuf);
void tnfs_invalidsession(Header *hdr);
void tnfs_badcommand(Header *hdr, Session *sess);
void tnfs_notpermitted(Header *hdr);
void tnfs_send(Session *sess, Header *hdr, unsigned char *msg, int msgsz);
void tnfs_resend(Session *sess, struct sockaddr_in *cliaddr, int cli_fd);
#endif
34 changes: 24 additions & 10 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*
* */

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Expand All @@ -35,6 +36,7 @@
#include "errortable.h"
#include "chroot.h"
#include "log.h"
#include "auth.h"

/* declare the main() - it won't be used elsewhere so I'll not bother
* with putting it in a .h file */
Expand All @@ -47,14 +49,15 @@ int main(int argc, char **argv)
char *uvalue = NULL;
char *gvalue = NULL;
#endif
bool read_only = false;
char *pvalue = NULL;

if(argc >= 2)
{
#ifdef ENABLE_CHROOT
while((opt = getopt(argc, argv, "u:g:p:")) != -1)
while((opt = getopt(argc, argv, "ru:g:p:")) != -1)
#else
while((opt = getopt(argc, argv, "p:")) != -1)
while((opt = getopt(argc, argv, "rp:")) != -1)
#endif
{
switch(opt)
Expand All @@ -63,6 +66,9 @@ int main(int argc, char **argv)
case 'p':
pvalue = optarg;
break;
case 'r':
read_only = true;
break;
#ifdef ENABLE_CHROOT
case 'u':
uvalue = optarg;
Expand All @@ -83,9 +89,9 @@ int main(int argc, char **argv)
else
{
#ifdef ENABLE_CHROOT
LOG("Usage: tnfsd <root dir> [-u <username> -g <group> -p <port>]\n");
LOG("Usage: tnfsd <root dir> [-u <username> -g <group> -p <port>] -r\n");
#else
LOG("Usage: tnfsd <root dir> [-p <port>]\n");
LOG("Usage: tnfsd <root dir> [-p <port>] -r\n");
#endif
exit(-1);
}
Expand Down Expand Up @@ -139,13 +145,21 @@ int main(int argc, char **argv)
const char *version = "24.0522.1";

LOG("Starting tnfsd version %s on port %d using root directory \"%s\"\n", version, port, argv[optind]);
if (read_only)
{
LOG("The server runs in read-only mode. TNFS clients can only list and download files.\n");
}
else
{
LOG("The server runs in read-write mode. TNFS clients can upload and modify files. Use -r to enable read-only mode.\n");
}

tnfs_init(); /* initialize structures etc. */
tnfs_init_errtable(); /* initialize error lookup table */
tnfs_event_init();
tnfs_sockinit(port); /* initialize communications */
tnfs_mainloop(); /* run */
tnfs_event_close();
tnfs_init(); /* initialize structures etc. */
tnfs_init_errtable(); /* initialize error lookup table */
tnfs_event_init(); /* initialize event system */
tnfs_sockinit(port); /* initialize communications */
auth_init(read_only); /* initialize authentication */
tnfs_mainloop(); /* run */

return 0;
}
13 changes: 10 additions & 3 deletions src/tnfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "endian.h"
#include "bsdcompat.h"
#include "log.h"
#include "auth.h"

char fnbuf[MAX_FILEPATH];
unsigned char iobuf[MAX_IOSZ + 2]; /* 2 bytes added for the size param */
Expand Down Expand Up @@ -95,13 +96,19 @@ void tnfs_open(Header *hdr, Session *s, unsigned char *buf, int bufsz)
return;
}

flags = *buf + (*(buf + 1) * 256);
mode = *(buf + 2) + (*(buf + 3) * 256);

if (!is_open_allowed(fnbuf, flags))
{
tnfs_notpermitted(hdr);
return;
}

for (i = 0; i < MAX_FD_PER_CONN; i++)
{
if (s->fd[i] == 0)
{
flags = *buf + (*(buf + 1) * 256);
mode = *(buf + 2) + (*(buf + 3) * 256);

#ifdef WITH_ZIP
fd = zipopen(fnbuf, tnfs_make_mode(flags), mode);
#else
Expand Down

0 comments on commit 6907e1f

Please sign in to comment.