140
134
static int twrite(int, char *, size_t, int);
141
135
static int v5_des_read(int, char *, size_t, int),
142
136
v5_des_write(int, char *, size_t, int);
143
#ifdef KRB5_KRB4_COMPAT
144
static int v4_des_read(int, char *, size_t, int),
145
v4_des_write(int, char *, size_t, int);
146
static C_Block v4_session;
147
static int right_justify;
149
137
static int do_lencheck;
151
#ifdef KRB5_KRB4_COMPAT
153
krb_sendauth(long options, int fd, KTEXT ticket,
154
char *service, char *inst, char *realm,
155
unsigned KRB4_32 checksum,
158
Key_schedule schedule,
159
struct sockaddr_in *laddr,
160
struct sockaddr_in *faddr,
164
139
#ifdef POSIX_SIGNALS
165
140
typedef sigset_t masktype;
638
#ifdef KRB5_KRB4_COMPAT
640
k4cmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm,
641
cred, schedule, msg_data, laddr, faddr, authopts, anyport)
645
char *locuser, *remuser, *cmd;
651
Key_schedule schedule;
653
struct sockaddr_in *laddr, *faddr;
659
struct sockaddr_in sockin, from;
661
int lport = START_PORT;
665
int addrfamily = AF_INET;
667
block_urgent(&oldmask);
668
if (kcmd_connect (&s, &addrfamily, &sockin, *ahost, &host_save, rport, &lport, laddr) == -1) {
669
restore_sigs(&oldmask);
673
/* If realm is null, look up from table */
674
if ((realm == NULL) || (realm[0] == '\0')) {
675
realm = krb_realmofhost(host_save);
678
status = setup_secondary_channel(s, fd2p, &lport, &addrfamily, &from,
683
/* set up the needed stuff for mutual auth */
686
status = krb_sendauth(authopts, s, ticket, service, *ahost,
687
realm, (unsigned long) getpid(), msg_data,
688
cred, schedule, laddr, faddr, "KCMDV0.1");
689
if (status != KSUCCESS) {
690
fprintf(stderr, "krb_sendauth failed: %s\n", krb_get_err_text(status));
694
(void) write(s, remuser, strlen(remuser)+1);
695
(void) write(s, cmd, strlen(cmd)+1);
698
if ((rc=read(s, &c, 1)) != 1) {
702
fprintf(stderr,"rcmd: bad connection with remote host\n");
708
/* If rlogind was compiled on SunOS4, and it somehow
709
got the shared library version numbers wrong, it
710
may give an ld.so warning about an old version of a
711
shared library. Just ignore any such warning.
712
Note that the warning is a characteristic of the
713
server; we may not ourselves be running under
716
char *check = "d.so: warning:";
721
while (read(s, &c, 1) == 1) {
736
(void) write(2, &cc, 1);
738
(void) write(2, check, (unsigned) (p - check));
741
(void) write(2, &c, 1);
742
while (read(s, &c, 1) == 1) {
743
(void) write(2, &c, 1);
750
restore_sigs(&oldmask);
758
restore_sigs(&oldmask);
761
#endif /* KRB5_KRB4_COMPAT */
765
612
setup_socket (struct sockaddr *sa, GETSOCKNAME_ARG3_TYPE len)
1157
#ifdef KRB5_KRB4_COMPAT
1160
v4_des_read(fd, buf, len, secondary)
1167
krb5_ui_4 net_len, rd_len;
1171
if (nstored >= len) {
1172
memcpy(buf, store_ptr, len);
1176
} else if (nstored) {
1177
memcpy(buf, store_ptr, nstored);
1178
nreturned += nstored;
1184
/* We're fetching the length which is MSB first, and the MSB
1185
has to be zero unless the client is sending more than 2^24
1186
(16M) bytes in a single write (which is why this code is used
1187
in rlogin but not rcp or rsh.) The only reasons we'd get
1188
something other than zero are:
1189
-- corruption of the tcp stream (which will show up when
1190
everything else is out of sync too)
1191
-- un-caught Berkeley-style "pseudo out-of-band data" which
1192
happens any time the user hits ^C twice.
1193
The latter is *very* common, as shown by an 'rlogin -x -d'
1194
using the CNS V4 rlogin. Mark EIchin 1/95
1197
cc = krb_net_read(fd, &c, 1);
1198
if (cc <= 0) return cc; /* read error */
1200
if (c == 0 || !do_lencheck) break;
1205
if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
1206
net_len = (net_len << 8) | c;
1207
if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
1208
net_len = (net_len << 8) | c;
1209
if ((cc = krb_net_read(fd, &c, 1)) != 1) return 0;
1210
net_len = (net_len << 8) | c;
1212
/* Note: net_len is unsigned */
1213
if (net_len > sizeof(des_inbuf)) {
1217
/* the writer tells us how much real data we are getting, but
1218
we need to read the pad bytes (8-byte boundary) */
1219
rd_len = roundup(net_len, 8);
1220
if ((cc = krb_net_read(fd, des_inbuf, rd_len)) != rd_len) {
1224
(void) pcbc_encrypt((des_cblock *) des_inbuf,
1225
(des_cblock *) storage,
1226
(int) ((net_len < 8) ? 8 : net_len),
1231
* when the cleartext block is < 8 bytes, it is "right-justified"
1232
* in the block, so we need to adjust the pointer to the data
1234
if (net_len < 8 && right_justify)
1235
store_ptr = storage + 8 - net_len;
1237
store_ptr = storage;
1239
if (nstored > len) {
1240
memcpy(buf, store_ptr, len);
1245
memcpy(buf, store_ptr, nstored);
1246
nreturned += nstored;
1254
v4_des_write(fd, buf, len, secondary)
1260
static char garbage_buf[8];
1261
unsigned char *len_buf = (unsigned char *) des_outpkt;
1264
* pcbc_encrypt outputs in 8-byte (64 bit) increments
1266
* it zero-fills the cleartext to 8-byte padding,
1267
* so if we have cleartext of < 8 bytes, we want
1268
* to insert random garbage before it so that the ciphertext
1269
* differs for each transmission of the same cleartext.
1270
* if len < 8 - sizeof(long), sizeof(long) bytes of random
1271
* garbage should be sufficient; leave the rest as-is in the buffer.
1272
* if len > 8 - sizeof(long), just garbage fill the rest.
1278
#define min(a,b) ((a < b) ? a : b)
1281
if (right_justify) {
1282
krb5_random_confounder(8 - len, garbage_buf);
1283
/* this "right-justifies" the data in the buffer */
1284
(void) memcpy(garbage_buf + 8 - len, buf, len);
1286
krb5_random_confounder(8 - len, garbage_buf + len);
1287
(void) memcpy(garbage_buf, buf, len);
1290
(void) pcbc_encrypt((des_cblock *) ((len < 8) ? garbage_buf : buf),
1291
(des_cblock *) (des_outpkt+4),
1292
(int) ((len < 8) ? 8 : len),
1297
/* tell the other end the real amount, but send an 8-byte padded
1299
len_buf[0] = (len & 0xff000000) >> 24;
1300
len_buf[1] = (len & 0xff0000) >> 16;
1301
len_buf[2] = (len & 0xff00) >> 8;
1302
len_buf[3] = (len & 0xff);
1303
if (write(fd, des_outpkt, roundup(len,8)+4) != roundup(len,8)+4) {
1310
#endif /* KRB5_KRB4_COMPAT */
1312
983
#ifndef HAVE_STRSAVE
1313
984
/* Strsave was a routine in the version 4 krb library: we put it here
1314
985
for compatablilty with version 5 krb library, since kcmd.o is linked