1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/*
20140211
Jan Mojzis
Public domain.
*/
#include "bug.h"
#include "buf.h"
#include "channel.h"
#include "ssh.h"
#include "bug.h"
#include "crypto_uint32.h"
#include "packet.h"
void packet_channel_send_data(struct buf *b) {
long long r;
long long limit = PACKET_LIMIT;
if (channel.maxpacket > 0) {
if (channel.maxpacket < PACKET_LIMIT) { limit = channel.maxpacket; }
}
buf_purge(b);
if (b->alloc <= PACKET_LIMIT) bug_nomem();
if (!packet_putisready()) return;
r = channel_read(b->buf + 9, limit - 9);
if (r == 0) return;
b->len = r + 9;
b->buf[0] = SSH_MSG_CHANNEL_DATA; /* byte SSH_MSG_CHANNEL_DATA */
crypto_uint32_store_bigendian(
b->buf + 1, channel_getid()); /* uint32 recipient channel */
crypto_uint32_store_bigendian(b->buf + 5, r); /* string data */
packet_put(b);
buf_purge(b);
return;
}
void packet_channel_send_extendeddata(struct buf *b) {
long long r;
long long limit = PACKET_LIMIT;
if (channel.maxpacket > 0) {
if (channel.maxpacket < PACKET_LIMIT) { limit = channel.maxpacket; }
}
buf_purge(b);
if (b->alloc <= PACKET_LIMIT) bug_nomem();
if (!packet_putisready()) return;
r = channel_extendedread(b->buf + 13, limit - 13);
if (r == 0) return;
b->len = r + 13;
b->buf[0] =
SSH_MSG_CHANNEL_EXTENDED_DATA; /* byte SSH_MSG_CHANNEL_EXTENDED_DATA */
crypto_uint32_store_bigendian(
b->buf + 1, channel_getid()); /* uint32 recipient channel */
crypto_uint32_store_bigendian(
b->buf + 5, 1); /* uint32 data_type_code (1 = stderr) */
crypto_uint32_store_bigendian(b->buf + 9, r); /* string data */
packet_put(b);
buf_purge(b);
return;
}
int packet_channel_send_windowadjust(struct buf *b) {
crypto_uint32 plus;
if (channel_getlen0() > CHANNEL_BUFSIZE / 2) return 1;
if (channel_getlocalwindow() > CHANNEL_BUFSIZE / 2) return 1;
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_WINDOW_ADJUST);
buf_putnum32(b, channel_getid());
plus = CHANNEL_BUFSIZE - channel_getlen0() - channel_getlocalwindow();
buf_putnum32(b, plus);
channel_incrementlocalwindow(plus);
packet_put(b);
buf_purge(b);
return 1;
}
void packet_channel_send_eof(struct buf *b) {
if (packet.flageofsent) return;
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_EOF);
buf_putnum32(b, channel_getid());
packet_put(b);
buf_purge(b);
packet.flageofsent = 1;
}
int packet_channel_send_close(struct buf *b, int exitsignal, int exitcode) {
packet_channel_send_eof(b);
if (packet.flagclosesent) return 1;
if (exitsignal > 0) {
buf_purge(b);
buf_putnum8(b,
SSH_MSG_CHANNEL_REQUEST); /* byte SSH_MSG_CHANNEL_REQUEST */
buf_putnum32(b, channel_getid()); /* uint32 recipient channel */
buf_putstring(b, "exit-signal"); /* string "exit-signal" */
buf_putnum8(b, 0); /* boolean FALSE */
buf_putstring(b,
ssh_sigstr(exitsignal)); /* string signal name (without
the "SIG" prefix) */
buf_putnum8(b, 0); /* boolean core dumped */
buf_putstring(
b, ssh_sigstrlong(exitsignal)); /* string error message in
ISO-10646 UTF-8 encoding */
buf_putstring(b, ""); /* string language tag [RFC3066] */
packet_put(b);
buf_purge(b);
if (!packet_sendall()) return 0;
}
else {
buf_purge(b);
buf_putnum8(b,
SSH_MSG_CHANNEL_REQUEST); /* byte SSH_MSG_CHANNEL_REQUEST */
buf_putnum32(b, channel_getid()); /* uint32 recipient channel */
buf_putstring(b, "exit-status"); /* string "exit-status" */
buf_putnum8(b, 0); /* boolean FALSE */
buf_putnum32(b, exitcode); /* uint32 exit_status */
packet_put(b);
buf_purge(b);
if (!packet_sendall()) return 0;
}
buf_purge(b);
buf_putnum8(b, SSH_MSG_CHANNEL_CLOSE); /* byte SSH_MSG_CHANNEL_CLOSE */
buf_putnum32(b, channel_getid()); /* uint32 recipient channel */
packet_put(b);
if (!packet_sendall()) return 0;
buf_purge(b);
packet.flagclosesent = 1;
return 1;
}
|