Imported from conserver-8.1.19.tar.gz

This commit is contained in:
Bryan Stansell 2013-09-26 11:07:01 -07:00
parent 64a2a77266
commit b94c8967bf
38 changed files with 4031 additions and 6179 deletions

32
CHANGES
View File

@ -1,6 +1,36 @@
CHANGES
=======
version 8.1.19 (Sep 26, 2013):
- prevent select/read loop when EOF on non-pty input (console) -
reported by Chris Marget <chris@marget.com>
- "!" syntax prefixing use of group names not honored - reported by
Zonker <consoleteam@gmail.com>
- fixed memory leak using timestamps - patch by Karvendhan M.
<Karvendhan.M@netapp.com>
- deprecated --with-cycladests (noop now) - cross-compilation should
work without it as autologin now expects setpgrp() to take two
arugments instead of testing for it
- no automatic checks for an empty password when using PAM
authentication - based on discussion with Ryan Kirkpatrick
<linux@rkirkpat.net>
- added 'sslcacertificatefile' and 'sslcacertificatepath' client
configuration options - based on patch by Aki Tuomi <cmouse@cmouse.fi>
- added 'sslcacertificatefile' and 'sslreqclientcert' server
configuration options
- added --with-req-server-cert to force clients to require a certificate
from the server when using SSL - based on emails with Thor Simon
<tls@coyotepoint.com>
- added server-side tasks (see conserver.cf man page) that are invoked
by the client (useful for things like IPMI-based power control of
servers, invoking resets of terminal server ports, or anything else
that requires scripting) - ideas from patch by Anton Lundin
<glance@acc.umu.se> and discussion on mailing list (2011)
- added 'confirm' option to break sequences
- added 'breaklist' option to limit exposure of break sequences to
consoles
- sending of break signals is now announced to all attached clients
version 8.1.18 (Nov 11, 2010):
- install man pages read-only and improved the contributed redhat init
script - patches by Eric Biederman <ebiederm@aristanetworks.com>
@ -902,5 +932,5 @@ before version 6.05:
and enhancements of various types were applied.
#
# $Id: CHANGES,v 1.225 2010/11/11 22:43:17 bryan Exp $
# $Id: CHANGES,v 1.238 2013/09/26 17:57:44 bryan Exp $
#

View File

@ -1,4 +1,5 @@
### Path settings
datarootdir = @datarootdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@

View File

@ -1,4 +1,5 @@
### Path settings
datarootdir = @datarootdir@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
prefix = @prefix@

View File

@ -69,11 +69,11 @@
*/
#ifndef lint
char *rcsid = "$Id: autologin.c,v 1.25 2006/04/10 01:50:16 bryan Exp $";
#endif /* not lint */
extern char *progname;
gid_t awGrps[NGROUPS_MAX];
int iGrps = 0;
char *rcsid = "$Id: autologin.c,v 1.27 2013/09/20 21:15:13 bryan Exp $";
#endif /* not lint */
extern char *progname;
gid_t awGrps[NGROUPS_MAX];
int iGrps = 0;
/*
* External variables
@ -82,366 +82,369 @@ int iGrps = 0;
extern int optind;
extern char *optarg;
void make_utmp();
void usage();
void make_utmp();
void usage();
int
Process()
{
int iErrs = 0;
int i, iNewGrp;
gid_t wGid;
uid_t wUid;
char *pcCmd = (char *)0,
*pcDevTty = (char *)0;
int iErrs = 0;
int i, iNewGrp;
gid_t wGid;
uid_t wUid;
char *pcCmd = (char *)0, *pcDevTty = (char *)0;
#ifdef HAVE_GETUSERATTR
char *pcGrps;
char *pcGrps;
#endif
struct passwd *pwd;
struct stat st;
struct termios n_tio;
struct passwd *pwd;
struct stat st;
struct termios n_tio;
#if defined(HAVE_BSM_AUDIT_H) && defined(HAVE_LIBBSM)
char my_hostname[MAXHOSTNAMELEN];
char my_hostname[MAXHOSTNAMELEN];
#endif
#if defined(HAVE_BSM_AUDIT_H) && defined(HAVE_LIBBSM)
if (0 != gethostname(my_hostname, sizeof(my_hostname))) {
(void) fprintf(stderr, "%s: gethostname: %s\n", progname, strerror(errno));
exit(1);
/* NOTREACHED */
}
if (0 != gethostname(my_hostname, sizeof(my_hostname))) {
(void)fprintf(stderr, "%s: gethostname: %s\n", progname,
strerror(errno));
exit(1);
/* NOTREACHED */
}
#endif
if ((char *)0 != pcCommand) {
if ((char *)0 == (pcCmd = (char *)malloc(strlen(pcCommand) + 4))) {
(void) fprintf(stderr, "%s: malloc: %s\n", progname, strerror(errno));
exit(1);
/* NOTREACHED */
}
(void)strcpy(pcCmd, "-c ");
(void)strcat(pcCmd, pcCommand);
if ((char *)0 != pcCommand) {
if ((char *)0 == (pcCmd = (char *)malloc(strlen(pcCommand) + 4))) {
(void)fprintf(stderr, "%s: malloc: %s\n", progname,
strerror(errno));
exit(1);
/* NOTREACHED */
}
(void)strcpy(pcCmd, "-c ");
(void)strcat(pcCmd, pcCommand);
}
if ( (char *)0 != pcGroup ) {
iErrs += addgroup(pcGroup);
}
if ((char *)0 != pcGroup) {
iErrs += addgroup(pcGroup);
}
if ( (char *)0 == pcLogin ) {
static char acLogin[17];
if ((struct passwd *)0 == (pwd = getpwuid(geteuid()))) {
(void) fprintf(stderr, "%s: %d: uid unknown\n", progname, geteuid());
exit(1);
/* NOTREACHED */
}
pcLogin = strcpy(acLogin, pwd->pw_name);
} else if ((struct passwd *)0 == (pwd = getpwnam(pcLogin))) {
(void) fprintf(stderr, "%s: %s: login name unknown\n", progname, pcLogin);
exit(1);
/* NOTREACHED */
if ((char *)0 == pcLogin) {
static char acLogin[17];
if ((struct passwd *)0 == (pwd = getpwuid(geteuid()))) {
(void)fprintf(stderr, "%s: %d: uid unknown\n", progname,
geteuid());
exit(1);
/* NOTREACHED */
}
wUid = pwd->pw_uid;
wGid = pwd->pw_gid;
(void)endpwent();
pcLogin = strcpy(acLogin, pwd->pw_name);
} else if ((struct passwd *)0 == (pwd = getpwnam(pcLogin))) {
(void)fprintf(stderr, "%s: %s: login name unknown\n", progname,
pcLogin);
exit(1);
/* NOTREACHED */
}
wUid = pwd->pw_uid;
wGid = pwd->pw_gid;
(void)endpwent();
#ifdef HAVE_GETUSERATTR
/* getuserattr() returns a funny list of groups:
* "grp1\0grp2\0grp3\0\0"
*/
if (0 == getuserattr(pcLogin, S_SUGROUPS, &pcGrps, SEC_LIST)) {
while ('\000' != *pcGrps) {
/* ignore "ALL" and any group beginning with '!' */
if ('!' == *pcGrps || 0 != strcmp(pcGrps, "ALL")) {
iErrs += addgroup(pcGrps);
}
pcGrps = pcGrps + strlen(pcGrps) + 1;
}
/* getuserattr() returns a funny list of groups:
* "grp1\0grp2\0grp3\0\0"
*/
if (0 == getuserattr(pcLogin, S_SUGROUPS, &pcGrps, SEC_LIST)) {
while ('\000' != *pcGrps) {
/* ignore "ALL" and any group beginning with '!' */
if ('!' == *pcGrps || 0 != strcmp(pcGrps, "ALL")) {
iErrs += addgroup(pcGrps);
}
pcGrps = pcGrps + strlen(pcGrps) + 1;
}
#endif /* HAVE_GETUSERATTR */
(void)endgrent();
}
#endif /* HAVE_GETUSERATTR */
(void)endgrent();
if ((char *)0 != pcTty) {
if ( '/' == *pcTty ) {
pcDevTty = pcTty;
} else {
if ( (char *)0 == (pcDevTty = (char *)malloc(strlen(pcTty)+5+1) ) ) {
(void) fprintf(stderr, "%s: malloc: %s\n", progname, strerror(errno));
exit(1);
}
sprintf(pcDevTty, "/dev/%s", pcTty);
}
if ((char *)0 != pcTty) {
if ('/' == *pcTty) {
pcDevTty = pcTty;
} else {
if ((char *)0 ==
(pcDevTty = (char *)malloc(strlen(pcTty) + 5 + 1))) {
(void)fprintf(stderr, "%s: malloc: %s\n", progname,
strerror(errno));
exit(1);
}
sprintf(pcDevTty, "/dev/%s", pcTty);
}
if (0 != stat(pcDevTty, &st)) {
(void) fprintf(stderr, "%s: Can't stat %s: %s\n", progname, pcDevTty, strerror(errno));
++iErrs;
if (0 != stat(pcDevTty, &st)) {
(void)fprintf(stderr, "%s: Can't stat %s: %s\n", progname,
pcDevTty, strerror(errno));
++iErrs;
#if defined(VCHR) && defined(VMPC)
} else if (VCHR != st.st_type && VMPC != st.st_type) {
(void) fprintf(stderr, "%s: %s is not a character device\n", progname, pcDevTty);
++iErrs;
} else if (VCHR != st.st_type && VMPC != st.st_type) {
(void)fprintf(stderr, "%s: %s is not a character device\n",
progname, pcDevTty);
++iErrs;
#endif
}
} else {
pcDevTty = (char *)0;
}
} else {
pcDevTty = (char *)0;
}
if (iErrs) {
usage();
exit(1);
/* NOTREACHED */
}
if (0 != geteuid()) {
(void) fprintf(stderr, "%s: Must be root!!!\n", progname);
exit(1);
/* NOTREACHED */
}
if (iGrps && 0 < setgroups(iGrps, awGrps)) {
(void) fprintf(stderr, "%s: Can't setgroups(): %s\n", progname, strerror(errno));
exit(1);
/* NOTREACHED */
}
if (iErrs) {
usage();
exit(1);
/* NOTREACHED */
}
if (0 != geteuid()) {
(void)fprintf(stderr, "%s: Must be root!!!\n", progname);
exit(1);
/* NOTREACHED */
}
if (iGrps && 0 < setgroups(iGrps, awGrps)) {
(void)fprintf(stderr, "%s: Can't setgroups(): %s\n", progname,
strerror(errno));
exit(1);
/* NOTREACHED */
}
/* Close open files
*/
for (i = (char *)0 == pcTty ? 3 : 0; i < getdtablesize(); ++i) {
(void) close(i);
}
/* Close open files
*/
for (i = (char *)0 == pcTty ? 3 : 0; i < getdtablesize(); ++i) {
(void)close(i);
}
/* Make us a session leader so that when we open /dev/tty
* it will become our controlling terminal.
*/
if (-1 == (iNewGrp = getsid(getpid()))) {
if (-1 == (iNewGrp = setsid())) {
(void) fprintf(stderr, "%s: setsid: %d: %s\n", progname, iNewGrp, strerror(errno));
iNewGrp = getpid();
}
/* Make us a session leader so that when we open /dev/tty
* it will become our controlling terminal.
*/
if (-1 == (iNewGrp = getsid(getpid()))) {
if (-1 == (iNewGrp = setsid())) {
(void)fprintf(stderr, "%s: setsid: %d: %s\n", progname,
iNewGrp, strerror(errno));
iNewGrp = getpid();
}
}
#if defined(HAVE_BSM_AUDIT_H) && defined(HAVE_LIBBSM)
if (!cannot_audit(0)) {
if (!cannot_audit(0)) {
# if defined(HAVE_GETAUDIT_ADDR)
struct auditinfo_addr audit_info;
struct auditinfo_addr audit_info;
# else
struct auditinfo audit_info;
struct auditinfo audit_info;
# endif
au_mask_t audit_mask;
au_mask_t audit_mask;
# if !defined(HAVE_GETAUDIT_ADDR)
struct hostent *hp;
struct hostent *hp;
# endif
int iAuditFile;
int fShowEvent = 1;
token_t *ptAuditToken;
int iAuditFile;
int fShowEvent = 1;
token_t *ptAuditToken;
(void)memset(&audit_info, 0, sizeof(audit_info));
audit_info.ai_auid = wUid;
audit_info.ai_asid = getpid();
audit_mask.am_success = audit_mask.am_failure = 0;
(void) au_user_mask(pcLogin, &audit_mask);
audit_info.ai_mask.am_success = audit_mask.am_success;
audit_info.ai_mask.am_failure = audit_mask.am_failure;
(void)memset(&audit_info, 0, sizeof(audit_info));
audit_info.ai_auid = wUid;
audit_info.ai_asid = getpid();
audit_mask.am_success = audit_mask.am_failure = 0;
(void)au_user_mask(pcLogin, &audit_mask);
audit_info.ai_mask.am_success = audit_mask.am_success;
audit_info.ai_mask.am_failure = audit_mask.am_failure;
# if defined(HAVE_GETAUDIT_ADDR)
(void)aug_get_machine(my_hostname,
&audit_info.ai_termid.at_addr[0],
&audit_info.ai_termid.at_type);
(void)aug_get_machine(my_hostname,
&audit_info.ai_termid.at_addr[0],
&audit_info.ai_termid.at_type);
# else
if ((char *)0 != (hp = gethostbyname(my_hostname))
&& AF_INET == hp->h_addrtype) {
(void)memcpy(&audit_info.ai_termid.machine,
hp->h_addr,
sizeof(audit_info.ai_termid.machine));
}
# endif
# if defined(HAVE_GETAUDIT_ADDR)
if (0 > setaudit_addr(&audit_info, sizeof(audit_info)))
# else
if (0 > setaudit(&audit_info))
# endif
{
fprintf(stderr, "%s: setaudit failed: %s\n",
progname,
strerror(errno));
fShowEvent = 0;
}
if (fShowEvent) {
fShowEvent = au_preselect(AUE_autologin,
&audit_mask,
AU_PRS_SUCCESS,
AU_PRS_REREAD);
}
if (fShowEvent) {
iAuditFile = au_open();
# if defined(HAVE_GETAUDIT_ADDR)
ptAuditToken = au_to_subject_ex(wUid,
wUid,
wGid,
wUid,
wGid,
audit_info.ai_asid,
audit_info.ai_asid,
&audit_info.ai_termid),
# else
ptAuditToken = au_to_subject(wUid,
wUid,
wGid,
wUid,
wGid,
audit_info.ai_asid,
audit_info.ai_asid,
&audit_info.ai_termid),
# endif
(void)au_write(iAuditFile, ptAuditToken);
ptAuditToken = au_to_text(gettext("successful login"));
(void)au_write(iAuditFile, ptAuditToken);
if ((char *)0 != pcCmd) {
ptAuditToken = au_to_text(pcCmd);
(void)au_write(iAuditFile, ptAuditToken);
}
# if defined(HAVE_GETAUDIT_ADDR)
ptAuditToken = au_to_return32(0, 0);
# else
ptAuditToken = au_to_return(0, 0);
# endif
(void)au_write(iAuditFile, ptAuditToken);
if(0 > au_close(iAuditFile, AU_TO_WRITE, AUE_autologin)) {
fprintf(stderr, "%s: audit write failed: %s",
progname,
strerror(errno));
}
}
if ((char *)0 != (hp = gethostbyname(my_hostname))
&& AF_INET == hp->h_addrtype) {
(void)memcpy(&audit_info.ai_termid.machine, hp->h_addr,
sizeof(audit_info.ai_termid.machine));
}
# endif
# if defined(HAVE_GETAUDIT_ADDR)
if (0 > setaudit_addr(&audit_info, sizeof(audit_info)))
# else
if (0 > setaudit(&audit_info))
# endif
{
fprintf(stderr, "%s: setaudit failed: %s\n", progname,
strerror(errno));
fShowEvent = 0;
}
if (fShowEvent) {
fShowEvent =
au_preselect(AUE_autologin, &audit_mask, AU_PRS_SUCCESS,
AU_PRS_REREAD);
}
if (fShowEvent) {
iAuditFile = au_open();
# if defined(HAVE_GETAUDIT_ADDR)
ptAuditToken =
au_to_subject_ex(wUid, wUid, wGid, wUid, wGid,
audit_info.ai_asid, audit_info.ai_asid,
&audit_info.ai_termid),
# else
ptAuditToken =
au_to_subject(wUid, wUid, wGid, wUid, wGid,
audit_info.ai_asid, audit_info.ai_asid,
&audit_info.ai_termid),
# endif
(void)au_write(iAuditFile, ptAuditToken);
ptAuditToken = au_to_text(gettext("successful login"));
(void)au_write(iAuditFile, ptAuditToken);
if ((char *)0 != pcCmd) {
ptAuditToken = au_to_text(pcCmd);
(void)au_write(iAuditFile, ptAuditToken);
}
# if defined(HAVE_GETAUDIT_ADDR)
ptAuditToken = au_to_return32(0, 0);
# else
ptAuditToken = au_to_return(0, 0);
# endif
(void)au_write(iAuditFile, ptAuditToken);
if (0 > au_close(iAuditFile, AU_TO_WRITE, AUE_autologin)) {
fprintf(stderr, "%s: audit write failed: %s", progname,
strerror(errno));
}
}
}
#endif
/* Open the TTY for stdin, stdout and stderr
*/
if ((char *)0 != pcDevTty) {
/* Open the TTY for stdin, stdout and stderr
*/
if ((char *)0 != pcDevTty) {
#ifdef TIOCNOTTY
if (-1 != (i = open("/dev/tty", 2, 0))) {
if ( ioctl(i, TIOCNOTTY, (char *)0) )
(void) fprintf(stderr, "%s: ioctl(%d, TIOCNOTTY, (char *)0): %s\n", progname, i, strerror(errno));
(void) close(i);
}
#endif
if (0 != open(pcDevTty, O_RDWR, 0666)) {
exit(1);
/* NOTREACHED */
}
dup(0);
dup(0);
if (-1 != (i = open("/dev/tty", 2, 0))) {
if (ioctl(i, TIOCNOTTY, (char *)0))
(void)fprintf(stderr,
"%s: ioctl(%d, TIOCNOTTY, (char *)0): %s\n",
progname, i, strerror(errno));
(void)close(i);
}
#endif
if (0 != open(pcDevTty, O_RDWR, 0666)) {
exit(1);
/* NOTREACHED */
}
dup(0);
dup(0);
}
/* put the tty in out process group
*/
/* put the tty in out process group
*/
#ifdef HAVE_TCGETPGRP
if (-1 >= (i = tcgetpgrp(0))){
(void) fprintf(stderr, "%s: tcgetpgrp: %s\n", progname, strerror(errno));
}
if (-1 >= (i = tcgetpgrp(0))) {
(void)fprintf(stderr, "%s: tcgetpgrp: %s\n", progname,
strerror(errno));
}
#endif
#ifndef SETPGRP_VOID
if (-1 != i && setpgrp(0, i) ){
(void) fprintf(stderr, "%s: setpgrp: %s, i = %d\n", progname, strerror(errno), i);
}
#endif
if (-1 != i && setpgrp(0, i)) {
(void)fprintf(stderr, "%s: setpgrp: %s, i = %d\n", progname,
strerror(errno), i);
}
#ifdef HAVE_TCSETPGRP
if (tcsetpgrp(0, iNewGrp)){
(void) fprintf(stderr, "%s: tcsetpgrp: %s\n", progname, strerror(errno));
}
#endif
#ifndef SETPGRP_VOID
if (-1 != iNewGrp && setpgrp(0, iNewGrp)){
(void) fprintf(stderr, "%s: setpgrp: %s, iNewGrp = %d\n", progname, strerror(errno), iNewGrp);
}
if (tcsetpgrp(0, iNewGrp)) {
(void)fprintf(stderr, "%s: tcsetpgrp: %s\n", progname,
strerror(errno));
}
#endif
if (-1 != iNewGrp && setpgrp(0, iNewGrp)) {
(void)fprintf(stderr, "%s: setpgrp: %s, iNewGrp = %d\n", progname,
strerror(errno), iNewGrp);
}
/* put the tty in the correct mode
*/
/* put the tty in the correct mode
*/
#ifdef HAVE_TCGETATTR
if (0 != tcgetattr(0, &n_tio)) {
(void) fprintf(stderr, "%s: tcgetattr: %s\n", progname, strerror(errno));
exit(1);
/* NOTREACHED */
}
if (0 != tcgetattr(0, &n_tio)) {
(void)fprintf(stderr, "%s: tcgetattr: %s\n", progname,
strerror(errno));
exit(1);
/* NOTREACHED */
}
#else
if (0 != ioctl(0, TCGETS, &n_tio)) {
(void) fprintf(stderr, "%s: iotcl: TCGETS: %s\n", progname, strerror(errno));
exit(1);
/* NOTREACHED */
}
if (0 != ioctl(0, TCGETS, &n_tio)) {
(void)fprintf(stderr, "%s: iotcl: TCGETS: %s\n", progname,
strerror(errno));
exit(1);
/* NOTREACHED */
}
#endif
n_tio.c_iflag &= ~(IGNCR|IUCLC);
n_tio.c_iflag |= ICRNL|IXON|IXANY;
n_tio.c_oflag &= ~(OLCUC|ONOCR|ONLRET|OFILL|NLDLY|CRDLY|TABDLY|BSDLY);
n_tio.c_oflag |= OPOST|ONLCR|TAB3;
n_tio.c_lflag &= ~(XCASE|NOFLSH|ECHOK|ECHONL);
n_tio.c_lflag |= ISIG|ICANON|ECHO;
n_tio.c_cc[VEOF] = '\004'; /* ^D */
n_tio.c_cc[VEOL] = '\000'; /* EOL */
n_tio.c_cc[VERASE] = '\010'; /* ^H */
n_tio.c_cc[VINTR] = '\003'; /* ^C */
n_tio.c_cc[VKILL] = '\025'; /* ^U */
/* MIN */
n_tio.c_cc[VQUIT] = '\034'; /* ^\ */
n_tio.c_cc[VSTART] = '\021'; /* ^Q */
n_tio.c_cc[VSTOP] = '\023'; /* ^S */
n_tio.c_cc[VSUSP] = '\032'; /* ^Z */
n_tio.c_iflag &= ~(IGNCR | IUCLC);
n_tio.c_iflag |= ICRNL | IXON | IXANY;
n_tio.c_oflag &=
~(OLCUC | ONOCR | ONLRET | OFILL | NLDLY | CRDLY | TABDLY | BSDLY);
n_tio.c_oflag |= OPOST | ONLCR | TAB3;
n_tio.c_lflag &= ~(XCASE | NOFLSH | ECHOK | ECHONL);
n_tio.c_lflag |= ISIG | ICANON | ECHO;
n_tio.c_cc[VEOF] = '\004'; /* ^D */
n_tio.c_cc[VEOL] = '\000'; /* EOL */
n_tio.c_cc[VERASE] = '\010'; /* ^H */
n_tio.c_cc[VINTR] = '\003'; /* ^C */
n_tio.c_cc[VKILL] = '\025'; /* ^U */
/* MIN */
n_tio.c_cc[VQUIT] = '\034'; /* ^\ */
n_tio.c_cc[VSTART] = '\021'; /* ^Q */
n_tio.c_cc[VSTOP] = '\023'; /* ^S */
n_tio.c_cc[VSUSP] = '\032'; /* ^Z */
#ifdef HAVE_TCSETATTR
if (0 != tcsetattr(0, TCSANOW, &n_tio)) {
(void) fprintf(stderr, "%s: tcsetattr: %s\n", progname, strerror(errno));
exit(1);
/* NOTREACHED */
}
if (0 != tcsetattr(0, TCSANOW, &n_tio)) {
(void)fprintf(stderr, "%s: tcsetattr: %s\n", progname,
strerror(errno));
exit(1);
/* NOTREACHED */
}
#endif
if (fMakeUtmp) {
extern char *ttyname();
make_utmp(pcLogin, (char *)0 != pcTty ? pcTty : ttyname(0));
}
/* Change ownership and modes on the tty.
*/
if ((char *)0 != pcDevTty) {
(void) chown(pcDevTty, wUid, wGid);
(void) chmod(pcDevTty, (mode_t) TTYMODE);
}
if (fMakeUtmp) {
extern char *ttyname();
make_utmp(pcLogin, (char *)0 != pcTty ? pcTty : ttyname(0));
}
/* Change ownership and modes on the tty.
*/
if ((char *)0 != pcDevTty) {
(void)chown(pcDevTty, wUid, wGid);
(void)chmod(pcDevTty, (mode_t) TTYMODE);
}
if ((char *)0 != pcCmd) {
execl(PATH_SU, "su", "-", pcLogin, pcCmd, (char *)0);
} else {
execl(PATH_SU, "su", "-", pcLogin, (char *)0);
}
if ((char *)0 != pcCmd) {
execl(PATH_SU, "su", "-", pcLogin, pcCmd, (char *)0);
} else {
execl(PATH_SU, "su", "-", pcLogin, (char *)0);
}
}
#ifndef HAVE_PUTENV
int
putenv(pcAssign)
char *pcAssign;
char *pcAssign;
{
register char *pcEq;
register char *pcEq;
if ((char *)0 != (pcEq = strchr(pcAssign, '='))) {
*pcEq++ = '\000';
(void)setenv(pcAssign, pcEq, 1);
*--pcEq = '=';
} else {
unsetenv(pcAssign);
}
if ((char *)0 != (pcEq = strchr(pcAssign, '='))) {
*pcEq++ = '\000';
(void)setenv(pcAssign, pcEq, 1);
*--pcEq = '=';
} else {
unsetenv(pcAssign);
}
}
#endif
int
addgroup(pcGrp)
char *pcGrp;
char *pcGrp;
{
struct group *grp;
struct group *grp;
grp = getgrnam(pcGrp);
if ((struct group *)0 == grp) {
(void) fprintf(stderr, "%s: Unknown group: %s\n", progname, pcGrp);
return(1);
}
if (iGrps >= NGROUPS_MAX) {
(void) fprintf(stderr, "%s: Too many groups specified with \"%s\".\n", progname, pcGrp);
return(1);
}
awGrps[iGrps++] = grp->gr_gid;
return(0);
grp = getgrnam(pcGrp);
if ((struct group *)0 == grp) {
(void)fprintf(stderr, "%s: Unknown group: %s\n", progname, pcGrp);
return (1);
}
if (iGrps >= NGROUPS_MAX) {
(void)fprintf(stderr,
"%s: Too many groups specified with \"%s\".\n",
progname, pcGrp);
return (1);
}
awGrps[iGrps++] = grp->gr_gid;
return (0);
}
@ -449,69 +452,69 @@ char *pcGrp;
*/
void
make_utmp(pclogin, pctty)
char *pclogin;
char *pctty;
char *pclogin;
char *pctty;
{
register int iFound, iPos;
register int fdUtmp;
register char *pcDev;
register struct utmp *up;
auto struct utmp utmp;
register int iFound, iPos;
register int fdUtmp;
register char *pcDev;
register struct utmp *up;
auto struct utmp utmp;
if ((char *)0 == pctty) {
return;
if ((char *)0 == pctty) {
return;
}
if ((fdUtmp = open(UTMP_FILE, O_RDWR, 0664)) < 0) {
return;
}
/* create empty utmp entry
*/
(void)memset(&utmp, 0, sizeof(struct utmp));
/* Only the last portion of the tty is saved, unless it's
* all digits. Then back up and include the previous part
* /dev/pty/02 -> pty/02 (not just 02)
*/
if ((char *)0 != (pcDev = strrchr(pctty, '/'))) {
if (!*(pcDev + strspn(pcDev, "/0123456789"))) {
while (pcDev != pctty && *--pcDev != '/') {
}
}
if ((fdUtmp = open(UTMP_FILE, O_RDWR, 0664)) < 0) {
return;
}
/* create empty utmp entry
*/
(void)memset(&utmp, 0, sizeof(struct utmp));
/* Only the last portion of the tty is saved, unless it's
* all digits. Then back up and include the previous part
* /dev/pty/02 -> pty/02 (not just 02)
*/
if ((char *)0 != (pcDev = strrchr(pctty, '/'))) {
if (! *(pcDev + strspn(pcDev, "/0123456789"))) {
while (pcDev != pctty && *--pcDev != '/') {
}
}
if (*pcDev == '/') {
++pcDev;
}
} else {
pcDev = pctty;
if (*pcDev == '/') {
++pcDev;
}
} else {
pcDev = pctty;
}
#ifdef HAVE_GETUTENT
/* look through getutent's by pid
*/
(void)setutent();
utmp.ut_pid = getpid();
iFound = iPos = 0;
while ((up = getutent()) != NULL) {
if (up->ut_pid == utmp.ut_pid) {
utmp = *up;
++iFound;
break;
}
iPos++;
}
(void)endutent();
/* we were an initprocess, now we are a login shell
*/
utmp.ut_type = USER_PROCESS;
(void)strncpy(utmp.ut_user, pclogin, sizeof(utmp.ut_user));
if ('\000' == utmp.ut_line[0]) {
(void)strncpy(utmp.ut_line, pcDev, sizeof(utmp.ut_line));
/* look through getutent's by pid
*/
(void)setutent();
utmp.ut_pid = getpid();
iFound = iPos = 0;
while ((up = getutent()) != NULL) {
if (up->ut_pid == utmp.ut_pid) {
utmp = *up;
++iFound;
break;
}
iPos++;
}
(void)endutent();
/* we were an initprocess, now we are a login shell
*/
utmp.ut_type = USER_PROCESS;
(void)strncpy(utmp.ut_user, pclogin, sizeof(utmp.ut_user));
if ('\000' == utmp.ut_line[0]) {
(void)strncpy(utmp.ut_line, pcDev, sizeof(utmp.ut_line));
}
#else
#ifdef HAVE_SETTTYENT
{
{
register struct ttyent *ty;
/* look through ttyslots by line?
@ -519,56 +522,56 @@ char *pctty;
(void)setttyent();
iFound = iPos = 0;
while ((ty = getttyent()) != NULL) {
if (strcmp(ty->ty_name, pcDev) == 0) {
++iFound;
break;
}
iPos++;
if (strcmp(ty->ty_name, pcDev) == 0) {
++iFound;
break;
}
iPos++;
}
/* fill in utmp from ty ZZZ */
(void)endttyent();
}
(void)strncpy(utmp.ut_line, pcDev, sizeof(utmp.ut_line));
(void)strncpy(utmp.ut_name, pclogin, sizeof(utmp.ut_name));
(void)strncpy(utmp.ut_host, "(autologin)", sizeof(utmp.ut_host));
}
(void)strncpy(utmp.ut_line, pcDev, sizeof(utmp.ut_line));
(void)strncpy(utmp.ut_name, pclogin, sizeof(utmp.ut_name));
(void)strncpy(utmp.ut_host, "(autologin)", sizeof(utmp.ut_host));
#else
/* look through /etc/utmp by hand (sigh)
*/
iFound = iPos = 0;
while (sizeof(utmp) == read(fdUtmp, & utmp, sizeof(utmp))) {
if (0 == strncmp(utmp.ut_line, pcDev, sizeof(utmp.ut_line))) {
++iFound;
break;
}
iPos++;
/* look through /etc/utmp by hand (sigh)
*/
iFound = iPos = 0;
while (sizeof(utmp) == read(fdUtmp, &utmp, sizeof(utmp))) {
if (0 == strncmp(utmp.ut_line, pcDev, sizeof(utmp.ut_line))) {
++iFound;
break;
}
(void)strncpy(utmp.ut_name, pclogin, sizeof(utmp.ut_name));
iPos++;
}
(void)strncpy(utmp.ut_name, pclogin, sizeof(utmp.ut_name));
#endif
#endif
utmp.ut_time = time((time_t *) 0);
utmp.ut_time = time((time_t *)0);
if (0 == iFound) {
fprintf(stderr, "%s: %s: no ttyslot\n", progname, pctty);
} else if (-1 == lseek(fdUtmp, (off_t)(iPos*sizeof(utmp)), 0)) {
fprintf(stderr, "%s: lseek: %s\n", progname, strerror(errno));
} else {
(void)write(fdUtmp, (char *)&utmp, sizeof(utmp));
}
(void)close(fdUtmp);
if (0 == iFound) {
fprintf(stderr, "%s: %s: no ttyslot\n", progname, pctty);
} else if (-1 == lseek(fdUtmp, (off_t) (iPos * sizeof(utmp)), 0)) {
fprintf(stderr, "%s: lseek: %s\n", progname, strerror(errno));
} else {
(void)write(fdUtmp, (char *)&utmp, sizeof(utmp));
}
(void)close(fdUtmp);
}
void
usage()
{
char *u_pch;
int u_loop;
char *u_pch;
int u_loop;
for (u_loop = 0; (char *)0 != (u_pch = au_terse[u_loop]); ++u_loop) {
fprintf(stdout, "%s: usage%s\n", progname, u_pch);
}
for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]); ++u_loop) {
fprintf(stdout, "%s\n", u_pch);
}
for (u_loop = 0; (char *)0 != (u_pch = au_terse[u_loop]); ++u_loop) {
fprintf(stdout, "%s: usage%s\n", progname, u_pch);
}
for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]); ++u_loop) {
fprintf(stdout, "%s\n", u_pch);
}
}

View File

@ -13,7 +13,7 @@
#ifndef HAVE_GETOPT
static int
optopt; /* character checked for validity */
optopt; /* character checked for validity */
/* get option letter from argument vector, also does -number correctly
* for nice, xargs, and stuff (these extras by ksb)
@ -21,166 +21,168 @@ static int
*/
static int
getopt(nargc, nargv, ostr)
int nargc;
char **nargv, *ostr;
int nargc;
char **nargv, *ostr;
{
register char *oli; /* option letter list index */
static char EMSG[] = ""; /* just a null place */
static char *place = EMSG; /* option letter processing */
register char *oli; /* option letter list index */
static char EMSG[] = ""; /* just a null place */
static char *place = EMSG; /* option letter processing */
if ('\000' == *place) { /* update scanning pointer */
if (optind >= nargc)
return EOF;
if (nargv[optind][0] != '-') {
register int iLen;
return EOF;
}
place = nargv[optind];
if ('\000' == *++place) /* "-" (stdin) */
return EOF;
if (*place == '-' && '\000' == place[1]) {
/* found "--" */
++optind;
return EOF;
}
} /* option letter okay? */
/* if we find the letter, (not a `:')
* or a digit to match a # in the list
*/
if ((optopt = *place++) == ':' ||
((char *)0 == (oli = strchr(ostr,optopt)) &&
(!(isdigit(optopt)||'-'==optopt) || (char *)0 == (oli = strchr(ostr, '#'))))) {
if(!*place) ++optind;
return('?');
if ('\000' == *place) { /* update scanning pointer */
if (optind >= nargc)
return EOF;
if (nargv[optind][0] != '-') {
register int iLen;
return EOF;
}
if ('#' == *oli) { /* accept as -digits */
optarg = place -1;
++optind;
place = EMSG;
return '#';
place = nargv[optind];
if ('\000' == *++place) /* "-" (stdin) */
return EOF;
if (*place == '-' && '\000' == place[1]) {
/* found "--" */
++optind;
return EOF;
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if ('\000' == *place)
++optind;
} else { /* need an argument */
if (*place) { /* no white space */
optarg = place;
} else if (nargc <= ++optind) { /* no arg!! */
place = EMSG;
return '*';
} else {
optarg = nargv[optind]; /* white space */
}
place = EMSG;
++optind;
}
/* option letter okay? */
/* if we find the letter, (not a `:')
* or a digit to match a # in the list
*/
if ((optopt = *place++) == ':' ||
((char *)0 == (oli = strchr(ostr, optopt)) &&
(!(isdigit(optopt) || '-' == optopt) ||
(char *)0 == (oli = strchr(ostr, '#'))))) {
if (!*place)
++optind;
return ('?');
}
if ('#' == *oli) { /* accept as -digits */
optarg = place - 1;
++optind;
place = EMSG;
return '#';
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if ('\000' == *place)
++optind;
} else { /* need an argument */
if (*place) { /* no white space */
optarg = place;
} else if (nargc <= ++optind) { /* no arg!! */
place = EMSG;
return '*';
} else {
optarg = nargv[optind]; /* white space */
}
return optopt; /* dump back option letter */
place = EMSG;
++optind;
}
return optopt; /* dump back option letter */
}
#endif /* ! HAVE_GETOPT */
char
*progname = "$Id: main.c,v 1.1 2003/11/04 02:36:24 bryan Exp $",
*au_terse[] = {
" [-u] [-c cmd] [-e env=value] [-g group] [-l login] [-t tty]",
" -h",
" -V",
(char *)0
},
*u_help[] = {
"c cmd command to run",
"e env=value environment variable to set",
"g group initial group",
"h print this help message",
"l login login name",
"t tty attach to this terminal",
"u do no make utmp entry",
"V show version information",
(char *)0
},
*pcCommand = (char *)0,
*pcGroup = (char *)0,
*pcLogin = (char *)0,
*pcTty = (char *)0;
*progname =
"$Id: main.c,v 1.2 2013/09/20 21:15:13 bryan Exp $", *au_terse[] = {
" [-u] [-c cmd] [-e env=value] [-g group] [-l login] [-t tty]",
" -h",
" -V",
(char *)0
}, *u_help[] = {
"c cmd command to run",
"e env=value environment variable to set",
"g group initial group",
"h print this help message",
"l login login name",
"t tty attach to this terminal",
"u do no make utmp entry",
"V show version information", (char *)0}, *pcCommand =
(char *)0, *pcGroup = (char *)0, *pcLogin = (char *)0, *pcTty =
(char *)0;
int
fMakeUtmp = 1,
iErrs = 0;
fMakeUtmp = 1, iErrs = 0;
#ifndef u_terse
#define u_terse (au_terse[0])
#endif
static char *rcsid =
"$Id: main.c,v 1.1 2003/11/04 02:36:24 bryan Exp $";
static char *rcsid = "$Id: main.c,v 1.2 2013/09/20 21:15:13 bryan Exp $";
/*
* parser
*/
int
main(argc, argv)
int argc;
char **argv;
int argc;
char **argv;
{
static char
sbOpt[] = "c:e:g:hl:t:uV",
*u_pch = (char *)0;
static int
u_loop = 0;
register int u_curopt;
extern int atoi();
static char
sbOpt[] = "c:e:g:hl:t:uV", *u_pch = (char *)0;
static int
u_loop = 0;
register int u_curopt;
extern int atoi();
progname = strrchr(argv[0], '/');
if ((char *)0 == progname)
progname = argv[0];
else
++progname;
while (EOF != (u_curopt = getopt(argc, argv, sbOpt))) {
switch (u_curopt) {
case '*':
fprintf(stderr, "%s: option `-%c\' needs a parameter\n", progname, optopt);
exit(1);
case '?':
fprintf(stderr, "%s: unknown option `-%c\', use `-h\' for help\n", progname, optopt);
exit(1);
case 'c':
pcCommand = optarg;
continue;
case 'e':
if (putenv(optarg) != 0) {
(void) fprintf(stderr, "%s: putenv(\"%s\"): failed\n", progname, optarg);
exit(1);
}
continue;
case 'g':
pcGroup = optarg;
continue;
case 'h':
for (u_loop = 0; (char *)0 != (u_pch = au_terse[u_loop]); ++u_loop) {
if ('\000' == *u_pch) {
fprintf(stdout, "%s: with no parameters\n", progname);
continue;
}
fprintf(stdout, "%s: usage%s\n", progname, u_pch);
}
for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]); ++u_loop) {
fprintf(stdout, "%s\n", u_pch);
}
exit(0);
case 'l':
pcLogin = optarg;
continue;
case 't':
pcTty = optarg;
continue;
case 'u':
fMakeUtmp = 0;
continue;
case 'V':
printf("%s: %s\n", progname, rcsid);
exit(0);
progname = strrchr(argv[0], '/');
if ((char *)0 == progname)
progname = argv[0];
else
++progname;
while (EOF != (u_curopt = getopt(argc, argv, sbOpt))) {
switch (u_curopt) {
case '*':
fprintf(stderr, "%s: option `-%c\' needs a parameter\n",
progname, optopt);
exit(1);
case '?':
fprintf(stderr,
"%s: unknown option `-%c\', use `-h\' for help\n",
progname, optopt);
exit(1);
case 'c':
pcCommand = optarg;
continue;
case 'e':
if (putenv(optarg) != 0) {
(void)fprintf(stderr, "%s: putenv(\"%s\"): failed\n",
progname, optarg);
exit(1);
}
break;
continue;
case 'g':
pcGroup = optarg;
continue;
case 'h':
for (u_loop = 0; (char *)0 != (u_pch = au_terse[u_loop]);
++u_loop) {
if ('\000' == *u_pch) {
fprintf(stdout, "%s: with no parameters\n",
progname);
continue;
}
fprintf(stdout, "%s: usage%s\n", progname, u_pch);
}
for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]);
++u_loop) {
fprintf(stdout, "%s\n", u_pch);
}
exit(0);
case 'l':
pcLogin = optarg;
continue;
case 't':
pcTty = optarg;
continue;
case 'u':
fMakeUtmp = 0;
continue;
case 'V':
printf("%s: %s\n", progname, rcsid);
exit(0);
}
Process();
exit(iErrs);
break;
}
Process();
exit(iErrs);
}

View File

@ -12,4 +12,3 @@ extern char *pcCommand, *pcGroup, *pcLogin, *pcTty;
/* from std_help.m */
/* from std_version.m */
/* from autologin.m */

View File

@ -315,6 +315,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@ -327,12 +330,12 @@
/* Define to 1 if the C compiler supports function prototypes. */
#undef PROTOTYPES
/* Defined if client requires server SSL certificate */
#undef REQ_SERVER_CERT
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define if setpgrp is POSIX */
#undef SETPGRP_VOID
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

7172
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@ AH_TEMPLATE([USE_EXTENDED_MESSAGES],[Defined if we produce extended messages])
AH_TEMPLATE([USE_UNIX_DOMAIN_SOCKETS],[Defined if we use Unix domain sockets])
AH_TEMPLATE([UDSDIR], [Directory for Unix domain sockets])
AH_TEMPLATE([FOR_CYCLADES_TS], [Defined if building for a Cyclades TS])
AH_TEMPLATE([REQ_SERVER_CERT], [Defined if client requires server SSL certificate])
dnl ### Normal initialization. ######################################
AC_INIT
@ -498,6 +499,19 @@ AC_ARG_WITH(openssl,
CPPFLAGS="$oCPPFLAGS"
LDFLAGS="$oLDFLAGS"
fi
AC_MSG_CHECKING(whether to require server cert)
AC_ARG_WITH(req-server-cert,
AS_HELP_STRING([--with-req-server-cert],[Require server SSL certificate by client]),
[case "$withval" in
yes)
AC_DEFINE(REQ_SERVER_CERT)
AC_MSG_RESULT(yes)
;;
*)
AC_MSG_RESULT(no)
;;
esac],[AC_MSG_RESULT(no)])
fi]
)
@ -705,13 +719,6 @@ AC_CHECK_LIB(util, openpty)
AC_CHECK_FUNCS(openpty)
AC_CHECK_FUNCS(getopt strerror getrlimit getsid setsid getuserattr setgroups tcgetpgrp tcsetpgrp tcgetattr tcsetattr tcsendbreak setpgrp getutent setttyent getspnam setlinebuf setvbuf ptsname grantpt unlockpt sigaction setsockopt getdtablesize putenv memset memcpy memcmp memmove sysconf getlogin inet_aton setproctitle gettimeofday strlcpy)
if test "$with_cycladests" != "yes"; then
AC_FUNC_SETPGRP
else
AC_DEFINE(SETPGRP_VOID, 1, [Define if setpgrp is POSIX])
AC_MSG_NOTICE([Building for a Cyclades-TS: setting SETPGRP_VOID because we cannot test this in cross-compilation])
fi
AC_CHECK_FUNC(strcasecmp,
[AC_DEFINE(HAVE_STRCASECMP, 1, [Define if strcasecmp is available])],
[AC_CHECK_FUNC(stricmp,

View File

@ -1,4 +1,5 @@
### Path settings
datarootdir = @datarootdir@
srcdir = @srcdir@
prefix = @prefix@
mandir = @mandir@

View File

@ -1,5 +1,5 @@
.\" $Id: conserver.cf.man,v 1.78 2007/04/02 17:59:16 bryan Exp $
.TH CONSERVER.CF 5 "2007/04/02" "conserver-8.1.18" "conserver"
.\" $Id: conserver.cf.man,v 1.84 2013/09/25 22:10:29 bryan Exp $
.TH CONSERVER.CF 5 "2013/09/25" "conserver-8.1.19" "conserver"
.SH NAME
conserver.cf \- console configuration file for
.BR conserver (8)
@ -220,6 +220,12 @@ Break sequences are accessed via the
client escape sequence.
.RS
.TP
\f3confirm\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Set whether or not to ask the client for confirmation before sending the
break sequence.
The default is ``no''.
.TP
\f3delay\fP \f2n\fP
.br
Set the time delay for the
@ -308,7 +314,7 @@ If the value of ``*'' is used, the configuration block will be applied to
all conserver hosts.
.RS
.TP
\f3autocomplete\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off
\f3autocomplete\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Turn the console name autocompletion feature on or off.
If autocompletion is on, a client can use any unique leading portion of a
@ -322,7 +328,7 @@ an access list (see the
.B \-a
command-line flag).
.TP
\f3daemonmode\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off
\f3daemonmode\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Set whether or not to become a daemon when run (see the
.B \-d
@ -372,7 +378,7 @@ Set the port used by the master conserver process (see the
.B \-p
command-line flag).
.TP
\f3redirect\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off
\f3redirect\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Turn redirection on or off (see the
.B \-R
@ -390,7 +396,7 @@ Set the base port number used by child processes (see the
.B \-b
command-line flag).
.TP
\f3setproctitle\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off
\f3setproctitle\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Set whether or not the process title shows master/group functionality
as well as the port number the process is listening on and how many
@ -407,7 +413,19 @@ credentials file location (see the
.B \-c
command-line flag).
.TP
\f3sslrequired\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off
\f3sslcacertificatefile\fP \f2filename\fP
.br
Load the valid CA certificates for the
.SM SSL
connection from the PEM encoded file. This option overrides the global CA
list.
.TP
\f3sslreqclientcert\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Set whether or not a certificate is required by the client to connect.
The default is ``no''.
.TP
\f3sslrequired\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Set whether or not encryption is required when talking to clients (see the
.B \-E
@ -461,6 +479,13 @@ Assign the break sequence
as the default for the console, which is used by
the ``^Ecl0'' client escape sequence.
.TP
\f3breaklist\fP \f2n\fP[\f3,\fP...]|\f3""\fP
Associate a list of break sequences referenced by
.I n
with the console.
If ``*'' is used (the default), all defined break sequences will be available.
If the null string (``\f3""\fP'') is used, no sequences will be available.
.TP
\f3device\fP \f2filename\fP
.br
Assign the serial device
@ -1040,6 +1065,13 @@ will be granted (or denied, if prefixed with `!') read-write access.
If the null string (``\f3""\fP'') is used, any
users previously defined for the console's read-write list are removed.
.TP
\f3tasklist\fP \f2c\fP[\f3,\fP...]|\f3""\fP
Associate a list of tasks referenced by
.I c
with the console.
If ``*'' is used (the default), all defined tasks will be available.
If the null string (``\f3""\fP'') is used, no tasks will be available.
.TP
\f3timestamp\fP [\f2number\fP[\f3m\fP|\f3h\fP|\f3d\fP|\f3l\fP]][\f3a\fP][\f3b\fP]|\f3""\fP
.br
Specifies the time between timestamps applied to the console
@ -1126,7 +1158,7 @@ If the null string (``\f3""\fP'') is used, no replacements will be done.
\f3group\fP \f2name\fP
.br
Define a user group identified as
.I name
.IR name .
.RS
.TP
\f3users\fP [\f3!\fP]\f2username\fP[\f3,\fP...]|\f3""\fP
@ -1153,6 +1185,74 @@ will be recorded with (or without, if prefixed with `!') access.
If the null string (``\f3""\fP'') is used, any
users previously defined for this group are removed.
.RE
.TP
\f3task\fP \f2c\fP
.br
Define a task where
.I c
is a lowercase alphanumeric (0-9a-z).
Tasks are invoked via the
.RI ``^Ec! c ''
client escape sequence.
.RS
.TP
\f3cmd\fP \f2command\fP|\f3""\fP
.br
Invoke
.I command
on the server when instructed by the client.
All file descriptors are closed, except for stderr (which is inherited from
the server).
The
.I command
is passed as an argument to ``/bin/sh -ce'' and is a ``fire and forget''
methodology (you need to check logs for any issues).
If the null string (``\f3""\fP'') is used, the entire task definition is ignored.
.TP
\f3confirm\fP \f3yes\fP|\f3true\fP|\f3on\fP|\f3no\fP|\f3false\fP|\f3off\fP
.br
Set whether or not to ask the client for confirmation before invoking the task.
The default is ``no''.
.TP
\f3description\fP \f2string\fP
.br
Set a description for the task. When a client lists tasks,
.I string
will be printed instead of the command defined above.
If the null string (``\f3""\fP'') is used, the command defined above will
be printed.
.TP
\f3runas\fP [\f2user\fP][:\f2group\fP]|\f3""\fP
.br
By default, the command invoked by
.B cmd
is run with the same privileges as the server.
If the server is running with root privileges, this option resets the user
and/or group of the invoked process to
.I user
and
.I group
respectively.
.I user
may be a username or numeric uid and
.I group
may be a group name or numeric gid.
Either one is optional.
If the server is not running with root privileges, these values
are not used.
If the null string (``\f3""\fP'') is specified, the default of running
with the same privileges as the server is restored.
.TP
\f3subst\fP \f2c\fP\f3=\fP\f2t\fP[\f2n\fP]\f2f\fP[\f3,\fP...]|\f3""\fP
.br
Perform character substitutions on the
.B cmd
value.
See the
.B devicesubst
option for an explanation of the format string.
If the null string (``\f3""\fP'') is used, no replacements will be done.
.RE
.SH AUTHORS
Bryan Stansell, conserver.com
.SH "SEE ALSO"

View File

@ -1,5 +1,5 @@
.\" $Id: conserver.passwd.man,v 1.10 2004/01/08 16:12:33 bryan Exp $
.TH CONSERVER.PASSWD 5 "2004/01/08" "conserver-8.1.18" "conserver"
.TH CONSERVER.PASSWD 5 "2004/01/08" "conserver-8.1.19" "conserver"
.SH NAME
conserver.passwd \- user access information for
.BR conserver (8)

View File

@ -3,7 +3,7 @@
<HTML>
<HEAD>
<META name="generator" content=
"HTML Tidy for Solaris (vers 7 December 2008), see www.w3.org">
"HTML Tidy for Solaris (vers 25 March 2009), see www.w3.org">
<META name="keywords" content=
"conserver,serial,console,serial console,unix,tty,ttya,ttyb, rs-232,rs232,bryan stansell,stansell,console server,terminal server,headless">
<META name="author" content=
@ -36,12 +36,12 @@ body {
"http://planetmirror.com/pub/conserver/">Australia</A>
&nbsp;&nbsp;<A href=
"http://conserver.linux-mirror.org/">Germany</A>
&nbsp;&nbsp;<A href=
"http://conserver.webdesign-zdg.de/">Germany</A>
&nbsp;&nbsp;<A href="http://conserver.rayba.co/">Germany</A>
&nbsp;&nbsp;<A href=
"http://conserver.cybermirror.org/">Germany</A>
&nbsp;&nbsp;<A href=
"http://conserver.oss-mirror.org/">Ireland</A>
&nbsp;&nbsp;<A href="http://conserver.shape.ws/">Malaysia</A>
&nbsp;&nbsp;<A href="http://conserver.rinet.ru/">Russia</A>
&nbsp;&nbsp;<A href="http://www.conserver.com/">US-West
(Primary)</A><BR>
@ -56,16 +56,11 @@ body {
--></TD>
<TD rowspan="2" align="right">
<FORM method="post" action=
"http://www.conserver.com/cgi-bin/htsearch">
<INPUT type="hidden" name="method" value="and">
<INPUT type="hidden" name="format" value="builtin-long">
<INPUT type="hidden" name="sort" value="score">
<INPUT type="hidden" name="config" value=""> <INPUT type=
"hidden" name="restrict" value=""> <INPUT type="hidden"
name="exclude" value=""> <INPUT type="text" size="20"
name="words" value=""> <INPUT type="submit" value=
"Search">
<FORM method="get" action=
"http://www.conserver.com/cgi-bin/omega">
<INPUT type="hidden" name="DEFAULTOP" value="and">
<INPUT type="text" size="20" name="P" value="">
<INPUT type="submit" value="Search">
</FORM>
</TD>
</TR>
@ -182,8 +177,8 @@ body {
<H3>Downloading</H3>
<P>The current version, released on Nov 11, 2010, is
<A href="8.1.18.tar.gz">8.1.18.tar.gz</A>. See the <A href=
<P>The current version, released on Sep 26, 2013, is
<A href="8.1.19.tar.gz">8.1.19.tar.gz</A>. See the <A href=
"CHANGES">CHANGES</A> file for information on the latest
updates.</P>

View File

@ -1,4 +1,5 @@
### Path settings
datarootdir = @datarootdir@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
prefix = @prefix@

View File

@ -1,5 +1,5 @@
/*
* $Id: client.c,v 5.93 2009/09/26 09:20:15 bryan Exp $
* $Id: client.c,v 5.95 2013/09/25 22:10:29 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -413,13 +413,12 @@ static HELP aHLTable[] = {
{WHEN_ALWAYS, "w who is on this console"},
{WHEN_ALWAYS, "x show console baud info"},
{WHEN_ALWAYS | IS_LIMITED, "z suspend the connection"},
{WHEN_ATTACH, "! invoke task"},
{WHEN_ATTACH | IS_LIMITED, "| attach local command"},
{WHEN_ALWAYS, "? print this message"},
{WHEN_ALWAYS, "<cr> ignore/abort command"},
{WHEN_ALWAYS, "^R replay the last line"},
{WHEN_ATTACH, "\\ooo send character by octal code"},
{WHEN_EXPERT, "^I toggle tab expansion"},
{WHEN_EXPERT, "+(-) do (not) drop line"},
};
/* list the commands we know for the user (ksb)

View File

@ -1,5 +1,5 @@
/*
* $Id: client.h,v 5.42 2007/04/02 18:18:59 bryan Exp $
* $Id: client.h,v 5.44 2013/09/23 22:58:21 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -51,7 +51,9 @@ typedef enum clientState {
S_CEXEC, /* client execing a program */
S_REPLAY, /* set replay length for 'r' */
S_PLAYBACK, /* set replay length for 'p' */
S_NOTE /* send a note to the logfile */
S_NOTE, /* send a note to the logfile */
S_TASK, /* invoke a task on the server side */
S_CONFIRM /* confirm input */
} CLIENTSTATE;
typedef struct client { /* Connection Information: */
@ -87,6 +89,9 @@ typedef struct client { /* Connection Information: */
STRING *accmd; /* the command the user issued */
struct sockaddr_in
cnct_port; /* where from */
FLAG confirmed; /* confirm state */
CLIENTSTATE cState; /* state needing confirmation */
char cOption; /* option initiating the confirmation */
} CONSCLIENT;
extern void Replay PARAMS((CONSENT *, CONSFILE *, unsigned short));

View File

@ -1,5 +1,5 @@
/*
* $Id: consent.c,v 5.151 2007/04/09 15:52:28 bryan Exp $
* $Id: consent.c,v 5.153 2013/09/26 17:32:54 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -459,7 +459,7 @@ StartInit(pCE)
if (dup(pout[0]) != 0 || dup(pin[1]) != 1) {
Error("[%s] StartInit(): fd sync error", pCE->server);
Bye(EX_OSERR);
exit(EX_OSERR);
}
close(pout[0]);
close(pin[1]);
@ -480,10 +480,62 @@ StartInit(pCE)
execve(apcArgv[0], apcArgv, environ);
Error("[%s] execve(%s): %s", pCE->server, apcArgv[2], strerror(errno));
Bye(EX_OSERR);
exit(EX_OSERR);
return;
}
/* We exit() here, so only call this in a child process before an exec() */
void
#if PROTOTYPES
SetupTty(CONSENT *pCE, int fd)
#else
SetupTty(pCE, fd)
CONSENT *pCE;
int fd;
#endif
{
struct termios n_tio;
# if HAVE_STROPTS_H && !defined(_AIX)
/* SYSVr4 semantics for opening stream ptys (gregf)
* under PTX (others?) we have to push the compatibility
* streams modules `ptem', `ld', and `ttcompat'
*/
ioctl(1, I_PUSH, "ptem");
ioctl(1, I_PUSH, "ldterm");
ioctl(1, I_PUSH, "ttcompat");
# endif
if (0 != tcgetattr(1, &n_tio)) {
exit(EX_OSERR);
}
n_tio.c_iflag &= ~(IGNCR | IUCLC);
n_tio.c_iflag |= ICRNL;
if (pCE->ixon == FLAGTRUE)
n_tio.c_iflag |= IXON;
if (pCE->ixany == FLAGTRUE)
n_tio.c_iflag |= IXANY;
if (pCE->ixoff == FLAGTRUE)
n_tio.c_iflag |= IXOFF;
n_tio.c_oflag &=
~(OLCUC | ONOCR | ONLRET | OFILL | NLDLY | CRDLY | TABDLY | BSDLY);
n_tio.c_oflag |= OPOST | ONLCR;
n_tio.c_lflag &= ~(XCASE | NOFLSH | ECHOK | ECHONL);
n_tio.c_lflag |= ISIG | ICANON | ECHO;
n_tio.c_cc[VEOF] = '\004';
n_tio.c_cc[VEOL] = '\000';
n_tio.c_cc[VERASE] = '\010';
n_tio.c_cc[VINTR] = '\003';
n_tio.c_cc[VKILL] = '@';
/* MIN */
n_tio.c_cc[VQUIT] = '\034';
n_tio.c_cc[VSTART] = '\021';
n_tio.c_cc[VSTOP] = '\023';
n_tio.c_cc[VSUSP] = '\032';
if (0 != tcsetattr(1, TCSANOW, &n_tio))
exit(EX_OSERR);
}
/* setup a virtual device (ksb)
*/
static int
@ -494,7 +546,6 @@ VirtDev(pCE)
CONSENT *pCE;
#endif
{
static struct termios n_tio;
int i;
pid_t iNewGrp;
extern char **environ;
@ -558,7 +609,7 @@ VirtDev(pCE)
if (dup(pCE->execSlaveFD) != 0 || dup(pCE->execSlaveFD) != 1) {
Error("[%s] fd sync error", pCE->server);
Bye(EX_OSERR);
exit(EX_OSERR);
}
if (geteuid() == 0) {
@ -569,52 +620,8 @@ VirtDev(pCE)
setuid(pCE->execuid);
}
}
# if HAVE_STROPTS_H && !defined(_AIX)
/* SYSVr4 semantics for opening stream ptys (gregf)
* under PTX (others?) we have to push the compatibility
* streams modules `ptem', `ld', and `ttcompat'
*/
CONDDEBUG((1, "VirtDev(): pushing ptemp onto pseudo-terminal"));
ioctl(0, I_PUSH, "ptem");
CONDDEBUG((1, "VirtDev(): pushing ldterm onto pseudo-terminal"));
ioctl(0, I_PUSH, "ldterm");
CONDDEBUG((1, "VirtDev(): pushing ttcompat onto pseudo-terminal"));
ioctl(0, I_PUSH, "ttcompat");
CONDDEBUG((1, "VirtDev(): done pushing modules onto pseudo-terminal"));
# endif
if (0 != tcgetattr(0, &n_tio)) {
Error("[%s] tcgetattr(0): %s", pCE->server, strerror(errno));
Bye(EX_OSERR);
}
n_tio.c_iflag &= ~(IGNCR | IUCLC);
n_tio.c_iflag |= ICRNL;
if (pCE->ixon == FLAGTRUE)
n_tio.c_iflag |= IXON;
if (pCE->ixany == FLAGTRUE)
n_tio.c_iflag |= IXANY;
if (pCE->ixoff == FLAGTRUE)
n_tio.c_iflag |= IXOFF;
n_tio.c_oflag &=
~(OLCUC | ONOCR | ONLRET | OFILL | NLDLY | CRDLY | TABDLY | BSDLY);
n_tio.c_oflag |= OPOST | ONLCR;
n_tio.c_lflag &= ~(XCASE | NOFLSH | ECHOK | ECHONL);
n_tio.c_lflag |= ISIG | ICANON | ECHO;
n_tio.c_cc[VEOF] = '\004';
n_tio.c_cc[VEOL] = '\000';
n_tio.c_cc[VERASE] = '\010';
n_tio.c_cc[VINTR] = '\003';
n_tio.c_cc[VKILL] = '@';
/* MIN */
n_tio.c_cc[VQUIT] = '\034';
n_tio.c_cc[VSTART] = '\021';
n_tio.c_cc[VSTOP] = '\023';
n_tio.c_cc[VSUSP] = '\032';
if (0 != tcsetattr(0, TCSANOW, &n_tio)) {
Error("[%s] tcsetattr(0,TCSANOW): %s", pCE->server,
strerror(errno));
Bye(EX_OSERR);
}
SetupTty(pCE, 0);
tcsetpgrp(0, iNewGrp);
@ -647,7 +654,7 @@ VirtDev(pCE)
execve(pcShell, ppcArgv, environ);
Error("[%s] execve(): %s", pCE->server, strerror(errno));
Bye(EX_OSERR);
exit(EX_OSERR);
return -1;
}

View File

@ -1,5 +1,5 @@
/*
* $Id: consent.h,v 5.68 2007/04/02 17:59:16 bryan Exp $
* $Id: consent.h,v 5.72 2013/09/26 17:32:55 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -122,11 +122,14 @@ typedef struct consent { /* console information */
unsigned short spinmax; /* initialization spin maximum */
unsigned short spintimer; /* initialization spin timer */
char *replstring; /* generic string for replacements */
char *tasklist; /* list of valid tasks */
char *breaklist; /* list of valid break sequences */
/* timestamp stuff */
int mark; /* Mark (chime) interval */
long nextMark; /* Next mark (chime) time */
FLAG activitylog; /* log attach/detach/bump */
FLAG breaklog; /* log breaks sent */
FLAG tasklog; /* log tasks invoked */
/* options */
FLAG ondemand; /* bring up on-demand */
FLAG reinitoncc; /* open if down on client connect */
@ -143,6 +146,8 @@ typedef struct consent { /* console information */
pid_t ipid; /* pid of virtual command */
pid_t initpid; /* pid of initcmd command */
CONSFILE *initfile; /* the command run on init */
pid_t taskpid; /* pid of task running */
CONSFILE *taskfile; /* the output from the task (read-only) */
STRING *wbuf; /* write() buffer */
int wbufIAC; /* next IAC location in wbuf */
IOSTATE ioState; /* state of the socket */
@ -192,3 +197,4 @@ extern void DestroyRemoteConsole PARAMS((REMOTE *));
extern void StartInit PARAMS((CONSENT *));
extern void StopInit PARAMS((CONSENT *));
extern char *ConsState PARAMS((CONSENT *));
extern void SetupTty PARAMS((CONSENT *, int));

View File

@ -1,6 +1,6 @@
.\" @(#)conserver.8 01/06/91 OSU CIS; Thomas A. Fine
.\" $Id: conserver.man,v 1.54 2006/12/31 02:02:48 bryan Exp $
.TH CONSERVER 8 "2006/12/31" "conserver-8.1.18" "conserver"
.TH CONSERVER 8 "2006/12/31" "conserver-8.1.19" "conserver"
.SH NAME
conserver \- console server daemon
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
/*
* $Id: cutil.c,v 1.134 2010/11/02 03:42:57 bryan Exp $
* $Id: cutil.c,v 1.138 2013/09/26 17:50:24 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -1397,7 +1397,8 @@ FileCanRead(cfp, prfd, pwfd)
return ((FD_ISSET(cfp->fd, prfd)
#if HAVE_OPENSSL
&& cfp->waitForRead != FLAGTRUE) || (FD_ISSET(fdout, pwfd)
&& cfp->waitForRead != FLAGTRUE) || (fdout >= 0 &&
FD_ISSET(fdout, pwfd)
&& cfp->waitForWrite ==
FLAGTRUE
#endif

View File

@ -1,5 +1,5 @@
/*
* $Id: group.c,v 5.332 2009/09/26 09:58:05 bryan Exp $
* $Id: group.c,v 5.344 2013/09/26 17:50:24 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -207,6 +207,28 @@ AbortAnyClientExec(pCL)
}
}
static int
#if PROTOTYPES
StopTask(CONSENT *pCE)
#else
StopTask(pCE)
CONSENT *pCE;
#endif
{
if (pCE->taskpid != 0) {
kill(pCE->taskpid, SIGHUP);
CONDDEBUG((1, "StopTask(): sending task pid %lu signal %d",
(unsigned long)pCE->taskpid, SIGHUP));
}
if (pCE->taskfile != (CONSFILE *)0) {
int taskfile = FileFDNum(pCE->taskfile);
FD_CLR(taskfile, &rinit);
FileClose(&pCE->taskfile);
pCE->taskfile = (CONSFILE *)0;
}
}
void
#if PROTOTYPES
ClientWantsWrite(CONSCLIENT *pCL)
@ -614,6 +636,7 @@ DestroyConsent(pGE, pCE)
pGE->pCLfree = pCL;
}
StopTask(pCE);
ConsDown(pCE, FLAGFALSE, FLAGTRUE);
for (ppCE = &(pGE->pCElist); *ppCE != (CONSENT *)0;
@ -653,6 +676,10 @@ DestroyConsent(pGE, pCE)
free(pCE->idlestring);
if (pCE->replstring != (char *)0)
free(pCE->replstring);
if (pCE->tasklist != (char *)0)
free(pCE->tasklist);
if (pCE->breaklist != (char *)0)
free(pCE->breaklist);
if (pCE->execSlave != (char *)0)
free(pCE->execSlave);
while (pCE->aliases != (NAMES *)0) {
@ -780,14 +807,20 @@ QuietConv(num_msg, msg, resp, appdata_ptr)
*/
int
#if PROTOTYPES
CheckPass(char *pcUser, char *pcWord)
CheckPass(char *pcUser, char *pcWord, FLAG empty_check)
#else
CheckPass(pcUser, pcWord)
CheckPass(pcUser, pcWord, empty_check)
char *pcUser;
char *pcWord;
FLAG empty_check;
#endif
{
if (pcWord == (char *)0) {
pcWord = "";
}
#if HAVE_PAM
if (empty_check == FLAGTRUE)
return AUTH_INVALID;
int pam_error;
char *appdata[2];
static pam_handle_t *pamh = (pam_handle_t *)0;
@ -839,9 +872,6 @@ CheckPass(pcUser, pcWord)
struct spwd *spwd;
#endif
if (pcWord == (char *)0) {
pcWord = "";
}
if ((pwd = getpwnam(pcUser)) == (struct passwd *)0) {
CONDDEBUG((1, "CheckPass(): getpwnam(%s): %s", pcUser,
strerror(errno)));
@ -1381,7 +1411,7 @@ WriteLog(pCE, s, len)
{
int i = 0;
int j;
STRING *buf = (STRING *)0;
static STRING *buf = (STRING *)0;
if ((CONSFILE *)0 == pCE->fdlog) {
return;
@ -1552,6 +1582,46 @@ ReapVirt(pGE)
StopInit(pCE);
break;
}
if (pid == pCE->taskpid) {
CONSCLIENT *pCL;
if (WIFEXITED(UWbuf)) {
Msg("[%s] task terminated: pid %lu: exit(%d)",
pCE->server, pid, WEXITSTATUS(UWbuf));
if (pCE->tasklog == FLAGTRUE)
TagLogfile(pCE,
"task terminated: pid %lu: exit(%d)",
pid, WEXITSTATUS(UWbuf));
/* tell all how it ended */
for (pCL = pCE->pCLon; (CONSCLIENT *)0 != pCL;
pCL = pCL->pCLnext) {
if (pCL->fcon) {
FilePrint(pCL->fd, FLAGFALSE,
"[task terminated: exit(%d)]\r\n",
WEXITSTATUS(UWbuf));
}
}
}
if (WIFSIGNALED(UWbuf)) {
Msg("[%s] task terminated: pid %lu: signal(%d)",
pCE->server, pid, WTERMSIG(UWbuf));
if (pCE->tasklog == FLAGTRUE)
TagLogfile(pCE,
"task terminated: pid %lu: signal(%d)",
pid, WTERMSIG(UWbuf));
/* tell all how it ended */
for (pCL = pCE->pCLon; (CONSCLIENT *)0 != pCL;
pCL = pCL->pCLnext) {
if (pCL->fcon) {
FilePrint(pCL->fd, FLAGFALSE,
"[task terminated: signal(%d)]\r\n",
WTERMSIG(UWbuf));
}
}
}
pCE->taskpid = 0;
StopTask(pCE);
break;
}
if (pid != pCE->ipid)
continue;
@ -1580,11 +1650,12 @@ ReapVirt(pGE)
int
#if PROTOTYPES
CheckPasswd(CONSCLIENT *pCL, char *pw_string)
CheckPasswd(CONSCLIENT *pCL, char *pw_string, FLAG empty_check)
#else
CheckPasswd(pCL, pw_string)
CheckPasswd(pCL, pw_string, empty_check)
CONSCLIENT *pCL;
char *pw_string;
FLAG empty_check;
#endif
{
FILE *fp;
@ -1592,7 +1663,8 @@ CheckPasswd(pCL, pw_string)
char *this_pw, *user;
if ((fp = fopen(config->passwdfile, "r")) == (FILE *)0) {
if (CheckPass(pCL->username->string, pw_string) == AUTH_SUCCESS) {
if (CheckPass(pCL->username->string, pw_string, empty_check) ==
AUTH_SUCCESS) {
Verbose("user %s authenticated", pCL->acid->string);
return AUTH_SUCCESS;
}
@ -1631,8 +1703,8 @@ CheckPasswd(pCL, pw_string)
if ((*this_pw == '\000' && *pw_string == '\000') ||
((strcmp(this_pw, "*passwd*") ==
0) ? (CheckPass(pCL->username->string,
pw_string) ==
0) ? (CheckPass(pCL->username->string, pw_string,
empty_check) ==
AUTH_SUCCESS) : (strcmp(this_pw,
crypt(pw_string,
this_pw)) == 0))) {
@ -1835,6 +1907,8 @@ SendBreak(pCLServing, pCEServing, bt)
short bt;
#endif
{
CONSCLIENT *pCL;
short waszero = 0;
if (bt < 0 || bt > 9) {
FileWrite(pCLServing->fd, FLAGFALSE, "aborted]\r\n", -1);
@ -1849,9 +1923,41 @@ SendBreak(pCLServing, pCEServing, bt)
return;
}
if (breakList[bt - 1].confirm == FLAGTRUE) {
switch (pCLServing->confirmed) {
case FLAGUNKNOWN:
FileWrite(pCLServing->fd, FLAGFALSE, "confirm? [y/N] ",
-1);
pCLServing->confirmed = FLAGFALSE;
pCLServing->cState = S_HALT1;
pCLServing->iState = S_CONFIRM;
pCLServing->cOption = '0' + bt;
return;
case FLAGFALSE:
FileWrite(pCLServing->fd, FLAGFALSE, "aborted]\r\n", -1);
pCLServing->confirmed = FLAGUNKNOWN;
return;
case FLAGTRUE:
pCLServing->confirmed = FLAGUNKNOWN;
}
}
ExpandString(breakList[bt - 1].seq->string, pCEServing, bt);
FileWrite(pCLServing->fd, FLAGFALSE, "sent]\r\n", -1);
/* tell all who sent it */
for (pCL = pCEServing->pCLon; (CONSCLIENT *)0 != pCL;
pCL = pCL->pCLnext) {
if (pCL == pCLServing)
continue;
if (pCL->fcon) {
FilePrint(pCL->fd, FLAGFALSE, "[break sent by %s]\r\n",
pCLServing->acid->string);
}
}
if (pCEServing->breaklog == FLAGTRUE) {
if (waszero) {
TagLogfile(pCEServing, "break #0(%d) sent -- `%s'", bt,
@ -1863,6 +1969,205 @@ SendBreak(pCLServing, pCEServing, bt)
}
}
static int
#if PROTOTYPES
StartTask(CONSENT *pCE, char *cmd, uid_t uid, gid_t gid)
#else
StartTask(pCE, cmd, uid, gid)
CONSENT *pCE;
char *cmd;
uid_t uid;
gid_t gid;
#endif
{
int i;
extern char **environ;
char *pcShell, **ppcArgv;
extern int FallBack PARAMS((char **, int *));
char *execSlave; /* pseudo-device slave side */
int execSlaveFD; /* fd of slave side */
int cofile;
if ((cofile = FallBack(&execSlave, &execSlaveFD)) == -1) {
Error("[%s] StartTask(): failed to allocate pseudo-tty: %s",
pCE->server, strerror(errno));
return -1;
}
if (execSlave != (char *)0)
free(execSlave);
fflush(stdout);
fflush(stderr);
switch (pCE->taskpid = fork()) {
case -1:
pCE->taskpid = 0;
return -1;
case 0:
break;
default: /* server */
close(execSlaveFD);
if ((pCE->taskfile =
FileOpenFD(cofile, simpleFile)) == (CONSFILE *)0) {
close(cofile);
Error("[%s] FileOpenFD(%d,simpleFile) failed", pCE->server,
cofile);
return -1;
}
Msg("[%s] task started: pid %lu", pCE->server,
(unsigned long)pCE->taskpid);
FD_SET(cofile, &rinit);
if (maxfd < cofile + 1)
maxfd = cofile + 1;
fflush(stderr);
return 0;
}
close(cofile);
#if HAVE_SETSID
setsid();
#else
tcsetpgrp(0, getpid());
#endif
close(1);
if (dup(execSlaveFD) != 1) {
Error("[%s] StartTask(): fd 1 sync error", pCE->server);
exit(EX_OSERR);
}
close(2);
if (dup(execSlaveFD) != 2) {
exit(EX_OSERR);
}
/* no stdin */
close(0);
close(execSlaveFD);
/* setup new process with clean file descriptors
*/
i = GetMaxFiles();
for ( /* i above */ ; --i > 2;) {
close(i);
}
if (geteuid() == 0) {
if (gid != 0)
setgid(gid);
if (uid != 0)
setuid(uid);
}
SetupTty(pCE, 1);
pcShell = "/bin/sh";
static char *apcArgv[] = {
"/bin/sh", "-ce", (char *)0, (char *)0
};
apcArgv[2] = cmd;
ppcArgv = apcArgv;
execve(pcShell, ppcArgv, environ);
Error("[%s] execve(): %s", pCE->server, strerror(errno));
exit(EX_OSERR);
return -1;
}
void
#if PROTOTYPES
InvokeTask(CONSCLIENT *pCLServing, CONSENT *pCEServing, char id)
#else
InvokeTask(pCLServing, pCEServing, id)
CONSCLIENT *pCLServing;
CONSENT *pCEServing;
char id;
#endif
{
TASKS *t = (TASKS *)0;
int ret;
char *cmd;
if ((id < '0' || id > '9') && (id < 'a' || id > 'z')) {
FileWrite(pCLServing->fd, FLAGFALSE, "aborted]\r\n", -1);
return;
}
if (pCEServing->taskpid != 0) {
FileWrite(pCLServing->fd, FLAGFALSE, "aborted - task running]\r\n",
-1);
return;
}
if ((char *)0 != strchr(pCEServing->tasklist, id) ||
(char *)0 != strchr(pCEServing->tasklist, '*')) {
for (t = taskList; t != (TASKS *)0; t = t->next) {
if (t->id == id)
break;
}
}
if (t == (TASKS *)0) {
FileWrite(pCLServing->fd, FLAGFALSE, "undefined]\r\n", -1);
return;
}
if (t->confirm == FLAGTRUE) {
switch (pCLServing->confirmed) {
case FLAGUNKNOWN:
FileWrite(pCLServing->fd, FLAGFALSE, "confirm? [y/N] ",
-1);
pCLServing->confirmed = FLAGFALSE;
pCLServing->cState = S_TASK;
pCLServing->iState = S_CONFIRM;
pCLServing->cOption = id;
return;
case FLAGFALSE:
FileWrite(pCLServing->fd, FLAGFALSE, "aborted]\r\n", -1);
pCLServing->confirmed = FLAGUNKNOWN;
return;
case FLAGTRUE:
pCLServing->confirmed = FLAGUNKNOWN;
}
}
if ((cmd = StrDup(t->cmd->string)) == (char *)0)
OutOfMem();
if (t->subst != (char *)0) {
substData->data = (void *)pCEServing;
ProcessSubst(substData, &cmd, (char **)0, (char *)0, t->subst);
}
if (StartTask(pCEServing, cmd, t->uid, t->gid) == 0) {
CONSCLIENT *pCL;
char *detail;
FilePrint(pCLServing->fd, FLAGFALSE, "`%c' started]\r\n", id);
detail = t->descr->used > 1 ? t->descr->string : cmd;
/* tell all who started it */
for (pCL = pCEServing->pCLon; (CONSCLIENT *)0 != pCL;
pCL = pCL->pCLnext) {
if (pCL == pCLServing)
continue;
if (pCL->fcon) {
FilePrint(pCL->fd, FLAGFALSE,
"[task `%s' started by %s]\r\n", detail,
pCLServing->acid->string);
}
}
if (pCEServing->tasklog == FLAGTRUE) {
TagLogfile(pCEServing, "task started: pid %lu -- `%s'",
pCEServing->taskpid, cmd);
}
} else {
FileWrite(pCLServing->fd, FLAGFALSE, "failure]\r\n", -1);
}
free(cmd);
}
#if HAVE_OPENSSL
int
#if PROTOTYPES
@ -2317,8 +2622,8 @@ CommandHosts(pGE, pCLServing, pCEServing, tyme, args)
pCE->ioState == ISNORMAL)
? (pCE->initfile == (CONSFILE *)
0 ? "up" : "init") : "down",
pCE->pCLwr ? pCE->pCLwr->acid->
string : pCE->pCLon ? "<spies>" : "<none>");
pCE->pCLwr ? pCE->pCLwr->acid->string : pCE->
pCLon ? "<spies>" : "<none>");
if (args != (char *)0)
break;
}
@ -2404,7 +2709,7 @@ CommandInfo(pGE, pCLServing, pCEServing, tyme, args)
}
FilePrint(pCLServing->fd, FLAGTRUE,
":%s:%s:%s,%s,%s,%s,%d,%d:%d:%s:",
":%s:%s:%s,%s,%s,%s,%s,%d,%d:%d:%s:",
((pCE->fup &&
pCE->ioState == ISNORMAL) ? (pCE->initfile ==
(CONSFILE *)0 ? "up" :
@ -2413,9 +2718,10 @@ CommandInfo(pGE, pCLServing, pCEServing, tyme, args)
(pCE->logfile == (char *)0 ? "" : pCE->logfile),
(pCE->nolog ? "nolog" : "log"),
(pCE->activitylog == FLAGTRUE ? "act" : "noact"),
(pCE->breaklog == FLAGTRUE ? "brk" : "nobrk"), pCE->mark,
(pCE->fdlog ? pCE->fdlog->fd : -1), pCE->breakNum,
(pCE->autoReUp ? "autoup" : "noautoup"));
(pCE->breaklog == FLAGTRUE ? "brk" : "nobrk"),
(pCE->tasklog == FLAGTRUE ? "task" : "notask"),
pCE->mark, (pCE->fdlog ? pCE->fdlog->fd : -1),
pCE->breakNum, (pCE->autoReUp ? "autoup" : "noautoup"));
if (pCE->aliases != (NAMES *)0) {
NAMES *n;
comma = 0;
@ -2806,6 +3112,41 @@ DoConsoleRead(pCEServing)
}
}
void
#if PROTOTYPES
DoTaskRead(CONSENT *pCEServing)
#else
DoTaskRead(pCEServing)
CONSENT *pCEServing;
#endif
{
unsigned char acInOrig[BUFSIZ];
int nr, i, fd;
CONSCLIENT *pCL;
if (pCEServing->taskfile == (CONSFILE *)0)
return;
fd = FileFDNum(pCEServing->taskfile);
/* read from task */
if ((nr =
FileRead(pCEServing->taskfile, acInOrig, sizeof(acInOrig))) < 0) {
CONDDEBUG((1, "DoTaskRead(): got %d bytes from fd %d", nr, fd));
StopTask(pCEServing);
return;
}
CONDDEBUG((1, "DoTaskRead(): read %d bytes from fd %d", nr, fd));
/* write console info to clients (not suspended)
*/
for (pCL = pCEServing->pCLon; (CONSCLIENT *)0 != pCL;
pCL = pCL->pCLnext) {
if (pCL->fcon)
FileWrite(pCL->fd, FLAGFALSE, (char *)acInOrig, nr);
}
}
void
#if PROTOTYPES
DoCommandRead(CONSENT *pCEServing)
@ -3045,7 +3386,8 @@ DoClientRead(pGE, pCLServing)
/* process password here...before we corrupt accmd */
if (pCLServing->iState == S_PASSWD) {
if (CheckPasswd(pCLServing, pCLServing->accmd->string)
if (CheckPasswd
(pCLServing, pCLServing->accmd->string, FLAGFALSE)
!= AUTH_SUCCESS) {
FileWrite(pCLServing->fd, FLAGFALSE,
"invalid password\r\n", -1);
@ -3150,8 +3492,8 @@ DoClientRead(pGE, pCLServing)
BuildString(pCLServing->peername->string,
pCLServing->acid);
if (pCLServing->caccess == 't' ||
CheckPasswd(pCLServing,
"") == AUTH_SUCCESS) {
CheckPasswd(pCLServing, "",
FLAGTRUE) == AUTH_SUCCESS) {
pCLServing->iState = S_NORMAL;
Verbose("<group> login %s",
pCLServing->acid->string);
@ -3348,9 +3690,8 @@ DoClientRead(pGE, pCLServing)
pcArgs, pCLServing->acid->string);
num =
DisconnectCertainClients(pGE,
pCLServing->
acid->string,
pcArgs);
pCLServing->acid->
string, pcArgs);
/* client expects this string to be formatted
* in this way only.
*/
@ -3369,6 +3710,7 @@ DoClientRead(pGE, pCLServing)
}
BuildString((char *)0, pCLServing->accmd);
} else
statestart:
switch (pCLServing->iState) {
case S_IDENT:
case S_PASSWD:
@ -3564,7 +3906,12 @@ DoClientRead(pGE, pCLServing)
FileWrite(pCLServing->fd, FLAGFALSE,
"list]\r\n", -1);
i = pCEServing->breakNum;
if (i == 0 || breakList[i - 1].seq->used <= 1)
if (i == 0 || breakList[i - 1].seq->used <= 1
|| pCEServing->breaklist == (char *)0 ||
((char *)0 ==
strchr(pCEServing->breaklist, '1' + i)
&& (char *)0 ==
strchr(pCEServing->breaklist, '*')))
FileWrite(pCLServing->fd, FLAGTRUE,
" 0 - 0ms, <undefined>\r\n",
-1);
@ -3577,15 +3924,24 @@ DoClientRead(pGE, pCLServing)
breakList[i - 1].delay,
acA1->string);
}
for (i = 0; i < 9; i++) {
if (breakList[i].seq->used > 1) {
FmtCtlStr(breakList[i].seq->string,
breakList[i].seq->used - 1,
acA1);
FilePrint(pCLServing->fd, FLAGTRUE,
" %d - %3dms, `%s'\r\n",
i + 1, breakList[i].delay,
acA1->string);
if (pCEServing->breaklist != (char *)0) {
for (i = 0; i < 9; i++) {
if ((char *)0 ==
strchr(pCEServing->breaklist,
'1' + i)
&& (char *)0 ==
strchr(pCEServing->breaklist, '*'))
continue;
if (breakList[i].seq->used > 1) {
FmtCtlStr(breakList[i].seq->string,
breakList[i].seq->used -
1, acA1);
FilePrint(pCLServing->fd, FLAGTRUE,
" %d - %3dms, `%s'\r\n",
i + 1,
breakList[i].delay,
acA1->string);
}
}
}
FileWrite(pCLServing->fd, FLAGFALSE, (char *)0,
@ -3600,6 +3956,94 @@ DoClientRead(pGE, pCLServing)
}
continue;
case S_TASK: /* task invocation */
pCLServing->iState = S_NORMAL;
if (pCEServing->taskpid != 0 && acIn[i] == '.') {
FileWrite(pCLServing->fd, FLAGFALSE,
"terminate]\r\n", -1);
StopTask(pCEServing);
continue;
}
if (acIn[i] != '?' &&
((acIn[i] < '0' || acIn[i] > '9') &&
(acIn[i] < 'a' || acIn[i] > 'z'))) {
FileWrite(pCLServing->fd, FLAGFALSE,
"aborted]\r\n", -1);
continue;
}
if (acIn[i] == '?') {
TASKS *t;
int saw = 0;
if (pCEServing->taskpid != 0) {
STRING *acA1 = AllocString();
STRING *acA2 = AllocString();
FilePrint(pCLServing->fd, FLAGFALSE,
"running - pid %lu - use `%s%s!.' to terminate]\r\n",
(unsigned long)pGE->pid,
FmtCtl(pCLServing->ic[0], acA1),
FmtCtl(pCLServing->ic[1], acA2));
DestroyString(acA1);
DestroyString(acA2);
return;
} else {
FileWrite(pCLServing->fd, FLAGFALSE,
"list]\r\n", -1);
if (pCEServing->tasklist != (char *)0) {
for (t = taskList; t != (TASKS *)0;
t = t->next) {
if ((char *)0 ==
strchr(pCEServing->tasklist,
t->id)
&& (char *)0 ==
strchr(pCEServing->tasklist,
'*'))
continue;
if (t->descr->used > 1) {
FilePrint(pCLServing->fd,
FLAGTRUE,
" %c - `%s'\r\n",
t->id,
t->descr->string);
} else if (t->cmd->used > 1) {
FilePrint(pCLServing->fd,
FLAGTRUE,
" %c - `%s'\r\n",
t->id,
t->cmd->string);
}
saw++;
}
}
if (saw == 0)
FileWrite(pCLServing->fd, FLAGTRUE,
" <undefined>\r\n", -1);
FileWrite(pCLServing->fd, FLAGFALSE,
(char *)0, 0);
}
} else {
if (pCLServing->fwr) {
InvokeTask(pCLServing, pCEServing,
acIn[i]);
} else
FileWrite(pCLServing->fd, FLAGFALSE,
"attach to invoke task]\r\n",
-1);
}
continue;
case S_CONFIRM:
if (acIn[i] == 'y' || acIn[i] == 'Y') {
pCLServing->confirmed = FLAGTRUE;
FileWrite(pCLServing->fd, FLAGFALSE, "y ", -1);
} else {
FileWrite(pCLServing->fd, FLAGFALSE, "n ", -1);
}
pCLServing->iState = pCLServing->cState;
acIn[i] = pCLServing->cOption;
goto statestart;
case S_CATTN: /* redef escape sequence? */
pCLServing->ic[0] = acInOrig[i];
FmtCtl(acInOrig[i], acA1);
@ -3688,16 +4132,6 @@ DoClientRead(pGE, pCLServing)
pCLServing->fcon = 1;
}
break;
case '+':
case '-':
if (0 !=
(pCLServing->fecho = '+' == acIn[i]))
FileWrite(pCLServing->fd, FLAGFALSE,
"drop line]\r\n", -1);
else
FileWrite(pCLServing->fd, FLAGFALSE,
"no drop line]\r\n", -1);
break;
case 'a': /* attach */
CommandAttach(pGE, pCLServing, pCEServing,
@ -3712,11 +4146,17 @@ DoClientRead(pGE, pCLServing)
break;
case 'c':
if (!pCLServing->fwr) {
goto unknownchar;
}
CommandChangeFlow(pGE, pCLServing,
pCEServing, tyme);
break;
case 'd': /* down a console */
if (!pCLServing->fwr) {
goto unknownchar;
}
CommandDown(pGE, pCLServing, pCEServing,
tyme);
break;
@ -3753,11 +4193,17 @@ DoClientRead(pGE, pCLServing)
break;
case 'L':
if (!pCLServing->fwr) {
goto unknownchar;
}
CommandLogging(pGE, pCLServing, pCEServing,
tyme);
break;
case 'l': /* halt character 1 */
if (!pCLServing->fwr) {
goto unknownchar;
}
if (pCEServing->fronly) {
FileWrite(pCLServing->fd, FLAGFALSE,
"can't halt read-only console]\r\n",
@ -3835,12 +4281,10 @@ DoClientRead(pGE, pCLServing)
break;
case 's': /* spy mode */
pCLServing->fwantwr = 0;
if (!pCLServing->fwr) {
FileWrite(pCLServing->fd, FLAGFALSE,
"ok]\r\n", -1);
break;
goto unknownchar;
}
pCLServing->fwantwr = 0;
BumpClient(pCEServing, (char *)0);
TagLogfileAct(pCEServing, "%s detached",
pCLServing->acid->string);
@ -3894,23 +4338,27 @@ DoClientRead(pGE, pCLServing)
BumpClient(pCEServing, (char *)0);
TagLogfileAct(pCEServing,
"%s detached",
pCLServing->
acid->string);
pCLServing->acid->
string);
FindWrite(pCEServing);
}
break;
case '|': /* wait for client */
if (ConsentUserOk
(pLUList,
pCLServing->username->string) == 1)
goto unknownchar;
case '!': /* invoke a task */
if (!pCLServing->fwr) {
FileWrite(pCLServing->fd, FLAGFALSE,
"attach to run local command]\r\n",
-1);
continue;
goto unknownchar;
}
pCLServing->iState = S_TASK;
FileWrite(pCLServing->fd, FLAGFALSE,
"task ", -1);
break;
case '|': /* wait for client */
if (!pCLServing->fwr ||
ConsentUserOk(pLUList,
pCLServing->username->
string) == 1)
goto unknownchar;
FileSetQuoteIAC(pCLServing->fd, FLAGFALSE);
FilePrint(pCLServing->fd, FLAGFALSE,
"%c%c", OB_IAC, OB_EXEC);
@ -3919,50 +4367,6 @@ DoClientRead(pGE, pCLServing)
pCLServing->iState = S_CWAIT;
break;
case '\t': /* toggle tab expand */
if (!pCLServing->fwr) {
FileWrite(pCLServing->fd, FLAGFALSE,
"attach to toggle tabs]\r\n",
-1);
continue;
}
if (pCEServing->type != DEVICE &&
pCEServing->type != EXEC) {
FileWrite(pCLServing->fd, FLAGFALSE,
"ok]\r\n", -1);
continue;
}
if (-1 ==
tcgetattr(FileFDNum
(pCEServing->cofile),
&sbuf)) {
FileWrite(pCLServing->fd, FLAGFALSE,
"failed]\r\n", -1);
continue;
}
if (TAB3 == (TABDLY & sbuf.c_oflag)) {
sbuf.c_oflag &= ~TABDLY;
sbuf.c_oflag |= TAB0;
} else {
sbuf.c_oflag &= ~TABDLY;
sbuf.c_oflag |= TAB3;
}
if (-1 ==
tcsetattr(FileFDNum
(pCEServing->cofile),
TCSANOW, &sbuf)) {
FileWrite(pCLServing->fd, FLAGFALSE,
"failed]\r\n", -1);
continue;
}
if (TAB3 == (TABDLY & sbuf.c_oflag))
FileWrite(pCLServing->fd, FLAGFALSE,
"tabs OFF]\r\n", -1);
else
FileWrite(pCLServing->fd, FLAGFALSE,
"tabs ON]\r\n", -1);
break;
case '.': /* disconnect */
case '\004':
case '\003':
@ -4672,6 +5076,8 @@ Kiddie(pGE, sfd)
DoConsoleRead(pCEServing);
if (FileCanRead(pCEServing->initfile, &rmask, &wmask))
DoCommandRead(pCEServing);
if (FileCanRead(pCEServing->taskfile, &rmask, &wmask))
DoTaskRead(pCEServing);
/* fall through to ISFLUSHING for buffered data */
case ISFLUSHING:
/* write cofile data */

View File

@ -1,5 +1,5 @@
/*
* $Id: group.h,v 5.49 2006/04/07 15:36:09 bryan Exp $
* $Id: group.h,v 5.51 2013/09/23 23:17:42 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -65,7 +65,7 @@ typedef struct grpent { /* group info */
extern time_t timers[];
extern void Spawn PARAMS((GRPENT *, int));
extern int CheckPass PARAMS((char *, char *));
extern int CheckPass PARAMS((char *, char *, FLAG));
extern void TagLogfile PARAMS((const CONSENT *, char *, ...));
extern void TagLogfileAct PARAMS((const CONSENT *, char *, ...));
extern void DestroyGroup PARAMS((GRPENT *));
@ -79,7 +79,7 @@ extern void DisconnectClient
PARAMS((GRPENT *, CONSCLIENT *, char *, FLAG));
extern int ClientAccess PARAMS((CONSENT *, char *));
extern void DestroyClient PARAMS((CONSCLIENT *));
extern int CheckPasswd PARAMS((CONSCLIENT *, char *));
extern int CheckPasswd PARAMS((CONSCLIENT *, char *, FLAG));
extern void DeUtmp PARAMS((GRPENT *, int));
extern void ClientWantsWrite PARAMS((CONSCLIENT *));
extern void SendIWaitClientsMsg PARAMS((CONSENT *, char *));

View File

@ -1,5 +1,5 @@
/*
* $Id: main.c,v 5.202 2009/09/26 09:23:04 bryan Exp $
* $Id: main.c,v 5.208 2013/09/25 22:10:29 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -69,7 +69,7 @@ CONFIG defConfig =
, FLAGFALSE
#endif
#if HAVE_OPENSSL
, (char *)0, FLAGTRUE
, (char *)0, FLAGTRUE, FLAGFALSE, (char *)0
#endif
};
@ -327,6 +327,7 @@ SetupSSL()
{
if (ctx == (SSL_CTX *)0) {
char *ciphers;
int verifymode;
SSL_load_error_strings();
if (!SSL_library_init()) {
Error("SetupSSL(): SSL_library_init() failed");
@ -360,7 +361,31 @@ SetupSSL()
} else {
ciphers = "ALL:!LOW:!EXP:!MD5:@STRENGTH";
}
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
if (config->sslcacertificatefile != (char *)0) {
STACK_OF(X509_NAME) * cert_names;
cert_names =
SSL_load_client_CA_file(config->sslcacertificatefile);
if (cert_names != NULL) {
SSL_CTX_set_client_CA_list(ctx, cert_names);
if (SSL_CTX_load_verify_locations
(ctx, config->sslcacertificatefile, NULL) != 1) {
Error("Could not setup CA certificate file to '%s'",
config->sslcacertificatefile);
Bye(EX_UNAVAILABLE);
}
} else {
Error
("SetupSSL(): could not load SSL client CA list from `%s'",
config->sslcacertificatefile);
Bye(EX_SOFTWARE);
}
}
verifymode = SSL_VERIFY_PEER;
if (config->sslreqclientcert == FLAGTRUE)
verifymode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
SSL_CTX_set_verify(ctx, verifymode, SSLVerifyCallback);
SSL_CTX_set_options(ctx,
SSL_OP_ALL | SSL_OP_NO_SSLv2 |
SSL_OP_SINGLE_DH_USE);
@ -765,6 +790,7 @@ DestroyDataStructures()
free(myAddrs);
DestroyBreakList();
DestroyTaskList();
DestroyStrings();
DestroyUserList();
if (substData != (SUBST *)0)
@ -824,12 +850,18 @@ SummarizeDataStructures()
size += strlen(pCE->idlestring);
if (pCE->replstring != (char *)0)
size += strlen(pCE->replstring);
if (pCE->tasklist != (char *)0)
size += strlen(pCE->tasklist);
if (pCE->breaklist != (char *)0)
size += strlen(pCE->breaklist);
if (pCE->fdlog != (CONSFILE *)0)
size += sizeof(CONSFILE);
if (pCE->cofile != (CONSFILE *)0)
size += sizeof(CONSFILE);
if (pCE->initfile != (CONSFILE *)0)
size += sizeof(CONSFILE);
if (pCE->taskfile != (CONSFILE *)0)
size += sizeof(CONSFILE);
if (pCE->aliases != (NAMES *)0) {
NAMES *n;
for (n = pCE->aliases; n != (NAMES *)0; n = n->next) {
@ -902,6 +934,8 @@ DumpDataStructures()
GRPENT *pGE;
CONSENT *pCE;
REMOTE *pRC;
int i;
TASKS *t;
#if HAVE_DMALLOC && DMALLOC_MARK_MAIN
CONDDEBUG((1, "DumpDataStructures(): dmalloc / MarkMain"));
@ -992,9 +1026,9 @@ DumpDataStructures()
pCE->nolog, FileFDNum(pCE->cofile),
FLAGSTR(pCE->activitylog), FLAGSTR(pCE->breaklog)));
CONDDEBUG((1,
"DumpDataStructures(): ixon=%s, ixany=%s, ixoff=%s",
FLAGSTR(pCE->ixon), FLAGSTR(pCE->ixany),
FLAGSTR(pCE->ixoff)));
"DumpDataStructures(): tasklog=%s, ixon=%s, ixany=%s, ixoff=%s",
FLAGSTR(pCE->tasklog), FLAGSTR(pCE->ixon),
FLAGSTR(pCE->ixany), FLAGSTR(pCE->ixoff)));
CONDDEBUG((1,
"DumpDataStructures(): autoreinit=%s, hupcl=%s, cstopb=%s, ondemand=%s",
FLAGSTR(pCE->autoreinit), FLAGSTR(pCE->hupcl),
@ -1019,6 +1053,11 @@ DumpDataStructures()
EMPTYSTR(pCE->motd), pCE->idletimeout,
EMPTYSTR(pCE->idlestring),
EMPTYSTR(pCE->replstring)));
CONDDEBUG((1,
"DumpDataStructures(): tasklist=%s, breaklist=%s, taskpid=%lu, taskfile=%d",
EMPTYSTR(pCE->tasklist), EMPTYSTR(pCE->breaklist),
(unsigned long)pCE->taskpid,
FileFDNum(pCE->taskfile)));
if (pCE->ro) {
CONSENTUSERS *u;
for (u = pCE->ro; u != (CONSENTUSERS *)0; u = u->next) {
@ -1046,6 +1085,19 @@ DumpDataStructures()
}
}
}
for (i = 0; i < 9; i++) {
CONDDEBUG((1,
"DumpDataStructures(): break: string=%s, delay=%d, confirm=%s",
EMPTYSTR(breakList[i].seq->string), breakList[i].delay,
FLAGSTR(breakList[i].confirm)));
}
for (t = taskList; t != (TASKS *)0; t = t->next) {
CONDDEBUG((1,
"DumpDataStructures(): task: id=%c, cmd=%s, descr=%s, uid=%d, gid=%d, subst=%s, confirm=%s",
t->id, EMPTYSTR(t->cmd->string),
EMPTYSTR(t->descr->string), t->uid, t->gid,
EMPTYSTR(t->subst), FLAGSTR(t->confirm)));
}
}
/* This makes sure a directory exists and tries to create it if it
@ -1568,12 +1620,29 @@ main(argc, argv)
else
config->sslrequired = defConfig.sslrequired;
if (optConf->sslreqclientcert != FLAGUNKNOWN)
config->sslreqclientcert = optConf->sslreqclientcert;
else if (pConfig->sslreqclientcert != FLAGUNKNOWN)
config->sslreqclientcert = pConfig->sslreqclientcert;
else
config->sslreqclientcert = defConfig.sslreqclientcert;
if (optConf->sslcredentials != (char *)0)
config->sslcredentials = StrDup(optConf->sslcredentials);
else if (pConfig->sslcredentials != (char *)0)
config->sslcredentials = StrDup(pConfig->sslcredentials);
else
config->sslcredentials = StrDup(defConfig.sslcredentials);
if (optConf->sslcacertificatefile != (char *)0)
config->sslcacertificatefile =
StrDup(optConf->sslcacertificatefile);
else if (pConfig->sslcacertificatefile != (char *)0)
config->sslcacertificatefile =
StrDup(pConfig->sslcacertificatefile);
else
config->sslcacertificatefile =
StrDup(defConfig.sslcacertificatefile);
#endif
#if HAVE_SETPROCTITLE

View File

@ -1,5 +1,5 @@
/*
* $Id: master.c,v 5.136 2009/09/26 09:23:04 bryan Exp $
* $Id: master.c,v 5.139 2013/09/23 23:17:42 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -461,8 +461,9 @@ DoNormalRead(pCLServing)
/* process password here...before we corrupt accmd */
if (pCLServing->iState == S_PASSWD) {
if (CheckPasswd(pCLServing, pCLServing->accmd->string) !=
AUTH_SUCCESS) {
if (CheckPasswd
(pCLServing, pCLServing->accmd->string, FLAGFALSE)
!= AUTH_SUCCESS) {
FileWrite(pCLServing->fd, FLAGFALSE,
"invalid password\r\n", -1);
BuildString((char *)0, pCLServing->accmd);
@ -564,7 +565,8 @@ DoNormalRead(pCLServing)
BuildString(pCLServing->peername->string,
pCLServing->acid);
if (pCLServing->caccess == 't' ||
CheckPasswd(pCLServing, "") == AUTH_SUCCESS) {
CheckPasswd(pCLServing, "",
FLAGTRUE) == AUTH_SUCCESS) {
pCLServing->iState = S_NORMAL;
Verbose("<master> login %s",
pCLServing->acid->string);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* $Id: readcfg.h,v 5.45 2005/06/07 19:55:51 bryan Exp $
* $Id: readcfg.h,v 5.49 2013/09/23 22:58:21 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -28,14 +28,28 @@ typedef struct config {
#if HAVE_OPENSSL
char *sslcredentials;
FLAG sslrequired;
FLAG sslreqclientcert;
char *sslcacertificatefile;
#endif
} CONFIG;
typedef struct breaks {
STRING *seq;
int delay;
FLAG confirm;
} BREAKS;
typedef struct tasks {
char id;
STRING *cmd;
STRING *descr;
uid_t uid;
gid_t gid;
char *subst;
FLAG confirm;
struct tasks *next;
} TASKS;
extern NAMES *userList; /* user list */
extern GRPENT *pGroups; /* group info */
extern REMOTE *pRCList; /* list of remote consoles we know about */
@ -44,12 +58,15 @@ extern ACCESS *pACList; /* `who do you love' (or trust) */
extern CONSENTUSERS *pADList; /* list of admin users */
extern CONSENTUSERS *pLUList; /* list of limited users */
extern BREAKS breakList[9]; /* list of break sequences */
extern TASKS *taskList; /* list of tasks */
extern SUBST *taskSubst; /* substitution function data for tasks */
extern CONFIG *pConfig; /* settings seen by config parser */
extern SUBST *substData; /* substitution function data */
extern void ReadCfg PARAMS((char *, FILE *));
extern void ReReadCfg PARAMS((int, int));
extern void DestroyBreakList PARAMS((void));
extern void DestroyTaskList PARAMS((void));
extern void DestroyUserList PARAMS((void));
extern void DestroyConfig PARAMS((CONFIG *));
extern NAMES *FindUserList PARAMS((char *));

View File

@ -1,5 +1,5 @@
/*
* $Id: version.h,v 1.77 2010/11/11 22:44:10 bryan Exp $
* $Id: version.h,v 1.78 2013/09/13 20:54:09 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -16,6 +16,6 @@ All rights reserved.\n"
#define VERSION_MAJOR 8
#define VERSION_MINOR 1
#define VERSION_REV 18
#define VERSION_REV 19
#define VERSION_TEXT "conserver.com version"
#define VERSION_UINT (VERSION_MAJOR * 1000000 + VERSION_MINOR * 1000 + VERSION_REV)

View File

@ -1,4 +1,5 @@
### Path settings
datarootdir = @datarootdir@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
prefix = @prefix@

View File

@ -1,5 +1,5 @@
/*
* $Id: console.c,v 5.185 2009/10/19 06:44:06 bryan Exp $
* $Id: console.c,v 5.188 2013/09/18 14:31:39 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -91,6 +91,20 @@ SetupSSL()
Error("Could not load SSL default CA file and/or directory");
Bye(EX_UNAVAILABLE);
}
if (config->sslcacertificatefile != (char *)0 ||
config->sslcacertificatepath != (char *)0) {
if (SSL_CTX_load_verify_locations
(ctx, config->sslcacertificatefile,
config->sslcacertificatepath) != 1) {
if (config->sslcacertificatefile != (char *)0)
Error("Could not setup ca certificate file to '%s'",
config->sslcacertificatefile);
if (config->sslcacertificatepath != (char *)0)
Error("Could not setup ca certificate path to '%s'",
config->sslcacertificatepath);
Bye(EX_UNAVAILABLE);
}
}
if (config->sslcredentials != (char *)0) {
if (SSL_CTX_use_certificate_chain_file
(ctx, config->sslcredentials) != 1) {
@ -106,7 +120,11 @@ SetupSSL()
}
ciphers = "ALL:!LOW:!EXP:!MD5:!aNULL:@STRENGTH";
} else {
#if defined(REQ_SERVER_CERT)
ciphers = "ALL:!LOW:!EXP:!MD5:!aNULL:@STRENGTH";
#else
ciphers = "ALL:!LOW:!EXP:!MD5:@STRENGTH";
#endif
}
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
SSL_CTX_set_options(ctx,
@ -1352,7 +1370,7 @@ Interact(pcf, pcMach)
if (screwy)
break;
else {
FD_SET(0, &rinit);
FD_CLR(0, &rinit);
continue;
}
}
@ -2317,7 +2335,18 @@ main(argc, argv)
config->sslcredentials = StrDup(pConfig->sslcredentials);
else
config->sslcredentials = (char *)0;
if (pConfig->sslcacertificatefile != (char *)0 &&
pConfig->sslcacertificatefile[0] != '\000')
config->sslcacertificatefile =
StrDup(pConfig->sslcacertificatefile);
else
config->sslcacertificatefile = (char *)0;
if (pConfig->sslcacertificatepath != (char *)0 &&
pConfig->sslcacertificatepath[0] != '\000')
config->sslcacertificatepath =
StrDup(pConfig->sslcacertificatepath);
else
config->sslcacertificatepath = (char *)0;
if (optConf->sslenabled != FLAGUNKNOWN)
config->sslenabled = optConf->sslenabled;
else if (pConfig->sslenabled != FLAGUNKNOWN)

View File

@ -1,5 +1,5 @@
.\" $Id: console.man,v 1.61 2006/04/03 13:32:12 bryan Exp $
.TH CONSOLE 1 "2006/04/03" "conserver-8.1.18" "conserver"
.\" $Id: console.man,v 1.65 2013/09/25 22:10:30 bryan Exp $
.TH CONSOLE 1 "2013/09/25" "conserver-8.1.19" "conserver"
.SH NAME
console \- console server client program
.SH SYNOPSIS
@ -564,6 +564,18 @@ Using the special value of ``0'' will cause the client to use the number
of lines of the current terminal (if that can be determined).
If the null string (``""'') is used, the replay length will not be overridden.
.TP
\f3sslcacertificatefile\fP \f2filename\fP
.br
Load the valid CA certificates for the
.SM SSL
connection from the PEM encoded file.
.TP
\f3sslcacertificatepath\fP \f2directory\fP
.br
Load the valid CA certificates for the
.SM SSL
connection from the PEM encoded files in the directory.
.TP
\f3sslcredentials\fP \f2filename\fP
.br
Set the
@ -868,7 +880,7 @@ replay the last 20 lines of output
set number of replay lines
.TP
.B s
switch to spy mode (read-only)
switch to spy mode (read only)
.TP
.B u
show status of hosts/users in this group
@ -885,6 +897,9 @@ examine this group's devices and modes
.B z
suspend this connection
.TP
.B !
invoke task
.TP
.B |
attach a local command to the console
.TP

View File

@ -1,5 +1,5 @@
/*
* $Id: readconf.c,v 5.5 2006/04/03 13:32:12 bryan Exp $
* $Id: readconf.c,v 5.7 2013/09/18 14:31:39 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -39,6 +39,10 @@ DestroyConfig(c)
#if HAVE_OPENSSL
if (c->sslcredentials != (char *)0)
free(c->sslcredentials);
if (c->sslcacertificatefile != (char *)0)
free(c->sslcacertificatefile);
if (c->sslcacertificatepath != (char *)0)
free(c->sslcacertificatepath);
#endif
free(c);
}
@ -93,6 +97,22 @@ ApplyConfigDefault(c)
StrDup(parserConfigDefault->sslcredentials)) == (char *)0)
OutOfMem();
}
if (parserConfigDefault->sslcacertificatefile != (char *)0) {
if (c->sslcacertificatefile != (char *)0)
free(c->sslcacertificatefile);
if ((c->sslcacertificatefile =
StrDup(parserConfigDefault->sslcacertificatefile)) ==
(char *)0)
OutOfMem();
}
if (parserConfigDefault->sslcacertificatepath != (char *)0) {
if (c->sslcacertificatepath != (char *)0)
free(c->sslcacertificatepath);
if ((c->sslcacertificatepath =
StrDup(parserConfigDefault->sslcacertificatepath)) ==
(char *)0)
OutOfMem();
}
if (parserConfigDefault->sslrequired != FLAGUNKNOWN)
c->sslrequired = parserConfigDefault->sslrequired;
if (parserConfigDefault->sslenabled != FLAGUNKNOWN)
@ -504,6 +524,60 @@ ConfigItemSslcredentials(id)
#endif
}
void
#if PROTOTYPES
ConfigItemSslcacertificatefile(char *id)
#else
ConfigItemSslcacertificatefile(id)
char *id;
#endif
{
CONDDEBUG((1, "ConfigItemSslcacertificatefile(%s) [%s:%d]", id, file,
line));
#if HAVE_OPENSSL
if (parserConfigTemp->sslcacertificatefile != (char *)0)
free(parserConfigTemp->sslcacertificatefile);
if ((id == (char *)0) || (*id == '\000')) {
parserConfigTemp->sslcacertificatefile = (char *)0;
return;
}
if ((parserConfigTemp->sslcacertificatefile = StrDup(id)) == (char *)0)
OutOfMem();
#else
Error
("sslcacertificatefile ignored - encryption not compiled into code [%s:%d]",
file, line);
#endif
}
void
#if PROTOTYPES
ConfigItemSslcacertificatepath(char *id)
#else
ConfigItemSslcacertificatepath(id)
char *id;
#endif
{
CONDDEBUG((1, "ConfigItemSslcacertificatepath(%s) [%s:%d]", id, file,
line));
#if HAVE_OPENSSL
if (parserConfigTemp->sslcacertificatepath != (char *)0)
free(parserConfigTemp->sslcacertificatepath);
if ((id == (char *)0) || (*id == '\000')) {
parserConfigTemp->sslcacertificatepath = (char *)0;
return;
}
if ((parserConfigTemp->sslcacertificatepath = StrDup(id)) == (char *)0)
OutOfMem();
#else
Error
("sslcacertificatepath ignored - encryption not compiled into code [%s:%d]",
file, line);
#endif
}
void
#if PROTOTYPES
ConfigItemSslrequired(char *id)
@ -712,6 +786,8 @@ ITEM keyConfig[] = {
{"port", ConfigItemPort},
{"replay", ConfigItemReplay},
{"sslcredentials", ConfigItemSslcredentials},
{"sslcacertificatefile", ConfigItemSslcacertificatefile},
{"sslcacertificatepath", ConfigItemSslcacertificatepath},
{"sslrequired", ConfigItemSslrequired},
{"sslenabled", ConfigItemSslenabled},
{"striphigh", ConfigItemStriphigh},
@ -793,6 +869,10 @@ ReadConf(filename, verbose)
#if HAVE_OPENSSL
CONDDEBUG((1, "pConfig->sslcredentials = %s",
EMPTYSTR(pConfig->sslcredentials)));
CONDDEBUG((1, "pConfig->sslcacertificatefile = %s",
EMPTYSTR(pConfig->sslcacertificatefile)));
CONDDEBUG((1, "pConfig->sslcacertificatepath = %s",
EMPTYSTR(pConfig->sslcacertificatepath)));
CONDDEBUG((1, "pConfig->sslrequired = %s",
FLAGSTR(pConfig->sslrequired)));
CONDDEBUG((1, "pConfig->sslenabled = %s",

View File

@ -1,5 +1,5 @@
/*
* $Id: readconf.h,v 5.4 2006/04/03 13:32:12 bryan Exp $
* $Id: readconf.h,v 5.6 2013/09/18 14:31:39 bryan Exp $
*
* Copyright conserver.com, 2000
*
@ -18,6 +18,8 @@ typedef struct config {
unsigned short playback;
#if HAVE_OPENSSL
char *sslcredentials;
char *sslcacertificatefile;
char *sslcacertificatepath;
FLAG sslrequired;
FLAG sslenabled;
#endif

View File

@ -1,4 +1,5 @@
### Path settings
datarootdir = @datarootdir@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
prefix = @prefix@

View File

@ -6,12 +6,13 @@
# outside of my own purposes. If this helps, cool. In the end I put the
# rootcert.pem file in my global certs directory (OPENSSL_ROOT/ssl/certs),
# point the server to server.pem and point the client at client.pem. I
# then run the c_rehash command (I supposed it helps or is important).
# When it asks for a passphrase, use 'pass', otherwise this script won't
# work. Ugly, yeah, but it's an ok test.
# then run the c_rehash command.
#
# You can also use the sslcacertificatefile options to point the client/server
# at rootcert.pem instead of populating the global repository
#
[ -f rootreq.pem -a -f rootkey.pem ] || cat <<EOD | openssl req -newkey rsa:1024 -sha1 -keyout rootkey.pem -out rootreq.pem -passin pass:pass -passout pass:pass
[ -f rootreq.pem -a -f rootkey.pem ] || cat <<EOD | openssl req -newkey rsa:1024 -sha1 -keyout rootkey.pem -out rootreq.pem -nodes
US
California
Folsom
@ -25,7 +26,7 @@ EOD
[ -f rootcert.pem ] || openssl x509 -req -in rootreq.pem -sha1 -extensions v3_ca -signkey rootkey.pem -out rootcert.pem
[ -f root.pem ] || cat rootcert.pem rootkey.pem > root.pem
[ -f serverreq.pem -a -f serverkey.pem ] || cat <<EOD | openssl req -newkey rsa:1024 -sha1 -keyout serverkey.pem -out serverreq.pem -passin pass:pass -passout pass:pass
[ -f serverreq.pem -a -f serverkey.pem ] || cat <<EOD | openssl req -newkey rsa:1024 -sha1 -keyout serverkey.pem -out serverreq.pem -nodes
US
California
Folsom
@ -39,7 +40,7 @@ EOD
[ -f servercert.pem ] || openssl x509 -req -in serverreq.pem -sha1 -extensions usr_cert -CA root.pem -CAkey root.pem -CAcreateserial -out servercert.pem
[ -f server.pem ] || cat servercert.pem serverkey.pem rootcert.pem > server.pem
[ -f clientreq.pem -a -f clientkey.pem ] || cat <<EOD | openssl req -newkey rsa:1024 -sha1 -keyout clientkey.pem -out clientreq.pem -passin pass:pass -passout pass:pass
[ -f clientreq.pem -a -f clientkey.pem ] || cat <<EOD | openssl req -newkey rsa:1024 -sha1 -keyout clientkey.pem -out clientreq.pem -nodes
US
California
Folsom

View File

@ -4,7 +4,7 @@
#
%define pkg conserver
%define ver 8.1.18
%define ver 8.1.19
# define the name of the machine on which the main conserver
# daemon will be running if you don't want to use the default

View File

@ -1,7 +1,7 @@
PKG="conserver"
NAME="Console server and client"
CATEGORY="system"
VERSION="8.1.18"
VERSION="8.1.19"
DESC="Console server and client"
CLASSES=none
ARCH=sparc

View File

@ -13,7 +13,8 @@
R set number of replay lines s spy mode (read only)
u show host status v show version info
w who is on this console x show console baud info
z suspend the connection | attach local command
? print this message <cr> ignore/abort command
^R replay the last line \ooo send character by octal code
z suspend the connection ! invoke task
| attach local command ? print this message
<cr> ignore/abort command ^R replay the last line
\ooo send character by octal code
[disconnect]

View File

@ -13,7 +13,8 @@
R set number of replay lines s spy mode (read only)
u show host status v show version info
w who is on this console x show console baud info
z suspend the connection | attach local command
? print this message <cr> ignore/abort command
^R replay the last line \ooo send character by octal code
z suspend the connection ! invoke task
| attach local command ? print this message
<cr> ignore/abort command ^R replay the last line
\ooo send character by octal code
[disconnect]