Added a restricted mode in the form of a new command: red

This commit is contained in:
alm 1993-05-27 01:27:46 +00:00
parent 9030436006
commit f7f6e6ffd5
5 changed files with 131 additions and 53 deletions

View File

@ -1,6 +1,8 @@
PROG= ed
CFLAGS=-g -DVI_BANG -DDES -DGNU_REGEX
CFLAGS+=-DVI_BANG -DDES -DGNU_REGEX
SRCS= ed.c re.c buf.c cbc.c
LDADD= -lgnuregex -lcrypt
LINKS= ${BINDIR}/ed ${BINDIR}/red
MLINKS= ed.1 red.1
.include <bsd.prog.mk>

View File

@ -40,3 +40,7 @@ The vi editor's bang command syntax is supported, i.e.,
If ed is invoked with a name argument prefixed by a bang, then the
remainder of the argument is interpreted as a shell command. To invoke
ed on a file whose name starts with bang, prefix the name with a backslash.
A restricted version of ed is supported when invoked as red. This limits
editing of files in the local directory only and prohibits !<shell-cmd>
commands.

View File

@ -1,15 +1,22 @@
.TH ED 1 386BSD
.TH ED 1 "21 May 1993"
.SH NAME
ed \- text editor
ed, red \- text editor
.SH SYNOPSIS
ed [-] [-sx] [-p \fIstring\fR] [\fIfile\fR]
.LP
red [-] [-sx] [-p \fIstring\fR] [\fIfile\fR]
.SH DESCRIPTION
.B ed
is a line-oriented text editor.
It is used to create, display, modify and otherwise manipulate text
files.
.B red
is a restricted
.BR ed :
it can edit files only in the current
directory and cannot execute shell commands.
If invoked with the
If invoked with a
.I file
argument, then a copy of
.I file
@ -35,7 +42,7 @@ executed to manipulate the contents of the editor buffer.
A typical command might look like:
.sp
.RS
,s/\fIold\fR/\fInew\fR/gp
,s/\fIold\fR/\fInew\fR/g
.RE
.sp
which replaces all occurences of the string
@ -55,7 +62,10 @@ enters input mode. This is the primary means
of adding text to a file.
In this mode, no commands are available;
instead, the standard input is written
directly to the editor buffer. Input mode is terminated by
directly to the editor buffer. Lines must end with a
.IR newline
character (entered by hitting the RETURN key).
Input mode is terminated by
entering a single period (\fI.\fR) on a line.
All
@ -106,18 +116,21 @@ Specifies a command prompt. This may be toggled on and off with the
command.
.TP 8
name
.I file
Specifies the name of a file to read. If
.I name
.I file
is prefixed with a
bang (!), then it is interpreted as a shell command. In this case,
what is read is
the standard output of
.I name
.I file
executed via
.IR sh (1).
To read a file whose name begins with a bang, prefix the
name with a backslash (\\).
The default filename is set to
.I file
only if it is not prefixed with a bang.
.SS LINE ADDRESSING
An address represents the number of line in the buffer.
@ -144,7 +157,7 @@ relative to the current address.
One exception to the rule that addresses represent line numbers is the
address
.I `0'
.I 0
(zero).
This means "before the first line,"
and is legal wherever it makes sense.
@ -317,6 +330,16 @@ in
it must be the first character.
A range of characters may be specified by separating the end characters
of the range with a `-', e.g., `a-z' specifies the lower case characters.
The following literal expressions can also be used in
.I char-class
to specify sets of characters:
\ \ [:alnum:]\ \ [:cntrl:]\ \ [:lower:]\ \ [:space:]
.PD 0
\ \ [:alpha:]\ \ [:digit:]\ \ [:print:]\ \ [:upper:]
.PD 0
\ \ [:blank:]\ \ [:graph:]\ \ [:punct:]\ \ [:xdigit:]
If `-' appears as the first or last
character of
.IR char-class ,
@ -325,6 +348,26 @@ All other characters in
.I char-class
match themselves.
Patterns in
.I char-class
of the form:
\ \ [.\fIcol-elm\fR.] or,
.PD 0
\ \ [=\fIcol-elm\fR=]
where
.I col-elm
is a
.I collating element
are interpreted according to
.IR locale (5)
(not currently supported).
See
.IR regex (3)
for an explanation of these constructs.
.TP 8
[^\fIchar-class\fR]
Matches any single character, other than newline, not in
@ -399,13 +442,19 @@ If the comma is also omitted, then it matches exactly
.I n
times.
.LP
Additional regular expression operators may be defined depending on the
particular
.IR regex (3)
implementation.
.SS COMMANDS
All
.B ed
commands are single characters, though some require additonal parameters.
If a command's paramters extend over several lines, then
If a command's parameters extend over several lines, then
each line except for the last
must end in a backslash (\\).
must be terminated with a backslash (\\).
In general, at most one command is allowed per line.
However, most commands accept a print suffix, which is any of
@ -461,9 +510,8 @@ The current address is set to the last line read.
.TP 8
.RI e \ !command
Edits the standard output of
.I command
executed via
.IR sh (1).
.I !command
executed as described below.
The default filename is unchanged.
Any lines in the buffer are deleted before the output of
.I command
@ -570,7 +618,7 @@ The current address is set to the resultant line.
Marks a line with a lower case letter
.IR lc .
The line can then be addressed as
.I `'lc'
.I 'lc
(i.e., a single quote followed by
.I lc
) in subsequent commands. The mark is not cleared until the line is
@ -586,7 +634,7 @@ printed.
(.,.)m(.)
Moves lines in the buffer. The addressed lines are moved to after the
right-hand destination address, which may be the address
.IR `0'
.IR 0
(zero).
The current address is set to the
last line moved.
@ -636,9 +684,8 @@ The current address is set to the last line read.
.TP 8
.RI ($)r \ !command
Reads the standard output of
.I command
executed via
.IR sh (1)
.I !command
executed as described below.
to after the addressed line.
The default filename is unchanged.
The current address is set to the last line read.
@ -663,6 +710,16 @@ is a postive number, causes only the
match to be replaced.
The current address is set the last line affected.
.I re
and
.I replacement
may be delimited by any character other than space and newline.
If one or two of the last delimiters is omitted, then the last line
affected is printed as though the print suffix
.I `p'
were specified.
An unescaped `&' in
.I replacement
is replaced by the currently matched text.
@ -682,15 +739,6 @@ Newlines may be included in
.I replacement
if they are escaped with a backslash (\\).
.I re
and
.I replacement
may be delimited by any character other than space and newline.
If one or two of the last delimiters is omitted, then the last line
affected is printed as though the print suffix
.I `p'
were specified.
.TP 8
.RI (.,.)s [rgp]*
Repeats the last substitution.
@ -719,7 +767,7 @@ The current address is set to the last line affected.
(.,.)t(.)
Copies (i.e., transfers) the addressed lines to after the right-hand
destination address, which may be the address
.IR `0'
.IR 0
(zero).
The current address is set to the last line
copied.
@ -780,9 +828,8 @@ command.
.TP 8
.RI (1,$)w \ !command
Writes the addressed lines to the standard input of
.I command
executed via
.IR sh (1).
.I !command
executed as described below.
The default filename and current address are unchanged.
.TP 8
@ -835,9 +882,8 @@ The current line is unchanged.
.TP 8
.RI (.,.)! command
Replaces the addressed lines with the output of
.I command
executed via
.IR sh (1).
.I !command
as described above.
The current address is set to the last line read.
.TP 8
@ -853,7 +899,7 @@ that line.
.TP 20
/tmp/ed.*
Buffer file
.PD 0
.TP 20
\fR./ed.hup\fR, $HOME/ed.hup
First and second files to which

View File

@ -114,6 +114,7 @@ int des = 0; /* if set, use crypt(3) for i/o */
int mutex = 0; /* if set, signals set "sigflags" */
int sigflags = 0; /* if set, signals received while mutex set */
int sigactive = 0; /* if set, signal handlers are enabled */
int red = 0; /* if set, restrict shell/directory access */
char dfn[MAXFNAME + 1] = ""; /* default filename */
long curln; /* current address */
@ -136,6 +137,7 @@ main(argc, argv)
int c, n;
long status = 0;
red = (n = strlen(argv[0])) > 2 && argv[0][n - 3] == 'r';
while ((c = getopt(argc, argv, "p:sx")) != EOF)
switch(c) {
case 'p': /* set prompt */
@ -182,11 +184,17 @@ main(argc, argv)
} else {
init_buf();
sigactive = 1; /* enable signal handlers */
if (argc) {
if (**argv != '!')
strcpy(dfn, *argv);
if (argc && **argv && ckfn(*argv)) {
if (doread(0, *argv) < 0 && !isatty(0))
quit(2);
else if (**argv != '!')
strcpy(dfn, *argv);
} else if (argc) {
fputs("?\n", stderr);
if (**argv == '\0')
sprintf(errmsg, "invalid filename");
if (!isatty(0))
quit(2);
}
}
for (;;) {
@ -638,7 +646,7 @@ docmd(glob)
}
VRFYCMD();
if (*fnp) strcpy(dfn, fnp);
printf("%s\n", dfn);
printf("%s\n", esctos(dfn));
break;
case 'g':
case 'G':
@ -1065,9 +1073,10 @@ getfn()
for (n = 0; *ibufp != '\n';)
file[n++] = *ibufp++;
file[n] = '\0';
return file;
return ckfn(file);
}
/* getrhs: extract substitution template from the command buffer */
getrhs(glob)
int glob;
@ -1142,11 +1151,14 @@ getshcmd()
static char *buf = NULL;
static int n = 0;
char *ip;
char *s; /* substitution char pointer */
int i = 0;
int j = 0;
if ((ip = ibufp = getcmdv(&j, 1)) == NULL)
if (red) {
sprintf(errmsg, "shell access restricted");
return ERR;
} else if ((s = ibufp = getcmdv(&j, 1)) == NULL)
return ERR;
CKBUF(buf, n, j + 1, ERR);
buf[i++] = '!'; /* prefix command w/ bang */
@ -1159,7 +1171,7 @@ getshcmd()
buf[i++] = *ibufp++;
break;
case '!':
if (ip != ibufp) {
if (s != ibufp) {
CKBUF(buf, n, i + 1, ERR);
buf[i++] = *ibufp++;
}
@ -1173,9 +1185,9 @@ getshcmd()
return ERR;
} else {
CKBUF(buf, n, i + shcmdi, ERR);
for (ip = shcmd + 1; ip < shcmd + shcmdi;)
buf[i++] = *ip++;
ip = ibufp++;
for (s = shcmd + 1; s < shcmd + shcmdi;)
buf[i++] = *s++;
s = ibufp++;
}
break;
case '%':
@ -1183,17 +1195,17 @@ getshcmd()
sprintf(errmsg, "no current filename");
return ERR;
}
j = strlen(dfn);
j = strlen(s = esctos(dfn));
CKBUF(buf, n, i + j, ERR);
for (ip = dfn; ip < dfn + j;)
buf[i++] = *ip++;
ip = ibufp++;
while (j--)
buf[i++] = *s++;
s = ibufp++;
break;
}
CKBUF(shcmd, shcmdsz, i + 1, ERR);
memcpy(shcmd, buf, i);
shcmd[shcmdi = i] = '\0';
return *ip == '!' || *ip == '%';
return *s == '!' || *s == '%';
}
@ -2182,3 +2194,16 @@ init_buf()
for (i = 0; i < 256; i++)
ctab[i] = i;
}
/* ckfn: return a legal filename */
char *
ckfn(s)
char *s;
{
if (red && (*s == '!' || !strcmp(s, "..") || strchr(s, '/'))) {
sprintf(errmsg, "shell access restricted");
return NULL;
}
return s;
}

View File

@ -200,6 +200,7 @@ if ((i) > (n)) { \
int append __P((long, int));
int cbcdec __P((char *, FILE *));
int cbcenc __P((char *, int, FILE *));
char *ckfn __P((char *));
int ckglob __P((void));
int ckrange __P((long, long));
int desflush __P((FILE *));