handle protocol version 2
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@11349 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -36,10 +36,36 @@ RCSID("$Id$");
|
|||||||
|
|
||||||
#if defined(KRB4) || defined(KRB5)
|
#if defined(KRB4) || defined(KRB5)
|
||||||
|
|
||||||
|
#ifdef KRB5
|
||||||
|
int key_usage = 1026;
|
||||||
|
|
||||||
|
void *ivec_in[2];
|
||||||
|
void *ivec_out[2];
|
||||||
|
|
||||||
|
void
|
||||||
|
init_ivecs(int client)
|
||||||
|
{
|
||||||
|
size_t blocksize;
|
||||||
|
|
||||||
|
krb5_crypto_block_size(context, crypto, &blocksize);
|
||||||
|
|
||||||
|
ivec_in[0] = malloc(blocksize);
|
||||||
|
memset(ivec_in[0], client, blocksize);
|
||||||
|
|
||||||
|
ivec_in[1] = malloc(blocksize);
|
||||||
|
memset(ivec_in[1], 2 | client, blocksize);
|
||||||
|
|
||||||
|
ivec_out[0] = malloc(blocksize);
|
||||||
|
memset(ivec_out[0], !client, blocksize);
|
||||||
|
|
||||||
|
ivec_out[1] = malloc(blocksize);
|
||||||
|
memset(ivec_out[1], 2 | !client, blocksize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
do_read (int fd,
|
do_read (int fd, void *buf, size_t sz, void *ivec)
|
||||||
void *buf,
|
|
||||||
size_t sz)
|
|
||||||
{
|
{
|
||||||
if (do_encrypt) {
|
if (do_encrypt) {
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
@@ -61,7 +87,11 @@ do_read (int fd,
|
|||||||
len = ntohl(len);
|
len = ntohl(len);
|
||||||
if (len > sz)
|
if (len > sz)
|
||||||
abort ();
|
abort ();
|
||||||
outer_len = krb5_get_wrapped_length (context, crypto, len);
|
/* ivec will be non null for protocol version 2 */
|
||||||
|
if(ivec != NULL)
|
||||||
|
outer_len = krb5_get_wrapped_length (context, crypto, len + 4);
|
||||||
|
else
|
||||||
|
outer_len = krb5_get_wrapped_length (context, crypto, len);
|
||||||
edata = malloc (outer_len);
|
edata = malloc (outer_len);
|
||||||
if (edata == NULL)
|
if (edata == NULL)
|
||||||
errx (1, "malloc: cannot allocate %u bytes", outer_len);
|
errx (1, "malloc: cannot allocate %u bytes", outer_len);
|
||||||
@@ -69,13 +99,22 @@ do_read (int fd,
|
|||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
status = krb5_decrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
|
status = krb5_decrypt_ivec(context, crypto, key_usage,
|
||||||
edata, outer_len, &data);
|
edata, outer_len, &data, ivec);
|
||||||
free (edata);
|
free (edata);
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
errx (1, "%s", krb5_get_err_text (context, status));
|
krb5_err (context, 1, status, "decrypting data");
|
||||||
memcpy (buf, data.data, len);
|
if(ivec != NULL) {
|
||||||
|
unsigned long l;
|
||||||
|
if(data.length < len + 4)
|
||||||
|
errx (1, "data received is too short");
|
||||||
|
_krb5_get_int(data.data, &l, 4);
|
||||||
|
if(l != len)
|
||||||
|
errx (1, "inconsistency in received data");
|
||||||
|
memcpy (buf, (unsigned char *)data.data+4, len);
|
||||||
|
} else
|
||||||
|
memcpy (buf, data.data, len);
|
||||||
krb5_data_free (&data);
|
krb5_data_free (&data);
|
||||||
return len;
|
return len;
|
||||||
} else
|
} else
|
||||||
@@ -86,7 +125,7 @@ do_read (int fd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
do_write (int fd, void *buf, size_t sz)
|
do_write (int fd, void *buf, size_t sz, void *ivec)
|
||||||
{
|
{
|
||||||
if (do_encrypt) {
|
if (do_encrypt) {
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
@@ -98,20 +137,27 @@ do_write (int fd, void *buf, size_t sz)
|
|||||||
if(auth_method == AUTH_KRB5) {
|
if(auth_method == AUTH_KRB5) {
|
||||||
krb5_error_code status;
|
krb5_error_code status;
|
||||||
krb5_data data;
|
krb5_data data;
|
||||||
u_int32_t len;
|
unsigned char len[4];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
status = krb5_encrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
|
_krb5_put_int(len, sz, 4);
|
||||||
buf, sz, &data);
|
if(ivec != NULL) {
|
||||||
|
unsigned char *tmp = malloc(sz + 4);
|
||||||
|
if(tmp == NULL)
|
||||||
|
err(1, "malloc");
|
||||||
|
_krb5_put_int(tmp, sz, 4);
|
||||||
|
memcpy(tmp + 4, buf, sz);
|
||||||
|
status = krb5_encrypt_ivec(context, crypto, key_usage,
|
||||||
|
tmp, sz + 4, &data, ivec);
|
||||||
|
free(tmp);
|
||||||
|
} else
|
||||||
|
status = krb5_encrypt_ivec(context, crypto, key_usage,
|
||||||
|
buf, sz, &data, ivec);
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
errx (1, "%s", krb5_get_err_text(context, status));
|
krb5_err(context, 1, status, "encrypting data");
|
||||||
|
|
||||||
assert (krb5_get_wrapped_length (context, crypto,
|
ret = krb5_net_write (context, &fd, len, 4);
|
||||||
sz) == data.length);
|
|
||||||
|
|
||||||
len = htonl(sz);
|
|
||||||
ret = krb5_net_write (context, &fd, &len, 4);
|
|
||||||
if (ret != 4)
|
if (ret != 4)
|
||||||
return ret;
|
return ret;
|
||||||
ret = krb5_net_write (context, &fd, data.data, data.length);
|
ret = krb5_net_write (context, &fd, data.data, data.length);
|
||||||
|
@@ -67,6 +67,8 @@ static const char *user;
|
|||||||
static int do_version;
|
static int do_version;
|
||||||
static int do_help;
|
static int do_help;
|
||||||
static int do_errsock = 1;
|
static int do_errsock = 1;
|
||||||
|
static char *protocol_version_str;
|
||||||
|
static int protocol_version = 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
@@ -80,6 +82,11 @@ loop (int s, int errsock)
|
|||||||
fd_set real_readset;
|
fd_set real_readset;
|
||||||
int count = 1;
|
int count = 1;
|
||||||
|
|
||||||
|
#ifdef KRB5
|
||||||
|
if(auth_method == AUTH_KRB5 && protocol_version == 2)
|
||||||
|
init_ivecs(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (s >= FD_SETSIZE || errsock >= FD_SETSIZE)
|
if (s >= FD_SETSIZE || errsock >= FD_SETSIZE)
|
||||||
errx (1, "fd too large");
|
errx (1, "fd too large");
|
||||||
|
|
||||||
@@ -106,7 +113,7 @@ loop (int s, int errsock)
|
|||||||
err (1, "select");
|
err (1, "select");
|
||||||
}
|
}
|
||||||
if (FD_ISSET(s, &readset)) {
|
if (FD_ISSET(s, &readset)) {
|
||||||
ret = do_read (s, buf, sizeof(buf));
|
ret = do_read (s, buf, sizeof(buf), ivec_in[0]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
err (1, "read");
|
err (1, "read");
|
||||||
else if (ret == 0) {
|
else if (ret == 0) {
|
||||||
@@ -118,7 +125,7 @@ loop (int s, int errsock)
|
|||||||
net_write (STDOUT_FILENO, buf, ret);
|
net_write (STDOUT_FILENO, buf, ret);
|
||||||
}
|
}
|
||||||
if (errsock != -1 && FD_ISSET(errsock, &readset)) {
|
if (errsock != -1 && FD_ISSET(errsock, &readset)) {
|
||||||
ret = do_read (errsock, buf, sizeof(buf));
|
ret = do_read (errsock, buf, sizeof(buf), ivec_in[1]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
err (1, "read");
|
err (1, "read");
|
||||||
else if (ret == 0) {
|
else if (ret == 0) {
|
||||||
@@ -138,7 +145,7 @@ loop (int s, int errsock)
|
|||||||
FD_CLR(STDIN_FILENO, &real_readset);
|
FD_CLR(STDIN_FILENO, &real_readset);
|
||||||
shutdown (s, SHUT_WR);
|
shutdown (s, SHUT_WR);
|
||||||
} else
|
} else
|
||||||
do_write (s, buf, ret);
|
do_write (s, buf, ret, ivec_out[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +173,7 @@ send_krb4_auth(int s,
|
|||||||
getpid(), &msg, &cred, schedule,
|
getpid(), &msg, &cred, schedule,
|
||||||
(struct sockaddr_in *)thisaddr,
|
(struct sockaddr_in *)thisaddr,
|
||||||
(struct sockaddr_in *)thataddr,
|
(struct sockaddr_in *)thataddr,
|
||||||
KCMD_VERSION);
|
KCMD_OLD_VERSION);
|
||||||
if (status != KSUCCESS) {
|
if (status != KSUCCESS) {
|
||||||
warnx("%s: %s", hostname, krb_get_err_text(status));
|
warnx("%s: %s", hostname, krb_get_err_text(status));
|
||||||
return 1;
|
return 1;
|
||||||
@@ -282,6 +289,8 @@ send_krb5_auth(int s,
|
|||||||
int status;
|
int status;
|
||||||
size_t len;
|
size_t len;
|
||||||
krb5_auth_context auth_context = NULL;
|
krb5_auth_context auth_context = NULL;
|
||||||
|
const char *protocol_string = NULL;
|
||||||
|
krb5_flags ap_opts;
|
||||||
|
|
||||||
status = krb5_sname_to_principal(context,
|
status = krb5_sname_to_principal(context,
|
||||||
hostname,
|
hostname,
|
||||||
@@ -300,13 +309,31 @@ send_krb5_auth(int s,
|
|||||||
cmd,
|
cmd,
|
||||||
remote_user);
|
remote_user);
|
||||||
|
|
||||||
|
ap_opts = 0;
|
||||||
|
|
||||||
|
if(do_encrypt)
|
||||||
|
ap_opts |= AP_OPTS_MUTUAL_REQUIRED;
|
||||||
|
|
||||||
|
switch(protocol_version) {
|
||||||
|
case 2:
|
||||||
|
ap_opts |= AP_OPTS_USE_SUBKEY;
|
||||||
|
protocol_string = KCMD_NEW_VERSION;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
protocol_string = KCMD_OLD_VERSION;
|
||||||
|
key_usage = KRB5_KU_OTHER_ENCRYPTED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
status = krb5_sendauth (context,
|
status = krb5_sendauth (context,
|
||||||
&auth_context,
|
&auth_context,
|
||||||
&s,
|
&s,
|
||||||
KCMD_VERSION,
|
protocol_string,
|
||||||
NULL,
|
NULL,
|
||||||
server,
|
server,
|
||||||
do_encrypt ? AP_OPTS_MUTUAL_REQUIRED : 0,
|
ap_opts,
|
||||||
&cksum_data,
|
&cksum_data,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -318,7 +345,9 @@ send_krb5_auth(int s,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = krb5_auth_con_getkey (context, auth_context, &keyblock);
|
status = krb5_auth_con_getlocalsubkey (context, auth_context, &keyblock);
|
||||||
|
if(keyblock == NULL)
|
||||||
|
status = krb5_auth_con_getkey (context, auth_context, &keyblock);
|
||||||
if (status) {
|
if (status) {
|
||||||
warnx ("krb5_auth_con_getkey: %s", krb5_get_err_text(context, status));
|
warnx ("krb5_auth_con_getkey: %s", krb5_get_err_text(context, status));
|
||||||
return 1;
|
return 1;
|
||||||
@@ -552,7 +581,7 @@ proto (int s, int errsock,
|
|||||||
(void *)&one, sizeof(one)) < 0)
|
(void *)&one, sizeof(one)) < 0)
|
||||||
warn("setsockopt stderr");
|
warn("setsockopt stderr");
|
||||||
}
|
}
|
||||||
|
|
||||||
return loop (s, errsock2);
|
return loop (s, errsock2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,6 +806,8 @@ struct getargs args[] = {
|
|||||||
"port" },
|
"port" },
|
||||||
{ "user", 'l', arg_string, &user, "Run as this user", "login" },
|
{ "user", 'l', arg_string, &user, "Run as this user", "login" },
|
||||||
{ "stderr", 'e', arg_negative_flag, &do_errsock, "Don't open stderr"},
|
{ "stderr", 'e', arg_negative_flag, &do_errsock, "Don't open stderr"},
|
||||||
|
{ "protocol", 'P', arg_string, &protocol_version_str,
|
||||||
|
"Protocol version", "protocol" },
|
||||||
{ "version", 0, arg_flag, &do_version, NULL },
|
{ "version", 0, arg_flag, &do_version, NULL },
|
||||||
{ "help", 0, arg_flag, &do_help, NULL }
|
{ "help", 0, arg_flag, &do_help, NULL }
|
||||||
};
|
};
|
||||||
@@ -840,7 +871,24 @@ main(int argc, char **argv)
|
|||||||
print_version (NULL);
|
print_version (NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(protocol_version_str != NULL) {
|
||||||
|
if(strcasecmp(protocol_version_str, "N") == 0)
|
||||||
|
protocol_version = 2;
|
||||||
|
else if(strcasecmp(protocol_version_str, "O") == 0)
|
||||||
|
protocol_version = 1;
|
||||||
|
else {
|
||||||
|
char *end;
|
||||||
|
int v;
|
||||||
|
v = strtol(protocol_version_str, &end, 0);
|
||||||
|
if(*end != '\0' || (v != 1 && v != 2)) {
|
||||||
|
errx(1, "unknown protocol version \"%s\"",
|
||||||
|
protocol_version_str);
|
||||||
|
}
|
||||||
|
protocol_version = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
status = krb5_init_context (&context);
|
status = krb5_init_context (&context);
|
||||||
if (status) {
|
if (status) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997 - 2000, 2002 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 1997 - 2002 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -99,6 +99,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef KRB5
|
#ifdef KRB5
|
||||||
#include <krb5.h>
|
#include <krb5.h>
|
||||||
|
#include <krb5-private.h> /* for _krb5_{get,put}_int */
|
||||||
#endif
|
#endif
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
#include <kafs.h>
|
#include <kafs.h>
|
||||||
@@ -132,25 +133,30 @@ extern int do_encrypt;
|
|||||||
extern krb5_context context;
|
extern krb5_context context;
|
||||||
extern krb5_keyblock *keyblock;
|
extern krb5_keyblock *keyblock;
|
||||||
extern krb5_crypto crypto;
|
extern krb5_crypto crypto;
|
||||||
|
extern int key_usage;
|
||||||
|
extern void *ivec_in[2];
|
||||||
|
extern void *ivec_out[2];
|
||||||
|
void init_ivecs(int);
|
||||||
#endif
|
#endif
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
extern des_key_schedule schedule;
|
extern des_key_schedule schedule;
|
||||||
extern des_cblock iv;
|
extern des_cblock iv;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KCMD_VERSION "KCMDV0.1"
|
#define KCMD_OLD_VERSION "KCMDV0.1"
|
||||||
|
#define KCMD_NEW_VERSION "KCMDV0.2"
|
||||||
|
|
||||||
#define USERNAME_SZ 16
|
#define USERNAME_SZ 16
|
||||||
#define COMMAND_SZ 1024
|
#define COMMAND_SZ 1024
|
||||||
|
|
||||||
#define RSH_BUFSIZ (16 * 1024)
|
#define RSH_BUFSIZ (5 * 1024) /* MIT kcmd can't handle larger buffers */
|
||||||
|
|
||||||
#define PATH_RSH BINDIR "/rsh"
|
#define PATH_RSH BINDIR "/rsh"
|
||||||
|
|
||||||
#if defined(KRB4) || defined(KRB5)
|
#if defined(KRB4) || defined(KRB5)
|
||||||
ssize_t do_read (int fd, void *buf, size_t sz);
|
ssize_t do_read (int, void*, size_t, void*);
|
||||||
ssize_t do_write (int fd, void *buf, size_t sz);
|
ssize_t do_write (int, void*, size_t, void*);
|
||||||
#else
|
#else
|
||||||
#define do_write(F, B, L) write((F), (B), (L))
|
#define do_write(F, B, L, I) write((F), (B), (L))
|
||||||
#define do_read(F, B, L) read((F), (B), (L))
|
#define do_read(F, B, L, I) read((F), (B), (L))
|
||||||
#endif
|
#endif
|
||||||
|
@@ -199,7 +199,7 @@ recv_krb4_auth (int s, u_char *buf,
|
|||||||
version);
|
version);
|
||||||
if (status != KSUCCESS)
|
if (status != KSUCCESS)
|
||||||
syslog_and_die ("recvauth: %s", krb_get_err_text(status));
|
syslog_and_die ("recvauth: %s", krb_get_err_text(status));
|
||||||
if (strncmp (version, KCMD_VERSION, KRB_SENDAUTH_VLEN) != 0)
|
if (strncmp (version, KCMD_OLD_VERSION, KRB_SENDAUTH_VLEN) != 0)
|
||||||
syslog_and_die ("bad version: %s", version);
|
syslog_and_die ("bad version: %s", version);
|
||||||
|
|
||||||
read_str (s, server_username, USERNAME_SZ, "remote username");
|
read_str (s, server_username, USERNAME_SZ, "remote username");
|
||||||
@@ -277,6 +277,24 @@ krb5_start_session (void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int protocol_version;
|
||||||
|
|
||||||
|
static krb5_boolean
|
||||||
|
match_kcmd_version(const void *data, const char *version)
|
||||||
|
{
|
||||||
|
if(strcmp(version, KCMD_NEW_VERSION) == 0) {
|
||||||
|
protocol_version = 2;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if(strcmp(version, KCMD_OLD_VERSION) == 0) {
|
||||||
|
protocol_version = 1;
|
||||||
|
key_usage = KRB5_KU_OTHER_ENCRYPTED;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
recv_krb5_auth (int s, u_char *buf,
|
recv_krb5_auth (int s, u_char *buf,
|
||||||
struct sockaddr *thisaddr,
|
struct sockaddr *thisaddr,
|
||||||
@@ -311,14 +329,15 @@ recv_krb5_auth (int s, u_char *buf,
|
|||||||
syslog_and_die ("krb5_sock_to_principal: %s",
|
syslog_and_die ("krb5_sock_to_principal: %s",
|
||||||
krb5_get_err_text(context, status));
|
krb5_get_err_text(context, status));
|
||||||
|
|
||||||
status = krb5_recvauth(context,
|
status = krb5_recvauth_match_version(context,
|
||||||
&auth_context,
|
&auth_context,
|
||||||
&s,
|
&s,
|
||||||
KCMD_VERSION,
|
match_kcmd_version,
|
||||||
server,
|
NULL,
|
||||||
KRB5_RECVAUTH_IGNORE_VERSION,
|
server,
|
||||||
NULL,
|
KRB5_RECVAUTH_IGNORE_VERSION,
|
||||||
&ticket);
|
NULL,
|
||||||
|
&ticket);
|
||||||
krb5_free_principal (context, server);
|
krb5_free_principal (context, server);
|
||||||
if (status)
|
if (status)
|
||||||
syslog_and_die ("krb5_recvauth: %s",
|
syslog_and_die ("krb5_recvauth: %s",
|
||||||
@@ -328,8 +347,17 @@ recv_krb5_auth (int s, u_char *buf,
|
|||||||
read_str (s, cmd, COMMAND_SZ, "command");
|
read_str (s, cmd, COMMAND_SZ, "command");
|
||||||
read_str (s, client_username, COMMAND_SZ, "local username");
|
read_str (s, client_username, COMMAND_SZ, "local username");
|
||||||
|
|
||||||
status = krb5_auth_con_getkey (context, auth_context, &keyblock);
|
if(protocol_version == 2) {
|
||||||
if (status)
|
status = krb5_auth_con_getremotesubkey(context, auth_context,
|
||||||
|
&keyblock);
|
||||||
|
if(status != 0 || keyblock == NULL)
|
||||||
|
syslog_and_die("failed to get remote subkey");
|
||||||
|
} else if(protocol_version == 1) {
|
||||||
|
status = krb5_auth_con_getkey (context, auth_context, &keyblock);
|
||||||
|
if(status != 0 || keyblock == NULL)
|
||||||
|
syslog_and_die("failed to get key");
|
||||||
|
}
|
||||||
|
if (status != 0 || keyblock == NULL)
|
||||||
syslog_and_die ("krb5_auth_con_getkey: %s",
|
syslog_and_die ("krb5_auth_con_getkey: %s",
|
||||||
krb5_get_err_text(context, status));
|
krb5_get_err_text(context, status));
|
||||||
|
|
||||||
@@ -436,6 +464,11 @@ loop (int from0, int to0,
|
|||||||
if(from0 >= FD_SETSIZE || from1 >= FD_SETSIZE || from2 >= FD_SETSIZE)
|
if(from0 >= FD_SETSIZE || from1 >= FD_SETSIZE || from2 >= FD_SETSIZE)
|
||||||
errx (1, "fd too large");
|
errx (1, "fd too large");
|
||||||
|
|
||||||
|
#ifdef KRB5
|
||||||
|
if(auth_method == AUTH_KRB5 && protocol_version == 2)
|
||||||
|
init_ivecs(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
FD_ZERO(&real_readset);
|
FD_ZERO(&real_readset);
|
||||||
FD_SET(from0, &real_readset);
|
FD_SET(from0, &real_readset);
|
||||||
FD_SET(from1, &real_readset);
|
FD_SET(from1, &real_readset);
|
||||||
@@ -454,7 +487,7 @@ loop (int from0, int to0,
|
|||||||
syslog_and_die ("select: %m");
|
syslog_and_die ("select: %m");
|
||||||
}
|
}
|
||||||
if (FD_ISSET(from0, &readset)) {
|
if (FD_ISSET(from0, &readset)) {
|
||||||
ret = do_read (from0, buf, sizeof(buf));
|
ret = do_read (from0, buf, sizeof(buf), ivec_in[0]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
syslog_and_die ("read: %m");
|
syslog_and_die ("read: %m");
|
||||||
else if (ret == 0) {
|
else if (ret == 0) {
|
||||||
@@ -475,7 +508,7 @@ loop (int from0, int to0,
|
|||||||
if (--count == 0)
|
if (--count == 0)
|
||||||
exit (0);
|
exit (0);
|
||||||
} else
|
} else
|
||||||
do_write (to1, buf, ret);
|
do_write (to1, buf, ret, ivec_out[0]);
|
||||||
}
|
}
|
||||||
if (FD_ISSET(from2, &readset)) {
|
if (FD_ISSET(from2, &readset)) {
|
||||||
ret = read (from2, buf, sizeof(buf));
|
ret = read (from2, buf, sizeof(buf));
|
||||||
@@ -488,7 +521,7 @@ loop (int from0, int to0,
|
|||||||
if (--count == 0)
|
if (--count == 0)
|
||||||
exit (0);
|
exit (0);
|
||||||
} else
|
} else
|
||||||
do_write (to2, buf, ret);
|
do_write (to2, buf, ret, ivec_out[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user