- (djm) OpenBSD CVS updates:

- markus@cvs.openbsd.org  2000/06/26 03:22:29
     [authfd.c]
     cleanup, less cut&paste
   - markus@cvs.openbsd.org  2000/06/26 15:59:19
     [servconf.c servconf.h session.c sshd.8 sshd.c]
     MaxStartups: limit number of unauthenticated connections, work by
     theo and me
   - deraadt@cvs.openbsd.org 2000/07/05 14:18:07
     [session.c]
     use no_x11_forwarding_flag correctly; provos ok
   - provos@cvs.openbsd.org  2000/07/05 15:35:57
     [sshd.c]
     typo
   - aaron@cvs.openbsd.org   2000/07/05 22:06:58
     [scp.1 ssh-agent.1 ssh-keygen.1 sshd.8]
     Insert more missing .El directives. Our troff really should identify
     these and spit out a warning.
   - todd@cvs.openbsd.org    2000/07/06 21:55:04
     [auth-rsa.c auth2.c ssh-keygen.c]
     clean code is good code
   - deraadt@cvs.openbsd.org 2000/07/07 02:14:29
     [serverloop.c]
     sense of port forwarding flag test was backwards
   - provos@cvs.openbsd.org  2000/07/08 17:17:31
     [compat.c readconf.c]
     replace strtok with strsep; from David Young <dyoung@onthejob.net>
   - deraadt@cvs.openbsd.org 2000/07/08 19:21:15
     [auth.h]
     KNF
   - ho@cvs.openbsd.org      2000/07/08 19:27:33
     [compat.c readconf.c]
     Better conditions for strsep() ending.
   - ho@cvs.openbsd.org      2000/07/10 10:27:05
     [readconf.c]
     Get the correct message on errors. (niels@ ok)
   - ho@cvs.openbsd.org      2000/07/10 10:30:25
     [cipher.c kex.c servconf.c]
     strtok() --> strsep(). (niels@ ok)
This commit is contained in:
Damien Miller 2000-07-11 17:31:38 +10:00
parent bc33bd44a2
commit 3702396526
19 changed files with 392 additions and 342 deletions

View File

@ -10,6 +10,45 @@
to compile on more platforms (incl NeXT).
- (djm) Added bsd-inet_aton and configure support for NeXT
- (djm) Misc NeXT fixes from Ben Lindstrom <mouring@pconline.com>
- (djm) OpenBSD CVS updates:
- markus@cvs.openbsd.org 2000/06/26 03:22:29
[authfd.c]
cleanup, less cut&paste
- markus@cvs.openbsd.org 2000/06/26 15:59:19
[servconf.c servconf.h session.c sshd.8 sshd.c]
MaxStartups: limit number of unauthenticated connections, work by
theo and me
- deraadt@cvs.openbsd.org 2000/07/05 14:18:07
[session.c]
use no_x11_forwarding_flag correctly; provos ok
- provos@cvs.openbsd.org 2000/07/05 15:35:57
[sshd.c]
typo
- aaron@cvs.openbsd.org 2000/07/05 22:06:58
[scp.1 ssh-agent.1 ssh-keygen.1 sshd.8]
Insert more missing .El directives. Our troff really should identify
these and spit out a warning.
- todd@cvs.openbsd.org 2000/07/06 21:55:04
[auth-rsa.c auth2.c ssh-keygen.c]
clean code is good code
- deraadt@cvs.openbsd.org 2000/07/07 02:14:29
[serverloop.c]
sense of port forwarding flag test was backwards
- provos@cvs.openbsd.org 2000/07/08 17:17:31
[compat.c readconf.c]
replace strtok with strsep; from David Young <dyoung@onthejob.net>
- deraadt@cvs.openbsd.org 2000/07/08 19:21:15
[auth.h]
KNF
- ho@cvs.openbsd.org 2000/07/08 19:27:33
[compat.c readconf.c]
Better conditions for strsep() ending.
- ho@cvs.openbsd.org 2000/07/10 10:27:05
[readconf.c]
Get the correct message on errors. (niels@ ok)
- ho@cvs.openbsd.org 2000/07/10 10:30:25
[cipher.c kex.c servconf.c]
strtok() --> strsep(). (niels@ ok)
20000709
- (djm) Only enable PAM_TTY kludge for Linux. Problem report from

View File

@ -16,7 +16,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rsa.c,v 1.26 2000/06/20 01:39:38 markus Exp $");
RCSID("$OpenBSD: auth-rsa.c,v 1.27 2000/07/07 03:55:03 todd Exp $");
#include "rsa.h"
#include "packet.h"
@ -179,8 +179,8 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
}
if (fail) {
fclose(f);
log(buf);
packet_send_debug(buf);
log("%s",buf);
packet_send_debug("%s",buf);
restore_uid();
return 0;
}

2
auth.h
View File

@ -7,7 +7,7 @@ void do_authentication2(void);
struct passwd *
auth_get_user(void);
int allowed_user(struct passwd * pw);;
int allowed_user(struct passwd * pw);
#define AUTH_FAIL_MAX 6
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)

View File

@ -27,7 +27,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: auth2.c,v 1.11 2000/06/19 00:50:11 markus Exp $");
RCSID("$OpenBSD: auth2.c,v 1.12 2000/07/07 03:55:03 todd Exp $");
#include <openssl/dsa.h>
#include <openssl/rsa.h>
@ -489,8 +489,8 @@ user_dsa_key_allowed(struct passwd *pw, Key *key)
}
}
if (fail) {
log(buf);
fclose(f);
log("%s",buf);
restore_uid();
return 0;
}

142
authfd.c
View File

@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfd.c,v 1.20 2000/06/20 01:39:38 markus Exp $");
RCSID("$OpenBSD: authfd.c,v 1.21 2000/06/26 09:22:29 markus Exp $");
#include "ssh.h"
#include "rsa.h"
@ -26,6 +26,9 @@ RCSID("$OpenBSD: authfd.c,v 1.20 2000/06/20 01:39:38 markus Exp $");
#include <openssl/rsa.h>
/* helper */
int ssh_agent_get_reply(AuthenticationConnection *auth);
/* Returns the number of the authentication fd, or -1 if there is none. */
int
@ -344,7 +347,7 @@ ssh_add_identity(AuthenticationConnection *auth,
{
Buffer buffer;
unsigned char buf[8192];
int len, l, type;
int len;
/* Format a message to the agent. */
buffer_init(&buffer);
@ -368,57 +371,11 @@ ssh_add_identity(AuthenticationConnection *auth,
atomicio(write, auth->fd, buffer_ptr(&buffer),
buffer_len(&buffer)) != buffer_len(&buffer)) {
error("Error writing to authentication socket.");
error_cleanup:
buffer_free(&buffer);
return 0;
}
/* Wait for response from the agent. First read the length of the
response packet. */
len = 4;
while (len > 0) {
l = read(auth->fd, buf + 4 - len, len);
if (l <= 0) {
error("Error reading response length from authentication socket.");
goto error_cleanup;
}
len -= l;
}
/* Extract the length, and check it for sanity. */
len = GET_32BIT(buf);
if (len > 256 * 1024)
fatal("Add identity response too long: %d", len);
/* Read the rest of the response in tothe buffer. */
buffer_clear(&buffer);
while (len > 0) {
l = len;
if (l > sizeof(buf))
l = sizeof(buf);
l = read(auth->fd, buf, l);
if (l <= 0) {
error("Error reading response from authentication socket.");
goto error_cleanup;
}
buffer_append(&buffer, (char *) buf, l);
len -= l;
}
/* Get the type of the packet. */
type = buffer_get_char(&buffer);
switch (type) {
case SSH_AGENT_FAILURE:
buffer_free(&buffer);
return 0;
case SSH_AGENT_SUCCESS:
buffer_free(&buffer);
return 1;
default:
fatal("Bad response to add identity from authentication agent: %d",
type);
}
/* NOTREACHED */
return 0;
buffer_free(&buffer);
return ssh_agent_get_reply(auth);
}
/*
@ -430,8 +387,8 @@ int
ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
{
Buffer buffer;
unsigned char buf[8192];
int len, l, type;
unsigned char buf[5];
int len;
/* Format a message to the agent. */
buffer_init(&buffer);
@ -449,59 +406,11 @@ ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
atomicio(write, auth->fd, buffer_ptr(&buffer),
buffer_len(&buffer)) != buffer_len(&buffer)) {
error("Error writing to authentication socket.");
error_cleanup:
buffer_free(&buffer);
return 0;
}
/*
* Wait for response from the agent. First read the length of the
* response packet.
*/
len = 4;
while (len > 0) {
l = read(auth->fd, buf + 4 - len, len);
if (l <= 0) {
error("Error reading response length from authentication socket.");
goto error_cleanup;
}
len -= l;
}
/* Extract the length, and check it for sanity. */
len = GET_32BIT(buf);
if (len > 256 * 1024)
fatal("Remove identity response too long: %d", len);
/* Read the rest of the response in tothe buffer. */
buffer_clear(&buffer);
while (len > 0) {
l = len;
if (l > sizeof(buf))
l = sizeof(buf);
l = read(auth->fd, buf, l);
if (l <= 0) {
error("Error reading response from authentication socket.");
goto error_cleanup;
}
buffer_append(&buffer, (char *) buf, l);
len -= l;
}
/* Get the type of the packet. */
type = buffer_get_char(&buffer);
switch (type) {
case SSH_AGENT_FAILURE:
buffer_free(&buffer);
return 0;
case SSH_AGENT_SUCCESS:
buffer_free(&buffer);
return 1;
default:
fatal("Bad response to remove identity from authentication agent: %d",
type);
}
/* NOTREACHED */
return 0;
buffer_free(&buffer);
return ssh_agent_get_reply(auth);
}
/*
@ -512,9 +421,7 @@ error_cleanup:
int
ssh_remove_all_identities(AuthenticationConnection *auth)
{
Buffer buffer;
unsigned char buf[8192];
int len, l, type;
unsigned char buf[5];
/* Get the length of the message, and format it in the buffer. */
PUT_32BIT(buf, 1);
@ -525,6 +432,20 @@ ssh_remove_all_identities(AuthenticationConnection *auth)
error("Error writing to authentication socket.");
return 0;
}
return ssh_agent_get_reply(auth);
}
/*
* Read for reply from agent. returns 1 for success, 0 on error
*/
int
ssh_agent_get_reply(AuthenticationConnection *auth)
{
Buffer buffer;
unsigned char buf[8192];
int len, l, type;
/*
* Wait for response from the agent. First read the length of the
* response packet.
@ -534,6 +455,7 @@ ssh_remove_all_identities(AuthenticationConnection *auth)
l = read(auth->fd, buf + 4 - len, len);
if (l <= 0) {
error("Error reading response length from authentication socket.");
buffer_free(&buffer);
return 0;
}
len -= l;
@ -542,9 +464,9 @@ ssh_remove_all_identities(AuthenticationConnection *auth)
/* Extract the length, and check it for sanity. */
len = GET_32BIT(buf);
if (len > 256 * 1024)
fatal("Remove identity response too long: %d", len);
fatal("Response from agent too long: %d", len);
/* Read the rest of the response into the buffer. */
/* Read the rest of the response in to the buffer. */
buffer_init(&buffer);
while (len > 0) {
l = len;
@ -562,16 +484,14 @@ ssh_remove_all_identities(AuthenticationConnection *auth)
/* Get the type of the packet. */
type = buffer_get_char(&buffer);
buffer_free(&buffer);
switch (type) {
case SSH_AGENT_FAILURE:
buffer_free(&buffer);
return 0;
case SSH_AGENT_SUCCESS:
buffer_free(&buffer);
return 1;
default:
fatal("Bad response to remove identity from authentication agent: %d",
type);
fatal("Bad response from authentication agent: %d", type);
}
/* NOTREACHED */
return 0;

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: cipher.c,v 1.28 2000/06/20 01:39:40 markus Exp $");
RCSID("$OpenBSD: cipher.c,v 1.29 2000/07/10 16:30:25 ho Exp $");
#include "ssh.h"
#include "cipher.h"
@ -174,14 +174,15 @@ cipher_name(int cipher)
int
ciphers_valid(const char *names)
{
char *ciphers;
char *ciphers, *cp;
char *p;
int i;
if (names == NULL || strcmp(names, "") == 0)
return 0;
ciphers = xstrdup(names);
for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) {
ciphers = cp = xstrdup(names);
for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
(p = strsep(&cp, CIPHER_SEP))) {
i = cipher_number(p);
if (i == -1 || !(cipher_mask2() & (1 << i))) {
xfree(ciphers);

View File

@ -28,7 +28,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: compat.c,v 1.17 2000/06/20 01:39:40 markus Exp $");
RCSID("$OpenBSD: compat.c,v 1.19 2000/07/09 01:27:32 ho Exp $");
#include "ssh.h"
#include "packet.h"
@ -81,13 +81,13 @@ compat_datafellows(const char *version)
int
proto_spec(const char *spec)
{
char *s, *p;
char *s, *p, *q;
int ret = SSH_PROTO_UNKNOWN;
if (spec == NULL)
return ret;
s = xstrdup(spec);
for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) {
q = s = xstrdup(spec);
for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
switch(atoi(p)) {
case 1:
if (ret == SSH_PROTO_UNKNOWN)

14
kex.c
View File

@ -28,7 +28,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: kex.c,v 1.8 2000/06/20 01:39:41 markus Exp $");
RCSID("$OpenBSD: kex.c,v 1.9 2000/07/10 16:30:25 ho Exp $");
#include "ssh.h"
#include "ssh2.h"
@ -287,13 +287,14 @@ char *
get_match(char *client, char *server)
{
char *sproposals[MAX_PROP];
char *c, *s, *p, *ret;
char *c, *s, *p, *ret, *cp, *sp;
int i, j, nproposals;
c = xstrdup(client);
s = xstrdup(server);
c = cp = xstrdup(client);
s = sp = xstrdup(server);
for ((p = strtok(s, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
(p = strsep(&sp, SEP)), i++) {
if (i < MAX_PROP)
sproposals[i] = p;
else
@ -301,7 +302,8 @@ get_match(char *client, char *server)
}
nproposals = i;
for ((p = strtok(c, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) {
for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
(p = strsep(&cp, SEP)), i++) {
for (j = 0; j < nproposals; j++) {
if (strcmp(p, sproposals[j]) == 0) {
ret = xstrdup(p);

View File

@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.37 2000/06/20 01:39:43 markus Exp $");
RCSID("$OpenBSD: readconf.c,v 1.40 2000/07/10 16:27:05 ho Exp $");
#include "ssh.h"
#include "cipher.h"
@ -164,7 +164,7 @@ static struct {
{ NULL, 0 }
};
/* Characters considered whitespace in strtok calls. */
/* Characters considered whitespace in strsep calls. */
#define WHITESPACE " \t\r\n="
@ -237,18 +237,18 @@ process_config_line(Options *options, const char *host,
char *line, const char *filename, int linenum,
int *activep)
{
char buf[256], *cp, *string, **charptr, *cp2;
char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg;
int opcode, *intptr, value;
u_short fwd_port, fwd_host_port;
/* Skip leading whitespace. */
cp = line + strspn(line, WHITESPACE);
if (!*cp || *cp == '\n' || *cp == '#')
s = line + strspn(line, WHITESPACE);
if (!*s || *s == '\n' || *s == '#')
return 0;
/* Get the keyword. (Each line is supposed to begin with a keyword). */
cp = strtok(cp, WHITESPACE);
opcode = parse_token(cp, filename, linenum);
keyword = strsep(&s, WHITESPACE);
opcode = parse_token(keyword, filename, linenum);
switch (opcode) {
case oBadOption:
@ -258,13 +258,13 @@ process_config_line(Options *options, const char *host,
case oForwardAgent:
intptr = &options->forward_agent;
parse_flag:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
value = 0; /* To avoid compiler warning... */
if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
value = 1;
else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
value = 0;
else
fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
@ -344,16 +344,16 @@ parse_flag:
case oStrictHostKeyChecking:
intptr = &options->strict_host_key_checking;
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing yes/no argument.",
filename, linenum);
value = 0; /* To avoid compiler warning... */
if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
value = 1;
else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
value = 0;
else if (strcmp(cp, "ask") == 0)
else if (strcmp(arg, "ask") == 0)
value = 2;
else
fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
@ -379,8 +379,8 @@ parse_flag:
case oIdentityFile:
case oIdentityFile2:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (*activep) {
intptr = (opcode == oIdentityFile) ?
@ -392,7 +392,7 @@ parse_flag:
charptr = (opcode == oIdentityFile) ?
&options->identity_files[*intptr] :
&options->identity_files2[*intptr];
*charptr = xstrdup(cp);
*charptr = xstrdup(arg);
*intptr = *intptr + 1;
}
break;
@ -404,11 +404,11 @@ parse_flag:
case oUser:
charptr = &options->user;
parse_string:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(cp);
*charptr = xstrdup(arg);
break;
case oGlobalKnownHostsFile:
@ -434,10 +434,10 @@ parse_string:
case oProxyCommand:
charptr = &options->proxy_command;
string = xstrdup("");
while ((cp = strtok(NULL, WHITESPACE)) != NULL) {
string = xrealloc(string, strlen(string) + strlen(cp) + 2);
while ((arg = strsep(&s, WHITESPACE)) != NULL && *arg != '\0') {
string = xrealloc(string, strlen(string) + strlen(arg) + 2);
strcat(string, " ");
strcat(string, cp);
strcat(string, arg);
}
if (*activep && *charptr == NULL)
*charptr = string;
@ -448,15 +448,15 @@ parse_string:
case oPort:
intptr = &options->port;
parse_int:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (cp[0] < '0' || cp[0] > '9')
if (arg[0] < '0' || arg[0] > '9')
fatal("%.200s line %d: Bad number.", filename, linenum);
/* Octal, decimal, or hex format? */
value = strtol(cp, &cp2, 0);
if (cp == cp2)
value = strtol(arg, &endofnumber, 0);
if (arg == endofnumber)
fatal("%.200s line %d: Bad number.", filename, linenum);
if (*activep && *intptr == -1)
*intptr = value;
@ -468,65 +468,65 @@ parse_int:
case oCipher:
intptr = &options->cipher;
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
value = cipher_number(cp);
value = cipher_number(arg);
if (value == -1)
fatal("%.200s line %d: Bad cipher '%s'.",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *intptr == -1)
*intptr = value;
break;
case oCiphers:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (!ciphers_valid(cp))
if (!ciphers_valid(arg))
fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (*activep && options->ciphers == NULL)
options->ciphers = xstrdup(cp);
options->ciphers = xstrdup(arg);
break;
case oProtocol:
intptr = &options->protocol;
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
value = proto_spec(cp);
value = proto_spec(arg);
if (value == SSH_PROTO_UNKNOWN)
fatal("%.200s line %d: Bad protocol spec '%s'.",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *intptr == SSH_PROTO_UNKNOWN)
*intptr = value;
break;
case oLogLevel:
intptr = (int *) &options->log_level;
cp = strtok(NULL, WHITESPACE);
value = log_level_number(cp);
arg = strsep(&s, WHITESPACE);
value = log_level_number(arg);
if (value == (LogLevel) - 1)
fatal("%.200s line %d: unsupported log level '%s'\n",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (*activep && (LogLevel) * intptr == -1)
*intptr = (LogLevel) value;
break;
case oRemoteForward:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (cp[0] < '0' || cp[0] > '9')
if (arg[0] < '0' || arg[0] > '9')
fatal("%.200s line %d: Badly formatted port number.",
filename, linenum);
fwd_port = atoi(cp);
cp = strtok(NULL, WHITESPACE);
if (!cp)
fwd_port = atoi(arg);
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing second argument.",
filename, linenum);
if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
fatal("%.200s line %d: Badly formatted host:port.",
filename, linenum);
if (*activep)
@ -534,18 +534,18 @@ parse_int:
break;
case oLocalForward:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (cp[0] < '0' || cp[0] > '9')
if (arg[0] < '0' || arg[0] > '9')
fatal("%.200s line %d: Badly formatted port number.",
filename, linenum);
fwd_port = atoi(cp);
cp = strtok(NULL, WHITESPACE);
if (!cp)
fwd_port = atoi(arg);
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing second argument.",
filename, linenum);
if (sscanf(cp, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
if (sscanf(arg, "%255[^:]:%hu", buf, &fwd_host_port) != 2)
fatal("%.200s line %d: Badly formatted host:port.",
filename, linenum);
if (*activep)
@ -554,26 +554,26 @@ parse_int:
case oHost:
*activep = 0;
while ((cp = strtok(NULL, WHITESPACE)) != NULL)
if (match_pattern(host, cp)) {
debug("Applying options for %.100s", cp);
while ((arg = strsep(&s, WHITESPACE)) != NULL && *arg != '\0')
if (match_pattern(host, arg)) {
debug("Applying options for %.100s", arg);
*activep = 1;
break;
}
/* Avoid garbage check below, as strtok already returned NULL. */
/* Avoid garbage check below, as strsep is done. */
return 0;
case oEscapeChar:
intptr = &options->escape_char;
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&s, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (cp[0] == '^' && cp[2] == 0 &&
(unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128)
value = (unsigned char) cp[1] & 31;
else if (strlen(cp) == 1)
value = (unsigned char) cp[0];
else if (strcmp(cp, "none") == 0)
if (arg[0] == '^' && arg[2] == 0 &&
(unsigned char) arg[1] >= 64 && (unsigned char) arg[1] < 128)
value = (unsigned char) arg[1] & 31;
else if (strlen(arg) == 1)
value = (unsigned char) arg[0];
else if (strcmp(arg, "none") == 0)
value = -2;
else {
fatal("%.200s line %d: Bad escape character.",
@ -590,9 +590,11 @@ parse_int:
}
/* Check that there is no garbage at end of line. */
if (strtok(NULL, WHITESPACE) != NULL)
fatal("%.200s line %d: garbage at end of line.",
filename, linenum);
if ((arg = strsep(&s, WHITESPACE)) != NULL && *arg != '\0')
{
fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
filename, linenum, arg);
}
return 0;
}

3
scp.1
View File

@ -9,7 +9,7 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
.\" $Id: scp.1,v 1.7 2000/04/13 02:26:37 damien Exp $
.\" $Id: scp.1,v 1.8 2000/07/11 07:31:38 djm Exp $
.\"
.Dd September 25, 1999
.Dt SCP 1
@ -106,6 +106,7 @@ to use IPv4 addresses only.
Forces
.Nm
to use IPv6 addresses only.
.El
.Sh AUTHORS
Timo Rinne <tri@iki.fi> and Tatu Ylonen <ylo@cs.hut.fi>
.Sh HISTORY

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: servconf.c,v 1.45 2000/06/20 01:39:44 markus Exp $");
RCSID("$OpenBSD: servconf.c,v 1.47 2000/07/10 16:30:25 ho Exp $");
#include "ssh.h"
#include "servconf.h"
@ -76,6 +76,7 @@ initialize_server_options(ServerOptions *options)
options->protocol = SSH_PROTO_UNKNOWN;
options->gateway_ports = -1;
options->num_subsystems = 0;
options->max_startups = -1;
}
void
@ -159,6 +160,8 @@ fill_default_server_options(ServerOptions *options)
options->protocol = SSH_PROTO_1|SSH_PROTO_2;
if (options->gateway_ports == -1)
options->gateway_ports = 0;
if (options->max_startups == -1)
options->max_startups = 10;
}
#define WHITESPACE " \t\r\n="
@ -183,7 +186,7 @@ typedef enum {
sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem
sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups
} ServerOpCodes;
/* Textual representation of the tokens. */
@ -239,6 +242,7 @@ static struct {
{ "protocol", sProtocol },
{ "gatewayports", sGatewayPorts },
{ "subsystem", sSubsystem },
{ "maxstartups", sMaxStartups },
{ NULL, 0 }
};
@ -300,7 +304,7 @@ read_server_config(ServerOptions *options, const char *filename)
{
FILE *f;
char line[1024];
char *cp, **charptr;
char *cp, **charptr, *arg;
int linenum, *intptr, value;
int bad_options = 0;
ServerOpCodes opcode;
@ -317,8 +321,8 @@ read_server_config(ServerOptions *options, const char *filename)
cp = line + strspn(line, WHITESPACE);
if (!*cp || *cp == '#')
continue;
cp = strtok(cp, WHITESPACE);
opcode = parse_token(cp, filename, linenum);
arg = strsep(&cp, WHITESPACE);
opcode = parse_token(arg, filename, linenum);
switch (opcode) {
case sBadOption:
bad_options++;
@ -333,23 +337,23 @@ read_server_config(ServerOptions *options, const char *filename)
if (options->num_ports >= MAX_PORTS)
fatal("%s line %d: too many ports.\n",
filename, linenum);
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%s line %d: missing port number.\n",
filename, linenum);
options->ports[options->num_ports++] = atoi(cp);
options->ports[options->num_ports++] = atoi(arg);
break;
case sServerKeyBits:
intptr = &options->server_key_bits;
parse_int:
cp = strtok(NULL, WHITESPACE);
if (!cp) {
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0') {
fprintf(stderr, "%s line %d: missing integer value.\n",
filename, linenum);
exit(1);
}
value = atoi(cp);
value = atoi(arg);
if (*intptr == -1)
*intptr = value;
break;
@ -363,11 +367,11 @@ parse_int:
goto parse_int;
case sListenAddress:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%s line %d: missing inet addr.\n",
filename, linenum);
add_listen_addr(options, cp);
add_listen_addr(options, arg);
break;
case sHostKeyFile:
@ -375,14 +379,14 @@ parse_int:
charptr = (opcode == sHostKeyFile ) ?
&options->host_key_file : &options->host_dsa_key_file;
parse_filename:
cp = strtok(NULL, WHITESPACE);
if (!cp) {
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0') {
fprintf(stderr, "%s line %d: missing file name.\n",
filename, linenum);
exit(1);
}
if (*charptr == NULL)
*charptr = tilde_expand_filename(cp, getuid());
*charptr = tilde_expand_filename(arg, getuid());
break;
case sPidFile:
@ -392,26 +396,26 @@ parse_filename:
case sRandomSeedFile:
fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
filename, linenum);
cp = strtok(NULL, WHITESPACE);
arg = strsep(&cp, WHITESPACE);
break;
case sPermitRootLogin:
intptr = &options->permit_root_login;
cp = strtok(NULL, WHITESPACE);
if (!cp) {
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0') {
fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
filename, linenum);
exit(1);
}
if (strcmp(cp, "without-password") == 0)
if (strcmp(arg, "without-password") == 0)
value = 2;
else if (strcmp(cp, "yes") == 0)
else if (strcmp(arg, "yes") == 0)
value = 1;
else if (strcmp(cp, "no") == 0)
else if (strcmp(arg, "no") == 0)
value = 0;
else {
fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
filename, linenum, cp);
filename, linenum, arg);
exit(1);
}
if (*intptr == -1)
@ -421,19 +425,19 @@ parse_filename:
case sIgnoreRhosts:
intptr = &options->ignore_rhosts;
parse_flag:
cp = strtok(NULL, WHITESPACE);
if (!cp) {
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0') {
fprintf(stderr, "%s line %d: missing yes/no argument.\n",
filename, linenum);
exit(1);
}
if (strcmp(cp, "yes") == 0)
if (strcmp(arg, "yes") == 0)
value = 1;
else if (strcmp(cp, "no") == 0)
else if (strcmp(arg, "no") == 0)
value = 0;
else {
fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
filename, linenum, cp);
filename, linenum, arg);
exit(1);
}
if (*intptr == -1)
@ -536,82 +540,82 @@ parse_flag:
case sLogFacility:
intptr = (int *) &options->log_facility;
cp = strtok(NULL, WHITESPACE);
value = log_facility_number(cp);
arg = strsep(&cp, WHITESPACE);
value = log_facility_number(arg);
if (value == (SyslogFacility) - 1)
fatal("%.200s line %d: unsupported log facility '%s'\n",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (*intptr == -1)
*intptr = (SyslogFacility) value;
break;
case sLogLevel:
intptr = (int *) &options->log_level;
cp = strtok(NULL, WHITESPACE);
value = log_level_number(cp);
arg = strsep(&cp, WHITESPACE);
value = log_level_number(arg);
if (value == (LogLevel) - 1)
fatal("%.200s line %d: unsupported log level '%s'\n",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (*intptr == -1)
*intptr = (LogLevel) value;
break;
case sAllowUsers:
while ((cp = strtok(NULL, WHITESPACE))) {
while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') {
if (options->num_allow_users >= MAX_ALLOW_USERS)
fatal("%s line %d: too many allow users.\n",
filename, linenum);
options->allow_users[options->num_allow_users++] = xstrdup(cp);
options->allow_users[options->num_allow_users++] = xstrdup(arg);
}
break;
case sDenyUsers:
while ((cp = strtok(NULL, WHITESPACE))) {
while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') {
if (options->num_deny_users >= MAX_DENY_USERS)
fatal( "%s line %d: too many deny users.\n",
filename, linenum);
options->deny_users[options->num_deny_users++] = xstrdup(cp);
options->deny_users[options->num_deny_users++] = xstrdup(arg);
}
break;
case sAllowGroups:
while ((cp = strtok(NULL, WHITESPACE))) {
while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') {
if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
fatal("%s line %d: too many allow groups.\n",
filename, linenum);
options->allow_groups[options->num_allow_groups++] = xstrdup(cp);
options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
}
break;
case sDenyGroups:
while ((cp = strtok(NULL, WHITESPACE))) {
while ((arg = strsep(&cp, WHITESPACE)) && *arg != '\0') {
if (options->num_deny_groups >= MAX_DENY_GROUPS)
fatal("%s line %d: too many deny groups.\n",
filename, linenum);
options->deny_groups[options->num_deny_groups++] = xstrdup(cp);
options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
}
break;
case sCiphers:
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.", filename, linenum);
if (!ciphers_valid(cp))
if (!ciphers_valid(arg))
fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (options->ciphers == NULL)
options->ciphers = xstrdup(cp);
options->ciphers = xstrdup(arg);
break;
case sProtocol:
intptr = &options->protocol;
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing argument.", filename, linenum);
value = proto_spec(cp);
value = proto_spec(arg);
if (value == SSH_PROTO_UNKNOWN)
fatal("%s line %d: Bad protocol spec '%s'.",
filename, linenum, cp ? cp : "<NONE>");
filename, linenum, arg ? arg : "<NONE>");
if (*intptr == SSH_PROTO_UNKNOWN)
*intptr = value;
break;
@ -621,31 +625,36 @@ parse_flag:
fatal("%s line %d: too many subsystems defined.",
filename, linenum);
}
cp = strtok(NULL, WHITESPACE);
if (!cp)
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing subsystem name.",
filename, linenum);
for (i = 0; i < options->num_subsystems; i++)
if(strcmp(cp, options->subsystem_name[i]) == 0)
if(strcmp(arg, options->subsystem_name[i]) == 0)
fatal("%s line %d: Subsystem '%s' already defined.",
filename, linenum, cp);
options->subsystem_name[options->num_subsystems] = xstrdup(cp);
cp = strtok(NULL, WHITESPACE);
if (!cp)
filename, linenum, arg);
options->subsystem_name[options->num_subsystems] = xstrdup(arg);
arg = strsep(&cp, WHITESPACE);
if (!arg || *arg == '\0')
fatal("%s line %d: Missing subsystem command.",
filename, linenum);
options->subsystem_command[options->num_subsystems] = xstrdup(cp);
options->subsystem_command[options->num_subsystems] = xstrdup(arg);
options->num_subsystems++;
break;
case sMaxStartups:
intptr = &options->max_startups;
goto parse_int;
default:
fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
filename, linenum, cp, opcode);
filename, linenum, arg, opcode);
exit(1);
}
if (strtok(NULL, WHITESPACE) != NULL) {
fprintf(stderr, "%s line %d: garbage at end of line.\n",
filename, linenum);
if ((arg = strsep(&cp, WHITESPACE)) != NULL && *arg != '\0') {
fprintf(stderr,
"%s line %d: garbage at end of line; \"%.200s\".\n",
filename, linenum, arg);
exit(1);
}
}

View File

@ -13,7 +13,7 @@
*
*/
/* RCSID("$OpenBSD: servconf.h,v 1.25 2000/06/20 01:39:44 markus Exp $"); */
/* RCSID("$OpenBSD: servconf.h,v 1.26 2000/06/26 21:59:18 markus Exp $"); */
#ifndef SERVCONF_H
#define SERVCONF_H
@ -99,6 +99,9 @@ typedef struct {
unsigned int num_subsystems;
char *subsystem_name[MAX_SUBSYSTEMS];
char *subsystem_command[MAX_SUBSYSTEMS];
int max_startups;
} ServerOptions;
/*
* Initializes the server options to special values that indicate that they

View File

@ -722,7 +722,7 @@ input_direct_tcpip(void)
originator, originator_port, target, target_port);
/* XXX check permission */
if (! no_port_forwarding_flag) {
if (no_port_forwarding_flag) {
xfree(target);
xfree(originator);
return -1;

View File

@ -8,10 +8,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: session.c,v 1.20 2000/06/18 04:42:54 markus Exp $");
#if defined(HAVE_USERSEC_H)
#include <usersec.h>
#endif
RCSID("$OpenBSD: session.c,v 1.22 2000/07/05 20:18:07 deraadt Exp $");
#include "xmalloc.h"
#include "ssh.h"
@ -35,6 +32,10 @@ RCSID("$OpenBSD: session.c,v 1.20 2000/06/18 04:42:54 markus Exp $");
#include <proj.h>
#endif /* WITH_IRIX_PROJECT */
#if defined(HAVE_USERSEC_H)
#include <usersec.h>
#endif
#ifdef HAVE_OSF_SIA
# include <sia.h>
# include <siad.h>
@ -90,6 +91,8 @@ static const char *__progname = "sshd";
extern int log_stderr;
extern int debug_flag;
extern int startup_pipe;
/* Local Xauthority file. */
static char *xauthfile;
@ -166,6 +169,7 @@ do_authenticated(struct passwd * pw)
* authentication.
*/
alarm(0);
close(startup_pipe);
/*
* Inform the channel mechanism that we are the server side and that
@ -1457,7 +1461,7 @@ session_subsystem_req(Session *s)
int
session_x11_req(Session *s)
{
if (!no_port_forwarding_flag) {
if (no_x11_forwarding_flag) {
debug("X11 forwarding disabled in user configuration file.");
return 0;
}
@ -1788,6 +1792,7 @@ do_authenticated2(void)
* authentication.
*/
alarm(0);
close(startup_pipe);
server_loop2();
if (xauthfile)
xauthfile_cleanup_proc(NULL);

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-agent.1,v 1.12 2000/05/03 18:04:39 markus Exp $
.\" $OpenBSD: ssh-agent.1,v 1.13 2000/07/06 04:06:56 aaron Exp $
.\"
.\" -*- nroff -*-
.\"
@ -133,6 +133,7 @@ Unix-domain sockets used to contain the connection to the
authentication agent.
These sockets should only be readable by the owner.
The sockets should get automatically removed when the agent exits.
.El
.Sh AUTHOR
Tatu Ylonen <ylo@cs.hut.fi>
.Pp

View File

@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 23:55:14 1995 ylo
.\"
.\" $Id: ssh-keygen.1,v 1.15 2000/05/09 01:03:02 damien Exp $
.\" $Id: ssh-keygen.1,v 1.16 2000/07/11 07:31:38 djm Exp $
.\"
.Dd September 25, 1999
.Dt SSH-KEYGEN 1
@ -188,6 +188,7 @@ The contents of this file should be added to
on all machines
where you wish to log in using DSA authentication.
There is no need to keep the contents of this file secret.
.El
.Sh AUTHOR
Tatu Ylonen <ylo@cs.hut.fi>
.Pp

View File

@ -7,7 +7,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keygen.c,v 1.27 2000/06/20 01:39:44 markus Exp $");
RCSID("$OpenBSD: ssh-keygen.c,v 1.28 2000/07/07 03:55:04 todd Exp $");
#include <openssl/evp.h>
#include <openssl/pem.h>
@ -127,13 +127,13 @@ do_convert_to_ssh2(struct passwd *pw)
exit(1);
}
dsa_make_key_blob(k, &blob, &len);
fprintf(stdout, SSH_COM_MAGIC_BEGIN "\n");
fprintf(stdout, "%s\n", SSH_COM_MAGIC_BEGIN);
fprintf(stdout,
"Comment: \"%d-bit DSA, converted from openssh by %s@%s\"\n",
BN_num_bits(k->dsa->p),
pw->pw_name, hostname);
dump_base64(stdout, blob, len);
fprintf(stdout, SSH_COM_MAGIC_END "\n");
fprintf(stdout, "%s\n", SSH_COM_MAGIC_END);
key_free(k);
xfree(blob);
exit(0);

11
sshd.8
View File

@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
.\" $Id: sshd.8,v 1.24 2000/06/18 04:50:45 djm Exp $
.\" $Id: sshd.8,v 1.25 2000/07/11 07:31:39 djm Exp $
.\"
.Dd September 25, 1999
.Dt SSHD 8
@ -435,6 +435,14 @@ QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
The default is INFO.
Logging with level DEBUG violates the privacy of users
and is not recommended.
.It Cm MaxStartups
Specifies the maximum number of concurrent unauthenticated connections to the
.Nm
daemon.
Additional connections will be dropped until authentication succeeds or the
.Cm LoginGraceTime
expires for a connection.
The default is 10.
.It Cm PasswordAuthentication
Specifies whether password authentication is allowed.
The default is
@ -954,6 +962,7 @@ Like
This can be used to specify
machine-specific login-time initializations globally.
This file should be writable only by root, and should be world-readable.
.El
.Sh AUTHOR
OpenSSH
is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen,

173
sshd.c
View File

@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshd.c,v 1.119 2000/06/22 16:32:27 markus Exp $");
RCSID("$OpenBSD: sshd.c,v 1.121 2000/07/05 21:35:56 provos Exp $");
#include "xmalloc.h"
#include "rsa.h"
@ -350,7 +350,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
break;
}
if (remote_minor < 3) {
packet_disconnect("Your ssh version is too old and"
packet_disconnect("Your ssh version is too old and "
"is no longer supported. Please install a newer version.");
} else if (remote_minor == 3) {
/* note that this disables agent-forwarding */
@ -400,6 +400,9 @@ destroy_sensitive_data(void)
key_free(sensitive_data.dsa_host_key);
}
int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */
int startup_pipe; /* in child */
/*
* Main program for the daemon.
*/
@ -408,7 +411,7 @@ main(int ac, char **av)
{
extern char *optarg;
extern int optind;
int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1;
int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1;
pid_t pid;
socklen_t fromlen;
int silent = 0;
@ -421,6 +424,8 @@ main(int ac, char **av)
struct addrinfo *ai;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
int listen_sock, maxfd;
int startup_p[2];
int startups = 0;
init_rng();
@ -746,6 +751,7 @@ main(int ac, char **av)
/* Arrange to restart on SIGHUP. The handler needs listen_sock. */
signal(SIGHUP, sighup_handler);
signal(SIGTERM, sigterm_handler);
signal(SIGQUIT, sigterm_handler);
@ -753,12 +759,15 @@ main(int ac, char **av)
signal(SIGCHLD, main_sigchld_handler);
/* setup fd set for listen */
fdset = NULL;
maxfd = 0;
for (i = 0; i < num_listen_socks; i++)
if (listen_socks[i] > maxfd)
maxfd = listen_socks[i];
fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
fdset = (fd_set *)xmalloc(fdsetsz);
/* pipes connected to unauthenticated childs */
startup_pipes = xmalloc(options.max_startups * sizeof(int));
for (i = 0; i < options.max_startups; i++)
startup_pipes[i] = -1;
/*
* Stay listening for connections until the system crashes or
@ -767,80 +776,128 @@ main(int ac, char **av)
for (;;) {
if (received_sighup)
sighup_restart();
/* Wait in select until there is a connection. */
if (fdset != NULL)
xfree(fdset);
fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
fdset = (fd_set *)xmalloc(fdsetsz);
memset(fdset, 0, fdsetsz);
for (i = 0; i < num_listen_socks; i++)
FD_SET(listen_socks[i], fdset);
for (i = 0; i < options.max_startups; i++)
if (startup_pipes[i] != -1)
FD_SET(startup_pipes[i], fdset);
/* Wait in select until there is a connection. */
if (select(maxfd + 1, fdset, NULL, NULL, NULL) < 0) {
if (errno != EINTR)
error("select: %.100s", strerror(errno));
continue;
}
for (i = 0; i < options.max_startups; i++)
if (startup_pipes[i] != -1 &&
FD_ISSET(startup_pipes[i], fdset)) {
/*
* the read end of the pipe is ready
* if the child has closed the pipe
* after successfull authentication
* or if the child has died
*/
close(startup_pipes[i]);
startup_pipes[i] = -1;
startups--;
}
for (i = 0; i < num_listen_socks; i++) {
if (!FD_ISSET(listen_socks[i], fdset))
continue;
fromlen = sizeof(from);
newsock = accept(listen_socks[i], (struct sockaddr *)&from,
&fromlen);
if (newsock < 0) {
if (errno != EINTR && errno != EWOULDBLOCK)
error("accept: %.100s", strerror(errno));
continue;
}
if (fcntl(newsock, F_SETFL, 0) < 0) {
error("newsock del O_NONBLOCK: %s", strerror(errno));
continue;
}
/*
* Got connection. Fork a child to handle it, unless
* we are in debugging mode.
*/
if (debug_flag) {
fromlen = sizeof(from);
newsock = accept(listen_socks[i], (struct sockaddr *)&from,
&fromlen);
if (newsock < 0) {
if (errno != EINTR && errno != EWOULDBLOCK)
error("accept: %.100s", strerror(errno));
continue;
}
if (fcntl(newsock, F_SETFL, 0) < 0) {
error("newsock del O_NONBLOCK: %s", strerror(errno));
continue;
}
if (startups >= options.max_startups) {
close(newsock);
continue;
}
if (pipe(startup_p) == -1) {
close(newsock);
continue;
}
for (j = 0; j < options.max_startups; j++)
if (startup_pipes[j] == -1) {
startup_pipes[j] = startup_p[0];
if (maxfd < startup_p[0])
maxfd = startup_p[0];
startups++;
break;
}
/*
* In debugging mode. Close the listening
* socket, and start processing the
* connection without forking.
* Got connection. Fork a child to handle it, unless
* we are in debugging mode.
*/
debug("Server will not fork when running in debugging mode.");
close_listen_socks();
sock_in = newsock;
sock_out = newsock;
pid = getpid();
break;
} else {
/*
* Normal production daemon. Fork, and have
* the child process the connection. The
* parent continues listening.
*/
if ((pid = fork()) == 0) {
if (debug_flag) {
/*
* Child. Close the listening socket, and start using the
* accepted socket. Reinitialize logging (since our pid has
* changed). We break out of the loop to handle the connection.
* In debugging mode. Close the listening
* socket, and start processing the
* connection without forking.
*/
debug("Server will not fork when running in debugging mode.");
close_listen_socks();
sock_in = newsock;
sock_out = newsock;
log_init(av0, options.log_level, options.log_facility, log_stderr);
pid = getpid();
break;
} else {
/*
* Normal production daemon. Fork, and have
* the child process the connection. The
* parent continues listening.
*/
if ((pid = fork()) == 0) {
/*
* Child. Close the listening and max_startup
* sockets. Start using the accepted socket.
* Reinitialize logging (since our pid has
* changed). We break out of the loop to handle
* the connection.
*/
startup_pipe = startup_p[1];
for (j = 0; j < options.max_startups; j++)
if (startup_pipes[j] != -1)
close(startup_pipes[j]);
close_listen_socks();
sock_in = newsock;
sock_out = newsock;
log_init(av0, options.log_level, options.log_facility, log_stderr);
break;
}
}
/* Parent. Stay in the loop. */
if (pid < 0)
error("fork: %.100s", strerror(errno));
else
debug("Forked child %d.", pid);
close(startup_p[1]);
/* Mark that the key has been used (it was "given" to the child). */
key_used = 1;
arc4random_stir();
/* Close the new socket (the child is now taking care of it). */
close(newsock);
}
/* Parent. Stay in the loop. */
if (pid < 0)
error("fork: %.100s", strerror(errno));
else
debug("Forked child %d.", pid);
/* Mark that the key has been used (it was "given" to the child). */
key_used = 1;
arc4random_stir();
/* Close the new socket (the child is now taking care of it). */
close(newsock);
} /* for (i = 0; i < num_listen_socks; i++) */
/* child process check (or debug mode) */
if (num_listen_socks < 0)
break;