| 30 |
#include "ttxssh.h" |
#include "ttxssh.h" |
| 31 |
#include "util.h" |
#include "util.h" |
| 32 |
#include "resource.h" |
#include "resource.h" |
| 33 |
|
#include "libputty.h" |
| 34 |
|
|
| 35 |
#include <openssl/bn.h> |
#include <openssl/bn.h> |
| 36 |
#include <openssl/evp.h> |
#include <openssl/evp.h> |
| 1459 |
int supported_ciphers; |
int supported_ciphers; |
| 1460 |
char FAR *inmsg; |
char FAR *inmsg; |
| 1461 |
Key hostkey; |
Key hostkey; |
| 1462 |
|
int supported_types; |
| 1463 |
|
|
| 1464 |
if (!grab_payload(pvar, 14)) |
if (!grab_payload(pvar, 14)) |
| 1465 |
return FALSE; |
return FALSE; |
| 1511 |
supported_ciphers, |
supported_ciphers, |
| 1512 |
supported_ciphers)) |
supported_ciphers)) |
| 1513 |
return FALSE; |
return FALSE; |
| 1514 |
|
|
| 1515 |
|
// SSH1 サーバは、サポートされている認証方式を送ってくる |
| 1516 |
|
// RSA が有効なら PAGEANT を有効にする |
| 1517 |
|
supported_types = get_uint32(inmsg + protocol_flags_pos + 8); |
| 1518 |
|
if ((supported_types & (1 << SSH_AUTH_RSA)) > 0) { |
| 1519 |
|
supported_types |= (1 << SSH_AUTH_PAGEANT); |
| 1520 |
|
} |
| 1521 |
if (!AUTH_set_supported_auth_types(pvar, |
if (!AUTH_set_supported_auth_types(pvar, |
| 1522 |
get_uint32(inmsg + protocol_flags_pos + 8))) |
supported_types)) |
| 1523 |
return FALSE; |
return FALSE; |
| 1524 |
|
|
| 1525 |
/* this must be the LAST THING in this function, since it can cause |
/* this must be the LAST THING in this function, since it can cause |
| 2186 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 2187 |
begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16); |
begin_send_packet(pvar, SSH_CMSG_AUTH_RSA_RESPONSE, 16); |
| 2188 |
|
|
| 2189 |
if (CRYPT_generate_RSA_challenge_response |
if (pvar->auth_state.cur_cred.method == SSH_AUTH_RSA) { |
| 2190 |
(pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) { |
if (CRYPT_generate_RSA_challenge_response |
| 2191 |
|
(pvar, pvar->ssh_state.payload + 2, challenge_bytes, outmsg)) { |
| 2192 |
|
|
| 2193 |
// セッション複製時にパスワードを使い回したいので、ここでのリソース解放はやめる。 |
// セッション複製時にパスワードを使い回したいので、ここでのリソース解放はやめる。 |
| 2194 |
// socket close時にもこの関数は呼ばれているので、たぶん問題ない。(2005.4.8 yutaka) |
// socket close時にもこの関数は呼ばれているので、たぶん問題ない。(2005.4.8 yutaka) |
| 2195 |
#if 0 |
#if 0 |
| 2196 |
//AUTH_destroy_cur_cred(pvar); |
//AUTH_destroy_cur_cred(pvar); |
| 2197 |
#endif |
#endif |
| 2198 |
|
|
| 2199 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 2200 |
|
|
| 2201 |
enque_simple_auth_handlers(pvar); |
enque_simple_auth_handlers(pvar); |
| 2202 |
} else { |
} else { |
| 2203 |
UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar, |
UTIL_get_lang_msg("MSG_SSH_DECRYPT_RSA_ERROR", pvar, |
| 2204 |
"An error occurred while decrypting the RSA challenge.\n" |
"An error occurred while decrypting the RSA challenge.\n" |
| 2205 |
"Perhaps the key file is corrupted."); |
"Perhaps the key file is corrupted."); |
| 2206 |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
notify_fatal_error(pvar, pvar->ts->UIMsg); |
| 2207 |
|
} |
| 2208 |
|
} |
| 2209 |
|
else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) { |
| 2210 |
|
unsigned char *hash; |
| 2211 |
|
int pubkeylen, hashlen; |
| 2212 |
|
|
| 2213 |
|
/* Pageant にハッシュを計算してもらう */ |
| 2214 |
|
pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey, |
| 2215 |
|
pvar->pageant_keylistlen); |
| 2216 |
|
hash = putty_hash_ssh1_challenge(pvar->pageant_curkey, |
| 2217 |
|
pubkeylen, |
| 2218 |
|
pvar->ssh_state.payload, |
| 2219 |
|
challenge_bytes + 2, |
| 2220 |
|
&hashlen); |
| 2221 |
} |
} |
| 2222 |
} |
} |
| 2223 |
|
|
| 2334 |
enque_handlers(pvar, 2, RSA_msgs, RSA_handlers); |
enque_handlers(pvar, 2, RSA_msgs, RSA_handlers); |
| 2335 |
break; |
break; |
| 2336 |
} |
} |
| 2337 |
|
case SSH_AUTH_PAGEANT:{ |
| 2338 |
|
unsigned char FAR *outmsg; |
| 2339 |
|
unsigned char *pubkey; |
| 2340 |
|
int len, bn_bytes; |
| 2341 |
|
|
| 2342 |
|
pubkey = pvar->pageant_curkey + 4; |
| 2343 |
|
len = get_ushort16_MSBfirst(pubkey); |
| 2344 |
|
bn_bytes = (len + 7) / 8; |
| 2345 |
|
pubkey += 2 + bn_bytes; |
| 2346 |
|
len = get_ushort16_MSBfirst(pubkey); |
| 2347 |
|
bn_bytes = (len + 7) / 8; |
| 2348 |
|
pubkey += 2; |
| 2349 |
|
outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + bn_bytes); |
| 2350 |
|
|
| 2351 |
|
notify_verbose_message(pvar, |
| 2352 |
|
"Trying RSA authentication...", |
| 2353 |
|
LOG_LEVEL_VERBOSE); |
| 2354 |
|
|
| 2355 |
|
set_ushort16_MSBfirst(outmsg, bn_bytes * 8); |
| 2356 |
|
memcpy(outmsg + 2, pubkey, bn_bytes); |
| 2357 |
|
/* don't destroy the current credentials yet */ |
| 2358 |
|
enque_handlers(pvar, 2, RSA_msgs, RSA_handlers); |
| 2359 |
|
break; |
| 2360 |
|
} |
| 2361 |
case SSH_AUTH_TIS:{ |
case SSH_AUTH_TIS:{ |
| 2362 |
if (cred->password == NULL) { |
if (cred->password == NULL) { |
| 2363 |
unsigned char FAR *outmsg = |
unsigned char FAR *outmsg = |
| 6080 |
| 1 << SSH2_CIPHER_AES192 | 1 << SSH2_CIPHER_AES256 |
| 1 << SSH2_CIPHER_AES192 | 1 << SSH2_CIPHER_AES256 |
| 6081 |
| 1 << SSH2_CIPHER_BLOWFISH |
| 1 << SSH2_CIPHER_BLOWFISH |
| 6082 |
); |
); |
| 6083 |
int type = (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA) | (1 << SSH_AUTH_TIS); |
int type = (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA) | |
| 6084 |
|
(1 << SSH_AUTH_TIS) | (1 << SSH_AUTH_PAGEANT); |
| 6085 |
|
|
| 6086 |
notify_verbose_message(pvar, "SSH2_MSG_NEWKEYS is received(DH key generation is completed).", LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, "SSH2_MSG_NEWKEYS is received(DH key generation is completed).", LOG_LEVEL_VERBOSE); |
| 6087 |
|
|
| 6365 |
static BOOL handle_SSH2_authrequest(PTInstVar pvar) |
static BOOL handle_SSH2_authrequest(PTInstVar pvar) |
| 6366 |
{ |
{ |
| 6367 |
buffer_t *msg = NULL; |
buffer_t *msg = NULL; |
| 6368 |
char *s; |
char *s, *username; |
| 6369 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 6370 |
int len; |
int len; |
| 6371 |
char *connect_id = "ssh-connection"; |
char *connect_id = "ssh-connection"; |
| 6380 |
|
|
| 6381 |
// ペイロードの構築 |
// ペイロードの構築 |
| 6382 |
if (pvar->ssh2_autologin == 1) { // SSH2自動ログイン |
if (pvar->ssh2_autologin == 1) { // SSH2自動ログイン |
| 6383 |
s = pvar->ssh2_username; |
username = pvar->ssh2_username; |
| 6384 |
} else { |
} else { |
| 6385 |
s = pvar->auth_state.user; // ユーザ名 |
username = pvar->auth_state.user; // ユーザ名 |
| 6386 |
} |
} |
| 6387 |
buffer_put_string(msg, s, strlen(s)); |
buffer_put_string(msg, username, strlen(username)); |
| 6388 |
|
|
| 6389 |
if (!pvar->tryed_ssh2_authlist) { // "none"メソッドの送信 |
if (!pvar->tryed_ssh2_authlist) { // "none"メソッドの送信 |
| 6390 |
// 認証リストをサーバから取得する。 |
// 認証リストをサーバから取得する。 |
| 6442 |
// セッションID |
// セッションID |
| 6443 |
buffer_append_length(signbuf, pvar->session_id, pvar->session_id_len); |
buffer_append_length(signbuf, pvar->session_id, pvar->session_id_len); |
| 6444 |
buffer_put_char(signbuf, SSH2_MSG_USERAUTH_REQUEST); |
buffer_put_char(signbuf, SSH2_MSG_USERAUTH_REQUEST); |
| 6445 |
s = pvar->auth_state.user; // ユーザ名 |
s = username; // ユーザ名 |
| 6446 |
buffer_put_string(signbuf, s, strlen(s)); |
buffer_put_string(signbuf, s, strlen(s)); |
| 6447 |
s = connect_id; |
s = connect_id; |
| 6448 |
buffer_put_string(signbuf, s, strlen(s)); |
buffer_put_string(signbuf, s, strlen(s)); |
| 6478 |
buffer_free(signbuf); |
buffer_free(signbuf); |
| 6479 |
free(signature); |
free(signature); |
| 6480 |
|
|
| 6481 |
|
} else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) { // Pageant |
| 6482 |
|
unsigned char *puttykey; |
| 6483 |
|
|
| 6484 |
|
s = connect_id; |
| 6485 |
|
buffer_put_string(msg, s, strlen(s)); |
| 6486 |
|
s = "publickey"; |
| 6487 |
|
buffer_put_string(msg, s, strlen(s)); |
| 6488 |
|
buffer_put_char(msg, 0); // false |
| 6489 |
|
|
| 6490 |
|
if (pvar->pageant_keycurrent != 0) { |
| 6491 |
|
// 直前の鍵をスキップ |
| 6492 |
|
len = get_uint32_MSBfirst(pvar->pageant_curkey); |
| 6493 |
|
pvar->pageant_curkey += 4 + len; |
| 6494 |
|
// 直前の鍵のコメントをスキップ |
| 6495 |
|
len = get_uint32_MSBfirst(pvar->pageant_curkey); |
| 6496 |
|
pvar->pageant_curkey += 4 + len; |
| 6497 |
|
// 次の鍵へ来る |
| 6498 |
|
} |
| 6499 |
|
puttykey = pvar->pageant_curkey; |
| 6500 |
|
|
| 6501 |
|
// アルゴリズムをコピーする |
| 6502 |
|
len = get_uint32_MSBfirst(puttykey+4); |
| 6503 |
|
buffer_put_string(msg, puttykey+8, len); |
| 6504 |
|
|
| 6505 |
|
// 鍵をコピーする |
| 6506 |
|
len = get_uint32_MSBfirst(puttykey); |
| 6507 |
|
puttykey += 4; |
| 6508 |
|
buffer_put_string(msg, puttykey, len); |
| 6509 |
|
puttykey += len; |
| 6510 |
|
|
| 6511 |
|
pvar->pageant_keycurrent++; |
| 6512 |
|
|
| 6513 |
} else { |
} else { |
| 6514 |
goto error; |
goto error; |
| 6515 |
|
|
| 6529 |
// keyboard-interactive method |
// keyboard-interactive method |
| 6530 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_INFO_REQUEST); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_INFO_REQUEST); |
| 6531 |
} |
} |
| 6532 |
|
else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) { |
| 6533 |
|
// Pageant |
| 6534 |
|
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_PK_OK); |
| 6535 |
|
} |
| 6536 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_SUCCESS); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_SUCCESS); |
| 6537 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_FAILURE); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_FAILURE); |
| 6538 |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_BANNER); |
SSH2_dispatch_add_message(SSH2_MSG_USERAUTH_BANNER); |
| 6539 |
SSH2_dispatch_add_message(SSH2_MSG_DEBUG); // support for authorized_keys command (2006.2.23 yutaka) |
SSH2_dispatch_add_message(SSH2_MSG_DEBUG); // support for authorized_keys command (2006.2.23 yutaka) |
| 6540 |
|
|
| 6541 |
{ |
{ |
| 6542 |
char buf[128]; |
char buf[128]; |
| 6543 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 6544 |
"SSH2_MSG_USERAUTH_REQUEST was sent(method %d)", |
"SSH2_MSG_USERAUTH_REQUEST was sent(method %d)", |
| 6545 |
pvar->auth_state.cur_cred.method); |
pvar->auth_state.cur_cred.method); |
| 6789 |
} |
} |
| 6790 |
if (strstr(cstring, "publickey")) { |
if (strstr(cstring, "publickey")) { |
| 6791 |
type |= (1 << SSH_AUTH_RSA); |
type |= (1 << SSH_AUTH_RSA); |
| 6792 |
|
type |= (1 << SSH_AUTH_PAGEANT); |
| 6793 |
} |
} |
| 6794 |
if (strstr(cstring, "keyboard-interactive")) { |
if (strstr(cstring, "keyboard-interactive")) { |
| 6795 |
type |= (1 << SSH_AUTH_TIS); |
type |= (1 << SSH_AUTH_TIS); |
| 6831 |
//notify_closed_connection(pvar); |
//notify_closed_connection(pvar); |
| 6832 |
|
|
| 6833 |
// retry countの追加 (2005.3.10 yutaka) |
// retry countの追加 (2005.3.10 yutaka) |
| 6834 |
pvar->userauth_retry_count++; |
if (pvar->auth_state.cur_cred.method != SSH_AUTH_PAGEANT) { |
| 6835 |
|
pvar->userauth_retry_count++; |
| 6836 |
|
} |
| 6837 |
|
else { |
| 6838 |
|
if (pvar->pageant_keycount <= pvar->pageant_keycurrent || |
| 6839 |
|
pvar->pageant_keyfinal) { |
| 6840 |
|
// 全ての鍵を試し終わった |
| 6841 |
|
// または、TRUE でのログインに失敗してここに来た |
| 6842 |
|
safefree(pvar->pageant_key); |
| 6843 |
|
pvar->userauth_retry_count++; |
| 6844 |
|
} |
| 6845 |
|
else { |
| 6846 |
|
// まだ鍵がある |
| 6847 |
|
handle_SSH2_authrequest(pvar); |
| 6848 |
|
return TRUE; |
| 6849 |
|
} |
| 6850 |
|
} |
| 6851 |
|
|
| 6852 |
if (pvar->ssh2_autologin == 1) { |
if (pvar->ssh2_autologin == 1) { |
| 6853 |
char uimsg[MAX_UIMSG]; |
char uimsg[MAX_UIMSG]; |
| 6887 |
|
|
| 6888 |
|
|
| 6889 |
// SSH2 keyboard-interactive methodの SSH2_MSG_USERAUTH_INFO_REQUEST 処理関数 |
// SSH2 keyboard-interactive methodの SSH2_MSG_USERAUTH_INFO_REQUEST 処理関数 |
| 6890 |
|
// |
| 6891 |
|
// 現状の実装では同じメッセージ番号が存在できないので、 |
| 6892 |
|
// SSH2 publickey で Pageant を使っているときの |
| 6893 |
|
// SSH2_MSG_USERAUTH_PK_OK もこの関数で処理する。(2007.2.12 maya) |
| 6894 |
|
// |
| 6895 |
// |
// |
| 6896 |
// ※メモ:OpenSSHでPAMを有効にする方法 |
// ※メモ:OpenSSHでPAMを有効にする方法 |
| 6897 |
//・ビルド |
//・ビルド |
| 6907 |
// (2005.1.23 yutaka) |
// (2005.1.23 yutaka) |
| 6908 |
BOOL handle_SSH2_userauth_inforeq(PTInstVar pvar) |
BOOL handle_SSH2_userauth_inforeq(PTInstVar pvar) |
| 6909 |
{ |
{ |
| 6910 |
int len; |
if (pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) { |
| 6911 |
char *data; |
// SSH2_MSG_USERAUTH_INFO_REQUEST |
| 6912 |
int slen = 0, num, echo; |
int len; |
| 6913 |
char *s, *prompt = NULL; |
char *data; |
| 6914 |
buffer_t *msg; |
int slen = 0, num, echo; |
| 6915 |
unsigned char *outmsg; |
char *s, *prompt = NULL; |
| 6916 |
int i; |
buffer_t *msg; |
| 6917 |
|
unsigned char *outmsg; |
| 6918 |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
int i; |
|
data = pvar->ssh_state.payload; |
|
|
// パケットサイズ - (パディングサイズ+1);真のパケットサイズ |
|
|
len = pvar->ssh_state.payloadlen; |
|
|
|
|
|
//debug_print(10, data, len); |
|
| 6919 |
|
|
| 6920 |
///////// step1 |
notify_verbose_message(pvar, "SSH2_MSG_USERAUTH_INFO_REQUEST is received.", LOG_LEVEL_VERBOSE); |
|
// get string |
|
|
slen = get_uint32_MSBfirst(data); |
|
|
data += 4; |
|
|
s = data; // name |
|
|
data += slen; |
|
| 6921 |
|
|
| 6922 |
// get string |
// 6byte(サイズ+パディング+タイプ)を取り除いた以降のペイロード |
| 6923 |
slen = get_uint32_MSBfirst(data); |
data = pvar->ssh_state.payload; |
| 6924 |
data += 4; |
// パケットサイズ - (パディングサイズ+1);真のパケットサイズ |
| 6925 |
s = data; // instruction |
len = pvar->ssh_state.payloadlen; |
|
data += slen; |
|
| 6926 |
|
|
| 6927 |
// get string |
//debug_print(10, data, len); |
|
slen = get_uint32_MSBfirst(data); |
|
|
data += 4; |
|
|
s = data; // language tag |
|
|
data += slen; |
|
| 6928 |
|
|
| 6929 |
// num-prompts |
///////// step1 |
| 6930 |
num = get_uint32_MSBfirst(data); |
// get string |
| 6931 |
data += 4; |
slen = get_uint32_MSBfirst(data); |
| 6932 |
|
data += 4; |
| 6933 |
|
s = data; // name |
| 6934 |
|
data += slen; |
| 6935 |
|
|
| 6936 |
///////// step2 |
// get string |
| 6937 |
// サーバへパスフレーズを送る |
slen = get_uint32_MSBfirst(data); |
| 6938 |
msg = buffer_init(); |
data += 4; |
| 6939 |
if (msg == NULL) { |
s = data; // instruction |
| 6940 |
// TODO: error check |
data += slen; |
|
return FALSE; |
|
|
} |
|
|
buffer_put_int(msg, num); |
|
| 6941 |
|
|
|
// プロンプトの数だけ prompt & echo が繰り返される。 |
|
|
for (i = 0 ; i < num ; i++) { |
|
| 6942 |
// get string |
// get string |
| 6943 |
slen = get_uint32_MSBfirst(data); |
slen = get_uint32_MSBfirst(data); |
| 6944 |
data += 4; |
data += 4; |
| 6945 |
prompt = data; // prompt |
s = data; // language tag |
| 6946 |
data += slen; |
data += slen; |
| 6947 |
|
|
| 6948 |
// get boolean |
// num-prompts |
| 6949 |
echo = data[0]; |
num = get_uint32_MSBfirst(data); |
| 6950 |
data += 1; |
data += 4; |
| 6951 |
|
|
| 6952 |
// keyboard-interactive method (2005.3.12 yutaka) |
///////// step2 |
| 6953 |
if (pvar->keyboard_interactive_password_input == 0 && |
// サーバへパスフレーズを送る |
| 6954 |
pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) { |
msg = buffer_init(); |
| 6955 |
AUTH_set_TIS_mode(pvar, prompt, slen); |
if (msg == NULL) { |
| 6956 |
AUTH_advance_to_next_cred(pvar); |
// TODO: error check |
| 6957 |
pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS; |
return FALSE; |
|
//try_send_credentials(pvar); |
|
|
buffer_free(msg); |
|
|
return TRUE; |
|
| 6958 |
} |
} |
| 6959 |
|
buffer_put_int(msg, num); |
| 6960 |
|
|
| 6961 |
// TODO: ここでプロンプトを表示してユーザから入力させるのが正解。 |
// プロンプトの数だけ prompt & echo が繰り返される。 |
| 6962 |
s = pvar->auth_state.cur_cred.password; |
for (i = 0 ; i < num ; i++) { |
| 6963 |
buffer_put_string(msg, s, strlen(s)); |
// get string |
| 6964 |
|
slen = get_uint32_MSBfirst(data); |
| 6965 |
|
data += 4; |
| 6966 |
|
prompt = data; // prompt |
| 6967 |
|
data += slen; |
| 6968 |
|
|
| 6969 |
|
// get boolean |
| 6970 |
|
echo = data[0]; |
| 6971 |
|
data += 1; |
| 6972 |
|
|
| 6973 |
|
// keyboard-interactive method (2005.3.12 yutaka) |
| 6974 |
|
if (pvar->keyboard_interactive_password_input == 0 && |
| 6975 |
|
pvar->auth_state.cur_cred.method == SSH_AUTH_TIS) { |
| 6976 |
|
AUTH_set_TIS_mode(pvar, prompt, slen); |
| 6977 |
|
AUTH_advance_to_next_cred(pvar); |
| 6978 |
|
pvar->ssh_state.status_flags &= ~STATUS_DONT_SEND_CREDENTIALS; |
| 6979 |
|
//try_send_credentials(pvar); |
| 6980 |
|
buffer_free(msg); |
| 6981 |
|
return TRUE; |
| 6982 |
|
} |
| 6983 |
|
|
| 6984 |
|
// TODO: ここでプロンプトを表示してユーザから入力させるのが正解。 |
| 6985 |
|
s = pvar->auth_state.cur_cred.password; |
| 6986 |
|
buffer_put_string(msg, s, strlen(s)); |
| 6987 |
|
} |
| 6988 |
|
|
| 6989 |
|
len = buffer_len(msg); |
| 6990 |
|
outmsg = begin_send_packet(pvar, SSH2_MSG_USERAUTH_INFO_RESPONSE, len); |
| 6991 |
|
memcpy(outmsg, buffer_ptr(msg), len); |
| 6992 |
|
finish_send_packet(pvar); |
| 6993 |
|
buffer_free(msg); |
| 6994 |
} |
} |
| 6995 |
|
else { // SSH_AUTH_PAGEANT |
| 6996 |
|
// SSH2_MSG_USERAUTH_PK_OK |
| 6997 |
|
buffer_t *msg = NULL; |
| 6998 |
|
char *s, *username; |
| 6999 |
|
unsigned char *outmsg; |
| 7000 |
|
int len; |
| 7001 |
|
char *connect_id = "ssh-connection"; |
| 7002 |
|
|
| 7003 |
len = buffer_len(msg); |
unsigned char *puttykey; |
| 7004 |
outmsg = begin_send_packet(pvar, SSH2_MSG_USERAUTH_INFO_RESPONSE, len); |
buffer_t *signbuf; |
| 7005 |
memcpy(outmsg, buffer_ptr(msg), len); |
unsigned char *signmsg; |
| 7006 |
finish_send_packet(pvar); |
unsigned char *signedmsg; |
| 7007 |
buffer_free(msg); |
int signedlen; |
| 7008 |
|
|
| 7009 |
|
notify_verbose_message(pvar, "SSH2_MSG_USERAUTH_PK_OK is received.", LOG_LEVEL_VERBOSE); |
| 7010 |
|
|
| 7011 |
|
if (pvar->ssh2_autologin == 1) { // SSH2自動ログイン |
| 7012 |
|
username = pvar->ssh2_username; |
| 7013 |
|
} else { |
| 7014 |
|
username = pvar->auth_state.user; // ユーザ名 |
| 7015 |
|
} |
| 7016 |
|
|
| 7017 |
|
// 署名するデータを作成 |
| 7018 |
|
signbuf = buffer_init(); |
| 7019 |
|
if (signbuf == NULL) { |
| 7020 |
|
safefree(pvar->pageant_key); |
| 7021 |
|
return FALSE; |
| 7022 |
|
} |
| 7023 |
|
buffer_append_length(signbuf, pvar->session_id, pvar->session_id_len); |
| 7024 |
|
buffer_put_char(signbuf, SSH2_MSG_USERAUTH_REQUEST); |
| 7025 |
|
s = username; // ユーザ名 |
| 7026 |
|
buffer_put_string(signbuf, s, strlen(s)); |
| 7027 |
|
s = connect_id; |
| 7028 |
|
buffer_put_string(signbuf, s, strlen(s)); |
| 7029 |
|
s = "publickey"; |
| 7030 |
|
buffer_put_string(signbuf, s, strlen(s)); |
| 7031 |
|
buffer_put_char(signbuf, 1); // true |
| 7032 |
|
|
| 7033 |
|
puttykey = pvar->pageant_curkey; |
| 7034 |
|
|
| 7035 |
|
// アルゴリズムをコピーする |
| 7036 |
|
len = get_uint32_MSBfirst(puttykey+4); |
| 7037 |
|
buffer_put_string(signbuf, puttykey+8, len); |
| 7038 |
|
|
| 7039 |
|
// 鍵をコピーする |
| 7040 |
|
len = get_uint32_MSBfirst(puttykey); |
| 7041 |
|
puttykey += 4; |
| 7042 |
|
buffer_put_string(signbuf, puttykey, len); |
| 7043 |
|
puttykey += len; |
| 7044 |
|
|
| 7045 |
|
// Pageant に署名してもらう |
| 7046 |
|
signmsg = (unsigned char *)malloc(signbuf->len + 4); |
| 7047 |
|
set_uint32_MSBfirst(signmsg, signbuf->len); |
| 7048 |
|
memcpy(signmsg + 4, signbuf->buf, signbuf->len); |
| 7049 |
|
signedmsg = putty_sign_ssh2_key(pvar->pageant_curkey, |
| 7050 |
|
signmsg, &signedlen); |
| 7051 |
|
buffer_free(signbuf); |
| 7052 |
|
if (signedmsg == NULL) { |
| 7053 |
|
safefree(pvar->pageant_key); |
| 7054 |
|
return FALSE; |
| 7055 |
|
} |
| 7056 |
|
|
| 7057 |
|
|
| 7058 |
|
// ペイロードの構築 |
| 7059 |
|
msg = buffer_init(); |
| 7060 |
|
if (msg == NULL) { |
| 7061 |
|
safefree(pvar->pageant_key); |
| 7062 |
|
safefree(signedmsg); |
| 7063 |
|
return FALSE; |
| 7064 |
|
} |
| 7065 |
|
s = username; // ユーザ名 |
| 7066 |
|
buffer_put_string(msg, s, strlen(s)); |
| 7067 |
|
s = connect_id; |
| 7068 |
|
buffer_put_string(msg, s, strlen(s)); |
| 7069 |
|
s = "publickey"; |
| 7070 |
|
buffer_put_string(msg, s, strlen(s)); |
| 7071 |
|
buffer_put_char(msg, 1); // true |
| 7072 |
|
|
| 7073 |
|
puttykey = pvar->pageant_curkey; |
| 7074 |
|
|
| 7075 |
|
// アルゴリズムをコピーする |
| 7076 |
|
len = get_uint32_MSBfirst(puttykey+4); |
| 7077 |
|
buffer_put_string(msg, puttykey+8, len); |
| 7078 |
|
|
| 7079 |
|
// 鍵をコピーする |
| 7080 |
|
len = get_uint32_MSBfirst(puttykey); |
| 7081 |
|
puttykey += 4; |
| 7082 |
|
buffer_put_string(msg, puttykey, len); |
| 7083 |
|
puttykey += len; |
| 7084 |
|
|
| 7085 |
|
// 署名されたデータ |
| 7086 |
|
len = get_uint32_MSBfirst(signedmsg); |
| 7087 |
|
buffer_put_string(msg, signedmsg + 4, len); |
| 7088 |
|
free(signedmsg); |
| 7089 |
|
|
| 7090 |
|
// パケット送信 |
| 7091 |
|
len = buffer_len(msg); |
| 7092 |
|
outmsg = begin_send_packet(pvar, SSH2_MSG_USERAUTH_REQUEST, len); |
| 7093 |
|
memcpy(outmsg, buffer_ptr(msg), len); |
| 7094 |
|
finish_send_packet(pvar); |
| 7095 |
|
buffer_free(msg); |
| 7096 |
|
|
| 7097 |
|
pvar->pageant_keyfinal = TRUE; |
| 7098 |
|
} |
| 7099 |
|
|
| 7100 |
return TRUE; |
return TRUE; |
| 7101 |
} |
} |