| 36 |
#define INTBLOB_LEN 20 |
#define INTBLOB_LEN 20 |
| 37 |
#define SIGBLOB_LEN (2*INTBLOB_LEN) |
#define SIGBLOB_LEN (2*INTBLOB_LEN) |
| 38 |
|
|
| 39 |
|
|
| 40 |
|
struct hostkeys_update_ctx { |
| 41 |
|
/* The hostname and (optionally) IP address string for the server */ |
| 42 |
|
char *host_str, *ip_str; |
| 43 |
|
|
| 44 |
|
/* |
| 45 |
|
* Keys received from the server and a flag for each indicating |
| 46 |
|
* whether they already exist in known_hosts. |
| 47 |
|
* keys_seen is filled in by hostkeys_find() and later (for new |
| 48 |
|
* keys) by client_global_hostkeys_private_confirm(). |
| 49 |
|
*/ |
| 50 |
|
Key **keys; |
| 51 |
|
int *keys_seen; |
| 52 |
|
size_t nkeys; |
| 53 |
|
|
| 54 |
|
size_t nnew; |
| 55 |
|
|
| 56 |
|
/* |
| 57 |
|
* Keys that are in known_hosts, but were not present in the update |
| 58 |
|
* from the server (i.e. scheduled to be deleted). |
| 59 |
|
* Filled in by hostkeys_find(). |
| 60 |
|
*/ |
| 61 |
|
Key **old_keys; |
| 62 |
|
size_t nold; |
| 63 |
|
}; |
| 64 |
|
|
| 65 |
|
|
| 66 |
////////////////////////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////////////////////////// |
| 67 |
// |
// |
| 68 |
// Key verify function |
// Key verify function |
| 1137 |
EC_KEY *ecdsa = NULL; |
EC_KEY *ecdsa = NULL; |
| 1138 |
EC_POINT *q = NULL; |
EC_POINT *q = NULL; |
| 1139 |
char *curve = NULL; |
char *curve = NULL; |
| 1140 |
Key *hostkey; // hostkey |
Key *hostkey = NULL; // hostkey |
| 1141 |
ssh_keytype type; |
ssh_keytype type; |
| 1142 |
unsigned char *pk = NULL; |
unsigned char *pk = NULL; |
| 1143 |
|
|
| 1144 |
|
if (data == NULL) |
| 1145 |
|
goto error; |
| 1146 |
|
|
| 1147 |
hostkey = malloc(sizeof(Key)); |
hostkey = malloc(sizeof(Key)); |
| 1148 |
if (hostkey == NULL) |
if (hostkey == NULL) |
| 1149 |
goto error; |
goto error; |
| 1829 |
|
|
| 1830 |
return (k); |
return (k); |
| 1831 |
} |
} |
| 1832 |
|
|
| 1833 |
|
|
| 1834 |
|
static void hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx) |
| 1835 |
|
{ |
| 1836 |
|
size_t i; |
| 1837 |
|
|
| 1838 |
|
if (ctx == NULL) |
| 1839 |
|
return; |
| 1840 |
|
for (i = 0; i < ctx->nkeys; i++) |
| 1841 |
|
key_free(ctx->keys[i]); |
| 1842 |
|
free(ctx->keys); |
| 1843 |
|
free(ctx->keys_seen); |
| 1844 |
|
for (i = 0; i < ctx->nold; i++) |
| 1845 |
|
key_free(ctx->old_keys[i]); |
| 1846 |
|
free(ctx->old_keys); |
| 1847 |
|
free(ctx->host_str); |
| 1848 |
|
free(ctx->ip_str); |
| 1849 |
|
free(ctx); |
| 1850 |
|
} |
| 1851 |
|
|
| 1852 |
|
// |
| 1853 |
|
// SSHサーバホスト鍵(known_hosts)の自動更新(OpenSSH 6.8 or later: host key rotation support) |
| 1854 |
|
// |
| 1855 |
|
// return 1: success |
| 1856 |
|
// 0: fail |
| 1857 |
|
// |
| 1858 |
|
int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen) |
| 1859 |
|
{ |
| 1860 |
|
int success = 1; // OpenSSH 6.8の実装では、常に成功で返すようになっているため、 |
| 1861 |
|
// それに合わせて Tera Term でも成功と返すことにする。 |
| 1862 |
|
int len; |
| 1863 |
|
char *cp, *fp; |
| 1864 |
|
char msg[128]; |
| 1865 |
|
unsigned char *blob = NULL; |
| 1866 |
|
buffer_t *b = NULL; |
| 1867 |
|
struct hostkeys_update_ctx *ctx = NULL; |
| 1868 |
|
Key *key = NULL; |
| 1869 |
|
|
| 1870 |
|
// TODO: Tera Termの設定で、当該機能のオンオフを制御できるようにする。 |
| 1871 |
|
|
| 1872 |
|
ctx = calloc(1, sizeof(struct hostkeys_update_ctx)); |
| 1873 |
|
if (ctx == NULL) |
| 1874 |
|
goto error; |
| 1875 |
|
|
| 1876 |
|
b = buffer_init(); |
| 1877 |
|
if (b == NULL) |
| 1878 |
|
goto error; |
| 1879 |
|
|
| 1880 |
|
cp = buffer_append_space(b, datalen); |
| 1881 |
|
memcpy(cp, dataptr, datalen); |
| 1882 |
|
|
| 1883 |
|
while (buffer_remain_len(b) > 0) { |
| 1884 |
|
key_free(key); |
| 1885 |
|
key = NULL; |
| 1886 |
|
|
| 1887 |
|
blob = buffer_get_string_msg(b, &len); |
| 1888 |
|
key = key_from_blob(blob, len); |
| 1889 |
|
if (key == NULL) { |
| 1890 |
|
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "Not found key into blob %p (%d)", blob, len); |
| 1891 |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
| 1892 |
|
goto error; |
| 1893 |
|
} |
| 1894 |
|
free(blob); |
| 1895 |
|
blob = NULL; |
| 1896 |
|
|
| 1897 |
|
fp = key_fingerprint(key, SSH_FP_HEX); |
| 1898 |
|
_snprintf_s(msg, sizeof(msg), _TRUNCATE, "SSH2_MSG_GLOBAL_REQUEST: received %s key %s", |
| 1899 |
|
get_sshname_from_key(key), fp); |
| 1900 |
|
notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); |
| 1901 |
|
free(fp); |
| 1902 |
|
} |
| 1903 |
|
|
| 1904 |
|
success = 1; |
| 1905 |
|
|
| 1906 |
|
error: |
| 1907 |
|
buffer_free(b); |
| 1908 |
|
hostkeys_update_ctx_free(ctx); |
| 1909 |
|
free(blob); |
| 1910 |
|
|
| 1911 |
|
return (success); |
| 1912 |
|
} |