| ︙ | | | ︙ | |
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
|
struct rdpkt1_state_tag rdpkt1_state;
struct rdpkt2_state_tag rdpkt2_state;
void (*protocol) (Ssh ssh, unsigned char *in, int inlen, int ispkt);
int (*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen);
};
#define logevent(s) { logevent(ssh->frontend, s); \
if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \
{ fprintf(stderr, "%s\n", s); fflush(stderr); } }
/* logevent, only printf-formatted. */
void logeventf(Ssh ssh, char *fmt, ...)
{
va_list ap;
char stuff[200];
va_start(ap, fmt);
vsprintf(stuff, fmt, ap);
va_end(ap);
logevent(stuff);
}
#define bombout(msg) ( ssh->state = SSH_STATE_CLOSED, \
(ssh->s ? sk_close(ssh->s), ssh->s = NULL : 0), \
logeventf msg, connection_fatal msg )
static int ssh_channelcmp(void *av, void *bv)
|
|
>
|
|
>
>
>
|
|
|
>
>
>
>
>
|
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
|
struct rdpkt1_state_tag rdpkt1_state;
struct rdpkt2_state_tag rdpkt2_state;
void (*protocol) (Ssh ssh, unsigned char *in, int inlen, int ispkt);
int (*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen);
};
#define logevent(s) do { \
logevent(ssh->frontend, s); \
if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) { \
fprintf(stderr, "%s\n", s); \
fflush(stderr); \
} \
} while (0)
/* logevent, only printf-formatted. */
void logeventf(Ssh ssh, char *fmt, ...)
{
va_list ap;
char *buf;
va_start(ap, fmt);
buf = dupvprintf(fmt, ap);
va_end(ap);
logevent(buf);
if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) {
fprintf(stderr, "%s\n", buf);
fflush(stderr);
}
sfree(buf);
}
#define bombout(msg) ( ssh->state = SSH_STATE_CLOSED, \
(ssh->s ? sk_close(ssh->s), ssh->s = NULL : 0), \
logeventf msg, connection_fatal msg )
static int ssh_channelcmp(void *av, void *bv)
|
| ︙ | | | ︙ | |
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
|
switch (ssh->pktin.type) {
/*
* These packets we must handle instantly.
*/
case SSH2_MSG_DISCONNECT:
{
/* log reason code in disconnect message */
char buf[256];
int reason = GET_32BIT(ssh->pktin.data + 6);
unsigned msglen = GET_32BIT(ssh->pktin.data + 10);
unsigned nowlen;
if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
sprintf(buf, "Received disconnect message (%s)",
ssh2_disconnect_reasons[reason]);
} else {
sprintf(buf, "Received disconnect message (unknown type %d)",
reason);
}
logevent(buf);
strcpy(buf, "Disconnection message text: ");
nowlen = strlen(buf);
if (msglen > sizeof(buf) - nowlen - 1)
msglen = sizeof(buf) - nowlen - 1;
memcpy(buf + nowlen, ssh->pktin.data + 14, msglen);
buf[nowlen + msglen] = '\0';
logevent(buf);
bombout((ssh,"Server sent disconnect message\ntype %d (%s):\n\"%s\"",
reason,
(reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
ssh2_disconnect_reasons[reason] : "unknown",
buf+nowlen));
crReturn(0);
}
break;
case SSH2_MSG_IGNORE:
goto next_packet;
case SSH2_MSG_DEBUG:
{
|
|
>
|
|
|
|
|
>
|
<
<
<
|
<
>
|
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
|
switch (ssh->pktin.type) {
/*
* These packets we must handle instantly.
*/
case SSH2_MSG_DISCONNECT:
{
/* log reason code in disconnect message */
char *buf;
int nowlen;
int reason = GET_32BIT(ssh->pktin.data + 6);
unsigned msglen = GET_32BIT(ssh->pktin.data + 10);
if (reason > 0 && reason < lenof(ssh2_disconnect_reasons)) {
buf = dupprintf("Received disconnect message (%s)",
ssh2_disconnect_reasons[reason]);
} else {
buf = dupprintf("Received disconnect message (unknown"
" type %d)", reason);
}
logevent(buf);
sfree(buf);
buf = dupprintf("Disconnection message text: %n%.*s",
msglen, &nowlen, ssh->pktin.data + 14);
logevent(buf);
bombout((ssh,"Server sent disconnect message\ntype %d (%s):\n\"%s\"",
reason,
(reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
ssh2_disconnect_reasons[reason] : "unknown",
buf+nowlen));
sfree(buf);
crReturn(0);
}
break;
case SSH2_MSG_IGNORE:
goto next_packet;
case SSH2_MSG_DEBUG:
{
|
| ︙ | | | ︙ | |
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
|
return 0; /* arrgh, no way to decline (FIXME?) */
value = ssh->pktin.data[ssh->pktin.savedpos] != 0;
ssh->pktin.savedpos++;
return value;
}
static void ssh2_pkt_getstring(Ssh ssh, char **p, int *length)
{
*p = NULL;
*length = 0;
if (ssh->pktin.length - ssh->pktin.savedpos < 4)
return;
*length = GET_32BIT(ssh->pktin.data + ssh->pktin.savedpos);
ssh->pktin.savedpos += 4;
if (ssh->pktin.length - ssh->pktin.savedpos < *length)
return;
*p = ssh->pktin.data + ssh->pktin.savedpos;
ssh->pktin.savedpos += *length;
}
static Bignum ssh2_pkt_getmp(Ssh ssh)
|
>
|
>
>
>
|
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
|
return 0; /* arrgh, no way to decline (FIXME?) */
value = ssh->pktin.data[ssh->pktin.savedpos] != 0;
ssh->pktin.savedpos++;
return value;
}
static void ssh2_pkt_getstring(Ssh ssh, char **p, int *length)
{
int len;
*p = NULL;
*length = 0;
if (ssh->pktin.length - ssh->pktin.savedpos < 4)
return;
len = GET_32BIT(ssh->pktin.data + ssh->pktin.savedpos);
if (len < 0)
return;
*length = len;
ssh->pktin.savedpos += 4;
if (ssh->pktin.length - ssh->pktin.savedpos < *length)
return;
*p = ssh->pktin.data + ssh->pktin.savedpos;
ssh->pktin.savedpos += *length;
}
static Bignum ssh2_pkt_getmp(Ssh ssh)
|
| ︙ | | | ︙ | |
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
|
if (port < 0)
port = 22; /* default ssh port */
ssh->savedport = port;
/*
* Try to find host.
*/
{
char buf[200];
sprintf(buf, "Looking up host \"%.170s\"", host);
logevent(buf);
}
addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr)))
return err;
/*
* Open socket.
*/
{
char buf[200], addrbuf[100];
sk_getaddr(addr, addrbuf, 100);
sprintf(buf, "Connecting to %.100s port %d", addrbuf, port);
logevent(buf);
}
ssh->fn = &fn_table;
ssh->s = new_connection(addr, *realhost, port, 0, 1, nodelay, (Plug) ssh);
if ((err = sk_socket_error(ssh->s))) {
ssh->s = NULL;
return err;
}
|
<
<
|
<
<
|
|
<
|
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
|
if (port < 0)
port = 22; /* default ssh port */
ssh->savedport = port;
/*
* Try to find host.
*/
logeventf(ssh, "Looking up host \"%s\"", host);
addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr)))
return err;
/*
* Open socket.
*/
{
char addrbuf[100];
sk_getaddr(addr, addrbuf, 100);
logeventf(ssh, "Connecting to %s port %d", addrbuf, port);
}
ssh->fn = &fn_table;
ssh->s = new_connection(addr, *realhost, port, 0, 1, nodelay, (Plug) ssh);
if ((err = sk_socket_error(ssh->s))) {
ssh->s = NULL;
return err;
}
|
| ︙ | | | ︙ | |
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
|
sfree(s->rsabuf);
ssh->cipher = (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
s->cipher_type == SSH_CIPHER_DES ? &ssh_des :
&ssh_3des);
ssh->v1_cipher_ctx = ssh->cipher->make_context();
ssh->cipher->sesskey(ssh->v1_cipher_ctx, ssh->session_key);
{
char buf[256];
sprintf(buf, "Initialised %.200s encryption", ssh->cipher->text_name);
logevent(buf);
}
ssh->crcda_ctx = crcda_make_context();
logevent("Installing CRC compensation attack detector");
crWaitUntil(ispkt);
if (ssh->pktin.type != SSH1_SMSG_SUCCESS) {
|
<
<
|
<
<
|
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
|
sfree(s->rsabuf);
ssh->cipher = (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
s->cipher_type == SSH_CIPHER_DES ? &ssh_des :
&ssh_3des);
ssh->v1_cipher_ctx = ssh->cipher->make_context();
ssh->cipher->sesskey(ssh->v1_cipher_ctx, ssh->session_key);
logeventf(ssh, "Initialised %s encryption", ssh->cipher->text_name);
ssh->crcda_ctx = crcda_make_context();
logevent("Installing CRC compensation attack detector");
crWaitUntil(ispkt);
if (ssh->pktin.type != SSH1_SMSG_SUCCESS) {
|
| ︙ | | | ︙ | |
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
|
}
if (s->pwpkt_type == SSH1_CMSG_AUTH_RSA) {
char *comment = NULL;
int type;
char msgbuf[256];
if (flags & FLAG_VERBOSE)
c_write_str(ssh, "Trying public key authentication.\r\n");
sprintf(msgbuf, "Trying public key \"%.200s\"", cfg.keyfile);
logevent(msgbuf);
type = key_type(cfg.keyfile);
if (type != SSH_KEYTYPE_SSH1) {
sprintf(msgbuf, "Key is of wrong type (%s)",
key_type_to_str(type));
logevent(msgbuf);
c_write_str(ssh, msgbuf);
c_write_str(ssh, "\r\n");
|
|
<
|
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
|
}
if (s->pwpkt_type == SSH1_CMSG_AUTH_RSA) {
char *comment = NULL;
int type;
char msgbuf[256];
if (flags & FLAG_VERBOSE)
c_write_str(ssh, "Trying public key authentication.\r\n");
logeventf(ssh, "Trying public key \"%s\"", cfg.keyfile);
type = key_type(cfg.keyfile);
if (type != SSH_KEYTYPE_SSH1) {
sprintf(msgbuf, "Key is of wrong type (%s)",
key_type_to_str(type));
logevent(msgbuf);
c_write_str(ssh, msgbuf);
c_write_str(ssh, "\r\n");
|
| ︙ | | | ︙ | |
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
|
}
{
char type;
int n;
int sport,dport,sserv,dserv;
char sports[256], dports[256], host[256];
char buf[1024];
ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
/* Add port forwardings. */
ssh->portfwd_strptr = cfg.portfwd;
while (*ssh->portfwd_strptr) {
type = *ssh->portfwd_strptr++;
n = 0;
|
<
|
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
|
}
{
char type;
int n;
int sport,dport,sserv,dserv;
char sports[256], dports[256], host[256];
ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
/* Add port forwardings. */
ssh->portfwd_strptr = cfg.portfwd;
while (*ssh->portfwd_strptr) {
type = *ssh->portfwd_strptr++;
n = 0;
|
| ︙ | | | ︙ | |
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
|
ssh->portfwd_strptr++;
dport = atoi(dports);
dserv = 0;
if (dport == 0) {
dserv = 1;
dport = net_service_lookup(dports);
if (!dport) {
sprintf(buf,
"Service lookup failed for destination port \"%s\"",
dports);
logevent(buf);
}
}
sport = atoi(sports);
sserv = 0;
if (sport == 0) {
sserv = 1;
sport = net_service_lookup(sports);
if (!sport) {
sprintf(buf,
"Service lookup failed for source port \"%s\"",
sports);
logevent(buf);
}
}
if (sport && dport) {
if (type == 'L') {
pfd_addforward(host, dport, sport, ssh);
sprintf(buf, "Local port %.*s%.*s%d%.*s forwarding to"
" %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
logevent(buf);
} else {
struct ssh_rportfwd *pf;
pf = smalloc(sizeof(*pf));
strcpy(pf->dhost, host);
pf->dport = dport;
if (add234(ssh->rportfwds, pf) != pf) {
sprintf(buf,
"Duplicate remote port forwarding to %s:%d",
host, dport);
logevent(buf);
sfree(pf);
} else {
sprintf(buf, "Requesting remote port %.*s%.*s%d%.*s"
" forward to %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
logevent(buf);
send_packet(ssh, SSH1_CMSG_PORT_FORWARD_REQUEST,
PKT_INT, sport,
PKT_STR, host,
PKT_INT, dport,
PKT_END);
do {
crReturnV;
|
<
|
|
<
<
|
|
<
|
|
|
|
|
|
|
<
|
|
|
<
|
|
|
|
|
|
|
<
|
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
|
ssh->portfwd_strptr++;
dport = atoi(dports);
dserv = 0;
if (dport == 0) {
dserv = 1;
dport = net_service_lookup(dports);
if (!dport) {
logeventf(ssh, "Service lookup failed for"
" destination port \"%s\"", dports);
}
}
sport = atoi(sports);
sserv = 0;
if (sport == 0) {
sserv = 1;
sport = net_service_lookup(sports);
if (!sport) {
logeventf(ssh, "Service lookup failed for source"
" port \"%s\"", sports);
}
}
if (sport && dport) {
if (type == 'L') {
pfd_addforward(host, dport, sport, ssh);
logeventf(ssh, "Local port %.*s%.*s%d%.*s forwarding to"
" %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
} else {
struct ssh_rportfwd *pf;
pf = smalloc(sizeof(*pf));
strcpy(pf->dhost, host);
pf->dport = dport;
if (add234(ssh->rportfwds, pf) != pf) {
logeventf(ssh,
"Duplicate remote port forwarding to %s:%d",
host, dport);
sfree(pf);
} else {
logeventf(ssh, "Requesting remote port %.*s%.*s%d%.*s"
" forward to %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
send_packet(ssh, SSH1_CMSG_PORT_FORWARD_REQUEST,
PKT_INT, sport,
PKT_STR, host,
PKT_INT, dport,
PKT_END);
do {
crReturnV;
|
| ︙ | | | ︙ | |
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
|
}
/*
* Utility routine for decoding comma-separated strings in KEXINIT.
*/
static int in_commasep_string(char *needle, char *haystack, int haylen)
{
int needlen = strlen(needle);
while (1) {
/*
* Is it at the start of the string?
*/
if (haylen >= needlen && /* haystack is long enough */
!memcmp(needle, haystack, needlen) && /* initial match */
(haylen == needlen || haystack[needlen] == ',')
|
>
>
>
|
|
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
|
}
/*
* Utility routine for decoding comma-separated strings in KEXINIT.
*/
static int in_commasep_string(char *needle, char *haystack, int haylen)
{
int needlen;
if (!needle || !haystack) /* protect against null pointers */
return 0;
needlen = strlen(needle);
while (1) {
/*
* Is it at the start of the string?
*/
if (haylen >= needlen && /* haystack is long enough */
!memcmp(needle, haystack, needlen) && /* initial match */
(haylen == needlen || haystack[needlen] == ',')
|
| ︙ | | | ︙ | |
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
|
ssh->exhash = ssh->exhashbase;
sha_string(&ssh->exhash, ssh->pktout.data + 5, ssh->pktout.length - 5);
ssh2_pkt_send(ssh);
if (!ispkt)
crWaitUntil(ispkt);
sha_string(&ssh->exhash, ssh->pktin.data + 5, ssh->pktin.length - 5);
/*
* Now examine the other side's KEXINIT to see what we're up
* to.
*/
{
char *str;
|
>
|
|
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
|
ssh->exhash = ssh->exhashbase;
sha_string(&ssh->exhash, ssh->pktout.data + 5, ssh->pktout.length - 5);
ssh2_pkt_send(ssh);
if (!ispkt)
crWaitUntil(ispkt);
if (ssh->pktin.length > 5)
sha_string(&ssh->exhash, ssh->pktin.data + 5, ssh->pktin.length - 5);
/*
* Now examine the other side's KEXINIT to see what we're up
* to.
*/
{
char *str;
|
| ︙ | | | ︙ | |
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
|
if (s->cscipher_tobe) {
if (s->warn)
askcipher(ssh->frontend, s->cscipher_tobe->name, 1);
break;
}
}
if (!s->cscipher_tobe) {
bombout((ssh,"Couldn't agree a client-to-server cipher (available: %s)", str));
crReturn(0);
}
ssh2_pkt_getstring(ssh, &str, &len); /* server->client cipher */
s->warn = 0;
for (i = 0; i < s->n_preferred_ciphers; i++) {
const struct ssh2_ciphers *c = s->preferred_ciphers[i];
|
|
>
|
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
|
if (s->cscipher_tobe) {
if (s->warn)
askcipher(ssh->frontend, s->cscipher_tobe->name, 1);
break;
}
}
if (!s->cscipher_tobe) {
bombout((ssh,"Couldn't agree a client-to-server cipher (available: %s)",
str ? str : "(null)"));
crReturn(0);
}
ssh2_pkt_getstring(ssh, &str, &len); /* server->client cipher */
s->warn = 0;
for (i = 0; i < s->n_preferred_ciphers; i++) {
const struct ssh2_ciphers *c = s->preferred_ciphers[i];
|
| ︙ | | | ︙ | |
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
|
if (s->sccipher_tobe) {
if (s->warn)
askcipher(ssh->frontend, s->sccipher_tobe->name, 2);
break;
}
}
if (!s->sccipher_tobe) {
bombout((ssh,"Couldn't agree a server-to-client cipher (available: %s)", str));
crReturn(0);
}
ssh2_pkt_getstring(ssh, &str, &len); /* client->server mac */
for (i = 0; i < s->nmacs; i++) {
if (in_commasep_string(s->maclist[i]->name, str, len)) {
s->csmac_tobe = s->maclist[i];
|
|
>
|
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
|
if (s->sccipher_tobe) {
if (s->warn)
askcipher(ssh->frontend, s->sccipher_tobe->name, 2);
break;
}
}
if (!s->sccipher_tobe) {
bombout((ssh,"Couldn't agree a server-to-client cipher (available: %s)",
str ? str : "(null)"));
crReturn(0);
}
ssh2_pkt_getstring(ssh, &str, &len); /* client->server mac */
for (i = 0; i < s->nmacs; i++) {
if (in_commasep_string(s->maclist[i]->name, str, len)) {
s->csmac_tobe = s->maclist[i];
|
| ︙ | | | ︙ | |
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
|
ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'B',keyspace);
ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'E',keyspace);
ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'F',keyspace);
ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
}
{
char buf[256];
sprintf(buf, "Initialised %.200s client->server encryption",
ssh->cscipher->text_name);
logevent(buf);
sprintf(buf, "Initialised %.200s server->client encryption",
ssh->sccipher->text_name);
logevent(buf);
if (ssh->cscomp->text_name) {
sprintf(buf, "Initialised %.200s compression",
ssh->cscomp->text_name);
logevent(buf);
}
if (ssh->sccomp->text_name) {
sprintf(buf, "Initialised %.200s decompression",
ssh->sccomp->text_name);
logevent(buf);
}
}
/*
* If this is the first key exchange phase, we must pass the
* SSH2_MSG_NEWKEYS packet to the next layer, not because it
* wants to see it but because it will need time to initialise
* itself before it sees an actual packet. In subsequent key
* exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
|
<
<
|
|
<
|
|
<
|
|
|
<
<
|
|
|
<
<
<
<
|
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
|
ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'B',keyspace);
ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace);
ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'E',keyspace);
ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace);
ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'F',keyspace);
ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace);
}
logeventf(ssh, "Initialised %.200s client->server encryption",
ssh->cscipher->text_name);
logeventf(ssh, "Initialised %.200s server->client encryption",
ssh->sccipher->text_name);
if (ssh->cscomp->text_name)
logeventf(ssh, "Initialised %s compression",
ssh->cscomp->text_name);
if (ssh->sccomp->text_name)
logeventf(ssh, "Initialised %s decompression",
ssh->sccomp->text_name);
/*
* If this is the first key exchange phase, we must pass the
* SSH2_MSG_NEWKEYS packet to the next layer, not because it
* wants to see it but because it will need time to initialise
* itself before it sees an actual packet. In subsequent key
* exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
|
| ︙ | | | ︙ | |
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
|
} while (ret == 0);
if (ret < 0)
cleanup_exit(0);
c_write_str(ssh, "\r\n");
}
s->username[strcspn(s->username, "\n\r")] = '\0';
} else {
char stuff[200];
strncpy(s->username, cfg.username, sizeof(s->username));
s->username[sizeof(s->username)-1] = '\0';
if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
sprintf(stuff, "Using username \"%s\".\r\n", s->username);
c_write_str(ssh, stuff);
}
}
s->got_username = TRUE;
/*
* Send an authentication request using method "none": (a)
* just in case it succeeds, and (b) so that we know what
|
|
|
>
|
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
|
} while (ret == 0);
if (ret < 0)
cleanup_exit(0);
c_write_str(ssh, "\r\n");
}
s->username[strcspn(s->username, "\n\r")] = '\0';
} else {
char *stuff;
strncpy(s->username, cfg.username, sizeof(s->username));
s->username[sizeof(s->username)-1] = '\0';
if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
stuff = dupprintf("Using username \"%s\".\r\n", s->username);
c_write_str(ssh, stuff);
sfree(stuff);
}
}
s->got_username = TRUE;
/*
* Send an authentication request using method "none": (a)
* just in case it succeeds, and (b) so that we know what
|
| ︙ | | | ︙ | |
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
|
"Reading private key file \"%.150s\"", cfg.keyfile);
keytype = key_type(cfg.keyfile);
if (keytype == SSH_KEYTYPE_SSH2) {
s->publickey_blob =
ssh2_userkey_loadpub(cfg.keyfile, NULL,
&s->publickey_bloblen);
} else {
char msgbuf[256];
logeventf(ssh->frontend,
"Unable to use this key file (%s)",
key_type_to_str(keytype));
sprintf(msgbuf, "Unable to use key file \"%.150s\" (%s)\r\n",
cfg.keyfile, key_type_to_str(keytype));
c_write_str(ssh, msgbuf);
s->publickey_blob = NULL;
}
} else
s->publickey_blob = NULL;
while (1) {
/*
|
|
|
>
|
>
|
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
|
"Reading private key file \"%.150s\"", cfg.keyfile);
keytype = key_type(cfg.keyfile);
if (keytype == SSH_KEYTYPE_SSH2) {
s->publickey_blob =
ssh2_userkey_loadpub(cfg.keyfile, NULL,
&s->publickey_bloblen);
} else {
char *msgbuf;
logeventf(ssh->frontend,
"Unable to use this key file (%s)",
key_type_to_str(keytype));
msgbuf = dupprintf("Unable to use key file \"%.150s\""
" (%s)\r\n", cfg.keyfile,
key_type_to_str(keytype));
c_write_str(ssh, msgbuf);
sfree(msgbuf);
s->publickey_blob = NULL;
}
} else
s->publickey_blob = NULL;
while (1) {
/*
|
| ︙ | | | ︙ | |
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
|
* Enable port forwardings.
*/
{
char type;
int n;
int sport,dport,sserv,dserv;
char sports[256], dports[256], host[256];
char buf[1024];
ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
/* Add port forwardings. */
ssh->portfwd_strptr = cfg.portfwd;
while (*ssh->portfwd_strptr) {
type = *ssh->portfwd_strptr++;
n = 0;
|
<
|
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
|
* Enable port forwardings.
*/
{
char type;
int n;
int sport,dport,sserv,dserv;
char sports[256], dports[256], host[256];
ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
/* Add port forwardings. */
ssh->portfwd_strptr = cfg.portfwd;
while (*ssh->portfwd_strptr) {
type = *ssh->portfwd_strptr++;
n = 0;
|
| ︙ | | | ︙ | |
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
|
ssh->portfwd_strptr++;
dport = atoi(dports);
dserv = 0;
if (dport == 0) {
dserv = 1;
dport = net_service_lookup(dports);
if (!dport) {
sprintf(buf,
"Service lookup failed for destination port \"%s\"",
dports);
logevent(buf);
}
}
sport = atoi(sports);
sserv = 0;
if (sport == 0) {
sserv = 1;
sport = net_service_lookup(sports);
if (!sport) {
sprintf(buf,
"Service lookup failed for source port \"%s\"",
sports);
logevent(buf);
}
}
if (sport && dport) {
if (type == 'L') {
pfd_addforward(host, dport, sport, ssh);
sprintf(buf, "Local port %.*s%.*s%d%.*s forwarding to"
" %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
logevent(buf);
} else {
struct ssh_rportfwd *pf;
pf = smalloc(sizeof(*pf));
strcpy(pf->dhost, host);
pf->dport = dport;
pf->sport = sport;
if (add234(ssh->rportfwds, pf) != pf) {
sprintf(buf,
"Duplicate remote port forwarding to %s:%d",
host, dport);
logevent(buf);
sfree(pf);
} else {
sprintf(buf, "Requesting remote port %.*s%.*s%d%.*s"
" forward to %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
logevent(buf);
ssh2_pkt_init(ssh, SSH2_MSG_GLOBAL_REQUEST);
ssh2_pkt_addstring(ssh, "tcpip-forward");
ssh2_pkt_addbool(ssh, 1);/* want reply */
if (cfg.rport_acceptall)
ssh2_pkt_addstring(ssh, "0.0.0.0");
else
ssh2_pkt_addstring(ssh, "127.0.0.1");
|
<
|
|
<
<
|
|
<
|
|
|
|
|
|
|
<
<
|
|
<
|
|
|
|
|
|
|
<
|
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
|
ssh->portfwd_strptr++;
dport = atoi(dports);
dserv = 0;
if (dport == 0) {
dserv = 1;
dport = net_service_lookup(dports);
if (!dport) {
logeventf(ssh, "Service lookup failed for destination"
" port \"%s\"", dports);
}
}
sport = atoi(sports);
sserv = 0;
if (sport == 0) {
sserv = 1;
sport = net_service_lookup(sports);
if (!sport) {
logeventf(ssh, "Service lookup failed for source"
" port \"%s\"", sports);
}
}
if (sport && dport) {
if (type == 'L') {
pfd_addforward(host, dport, sport, ssh);
logeventf(ssh, "Local port %.*s%.*s%d%.*s forwarding to"
" %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
} else {
struct ssh_rportfwd *pf;
pf = smalloc(sizeof(*pf));
strcpy(pf->dhost, host);
pf->dport = dport;
pf->sport = sport;
if (add234(ssh->rportfwds, pf) != pf) {
logeventf(ssh, "Duplicate remote port forwarding"
" to %s:%d", host, dport);
sfree(pf);
} else {
logeventf(ssh, "Requesting remote port %.*s%.*s%d%.*s"
" forward to %s:%.*s%.*s%d%.*s",
(int)(sserv ? strlen(sports) : 0), sports,
sserv, "(", sport, sserv, ")",
host,
(int)(dserv ? strlen(dports) : 0), dports,
dserv, "(", dport, dserv, ")");
ssh2_pkt_init(ssh, SSH2_MSG_GLOBAL_REQUEST);
ssh2_pkt_addstring(ssh, "tcpip-forward");
ssh2_pkt_addbool(ssh, 1);/* want reply */
if (cfg.rport_acceptall)
ssh2_pkt_addstring(ssh, "0.0.0.0");
else
ssh2_pkt_addstring(ssh, "127.0.0.1");
|
| ︙ | | | ︙ | |
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
|
pf.sport = ssh2_pkt_getuint32(ssh);
realpf = find234(ssh->rportfwds, &pf, NULL);
if (realpf == NULL) {
error = "Remote port is not recognised";
} else {
char *e = pfd_newconnect(&c->u.pfd.s, realpf->dhost,
realpf->dport, c);
char buf[1024];
sprintf(buf, "Received remote port open request for %s:%d",
realpf->dhost, realpf->dport);
logevent(buf);
if (e != NULL) {
sprintf(buf, "Port open failed: %s", e);
logevent(buf);
error = "Port open failed";
} else {
logevent("Forwarded port opened successfully");
c->type = CHAN_SOCKDATA;
}
}
} else if (typelen == 22 &&
|
<
|
|
<
|
<
|
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
|
pf.sport = ssh2_pkt_getuint32(ssh);
realpf = find234(ssh->rportfwds, &pf, NULL);
if (realpf == NULL) {
error = "Remote port is not recognised";
} else {
char *e = pfd_newconnect(&c->u.pfd.s, realpf->dhost,
realpf->dport, c);
logeventf(ssh, "Received remote port open request"
" for %s:%d", realpf->dhost, realpf->dport);
if (e != NULL) {
logeventf(ssh, "Port open failed: %s", e);
error = "Port open failed";
} else {
logevent("Forwarded port opened successfully");
c->type = CHAN_SOCKDATA;
}
}
} else if (typelen == 22 &&
|
| ︙ | | | ︙ | |
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
|
}
}
void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
{
struct ssh_channel *c = (struct ssh_channel *)channel;
Ssh ssh = c->ssh;
char buf[1024];
sprintf(buf, "Opening forwarded connection to %.512s:%d", hostname, port);
logevent(buf);
if (ssh->version == 1) {
send_packet(ssh, SSH1_MSG_PORT_OPEN,
PKT_INT, c->localid,
PKT_STR, hostname,
PKT_INT, port,
//PKT_STR, <org:orgport>,
|
<
|
<
|
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
|
}
}
void ssh_send_port_open(void *channel, char *hostname, int port, char *org)
{
struct ssh_channel *c = (struct ssh_channel *)channel;
Ssh ssh = c->ssh;
logeventf(ssh, "Opening forwarded connection to %s:%d", hostname, port);
if (ssh->version == 1) {
send_packet(ssh, SSH1_MSG_PORT_OPEN,
PKT_INT, c->localid,
PKT_STR, hostname,
PKT_INT, port,
//PKT_STR, <org:orgport>,
|
| ︙ | | | ︙ | |