mirror of
https://github.com/bstansell/conserver.git
synced 2024-12-18 20:37:56 +00:00
Imported from conserver-8.1.19.tar.gz
This commit is contained in:
parent
64a2a77266
commit
b94c8967bf
32
CHANGES
32
CHANGES
@ -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 $
|
||||
#
|
||||
|
@ -1,4 +1,5 @@
|
||||
### Path settings
|
||||
datarootdir = @datarootdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
|
@ -1,4 +1,5 @@
|
||||
### Path settings
|
||||
datarootdir = @datarootdir@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
prefix = @prefix@
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
278
autologin/main.c
278
autologin/main.c
@ -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);
|
||||
}
|
||||
|
@ -12,4 +12,3 @@ extern char *pcCommand, *pcGroup, *pcLogin, *pcTty;
|
||||
/* from std_help.m */
|
||||
/* from std_version.m */
|
||||
/* from autologin.m */
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
21
configure.in
21
configure.in
@ -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,
|
||||
|
@ -1,4 +1,5 @@
|
||||
### Path settings
|
||||
datarootdir = @datarootdir@
|
||||
srcdir = @srcdir@
|
||||
prefix = @prefix@
|
||||
mandir = @mandir@
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
<A href=
|
||||
"http://conserver.linux-mirror.org/">Germany</A>
|
||||
<A href=
|
||||
"http://conserver.webdesign-zdg.de/">Germany</A>
|
||||
<A href="http://conserver.rayba.co/">Germany</A>
|
||||
<A href=
|
||||
"http://conserver.cybermirror.org/">Germany</A>
|
||||
<A href=
|
||||
"http://conserver.oss-mirror.org/">Ireland</A>
|
||||
<A href="http://conserver.shape.ws/">Malaysia</A>
|
||||
<A href="http://conserver.rinet.ru/">Russia</A>
|
||||
<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>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
### Path settings
|
||||
datarootdir = @datarootdir@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
prefix = @prefix@
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 *));
|
||||
|
@ -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
|
||||
|
@ -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
@ -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 *));
|
||||
|
@ -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)
|
||||
|
@ -1,4 +1,5 @@
|
||||
### Path settings
|
||||
datarootdir = @datarootdir@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
prefix = @prefix@
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
### Path settings
|
||||
datarootdir = @datarootdir@
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
prefix = @prefix@
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user