| 4158 |
} |
} |
| 4159 |
|
|
| 4160 |
|
|
| 4161 |
static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) |
static void choose_SSH2_proposal(char *server_proposal, |
| 4162 |
|
char *my_proposal, |
| 4163 |
|
char *dest, |
| 4164 |
|
int dest_len) |
| 4165 |
{ |
{ |
| 4166 |
char tmp[1024], *ptr; |
char tmp_cli[1024], *ptr_cli, *ctc_cli; |
| 4167 |
|
char tmp_svr[1024], *ptr_svr, *ctc_svr; |
| 4168 |
SSHCipher cipher = SSH_CIPHER_NONE; |
SSHCipher cipher = SSH_CIPHER_NONE; |
| 4169 |
|
|
| 4170 |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, my_proposal); |
strncpy_s(tmp_cli, sizeof(tmp_cli), my_proposal, _TRUNCATE); |
| 4171 |
ptr = strtok(tmp, ","); // not thread-safe |
ptr_cli = strtok_s(tmp_cli, ",", &ctc_cli); |
| 4172 |
while (ptr != NULL) { |
while (ptr_cli != NULL) { |
| 4173 |
// server_proposalにはサーバのproposalがカンマ文字列で格納されている |
// server_proposalにはサーバのproposalがカンマ文字列で格納されている |
| 4174 |
if (strstr(server_proposal, ptr)) { // match |
strncpy_s(tmp_svr, sizeof(tmp_svr), server_proposal, _TRUNCATE); |
| 4175 |
break; |
ptr_svr = strtok_s(tmp_svr, ",", &ctc_svr); |
| 4176 |
|
while (ptr_svr != NULL) { |
| 4177 |
|
if (strcmp(ptr_svr, ptr_cli) == 0) { // match |
| 4178 |
|
goto found; |
| 4179 |
|
} |
| 4180 |
|
ptr_svr = strtok_s(NULL, ",", &ctc_svr); |
| 4181 |
} |
} |
| 4182 |
ptr = strtok(NULL, ","); |
ptr_cli = strtok_s(NULL, ",", &ctc_cli); |
| 4183 |
} |
} |
| 4184 |
|
|
| 4185 |
// サーバの proposal に、クライアントの proposal がひとつも |
found: |
| 4186 |
// 含まれていない場合 (2007.10.17 maya) |
if (ptr_cli != NULL) { |
| 4187 |
if (ptr == NULL) { |
strncpy_s(dest, dest_len, ptr_cli, _TRUNCATE); |
|
return (cipher); |
|
| 4188 |
} |
} |
| 4189 |
|
else { |
| 4190 |
|
strncpy_s(dest, dest_len, "", _TRUNCATE); |
| 4191 |
|
} |
| 4192 |
|
} |
| 4193 |
|
|
| 4194 |
|
static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) |
| 4195 |
|
{ |
| 4196 |
|
SSHCipher cipher = SSH_CIPHER_NONE; |
| 4197 |
|
char str_cipher[16]; |
| 4198 |
|
|
| 4199 |
if (strstr(ptr, "3des-cbc")) { |
choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); |
| 4200 |
|
|
| 4201 |
|
if (strcmp(str_cipher, "3des-cbc") == 0) { |
| 4202 |
cipher = SSH2_CIPHER_3DES_CBC; |
cipher = SSH2_CIPHER_3DES_CBC; |
| 4203 |
} else if (strstr(ptr, "aes128-cbc")) { |
} else if (strcmp(str_cipher, "aes128-cbc") == 0) { |
| 4204 |
cipher = SSH2_CIPHER_AES128_CBC; |
cipher = SSH2_CIPHER_AES128_CBC; |
| 4205 |
} else if (strstr(ptr, "aes192-cbc")) { |
} else if (strcmp(str_cipher, "aes192-cbc") == 0) { |
| 4206 |
cipher = SSH2_CIPHER_AES192_CBC; |
cipher = SSH2_CIPHER_AES192_CBC; |
| 4207 |
} else if (strstr(ptr, "aes256-cbc")) { |
} else if (strcmp(str_cipher, "aes256-cbc") == 0) { |
| 4208 |
cipher = SSH2_CIPHER_AES256_CBC; |
cipher = SSH2_CIPHER_AES256_CBC; |
| 4209 |
} else if (strstr(ptr, "blowfish-cbc")) { |
} else if (strcmp(str_cipher, "blowfish-cbc") == 0) { |
| 4210 |
cipher = SSH2_CIPHER_BLOWFISH_CBC; |
cipher = SSH2_CIPHER_BLOWFISH_CBC; |
| 4211 |
} else if (strstr(ptr, "aes128-ctr")) { |
} else if (strcmp(str_cipher, "aes128-ctr") == 0) { |
| 4212 |
cipher = SSH2_CIPHER_AES128_CTR; |
cipher = SSH2_CIPHER_AES128_CTR; |
| 4213 |
} else if (strstr(ptr, "aes192-ctr")) { |
} else if (strcmp(str_cipher, "aes192-ctr") == 0) { |
| 4214 |
cipher = SSH2_CIPHER_AES192_CTR; |
cipher = SSH2_CIPHER_AES192_CTR; |
| 4215 |
} else if (strstr(ptr, "aes256-ctr")) { |
} else if (strcmp(str_cipher, "aes256-ctr") == 0) { |
| 4216 |
cipher = SSH2_CIPHER_AES256_CTR; |
cipher = SSH2_CIPHER_AES256_CTR; |
| 4217 |
} else if (strstr(ptr, "arcfour128")) { |
} else if (strcmp(str_cipher, "arcfour128") == 0) { |
| 4218 |
cipher = SSH2_CIPHER_ARCFOUR128; |
cipher = SSH2_CIPHER_ARCFOUR128; |
| 4219 |
} else if (strstr(ptr, "arcfour256")) { |
} else if (strcmp(str_cipher, "arcfour256") == 0) { |
| 4220 |
cipher = SSH2_CIPHER_ARCFOUR256; |
cipher = SSH2_CIPHER_ARCFOUR256; |
| 4221 |
} else if (strstr(ptr, "arcfour")) { |
} else if (strcmp(str_cipher, "arcfour") == 0) { |
| 4222 |
cipher = SSH2_CIPHER_ARCFOUR; |
cipher = SSH2_CIPHER_ARCFOUR; |
| 4223 |
} else if (strstr(ptr, "cast128-cbc")) { |
} else if (strcmp(str_cipher, "cast128-cbc") == 0) { |
| 4224 |
cipher = SSH2_CIPHER_CAST128_CBC; |
cipher = SSH2_CIPHER_CAST128_CBC; |
| 4225 |
} |
} |
| 4226 |
|
|
| 4230 |
|
|
| 4231 |
static enum hmac_type choose_SSH2_hmac_algorithm(char *server_proposal, char *my_proposal) |
static enum hmac_type choose_SSH2_hmac_algorithm(char *server_proposal, char *my_proposal) |
| 4232 |
{ |
{ |
|
char tmp[1024], *ptr; |
|
| 4233 |
enum hmac_type type = HMAC_UNKNOWN; |
enum hmac_type type = HMAC_UNKNOWN; |
| 4234 |
|
char str_hmac[16]; |
| 4235 |
|
|
| 4236 |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, my_proposal); |
choose_SSH2_proposal(server_proposal, my_proposal, str_hmac, sizeof(str_hmac)); |
| 4237 |
ptr = strtok(tmp, ","); // not thread-safe |
|
| 4238 |
while (ptr != NULL) { |
if (strcmp(str_hmac, "hmac-sha1") == 0) { |
|
// server_proposalにはサーバのproposalがカンマ文字列で格納されている |
|
|
if (strstr(server_proposal, ptr)) { // match |
|
|
break; |
|
|
} |
|
|
ptr = strtok(NULL, ","); |
|
|
} |
|
|
if (strstr(ptr, "hmac-sha1")) { |
|
| 4239 |
type = HMAC_SHA1; |
type = HMAC_SHA1; |
| 4240 |
} else if (strstr(ptr, "hmac-md5")) { |
} else if (strcmp(str_hmac, "hmac-md5") == 0) { |
| 4241 |
type = HMAC_MD5; |
type = HMAC_MD5; |
| 4242 |
} |
} |
| 4243 |
|
|
| 4245 |
} |
} |
| 4246 |
|
|
| 4247 |
|
|
| 4248 |
static int choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal) |
static enum compression_algorithm choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal) |
| 4249 |
{ |
{ |
| 4250 |
char tmp[1024], *ptr, *q, *index; |
enum compression_algorithm type = COMP_UNKNOWN; |
| 4251 |
int ret = COMP_UNKNOWN; |
char str_comp[20]; |
| 4252 |
|
|
| 4253 |
// OpenSSH 4.3では遅延パケット圧縮("zlib@openssh.com")が新規追加されているため、 |
// OpenSSH 4.3では遅延パケット圧縮("zlib@openssh.com")が新規追加されているため、 |
| 4254 |
// マッチしないように修正した。 |
// マッチしないように修正した。 |
| 4257 |
// 遅延パケット圧縮に対応。 |
// 遅延パケット圧縮に対応。 |
| 4258 |
// (2006.6.23 maya) |
// (2006.6.23 maya) |
| 4259 |
|
|
| 4260 |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, my_proposal); |
choose_SSH2_proposal(server_proposal, my_proposal, str_comp, sizeof(str_comp)); |
|
ptr = strtok(tmp, ","); // not thread-safe |
|
|
while (ptr != NULL) { |
|
|
// server_proposalにはサーバのproposalがカンマ文字列で格納されている |
|
|
for (index = server_proposal; index < server_proposal + strlen(server_proposal) ; index++) { |
|
|
if (q = strstr(index, ptr)) { // match |
|
|
q = q + strlen(ptr); |
|
|
if (*q == '\0' || *q == ',') // 単語の区切りであればマッチ |
|
|
goto found; |
|
|
index = q; // pointer update |
|
|
} |
|
|
} |
|
|
ptr = strtok(NULL, ","); |
|
|
} |
|
| 4261 |
|
|
|
found: |
|
| 4262 |
// support of "Compression delayed" (2006.6.23 maya) |
// support of "Compression delayed" (2006.6.23 maya) |
| 4263 |
if (strstr(ptr, "zlib@openssh.com")) { |
if (strcmp(str_comp, "zlib@openssh.com") == 0) { |
| 4264 |
ret = COMP_DELAYED; |
type = COMP_DELAYED; |
| 4265 |
} else if (strstr(ptr, "zlib")) { |
} else if (strcmp(str_comp, "zlib") == 0) { |
| 4266 |
ret = COMP_ZLIB; // packet compression enabled |
type = COMP_ZLIB; // packet compression enabled |
| 4267 |
} else if (strstr(ptr, "none")) { |
} else if (strcmp(str_comp, "none") == 0) { |
| 4268 |
ret = COMP_NONE; // packet compression disabled |
type = COMP_NONE; // packet compression disabled |
| 4269 |
} |
} |
| 4270 |
|
|
| 4271 |
return (ret); |
return (type); |
| 4272 |
} |
} |
| 4273 |
|
|
| 4274 |
// 暗号アルゴリズムのキーサイズ、ブロックサイズ、MACサイズのうち最大値(we_need)を決定する。 |
// 暗号アルゴリズムのキーサイズ、ブロックサイズ、MACサイズのうち最大値(we_need)を決定する。 |
| 4346 |
int offset = 0; |
int offset = 0; |
| 4347 |
char *msg = NULL; |
char *msg = NULL; |
| 4348 |
char tmp[1024+512]; |
char tmp[1024+512]; |
| 4349 |
char *ptr; |
char str_kextype[40]; |
| 4350 |
|
char str_keytype[10]; |
| 4351 |
|
|
| 4352 |
notify_verbose_message(pvar, "SSH2_MSG_KEXINIT was received.", LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, "SSH2_MSG_KEXINIT was received.", LOG_LEVEL_VERBOSE); |
| 4353 |
|
|
| 4413 |
// 先頭から自分の myproposal[] と比較を行い、最初にマッチしたものがKEXアルゴリズムとして |
// 先頭から自分の myproposal[] と比較を行い、最初にマッチしたものがKEXアルゴリズムとして |
| 4414 |
// 選択される。(2004.10.30 yutaka) |
// 選択される。(2004.10.30 yutaka) |
| 4415 |
pvar->kex_type = -1; |
pvar->kex_type = -1; |
| 4416 |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, myproposal[PROPOSAL_KEX_ALGS]); |
choose_SSH2_proposal(buf, myproposal[PROPOSAL_KEX_ALGS],str_kextype, sizeof(str_kextype)); |
| 4417 |
ptr = strtok(tmp, ","); // not thread-safe |
if (strlen(str_kextype) == 0) { // not match |
|
while (ptr != NULL) { |
|
|
// buf[]にはサーバのproposalがカンマ文字列で格納されている |
|
|
if (strstr(buf, ptr)) { // match |
|
|
break; |
|
|
} |
|
|
ptr = strtok(NULL, ","); |
|
|
} |
|
|
if (ptr == NULL) { // not match |
|
| 4418 |
strncpy_s(tmp, sizeof(tmp), "unknown KEX algorithm: ", _TRUNCATE); |
strncpy_s(tmp, sizeof(tmp), "unknown KEX algorithm: ", _TRUNCATE); |
| 4419 |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
| 4420 |
msg = tmp; |
msg = tmp; |
| 4421 |
goto error; |
goto error; |
| 4422 |
} |
} |
| 4423 |
if (strstr(ptr, KEX_DH14)) { |
if (strcmp(str_kextype, KEX_DH14) == 0) { |
| 4424 |
pvar->kex_type = KEX_DH_GRP14_SHA1; |
pvar->kex_type = KEX_DH_GRP14_SHA1; |
| 4425 |
} else if (strstr(ptr, KEX_DH1)) { |
} else if (strcmp(str_kextype, KEX_DH1) == 0) { |
| 4426 |
pvar->kex_type = KEX_DH_GRP1_SHA1; |
pvar->kex_type = KEX_DH_GRP1_SHA1; |
| 4427 |
} else if (strstr(ptr, KEX_DHGEX)) { |
} else if (strcmp(str_kextype, KEX_DHGEX) == 0) { |
| 4428 |
pvar->kex_type = KEX_DH_GEX_SHA1; |
pvar->kex_type = KEX_DH_GEX_SHA1; |
| 4429 |
} |
} |
| 4430 |
|
|
| 4431 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "KEX algorithm: %s", ptr); |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "KEX algorithm: %s", str_kextype); |
| 4432 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 4433 |
|
|
| 4434 |
// ホストキーアルゴリズムチェック |
// ホストキーアルゴリズムチェック |
| 4440 |
buf[i] = 0; |
buf[i] = 0; |
| 4441 |
offset += size; |
offset += size; |
| 4442 |
pvar->hostkey_type = -1; |
pvar->hostkey_type = -1; |
| 4443 |
_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, |
choose_SSH2_proposal(buf, myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], str_keytype, sizeof(str_keytype)); |
| 4444 |
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]); |
if (strlen(str_keytype) == 0) { // not match |
|
ptr = strtok(tmp, ","); // not thread-safe |
|
|
while (ptr != NULL) { |
|
|
// buf[]にはサーバのproposalがカンマ文字列で格納されている |
|
|
if (strstr(buf, ptr)) { // match |
|
|
break; |
|
|
} |
|
|
ptr = strtok(NULL, ","); |
|
|
} |
|
|
if (ptr == NULL) { // not match |
|
| 4445 |
strncpy_s(tmp, sizeof(tmp), "unknown host KEY type: ", _TRUNCATE); |
strncpy_s(tmp, sizeof(tmp), "unknown host KEY type: ", _TRUNCATE); |
| 4446 |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
| 4447 |
msg = tmp; |
msg = tmp; |
| 4448 |
goto error; |
goto error; |
| 4449 |
} |
} |
| 4450 |
if (strstr(ptr, "ssh-rsa")) { |
if (strcmp(str_keytype, "ssh-rsa") == 0) { |
| 4451 |
pvar->hostkey_type = KEY_RSA; |
pvar->hostkey_type = KEY_RSA; |
| 4452 |
} else if (strstr(ptr, "ssh-dss")) { |
} else if (strcmp(str_keytype, "ssh-dss") == 0) { |
| 4453 |
pvar->hostkey_type = KEY_DSA; |
pvar->hostkey_type = KEY_DSA; |
| 4454 |
} else if (strstr(ptr, "rsa1")) { |
} else if (strcmp(str_keytype, "rsa1") == 0) { |
| 4455 |
pvar->hostkey_type = KEY_RSA1; |
pvar->hostkey_type = KEY_RSA1; |
| 4456 |
} else if (strstr(ptr, "rsa")) { |
} else if (strcmp(str_keytype, "rsa") == 0) { |
| 4457 |
pvar->hostkey_type = KEY_RSA; |
pvar->hostkey_type = KEY_RSA; |
| 4458 |
} else if (strstr(ptr, "dsa")) { |
} else if (strcmp(str_keytype, "dsa") == 0) { |
| 4459 |
pvar->hostkey_type = KEY_DSA; |
pvar->hostkey_type = KEY_DSA; |
| 4460 |
} |
} |
| 4461 |
#if 0 |
#if 0 |
| 4469 |
#endif |
#endif |
| 4470 |
|
|
| 4471 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 4472 |
"server host key algorithm: %s", ptr); |
"server host key algorithm: %s", str_keytype); |
| 4473 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 4474 |
|
|
| 4475 |
// クライアント -> サーバ暗号アルゴリズムチェック |
// クライアント -> サーバ暗号アルゴリズムチェック |