1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/pty/pty.c (getDevice): add nomesg argument.

(get_device_once): add nomesg argument.  chmod slave tty to 0600
  if nomesg.  more error tests.
  (no_mesg): new function.
  (pty_open): make slave tty's mode 0600.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20795 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2008-12-16 11:39:17 +00:00
parent 3ea21e47c1
commit e27fbfbc98
3 changed files with 90 additions and 80 deletions

View file

@ -1,3 +1,11 @@
Tue Dec 16 20:34:44 2008 Tanaka Akira <akr@fsij.org>
* ext/pty/pty.c (getDevice): add nomesg argument.
(get_device_once): add nomesg argument. chmod slave tty to 0600
if nomesg. more error tests.
(no_mesg): new function.
(pty_open): make slave tty's mode 0600.
Tue Dec 16 20:24:20 2008 Tadayoshi Funaba <tadf@dotrb.org> Tue Dec 16 20:24:20 2008 Tadayoshi Funaba <tadf@dotrb.org>
* lib/date/format.rb (_parse): m17n compliant. * lib/date/format.rb (_parse): m17n compliant.

View file

@ -130,7 +130,7 @@ struct pty_info {
rb_pid_t child_pid; rb_pid_t child_pid;
}; };
static void getDevice(int*, int*, char [DEVICELEN]); static void getDevice(int*, int*, char [DEVICELEN], int);
struct exec_info { struct exec_info {
int argc; int argc;
@ -248,7 +248,7 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
argv = &v; argv = &v;
} }
getDevice(&master, &slave, SlaveName); getDevice(&master, &slave, SlaveName, 0);
carg.master = master; carg.master = master;
carg.slave = slave; carg.slave = slave;
@ -271,10 +271,19 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
} }
static int static int
get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail) no_mesg(char *slavedevice, int nomesg)
{
if (nomesg)
return chmod(slavedevice, 0600);
else
return 0;
}
static int
get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg, int fail)
{ {
#if defined(HAVE_POSIX_OPENPT) #if defined(HAVE_POSIX_OPENPT)
int masterfd,slavefd; int masterfd = -1, slavefd = -1;
char *slavedevice; char *slavedevice;
struct sigaction dfl, old; struct sigaction dfl, old;
@ -282,33 +291,34 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
dfl.sa_flags = 0; dfl.sa_flags = 0;
sigemptyset(&dfl.sa_mask); sigemptyset(&dfl.sa_mask);
if((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) != -1) { if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
sigaction(SIGCHLD, &dfl, &old); if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
if(grantpt(masterfd) != -1) { if (grantpt(masterfd) == -1) goto grantpt_error;
sigaction(SIGCHLD, &old, NULL); if (sigaction(SIGCHLD, &old, NULL) == -1) goto error;
if(unlockpt(masterfd) != -1) { if (unlockpt(masterfd) == -1) goto error;
if((slavedevice = ptsname(masterfd)) != NULL) { if ((slavedevice = ptsname(masterfd)) == NULL) goto error;
if((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) != -1) { if (no_mesg(slavedevice, nomesg) == -1) goto error;
if ((slavefd = open(slavedevice, O_RDWR|O_NOCTTY, 0)) == -1) goto error;
#if defined I_PUSH && !defined linux #if defined I_PUSH && !defined linux
if(ioctl(slavefd, I_PUSH, "ptem") != -1) { if (ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
if(ioctl(slavefd, I_PUSH, "ldterm") != -1) { if (ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
ioctl(slavefd, I_PUSH, "ttcompat"); if (ioctl(slavefd, I_PUSH, "ttcompat") == -1) goto error;
#endif #endif
*master = masterfd;
*slave = slavefd; *master = masterfd;
strlcpy(SlaveName, slavedevice, DEVICELEN); *slave = slavefd;
return 0; strlcpy(SlaveName, slavedevice, DEVICELEN);
#if defined I_PUSH && !defined linux return 0;
}
} grantpt_error:
#endif sigaction(SIGCHLD, &old, NULL);
} error:
} if (slavefd != -1) close(slavefd);
} if (masterfd != -1) close(masterfd);
} if (!fail) {
close(masterfd); rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
} }
if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
return -1; return -1;
#elif defined HAVE_OPENPTY #elif defined HAVE_OPENPTY
/* /*
@ -320,12 +330,18 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
if (!fail) return -1; if (!fail) return -1;
rb_raise(rb_eRuntimeError, "openpty() failed"); rb_raise(rb_eRuntimeError, "openpty() failed");
} }
if (no_mesg(slavedevice, nomesg) == -1) {
if (!fail) return -1;
rb_raise(rb_eRuntimeError, "can't chmod slave pty");
}
return 0; return 0;
#elif defined HAVE__GETPTY #elif defined HAVE__GETPTY
char *name; char *name;
mode_t mode = nomesg ? 0600 : 0622;
if (!(name = _getpty(master, O_RDWR, 0622, 0))) { if (!(name = _getpty(master, O_RDWR, mode, 0))) {
if (!fail) return -1; if (!fail) return -1;
rb_raise(rb_eRuntimeError, "_getpty() failed"); rb_raise(rb_eRuntimeError, "_getpty() failed");
} }
@ -335,72 +351,70 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int fail)
return 0; return 0;
#elif defined(HAVE_PTSNAME) #elif defined(HAVE_PTSNAME)
int i,j; int masterfd = -1, slavefd = -1;
char *pn; char *slavedevice;
void (*s)(); void (*s)();
extern char *ptsname(int); extern char *ptsname(int);
extern int unlockpt(int); extern int unlockpt(int);
extern int grantpt(int); extern int grantpt(int);
if((i = open("/dev/ptmx", O_RDWR, 0)) != -1) { if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
s = signal(SIGCHLD, SIG_DFL); s = signal(SIGCHLD, SIG_DFL);
if(grantpt(i) != -1) { if(grantpt(masterfd) == -1) goto error;
signal(SIGCHLD, s); signal(SIGCHLD, s);
if(unlockpt(i) != -1) { if(unlockpt(masterfd) == -1) goto error;
if((pn = ptsname(i)) != NULL) { if((slavedevice = ptsname(masterfd)) == NULL) goto error;
if((j = open(pn, O_RDWR, 0)) != -1) { if (no_mesg(slavedevice, nomesg) == -1) goto error;
if((slavefd = open(slavedevice, O_RDWR, 0)) == -1) goto error;
#if defined I_PUSH && !defined linux #if defined I_PUSH && !defined linux
if(ioctl(j, I_PUSH, "ptem") != -1) { if(ioctl(slavefd, I_PUSH, "ptem") == -1) goto error;
if(ioctl(j, I_PUSH, "ldterm") != -1) { if(ioctl(slavefd, I_PUSH, "ldterm") == -1) goto error;
ioctl(j, I_PUSH, "ttcompat"); ioctl(slavefd, I_PUSH, "ttcompat");
#endif #endif
*master = i; *master = masterfd;
*slave = j; *slave = slavefd;
strlcpy(SlaveName, pn, DEVICELEN); strlcpy(SlaveName, slavedevice, DEVICELEN);
return 0; return 0;
#if defined I_PUSH && !defined linux
} error:
} if (slavefd != -1) close(slavefd);
#endif if (masterfd != -1) close(masterfd);
}
}
}
}
close(i);
}
if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device"); if (!fail) rb_raise(rb_eRuntimeError, "can't get Master/Slave device");
return -1; return -1;
#else #else
int i,j; int masterfd = -1, slavefd = -1;
const char *const *p; const char *const *p;
char MasterName[DEVICELEN]; char MasterName[DEVICELEN];
for (p = deviceNo; *p != NULL; p++) { for (p = deviceNo; *p != NULL; p++) {
snprintf(MasterName, sizeof MasterName, MasterDevice, *p); snprintf(MasterName, sizeof MasterName, MasterDevice, *p);
if ((i = open(MasterName,O_RDWR,0)) >= 0) { if ((masterfd = open(MasterName,O_RDWR,0)) >= 0) {
*master = i; *master = masterfd;
snprintf(SlaveName, DEVICELEN, SlaveDevice, *p); snprintf(SlaveName, DEVICELEN, SlaveDevice, *p);
if ((j = open(SlaveName,O_RDWR,0)) >= 0) { if ((slavefd = open(SlaveName,O_RDWR,0)) >= 0) {
*slave = j; *slave = slavefd;
chown(SlaveName, getuid(), getgid()); if (chown(SlaveName, getuid(), getgid()) != 0) goto error;
chmod(SlaveName, 0622); if (chmod(SlaveName, nomesg ? 0600 : 0622) != 0) goto error;
return 0; return 0;
} }
close(i); close(masterfd);
} }
} }
error:
if (slavefd != -1) close(slavefd);
if (masterfd != -1) close(masterfd);
if (fail) rb_raise(rb_eRuntimeError, "can't get %s", SlaveName); if (fail) rb_raise(rb_eRuntimeError, "can't get %s", SlaveName);
return -1; return -1;
#endif #endif
} }
static void static void
getDevice(int *master, int *slave, char SlaveName[DEVICELEN]) getDevice(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg)
{ {
if (get_device_once(master, slave, SlaveName, 0)) { if (get_device_once(master, slave, SlaveName, nomesg, 0)) {
rb_gc(); rb_gc();
get_device_once(master, slave, SlaveName, 1); get_device_once(master, slave, SlaveName, nomesg, 1);
} }
} }
@ -444,7 +458,7 @@ pty_open(VALUE klass)
rb_io_t *master_fptr, *slave_fptr; rb_io_t *master_fptr, *slave_fptr;
VALUE assoc; VALUE assoc;
getDevice(&master_fd, &slave_fd, slavename); getDevice(&master_fd, &slave_fd, slavename, 1);
master_io = rb_obj_alloc(rb_cIO); master_io = rb_obj_alloc(rb_cIO);
MakeOpenFile(master_io, master_fptr); MakeOpenFile(master_io, master_fptr);

View file

@ -99,23 +99,11 @@ class TestPTY < Test::Unit::TestCase
end end
def test_stat_slave def test_stat_slave
# If grantpt is used, the slave device is changed as follows.
# owner: real UID
# group: an unspecified value (e.g. tty)
# mode: 0620 (rw--w----)
#
# The group is not testable because unspecified.
#
# The mode is testable but the condition is relaxed because other
# pty functions (openpty, _getpty, etc.) may not use 0620.
# But no one can read from the tty, I hope (for security reason).
#
PTY.open {|master, slave| PTY.open {|master, slave|
s = File.stat(slave.path) s = File.stat(slave.path)
assert_equal(Process.uid, s.uid) assert_equal(Process.uid, s.uid)
assert_equal(0600, s.mode & 0755) assert_equal(0600, s.mode & 0777)
} }
end end
end if defined? PTY end if defined? PTY