nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Nano-devel] Enhancement: nano 1.3.1 restricted mode patch


From: IO ERROR
Subject: [Nano-devel] Enhancement: nano 1.3.1 restricted mode patch
Date: Mon, 16 Feb 2004 10:47:08 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6b) Gecko/20040127 Thunderbird/0.4

Recently I needed a small text editor that could be secured in such a way that it would only edit a specific file or files, and not allow the user access to the underlying filesystem or a command shell. I chose to use nano, since it was easy to use. However, I had to patch it a bit, since while it has a chroot-like mode, this wasn't sufficiently secure.

The included patch enhances nano by adding a restricted mode, wherein nano will not:
* Read any file not specified on the command line
* Write to any file not specified on the command line
* Read the .nanorc or global nanorc files
* Append or prepend any files
* Allow suspending

It does this by adding a RESTRICTED flag to the global flags (I had to change it to unsigned to add in the flag) and checking it in numerous places. Probably a few more than necessary, but I sleep better at night.

To start nano in restricted mode with this patch, call it through a symlink that starts with 'r', e.g. "rnano", or call nano with the -Z option.

diff -urN nano-1.3.1.orig/src/files.c nano-1.3.1/src/files.c
--- nano-1.3.1.orig/src/files.c 2004-01-08 10:10:01.000000000 -0600
+++ nano-1.3.1/src/files.c      2004-02-14 19:39:34.000000000 -0600
@@ -1682,7 +1682,7 @@
 
     answer = mallocstrcpy(answer, path);
 
-    if (exiting && ISSET(TEMP_OPT)) {
+    if (exiting && ISSET(TEMP_OPT) || ISSET(RESTRICTED)) {
        if (filename[0] != '\0') {
            i = write_file(answer, 0, 0, 0);
            display_main_list();
@@ -1804,7 +1804,7 @@
                i = do_yesno(0, _("File exists, OVERWRITE ?"));
                if (i == 0 || i == -1)
                    continue;
-           } else if (filename[0] != '\0'
+           } else if (filename[0] != '\0' && !ISSET(RESTRICTED)
 #ifndef NANO_SMALL
                && (!ISSET(MARK_ISSET) || exiting)
 #endif
@@ -1818,7 +1818,7 @@
 #ifndef NANO_SMALL
        /* Here's where we allow the selected text to be written to
         * a separate file. */
-       if (ISSET(MARK_ISSET) && !exiting) {
+       if (ISSET(MARK_ISSET) && !exiting && !ISSET(RESTRICTED)) {
            filestruct *fileagebak = fileage;
            filestruct *filebotbak = filebot;
            int oldmod = ISSET(MODIFIED);
diff -urN nano-1.3.1.orig/src/global.c nano-1.3.1/src/global.c
--- nano-1.3.1.orig/src/global.c        2004-01-08 10:10:01.000000000 -0600
+++ nano-1.3.1/src/global.c     2004-02-14 19:19:26.000000000 -0600
@@ -39,7 +39,7 @@
 int search_last_line;          /* Is this the last search line? */
 int search_offscreen;          /* Search lines not displayed */
 
-int flags = 0;                 /* Our new flag containing many options */
+unsigned long flags = 0;               /* Our new flag containing many options 
*/
 WINDOW *edit;                  /* The file portion of the editor */
 WINDOW *topwin;                        /* Top line of screen */
 WINDOW *bottomwin;             /* Bottom buffer */
@@ -461,6 +461,7 @@
 
     /* this is so we can view multiple files */
     /* Translators: try to keep this string under 10 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&main_list, NANO_INSERTFILE_KEY, _("Read File"),
                IFHELP(nano_insert_msg, NANO_NO_KEY), NANO_INSERTFILE_FKEY,
                NANO_NO_KEY,
@@ -785,6 +786,7 @@
 
 #ifndef DISABLE_BROWSER
     /* Translators: try to keep this string under 16 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&writefile_list, NANO_TOFILES_KEY, _("To Files"),
                IFHELP(nano_tofiles_msg, NANO_NO_KEY), NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
@@ -792,22 +794,26 @@
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 16 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&writefile_list, NANO_NO_KEY, _("DOS Format"),
                IFHELP(nano_dos_msg, TOGGLE_DOS_KEY), NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
 
     /* Translators: try to keep this string under 16 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&writefile_list, NANO_NO_KEY, _("Mac Format"),
                IFHELP(nano_mac_msg, TOGGLE_MAC_KEY), NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
 #endif
 
     /* Translators: try to keep this string under 16 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&writefile_list, NANO_NO_KEY, _("Append"),
                IFHELP(nano_append_msg, NANO_APPEND_KEY), NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
 
     /* Translators: try to keep this string under 16 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&writefile_list, NANO_NO_KEY, _("Prepend"),
                IFHELP(nano_prepend_msg, NANO_PREPEND_KEY), NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
@@ -834,6 +840,7 @@
                NANO_NO_KEY, VIEW, 0);
 
 #ifndef DISABLE_BROWSER
+    if (!ISSET(RESTRICTED))
     sc_init_one(&insertfile_list, NANO_TOFILES_KEY, _("To Files"),
                IFHELP(nano_tofiles_msg, NANO_NO_KEY), NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
@@ -841,12 +848,14 @@
 
 #ifndef NANO_SMALL
     /* Translators: try to keep this string under 22 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&insertfile_list, NANO_EXTCMD_KEY, _("Execute Command"),
                IFHELP(nano_execute_msg, NANO_NO_KEY), NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
 
 #ifdef ENABLE_MULTIBUFFER
     /* Translators: try to keep this string under 22 characters long */
+    if (!ISSET(RESTRICTED))
     sc_init_one(&insertfile_list, NANO_NO_KEY, _("New Buffer"),
                IFHELP(nano_multibuffer_msg, TOGGLE_MULTIBUFFER_KEY), 
NANO_NO_KEY,
                NANO_NO_KEY, NOVIEW, 0);
diff -urN nano-1.3.1.orig/src/nano.c nano-1.3.1/src/nano.c
--- nano-1.3.1.orig/src/nano.c  2004-01-08 10:10:01.000000000 -0600
+++ nano-1.3.1/src/nano.c       2004-02-14 19:29:55.000000000 -0600
@@ -151,6 +151,9 @@
     char *ret;
     int i = -1;
 
+    /* No emergency files in restricted mode! */
+    if (ISSET(RESTRICTED)) return;
+
     /* If we can't save, we have REAL bad problems, but we might as well
        TRY. */
     if (die_filename[0] == '\0')
@@ -657,6 +660,7 @@
 #ifdef ENABLE_COLOR
     print1opt(_("-Y [str]"), _("--syntax [str]"), _("Syntax definition to 
use"));
 #endif
+    print1opt(_("-Z"), _("--restricted"), _("Restricted mode"));
     print1opt("-c", "--const", _("Constantly show cursor position"));
 #ifndef NANO_SMALL
     print1opt("-d", "--rebinddelete", _("Fix Backspace/Delete confusion 
problem"));
@@ -3118,6 +3122,7 @@
        {"smooth", 0, 0, 'S'},
        {"autoindent", 0, 0, 'i'},
        {"cut", 0, 0, 'k'},
+       {"restricted", 0, 0, 'Z'},
 #endif
        {0, 0, 0, 0}
     };
@@ -3137,11 +3142,11 @@
 #endif
 
 #ifdef HAVE_GETOPT_LONG
-    while ((optchr = getopt_long(argc, argv, 
"h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz",
+    while ((optchr = getopt_long(argc, argv, 
"h?BDFHIMNQ:RST:VY:Zabcdefgijklmo:pr:s:tvwxz",
                                 long_options, NULL)) != -1) {
 #else
     while ((optchr =
-           getopt(argc, argv, "h?BDFHIMNQ:RST:VY:abcdefgijklmo:pr:s:tvwxz")) 
!= -1) {
+           getopt(argc, argv, "h?BDFHIMNQ:RST:VY:Zabcdefgijklmo:pr:s:tvwxz")) 
!= -1) {
 #endif
 
        switch (optchr) {
@@ -3226,6 +3231,10 @@
            syntaxstr = mallocstrcpy(syntaxstr, optarg);
            break;
 #endif
+       case 'Z':
+           SET(RESTRICTED);
+           SET(NO_RCFILE);
+           break;
        case 'c':
            SET(CONSTUPDATE);
            break;
@@ -3302,6 +3311,12 @@
        }
     }
 
+    /* If filename starts with 'r' we use restricted mode. */
+    if (argv[0][0] == 'r') {
+       SET(RESTRICTED);
+       SET(NO_RCFILE);
+    }
+
 /* We've read through the command line options.  Now back up the flags
    and values that are set, and read the rcfile(s).  If the values
    haven't changed afterward, restore the backed-up values. */
diff -urN nano-1.3.1.orig/src/nano.h nano-1.3.1/src/nano.h
--- nano-1.3.1.orig/src/nano.h  2004-01-08 10:10:01.000000000 -0600
+++ nano-1.3.1/src/nano.h       2004-02-14 19:03:05.000000000 -0600
@@ -289,6 +289,7 @@
 #define HISTORY_CHANGED                (1<<28)
 #define HISTORYLOG             (1<<29)
 #define JUSTIFY_MODE           (1<<30)
+#define RESTRICTED             (1<<31)
 
 /* Control key sequences, changing these would be very very bad. */
 #define NANO_CONTROL_SPACE 0
diff -urN nano-1.3.1.orig/src/proto.h nano-1.3.1/src/proto.h
--- nano-1.3.1.orig/src/proto.h 2004-01-08 10:10:01.000000000 -0600
+++ nano-1.3.1/src/proto.h      2004-02-14 19:40:09.000000000 -0600
@@ -40,7 +40,7 @@
 #endif
 extern long totsize;
 extern int temp_opt;
-extern int flags;
+extern unsigned long flags;
 extern int tabsize;
 extern int search_last_line;
 extern int search_offscreen;
diff -urN nano-1.3.1.orig/doc/man/nano.1 nano-1.3.1/doc/man/nano.1
--- nano-1.3.1.orig/doc/man/nano.1      2004-01-08 10:10:01.000000000 -0600
+++ nano-1.3.1/doc/man/nano.1   2004-02-14 19:45:38.000000000 -0600
@@ -88,6 +88,11 @@
 .I .nanorc
 to use, if available.
 .TP
+.B \-Z (\-\-restricted)
+Don't allow suspending, read the
+.I .nanorc
+file, or read/write of any file not specified on the command line.
+.TP
 .B \-c (\-\-const)
 Constantly show the cursor position.
 .TP
diff -urN nano-1.3.1.orig/doc/texinfo/nano.texi nano-1.3.1/doc/texinfo/nano.texi
--- nano-1.3.1.orig/doc/texinfo/nano.texi       2004-01-08 10:10:01.000000000 
-0600
+++ nano-1.3.1/doc/texinfo/nano.texi    2004-02-14 19:49:50.000000000 -0600
@@ -153,6 +153,10 @@
 Specify a specific syntax highlighting from the .nanorc to use, if
 available.
 
address@hidden -Z, --restricted
+Don't allow suspending, read the .nanorc file, or read/write of any file
+not specified on the command line.
+
 @item -c, --const
 Constantly display the cursor position and line number on the statusbar.
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]