| ︙ | | | ︙ | |
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
|
break;
case CHAN_SOCKDATA:
pfd_override_throttle(c->u.x11.s, enable);
break;
}
}
}
/*
* Handle the key exchange and user authentication phases.
*/
static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
{
int i, j;
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
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
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
|
break;
case CHAN_SOCKDATA:
pfd_override_throttle(c->u.x11.s, enable);
break;
}
}
}
/*
* Username and password input, abstracted off into reusable
* routines (hopefully even reusable between SSH1 and SSH2!).
*/
static char *ssh_userpass_input_buffer;
static int ssh_userpass_input_buflen;
static int ssh_userpass_input_bufpos;
static int ssh_userpass_input_echo;
/* Set up a username or password input loop on a given buffer. */
void setup_userpass_input(char *buffer, int buflen, int echo)
{
ssh_userpass_input_buffer = buffer;
ssh_userpass_input_buflen = buflen;
ssh_userpass_input_bufpos = 0;
ssh_userpass_input_echo = echo;
}
/*
* Process some terminal data in the course of username/password
* input. Returns >0 for success (line of input returned in
* buffer), <0 for failure (user hit ^C/^D, bomb out and exit), 0
* for inconclusive (keep waiting for more input please).
*/
int process_userpass_input(unsigned char *in, int inlen)
{
char c;
while (inlen--) {
switch (c = *in++) {
case 10:
case 13:
ssh_userpass_input_buffer[ssh_userpass_input_bufpos] = 0;
ssh_userpass_input_buffer[ssh_userpass_input_buflen-1] = 0;
return +1;
break;
case 8:
case 127:
if (ssh_userpass_input_bufpos > 0) {
if (ssh_userpass_input_echo)
c_write_str("\b \b");
ssh_userpass_input_bufpos--;
}
break;
case 21:
case 27:
while (ssh_userpass_input_bufpos > 0) {
if (ssh_userpass_input_echo)
c_write_str("\b \b");
ssh_userpass_input_bufpos--;
}
break;
case 3:
case 4:
return -1;
break;
default:
if (((c >= ' ' && c <= '~') ||
((unsigned char) c >= 160))
&& ssh_userpass_input_bufpos < ssh_userpass_input_buflen-1) {
ssh_userpass_input_buffer[ssh_userpass_input_bufpos++] = c;
if (ssh_userpass_input_echo)
c_write(&c, 1);
}
break;
}
}
return 0;
}
/*
* Handle the key exchange and user authentication phases.
*/
static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
{
int i, j;
|
| ︙ | | | ︙ | |
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
|
crReturn(0);
}
logevent("Successfully started encryption");
fflush(stdout);
{
static int pos = 0;
static char c;
if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
if (ssh_get_line && !ssh_getline_pw_only) {
if (!ssh_get_line("login as: ",
username, sizeof(username), FALSE)) {
/*
* get_line failed to get a username.
* Terminate.
*/
logevent("No username provided. Abandoning session.");
ssh_state = SSH_STATE_CLOSED;
crReturn(1);
}
} else {
c_write_str("login as: ");
ssh_send_ok = 1;
while (pos >= 0) {
crWaitUntil(!ispkt);
while (inlen--)
switch (c = *in++) {
case 10:
case 13:
username[pos] = 0;
pos = -1;
break;
case 8:
case 127:
if (pos > 0) {
c_write_str("\b \b");
pos--;
}
break;
case 21:
case 27:
while (pos > 0) {
c_write_str("\b \b");
pos--;
}
break;
case 3:
case 4:
cleanup_exit(0);
break;
default:
if (((c >= ' ' && c <= '~') ||
((unsigned char) c >= 160))
&& pos < sizeof(username)-1) {
username[pos++] = c;
c_write(&c, 1);
}
break;
}
}
c_write_str("\r\n");
username[strcspn(username, "\n\r")] = '\0';
}
} else {
strncpy(username, cfg.username, 99);
username[99] = '\0';
}
send_packet(SSH1_CMSG_USER, PKT_STR, username, PKT_END);
|
<
<
>
|
>
>
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
|
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
|
crReturn(0);
}
logevent("Successfully started encryption");
fflush(stdout);
{
if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
if (ssh_get_line && !ssh_getline_pw_only) {
if (!ssh_get_line("login as: ",
username, sizeof(username), FALSE)) {
/*
* get_line failed to get a username.
* Terminate.
*/
logevent("No username provided. Abandoning session.");
ssh_state = SSH_STATE_CLOSED;
crReturn(1);
}
} else {
static int ret;
c_write_str("login as: ");
ssh_send_ok = 1;
setup_userpass_input(username, sizeof(username), 1);
do {
crWaitUntil(!ispkt);
ret = process_userpass_input(in, inlen);
} while (ret == 0);
if (ret < 0)
cleanup_exit(0);
c_write_str("\r\n");
}
} else {
strncpy(username, cfg.username, 99);
username[99] = '\0';
}
send_packet(SSH1_CMSG_USER, PKT_STR, username, PKT_END);
|
| ︙ | | | ︙ | |
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
|
connection_fatal("Unable to authenticate");
ssh_state = SSH_STATE_CLOSED;
crReturn(1);
}
} else {
/* Prompt may have come from server. We've munged it a bit, so
* we know it to be zero-terminated at least once. */
c_write_untrusted(prompt, strlen(prompt));
pos = 0;
ssh_send_ok = 1;
while (pos >= 0) {
crWaitUntil(!ispkt);
while (inlen--)
switch (c = *in++) {
case 10:
case 13:
password[pos] = 0;
pos = -1;
break;
case 8:
case 127:
if (pos > 0)
pos--;
break;
case 21:
case 27:
pos = 0;
break;
case 3:
case 4:
cleanup_exit(0);
break;
default:
if (pos < sizeof(password)-1)
password[pos++] = c;
break;
}
}
c_write_str("\r\n");
}
tryauth:
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
/*
* Try public key authentication with the specified
|
>
|
<
>
>
>
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
|
connection_fatal("Unable to authenticate");
ssh_state = SSH_STATE_CLOSED;
crReturn(1);
}
} else {
/* Prompt may have come from server. We've munged it a bit, so
* we know it to be zero-terminated at least once. */
static int ret;
c_write_untrusted(prompt, strlen(prompt));
pos = 0;
setup_userpass_input(password, sizeof(password), 0);
do {
crWaitUntil(!ispkt);
ret = process_userpass_input(in, inlen);
} while (ret == 0);
if (ret < 0)
cleanup_exit(0);
c_write_str("\r\n");
}
tryauth:
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
/*
* Try public key authentication with the specified
|
| ︙ | | | ︙ | |
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
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
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
|
* accepted, _or_ they will type a password. If they mistype
* the username they will want to be able to get back and
* retype it!
*/
username[0] = '\0';
got_username = FALSE;
do {
static int pos;
static char c;
/*
* Get a username.
*/
pos = 0;
if (got_username && !cfg.change_username) {
/*
* We got a username last time round this loop, and
* with change_username turned off we don't try to get
* it again.
*/
} else if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
if (ssh_get_line && !ssh_getline_pw_only) {
if (!ssh_get_line("login as: ",
username, sizeof(username), FALSE)) {
/*
* get_line failed to get a username.
* Terminate.
*/
logevent("No username provided. Abandoning session.");
ssh_state = SSH_STATE_CLOSED;
crReturnV;
}
} else {
c_write_str("login as: ");
ssh_send_ok = 1;
while (pos >= 0) {
crWaitUntilV(!ispkt);
while (inlen--)
switch (c = *in++) {
case 10:
case 13:
username[pos] = 0;
pos = -1;
break;
case 8:
case 127:
if (pos > 0) {
c_write_str("\b \b");
pos--;
}
break;
case 21:
case 27:
while (pos > 0) {
c_write_str("\b \b");
pos--;
}
break;
case 3:
case 4:
cleanup_exit(0);
break;
default:
if (((c >= ' ' && c <= '~') ||
((unsigned char) c >= 160))
&& pos < sizeof(username)-1) {
username[pos++] = c;
c_write(&c, 1);
}
break;
}
}
}
c_write_str("\r\n");
username[strcspn(username, "\n\r")] = '\0';
} else {
char stuff[200];
strncpy(username, cfg.username, 99);
username[99] = '\0';
|
<
<
<
<
>
<
>
>
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
<
|
4107
4108
4109
4110
4111
4112
4113
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
4148
4149
4150
4151
4152
|
* accepted, _or_ they will type a password. If they mistype
* the username they will want to be able to get back and
* retype it!
*/
username[0] = '\0';
got_username = FALSE;
do {
/*
* Get a username.
*/
if (got_username && !cfg.change_username) {
/*
* We got a username last time round this loop, and
* with change_username turned off we don't try to get
* it again.
*/
} else if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
if (ssh_get_line && !ssh_getline_pw_only) {
if (!ssh_get_line("login as: ",
username, sizeof(username), FALSE)) {
/*
* get_line failed to get a username.
* Terminate.
*/
logevent("No username provided. Abandoning session.");
ssh_state = SSH_STATE_CLOSED;
crReturnV;
}
} else {
static int ret;
c_write_str("login as: ");
ssh_send_ok = 1;
setup_userpass_input(username, sizeof(username), 1);
do {
crWaitUntilV(!ispkt);
ret = process_userpass_input(in, inlen);
} while (ret == 0);
if (ret < 0)
cleanup_exit(0);
}
c_write_str("\r\n");
username[strcspn(username, "\n\r")] = '\0';
} else {
char stuff[200];
strncpy(username, cfg.username, 99);
username[99] = '\0';
|
| ︙ | | | ︙ | |
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
|
can_keyb_inter = cfg.try_ki_auth &&
in_commasep_string("keyboard-interactive", methods, methlen);
}
method = 0;
ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
if (!method && can_pubkey && agent_exists() && !tried_agent) {
/*
* Attempt public-key authentication using Pageant.
*/
static unsigned char request[5], *response, *p;
static int responselen;
static int i, nkeys;
|
>
>
>
>
>
>
>
>
|
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
|
can_keyb_inter = cfg.try_ki_auth &&
in_commasep_string("keyboard-interactive", methods, methlen);
}
method = 0;
ssh_pkt_ctx &= ~SSH2_PKTCTX_AUTH_MASK;
/*
* Most password/passphrase prompts will be
* non-echoing, so we set this to 0 by default.
* Exception is that some keyboard-interactive prompts
* can be echoing, in which case we'll set this to 1.
*/
echo = 0;
if (!method && can_pubkey && agent_exists() && !tried_agent) {
/*
* Attempt public-key authentication using Pageant.
*/
static unsigned char request[5], *response, *p;
static int responselen;
static int i, nkeys;
|
| ︙ | | | ︙ | |
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
|
int name_len, inst_len, lang_len;
ssh2_pkt_getstring(&name, &name_len);
ssh2_pkt_getstring(&inst, &inst_len);
ssh2_pkt_getstring(&lang, &lang_len);
if (name_len > 0) {
c_write_untrusted(name, name_len);
c_write_str("\n");
}
if (inst_len > 0) {
c_write_untrusted(inst, inst_len);
c_write_str("\n");
}
num_prompts = ssh2_pkt_getuint32();
}
/*
* If there are prompts remaining in the packet,
* display one and get a response.
|
|
|
|
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
|
int name_len, inst_len, lang_len;
ssh2_pkt_getstring(&name, &name_len);
ssh2_pkt_getstring(&inst, &inst_len);
ssh2_pkt_getstring(&lang, &lang_len);
if (name_len > 0) {
c_write_untrusted(name, name_len);
c_write_str("\r\n");
}
if (inst_len > 0) {
c_write_untrusted(inst, inst_len);
c_write_str("\r\n");
}
num_prompts = ssh2_pkt_getuint32();
}
/*
* If there are prompts remaining in the packet,
* display one and get a response.
|
| ︙ | | | ︙ | |
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
|
ssh2_pkt_send();
logevent("Unable to authenticate");
connection_fatal("Unable to authenticate");
ssh_state = SSH_STATE_CLOSED;
crReturnV;
}
} else {
static int pos = 0;
static char c;
c_write_untrusted(pwprompt, strlen(pwprompt));
ssh_send_ok = 1;
pos = 0;
while (pos >= 0) {
crWaitUntilV(!ispkt);
while (inlen--)
switch (c = *in++) {
case 10:
case 13:
password[pos] = 0;
pos = -1;
break;
case 8:
case 127:
if (pos > 0)
pos--;
break;
case 21:
case 27:
pos = 0;
break;
case 3:
case 4:
cleanup_exit(0);
break;
default:
if (pos < sizeof(password)-1)
password[pos++] = c;
break;
}
}
c_write_str("\r\n");
}
}
if (method == AUTH_PUBLICKEY_FILE) {
/*
* We have our passphrase. Now try the actual authentication.
|
|
<
<
>
|
<
>
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
|
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
|
ssh2_pkt_send();
logevent("Unable to authenticate");
connection_fatal("Unable to authenticate");
ssh_state = SSH_STATE_CLOSED;
crReturnV;
}
} else {
static int ret;
c_write_untrusted(pwprompt, strlen(pwprompt));
ssh_send_ok = 1;
setup_userpass_input(password, sizeof(password), echo);
do {
crWaitUntilV(!ispkt);
ret = process_userpass_input(in, inlen);
} while (ret == 0);
if (ret < 0)
cleanup_exit(0);
c_write_str("\r\n");
}
}
if (method == AUTH_PUBLICKEY_FILE) {
/*
* We have our passphrase. Now try the actual authentication.
|
| ︙ | | | ︙ | |