{"version":3,"file":"ssh.html","sources":["ssh.c","readconf.c","clientloop.c","sshtty.c","sshconnect.c","sshconnect2.c","mux.c","ssherr.c","sshbuf.c","sshkey.c","sshbuf-getput-basic.c","sshbuf-misc.c","authfd.c","authfile.c","bufaux.c","buffer.c","canohost.c","channels.c","cipher.c","cipher-aesctr.c","compat.c","fatal.c","hostfile.c","log.c","match.c","nchan.c","packet.c","opacket.c","readpass.c","ttymodes.c","./ttymodes.h","xmalloc.c","atomicio.c","key.c","dispatch.c","mac.c","uidswap.c","misc.c","utf8.c","monitor_fdpass.c","rijndael.c","msg.c","dns.c","entropy.c","umac.c","./umac.c","cipher-chachapoly.c","ssh-ed25519.c","digest-libc.c","hmac.c","ed25519.c","verify.c","hash.c","blocks.c","kex.c","kexc25519c.c","platform-pledge.c","krl.c","bitmap.c","crc32.c","deattack.c","poly1305.c","chacha.c","sc25519.c","ge25519.c","fe25519.c","kexc25519.c","smult_curve25519_ref.c","arc4random.c","./chacha_private.h","bsd-closefrom.c","bsd-getpeereid.c","bsd-misc.c","fake-rfc2553.c","base64.c","bcrypt_pbkdf.c","bindresvport.c","blowfish.c","daemon.c","fmt_scaled.c","getrrsetbyname.c","glob.c","readpassphrase.c","reallocarray.c","setproctitle.c","sha1.c","sha2.c","rmd160.c","md5.c","strtonum.c","timingsafe_bcmp.c","vis.c","explicit_bzero.c"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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A;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AAEA;AAAA;AAAA;;AACA;;AAEA;AAAA;AAAA;;AACA;;;;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;;AACA;AAAA;;;;AACA;;;;AAGA;AAAA;;;;AACA;AAEA;AAMA;;;AAIA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAGA;AADA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAGA;AADA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;AACA;AAAA;;AAEA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AAOA;AAAA;AAAA;;AANA;AAAA;AAAA;;AAMA;AAAA;AAAA;;AALA;AAAA;AAAA;;AAKA;AAAA;AAAA;;AAHA;AADA;AACA;;AAGA;AAAA;AAAA;;AADA;AADA;AACA;;AACA;AAAA;AAAA;;AASA;AAAA;AA3TA;;;;AAAA;AAAA;;;;;;AA2TA;AAAA;;AACA;AAAA;AA5TA;;;;AAAA;AAAA;;;;;;AA4TA;AAAA;;AACA;AAAA;AA7TA;;;;AAAA;AAAA;;;;;;AA6TA;AAAA;;AACA;AAAA;AA9TA;;;AAAA;AAAA;;;;AAoUA;;;AANA;AAAA;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6ZA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAGA;AAAA;AA1EA;;AAEA;AAAA;AAAA;AAAA;;AAFA;;AAEA;AAAA;AAAA;AAAA;;AA0EA;AAAA;AAxFA;AAAA;AAAA;AAAA;AA2FA;AAAA;;;;;;;;;;;;;;;;;;;;;;AArFA;AAAA;AAAA;AAAA;AAsFA;AAAA;AApJA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAuFA;AAAA;AArJA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAwFA;AAAA;;;;;;;;;;;;;;;;;;;;;;AAxFA;AAAA;AAAA;AAAA;AAyFA;AAAA;AAvJA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA0FA;AAAA;AAxJA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA2FA;AAAA;AAzJA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA4FA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA5FA;AAAA;AAAA;AAAA;AA6FA;AAAA;AA3JA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA8FA;AAAA;AA5JA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA+FA;AAAA;AA7JA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAgGA;AAAA;AA9JA;;;;AAkBA;;;AA4CA;AAAA;AAAA;AAAA;AAiGA;AA/JA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAkGA;AAAA;AAhKA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAmGA;AAAA;AAjKA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAoGA;AAAA;AAlKA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAyGA;AAAA;AAvKA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA0GA;AAAA;AAxKA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA2GA;AAAA;AAzKA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA4GA;AAAA;AA1KA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA6GA;AAAA;AA3KA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA8GA;AAAA;AA5KA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA+GA;AAAA;AA7KA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAgHA;AAAA;;;;;;;;;;;;;;;;;;;;;;AAhHA;AAAA;AAAA;AAAA;AAiHA;AAAA;AA/KA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAkHA;AAAA;AAhLA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAmHA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AAnHA;AAAA;AAAA;AAAA;AAwHA;AAAA;AAtLA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AAyHA;AAAA;;;;;;;;;;;;;;;;;;;;;;AAzHA;AAAA;AAAA;AAAA;AA0HA;AAAA;AAxLA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA2HA;AAAA;;;;;;;;;;;;;;;;;;;;;;AA3HA;AAAA;AAAA;AAAA;AA4HA;AAAA;AA1LA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA6HA;AAAA;;;;;;;;;;;;;;;;;;;;;;AA7HA;AAAA;AAAA;AAAA;AA8HA;AAAA;AA5LA;AA+BA;AAAA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;AA+HA;AAAA;;;;;;;;;;;;;;;;;;;;;;AA/HA;AAAA;AAAA;AAAA;AAkIA;AAAA;AAxIA;AAAA;AAAA;AAAA;AA4IA;AAAA;AA5IA;AAAA;AAAA;AAAA;AA6IA;AAAA;AA7IA;AAAA;AAAA;AAAA;AA8IA;AAAA;AA9IA;AAAA;AAAA;AAAA;AA+IA;AAAA;AA/IA;AAAA;AAAA;AAAA;AAgJA;AAAA;AAhJA;AAAA;AAAA;AAAA;AAmJA;AAAA;AAvIA;;AAEA;AAAA;AAAA;AAAA;;AAsIA;AAAA;AAAA;AAAA;AAtIA;AAAA;AAAA;AAAA;AAuIA;AAAA;AAzIA;;AAEA;AAAA;AAAA;AAAA;;AAwIA;AA1IA;;AAEA;AAAA;AAAA;AAAA;;AAyIA;AAAA;AA3IA;;AAEA;AAAA;AAAA;AAAA;;AA0IA;AAAA;AA5IA;;AAEA;AAAA;AAAA;AAAA;;AA2IA;AAAA;AA7IA;;AAEA;AAAA;AAAA;AAAA;;AA4IA;AAAA;AA9IA;;AAEA;AAAA;AAAA;AAAA;;AA6IA;AAAA;AAAA;AAAA;AA7IA;AAAA;AAAA;AAAA;AA8IA;AAAA;AAhJA;;AAEA;AAAA;AAAA;AAAA;;AA+IA;AAAA;AAAA;AAjJA;;AAEA;AAAA;AAAA;AAAA;;AAgJA;AAAA;AAAA;AAAA;AAhJA;AAAA;AAAA;AAAA;AAoJA;AAAA;AAtJA;;AAEA;AAAA;AAAA;AAAA;;AAqJA;AAAA;AAvJA;;AAEA;AAAA;AAAA;AAAA;;AAsJA;AAAA;AAxJA;;AAEA;AAAA;AAAA;AAAA;;AAuJA;AAAA;AAzJA;;AAEA;AAAA;AAAA;AAAA;;AA0JA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAvJA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;AAwJA;AAAA;AA/IA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;AAEA;AA6IA;AAAA;AAhJA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;AAEA;AA8IA;AAAA;AAjJA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;AAEA;AA+IA;AAAA;AA3JA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;AAgKA;AAAA;AAAA;;AACA;;AAvLA;AAAA;AAAA;AAAA;;AA4LA;AACA;AAAA;AAAA;;AACA;;AAEA;AAAA;;AACA;AAAA;AAAA;;AACA;;AAEA;AAAA;;AACA;AAGA;AAAA;AAAA;;AACA;AACA;AAAA;;;;AACA;AAAA;AACA;AAAA;AADA;AAAA;AAAA;AAAA;;AADA;AAAA;;;;;;;;AAIA;;AAIA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAGA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAtNA;AAAA;AAAA;AAAA;;;;AAxDA;AA+BA;AAAA;AAAA;AA/BA;AA8DA;AAAA;AAAA;AAAA;;AAsNA;AAAA;AAAA;;AACA;;AAEA;AACA;AAAA;;AAIA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAKA;AAAA;AADA;AAAA;AAIA;AAAA;AAAA;;AACA;AAAA;AArOA;;AA4PA;;AA1PA;AAAA;AAAA;AAAA;AA0PA;;AApBA;AAAA;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AAEA;AAEA;AAEA;AAEA;AAAA;AAAA;AACA;AAfA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBA;;;;;;;;;;;;;AAlOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;;AA6BA;;;;;;AA3BA;AAAA;AAAA;;;;AACA;AAAA;;;;;;;AAKA;AAAA;AACA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;;AAEA;AAAA;AAAA;AAAA;;;;;AAaA;;AA3BA;AAAA;;;;;;;AA6BA;;;;;;AAxBA;AAAA;AAAA;;;;;AACA;AAAA;;;;;;;;;;;;;AA3DA;AAAA;AACA;AAAA;AAAA;AADA;;;;;AAAA;;;;;;;;;AA6DA;AAAA;AACA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;;AAEA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;;AAEA;AAAA;AAAA;AAAA;;;;;AAIA;;AA3BA;AAAA;;;;;;;AA6BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpoEA;AACA;AACA;AAAA;AAAA;AAAA;AA9BA;;;AAqKA;;AAlKA;AACA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;AAFA;AAAA;;;;;;;AAGA;AAAA;AA2BA;AAAA;;AAmIA;;;AA/HA;;;;;AAAA;AAAA;;AACA;;;;AAYA;AAAA;;AAEA;AADA;AAAA;AACA;;AAEA;AAAA;;AA8GA;;;;;;;AAzGA;;AAQA;AACA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;AA+FA;;AA1FA;AAAA;AACA;;AAEA;AAAA;AACA;AACA;;AAqFA;;AAjFA;AAGA;AAHA;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA7DA;AAAA;;AA8DA;AAAA;AAGA;AAHA;;AAIA;;;;;AAEA;AAAA;;;;;;;;;;;;AAaA;AACA;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AACA;AACA;;;;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AADA;;;AAIA;;;AAIA;;;;;;;;AACA;AACA;;;;AAIA;AAAA;;AACA;;AA4BA;;AA7BA;;;AA6BA;;AAXA;AAEA;AACA;;;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;AADA;AAAA;AADA;AAAA;;;;;;;;AAOA;;;;;;;;AAoaA;AAEA;AACA;AAAA;AAEA;AAEA;;;;;;;;;;;;;;;;;AAnEA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;;;AAGA;AAAA;;AACA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;;AAIA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAqCA;AACA;;;;;;AAlCA;AAAA;;AAKA;AAAA;AAFA;AAAA;AAAA;AAAA;;AAKA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;AAMA;AACA;AADA;;AAGA;AAAA;;AACA;;;AAKA;AAAA;AAAA;AAAA;;AACA;AAQA;AACA;;AAPA;AAMA;AACA;;;;;AALA;AACA;AAGA;AACA;;;;AADA;AACA;;;;;;AADA;AACA;;;;;;;;;AAKA;AACA;;;;;;;;;AAgBA;AAKA;AAAA;AAAA;AAAA;AACA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAUA;;;;;AALA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;AAgjBA;AACA;AACA;AAAA;AACA;;;;;;;AAOA;AACA;;;;;;;;AAKA;AAAA;AAAA;;;AAKA;;AAFA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA/XA;;;;;AAIA;AAAA;AAAA;;;AA6NA;;AAzNA;;;;;;;AAGA;;;AAsNA;;;;;;;;;;;AAjNA;AAAA;AAEA;AAAA;;;AA4LA;AAAA;AAAA;AAAA;AAAA;;AAKA;;;;;;;AA9LA;AAGA;;;;;;;;;;AAsBA;AAAA;;AAIA;;;;AAYA;AAAA;AAEA;AAAA;AAzbA;AAAA;;AACA;AAAA;AACA;AADA;;AAEA;AAAA;;AACA;AAAA;AACA;AADA;;AAGA;AAAA;AAAA;AAAA;AAMA;AACA;AACA;AAGA;AAAA;AAGA;AAGA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;;;;;;AAsaA;AAAA;;;;;AACA;AAAA;AAGA;AADA;AAEA;AAAA;AAEA;AAAA;AACA;AAAA;;;;;;AAKA;AAAA;;;;;AACA;AAAA;AAAA;;AAIA;;;;AAHA;;;;;;;;AAUA;AAAA;;;;;;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAIA;AADA;;;;AAIA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;;;AAGA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;;;;;;AAIA;AAAA;;;;;;AASA;AAAA;AAAA;AADA;AAIA;AAEA;AAAA;AAEA;AAAA;AAGA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;;;;;AAKA;AAAA;;;;;AAIA;AAAA;;;;;AAMA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AAAA;;;;;AACA;AAAA;AACA;AAAA;;;;;;AAMA;;;;AACA;AAAA;;;AACA;AAvNA;AAAA;AAEA;AAAA;AAEA;AAAA;AACA;AADA;AAEA;AADA;AAEA;AAAA;AADA;;;AAIA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;AALA;AAAA;;;;;;;AAQA;AAAA;AAAA;AAAA;AAIA;AAAA;;;;;;AAsMA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AACA;;;;;;;AAIA;AAAA;;;;;;AAxXA;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AACA;;;;;AAEA;AAAA;AAAA;AAAA;AACA;;;;;;;AACA;AAAA;AAEA;;;;;;;AAIA;AACA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAAA;;;;AAEA;;;;;;;AAKA;AAAA;AAAA;AAAA;;AACA;AACA;;;AAIA;AAEA;AAFA;AAIA;;;;;;;;;;;;;;;AAOA;;;;AAIA;AAAA;AAAA;AAAA;;;;AACA;;;;AAIA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAyBA;AAAA;;AACA;;;AAGA;AAAA;;AAOA;AAAA;;AACA;;;;AAPA;AAAA;;AAEA;;;;AASA;;;AAnCA;AAAA;;AACA;;;AAGA;;;AAEA;;AAIA;AAEA;;;;;;;;;AALA;AACA;;;;;;;;;;AAHA;AAAA;;;;;;;;;;AASA;;;;;AAGA;;;;;AAsBA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;;;;;AA8QA;;;;;;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;AAhJA;AAAA;;AACA;AAAA;AAAA;AAAA;AAKA;AADA;;;;;;AAmKA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAhNA;AAAA;;;;;;;;;;AAaA;AAAA;AAEA;AAAA;;AAEA;AAAA;;AACA;AACA;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AACA;AAAA;AACA;;AA2LA;;;AAxLA;;AAwLA;;;AAlMA;AAAA;;;AAoHA;AAAA;;;AAIA;;AA0EA;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkLA;AAAA;AAEA;AAEA;AAGA;AAEA;AAAA;;;;AACA;AAAA;AAAA;;AACA;AACA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAEA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;;AACA;AACA;AACA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AACA;AAAA;AADA;;AAEA;AACA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AACA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAzwCA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8wCA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;;AAEA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;;;;AAAA;;;AACA;AAAA;;;;AAAA;;;AACA;AAAA;;;;AAAA;;;;;;AAEA;AACA;AAGA;AACA;AACA;AAopCA;AAAA;;AAEA;AAAA;AAVA;;AACA;AAAA;AACA;AAAA;;;AAhDA;AAAA;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAAA;AAGA;AAAA;AACA;AAAA;;AA1mCA;AAAA;;AACA;;AACA;AAAA;;AACA;;AACA;AAAA;;AACA;;AACA;AAAA;;AACA;;AACA;AAEA;;AACA;AAAA;AAAA;AAAA;;AAEA;AAAA;;AA9lCA;AAAA;;AAtQA;AACA;AAAA;AAAA;AA+QA;AAAA;AACA;;;AAKA;AACA;AACA;AAAA;AACA;AAAA;;AACA;;AAMA;AAAA;AAAA;AAAA;;AACA;;;AAEA;;;;;;AA9SA;AAAA;;AACA;AAAA;AACA;;;AAiRA;AACA;AACA;AAAA;AACA;AAAA;;;AA0lCA;AACA;;AACA;;;;AAvIA;AACA;AACA;AAAA;AAsIA;;;;AAMA;;;AASA;AAAA;;;;;;;;;;;AAlKA;AAAA;AAuKA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;AAGA;AAAA;AAAA;;;AAEA;AAAA;;AAEA;AACA;AAAA;AAAA;;;;;AAGA;;;AAMA;AAAA;;;AAxlCA;AAAA;;;AACA;AAAA;AADA;;;;AAEA;AAEA;AAAA;AAAA;;AACA;AAAA;;;;;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAEA;AAAA;;;AAAA;AAAA;;;;AACA;AAAA;AACA;AAAA;;;AAbA;AAAA;;;;;;;;AA+lCA;AAAA;AAAA;;AACA;;AAlkCA;AAAA;;;AAGA;AAEA;AAEA;AAAA;;AACA;;;AAEA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AAyjCA;AAAA;;;;;;AA7BA;;;AAoCA;AAEA;AAAA;AAlhCA;AAAA;AAIA;AAGA;AAAA;;;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAKA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;AACA;AAAA;AAAA;;;;;AAGA;AAAA;;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;;;;;AAGA;AAAA;;;;;;;;;;;;;;;;;;;AAKA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AASA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;AAAA;AAAA;;;;AAxZA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AADA;;;AAGA;;;AACA;AAAA;;;AAEA;;AACA;AAAA;;AACA;;;;AACA;;AAEA;AACA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAEA;AAAA;AAAA;AAAA;;AA6YA;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAEA;AAAA;;;;AAGA;AAAA;AACA;AADA;AAAA;AAEA;;;;AAGA;AACA;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AACA;;AAQA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;;;;AACA;AAKA;AALA;;;;AAKA;AAAA;;;;AArHA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AA8RA;AAAA;AAAA;AAAA;AACA;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;;;;;;;;;AAMA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAyvBA;AAAA;;;;;AAIA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAGA;AA14BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAEA;AACA;;AAOA;AAFA;AAAA;AAGA;AAAA;AACA;;;AAOA;;;AACA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAUA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAGA;AAAA;AACA;;;;;;AAGA;;;AAy2BA;AAAA;;;;;AAGA;AAAA;;AAEA;AAvVA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAEA;AAAA;AACA;;;AACA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AAUA;AAAA;AAAA;AADA;AAAA;AAEA;AAAA;;AATA;;;;AAwBA;AAAA;;AAKA;;;AAOA;;;;;AAxBA;AAQA;AAAA;;;;AACA;AAAA;AACA;AAAA;;;AAgUA;AApSA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AACA;AADA;AAEA;;;AACA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;AAQA;AAAA;AAAA;AADA;AAAA;AAEA;AAAA;AACA;;;;;;AAKA;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AACA;AADA;AAEA;;;AACA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;AAOA;;;;;;AAKA;;;;AAiQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAOA;AAAA;;AACA;AAAA;AAAA;;;;;;AArFA;AAAA;;;;;;;AAeA;AADA;AAAA;AAAA;AAAA;AAAA;;;AA97BA;AAAA;;;AArZA;AAAA;;;AA6UA;AAAA;AAAA;AACA;AAAA;;;AAqSA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAuyBA;;;;;;;;AAKA;AAAA;AACA;AAAA;AAKA;AAEA;AAAA;;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;AAGA;;AAGA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAOA;AAAA;;AAAA;AAAA;;AACA;AACA;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAMA;AAAA;AAAA;;AAEA;AADA;AAAA;AAEA;AAAA;;AAIA;AAAA;;;AACA;AACA;AAAA;AADA;AAEA;;;AAAA;AAAA;;;;AAGA;;;;AAFA;;;AAMA;AAAA;;;AACA;AACA;AAAA;AADA;AAEA;;;AAAA;AAAA;;;;AAGA;;;;AAFA;;;AAMA;AACA;AACA;AACA;AA1/CA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4/CA;AACA;AAAA;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;AAIA;AAAA;AAAA;AACA;AAAA;;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AACA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6RA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;;AA/LA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAHA;AAMA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAGA;;;;;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;;;;AAIA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;AADA;AAAA;AAAA;AAAA;;;;;;;AAOA;AACA;AACA;;;;AA4JA;AAAA;;AAjJA;AAAA;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAEA;AAEA;;;;;;AAyIA;AAAA;;AAEA;AAAA;;;;AAxFA;AAAA;;;AACA;AACA;;;AAIA;;;;;;;;AAOA;AADA;AAIA;AAAA;;;;;;AAPA;AADA;AAAA;AAAA;AAAA;;;;;;;;;;;AA/CA;AAAA;;AACA;AACA;;;AAIA;AAAA;;AAAA;AAAA;AAAA;;AACA;;;;AAIA;AAAA;AACA;AAAA;AAAA;;AAIA;;;;AAHA;;;AAKA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;;AAEA;AAGA;AAAA;;;;;;;AAqGA;;AAAA;AAAA;;AACA;AAAA;AAyBA;AACA;;AAxBA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AAmBA;AACA;;AAnBA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAaA;AACA;;;AAXA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;;AAEA;AAAA;AAEA;AACA;;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AACA;AACA;AAAA;;AAwCA;;AAtCA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;;;AACA;;;;AACA;;AACA;AAAA;;;AAEA;AAAA;;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;;;;;AACA;AAAA;;AACA;AACA;AAAA;AAAA;;;AAGA;AAAA;;AAGA;;;;AAGA;AAAA;AAAA;AAAA;;;;;AARA;;;;AAWA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;AAEA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;;;;AAEA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+YA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;;AA9JA;AACA;AACA;AAEA;AASA;AAAA;AACA;AAAA;AADA;;AAGA;AAAA;AAAA;AAAA;;AAGA;AACA;AAAA;;;;;AACA;AACA;AACA;AAAA;;;;AAKA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AAAA;AAGA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AA3DA;AACA;AAAA;AAAA;AAGA;;;;;AAAA;;;;;;;;;AAGA;AAAA;;AACA;AAAA;;;;;;;;;;;;;;;;;AAEA;AAAA;;;;;;;;;;AAuDA;AAAA;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;;;AAKA;AAAA;AACA;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;;;;;AAAA;AAAA;AACA;;;;;;;;;AAOA;AAAA;AACA;AAEA;;;;;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;AAxBA;AADA;AAAA;AAAA;AAAA;;AAnBA;AAAA;;;;;;AACA;AACA;AACA;AAAA;;;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;;;;;AAwBA;AAAA;AADA;AAAA;AAAA;AAAA;;;;;AAQA;AAAA;AAAA;AAAA;AAAA;;;;;;AAnCA;AADA;AAAA;AAAA;AAAA;;;;;;;;AA2CA;AAAA;;AACA;AAAA;;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAHA;AAMA;AACA;AAAA;AADA;AAEA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAKA;AAAA;AACA;AAAA;;;;;;;AACA;AAAA;AAAA;AACA;;AAAA;;;;;AAFA;AAAA;;;;;;;;;AAMA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;AAAA;AAAA;;;;;AAEA;;;;AAMA;AAAA;AAAA;AAAA;AAEA;AAAA;;;AAKA;AADA;AAAA;AAAA;AAAA;AAAA;;AAHA;AACA;;;AAGA;AADA;AAAA;AAAA;AAAA;AAAA;;AADA;AAAA;;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;;;;;AACA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;;;;;;;;;;AAPA;AAAA;;;;;;;;AAMA;AADA;AAAA;AAAA;AAAA;AAAA;;;AAIA;AADA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA5nDA;AAAA;AAAA;AAAA;AACA;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAKA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAwnDA;AACA;AAAA;AACA;;;;;;;AAqBA;;AAMA;AACA;;AANA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AAEA;AACA;;;;;;;;;AAx9DA;AAAA;;AAYA;;AAVA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;;AAGA;AAAA;AAEA;;;;;AA8kEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAEA;;;;;;AA97EA;AACA;AACA;;;;;;AAdA;AACA;AACA;;;;;;;AA4uCA;AACA;AACA;AAAA;AAAA;AAAA;AACA;;;;;;AAiwCA;AAAA;AAAA;AAAA;AAzgFA;AAAA;;AACA;AAAA;AAAA;AACA;;AAygFA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;;AAFA;AACA;AACA;AAAA;;;;;;;;;AA57BA;AAAA;AAEA;AAAA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AACA;AAAA;AAKA;AAEA;AACA;;;;;;;;;;;;;;AAtBA;AAAA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AACA;AACA;;;;;;;;;;;;;;AAhBA;AAAA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AACA;AACA;;;;;;;;;;;;;;;;;AAsCA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;;;;;;AAGA;AADA;AAAA;AAAA;AAAA;;;AAUA;AAAA;;AACA;AAEA;AAAA;AACA;AAAA;AAEA;;AAKA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;;;AAVA;AAAA;AACA;AAAA;AAQA;AAAA;AACA;;;;;;;;;;;AAqVA;AAAA;AAAA;AAMA;AAAA;AAAA;;AAyBA;;AAzBA;AAAA;AAAA;;AAyBA;;AAxBA;AAAA;;AAwBA;;AApBA;AAAA;AAAA;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AADA;AAAA;AAAA;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAgBA;;;AAVA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAGA;;;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAKA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AACA;AADA;AACA;;;;AAGA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;;;;;;AARA;AAAA;;;;;;;AAKA;AAAA;AAAA;;;AAKA;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;AACA;AADA;AACA;;;;AAGA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;AANA;AAAA;AAAA;;;;;;;AAGA;AAAA;AAAA;;;AAKA;AAAA;;AACA;AAAA;;;;AACA;;;AAIA;AAAA;;;;AACA;AACA;AAEA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;;;;;AAIA;AAXA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAQA;;;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAAA;;;;;AACA;;;AACA;AACA;;AACA;;AAQA;;;;;AAAA;;AAOA;;AANA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAHA;AAGA;;AAGA;;AADA;AADA;AAAA;AAAA;AAAA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;AAKA;AAQA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;;AACA;AAEA;AAkDA;;AA/CA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAMA;AAAA;AAAA;;;;;;;;;;AACA;AAAA;AAAA;AAAA;;AAGA;AACA;AACA;;;;;;AACA;AAAA;AACA;AAAA;AADA;AACA;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;AAIA;AAAA;;;;;AAKA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AADA;AACA;;;;;AAMA;AAAA;AAAA;AACA;;;;;;AA1BA;AAAA;;;;;;;;;;AAWA;AADA;AAAA;AAAA;AAAA;AAAA;;;AAKA;AADA;AAAA;AAAA;AAAA;;;;AAOA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAQA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;;;;;AAEA;AACA;;;;;;;AAvLA;;AAYA;;AAVA;AAAA;AAAA;;;;;;;;AACA;AAAA;AAAA;AADA;AAAA;AAAA;;;;;;;;;;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;;;;;;;AACA;AAAA;AAAA;AADA;AAAA;AAAA;;;;;;;;;;AAEA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AACA;;;;;;;;;;AAjMA;AAAA;AAAA;AAKA;;;AAoCA;;AAjCA;AAAA;;AACA;;AAgCA;;AA5BA;AAAA;AAAA;AAAA;AAGA;AAAA;;AACA;;AAwBA;;AApBA;AAEA;AAAA;AAQA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkhBA;AAAA;AAAA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAGA;;AAIA;AAAA;AAAA;;AACA;;AAEA;AA1sDA;AAEA;AACA;AAAA;AAEA;AAusDA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;AACA;;;;;AACA;AACA;AAAA;AAEA;AAAA;;AAIA;AAAA;AAAA;AAAA;;;AAIA;AACA;AAAA;;;;AAEA;AACA;AAAA;;;AACA;;AAGA;AAAA;AAGA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;;;;;AADA;AAAA;;;;;;;AAYA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;AAVA;AAAA;AACA;;;AAlBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;AAZA;AAAA;;;;AA2CA;AACA;;AAiBA;AAhxDA;AAEA;AACA;AAAA;AAEA;AA6wDA;AAAA;AAEA;;AApBA;AAAA;AAEA;AAEA;;AAIA;AAAA;AAAA;AAAA;AAEA;AA1wDA;AAEA;AACA;AAAA;AAEA;;AA8vDA;AAAA;AAAA;AAAA;AAEA;AArwDA;AAEA;AACA;AAAA;AAEA;;AAwwDA;AAAA;AAAA;AAAA;AACA;AAAA;AAMA;;;;;;AAsEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAKA;AAAA;AAAA;AAAA;;AAIA;;AAHA;AACA;AAEA;;;;;AC1pFA;AAAA;AAAA;AAAA;;;;;;AAMA;AAAA;;;AAEA;AAAA;AAAA;AAAA;;AAIA;;;AAHA;;AACA;;;;AAGA;;;;;;;;;AAOA;AAAA;AAAA;AAAA;;AACA;;AAsBA;;AArBA;AAqBA;;AAlBA;AACA;AACA;AAAA;AAEA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;AAIA;AACA;;AAJA;;AAIA;;AAHA;AAGA;;;;;ACyKA;AAAA;;AAEA;;AADA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmPA;AAAA;;AAGA;AAAA;;AACA;;AAOA;;AALA;AAAA;;AApUA;AAAA;;;;AAAA;AAAA;;;;;;;;;;AAIA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;;AADA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;;AAIA;AA7GA;AAAA;AACA;AAAA;AACA;AACA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AA0GA;AAAA;AAGA;AAAA;;AAkCA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAGA;AAAA;AACA;AAAA;AAAA;AAGA;AAGA;AAAA;AAAA;AAAA;;AA6QA;;AAxTA;AAAA;AAGA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;;AACA;;AACA;AAAA;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAIA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AAAA;;AAhBA;AAEA;AAAA;AAIA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AAAA;;AA3HA;AAAA;AAAA;AAGA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;;AAIA;AA7BA;AAAA;AACA;AAAA;AACA;AACA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AA0BA;AAAA;AAGA;AAAA;;AAqCA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;;AAEA;AAAA;;;;AACA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;;AAyVA;;AAxYA;AAAA;AAEA;AAAA;AAAA;AAEA;AAAA;;;;AACA;AAAA;;AACA;;AAEA;AAAA;;AAWA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAMA;AACA;AAAA;AACA;AAAA;;;;;AArBA;AAAA;;AACA;;AAEA;AAAA;;AAOA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAMA;AACA;AAAA;AACA;AAAA;;AAjBA;AAMA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAMA;AACA;AAAA;AACA;AAAA;;AA+QA;AAKA;AAAA;AAAA;AAAA;AACA;AACA;AAEA;;;;;;;;;;AACA;;AAEA;AACA;;;;;;AAOA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAEA;;AACA;AAAA;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAvLA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AACA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAGA;AAAA;AAAA;;;AAIA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;;AACA;AACA;AADA;AAAA;AAAA;AAAA;AAEA;;;;;;AASA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AACA;AAAA;;;;AAAA;AAAA;;;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AACA;;;;AACA;AACA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;;;;;;AAGA;AACA;AAAA;;;AAIA;AAAA;;AACA;;;AA6IA;AAAA;AAhIA;AAEA;AAAA;;;AACA;;;;AAIA;AACA;AACA;;AACA;;;;AAIA;AAAA;AAAA;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;AAGA;;;;;;;;;;;;;;;;;;;;AACA;AAAA;AAAA;;;;;;;;;AAOA;AAAA;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;;;;;AAIA;AACA;AACA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;;AAKA;;;;AAJA;AAAA;;;;;;AAWA;;;;;;;;;;AAGA;;;;;;;;;AAAA;AAAA;;AACA;AACA;AAAA;;AACA;AAAA;;;;;;;;;AA+DA;;;;AAMA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;;;;;;;;;AA3BA;AAAA;AAAA;;;;;;;AAsBA;AAAA;AAAA;AASA;;;;;;;;AAzCA;;;;;;;;;AAnIA;AAAA;AAAA;AAAA;AAAA;;;AAEA;AAAA;AAAA;AAAA;AAAA;;;AA4BA;AAAA;;;AA2DA;AAAA;AAAA;;;AA8FA;AAGA;;AACA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAGA;;;;;;;;;AAbA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA;AAAA;AACA;AAAA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AACA;AAMA;AAAA;;AACA;AACA;;;;;AAKA;;;;;;;;;;;;;AAIA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;;;;;AAGA;;;AACA;AAAA;AAAA;;;;;;;;AAOA;AAAA;AAEA;;;;;AAMA;;;;;;;;;AACA;AACA;AAAA;AAAA;;;;;;AAOA;AAAA;;;;;;;;;;;;AApCA;AAAA;;;;;;;;;;;AAmBA;AAAA;AAEA;;;;;AAMA;;;;;;;;;AACA;AACA;AAAA;AAAA;;;;;AAOA;AAAA;;;;;AApCA;;;;AAAA;;;;;;;;;;;;AAiCA;AAAA;AAAA;;;AAOA;AACA;AAAA;;;;;AAEA;AAAA;;;;AAlCA;AAAA;;;AAMA;AAAA;AAAA;AADA;AAAA;AAAA;;;AAOA;AAAA;AAAA;;AACA;AAAA;;AAIA;AAAA;AAAA;AADA;AAAA;AAAA;;;;AAYA;AAAA;;;AAQA;AAAA;AACA;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;AACA;AAAA;AAAA;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAGA;;;;AAEA;AACA;AADA;AAAA;AAAA;AAAA;;AAGA;;;;AAGA;AAAA;;;AA4BA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;AAvBA;;AACA;AAAA;;AACA;AAAA;;AAEA;AAEA;AAAA;;;;AACA;AACA;;;;;;;;;AAKA;AAAA;AAAA;;;AAWA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;AATA;;;;;;;;;AAUA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;;AACA;AAAA;;AAEA;;AAEA;AAAA;AACA;;AAFA;AACA;AAAA;AACA;;;;;;;;;;AA/JA;AAAA;AAAA;AAAA;AAGA;AAAA;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;AACA;AADA;AACA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AACA;;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;AAwNA;;;;AAAA;AAAA;AAAA;;;AAmBA;;AACA;AAAA;;;AACA;AACA;;AAEA;;;;AADA;AAAA;AAAA;;;AAGA;;;;;;AAWA;;AAQA;;AAPA;AAAA;;AAIA;AAAA;AAGA;;AANA;AAAA;AACA;AAAA;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6bA;AAEA;AAGA;AADA;AACA;;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAKA;AAAA;;AAsBA;AAAA;;AACA;;;AAAA;;;AADA;AAAA;AAAA;AAAA;;;AArBA;AAAA;AAAA;AAAA;AACA;AADA;AACA;;AAEA;AADA;AAAA;AAAA;AAAA;;;;AAKA;AAAA;AAIA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AALA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;AAAA;AAAA;;;;;;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AASA;AAAA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAOA;AAAA;;;AACA;;;;;;;AAMA;AACA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAOA;AACA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAQA;AAAA;;;AAKA;AAAA;;;;;AAEA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AACA;AAAA;AADA;AAAA;AAAA;AAEA;AAAA;AAFA;;;;;;AAOA;;;AAEA;AAAA;AACA;;;;;;;AAOA;AAAA;AACA;AACA;AAFA;;;;AAKA;AAAA;AACA;AACA;AACA;AAAA;AAAA;;AAKA;;AAJA;AAAA;AACA;AAAA;AAGA;;;;;;;AA4GA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AAEA;;AACA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AADA;AAAA;AAAA;AAAA;AAEA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AArpBA;AAAA;AAtFA;;;AAGA;AAAA;AADA;AACA;AAAA;;;;;AAEA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AAwFA;AAaA;AAAA;AAAA;AACA;AAAA;AADA;;AAEA;;AA8YA;;AArYA;AAMA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;;;AAEA;AACA;;;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;AAEA;;;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;AAIA;AAAA;AAAA;AAAA;;AACA;;;;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AADA;AAAA;;;;;;;;;;;;;;;;AAMA;AACA;AAMA;AAQA;AAAA;;;AACA;AAEA;;AACA;;AACA;AAAA;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AA9LA;AAAA;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AACA;AAAA;;;;AAJA;AAAA;AAAA;;;;;;;AAiMA;AAAA;AAAA;AAAA;;;;;AAeA;AAAA;;;;;;AAEA;AADA;AAGA;AADA;AAEA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;;;;;;;AAKA;AAAA;;;;;;;;;;;AAEA;AACA;AAEA;;AACA;;;;;;;AAIA;AAAA;;;;;AAGA;;;AAOA;AADA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;AA0dA;AAAA;;;;AAEA;AAAA;;;;AAEA;AAAA;AAAA;AACA;AADA;AAEA;AAAA;AAAA;AACA;AADA;AAEA;AAAA;AAAA;;;;;AAKA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AALA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;;AACA;AAAA;;AACA;AACA;;;;;AApBA;AAAA;AAAA;;;;;;;AAndA;;AAKA;;AAJA;;AAOA;AADA;AAGA;AADA;AAEA;AAAA;AAAA;;;;;AAEA;AACA;AAAA;;;AACA;AAAA;;AAKA;;;AAJA;;;;;AAcA;AAAA;AACA;AAAA;AAAA;AACA;AARA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA;AACA;AAhTA;AAAA;;;;;AAGA;AACA;;;;AACA;;;;;;;AACA;AAAA;;;;;;;;;;;;AAEA;AAAA;AAEA;;;;AACA;;;;;;;;;;;;;;;AA8SA;AAAA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;AAQA;;;;AALA;AADA;AAAA;;;;AAEA;AAAA;AACA;AADA;AADA;;;AAAA;;;AAUA;AAAA;AACA;AADA;AAEA;;;;AAGA;;AAEA;AADA;AAAA;;;;;AAGA;AAAA;AAAA;AAAA;;;;;;;;AAIA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAMA;AAAA;;;;;;;;;;;;;;;;;;;;;;;AAgBA;AAAA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAOA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAMA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;;AAGA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;;AAIA;AAEA;AADA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;;;;;;;;;;;;AAYA;AAAA;;;;AACA;AAEA;;;AAGA;AAAA;;AAOA;AAAA;;;;AACA;;;;AAPA;AAEA;;;;;;;;AAUA;AAAA;;;;AACA;AAEA;;;AAGA;AAAA;;;;AACA;AAEA;;;AAGA;AAAA;AACA;AAAA;AADA;;AAEA;AAGA;AADA;;;;;AAIA;AAAA;;;;AACA;AAEA;;;AAGA;AAAA;AAAA;AAAA;;;;;;;;;;;;AAiBA;AAAA;AAAA;AAAA;AACA;AADA;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;;AACA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;;AAIA;;;AACA;AAAA;AACA;;;;;;;;;;;;;AAGA;AAjfA;AAAA;;;;AAGA;AACA;;;;;AACA;;;;;;;AACA;AAAA;;;;;;;;;;;;AAEA;AAAA;AAEA;;;;;AACA;;;;;;;;;;;;;AA8fA;AAAA;AAAA;;;;;AAKA;AACA;AACA;AAAA;;;;;;;;;;AAxTA;AAAA;AAGA;;AAFA;AAAA;AAAA;AAAA;;;AAGA;AACA;AADA;AAAA;;;AAKA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAKA;AAAA;AAAA;AAAA;;;;;;AASA;AAAA;AAAA;;;;AA8fA;AAAA;AAAA;;;;AAjdA;AAAA;AAAA;;;;AA0EA;AADA;AAAA;AAAA;AAAA;;;;;AAqDA;AADA;AAAA;AAAA;AAAA;;;;;AAyDA;AAAA;;;;AAYA;AAAA;;;;AA2BA;AAAA;;;;;AA2BA;AAAA;;;;;AAvBA;AAAA;AAAA;AAAA;;AACA;AAAA;AAEA;;;;AAwBA;;AACA;;AACA;AAAA;AACA;AAAA;AACA;;AACA;;;;AAIA;;AAFA;;AAEA;;AA9BA;AAAA;AACA;AAAA;AACA;;AACA;;;;AA2BA;;AAzBA;;AAyBA;;;;;;;;;;;;AA4HA;AAAA;AAMA;AAAA;AACA;AAAA;AAAA;AAGA;AACA;AAGA;AAGA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;AAQA;AAAA;;AAPA;AACA;AASA;AACA;;;;;;;;;;;;;;;;AAgGA;AAAA;AACA;AADA;;;AA2BA;;AA1BA;AAAA;;;AA0BA;;AAvBA;AAAA;;;;AAAA;AAAA;;;;;;;;;;AAGA;AACA;;;AAEA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;;;;AACA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAEA;AAAA;AAAA;AAGA;AAAA;AAHA;;AAIA;;;;;;;;;;;;;;;;;;;;AAMA;AAEA;AAAA;;AAqBA;;AAlBA;AAAA;;AACA;AAiBA;;AAbA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;AACA;AACA;AAAA;AAUA;;;;;AANA;AACA;AAAA;AADA;AACA;;AACA;AAAA;;AAEA;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACsLA;AAIA;AAAA;AACA;AACA;AAAA;AAGA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;AAQA;;AACA;AAAA;AACA;;;;;;;;;;AACA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;;;AACA;;;;;;;;;AAIA;AACA;AAFA;AAEA;;;;;;;AAPA;AAAA;AAAA;AAAA;;;;;;;AAUA;AAAA;AAAA;AAAA;AACA;AAIA;;;;;;;AAGA;;;;;AAGA;AAAA;AAAA;AACA;AAAA;AACA;AACA;;;;AAIA;AAAA;AACA;;AACA;AAAA;;;;AAIA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;AAKA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;AACA;AAAA;;;;;AAGA;AAAA;;AACA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAQA;AAAA;AAAA;AAAA;AAEA;AAAA;;;AAEA;AADA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AA3NA;AAAA;AACA;AAGA;AACA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AACA;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AAEA;;;;AACA;;AADA;;;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAlCA;AAAA;;AAkCA;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAGA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AADA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;AACA;AAAA;;AAIA;AAAA;;AACA;AAAA;;;;AACA;AAAA;AAAA;;;;;;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAKA;AAAA;AAAA;;AACA;AAAA;;;AAGA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;;AAIA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAGA;AAAA;;AACA;AAAA;;;AAGA;AAAA;;AAOA;AACA;;;AAPA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AACA;;;;;AA2HA;AADA;AAAA;AAAA;AAAA;;;;AAIA;AAAA;;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA5BA;AAAA;AAAA;AAAA;AAAA;;;;AAkCA;AAAA;;AAIA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;;AAVA;AAAA;AACA;AAAA;AAEA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;AAjYA;AAAA;AAAA;;;AAmCA;;;;;;;AAlCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;;;AAOA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;;AAnCA;AAAA;AAAA;AAGA;;AAFA;AAAA;AAAA;;;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;;;;;;;;AAIA;AAAA;;;;AA+BA;AAAA;AACA;;;;AAGA;AAAA;AACA;AACA;AAAA;;;;;AA3CA;AAAA;AAAA;AAGA;;AAFA;AAAA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;;;AAIA;AAAA;;AAuBA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAnSA;AAEA;AAAA;AAAA;;AAEA;;;AAIA;AAAA;AAEA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AA1NA;AAAA;;;AACA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;AAOA;;;AAkNA;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;;;;;;;;;;AAkSA;;;;;;;AA/BA;AAAA;;;;;;;;;;AACA;AAAA;;;AAkCA;;;;;;;;;;AAMA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AAqBA;;AAlBA;;AAAA;AAAA;AAAA;;AACA;AACA;AAAA;;AAgBA;;;AAZA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAEA;AAAA;;AAEA;;;;;;;;;;;;AA3oBA;AAAA;AACA;AADA;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AAwBA;;AArBA;;AACA;;AAGA;AADA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;;AAIA;;;;;;AAzCA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;;;;;;;;;;;;;;;;;;;AAkDA;AAEA;;AACA;AAAA;;AAEA;AAAA;AAAA;AAAA;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;;AACA;AAAA;;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAGA;AAFA;AAAA;AAAA;AAAA;AAGA;AACA;AAAA;AACA;AAAA;AACA;;AAKA;AAFA;AAAA;AAAA;AAAA;AAGA;AACA;;;;;AAMA;AAFA;AAAA;AAAA;AAAA;AAGA;AACA;AAAA;;;;AACA;AAAA;AACA;AACA;;;AAGA;AAAA;AACA;AApBA;;;;;;AA+BA;;AATA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AAGA;;;;;;;;;;;AA+iBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAEA;;AACA;AAAA;;AAEA;AAAA;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AACA;AACA;AAEA;AAOA;AAAA;AACA;AAAA;AAEA;AAAA;AACA;AACA;;;;;;AAAA;AACA;AAEA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;AACA;AACA;AATA;AACA;AADA;;;;;;;;;AAWA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AACA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AA7/BA;;AACA;AAAA;;AACA;AAAA;AAAA;;AASA;AAAA;AACA;AAAA;;;AARA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;;;AAKA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;AACA;AAAA;;;AAGA;AAAA;AAAA;;AACA;AAAA;;;;AAGA;AAAA;;;AAMA;AAAA;AACA;;;;AAEA;AAAA;AACA;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;AAAA;;;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAEA;;;;;AAlBA;AAAA;AAAA;AAAA;;;;AAwBA;;;;AACA;AACA;AAGA;;AAEA;;AADA;AACA;;;;;;;;;;;;;;;;;;;;;AA4kBA;AAEA;AAGA;AAAA;AAAA;AAAA;AAEA;;AADA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;AAuDA;;AAnDA;AAAA;AAEA;AAAA;;;AAiDA;;;;;;;AAhDA;;;;AAGA;AACA;AAAA;;;;;;;;AAMA;AAAA;;;;;;;AAKA;AAAA;;;;;AAKA;;;;;;;;;AAGA;AAAA;AAAA;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;;;;AAAA;AAAA;;AACA;AAAA;;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;;;;;;;;AAEA;;AACA;AAAA;AACA;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;;;;;;AA7CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;;;;;;;;;;AAMA;AACA;;;AA0CA;;;AAbA;AAAA;;;AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA1NA;AAAA;AAAA;AAAA;AACA;;;AA0HA;;AAxHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;;AAEA;;AAmHA;;AA/GA;AACA;AAAA;AAAA;;;;AAIA;AACA;;;AAJA;AACA;;;AAKA;AACA;AAAA;AAEA;AAAA;AAAA;;AAEA;AAAA;;;;;AAHA;AAIA;AAAA;AAAA;;AAGA;AAAA;AAAA;AAAA;AACA;AACA;AAtGA;AAAA;;;AAFA;AAGA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;AAOA;;;AA8FA;;AAJA;;AAMA;AAAA;AAAA;AAQA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;AAFA;AAAA;;;;;;;;;;;;;;;AAeA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;AACA;AAAA;AAAA;;;;;;AAvFA;AAAA;AAGA;AAAA;;;;;AAIA;;AAAA;AAAA;;;AACA;AAAA;AAAA;;;;AACA;AAAA;;;;;;;AAFA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;AACA;AAAA;;;;;;;;AA6EA;AAAA;;;;;;;;;;;;;AAcA;AAAA;AAAA;AAAA;;;;;AAFA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAWA;AAAA;AAAA;AArIA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAnBA;AAAA;;;AAFA;AAGA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;AAOA;;;AAYA;;;;;AAQA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;;AA5BA;AAAA;;;AAFA;AAGA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;AAOA;;;AAqBA;;;;;;AAIA;AAAA;;AAjCA;AAAA;;;AAFA;AAGA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;AAOA;;;AA2BA;AAEA;;;;;;;;;;;;;;;;AAsHA;AAAA;AAAA;AAAA;AAAA;;;;AAQA;AAAA;AAAA;;;;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;;AAEA;AAAA;AAGA;AAAA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;;AACA;AAAA;;AACA;AAGA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;;AAGA;;;AAtCA;AAAA;AACA;;AAqCA;;;;;;;;;;;;;;;;;;;;;;;;AApuBA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;;;AAEA;AAAA;AAAA;AACA;AACA;;;;;;AAGA;AACA;;;;;;;;AA86CA;AAAA;;;;;;;;;AACA;;;AAEA;AAAA;;;;;AAAA;AAAA;;AAOA;AAAA;;;;;AA/CA;AAAA;AAAA;;;;;AAAA;AAAA;;;;;AAGA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;;;;;;;;;;AAsCA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;;;AAKA;AAAA;AAAA;;;;;;;;AAKA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AA7CA;AAAA;;;;;;;AACA;AAAA;;;;AADA;AAAA;AAAA;;;;;;;;AA8CA;AA3DA;AAAA;AAAA;;AAAA;AAAA;;AAGA;AAAA;AAAA;;;;AAAA;AAAA;;;;;;;;;;AAaA;AAAA;AA2CA;;AAOA;AAfA;AAAA;AAAA;AAAA;;;;;;;;AAUA;AAAA;AACA;AAAA;AACA;AACA;AAr8CA;;;;;;;;AAEA;AAGA;AAAA;AAIA;AAAA;AAAA;AAAA;;;;;AAIA;AACA;AAAA;;;AA26CA;AACA;AAz7CA;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;AASA;AAAA;AAAA;AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAvUA;AAKA;AACA;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAEA;AAAA;AADA;AAAA;AAGA;AAAA;AADA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAIA;AAAA;AAAA;AADA;AAAA;AAEA;AAAA;;;AAQA;AAAA;AA3EA;AACA;AACA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;;;;;;;;AAEA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;;;;;;;;AAGA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;AASA;AAAA;;;;;AAAA;AAAA;;;;AACA;AAAA;;;;AAGA;AADA;AAAA;;AAIA;AAAA;;AAAA;;AAAA;;AAFA;AAAA;;AAAA;;AAAA;;AALA;AAAA;;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;;;AASA;AAAA;;;;AAAA;AAAA;AAAA;;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;;;AA2BA;AACA;;AAGA;;;;AAFA;AAAA;AAAA;;;;AAQA;;;AAIA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAIA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAaA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAIA;AAAA;AADA;AAEA;AAAA;AAAA;AAAA;;AAGA;AAAA;AACA;AAAA;AAAA;AASA;;AAZA;AAAA;AAAA;AAAA;;;;;;;;;AAlIA;AAEA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4QA;AAIA;AAAA;;AACA;;AACA;AAAA;;;AAkjDA;AACA;AAAA;;;;AA9EA;AAAA;AAAA;;;AAAA;AAAA;;AAGA;AAAA;AAAA;;AAAA;AAAA;;;;;AA6EA;AAAA;;AACA;;AACA;AAAA;AAAA;;;;AAJA;AAAA;AAAA;;;;;;;;AAOA;AAAA;;AACA;AAAA;AAAA;;AACA;AA3jDA;;;;;AAGA;AAk6BA;AAIA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAGA;AAAA;;;;AACA;AAAA;AACA;;;;AAAA;AAAA;;;;AAEA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;;;;;AAEA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAZA;;;;;;;;AAeA;AAAA;;;;AACA;AAAA;AACA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAVA;AAAA;;;;;;;;AAaA;;;;AAIA;AAAA;;;AAMA;AAAA;AAAA;;;;;;AAEA;;;AAAA;;;;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;;AAKA;AAAA;;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAvBA;AAAA;AAAA;AAAA;;;;;;;;;AA0BA;;AAEA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAFA;;;;;;;;AAIA;AAAA;AAAA;;;;;;;;AAnCA;AADA;AAAA;AAAA;AAAA;;;AAEA;AAAA;;;;;;;AALA;AADA;AAAA;AAAA;AAAA;;;;AA2CA;AAAA;;;;AAAA;AACA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;;;;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;;;AAJA;AAAA;;;;;;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAMA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;;;;;AAnBA;;;;;;;;AAuBA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAFA;;;;;;;;;AAKA;AAAA;;;;AAAA;AACA;AAAA;AAAA;;;;;AACA;AACA;AADA;AACA;;;;;;AAGA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;AAKA;AAAA;AADA;AAAA;AAAA;AAAA;AADA;AAAA;AAEA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAbA;;;;;;;;AA/gCA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAw+CA;AAAA;;;;;;;AACA;AAAA;;;;;AADA;AAAA;AAAA;;;;;;;;;;;AAGA;AAAA;;;AA1+CA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAEA;AAFA;AAEA;AACA;;AACA;AAAA;;AAEA;AAAA;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAFA;AAAA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AADA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;AAghCA;AAAA;;AACA;;;AACA;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;AALA;;;;;;;;AA/gCA;AAEA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;AAgFA;AAEA;AAAA;AAAA;;;;;;;;;AA1CA;AAAA;AAAA;;;;;;;;;;;;;;AAjCA;AAGA;AAAA;;;AAGA;AAAA;;AAEA;AAAA;AAAA;AACA;AAAA;;;;AAkBA;;AAhBA;;;AAEA;AAAA;;;AAcA;;AAZA;AAmcA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAlcA;AACA;AACA;AACA;;AAIA;;;;;;;;;AAwEA;AAIA;;AACA;AAAA;;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;;;AACA;AAAA;AAAA;AACA;AACA;AAAA;AACA;;;;;;;;;;AAkBA;AAAA;AAAA;AAAA;AAAA;AAMA;;AACA;AAAA;;AAEA;AAAA;AACA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;;AACA;AAi4BA;AAAA;AAAA;;;;AACA;AAAA;AADA;AAAA;;;;;;;;;AA73BA;AAAA;AAEA;AACA;;;;;;;;;;;;AAhEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;;AAHA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;;;ACisBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIA;AACA;AACA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AACA;;;;;;;;;;;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIA;AACA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AACA;;;;;;;;;;;;;;;;;;AAOA;AAKA;AACA;AAAA;AADA;;AAwEA;;AApEA;;;AASA;AACA;;AAAA;;;AACA;AAAA;AAAA;;;;AADA;AAAA;AAAA;AAFA;AAAA;;;;;;;AAMA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAGA;;;;;AADA;AAAA;;;;;AAcA;AAAA;;;;AAKA;AAAA;;AAWA;AAAA;AACA;AAAA;AACA;AAEA;AAAA;AAGA;AAEA;AAHA;AAAA;AAIA;AAAA;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;AAvBA;AAAA;AAAA;;AAKA;AAAA;AAEA;AAAA;;;AALA;AACA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAlBA;AAAA;;AACA;AACA;;AAEA;AACA;AAAA;AACA;AACA;AAiCA;;;;;;;;;;;;;;;;;;;;AA3MA;AAAA;AAOA;;AACA;AACA;AACA;AAAA;AAAA;AAIA;AACA;AACA;AAEA;AAAA;AACA;AADA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;;AAsDA;;AAlDA;AACA;AAGA;AAAA;AAAA;;;;;AAKA;AAAA;AAEA;AAAA;;AAGA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;;AACA;;;;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAIA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;;;;;AARA;AAAA;;;AAYA;AAAA;;;;AACA;AAAA;AACA;AADA;;;;;;;;;AArCA;AAAA;;;AAyCA;AACA;;AAEA;;;;;;;;;AAh+BA;AAAA;AAAA;AAAA;AAEA;AAEA;AAAA;AAAA;AAAA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;AACA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAEA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;AACA;;;;AAGA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;;AA8BA;AAAA;AAEA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;;AA+BA;;AA5BA;AAAA;;;AAKA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAsBA;;AAlBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;;;AACA;AACA;AAEA;AAAA;AAAA;;;;AAKA;AAAA;AACA;AACA;AAXA;AAAA;;;;;AAKA;AACA;;;;AAOA;;AAEA;;;AA1BA;AAAA;;AA0BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AAEA;AAAA;;;;;AACA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;;;AACA;AAAA;;;;AAYA;;;AAGA;AAAA;;;;;;AAEA;AAAA;;;;;AAnGA;AAAA;AAAA;AAAA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;;;AAIA;AAAA;;;;AACA;AAAA;AAAA;AAAA;;;;;AADA;AAAA;;;;;;;;;;AA8FA;AALA;AAAA;;;;;;AAQA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;;;;;;;;AACA;AAAA;;;AAOA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;AACA;AAAA;AACA;;AAKA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AADA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAqBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;;;AAqBA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;;AACA;AAAA;AAEA;AACA;AACA;;;;AAMA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAGA;AAAA;;AACA;;AACA;AAAA;;AACA;;AACA;AAAA;;AACA;;AAIA;AAAA;AAAA;AAAA;AAKA;AAIA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;;AACA;AAGA;AAHA;;AAOA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AAIA;;AA3EA;AAAA;AAEA;AACA;AACA;;;AAEA;AACA;AACA;AACA;AAAA;AACA;;;;;AAEA;AAAA;AAAA;AADA;;AAAA;;;;;;;AAEA;;AAEA;AACA;;AA2DA;;;AApGA;AAAA;AAAA;AAAA;AAGA;AADA;;;;;;AACA;AADA;AAAA;;;;;;;;;AAEA;;;;;;;AACA;AAAA;AAAA;AADA;;AAAA;;;;;;;;;AAEA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;;AAsFA;;;;;;;;;;;;;;;;;;;;AAjJA;AACA;AACA;;;;;;;AACA;AAAA;AAAA;AADA;;AAAA;;;;;;;;;AAEA;AACA;AAAA;AACA;AACA;AAAA;;AA0IA;;;;;;;;;;AAGA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAAA;AAEA;;;;;;;;;;AAIA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;AAGA;AADA;AAAA;AAAA;;AAEA;AAAA;AACA;AACA;AACA;AAUA;;;AALA;AACA;AACA;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0JA;AAGA;AAAA;;;AACA;AAAA;;;;AACA;AAAA;;AACA;AAAA;;;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;;;;AAKA;AAAA;;AACA;;;;;AAGA;AAAA;;AACA;;;;;AAIA;AACA;AAAA;AAAA;AACA;AACA;AADA;;AAIA;AAAA;AAAA;AACA;AAGA;AAFA;AADA;;AAKA;AAAA;AACA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;;AAWA;AAAA;AAAA;AAAA;;AACA;AAAA;;;AAIA;AAAA;;AACA;AAAA;AAAA;AAAA;;;AAIA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;AAQA;AAAA;;;;;;;;AAjLA;AAAA;AAVA;;;AAYA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;AAuKA;;;;;;;;;;;AAjLA;AAAA;AAVA;;;AAIA;AAAA;;;;AAQA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;AAuKA;;;;;;;;;;;AAaA;AAAA;;;;;;;;;AA9LA;AAAA;AAVA;;;AAYA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;AAoLA;;;;;;;;;;AA9LA;AAAA;AAVA;;;AAIA;AAAA;;;;AAQA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;AAoLA;;;;;;;;;AAGA;;;;;AAEA;AAAA;AAEA;AACA;AAEA;AAAA;AAAA;AADA;;;;;;;;;;;AAlBA;AAAA;AAEA;AACA;;;;AAuBA;AAAA;AAAA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;AACA;AACA;;;;;;;;;;;;AAKA;AAAA;;;AACA;AAAA;;;;;AASA;AAoBA;AACA;;AAhBA;AAAA;AAAA;AACA;;;;;AAEA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAjIA;AAAA;;AAiIA;AAAA;AACA;AAGA;AAAA;;;;;;AAtBA;AAAA;AACA;AACA;AACA;;;;AA0BA;;AAQA;;;AA/FA;AAAA;AAAA;AAAA;;AArBA;AAAA;AAAA;AAAA;;;AAEA;AACA;AACA;AACA;AACA;;AA8GA;;;;;;;;;;;;;;;;AAlJA;AAAA;AA6IA;AACA;AACA;;;AALA;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA;AAEA;AAAA;;AACA;AAAA;;;;AACA;AAAA;;AACA;AAAA;;;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;;;;AAMA;AAAA;;AACA;;;;;AAGA;AAAA;;AACA;;;;;AAIA;AACA;AAAA;AAAA;AACA;AACA;AADA;;AAIA;AAAA;AAAA;AACA;AAGA;AAFA;AADA;;AAKA;AAAA;AACA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;;;;AAGA;AAAA;;;;;;;;;;;;;;;;AA3TA;AAAA;AAVA;;;AAYA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;;;AAiTA;;;;;;;;;;;;AA3TA;AAAA;AAVA;;;AAIA;AAAA;;AAQA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;;;;AAiTA;;;;;;;;;;;;;;AASA;AAAA;;;;;;;;;;;;;;;;AApUA;AAAA;AAVA;;;AAYA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;;;AA0TA;;;;;;;;;;;;AApUA;AAAA;AAVA;;;AAIA;AAAA;;AAQA;AAAA;AAZA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAUA;AAAA;AAAA;;AAEA;AAAA;AAhBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAcA;AAAA;AAlBA;AAAA;;AAEA;;;;AAEA;AAAA;;;;;AAgBA;AAAA;AAAA;;;;;;;;;;;AA0TA;;;;;;;;;;;;;;;;;;;;;AAUA;;;;AAEA;;AAOA;AAAA;;;;;;AAIA;AACA;;;;;;AAKA;AACA;AAEA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;AASA;AACA;AACA;AAEA;;;;AATA;AACA;AACA;;AAGA;AACA;AACA;AAEA;;;;;;;;;;;;;;AA5FA;AAAA;;AAwFA;AACA;AACA;AAEA;;;;;;;;;;;;;;;;;;;;;;;AAaA;AAAA;;;;AACA;AAAA;;;;AACA;AAAA;;AAMA;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAKA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;;AADA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAGA;;;AAYA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;;;AAaA;AAAA;AAAA;;AAGA;AADA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAEA;AACA;AACA;;;;AAMA;AAAA;;AACA;;AACA;AAAA;;AACA;;AAEA;AAAA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;AAGA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AAAA;;AAIA;;AAhDA;AAAA;AAEA;AACA;AACA;;;AAEA;AACA;AACA;;AAwCA;;;AAhEA;AAGA;AACA;AACA;;AA2DA;;;;;;AAjFA;AACA;AACA;AAAA;;AA+EA;;;;;;;;;;AAgDA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;AAGA;AADA;AAAA;AAAA;;AAEA;AAAA;AACA;AACA;AACA;AAmBA;;;AAdA;AAAA;;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;;AAIA;AACA;AAGA;;;;;;;;;;AAGA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAEA;;;;;;;;;AAn6BA;AAAA;AAAA;AAEA;AAEA;AAAA;AAAA;AAAA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAQA;AAAA;AAAA;AACA;;AARA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;AACA;AAEA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;AAo0BA;;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;;AAIA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AAAA;AAAA;;AAIA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;AAAA;AACA;AACA;;;;;;;;;;;;;;;;;;AA5iBA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;;;;;;;AACA;AAAA;AACA;AAAA;AAAA;AACA;AADA;;AACA;AAAA;AANA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BA;AAAA;;;;AAhBA;AAAA;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAHA;AAAA;AAAA;AAAA;AAiBA;AAAA;;;;AAVA;AAAA;AAAA;;AACA;AAAA;;;;;;;;;;;;;;AAEA;AAAA;AACA;AAAA;AAAA;AACA;AADA;;AACA;AAAA;AANA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA;AAAA;;;;AAFA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA;AAKA;AAAA;AAAA;;AAEA;AAAA;AAgEA;;AA7DA;AACA;AAAA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;;;AACA;AAAA;;;;;;AAIA;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAMA;AAAA;AAAA;AAGA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AADA;;;AAGA;AACA;AAAA;AAAA;;;;;AAKA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAKA;AADA;AAAA;;AAHA;AAAA;;AAOA;AACA;AAAA;AAAA;;AACA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;;;AA3CA;AAAA;;;;AA8CA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;AAkrBA;;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;AACA;;AAIA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIA;AACA;AAAA;AADA;AAEA;;AAEA;AAEA;AACA;AADA;AAGA;;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AAAA;;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAGA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;AAIA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;AAKA;AACA;;AALA;AAAA;;;;;;;AACA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAAA;AAAA;;;AAEA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4uBA;AAAA;;AACA;AAAA;AAAA;;;AAMA;;;AAGA;;;;;;;;AA0FA;;;AAlFA;AACA;AAEA;AAAA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;;AACA;;;;;;AAMA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;;AAGA;AAAA;AAAA;AACA;AAAA;AADA;;;AAEA;AAAA;AACA;;AACA;AAAA;AAAA;;AACA;AAAA;;;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;;;;AAGA;;AAoDA;;AAjDA;AApoBA;AACA;AACA;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAGA;AAAA;;AACA;AA2nBA;AAAA;AACA;;AA6CA;;AArqBA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAEA;AAAA;;;AACA;AACA;AAEA;AAAA;AACA;AACA;AANA;AAAA;;;;;;AAQA;AA0mBA;;;AAEA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AACA;AAAA;;;;;AAzjBA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAGA;AAAA;;;AAUA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAeA;AACA;AAAA;AAAA;;;;;AAVA;AACA;AAAA;AAAA;;;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AAAA;;;;AAtBA;AAAA;AAAA;;AACA;;;AAIA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;;;AA0iBA;AAAA;;AAEA;AAAA;;AADA;AAAA;AACA;AAAA;;;;AAEA;AAAA;;AAEA;AAAA;;AADA;AAAA;AAAA;;;;;AAGA;AAAA;;AACA;AAAA;;AAwBA;;AA/bA;AAAA;AAEA;AAAA;AAAA;;;AACA;AAAA;;AAIA;AAEA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AACA;;;AAGA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;;;;AApkDA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;;;;AAIA;AAAA;;;;;;;;AACA;AAAA;AAAA;AAAA;;;;;AADA;AAAA;;;;;;;;AA8jDA;AAAA;AAAA;AAAA;;;;;;AAFA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAOA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;;AAGA;AAAA;AAAA;;AAFA;AAAA;;AAEA;AAAA;AAAA;;AADA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAGA;AACA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;;;AAIA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAIA;AACA;AAAA;AAAA;AAAA;AAkBA;AAAA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AACA;AACA;AACA;AAEA;AACA;;;;AACA;AAAA;AAAA;AAAA;;;AAUA;AACA;AAAA;;;;;;;AAEA;;;;;;;;;;;;;;AAGA;AAAA;;;;;AAIA;AAAA;AAAA;AAAA;AAVA;AACA;AAAA;;;;;;;;AAcA;AAAA;;;;;AAIA;;;;;AAEA;AArBA;AACA;AAAA;;;;;;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAuBA;;;;;AAdA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;;;AAKA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAIA;AACA;;;;;AACA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;;;AAGA;;AACA;;;;AAGA;AAAA;;;;;AANA;AAAA;AAAA;;;;AAQA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;;AAFA;AAAA;AAAA;AAAA;AAEA;AAAA;;;;AApFA;AACA;AACA;AAAA;;;;;AAGA;AACA;AACA;AAAA;AAAA;AAAA;;;;;AAGA;AACA;AAAA;AAAA;AAAA;;;;;;;AA4WA;;;;AArPA;AAAA;AAEA;AAAA;AAAA;;AACA;AAAA;AAiOA;AAAA;;AA7NA;AAEA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AACA;;;AAGA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;;AAEA;AAAA;AAAA;;AADA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAGA;AAEA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;AAuLA;AAAA;;AAnLA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAIA;AACA;AAAA;AAAA;AAAA;AAgBA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AAKA;AACA;AAAA;;AAOA;AAAA;AAAA;AAAA;AAAA;;AANA;AAAA;AAAA;;AAgJA;AAAA;;AA/IA;AAAA;AAAA;;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;AAFA;AAAA;;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;AA6IA;AAAA;;;;;AAzKA;AACA;AACA;AAAA;AAAA;;;;AAEA;AACA;AACA;AAAA;AAAA;;;;AAEA;AACA;AAAA;AAAA;AAAA;AAgKA;AAAA;;;;;;AAhIA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAGA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;AAGA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAeA;AACA;AAAA;AAAA;AAiGA;AAAA;;AAEA;AAAA;;AADA;AAAA;AACA;AAAA;;;;AA7GA;AACA;AAAA;AAAA;;;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AAAA;;;;;;AAyGA;AAAA;;AAGA;AAAA;;AAFA;AAAA;AAEA;AAAA;;;;AAlRA;AACA;AACA;AAAA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAGA;AAAA;;;AAIA;AACA;;AACA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AAGA;AAEA;AAAA;AACA;AAAA;AAAA;;;AALA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AATA;;;;AA+QA;;;;AAFA;AAAA;AAAA;;;;;;;;;;;;;;AAnwBA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AACA;AAEA;;;;;;;AACA;AAAA;;;;;;AAKA;AACA;;;;AACA;AAAA;;;AAKA;;;;;;;;;;;AAZA;AAAA;;;;;;AAuBA;AAKA;;;;;AA7BA;;;;;;;;AAEA;AACA;AAAA;;AA8BA;;;AAfA;AAAA;AACA;AACA;AAAA;;AAaA;;;AARA;AACA;AAAA;;AAOA;;;;AAFA;;AAEA;;;;;;;;;;;;;AAUA;AACA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;;AAeA;;AAZA;AAAA;AACA;AAAA;;AAOA;AACA;AAAA;AACA;;AAEA;;AAVA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;;AAOA;;;;;;;;;;;;;;;;AAqDA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAGA;AAAA;;AACA;;AAqBA;;AAjBA;AACA;;AACA;AACA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAEA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;AAGA;;;;;;;;;AAsIA;AAKA;AAAA;AACA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;;AAGA;AAHA;AADA;AAAA;;;;;;;;;;;AAOA;AAAA;;;;;AAKA;;;AAHA;AAAA;AADA;;AACA;AADA;AADA;AAAA;;;;;;;;AAKA;;;;;;AA7XA;AACA;;;;;;AASA;AAAA;AAEA;AAAA;;AACA;;AAEA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;AA6QA;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;AAEA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;;AAIA;AAAA;;;;AACA;AAAA;AAAA;;;AAFA;;AAFA;;AAMA;AAAA;AAAA;AACA;AAAA;AAAA;;AAIA;AAAA;AAAA;AAAA;AADA;;AAFA;;AAKA;AAAA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAGA;AAAA;;AACA;;AAwCA;;AApCA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAOA;AAAA;AAAA;;AACA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AACA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;;AACA;AAAA;AAAA;AAAA;;;;;AAGA;AACA;AACA;AAAA;;AAeA;;;;AAZA;AACA;AACA;AAAA;AAAA;AAAA;;AAUA;;;;AAPA;AAAA;AAAA;AAAA;AAAA;;;AAGA;AAEA;AAAA;AAAA;;AAEA;;;;;;;;;;;AA3UA;AACA;AAAA;AACA;AACA;;;AA2BA;;;;;;;AA1BA;AAAA;;;;;;AAIA;AACA;;;;AACA;AAAA;;;AAKA;;;;;;;;;;;;AAXA;AAAA;;;;;;AAmBA;AAIA;;;;;AAxBA;;;;;;;;;;AAEA;AAAA;;AAyBA;;;AANA;AAAA;;AAMA;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACh4CA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEA;;;;;ACnEA;AAAA;;;AAYA;;AAVA;AAAA;AACA;AAAA;AAEA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;;;AAKA;;AAJA;;AAIA;;;;;;;AAOA;AAAA;AAAA;;;AAUA;;AATA;AAAA;;;AASA;;AAPA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;;AAGA;;;;;;;;;;AApEA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AA8EA;AAAA;AACA;AAAA;AAAA;;AAEA;;;;;;;;;AAtEA;AACA;;AAqEA;;;;;;;;;AAtEA;AACA;;AAqEA;;;;;;;;;;AAjFA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AAAA;AAAA;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;;;;;;AAgQA;;;;;AArPA;AACA;;;;AAZA;;AAAA;AAAA;AAAA;;;;;;;;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAgPA;;;;;;;;;;;AArOA;AACA;;;AA8CA;AAAA;AAAA;;;AAuCA;;AAtCA;AAAA;;;AAsCA;;AApCA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AA2BA;AAAA;;;AAKA;;AAJA;;AAIA;;;;;;;;;AAtFA;AACA;;AAqFA;;;;;;;;AAoBA;;AAgCA;;AArJA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAmIA;AAAA;AAAA;AACA;AAMA;AAAA;AAAA;AACA;;AAUA;;AARA;AACA;AAAA;;AACA;AAAA;AAAA;AACA;AAAA;;AAEA;AACA;;AAEA;;AADA;AACA;;;;;;;;;AA1IA;AACA;AAyIA;;;;;;;AArJA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAgQA;;AACA;;;;;;;;;AAtPA;AACA;;AAqPA;;;;;;;AAjQA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAgPA;;AACA;;;;;;;;;AAtOA;AACA;;AAqOA;;;;;;AA3IA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;AAEA;;AADA;AACA;;;;;;;;AA8CA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AA5JA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AAkKA;;;;;;;;;AAvJA;AACA;AAuJA;AAAA;AACA;;;AADA;AAAA;AACA;AAAA;;AAMA;;AALA;AAAA;AAAA;;AAKA;;AAJA;AAAA;AACA;AAGA;;;AAZA;AAAA;AAAA;AAAA;AAYA;;;;;;;;;;AA1KA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AA8MA;AAAA;AAAA;AAAA;;;AA2BA;;AAzBA;;;AAyBA;;AAvBA;;;AAuBA;;AAlNA;;;;;AA8LA;;AA3LA;AAAA;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;;;;;AAyLA;AAAA;AAAA;;;AACA;AAGA;AAAA;AAHA;AAIA;AAAA;AAEA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;;AAUA;;AARA;AAAA;AACA;;;;AAGA;;;AAIA;;;;AAFA;;AAEA;;;;;;;;;AA9NA;AACA;;AA6NA;;;;;;;;AAzOA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAsQA;AAAA;AAAA;;;AAGA;;AADA;AAAA;;AACA;;;;;;;;;AA9PA;AACA;;AA6PA;;;;;;;;;AAzQA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAkRA;AAAA;AAAA;;;AAOA;;AAHA;;;AAGA;;AAHA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AA3QA;AACA;;AA6QA;;;;;;;;;AAUA;AAAA;;;AAiCA;;AA3BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAlRA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;AA8QA;AAAA;AAAA;AAAA;;;AAyBA;;AAjBA;AAAA;AAEA;AAAA;AAAA;AAGA;AAAA;AAAA;;;AAYA;;AARA;AACA;AAAA;AAAA;AACA;AAAA;AAEA;;AAIA;;;;;;;;AAQA;;AACA;;AAGA;AAAA;;;AAQA;;AALA;AAAA;AAAA;AACA;AAAA;;;AAIA;;AALA;AAGA;;AAEA;;;;;;;;;AAxVA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAkWA;;;AAOA;;;AAzWA;AAAA;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;;;;;;AAgPA;;;;;AArOA;AACA;;;AAwVA;;;AAKA;;AAHA;AAAA;AAAA;;AAGA;;;;;;;;;AA9VA;AACA;;AA6VA;;;;;;;;;AAzWA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAmXA;;;AAOA;;;AA1XA;AAAA;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;;;;;;AAgPA;;;;;AArOA;AACA;;;AAyWA;;;AAKA;;AAHA;AAAA;AAAA;;AAGA;;;;;;;;;AA/WA;AACA;;AA8WA;;;;;;;;;;;;;;;;;;;;;;;AC5RA;AAAA;;;AAGA;;;;;;AA6BA;;;;;;;;;;;;;;;;;AApBA;;;AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0KA;;;;;;AAzJA;AAAA;;;;AACA;AAAA;;;;AADA;AAAA;;;;;AAKA;;;;AAHA;;AAGA;;;;;;;;AAOA;AAAA;;;;;;;;;AAGA;AAAA;;AAAA;AAAA;;;;;;;;;;AAHA;;;;AAOA;;AAHA;AAAA;;AAGA;;;;;;;;;;;;;;;;AAmBA;AAAA;;;;;AAKA;;;;;;;AAIA;;AAZA;;;;AACA;AAAA;AAAA;;;AAEA;AAAA;AAAA;;;;AAKA;AAAA;;AAIA;;;;;;AAAA;;AATA;AAAA;;;;;AAKA;;AAIA;;AATA;AAAA;;;;AAKA;;;AAIA;;AAXA;AAAA;AAEA;AAAA;;;;AAKA;AAAA;;AAIA;;;;;AARA;;AAQA;;;;;;;;;;;AASA;;;AAkCA;;AAlCA;AAAA;;;AAkCA;;AAhCA;AAAA;AAAA;;;AAgCA;;AA7BA;AADA;;;;;;;;AAAA;AAAA;;;;AA5DA;AAAA;;;;AACA;AAAA;;;;AADA;AAAA;;;;;;;;;AAEA;;;;;;;;;;;;;;;AA2DA;AADA;;;;;;;;;;AAAA;AAAA;;;;AA5DA;AAAA;;;;;AACA;AAAA;;;;;AADA;AAAA;;;;;;;;;;;;AAEA;;;;;;;;;;;;;;;;;;;AAwEA;AAAA;;;;;;;;;;;AAGA;AAAA;AACA;;;;;;AAJA;;;;AAOA;AAAA;;;;;;AApBA;AADA;;;;;;;;;;AAIA;;AA0BA;;;AANA;;AAMA;;;;AAFA;;AAEA;;;;;;AAKA;;;;;;;;;;AAkBA;;;;;;AAmBA;;;;;AAEA;;;;;;;;;;;;;;;AA/JA;AAAA;;;;AAgKA;;;;;;;AAyJA;AAAA;;;AA+DA;;AA7DA;AAEA;AAAA;AAGA;;;;;;;;;;;;AAwDA;;;;AAZA;;AAYA;;;AAxXA;AAAA;AAgXA;;;AAQA;;AAtFA;AAAA;;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AAqEA;;AAOA;;;;AAjFA;;AA0EA;AACA;;AAMA;;;;;;;AAzGA;;AAYA;;AAVA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;;;;;;;AACA;AAAA;AAAA;AADA;AAAA;AAAA;;;;;;;;;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AACA;;;;;;AAwJA;;AAgDA;;AA9CA;;;AA0BA;AAAA;AAAA;;AACA;AACA;AAAA;AACA;;AAEA;AAAA;AAAA;;AACA;AACA;AAAA;AACA;;AAxTA;;;;;;;;;;;;;;;;;;;;;;;AA/JA;AAAA;AA+dA;;AACA;AAAA;AAAA;;;AACA;AACA;AACA;;;;;;;;AA4BA;AAAA;AAAA;;;AAgDA;;AA/CA;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;AAAA;;;AA+CA;;;;;;;;AAAA;;;AANA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;;;;AADA;;AAMA;;;;;;;;;AAKA;AAAA;AAAA;;;AAOA;;AAPA;AAAA;AAAA;;;AAOA;;;;;;;;;;;;;;;;;;;AA3jBA;AAAA;AAsjBA;;;;AACA;AAAA;AAAA;AAAA;AA/EA;AAAA;AAAA;;;;AAEA;;;AAiFA;;AA/EA;AAAA;AAAA;AAAA;AAAA;;;AA+EA;;AA7EA;AAAA;AAAA;AAAA;AACA;AAAA;AADA;AACA;;;;;;;AA4EA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA3DA;;;;;;;;;;;;;;;;;;;;;;AAAA;;;AA2DA;;;;;;;;AAAA;;;AAlBA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;;;;AADA;;AAkBA;;;;;;;AAgFA;AAAA;;;;;;;;;AAxEA;;;;;AApaA;;;;;;;;;;;;;;;;;AA/JA;AAAA;AAskBA;;;;AACA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;;;;;;;;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAxlBA;;;;;AAomBA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAmCA;AAAA;AAAA;;;;;AAEA;AAAA;;;;;AAEA;AADA;AACA;;;;;;;;;;;;;;;AAOA;;;;;;;AAcA;AAAA;;;AAOA;;AALA;AACA;;AACA;;;;;AACA;;AAEA;;;;;;;;AA0CA;AAAA;;;;;;;;;AA3BA;;AACA;;AACA;;AACA;;AACA;AAAA;;;AAkBA;;AAhBA;AAAA;;AAEA;;AAEA;;;AAEA;AAAA;AAAA;;;;AAIA;AAAA;;;;;;;;;AAIA;;AAEA;;;;;;;;;;AAsBA;;AACA;;AACA;;AACA;;AACA;AAAA;;;AA6CA;;AAxCA;AAAA;;;;;AAjDA;AAAA;;;AAyFA;;AAvFA;AAAA;;AAEA;AAIA;AAAA;;;;AAIA;AAAA;AAIA;;;;;;;AAAA;;AAyEA;;;AArBA;AAAA;;;;AAIA;AACA;;;AAIA;;;;;;AAIA;AAAA;;;;;;;;;AAGA;AACA;;;AAIA;;AAHA;AACA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwOA;AAAA;;;AAmCA;;;;;AA/BA;AACA;;;;AAAA;;;;AAGA;;;;;;;AAKA;AACA;AAAA;AADA;;;;;AAIA;AACA;AAAA;AADA;;;;;AAIA;AAAA;AAtMA;AAAA;AACA;AAAA;;;;AAEA;;;;;;;;AAGA;;;;;;AAQA;AADA;AAPA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AADA;AAEA;AAXA;;AANA;;;;;;;AAAA;;;;;;AAuBA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;;;;;;AAlBA;AANA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AARA;;;;;AAQA;AARA;AAUA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AADA;AAEA;AAXA;;;;;;AAAA;AAsBA;AAAA;AACA;AAAA;;;;;;AAsKA;AACA;AAAA;AAlHA;AAAA;;;;AAIA;AAKA;;;;;;;AAGA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;;AACA;AAAA;;AACA;AAZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;;AACA;AAAA;;AACA;AAZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;;AACA;AAAA;;AACA;AAZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;;AACA;AAAA;;AAjBA;AAAA;;;;;;;;;AATA;AAAA;;;;AAgCA;AAAA;AACA;AAAA;;;;;;;;;;;;;;;;;;AA/8BA;AAAA;;;;;;;;;;;;AAk9BA;AAAA;AAAA;AAAA;AAGA;;;;;;;;;;;;;;;;;;;AAr9BA;AAAA;;;AAs9BA;AAAA;;;;;AACA;;;;AAAA;;;AAGA;AAAA;AACA;;;;AAAA;;;AAIA;;AACA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;AACA;AACA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AACA;;;AAIA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAJA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AADA;;;;;;;AAAA;AAEA;AAAA;AACA;;;AAIA;AACA;AAAA;AAAA;;;;AACA;AAAA;;;AACA;AACA;AACA;AAAA;;;;;AACA;;;;;AACA;;;;;;;AAyCA;AAAA;AAAA;AACA;AAAA;;AAMA;;;;AAHA;AAAA;AAAA;AACA;AAAA;;AAEA;;;;;;;;;;;;AA3OA;AAAA;AAAA;AAAA;AAEA;;;AAUA;;AAVA;AAAA;;;AAUA;;AARA;AACA;AACA;;;AAMA;;;;;AAJA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;AAHA;AAAA;;;;;;;;AAMA;;;;;;;;AArCA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAGA;;;AAeA;;AAfA;AAAA;;;AAeA;;AAbA;AACA;AACA;;;AAWA;;AARA;AADA;AACA;;AACA;AACA;;AAMA;;AAFA;AAAA;AAAA;;AAEA;;;;;;;;;;;;;;;AAkSA;;;;;AAGA;AAEA;;;;;;;AA6BA;AACA;;;;;AAEA;AA/kCA;AAAA;;;;AACA;AAAA;;;;AADA;AAAA;;;;AAolCA;;;;;;AAllCA;;;;;;;;;;;;;;;;;;AAklCA;AACA;;;;;;;;;;;;AAzkCA;AAAA;;;;;;;;AAGA;AAAA;;AAAA;AAAA;;;;;;;;;;AAHA;;;AAIA;AAAA;AAkkCA;;;;;;;;;;AAEA;;;AAGA;AACA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;;;;;AAGA;AACA;;;AAOA;AAAA;;;AALA;;;;AACA;;;;;;;;;;;;;;AAKA;AAAA;;AACA;;;;AAGA;AACA;AA60BA;AAAA;;AA50BA;;;;AA80BA;AACA;AAh1BA;AACA;;;;;AAIA;AAAA;AAAA;;AACA;;;;;;AAIA;AAAA;AAAA;;AACA;;;;;;;;;AAGA;;;;;;;;;;;;;;;;;;AAppCA;AAAA;AAqpCA;;;;AAx/BA;;;AAEA;;;;;;;;;;;;;;AA/JA;AAAA;AAspCA;;AAIA;AAAA;AAAA;;;;AACA;;;;AACA;AAAA;AAAA;AACA;;;;;;;AANA;;;;;;;;AA2CA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;AAMA;AAGA;;;;;;;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+jBA;AAGA;AASA;;AACA;;AACA;AAAA;;;;;AAIA;AAAA;;AAKA;AAlxDA;AAAA;;;;;AACA;AAAA;;;;;AADA;AAAA;;;;;;;;;;AAEA;;;AAixDA;;;;;;;;;;;;;;;;;;;;;;AA5yDA;AAAA;AA4yDA;;;;;;;;;;;;;;;;;;;;AAyGA;AAAA;;;;;;;;;;;;;;;AAMA;AAAA;;;;;AAEA;AAAA;;;;;AAIA;AAAA;;;;;AAIA;AAAA;AAAA;AACA;;;;;AAGA;AAAA;;;;;;;;AA1wDA;;;;;;;;;;;;;;;;AA/JA;AAAA;AAo7DA;;AA5RA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;;AAIA;AAAA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;;;AAKA;AAAA;AAAA;AAAA;AAAA;;;;;AAOA;AAAA;AAAA;;;;AACA;AAGA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AACA;;;;;AAIA;AAAA;AAAA;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAtBA;AAAA;AAAA;;;;;;AAiBA;AACA;AAAA;AAAA;;;;;;;AAWA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAMA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;;;;;AAKA;AAAA;;;;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;;;;AAOA;AAAA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AAAA;AAAA;AA7mDA;AAAA;;;;;AAinDA;AAAA;AACA;AAAA;AAqRA;AAAA;AAAA;;;;;AAEA;;;;;;;;;;AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAjSA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;;;;AAyKA;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;;;;AAMA;;;;;;;;AAIA;AACA;AACA;AAAA;AAEA;AAAA;AAKA;;;;;;;;AASA;AAAA;;;AAKA;;AAHA;AACA;;AAEA;;;;;;;;;AAtqBA;AAKA;AAAA;;;AAeA;;AAtCA;AAAA;;;;;AAhEA;AAAA;;;;AArlBA;AAulBA;;AAEA;AAAA;;;;AAWA;AAvuCA;;;;;;;;;;;;;;;;;AApBA;;;AAmzCA;AAAA;AAAA;AAAA;AAMA;AAYA;;;;;AAEA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;;;;;AACA;AAAA;;;;;;;AA9EA;;;;;AAqFA;;AAEA;;;;;;;;;;;AAmNA;AAAA;AAAA;;AACA;AACA;;AAGA;AAAA;AAAA;;;AAyCA;;AAryCA;AAAA;;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AAqvCA;AAGA;AAAA;AAAA;AAAA;;;AAmCA;;AAlCA;AAAA;AAAA;AAAA;AAAA;;;AAkCA;;AAjCA;AAAA;AAAA;AAAA;AAAA;;;AAiCA;;AA9BA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;;;AA0BA;;;AAxBA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;;AACA;AACA;;;AAmBA;;;AAhBA;AAAA;AAAA;;;AAgBA;;AAdA;;;;;AACA;AAAA;AACA;;;AAYA;;AAVA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;;AAFA;AAAA;AAAA;;;;;;;;AAGA;AAAA;;AAOA;;;;AAFA;AAAA;;AAEA;;;;AAhyCA;;AA0vCA;;AAsCA;;;;;;;AAQA;AACA;;;;;;;AAmEA;;;AArBA;AAAA;;;AAqBA;;AAnBA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;;AAIA;AAAA;;;AAHA;;AAiBA;;;AAp/CA;;;;;;;;;;;;;;;;AA/JA;AAAA;AA2oDA;;AACA;AAAA;;AACA;;AAMA;;;;AAFA;;AAEA;;;;;;;;;;;;AA+VA;;AACA;;AACA;;AACA;;AACA;;;;;AAEA;;;;;;;;;;AAgBA;;;;AAIA;;;;;;;;;;;AAUA;AAAA;AAAA;;;;;AAEA;;;;;;;;;;AAgBA;;;;AAIA;;;;;;AAkGA;AAAA;;;AAsBA;;AAl4DA;AAAA;;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AAo3DA;AAAA;AAEA;;AAEA;;;;AA73DA;;AAy3DA;AAAA;;AAIA;;;;;;AAMA;;;;;;;;;;;;AAMA;;;AAhrEA;AAAA;AA0qEA;;;AAMA;;AAJA;AAAA;AAAA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;AAAA;;AAEA;;;;;;;;;;;AAoHA;AAEA;;AACA;;AAEA;;;;;;AAMA;;;;AACA;;;;AANA;;;;AACA;;;;;;AASA;;AAEA;;;;AAGA;AAAA;AAAA;AAAA;;AACA;;;;AAGA;AAAA;AAAA;;AACA;;;;AAGA;AAAA;AAAA;;AACA;;;;;AACA;;;;AAGA;;;;;;;;AAGA;AAAA;AAAA;AAAA;AADA;;;;;AAAA;;;;;;;AAOA;;;;;AAMA;;;;;;;;;;;;;;;;;AASA;AAAA;AACA;AAAA;AAAA;;;AACA;AAAA;;;AAyBA;AACA;;;;;;AArBA;AAAA;AAAA;AAAA;AAEA;AACA;;AAEA;;;;;;;AAEA;AAAA;AAAA;AAAA;AAEA;AACA;;AAGA;AAAA;;AACA;AAAA;;AAMA;AACA;;AANA;AAAA;;AACA;AAAA;;AAIA;AACA;;AAHA;AAAA;AAAA;AAAA;;AAEA;AACA;;;;;;;;;;AAl3EA;;;;;;;;;;;;;;;;;AApBA;;;AA64EA;AAAA;;;AAEA;;;AA8DA;AAAA;AAAA;AACA;;;;;AACA;AAAA;AAAA;AACA;;;;;;;;AAIA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AACA;;;;;AACA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;AAUA;;;;;;;;;;;;;;;;;;AAMA;AACA;AACA;AAAA;AAEA;AAAA;AAKA;;AACA;;AACA;AAAA;;;AAEA;AAp9EA;AAAA;;;;AACA;AAAA;;;;AADA;AAAA;;;;;;;;;AAEA;;;;AA0YA;AAEA;;;AA1CA;;;;;;AA6CA;;;;AAsqEA;AAIA;AAAA;;;;;AACA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAPA;;;;;;AA1mBA;AAAA;;;;;AAEA;AAAA;AACA;AAAA;AAunBA;;;;;AACA;AApuEA;;;;;;;;;;AAquEA;AAAA;;;;;AACA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;AAMA;AAdA;;AAmCA;AACA;AACA;;;;;;;;;AAGA;AAAA;AAMA;AAAA;AACA;AAAA;;AACA;AAAA;AACA;AAAA;;AAEA;AAAA;;AAIA;;AAHA;AAAA;AACA;AAAA;AAEA;;;;;;;;;;AA0hCA;;AACA;;AACA;;AACA;;;;AAgBA;;AAiBA;;;;AAdA;AAGA;AAAA;AAAA;AAAA;;AAWA;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAnvBA;AAAA;AAAA;AAKA;AAEA;AACA;AACA;AACA;AAGA;;AACA;;AACA;;AACA;;AAEA;AAAA;;;;;AACA;AAAA;;;;AACA;AAAA;;;;AAMA;AACA;AACA;;;;AACA;AAAA;;AAKA;AAGA;;;;AAJA;;;AAKA;;;;;;;AACA;AAAA;;;;;;;;;AAIA;AACA;AACA;AACA;AADA;;AAEA;AAAA;;;;;;;;AAVA;;;;;;;;;;AAYA;AAAA;;AAYA;AAAA;AAAA;;AAIA;AAAA;;;;AACA;AAAA;AAAA;;AAKA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;;AAGA;AAAA;AAAA;;;;;AAIA;;;;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;;;;;;AAKA;AAAA;AAAA;;AAIA;AAAA;AAAA;AAIA;AAAA;AAJA;;;;;;AAJA;AAAA;;;;;AAQA;AAAA;;;;;;AAOA;AACA;AAAA;;;;;AAAA;AAAA;;;;;AAMA;AACA;AACA;AACA;AAAA;AAAA;;;;;AAIA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;AACA;AADA;AACA;;;;;;AAOA;AAAA;AAAA;AAAA;;;;;AAMA;AAAA;;;;;AAEA;AADA;AACA;;;;;AAEA;AAAA;AAAA;AACA;AADA;;;;;;;;;;;;;;;AAOA;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;;;;;AAMA;AAAA;;;;;AACA;AAAA;;;;;AAEA;AAAA;AAAA;;;;;AAMA;AAAA;;;;;AACA;AAAA;;;;;;;;AAKA;AAAA;;;;AACA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;;;;;;;;;AAWA;AAAA;AACA;;;;;;AAGA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AACA;AAAA;AACA;AAAA;;AAEA;;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;;AARA;AAAA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;;;;;;;;AC1yGA;AAGA;AAAA;;;;AAEA;AAAA;AAAA;;AACA;;;;;;AAEA;;;;;;;;;AAKA;AAGA;AAAA;;;AAKA;;AAHA;;;AAGA;;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;AAKA;AAGA;AAAA;;;AAKA;;AAHA;;;AAGA;;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;;;;;;;AAkBA;AAGA;AAAA;;;;AAEA;;;;AACA;AAAA;;;;AAEA;;;;;;;;;AASA;;AACA;;AACA;;AACA;;AAgDA;AAMA;AAAA;;;AAvCA;;AA2CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AA5CA;;AAgDA;AAAA;AAAA;AAKA;;;AArDA;;AAmBA;AAAA;AAAA;;;AAnBA;;;AAXA;AAAA;AAAA;AAAA;;;AAWA;;AAPA;;AACA;;AACA;AAAA;;;;AAKA;;AAFA;;AAEA;;;;;;;;;AASA;;AACA;;AACA;;AACA;;AAqBA;AAMA;AAAA;;;AAbA;;AAiBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAlBA;;AAsBA;AAAA;AAAA;;;AAtBA;;;AA2BA;AAAA;AArCA;;;AAEA;;AACA;AAAA;AAAA;AAAA;;AAOA;;;;;;;;;;;AAwCA;;AACA;;AACA;;AACA;;AApCA;AAMA;AAAA;;;AAqDA;;AAjDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAgDA;;AA5CA;AAAA;AAAA;;;AA4CA;;AAvCA;AAoBA;;AACA;AAAA;;AAAA;AAAA;AAAA;;;AAkBA;;;;AA3DA;AAMA;AAAA;;;AAqDA;;AAjDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAgDA;;AA5CA;AAAA;AAAA;;;AA4CA;;AAzEA;AAAA;AAAA;;;AAyEA;;;AAXA;AAAA;AAAA;AAAA;;;AAWA;;;AANA;;AACA;AAAA;;;;AAKA;;AAFA;;AAEA;;;;;;;;;;AA4BA;AAAA;;;;AAEA;;;;AACA;AAAA;;;;AAEA;;;;;;;;;AAKA;AAAA;AAVA;AAAA;;;;AAEA;;;;AACA;AAAA;;;;AAOA;;;;;;;;;;;;;AASA;AAaA;AAAA;AACA;AAAA;;;AAXA;;AAeA;;;AAfA;;AAoBA;AAAA;AACA;AAAA;AAAA;;;AArBA;;AAuBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAXA;AAAA;;AAWA;AAAA;AAAA;;;AAvBA;;AA4BA;;AA5BA;;;;;;;;;AAsDA;AAAA;;;AAIA;;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;;AAoBA;AAAA;;;;AAEA;AAAA;;;AAEA;;;;;;;;;;;AAQA;;;AAUA;;AANA;AAAA;AAAA;;;AAMA;;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAGA;;AAFA;AAAA;AAAA;;AAEA;;;;;;;;;;AAKA;;;;AAAA;AAfA;;;AAeA;;;;;AAXA;AAAA;AAAA;;;AAWA;;AATA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAQA;;AAPA;AAAA;AAAA;;AAOA;;;;;;;;;;AAMA;AAAA;AArBA;;;AAqBA;;AAjBA;AAAA;AAAA;;;AAiBA;;AAfA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAcA;;AAbA;AAAA;AAAA;;AAaA;;;;;;;;AAWA;AAAA;AAAA;;;AAcA;;AAZA;AAzOA;AAMA;AAAA;;;AA+OA;;AA3OA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AA0OA;;AAtOA;AAAA;AAAA;;;AAsOA;;AAjOA;AAwNA;AAAA;;;AASA;;AAPA;AAAA;AAAA;;AACA;AAAA;;AAIA;;AAEA;;;;;;;AALA;;AAKA;;;;;;;;;;;;AASA;;;AAoBA;;AAfA;;;;;;;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;;AAMA;;;;AAAA;AACA;AAAA;AAAA;AAAA;;;AAQA;;AANA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AACA;;;AAGA;;AAFA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;;;AAlRA;AAMA;AAAA;;;AAgTA;;AA5SA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AA2SA;;AAvSA;AAAA;AAAA;;;AAuSA;;AAlSA;AAAA;AA4QA;;;;;AAAA;AAAA;;;AAsBA;;AAnBA;;;AAmBA;;AAlBA;;AAAA;;;;;AAkBA;;;;;;AAfA;AAAA;AAAA;;;;;AACA;AAAA;AACA;AAFA;;;;;;;;;;AAIA;;AACA;;AACA;;AACA;;AACA;AAAA;AAAA;AAAA;;AAOA;;;;;;ACjXA;AACA;AAIA;;AACA;;;AACA;AAAA;AAAA;AAAA;AACA;;;;AAAA;AAAA;;;;AAEA;AAAA;;AACA;AACA;;;;;;;;AAIA;;;;;;;AAKA;AAIA;;;AAiBA;;AAfA;AAAA;;;AAeA;;AAbA;AAAA;;AACA;AACA;;AAWA;;AARA;AAAA;AACA;AACA;AACA;;AAKA;;;;;;;;AAKA;AACA;AAGA;;;AAcA;;AAXA;;;;;AAAA;AAAA;;;;AACA;AAAA;AAAA;;AAEA;;;;;AAQA;;;;;AANA;AAAA;AAAA;;;AAMA;;AAJA;;AACA;;AACA;AAAA;;AAEA;;;;;;;;;AClEA;;AACA;;AAEA;AACA;;;AAuBA;;AApBA;AACA;AACA;AAAA;AAEA;AAAA;;;AAgBA;;AAZA;AAAA;AAAA;;AACA;AAAA;;;AAOA;;AAIA;;AAFA;;AAEA;;;;AAVA;AAAA;AACA;AACA;AAAA;;AAQA;;;;;;AAsDA;AAAA;;AAEA;;AADA;AACA;;;;;;;;;;;AA7CA;AACA;AAGA;AAAA;;;AACA;AACA;AADA;AACA;AAAA;;AAMA;AAAA;;AAIA;AACA;;;;AAIA;AACA;;;;;;AAEA;AAAA;AAEA;AAAA;;;;;AAEA;AAAA;AAEA;;;;;AARA;;;;;;;;;;;;;;;;;;;;AAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsMA;;;AAtEA;AAAA;;;AAsEA;;AApEA;AAAA;;;AAGA;AAAA;;AAIA;AAAA;;AAEA;;;;;;;;;;AAAA;AAGA;;AAMA;AAAA;;AAEA;AAAA;;;;AAIA;;;;AAMA;AAAA;;AAkCA;;AAIA;;AArCA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;;;;;;;;;;AAeA;AAAA;AAAA;AAlGA;AAIA;AAAA;;AACA;AAAA;;AAEA;AAAA;AAAA;AAAA;;;;;;;;;;;;;AAQA;AAAA;;;;;;;;;;;;;AAsFA;AAAA;AAAA;AAdA;;;;;;;;AAWA;AAzFA;;;;;AACA;AAAA;AACA;;;AAIA;;AA6FA;AArBA;AAAA;;;;;;;;AA4BA;;;;;;AAPA;AArBA;;;;;;;;;;AAuBA;AACA;;;;;;;AAIA;;;AAaA;AAAA;;;;;;AACA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;AAJA;AAAA;AAAA;;;;;;;;AAMA;;AAfA;;;;;;;;;;;;;;;;;;;AAJA;;AAIA;;;;;;AAOA;;AASA;;AAPA;AAAA;;;;;;AACA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;AAJA;AAAA;AAAA;;;;;;;;AAMA;AACA;;;;;;;;;;;;;;;;;;;;AAsEA;AACA;AAAA;AAIA;AACA;AAEA;;;AAoCA;;AAlCA;AAEA;AAAA;;;AAgCA;;AA9BA;AAAA;;;AA9BA;;;;AAAA;AAAA;;AACA;AAAA;;;;AAEA;AAAA;;;;;;;;;;;;;;AA6BA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;;AAEA;AAAA;;AAEA;AAAA;;AAEA;;;;;;;;;;;;;;;AAOA;AAAA;;AAEA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;AAAA;;AACA;AAAA;AACA;AAAA;;AAEA;;AAEA;;;;;;;;;;;;;AAgEA;AAAA;AAGA;AAAA;;;AA8CA;;AA3CA;;;;AAqBA;AAAA;AAGA;AAAA;;AAhEA;AAAA;;AACA;AAgEA;;;AAtDA;;AACA;AAAA;;;;;AACA;AAAA;;;;;;AAGA;;AACA;AAAA;;;;;;;AA0DA;AAAA;;AAEA;AAAA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;;AAEA;;;;;;;;;;;ACrfA;AAAA;;;AA2CA;;AAzCA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;AAwCA;;;AAjCA;AAAA;;;;;AAAA;AAAA;;;;;;;;AACA;;;AAGA;AAAA;;;AA6BA;;AA5BA;;AAAA;AAAA;;;AA4BA;;;;AAzBA;AAAA;;;;;AAMA;AAAA;;;;;AAEA;AAAA;;;;;;;;AAPA;AAAA;AAAA;;;AAaA;AAAA;;;;;;AAOA;;AAIA;;;;;;AAJA;AAEA;;AAEA;;;;;;;;;;;;;;;;AAsCA;AAAA;;;AAqBA;;AAXA;AAAA;AAAA;AAAA;;;AAWA;;AAXA;AAAA;AAAA;AAAA;;;AAWA;;AAVA;AACA;AACA;AAEA;AADA;AAAA;AAAA;AAAA;AAEA;AACA;;AAIA;;;;;;;;;;;;AAIA;AAKA;;AACA;;AACA;;AACA;;AAEA;AAAA;;AACA;;;AAiBA;;AAhBA;;AAgBA;;AAbA;AAAA;;;;AAOA;;;AAgBA;;AACA;AAAA;;;;AAIA;AAAA;;AACA;;;;;;AAOA;;;;AAlCA;;;;;;AASA;;AAEA;;;;;;;;;;;;AAqHA;;AACA;;AACA;;AACA;;AAIA;AAAA;;;;;AAeA;AAIA;AAAA;;;;AAEA;AAAA;;AAKA;;;;;AAHA;;;;;;;;;;AAmBA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;;AACA;AAAA;;;;;;AAEA;;;;;;;;;;;;AAGA;;;;;AAGA;;;;;;;;;;;;;AA/GA;AAGA;;AACA;;AACA;AAAA;;;AAkCA;;AAhCA;AACA;;;;AACA;AACA;AAAA;;;;;;;AAOA;AAAA;;;;AACA;AAAA;;;;;;;;;;;;;;;;;;;AAGA;AAAA;;;;AAGA;AAAA;;;;;;;AAjBA;AACA;;;;;AAiBA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;;;AAGA;;AAOA;;;AAFA;;AAEA;;;;;;;;;;AA+EA;AAGA;;AACA;;AAEA;AAAA;AAAA;;;AAkBA;;AAfA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;;;;AAIA;;;;AAKA;AAAA;AACA;;AAEA;;;;;;;;;;;;;;;AAOA;AAGA;;AACA;;;;;;;;AAsCA;;;AAvBA;AACA;;;AAnDA;AAMA;AAAA;AAAA;;;;;AAGA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;;;AASA;AAAA;AACA;AA8BA;;AAIA;AAAA;AAAA;;;;AAKA;AAAA;AAAA;;AACA;AAAA;AADA;AAAA;AAAA;;;;AAKA;AAAA;AACA;;;;;;;;;;;;;;AAGA;AAAA;AACA;;AAEA;;;;;;;;;;;;;;;AAiBA;AAIA;AAAA;AAEA;AAAA;;;AAuCA;;AAZA;AAxBA;AACA;;;;;;;;;;AAIA;AAAA;;;;;;;;;AAAA;;;AAAA;;;;;;AAWA;AAAA;;;;;AAIA;AAAA;;;;;AAEA;AAAA;;;;;AAMA;;;AA5BA;AACA;;;;;;;;;;AAIA;AAAA;;;;;;;;;AAAA;;;AAAA;;;;;;AAWA;AAAA;;;;;AAIA;AAAA;;;;;AAEA;AAAA;;;;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;AAIA;;;AA5BA;AACA;;;;;;;;AAgCA;AACA;;AAEA;;;;;;;AAcA;AAEA;;;AAOA;;;;;;;;;;;;;;;;;;;;;AAWA;;;;;;;;AC9hBA;AAIA;AAAA;;;AAKA;;AAJA;AAAA;AAAA;AAAA;AAAA;;AAIA;;;;;;;;;;AALA;AAAA;;AAeA;AAAA;;AAdA;AAAA;AAAA;AAAA;AAAA;AAYA;AAAA;AAAA;;;;;;;;;;AAsCA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;AAmBA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAMA;;AAHA;;AACA;AAAA;;AACA;;AACA;;;;;;;;;;;;AAPA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAcA;AAAA;AAAA;;AAXA;;AACA;AAAA;;AACA;AAQA;;AACA;AAAA;AAAA;;AACA;;;;;;;;;;;;;AAoCA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAMA;;AAHA;;AACA;AAAA;;AACA;;AACA;;;;;;;;;;;;AAPA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAcA;AAAA;AAAA;;AAXA;;AACA;AAAA;;AACA;AAQA;;AACA;AAAA;AAAA;;AACA;;;;;;;;;;;AAIA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAIA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AA0BA;AAIA;AAAA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AC1NA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AASA;AAAA;;AAEA;AAAA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAKA;AAEA;;;;AAOA;;;;;AAAA;;;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;AAgBA;AAAA;AARA;AAAA;;AAYA;;AAXA;AAAA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;;;;;;;;;AAgBA;AAAA;AAVA;;;AAcA;;;;AADA;AAAA;AAAA;;;;AAPA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AC6BA;AAAA;;AAEA;;;;;AACA;;;;;;;;;;;;;;;;AA7CA;AACA;AAEA;;AAIA;AAAA;;;AA4BA;;;AA/BA;AAAA;;;AA+BA;;;AAvBA;;;AACA;AA1CA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAGA;AAEA;AAAA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AACA;;;;;;;;;;;;;AA8CA;AAAA;;AAKA;;;;;AAAA;;;AAdA;AAAA;AACA;;AAKA;;AAQA;;AAXA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAYA;;;;;;;;AAiBA;AAAA;;AAEA;;;;;AACA;;;;;;;;;AAQA;AAAA;;;AAYA;;AARA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;;AAIA;;;;;;AA8CA;AAAA;;;;;;;;;;;;;;;AAjCA;AACA;AACA;;AAMA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAmBA;;;AAzBA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAwBA;;;AAbA;;;AACA;;;;;;;;;;;AAYA;;;AALA;AACA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;;AAEA;;AACA;;;;;;AAWA;AAAA;;;;;;;ACNA;AAAA;AAIA;AAAA;AAAA;AAAA;;AACA;AAAA;;AASA;;AANA;AAAA;AAAA;AACA;;;AAKA;;AAJA;AAAA;;AAIA;;;;;;;AAqBA;AAAA;AAAA;AA/BA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAoDA;;AAjDA;AAAA;AAAA;AACA;;AACA;AAAA;;AA+CA;;AAfA;;;;AAeA;;;;;;AAFA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;;;;;;;;;;;;AAmDA;AAAA;AAAA;AAQA;AAAA;;AACA;AACA;AAAA;AACA;AAAA;;;;;AAAA;AACA;;;;;;;;;;;;;;AAIA;AAAA;AAAA;;;;;AADA;AAAA;;;;;;;;;AAMA;;;;;;;;AAGA;;AACA;AAAA;AAAA;;;;;;;;AAEA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;AAGA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAEA;AAIA;AANA;AAEA;AAIA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;AAvHA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAEA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAEA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAOA;;AAQA;;;AANA;;;AAEA;;;AAIA;;AAFA;AAEA;;;;;;;AA0GA;AAEA;;;AAMA;;AALA;AACA;AACA;AAAA;;;AAGA;;AAtBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;AAEA;;;;;;;;;;;;;;;;;;;AAeA;AAAA;AAAA;AAOA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;AACA;AAGA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;AACA;AACA;AACA;AAAA;AACA;AAAA;;;;;;;;;;;;AAXA;AAAA;;;;;;;;;AAeA;AAAA;AACA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AACA;AAAA;AADA;;;;;AAEA;AAAA;AAAA;;AAIA;AACA;AAAA;AACA;AAAA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAwhGA;;;AACA;AAAA;AAAA;AAGA;;;AACA;AAAA;;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;AAGA;;;;AAjiGA;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;;;;;;AAvBA;AAAA;;;;;;;;AA2BA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;;AACA;AAlFA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;;AAUA;AAhBA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;AAWA;AAjBA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;AAYA;AAlBA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;AA8EA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AALA;AAAA;;;;;;;;AAOA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;;AAJA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AACA;AACA;;AAHA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;;;;;;;;;;;;;AA+LA;AACA;AACA;AAAA;AACA;AAAA;;AAwCA;AACA;AAAA;AACA;AACA;;;;;AA1CA;AAAA;AAAA;AACA;;;;;AAEA;;;;;;;;;;;;;;;AAwBA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AANA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;;;;;AAjCA;AAAA;;;;;;;;;AAoCA;AAAA;AAAA;;;AAIA;AACA;AAAA;AACA;AACA;;;;;;;AAtOA;AAAA;;AAGA;;;;;AAFA;AAAA;AAAA;AAAA;;;;AACA;;;;AAFA;AAAA;;;;;;;AAGA;;;;;;;AAyBA;AAAA;;AAgBA;;;;;AAfA;AAAA;AAAA;AACA;;;;;AACA;;;;;;;;;;AAOA;AArJA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;AAgJA;;;;;AAXA;AAAA;;;;;;;AAgBA;;;;;;;AASA;AAGA;AAAA;;;AAoBA;;;;;AAnBA;AAAA;AAAA;AACA;;;;AAAA;AAAA;;AASA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAXA;AAAA;;;;;;;;;;AAoBA;;AAPA;AAAA;AAAA;AACA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAQA;;;;;;;AAMA;AAAA;AAAA;AAGA;AAAA;;;;;;;;;;;;AACA;AAAA;AACA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;AAJA;AAAA;;;;;;;;;AAoBA;AAAA;;;AAcA;AAAA;AAAA;;;;;AAjCA;AAAA;AACA;;AAEA;;;;;;;;;;;;;;;;;;;;AAJA;AAAA;;;;;;;;AAkCA;AAAA;AAAA;;;AAJA;AAAA;;AACA;AAAA;;;;;;AAQA;;;;;;;;AA8GA;AAAA;AAAA;AAAA;AAAA;AApiBA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAgCA;;;;;;AAaA;AAAA;AAAA;AAAA;;;;AAyfA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;;AAljBA;AAAA;;;AAwiBA;AAAA;AAUA;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAtjBA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAgCA;;;;;;AAaA;AAAA;AAAA;AAAA;;;;AA2gBA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;AAlkBA;AAAA;;;AA0jBA;AAAA;AAQA;;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAtkBA;AAAA;AAAA;AAAA;;AACA;AAAA;AA4kBA;AAAA;AAAA;;AAzkBA;AAAA;AAAA;AACA;;AACA;AAAA;AAukBA;AAAA;AAAA;;AAviBA;;;AAyiBA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;AAjiBA;AAAA;AAAA;AAAA;AA0hBA;AAAA;AAAA;;;;;;;;;AAUA;AAAA;AAAA;AAAA;AAvlBA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAgCA;;;;;;AAaA;AAAA;AAAA;AAAA;;;;AA4iBA;AAAA;AACA;AAAA;AACA;;AAhmBA;AAAA;;;AA2lBA;AAAA;AAKA;;;;;;;;;AAGA;AAAA;AAAA;AApmBA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAsmBA;AAAA;AACA;AAAA;AACA;;AA7mBA;AAAA;;;AAwmBA;AAAA;AAKA;;;;;;;AAGA;AAAA;AAAA;AAjnBA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAmnBA;AAAA;AACA;AAAA;AACA;;AA1nBA;AAAA;;;AAqnBA;AAAA;AAKA;;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AA9nBA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAgCA;;;;;;AAaA;AAAA;AAAA;AAAA;;;;AAolBA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;AA1oBA;AAAA;;;AAmoBA;AAAA;AAOA;;;;;;;;;;;AA8eA;AAAA;AAAA;AAMA;AADA;AAAA;AAAA;AAAA;AAGA;AAIA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAxkCA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAEA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;;AAUA;;;AAgjCA;AAEA;;AAhjCA;AA8iCA;AAEA;;;;;;;;;;;;;;AAoHA;AAAA;AAAA;AACA;AAAA;;;;AAAA;;;;AACA;AACA;AAAA;AAEA;;AAEA;AACA;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;;;AA+BA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AACA;AAAA;AAEA;AACA;AACA;;AAzCA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;;AAEA;AAAA;AAAA;;;AACA;AAAA;;;AAEA;;AAIA;AAAA;;;;AAEA;AAAA;;;AAEA;;AAGA;AACA;AAAA;;AAEA;AAAA;AAWA;AACA;AACA;;;;;;AAkBA;AACA;;;;;;;;;;;;AA6rBA;AAAA;AAAA;AAAA;AAEA;AAAA;AAIA;AAGA;AAAA;;;;AAAA;AAAA;;;;;;;;AACA;AAAA;AACA;AAAA;AAAA;AACA;;;AAEA;AACA;AAAA;AACA;AAAA;AAEA;;AAGA;;AAFA;AAAA;AAAA;AAEA;;;;;;;;;;;;;;;;AAlFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAAA;;AA1CA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AADA;AACA;AAEA;AAAA;;;AAEA;AAAA;;AA3BA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AA7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AA8FA;;AAEA;AACA;;AACA;;AACA;AAAA;;;;;;;;;AACA;AAAA;AAAA;AACA;;;AAEA;AAAA;AAAA;;AAMA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;;AACA;;;;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AADA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AADA;;;;;AACA;;;;AA1DA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;;;;AAEA;AAAA;AAAA;;AAEA;AAAA;;AAEA;AAAA;AAAA;AAAA;AACA;;;;;AAmBA;AAAA;;;;;;;;AAuBA;AAAA;;;;AAtBA;AAAA;AAAA;AACA;;;AAEA;AAAA;AAAA;;AAEA;;AAIA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;;AACA;;;;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AADA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AADA;;;;;AACA;;;;AA1DA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;;;;AAEA;AAAA;AAAA;;AAEA;AAAA;;AAEA;AAAA;AAAA;AAAA;AACA;;;;AAmBA;AAAA;;;;;;;;AAuBA;AAAA;;;;;AAWA;;AAHA;AAAA;;AAGA;;AAFA;AAAA;AAAA;AAAA;AAEA;;;;;;;;;;;;;;AAj0CA;AAEA;AAAA;;AAAA;AAAA;;;AAAA;AAAA;;;AAEA;AAAA;AAAA;AACA;AADA;;AAEA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AACA;AAAA;;AACA;AAAA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;;;;;;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAGA;;;;AAIA;AAAA;;AAYA;;AAZA;AAAA;AAAA;;AAYA;;AAXA;AAAA;;AAAA;AAAA;;AAWA;;;AAVA;AAAA;AAAA;;;AACA;AAAA;AAAA;;;AAEA;;;;AAOA;;AARA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;;;;AAPA;AAAA;AAAA;AAAA;;AAOA;;AANA;AAAA;;AAMA;;AAJA;AAAA;AAAA;AAAA;AAAA;;AAIA;;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;;;;;;;;;;AA8HA;AAAA;AAAA;AAEA;AAAA;;;AAKA;AACA;AAeA;;;;AAbA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAAA;;AAGA;;AAFA;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;;;AAAA;;;;;;;;;;AA5MA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;AAIA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAieA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA;;AAvBA;AACA;;;AAlQA;AAAA;AAAA;AAEA;AAEA;;;;;AAEA;AAIA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAKA;;;;AACA;AAAA;AAAA;;AACA;AACA;;;;;;;;;AAGA;AANA;;;;;AAAA;;;;;;;;;AASA;AADA;AAAA;;;;;AAKA;;;;;;AAEA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAAA;;AAEA;AADA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAEA;AAAA;AAAA;AACA;AACA;;;AACA;AAAA;AACA;AAAA;;AAEA;AACA;AACA;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;;AAEA;AADA;AAAA;AAAA;AAAA;;;;AAIA;AAAA;AACA;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;AAKA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;;;AATA;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;AAoCA;AAAA;AAAA;AACA;AACA;AAAA;;;AAEA;AACA;AAAA;AAAA;AAAA;;AAEA;;;;;AAEA;AAAA;AAAA;AACA;AAAA;;;;;AAGA;;;;;AACA;AAAA;AAAA;AADA;;;;AAAA;;;;;;;AAWA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;;;;AARA;AADA;AAAA;;;;AAYA;AAAA;AAAA;AACA;;;;AAEA;AAAA;AAAA;AACA;;AADA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AADA;;;;;;;;AAWA;AAAA;AAAA;;;;;;;;;AANA;AAcA;AAAA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AAAA;AAEA;;;;;AAEA;;AAEA;;AACA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AACA;;AAEA;;AAEA;AADA;AAAA;AAAA;AAAA;;;;;;;AAMA;AAAA;;;;;;;;AAEA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AAAA;AACA;;;;;AA1DA;AAAA;AAAA;;;;;;;;;;;;;;;AAoHA;;AAEA;;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;;AAHA;AACA;AAEA;;;;AAVA;AAUA;;;;;;;;;AA1TA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AACA;;;;;AAAA;;AAEA;AAAA;AACA;AAEA;;AAEA;AAAA;AAAA;;AAOA;;AALA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;;AAHA;AAAA;;AAGA;;AAFA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4mBA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAAA;AACA;AAAA;AACA;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;;;;;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAGA;;AAoBA;AAAA;AAAA;;AACA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AACA;;;AAEA;AAAA;AAAA;;;AAGA;;;AAFA;;;;;;AApBA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AACA;;;AAEA;AAAA;;AAKA;;;AAJA;AAAA;AACA;AACA;AAAA;AAAA;;;;;AAyBA;AAKA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AACA;AAAA;AAAA;;;AASA;AAAA;AAAA;;AAGA;AAAA;AACA;AAAA;;;;AAHA;AAAA;;;;;AATA;AAAA;;AAeA;;;;AAdA;AAAA;AAAA;AAAA;AACA;AAAA;;AAGA;;;AAFA;;;;;AAYA;AAAA;;;AAEA;;;AAqBA;;AACA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;AAEA;;AAeA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAtEA;AAAA;;AAsEA;AAAA;AACA;AAAA;;;;;;;;;AAIA;;;;AA5BA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;;;AAEA;AAAA;;AAKA;;;AAJA;AACA;AAAA;AAAA;AAAA;AACA;;;;AA/BA;AAAA;AACA;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;;AAEA;;;;;AACA;AAAA;;AAGA;;;AAFA;;;;;AAiDA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAmFA;AAAA;;AAIA;;AA5EA;AAAA;AAAA;;;AACA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;AAgBA;;;;;;;;AAfA;AACA;AADA;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;;AAEA;;AAKA;AACA;AAAA;AAAA;AAAA;;;;AAJA;AAAA;AADA;AAAA;AAAA;AAAA;AA38CA;AAEA;;;;AACA;AACA;AACA;AAAA;;;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;;;;AA68CA;;AAEA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AACA;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;AAAA;AAAA;;;;;AAEA;;AAKA;AAAA;;AAEA;AADA;AAAA;;;AAGA;AAAA;;;;;;AAPA;AAAA;AADA;AAAA;AAAA;AAAA;AA79CA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;;;;AAy+CA;AAAA;;AA4BA;;AA3BA;AAAA;AAAA;AAAA;;AA2BA;;AA1BA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AADA;AAEA;AAAA;AADA;;AAyBA;;AAvBA;AAAA;AAAA;;AAuBA;;AAtBA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AACA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AACA;AAcA;;;;;;;;;;;;;;;;AApXA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA4CA;;AAzCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;;;;;;;;;;;;AAMA;;;;;;;;;;;;;;;;;;;;AAWA;AACA;AAAA;AACA;;AAQA;AAAA;;AACA;;AAEA;AAAA;AAAA;AAAA;AADA;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;AAAA;;AAEA;;AAGA;;AAFA;AAEA;;AAnBA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAgBA;;;AAfA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAlBA;AAAA;;AAkBA;AAAA;AAeA;;;;;;;;;;;;;;;;;;;;;;AAvMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAoDA;;AAnDA;AACA;AACA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AACA;AAlgCA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;AA8/BA;AACA;AAAA;;AAEA;;AAQA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAFA;AAGA;AAAA;;;AAeA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;AAEA;AAAA;;AACA;AAAA;;AAnBA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;AAAA;;AAGA;AAAA;;AAFA;;AAIA;AAAA;;AASA;AAEA;;AAxCA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAqCA;;;AApCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAoCA;;;;;;;;;;;;;;AAkKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA0BA;;AAzBA;AACA;AACA;;AASA;AAAA;AAAA;AAAA;AAFA;AAIA;AAAA;;;AAOA;AACA;AAAA;AAAA;AAAA;;AAPA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;AAKA;AAAA;AAEA;;AArBA;AAAA;AAAA;AADA;AAAA;AAEA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAoBA;;;AAnBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAmBA;;;;;;;;;;;;;;;;;;;;AAMA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAmDA;;AAlDA;AAAA;;AACA;AAAA;AAAA;AACA;;AAEA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoyEA;AAAA;AACA;AAAA;AAAA;;;AACA;AAAA;AAAA;;AACA;;;AAEA;;;;;AAEA;AAxyEA;AACA;AAAA;;;AAOA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;AARA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;;AAQA;AADA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AA9xCA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AA+xCA;AAuBA;;AAlBA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AA0wEA;AAAA;AACA;AAAA;AAAA;;;AACA;AAAA;AAAA;;AACA;;;AAEA;;;;;AAEA;AA9wEA;AAAA;;;AASA;AACA;AAAA;AAAA;AAAA;;AATA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AAMA;;;AAEA;AAAA;AAEA;;;;;;;;;;;;;;;;;;;;;AAuTA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAwCA;;AArCA;AAKA;AACA;AACA;AAAA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AA2BA;;;AA1BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAHA;AAAA;;AAGA;AAAA;AA0BA;;AAtBA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;AAmBA;;AAhBA;AAAA;;AAAA;AAAA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAEA;AAaA;;;AATA;AAAA;AACA;AAAA;AAFA;AAGA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;AAlGA;AAAA;AAAA;AAKA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAMA;AAAA;;AA+BA;;AA7BA;AAAA;AAAA;AAEA;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAwBA;;AArBA;AAAA;AAAA;;AAqBA;;AAnBA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;AAiBA;;;;;;AAZA;AAAA;AAAA;;AAYA;;AAZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAYA;;AAXA;AAAA;AAAA;;AAWA;;AAVA;AAAA;AACA;AADA;AAEA;;AAAA;AAAA;AAAA;;AAQA;;AARA;AAAA;AAAA;;AAQA;;;AANA;;AAIA;AAEA;;;AALA;AAKA;;;;;;;;;AAlmCA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;AAyIA;AAEA;AAAA;;;AAIA;AAnJA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAkKA;;AAjKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiKA;;;;AAVA;AACA;AAAA;AACA;AACA;AA9oBA;AAEA;;AACA;AACA;AACA;AAAA;;AAnBA;AAAA;;;;;;;AACA;AAAA;AACA;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AALA;AAAA;;;;;;;;;AAoBA;;;AAyoBA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;;;;AAAA;;;;;;;;;;;AAvHA;AAEA;AAAA;AAAA;;AAOA;;AANA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAEA;;;;;;;;AAMA;AAAA;AAAA;;AACA;AAGA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;AA+lCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAQA;;AARA;AAAA;AAAA;;AAQA;;AAPA;AAAA;AACA;AADA;AAEA;;AACA;AAIA;;AAFA;AAEA;;;;;;;;;;;AA3lCA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;;AAAA;AAAA;AAAA;;AACA;;AAuDA;;;AAjDA;AAAA;;;AAiDA;;AA7CA;AACA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AALA;AAOA;AAAA;;AAqCA;;;AA/BA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;;;AA+BA;;AA1BA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAKA;AAAA;;AACA;AACA;AADA;AACA;;AAKA;AAAA;AAAA;;AAWA;AADA;;AAGA;;AAZA;AAAA;AAAA;AAAA;;AAYA;;;;AAjBA;;AAiBA;;;AAxBA;;AAwBA;;;;;;;;;;;AAy5BA;AAAA;AAAA;;;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;AACA;;AAUA;;AATA;;AAMA;;;;;AAJA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;AAMA;;;AADA;;AACA;;;;;;;;;;;;;;;;;;;AAw8DA;AAAA;AAAA;;;AAgDA;;;;AA/CA;AAAA;;;AAGA;AAAA;AACA;AACA;AAAA;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAEA;;;;AACA;;;;;;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AADA;AACA;;AACA;AAAA;AAAA;AAAA;AACA;;AAAA;;AAAA;AAAA;;;AAEA;AAAA;;;;AAGA;AAAA;;;;;AAEA;AAAA;AAAA;AACA;AAAA;AADA;AACA;;;;;AAAA;AAAA;AAAA;;;;;AAEA;AACA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AACA;AACA;AAAA;;;AArCA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AA6BA;AAAA;AAAA;AAAA;AAAA;;;AAWA;AAAA;AAAA;AAAA;;AACA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;;AAIA;;;AAAA;;;;;;;;;AAvrDA;AACA;;;;;;;;;;;;;;;;;;;;;AAUA;AAAA;;AAqHA;;;;AApHA;AAAA;AAAA;AACA;;;AAOA;AAAA;;;;;;;;AACA;AACA;AADA;;;;;AAOA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;;;;AAKA;AAAA;AAAA;;;AAEA;AAAA;AAAA;;AAqDA;AAAA;;;;AACA;AAAA;;;;;AAOA;AAAA;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AAAA;AAAA;;;;;;;;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;;;AAhEA;AAAA;AAAA;;AAKA;AAEA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;AAOA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;;;;;AATA;AAAA;AAFA;AAAA;AAGA;;;;AAgBA;AAAA;;;AAMA;AAAA;AAAA;;AACA;AAAA;;;;AAIA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;;;AAXA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;;;;;;;AAYA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;;;AAiBA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AACA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAlHA;AAAA;AAAA;;;;;;;;;AAkFA;AAAA;;;AAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA;AAGA;AAAA;AAOA;AAAA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAwIA;;AArIA;AAAA;;AACA;AAAA;;AAoIA;;AAjIA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;AACA;AAAA;;AAEA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAKA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAIA;AAAA;;AACA;AAAA;;AAKA;AADA;AAEA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;AAXA;AAAA;AAAA;AAAA;AAAA;;;;;AALA;AAAA;;;;;AAyBA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAIA;AAAA;;AACA;AAAA;;AAIA;AAEA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;AAZA;AAAA;AAAA;AAAA;AAAA;;;;;AALA;AAAA;;;;;AAsBA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;;AACA;AAAA;;AAIA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAnGA;AAAA;;AAkGA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AApGA;AAAA;;AAoGA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;;;;;;;;;;;;;;AAjBA;AAAA;AAAA;AAAA;AAAA;;;;;AAoBA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA/zEA;AAAA;;;;;;;;AACA;AAAA;AACA;;AAAA;AAAA;AAAA;;;;;AAFA;AAAA;;;;;;;;;AAi0EA;AAAA;AAAA;AAAA;;AAGA;AAAA;;;;;AAFA;;;;;;;;;;;;;;;;;AAOA;;;AACA;AAAA;;AACA;AAAA;;;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAHA;;;AAQA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;;AAEA;;;;;;;;;;;;;;;;;;;AAWA;AAaA;;;AA6DA;;AA7DA;AAAA;;;AA6DA;;AA3DA;AAAA;AAAA;;;AA2DA;;AAzDA;AAAA;;AAcA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA4CA;;AAxCA;AAAA;;;AACA;AAAA;;;AAIA;AACA;;AACA;AAAA;;;;AAIA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAKA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;AALA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAYA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAGA;AAAA;AAAA;AAAA;;AAGA;AAAA;;;AAFA;;;;;;;;;AAKA;;AAEA;;;;;;;;;;;;;;;;;;;;;AAcA;AAn9EA;AAAA;AAAA;AAAA;;AACA;AAAA;AAq9EA;AAAA;AAAA;;AAl9EA;AAAA;AAAA;AACA;;AACA;AAAA;AAg9EA;AAAA;AAAA;;AAh7EA;;;;;;AAaA;AAAA;AAAA;AAAA;AAm6EA;AAAA;AAAA;;;AACA;AAAA;;AA+CA;;AA3CA;;;;;;AA2CA;;;AAtCA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AADA;AAUA;AAAA;AAQA;AAAA;;AARA;AAAA;AAAA;;;AA0BA;;AAxBA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAuBA;;;;;AAjBA;AAAA;AAAA;;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;;AAKA;AAAA;;;;;;AAHA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;;;;;AANA;;;AAGA;;AAFA;;AAGA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA;AAlhFA;AAAA;AAAA;AAAA;;AACA;AAAA;AAqhFA;AAAA;AAAA;;AAlhFA;AAAA;AAAA;AACA;;AACA;AAAA;AAghFA;AAAA;AAAA;;AAh/EA;;;;;;AAaA;AAAA;AAAA;AAAA;AAm+EA;AAAA;AAAA;;;AACA;AAAA;;AAiCA;;AA/BA;AAAA;;AACA;AAAA;AA8BA;;AA3BA;AAAA;AAAA;AAAA;;;AACA;AAAA;AAAA;;AAGA;AAAA;AAAA;;AAFA;AAAA;;;;;AAKA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;AACA;AADA;;AAKA;AAAA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAQA;;AALA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAEA;;;;AAhBA;AAAA;AAAA;AAAA;AAgBA;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAlkFA;AAAA;AAAA;AAAA;;AACA;AAAA;AAokFA;AAAA;AAAA;;AAjkFA;AAAA;AAAA;AACA;;AACA;AAAA;AA+jFA;AAAA;AAAA;;AA/hFA;;;;;;AAaA;AAAA;AAAA;AAAA;AAkhFA;AAAA;AAAA;;;AACA;AAAA;;AAYA;;AAVA;AAGA;AAAA;AAAA;;AAOA;;AAPA;AAAA;AAAA;;AAOA;;AANA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;AAIA;;AAHA;AAGA;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA5lFA;AAAA;AAAA;AAAA;;AACA;AAAA;AA8lFA;AAAA;AAAA;;AA3lFA;AAAA;AAAA;AACA;;AACA;AAAA;AAylFA;AAAA;AAAA;;AAzjFA;;;;;;AAaA;AAAA;AAAA;AAAA;AA4iFA;AAAA;AAAA;;;AACA;AAAA;;AA0BA;;AApBA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AASA;AAAA;;AASA;;AAJA;AAAA;AACA;AAGA;;;;;;;;;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAjoFA;AAAA;AAAA;AAAA;;AACA;AAAA;AAooFA;AAAA;AAAA;;AAjoFA;AAAA;AAAA;AACA;;AACA;AAAA;AA+nFA;AAAA;AAAA;;AA/lFA;;;;;;AAaA;AAAA;AAAA;AAAA;AAklFA;AAAA;AAAA;;;AACA;AAAA;;AAKA;;AAHA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAEA;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAjpFA;AAAA;AAAA;AAAA;;AACA;AAAA;AAopFA;AAAA;AAAA;;AAjpFA;AAAA;AAAA;AACA;;AACA;AAAA;AA+oFA;AAAA;AAAA;;AA/mFA;;;;;;AAaA;AAAA;AAAA;AAAA;AAkmFA;AAAA;AAAA;;;AAEA;AAAA;;AAQA;;AANA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAEA;AAEA;;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AAxqFA;AAAA;AAAA;AAAA;;AACA;AAAA;AA2qFA;AAAA;AAAA;;AAxqFA;AAAA;AAAA;AACA;;AACA;AAAA;AAsqFA;AAAA;AAAA;;AAtoFA;;;;;;AAaA;AAAA;AAAA;AAAA;AAynFA;AAAA;AAAA;;;AAEA;AAAA;;AAuBA;;AArBA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAEA;AAAA;AACA;AAEA;AAAA;;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;AAKA;;;AAJA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;AAEA;AACA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;;;;;;AAoBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AA/tFA;AAAA;AAAA;AAAA;;AACA;AAAA;AAkuFA;AAAA;AAAA;;AA/tFA;AAAA;AAAA;AACA;;AACA;AAAA;AA6tFA;AAAA;AAAA;;AA7rFA;;;;;;AAaA;AAAA;AAAA;AAAA;AAgrFA;AAAA;AAAA;;;AAEA;AAAA;;AAyBA;;AAvBA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;;AACA;AACA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;AAGA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAEA;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;;AAqBA;;AAjBA;AA5wFA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAgCA;;;;;;AAaA;AAAA;AAAA;AAAA;;;;AAguFA;AAAA;;AAUA;;AARA;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAEA;;AA5xFA;AAAA;;;AA+wFA;AAAA;AAaA;;;;;;;;;;AAIA;AAAA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;;AAGA;;;AAFA;AAAA;;;AAIA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAEA;AACA;AACA;;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;;AADA;AAAA;AACA;;;;;;;;;;;;;;;;AAsjCA;AAKA;AACA;;;AACA;AAAA;;;;;;AAnfA;AAAA;AAAA;;AAEA;AAAA;AAAA;AACA;AADA;;AAGA;AAAA;;;;;AACA;AAAA;;;;;;;;AA6eA;;;;;;;;;;;;;;;AAOA;AAAA;;;;;;;AA1fA;AAAA;AAAA;;AAEA;AAAA;AAAA;AACA;AADA;;AAGA;AAAA;;;;;;AACA;AAAA;;;;;;;;;AAsfA;;;;;;;;;;;;;;;AAOA;;;;AAOA;;AACA;;;AAPA;AAAA;AAAA;AAAA;AAEA;;;AAKA;;AAJA;;AAIA;;;;;;;;;;;;;;;;;;;;;AA9IA;AAEA;;;AAIA;AAAA;;AAUA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AAAA;;;;AAnBA;AAAA;AAAA;AAAA;AAAA;;AAmDA;;AA9BA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;AACA;;AACA;AAAA;;AACA;;AACA;;AAEA;AADA;AAAA;AAAA;AAAA;;AAoBA;;;;AAdA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;;AAMA;AAEA;AAAA;;AAEA;;AARA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AA1EA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;;AACA;;;AAEA;;;;;AAEA;;AA4EA;;;;;;;;;;;AA5/BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AAAA;AAEA;AACA;AAAA;AAAA;AAAA;AA30FA;AAAA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;;AACA;AAAA;;;AAgCA;;;;;;AAaA;AAAA;AAAA;AAAA;;;;AA8xFA;AAAA;;AAUA;;AARA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAOA;;AALA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAEA;;AA11FA;AAAA;;;AA60FA;AAAA;AAaA;;;;;;AAOA;AACA;;;;;;;;;;;;;;;;AAkZA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;AAnBA;AAAA;;;AAuBA;;;;;AAtBA;AAAA;AAAA;AACA;;;;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;AARA;AAAA;;;;;;;;AAuBA;;AADA;AAAA;AAAA;;AA9DA;AAEA;AAAA;;;AA6DA;;;;;;;;;;;AA5DA;AAAA;AAAA;AACA;;;;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;AAIA;;;;AAMA;AAAA;AACA;;AAGA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;AAnBA;AAAA;;;;;;;;AA6DA;;;AA5DA;AAAA;AAAA;AACA;;;;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;AAIA;;;;AAMA;AAAA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;AAnBA;AAAA;;;;;;;;AA6DA;;;;;;;AA5DA;AAAA;AAAA;AACA;;;;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;AAOA;;AAGA;AAAA;AACA;;AAGA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;AAnBA;AAAA;;;;;;;;AA6DA;;;AA5DA;AAAA;AAAA;AACA;;;;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;AAOA;;AAGA;AAAA;AAAA;;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;AAnBA;AAAA;;;;;;;;AA6DA;;;;;;;;;;;;;;AAlYA;AAGA;;;AAEA;AAAA;;;AAEA;AAAA;AAAA;;AAuBA;AAAA;;AACA;AAAA;;;;;;;;;AAvBA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;AAQA;;;;;;;;;;AAPA;AAAA;;;;;AAAA;AAAA;AACA;AAAA;AADA;;AAcA;AAAA;;AACA;AAAA;;AACA;AAAA;;;;;;;;;;;AARA;AAAA;;;;AACA;AAAA;;;;AACA;AAAA;;;;;;AAmBA;;AAEA;;AADA;AACA;;;;;;;AA+VA;AAAA;AAAA;;AAIA;;AAGA;;AANA;;AAMA;;;;;;;;;;;;;AA9MA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAWA;AAAA;AAAA;;AACA;AAAA;;;;;AACA;AAAA;;AA0DA;;AAnDA;AAAA;AAAA;;AACA;;AAkDA;;AA/CA;AAAA;;AAKA;AAAA;;;;AAJA;;AA8CA;;;;AAtCA;AAAA;;;;;AAIA;AAAA;AAAA;AAAA;;AAkCA;;;;AA9BA;AAAA;AAAA;;AACA;;AA6BA;;AA1BA;AAAA;;AACA;AAAA;;AAyBA;;AArBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AACA;AACA;AAAA;AADA;AAEA;AACA;;;AAcA;;AAXA;AAAA;AAAA;AAGA;AAGA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAvNA;AAMA;AAAA;;AAEA;AAAA;AAAA;;;;;;;;;;AAGA;AACA;AADA;;AAEA;;AACA;;AA+HA;;AA5HA;AAAA;;AACA;;AA2HA;;;;;AArHA;;AAAA;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AAIA;;AADA;AAAA;AAAA;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAiGA;;AA5FA;;AACA;;;AACA;;;;;;;;AACA;AAAA;;;AAEA;AAAA;AACA;;;;;;AAGA;AAAA;AACA;;;;;;;;;;;;;AASA;AAAA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;;;;;;;;;;;;;AAEA;AAAA;AAAA;AAAA;AACA;;AACA;AAAA;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;AAEA;AAAA;AAAA;AAAA;AAAA;;;;AAtrDA;AAMA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAorDA;AAAA;;AACA;;AAEA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAGA;;AAAA;;AAFA;AAAA;;AAEA;AAAA;;AAEA;;;;AAIA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;AAQA;AAAA;AAAA;;AAEA;AAAA;;AACA;AAAA;AACA;AAAA;;;;AAKA;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;;;;AACA;;;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;;;;;;;;;;;;;AAhFA;;AAAA;;;;;;;AAqFA;;;;;;;;AAEA;AADA;AAAA;AAAA;AAAA;;;AAEA;AAAA;;AAEA;;;;;;;;;;;;AA8PA;AAAA;AAKA;AAAA;;;AAgBA;AAAA;AAAA;;AAsBA;;AA+BA;;AApDA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAGA;AAAA;;;;;;;;AA4CA;;;;AAnCA;AAAA;AAAA;;;;AAjCA;AAAA;AACA;AAAA;AAAA;;;AAKA;AACA;AAAA;AACA;AAAA;AAnCA;;;AACA;AAAA;AAAA;AAGA;;;AACA;AAAA;;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;AAGA;;;;AA0BA;AACA;AAAA;AAAA;AAAA;;AAPA;AACA;AAAA;AACA;AAAA;AAAA;;AAOA;AAAA;AACA;;;AA8BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA9CA;AAAA;;AA6CA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA/CA;AAAA;;AA+CA;AACA;AAAA;AAAA;;AAOA;AAAA;AAAA;AADA;AAAA;AAAA;AAGA;AAAA;;;AAPA;AADA;AAAA;AAAA;;;;;AAUA;AAAA;AAAA;;AAOA;AAAA;;;;AAAA;;;;AADA;AAAA;AAEA;AAAA;AACA;AAAA;;;AARA;AAAA;AAEA;AAAA;AADA;AAAA;AAAA;;;;;AASA;AAAA;;AAEA;;;;;;;;;;;;AA6IA;AAAA;AAEA;AAAA;AAAA;;AAnCA;AAAA;;;AA0CA;;AAvCA;AAAA;;;;;;AA7DA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AACA;AAAA;;;;;;;;;AAwDA;;;;;;;;;;;;AAIA;;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;;AAkBA;;AAlCA;AAAA;;AAkCA;;;AAHA;AACA;AAAA;AAAA;AAAA;AAAA;;AA/EA;AAAA;;;AAiFA;;AA9EA;AAAA;;;;;;;;AA1CA;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;;AAEA;AAAA;;;;AAOA;AAAA;AADA;;;AAiCA;;;;;;;;AADA;;;;;;;;;;;;AAIA;;AACA;AAAA;;AAyEA;;AAtEA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAlLA;;;AACA;AAAA;AAAA;AAGA;;;AACA;AAAA;;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;AAGA;;;;AAyKA;AACA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;;AAwDA;;;;;;;;;AAsCA;AAAA;AAEA;AAEA;AAFA;AAAA;;AACA;AAAA;AAAA;AAAA;AAsBA;;AAjBA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AACA;;AACA;AAAA;AAAA;AAAA;AADA;AAAA;AAYA;;AATA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;;;;;;;;;;;;AAuPA;AAKA;AAAA;;;;;;;;;;;;AAnbA;AAAA;AAAA;;AAEA;AAAA;AAAA;;;;;;;;;AA1HA;AAAA;;AAAA;AAAA;;;;;;;;;AAmIA;AAAA;;;;;;;AAwaA;;;;;;;;AAGA;AAAA;AAAA;;;AAUA;;AANA;AAAA;AApBA;;AA0BA;;AAFA;;;;AADA;AAAA;;AAGA;;;;;;;;;;AAGA;AAIA;AAAA;;;;;;AAnbA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AACA;AAAA;;;;;;;;AA8aA;;;;;;;AAIA;AAAA;AArCA;;AA2CA;;;AAHA;AAAA;;AAGA;;;;;;;;;AA2EA;AAAA;;AAaA;;;;;;;AAZA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;;;AAXA;AAAA;AAAA;;;;;;;AAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+KA;AACA;;AACA;;AAmGA;;AArEA;AAAA;;AACA;AAAA;;AAmBA;AACA;AACA;;AACA;AAAA;;AA8CA;;AA3CA;AAEA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAwCA;;AAlCA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;;AA6BA;;;AAzBA;;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;AAXA;;AAAA;;;;;;;;;;;;;AAiBA;AAAA;AAMA;;AAEA;;;AARA;AAEA;AAAA;AACA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAMA;;;AAlEA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAiEA;;AA5DA;AAnFA;AAAA;AAjBA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AAAA;AACA;AAAA;;;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AA4FA;AAAA;;AA2DA;;;;;;;;;;AAUA;AAAA;AAAA;AAMA;AAEA;AAEA;AAAA;AAAA;AAAA;;AAGA;;;AAFA;AAAA;;;AAIA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAGA;AACA;;AAQA;;;;AANA;AAGA;AAAA;AACA;AAAA;AAEA;AACA;;;;;AAMA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;;;AATA;AACA;AAAA;AAOA;AAAA;AACA;;;;;;;;;AAMA;AAAA;AAAA;AAAA;AAEA;;;AAIA;;;;AAGA;;;;AAGA;AAAA;;;AAGA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;;;;;;;;;;;;;AAYA;AAAA;AAMA;AAAA;;AACA;AAAA;;AACA;AAAA;;AACA;AAiDA;;;AA5CA;AACA;;;;AACA;AACA;;;;AACA;AAAA;AAAA;;;;AAIA;AAAA;;AAEA;AAAA;AAGA;AAAA;AACA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAJA;AAAA;;;;;;;AAEA;AAAA;AAAA;;;AAIA;AAGA;AAAA;AACA;AACA;;AAIA;AAAA;AAGA;AAAA;;AAIA;AAAA;;AAHA;AACA;AAAA;;AAIA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;;;;;AAUA;AAAA;AACA;AAAA;AACA;AACA;;;;;;;;;;ACn6IA;AAAA;;;;AAKA;AAPA;AAAA;AAEA;AAAA;;;;AAKA;AAAA;AAPA;AAAA;AAEA;AAAA;;;;AAKA;AAAA;AAPA;AAAA;AAEA;AAAA;;;;AAKA;AAAA;;AAIA;;;;;;AATA;AAAA;;;;AAKA;;AAIA;;;AARA;;AAQA;;;;;;AAKA;AAAA;AAAA;;;;;;AAMA;AAAA;AAAA;;;;;;AAMA;AAAA;AAAA;;;AAGA;;AATA;AAAA;;AASA;;;;;;AAKA;AAAA;AAAA;;;;;;AAUA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AACA;AADA;;;AAAA;;;;;;AAaA;AAAA;AAAA;AAAA;;;;;;AAMA;AAAA;;;;;;AA0BA;AAAA;;;AAGA;;AAHA;AAAA;;;AAGA;;AAHA;AAAA;;;AAGA;;AAHA;AAAA;;;AAGA;;AAHA;AAAA;AAAA;AAAA;;;;;;;;;;;AAuBA;;;AAcA;;AAdA;AAAA;;;AAcA;;AAZA;AAAA;AAAA;;;AAYA;;;AATA;AADA;;;;;AAAA;AAAA;;;;;AA3BA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;;;;;;;;AA8BA;AAAA;AAAA;;;;;;;AACA;;AAMA;;;AAFA;;AAEA;;;;;;;;AAWA;;;AAMA;;AAHA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;;AAGA;;;;;;AAFA;AAAA;;AAEA;;;;;;AA5CA;AAAA;AAAA;AAAA;AAkDA;;;AAAA;;AAAA;;AAAA;;;;;;AAMA;;;;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;AACA;;;;AAGA;;;;;;;;;;;;;;AAeA;AACA;AAAA;;;AAiGA;;AA9FA;AAAA;AAAA;AACA;AADA;AAAA;AAKA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;;;;;AACA;;AAjJA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AACA;AADA;;;;;;AAiJA;;;;;;AAKA;AAAA;AACA;AAAA;AAAA;AAAA;;;AAKA;AAAA;;AAMA;AAAA;;;;;;;;AALA;AAAA;AAAA;AAAA;AACA;;;;AANA;AAAA;AAgEA;;;;;;;AAEA;;AAYA;;;AALA;AACA;;AAIA;;;;;;;;;;;;;AAgBA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;AAAA;AADA;;AAuDA;;AAnDA;AAAA;;AAOA;AAAA;;;AA4CA;;AA3CA;AAAA;;AA2CA;;AAlDA;;AACA;;AACA;AAAA;AACA;AADA;;AAgDA;;;;;;;;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;;AAMA;;AAJA;;;AAIA;;AAFA;AAAA;;AAEA;;;;;;AAKA;;AAcA;;AAZA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;;AACA;AAAA;;;AAFA;AAAA;;AASA;AACA;AACA;;;;;;;;;AC7dA;AAAA;AAAA;AACA;;;;;;;AAKA;AAAA;AACA;;;;;;;;;;;;;;;AAQA;;AAQA;;;;;;;;;;;;;;;;;;;;;AARA;AACA;;AACA;AAAA;AArCA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;AAwCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AANA;;;;;;;AAQA;;;;;;ACjCA;AAAA;AAAA;;AAIA;;AAFA;AACA;AACA;;;;;;AAIA;AAAA;AACA;AACA;;;;;;;AAGA;AAAA;;;AAmJA;AACA;AAAA;;;;;;AADA;AAAA;;;;;;;;;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;AAMA;;;AAFA;AAAA;;AAEA;;;;;;;;;;;;AASA;;;AAwBA;;AAtBA;AAAA;AACA;;;AAqBA;;AAnBA;AAAA;;;;;;;;;AAAA;AAAA;;;;;AACA;;;;;;;;;;AAYA;AAAA;;;AAbA;AAAA;;;;;;;;AAUA;AAVA;AAAA;;;;;;;;;;AAiBA;;AAEA;;;;;;;AAGA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;;AASA;;AAPA;AAAA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;;;AAEA;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;;AASA;;AAPA;AAAA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;;;AAEA;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;;AAiBA;;AAfA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;;;AACA;AACA;;AACA;AAAA;;;;;;;;AACA;AAAA;;;;AACA;AAEA;;AACA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;;;AAEA;;;;;;;;;;;ACrQA;AACA;AAEA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;ACoFA;AAEA;;AAEA;;AArDA;;AACA;;AA2EA;;AAxEA;AAAA;;AACA;;AAuEA;;AApEA;AACA;AACA;AAAA;;AACA;;AAiEA;;AA7DA;AAAA;AAAA;AAEA;AAAA;;AACA;AAAA;;AA0DA;;AAvDA;AAAA;AACA;AACA;AAAA;AAEA;AACA;AACA;;AACA;;AAgDA;;AA7CA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;;AA4CA;;;AAfA;AAAA;;AAIA;AAAA;AAAA;;AAHA;AAAA;;AAGA;AAAA;AAAA;;AAFA;AAAA;AAAA;;AAEA;AAAA;AAAA;;AADA;AAAA;;AACA;AAAA;AAAA;;AACA;AAEA;AAAA;;AAEA;AAAA;AAAA;;AADA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIA;;;;;AAqEA;AAEA;AACA;;;;;;;;;;;;AAiDA;AACA;AAAA;AACA;AAAA;AAEA;;;;;;AAEA;AAAA;AAAA;;AAEA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;;AAGA;;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;;;;;;;;;;AApDA;AAAA;AAGA;AAAA;AAGA;AAAA;AAAA;;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;AAuBA;;AAjBA;AAAA;AAAA;AACA;AAAA;AADA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AACA;AAAA;AAAA;AADA;AACA;;;AAaA;;AAXA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2ZA;AAQA;AACA;AAAA;AAAA;AAAA;;;AAwKA;;AAtKA;AAAA;;;AAsKA;;AAnKA;AAAA;AAAA;AAAA;AACA;AAAA;;;;;;;;;;;;;;;;;;AACA;AAAA;AAAA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;;;AAGA;;;;;;;;;;;;;;;AAAA;;;;;;;AAIA;AACA;AAAA;;;;;;;;;AAzgBA;;;AAKA;AAAA;;AACA;AAAA;;;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;;;;AAEA;AAAA;;;;;;;;;AAOA;;;;;;;;;;;;;;;AAAA;;;;;;AAyfA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;AAvfA;AAsfA;;;AASA;;;;;;;;;AAAA;;;AAEA;AACA;;;;AAIA;AA7EA;AAAA;AAEA;;AAKA;AAAA;;AAyEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAtEA;AAAA;;AACA;AAAA;;;;;;AAEA;AAAA;;;;;;;AAwEA;AACA;AAAA;AAAA;AAAA;;;;AAKA;AA1FA;AAAA;AAEA;;AAKA;AAAA;;AAuFA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAnFA;AAAA;;;;AACA;AAAA;;;;;AAEA;AAAA;;;;;AAsFA;AACA;AAAA;AAAA;AAAA;;;AASA;AAAA;AADA;;;;;;;;;AAMA;;;;;;;;;;;;;;;;;;AAIA;AADA;AAAA;AAAA;AAAA;;;AAIA;AAAA;;;AAiCA;AACA;AAAA;;;;AACA;AAAA;AAAA;;;;AAEA;AACA;AAAA;AACA;AAAA;AAMA;AAAA;AAAA;;AACA;AAAA;;AACA;;;;;;;;;;AAQA;;;;;;;;;;;;;;;AAAA;;;;;AAIA;AADA;AAAA;AAAA;AAAA;AAEA;;;;;AAEA;;;;;;;;AAtDA;AAAA;AAAA;;;;AAzmBA;;;AAAA;;;;;;;;;AAAA;AAAA;;;AAGA;AAAA;;;;;;;AAIA;;;;;;;;;AAAA;AAAA;;;AAIA;AAmnBA;AAAA;AAAA;AACA;;;AA0CA;AAAA;;;;;;;;;AARA;AAAA;AACA;AACA;AACA;AAAA;;;;;;;AAvJA;AAAA;;;;;;AA6FA;AAAA;;;;;;AAkEA;AAAA;AACA;;AAEA;;;;;;;AAhjBA;AAAA;AAAA;;;;AAMA;AACA;AACA;AACA;;;;;AARA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAJA;AAAA;AAAA;;;;;;;;;AAMA;AACA;AACA;AACA;;;;;;;;;AAgGA;AAGA;;AACA;AAAA;;AACA;AAAA;;;;;;;;;;;;;;;;;AA3DA;AACA;AAAA;AACA;;;;AAAA;;;AAAA;AAEA;;AACA;;AAEA;AAAA;AAAA;;;;;;;;;;;AACA;;;;;;;AAIA;AAAA;AAAA;;;;;;;;;;;;;AAYA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AASA;AAAA;;;;;;;AASA;AAAA;AAAA;;;;;;;;;;;;AAnCA;AAAA;AAAA;;;;;;;;;;;;;;;;;;AAKA;AAAA;AAAA;AAGA;AAHA;;;;;;;AALA;AAAA;;;;;;;;;;;;AACA;;;;;;;;;AAIA;AAAA;AAAA;;;AAYA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AASA;AAAA;;;;;;;AASA;AAAA;AAAA;;;;;;;;;;AAnCA;AAAA;AAAA;;;;;;;;;;;;AAKA;AAOA;;;;;;AACA;AAAA;;;;;;;;;AASA;AAAA;AAAA;;;;;;;;;AAOA;AAAA;AAAA;;;;;;AAzEA;AASA;AANA;AAAA;;;AAoFA;;;;;;;AAnFA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;;;;;;;;;AAHA;AAAA;;;;;;;;AAoFA;;;;AAnFA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;AADA;AAAA;;;;;;;;;AANA;AAAA;;;;;;;;AAoFA;;;;;AAAA;;AAFA;;AAEA;;;;;;;;AAgBA;AACA;AAAA;AADA;;;;;;;;;AA8CA;;;;AAEA;AACA;;;;AAEA;AACA;;;;AAEA;;;;;;;;;;;AAjDA;AAAA;AAAA;AAAA;AAAA;AAMA;AACA;AAEA;;;AAOA;;AAGA;AAAA;;;AAFA;AAAA;AAAA;AAAA;;;;AAPA;AAAA;;AAKA;AAAA;;;AAJA;AAAA;AACA;;AAgBA;;;AAPA;AACA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;;;AACA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8FA;AAAA;AAEA;AAAA;AAIA;AAEA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;;;AAsGA;;AApGA;AAAA;AACA;AAAA;AACA;AAAA;AAKA;AAAA;AAAA;;;;;;AACA;AAAA;AAAA;;;;;AAKA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;AAIA;AAAA;AAAA;;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;AAMA;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;AAKA;;;;;;AACA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AACA;;;;;;AAMA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AAAA;AAAA;AAAA;;;;;;AAIA;;AAhBA;AAAA;;;;;;;;AAkBA;AAAA;AACA;AAEA;AAAA;;AAyBA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAxBA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAKA;AAAA;AAAA;;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAKA;AAAA;AAAA;;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAeA;AAAA;AAAA;AAAA;;AACA;;;;;;AACA;AAAA;AACA;AAAA;AACA;AAAA;;AACA;;AACA;AAAA;AACA;AACA;;;AAGA;;AAFA;AAAA;;AAEA;;;;;;;;;;;;AA7KA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAGA;AAAA;;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AA4CA;;AAtCA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAqCA;;AA5BA;AAAA;AAAA;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;;;;AADA;AAAA;AAAA;AACA;;;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBA;;;AAbA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAWA;;;;AALA;AAAA;AACA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAEA;;;;;;;AC7YA;;;AAKA;;AAHA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;AAAA;AAAA;;;;;AAGA;;;;;;;;;;AAFA;AAAA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA;;;;;;;;;AASA;AACA;AAEA;;;;;;;;;;;;;;;;AA6OA;AAAA;AAGA;AAAA;;AAmEA;;;;AA9DA;AAAA;AAAA;;;;;;AAKA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;;;;;;;;AAEA;;;AAGA;AAAA;AAAA;AADA;AAEA;AAAA;;;AAMA;AAAA;;AAUA;AAAA;;;AAAA;AAAA;AACA;AAAA;AACA;;;AAXA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;;;AANA;AACA;AAAA;AACA;;;AAgBA;AAAA;AACA;;;;;;;;;AA/RA;AACA;AAEA;AAAA;;;;;;;;;AAUA;AACA;AAEA;;;;;;;;;AASA;AACA;AAEA;;;;;;;;;AASA;AACA;AAEA;;;;;;;;;AAOA;AACA;AAEA;;;;;;;;;AAOA;AACA;AAEA;;;;;;;;;;AAOA;AAAA;AAMA;AAEA;;AAYA;AAAA;AAAA;AAEA;AAAA;;AALA;AAQA;AACA;AAEA;AACA;;AA6DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAlBA;AAAA;AAAA;AAGA;AAAA;;;;;AAYA;;;AAAA;AACA;AAEA;;;;;;AAMA;AAAA;;AAGA;;AADA;AAAA;AAAA;AACA;;;;;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAKA;AAAA;AAIA;AAAA;AAAA;;AACA;AACA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAEA;AAAA;;AAEA;AACA;;;;;;;;;;;AAgBA;AACA;AAEA;;;;;;;;;;ACxUA;;;;;;;;;;;;;;;AAuCA;AAAA;;;;;AAIA;AAAA;AAAA;;;;;AAIA;AACA;;;;;AA/CA;AAAA;AAAA;;;;AAIA;AAGA;;;;;;;;AAqBA;AAAA;;;;;;;;AACA;AAAA;AADA;;;;;AAAA;AAAA;;;;;;;;;;;;;AAXA;AAAA;;;;;;;AACA;;;AACA;AAAA;;;;;;AAFA;AAAA;;;;;;;;;;;AAiCA;;;;;;;;;;;;;;AAcA;;;;;AAGA;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAWA;;;;;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AADA;AAAA;AADA;AAAA;AAAA;;;;;;;;;;AAKA;;;;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;;;;;;AAIA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAaA;;;;;;AA1CA;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAWA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAEA;AAAA;AAAA;;;;AACA;;;AADA;AAAA;AAAA;AADA;AAAA;AADA;AAAA;AAAA;;;;;;;;;;AAKA;;;;;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;;;;;;AAIA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAaA;;;;;;;;;AAWA;AAGA;AACA;AACA;AACA;;;;;;;;;;;;;;;AA2EA;AAAA;AACA;AAAA;AAEA;AAAA;;;;;;;AAAA;AAAA;AAEA;AAFA;;;;;AAGA;AAAA;AAFA;;AADA;;;;;;;;;;AASA;AAAA;;;;;;;;;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AADA;;;;;;;AARA;AAAA;;;AAQA;AAAA;;;;;;;AAGA;AAAA;AAAA;AAAA;;;;;AADA;;;;;;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AADA;;;;;;;;AARA;AAAA;;AAYA;AACA;;AACA;AAAA;;AACA;;;AAAA;AAAA;AAAA;;;AADA;;AAEA;AACA;;AAUA;;;AALA;;AACA;AAAA;;AACA;AACA;;AAEA;;;;;;;;;;;;AASA;AAAA;AACA;AACA;AAGA;AAAA;AAAA;;AACA;AACA;;AAeA;;AAXA;AACA;AACA;AAAA;;;;AA9LA;;;AAGA;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAWA;;;;;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AADA;AAAA;AADA;AAAA;AAAA;;;;;;;;;;AAKA;;;;;;;;;;;;;AAIA;AAAA;AAAA;;;;;;AAIA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;AA+JA;;;;;;;AACA;AAAA;;AACA;;AACA;;AAJA;AAAA;;;;;;;;AAOA;;AAEA;;;;;;;;AC3LA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAOA;AADA;AAAA;AAAA;AAAA;AAIA;;AARA;AAlDA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAsDA;;;;;;;;;AAqWA;AAAA;AAAA;AAEA;AAAA;;AAAA;AAAA;;AAqBA;;;AAnBA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAaA;AAAA;AAAA;;AAKA;;AAFA;AAAA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;;AAZA;AAAA;;AAYA;;AAXA;AAAA;AAAA;;AAWA;;AARA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA;;;;;;;;;;AA1XA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAEA;AADA;AAAA;AAoBA;;AAhBA;AAAA;AAAA;;AAaA;AADA;AAAA;AAAA;AAAA;AAIA;;AAdA;AAAA;;AA8EA;AAAA;AAAA;AACA;AAAA;;AAGA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AAIA;AADA;AAAA;AAAA;AAAA;;AA7JA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAgFA;;AAbA;AAAA;AAAA;AAAA;;;AA+LA;AAAA;AAAA;AACA;AAAA;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;;AAIA;AADA;AAAA;AAAA;AAAA;;;;;AA/QA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAgFA;;;;;;;;AAwCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAEA;AADA;AAAA;AAgBA;;AAZA;AAAA;AAAA;;AASA;AADA;AAAA;AAAA;AAAA;AAIA;;AAVA;AACA;AAAA;;;AA8BA;AAAA;AAAA;AACA;AAAA;;AAGA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AAIA;AADA;AAAA;AAAA;AAAA;;;;;AAtKA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAmIA;;;;;;;;AA2PA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;;AAAA;AAAA;;AAeA;;;AAZA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAMA;AAAA;AAAA;;AAKA;;AAFA;AAAA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;;AAVA;AAAA;;AAUA;;AAPA;AAAA;AAAA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA;;;;;;;;AA9LA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAMA;;AAJA;AApOA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAoOA;;;;;;;;;AAkFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;;;AApOA;AAAA;AACA;AAAA;;;AA9EA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAuTA;;;;AAlOA;AADA;AAAA;AAAA;AAAA;;;;;;;;AA2IA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAnOA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAqTA;;AAIA;;;;AAvTA;;AAoTA;AAAA;AAAA;;AAGA;;AAFA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAEA;;AAFA;AAAA;AAAA;;AAEA;;;;;AADA;AACA;;;;;;;;;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;;AAjTA;AAAA;AACA;AAAA;;;AAtBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAwUA;;;;AA/SA;AAuHA;AAAA;AAAA;AACA;AAAA;;AAGA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AAIA;AADA;AAAA;AAAA;AAAA;;AA7JA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAwUA;;;;AAxLA;AAAA;AAAA;AACA;AAAA;;AAGA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AAIA;AADA;AAAA;AAAA;AAAA;;AA7JA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAwUA;;;;AApSA;AADA;AAAA;AAAA;AAAA;AAqSA;;;;AAjJA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;AAEA;AADA;AAAA;;;;AAEA;AAAA;;AAEA;AAAA;;;;;AAzLA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAbA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAsMA;;AA7LA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;AAoMA;AAAA;;;AAEA;AAnNA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAqNA;AAAA;AAAA;;;AA+CA;AAAA;AAAA;AACA;AAAA;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;;AAIA;AADA;AAAA;AAAA;AAAA;;;;;AA/QA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AA0UA;;;;;AAxUA;AAwUA;;;;;;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;AAvOA;AAAA;;;;AA4IA;;AAUA;AADA;AAAA;AAAA;AAAA;AAsFA;;AA5FA;AACA;AAAA;AAAA;AAAA;;;AA+CA;AAAA;AAAA;AACA;AAAA;;AAEA;AADA;AAAA;;;AAIA;AAAA;AAAA;;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;;;AA3SA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAuUA;;;;AAxOA;AAyDA;AAAA;AAAA;AACA;AAAA;;AAGA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AAIA;AADA;AAAA;AAAA;AAAA;;AAtKA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAuUA;;;;AAnOA;AAoDA;AAAA;AAAA;AACA;AAAA;;AAGA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AAIA;AADA;AAAA;AAAA;AAAA;;AAtKA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAuUA;;;;AA7NA;AADA;AAAA;AAAA;AAAA;AA8NA;;;;;;;;AAKA;AACA;;;;;;;;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAuCA;;AApCA;AAAA;AAAA;;;AAoCA;;AApCA;AAAA;AAAA;;;AAoCA;;AAlCA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAiCA;;AA9BA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA0BA;;;;;AAtBA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAqBA;;AAlBA;AAAA;;;AACA;;AAIA;AAAA;;;;AAEA;AAAA;AADA;AAAA;;AAYA;;AAhHA;AAAA;AAAA;AAAA;AACA;AAAA;AAGA;AAFA;AADA;;AAGA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAEA;AAAA;AAAA;;AAGA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;;AALA;AAAA;AAAA;;;;;AAoGA;AAAA;AAAA;;;AAMA;;AAJA;AAAA;AAAA;AAAA;;AAIA;;;;;;ACzPA;AAAA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AAwBA;;;AAvBA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAKA;AAAA;AACA;;AAYA;;;;;AARA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;;AAEA;;AAEA;;;;;;AAaA;AAAA;;;;AACA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;AADA;AAAA;;;;;;;;;;AASA;AAAA;AAAA;AAGA;AAGA;;AACA;AAAA;;AA4BA;;AAzBA;;AACA;AACA;;AACA;AAAA;;AAsBA;;;;;;;AAnBA;AACA;AACA;AAAA;AACA;AAAA;AACA;;AACA;AAAA;AACA;;AAKA;AAAA;AAAA;AAAA;AACA;AAAA;AAKA;;AAEA;;;;;;;AAZA;AAAA;AAAA;AAAA;AAAA;AACA;;AAWA;;;;;;;AAqMA;AAAA;AAGA;AAAA;AAAA;;;AAaA;;AAZA;AAAA;;AAMA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;;AAPA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;;;;;;AAQA;;;;;;;;;;;;AA1GA;AAIA;AAAA;;;;;AAAA;AAAA;AAAA;;;;AAIA;;;;AAEA;AACA;AACA;AAAA;AACA;;;;AAEA;AACA;AACA;AAAA;AACA;;;;AAEA;AAAA;AAAA;;AAAA;AAAA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;AAGA;;;;;;;;AA/HA;AAEA;AAAA;AAAA;;;;;AAIA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;;AANA;AAAA;;AAMA;AAAA;AAAA;AAAA;;AANA;AAAA;;;;;;;;;;AAOA;;;;;;AAKA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;;;;;AAKA;AAAA;AAAA;AAAA;;;;;;;;;;AAyBA;AAGA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AACA;AADA;AAEA;;;AACA;AAAA;AAAA;AACA;;;;;AAAA;AACA;;;;;;AAEA;AACA;AAAA;AACA;AAFA;;;;AAQA;;;AAFA;AAqJA;AACA;AAAA;AAvJA;AAAA;AAAA;AAAA;;AAGA;;;;;;AAmJA;AACA;AAAA;AAAA;;;;;;;;AArFA;;AACA;AAAA;AAAA;AAAA;;AACA;;AAEA;;AADA;AAAA;AAAA;AAAA;AACA;;;;;;AA0BA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;;AAEA;;AADA;AACA;;;;;;AAOA;AAAA;AAAA;;;;;;AAQA;AAAA;AAAA;AAAA;;;;;;;;;;AA+DA;AAAA;AAEA;AAGA;AAAA;AAAA;;AAgDA;;AA9CA;AACA;AAAA;AAAA;AAAA;;AACA;AACA;AAAA;;AAEA;AACA;AAAA;;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AACA;AAAA;AAAA;;AAIA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AADA;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;;AAPA;AAQA;;;AAEA;AAAA;AAAA;;AAIA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AADA;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;;AAPA;AAQA;;;;AAGA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;;;;;;AAeA;AAAA;AAAA;AAAA;;;;;;;;;;AAuDA;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAGA;;AADA;AAlDA;AAAA;AAAA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAkDA;;;;;;;;;;AAtBA;AAAA;AAAA;;AACA;AAAA;;;;;;AACA;AAAA;;;AAEA;AAAA;AAAA;AAxBA;AAAA;;;AA0CA;;AAxCA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;AACA;AAAA;;;AAEA;AAAA;AAAA;;AAmCA;;;;;AAAA;;;;;AAAA;;;;;;;AAAA;;;;;AAAA;;;;;;;;;;;;;;;;AAoJA;AASA;AAAA;AAAA;;AAkBA;;;AAjBA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;;;AAsEA;;AAnEA;AAAA;AACA;;;AAkEA;;AAhEA;AACA;AADA;AACA;;;AA+DA;;AA7DA;AAAA;AACA;AACA;AADA;AACA;;;;;AA2DA;;;AAvDA;AAAA;AAAA;AAGA;AAAA;AACA;AAAA;AAAA;AAAA;;;AACA;AAAA;AAAA;AACA;;;AAiDA;;AA7CA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AAAA;;;AA2CA;;AAvCA;AAAA;AACA;AAAA;AADA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;AAoCA;;AA3BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;AA0BA;;AAxBA;AACA;AAAA;AADA;AACA;;;AAuBA;;AArBA;AAAA;AACA;AAAA;AACA;AAAA;AAFA;AAEA;;;AAmBA;;AAZA;AAAA;AAAA;AAAA;AAEA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;AASA;;;;;;;;;;;;AAxNA;AAAA;AAAA;AAAA;;;AAsCA;;AAlCA;AAAA;;;AAkCA;;AA7BA;AADA;AAAA;AAAA;AACA;;;AA6BA;;AA3BA;AAAA;AAAA;AAAA;;;;AAKA;AAAA;AACA;AAAA;AAAA;AAGA;AAAA;AAAA;;;;;;;;;;;;;;;;AAQA;AAAA;AAAA;AADA;AAAA;AACA;;;;;;AAQA;AAAA;AAAA;AAAA;;;;;;;;;;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAhCA;AAAA;;AAgCA;;AAKA;;;AAAA;;;;;;;;;;;;;;;;;AAsLA;AAAA;AAAA;AAAA;AAAA;AAEA;AAUA;AAAA;AAEA;;AAEA;AAEA;AACA;;;AAGA;AAEA;AACA;;;AAEA;AAAA;AAAA;;;AAGA;AACA;AAAA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;;AAGA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAmDA;;AAjDA;AAAA;AAAA;AACA;AAGA;AAAA;AAAA;AAAA;;AAFA;AAGA;AAAA;;;AA4CA;;;AAzCA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AADA;AACA;;;AAsCA;;AApCA;AAAA;AAAA;;AACA;AAAA;AAAA;;AACA;AAAA;AACA;;;AAMA;AAAA;;;;;;;AAEA;AAAA;AAAA;;;;;;;;;;AAAA;AAAA;AAAA;;AA3WA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAmYA;;;;;AAzXA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;AACA;AAAA;;;AAEA;AAAA;AAAA;;;;;;AAoXA;;;;;AAAA;;;;AAvWA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;AACA;AAAA;;;AAEA;AAAA;AAAA;;;;;;AAmWA;;;;;AAAA;;;;;AAfA;;;AAMA;AAAA;AAAA;;AACA;AAAA;AAAA;;;AAEA;AAAA;;;AAFA;AAGA;AAAA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAEA;AAAA;;AAEA;;;;;;AAyFA;AAAA;AAIA;AAAA;AAIA;;;;;;;;;;;;;;;;;;;;;AAQA;AAUA;AAAA;AAAA;;;;;AAEA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;;;;;;;AAEA;AAAA;AAAA;AAAA;AAAA;AArCA;AAAA;AAIA;;AAmCA;AAAA;;AAMA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAEA;AAAA;AAAA;;;AAyHA;;AAvHA;AAAA;AAAA;AACA;AACA;AADA;AACA;;;AAqHA;;AAnHA;AAAA;AACA;AAAA;AACA;;;AAiHA;;AAhHA;AACA;AADA;AACA;;;AA+GA;;;;AAxGA;AAAA;AAMA;AACA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AAAA;AAAA;;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAJA;AAAA;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAJA;AAAA;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAJA;AAAA;;AAIA;AADA;AAGA;AAAA;;;AAyFA;;AAvFA;AAAA;AAAA;AAIA;AAIA;AAEA;AAAA;;;AA6EA;;AA3EA;;;;;;;AAEA;AAAA;AAAA;AAAA;;;AAyEA;;;AAvEA;AAAA;AAAA;AAAA;;AAEA;AAAA;;;;;;;;AAGA;AAAA;;AAGA;AAAA;AACA;AAAA;AAAA;AACA;;;AA6DA;;AAxDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;AAKA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AADA;AAEA;;;AA+CA;;;;;AA1CA;AAAA;AACA;AAAA;AAAA;AADA;AACA;;;AAyCA;;AAvCA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAFA;AAEA;;;AAqCA;;;AAlCA;AAAA;AAAA;;AACA;AAAA;AAAA;;AAEA;AACA;AADA;AACA;;;AA8BA;;;AAzBA;AAAA;AAAA;AAAA;AAAA;;;AAyBA;;;;AAjBA;AAAA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;;AAcA;;;AAZA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AAGA;;AAOA;;;;AANA;AAAA;AAAA;;;AAMA;;AALA;;AAKA;;;;;AAAA;;;;;;;;;;;;;AA7MA;AAEA;AAQA;AAAA;AAGA;AAAA;AAAA;;;;;AAGA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAzcA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAsdA;;;AA1bA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;AACA;AAAA;;;AAEA;AAAA;AAAA;AAkbA;;;;;;;AAIA;;;;;;;;;;;;;;;;;AAjBA;AAAA;AAAA;;;AAiBA;;AAdA;AAAA;AAAA;;;AAcA;;AAdA;AAAA;AAAA;;;AAcA;;AAvdA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAsdA;;;AA5cA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;;;;;;AACA;AAAA;;;;;;;AAycA;;;;;;;AAvcA;AAAA;AAAA;AAmcA;;AAIA;;;;AAAA;;;;;;;;;;AA8LA;AAAA;AAAA;AAAA;AAEA;AAKA;AAAA;AAAA;AAAA;;;AAqEA;;AAnEA;AAAA;AAAA;AAAA;AAjBA;AAAA;AAAA;AAAA;AAkBA;;;AAOA;;;AANA;AAAA;AAAA;AADA;;AAOA;AAAA;AAAA;AAAA;;;;;;;;AAEA;AAAA;;;AACA;AAAA;AAAA;AACA;AACA;;;AAsDA;;AApDA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;;AAgDA;;AAxCA;;AAwCA;;;AAlCA;;AACA;;AAEA;AAAA;;;AA+BA;;AA3BA;;;AA2BA;;AA1BA;AACA;AAAA;AAAA;;;;AACA;AAAA;;;;;;AACA;AAAA;AAOA;AAAA;AAAA;AADA;AAAA;;;;;AAMA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;;;;;;;;AAVA;AAAA;AAEA;;AAaA;;;AAAA;;;;;;;;;;;;AAvVA;AAIA;AAAA;AAAA;;;AAmCA;;AA/BA;AAAA;AAAA;;;AA+BA;;AAryBA;AAAA;;AACA;AAAA;AAAA;;;AAoyBA;;AApyBA;AAAA;AAAA;;;AAoyBA;;;AA3BA;AAAA;AAAA;AAAA;;;AA2BA;;AApBA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;AAoBA;;;AAhBA;AAAA;AAAA;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAeA;;;;AAXA;;;AAWA;;AAVA;AAAA;AAAA;;;AAUA;;AANA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;;;;AAFA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AACA;AAAA;AAAA;;;;AACA;AAAA;AAAA;;;;AAFA;;AAGA;;;;;;;;;;;;;;;;;;;AA2TA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAEA;;;AAgFA;;AAzEA;AAAA;;;AAMA;AACA;;;;;AAEA;AAAA;;;AACA;;;;;;;;;;AAm/CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;AA5+CA;;;AAAA;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AACA;AADA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;AACA;;;;;;;;;;;;;AAKA;;AACA;AAAA;AACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AACA;;;;;AAEA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;;AAEA;AAAA;;;;;;;AAEA;AACA;AAAA;;;;;;;;;;;AAKA;;;;;;AAKA;AAAA;AACA;;;;;AAIA;;;;;AA4iBA;AAGA;AAAA;AAAA;;AASA;AAAA;AAAA;AAljBA;;;;;;AA0iBA;AAAA;AACA;;;;AACA;AAAA;;;;;;;;AAGA;AAAA;;AA5mBA;AACA;;;;;;;;;AAhBA;AAAA;;;;;;;;;AAgFA;;AAEA;;;;;;;;;;;;;;AAkuBA;AAEA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAEA;;;AA6CA;;AA3CA;AAAA;;AACA;;AA0CA;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;;;;;AA7CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AACA;AADA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;AACA;;;;;;;;;;;;;AAIA;;AACA;AAAA;AACA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AACA;;;;;AAEA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;;AAEA;AAAA;;;;;;;AAEA;AACA;AAAA;;;;;;;;;;;AAKA;;;;;;AAIA;AAAA;;;;;;;;;AAxCA;AAAA;;;AAqCA;;AAUA;;;AANA;;AAMA;;;AAFA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;AA7UA;;;AAMA;AACA;AAAA;;AA6CA;AACA;;;;;;;;;;;;;;;;;;;;AA64BA;AAAA;AAAA;AAAA;AAv4BA;;;;;;AAEA;AAAA;AAAA;AACA;AAAA;;;AAtDA;AACA;;;;;;AAEA;AAAA;;;;;;AACA;AAGA;;;;;;;;AAEA;;;;;AA+5BA;AAAA;AAAA;AAAA;AA55BA;;;;;;AA86BA;AAAA;AAAA;AAAA;AA76BA;;;;;;AA66BA;AAAA;AAAA;AAAA;AA56BA;;;;;;AAIA;AAAA;AAAA;AACA;AAAA;;;;;AA25BA;AAAA;AAAA;AAAA;AA34BA;;;;;;AAGA;AADA;AAAA;;;;;;;;;;;;AAtBA;AAAA;;AAuDA;;;AAw2BA;AAAA;AAAA;AAAA;AAx5BA;;;AAgDA;;AAo3BA;AAAA;AAAA;AAAA;AAn6BA;;;AA+CA;;AA5CA;AAAA;AAAA;AAAA;AACA;AAAA;AADA;AAAA;AAIA;AA/5CA;AACA;AAAA;AA+5CA;AAAA;AALA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;;AAsCA;;;AAo3BA;AAAA;AAAA;AAAA;AAj4BA;;;AAaA;;AAVA;AA77CA;AACA;AAAA;AA67CA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;;AAQA;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAtTA;AASA;AAAA;AAAA;;;;AA1CA;;;AAoQA;;AAlQA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;;AACA;AAAA;AAAA;;;AA+PA;;AA7PA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AA4PA;;;;;;;AAxPA;AACA;AAAA;AAAA;;;AAuPA;;AArPA;AAAA;AAAA;AACA;AAAA;AACA;AADA;AACA;;;AAmPA;;AAlPA;AAAA;AAAA;;;AAkPA;;AAjPA;AAAA;AAAA;;;AAiPA;;AAhPA;AAAA;AAAA;;;AAgPA;;AA9OA;AA9jBA;AAAA;AAIA;;AA2jBA;AAAA;AAAA;AAAA;;AAGA;;AA0OA;;AAvNA;AAEA;AAAA;AAAA;;;AAqNA;;AAlNA;AAAA;AAAA;;;;;;AAEA;AACA;AAEA;AAAA;AAAA;AAAA;;;AAGA;AAAA;AAAA;;AACA;AAAA;;;;;AADA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;;;;;;;;;;;AADA;AAAA;;;;AAGA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAFA;AAEA;;;AAmMA;;AAjMA;AAAA;AAAA;;AAUA;AAAA;AAAA;;;;;;AALA;AAAA;AACA;AAAA;AAAA;;AA2LA;;;;;;;;AAtLA;AAAA;AAAA;;;AAKA;AAAA;AAAA;AAAA;;;AAiLA;;AA/KA;AAAA;AAAA;AACA;AAAA;AACA;;;AA6KA;;AA3KA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AADA;AAEA;;;AAyKA;;AAvKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;AAQA;AAAA;AACA;;AA6JA;;AA1JA;AAAA;AAAA;;;;;;AA0JA;;;;;AA7IA;;;;;;;;;;;AARA;AAYA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AADA;;AAsIA;;AA3HA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AA2HA;;;;AApHA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAFA;;;;;;;;;;;AAmHA;;;AA9GA;;AA8GA;;;;;AA1GA;AAAA;AAAA;AACA;;;AAyGA;;AAvGA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AADA;AACA;;;AAsGA;;AApGA;AAAA;AAAA;;;AAoGA;;;AAlGA;AAAA;AAAA;;AAEA;AAAA;AAAA;;;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAHA;;;;;;;;;;;AAgGA;;;AA1FA;AACA;AAAA;;;AAyFA;;AAtFA;AAAA;AACA;AAAA;AA56CA;;AAGA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AASA;AAAA;;AACA;AAAA;AACA;AAAA;;AAEA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;;AA++CA;;AAh/CA;;AAg/CA;;;;;AA7/CA;AAAA;AAAA;;AA6/CA;;;AAjFA;AAAA;AAAA;AAAA;AAAA;;;AAiFA;;;;AA9EA;;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;;AACA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;;;AAyEA;;;AAvEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAEA;;AACA;AAAA;AACA;;;AA+DA;;AA9DA;AAAA;AAFA;;AAgEA;;AAxDA;AAAA;AAAA;;;AAwDA;;AAvDA;AAAA;AAAA;;;AAuDA;;AAlDA;;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AACA;AACA;AADA;AACA;;;AA+CA;;AA7CA;AAAA;AACA;AACA;AADA;AACA;;;;;;AA2CA;;;;AAlCA;AAAA;AAAA;;;AAkCA;;AAhCA;AA5wBA;AAAA;AAIA;;AAywBA;AAAA;;;;;;AACA;AAAA;;AAAA;AACA;AAAA;AACA;;;AA4BA;;AA3BA;AAAA;AAFA;;AA6BA;;AAvBA;AAAA;AAAA;;;;;AACA;AACA;AAAA;AADA;AACA;;;;;;;AAqBA;;;;AAnBA;;;AAAA;AAAA;AAAA;;;;;AACA;;;;;;AAQA;AAGA;AAAA;;;AAOA;;AANA;AAAA;AACA;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;AAnZA;AAQA;AAGA;AAAA;AAAA;AAAA;;;AA0HA;;AAvHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;AACA;AADA;;AAqHA;;AAhHA;AAAA;AAGA;AAAA;AAAA;AAAA;;;AA6GA;;AAvGA;AAAA;AAAA;;;AAuGA;;AA/FA;AAAA;AAAA;AAAA;;;AAEA;AACA;AAAA;AADA;;;;;;;;;;;;;;;;;;AAeA;AAAA;AACA;AAAA;AAAA;;;AA6EA;;AA5EA;AAAA;AADA;;AA6EA;;;AArEA;AAAA;AAAA;AACA;AAAA;AAAA;;;AAoEA;;AAlEA;AAAA;AACA;AAAA;AADA;AACA;;;AAiEA;;AA9DA;AAAA;AAAA;;;AA8DA;;AArDA;AAAA;AACA;AAAA;AAAA;AADA;AAIA;AAAA;AAAA;AAAA;AAAA;;;AAiDA;;AA7CA;AAAA;AAAA;AAEA;;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;;;AA0CA;;AAzCA;AAAA;AADA;;AA0CA;;AApCA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;AACA;AACA;AAAA;;;AAgCA;;AA/BA;AAAA;AADA;;AAgCA;;AA3BA;AAAA;AAAA;;;AA2BA;;AAxBA;AAAA;AAAA;;AACA;AAAA;AAAA;AACA;AACA;AADA;AACA;;;AAqBA;;AAnBA;AAAA;AACA;AACA;AADA;AACA;;;AAiBA;;;AAdA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;AAYA;;AAVA;;;;;;;AAUA;;;AAVA;AACA;AAAA;AACA;AAAA;;;AAQA;;AAPA;AAAA;AADA;;AAQA;;;;;;;;;;;;;;AA80CA;AACA;AAGA;AAAA;AA7DA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;;;;;AAuEA;;AAzMA;AAAA;AAAA;AAAA;AAoMA;;;AAKA;;AAJA;AAAA;;;AAIA;;;;;AAAA;;AA3NA;AAAA;AAAA;AAAA;AA+MA;;;AAYA;;AAzMA;AAAA;AAAA;AAAA;AA8LA;;;AAWA;;AAzMA;AAAA;AAAA;AAAA;AA+LA;;;AAUA;;AATA;AAAA;;;AASA;;;;AAAA;;;;;;;;;;;AA5uEA;AAAA;AAAA;AAAA;;;AAuCA;;AAnCA;AADA;AAAA;AAAA;AACA;;;AAmCA;;AAjCA;AAAA;AAAA;AAAA;;AAIA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA;AAAA;AAAA;AADA;AAAA;AACA;;;;;;;;AAgBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAjCA;AAAA;;AAiCA;;AAKA;;;;AAAA;;;;AAAA;;;AAAA;;;;;;;;;;;AAkqEA;AAEA;AAAA;;AAAA;AAAA;AAAA;;;;AA3BA;;;AAiCA;;AA/BA;AAAA;AAAA;AACA;;;AA8BA;;AA5BA;AAAA;AACA;AAAA;AAx0DA;AAAA;AAIA;;AAs0DA;AAAA;AAAA;AAAA;;AAEA;AACA;AADA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AACA;AADA;AACA;;;AAmBA;;;AAfA;AAAA;;AAeA;;;AAJA;AAAA;;AAGA;;AACA;;AAHA;;AAGA;;;;;;;;;;;;;;AA3jFA;AAGA;AAGA;;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;;;AASA;AAAA;AAAA;;AACA;AAAA;AACA;AAAA;;;AAEA;AAAA;AAAA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;;AAEA;;AAHA;;AAGA;;;;;AAhBA;AAAA;AAAA;AAAA;;;;;;;AA+vDA;AACA;AAAA;AAAA;AAGA;;;AACA;AAAA;AACA;AAAA;AADA;;;AAGA;AAAA;AAAA;;;AAWA;;AAXA;AAAA;AAAA;;;AAWA;;AAVA;AAAA;AAAA;AADA;AAAA;;;;;;AAWA;;;;AAJA;AAAA;AAAA;;;;;;AAIA;;;;;;AAAA;;;;;;AA4tBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;;;;;;;;AAv5BA;AAGA;AAAA;AAAA;;AASA;AAAA;AAAA;;AAIA;;AAZA;AAAA;AACA;;;;;AACA;AAAA;;;;;;;AAUA;;;;AAPA;AAAA;;AAOA;;;;;;;;;AAxiBA;AAAA;;AAEA;AAAA;AAAA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AA+2CA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAkBA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAZA;AAAA;AAAA;AAAA;AAAA;;;;;;AAz0BA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;AAkBA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAsBA;;;AAnBA;AACA;AAGA;AAAA;AA43BA;AAAA;AACA;AAAA;AACA;;;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAx3BA;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAmvBA;AAAA;AAAA;AAAA;AArvBA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AADA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAm3BA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AA/3BA;;AAquBA;AAAA;AAAA;AAAA;AApuBA;;AA4vBA;AAAA;AAAA;AAAA;AA3vBA;;AA2vBA;AAAA;AAAA;AAAA;AA1vBA;;AACA;AAAA;;;;;;;;;;;;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAOA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AA82BA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;AA1JA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAwBA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;AAzuBA;AAAA;AAAA;AAAA;AACA;AACA;AAthDA;AACA;AAAA;AAkhDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAkBA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAAA;;;;AAGA;AAAA;AAAA;;;;AAEA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;;;;;;;;;;AAOA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAEA;AACA;AAAA;AAAA;AAFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAOA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;AAqBA;AAAA;;AACA;AAAA;;AACA;AA9DA;AAAA;AAAA;AAAA;AACA;AACA;AAthDA;AACA;AAAA;AAkhDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsEA;AACA;AAIA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;;AACA;;;AAEA;AAAA;;AAIA;AACA;AAAA;;AAJA;;;;;;;;AAqGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAQA;AAAA;AAAA;AAAA;;;AACA;AADA;;;AAIA;;;;;;;;;;;;;;;;;AAMA;AAAA;;AAuBA;;AAh0DA;AAEA;AACA;AAAA;AAAA;AAAA;AACA;AAOA;AAgyDA;;;AAGA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;AAgBA;;AAdA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAeA;;;;AATA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;AAOA;;AALA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;AAMA;;;;AAAA;;;;;;;;;;;AAOA;AAEA;AAAA;AAAA;;AAaA;;AAXA;AAGA;AAAA;AAGA;AAAA;;AAKA;;AAFA;AAAA;AADA;AAAA;AACA;AAEA;;;;;;AAOA;AAAA;AAAA;AAAA;;;;;;AA0BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AAMA;AAAA;AAAA;AACA;;;;;;AAKA;AAAA;AAAA;AAAA;;;;;;;;;;;;;AAoBA;AAAA;AAAA;AA8iBA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAjjBA;;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA2ZA;AAAA;AAAA;AAAA;AA5ZA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;;;AAOA;;;AANA;AAAA;;AACA;;;;;AACA;AAiZA;AAAA;AAAA;AAAA;AAjZA;;;;;;AAEA;AALA;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAGA;;;;;;;;AAmZA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAhZA;AAEA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AADA;AAEA;AAAA;AAAA;;;;;;;;AA+WA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAwBA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAYA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AA8DA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAsCA;;AACA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;;;AA6FA;AAAA;AAAA;AACA;;;;;;;;ACj+FA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAIA;AAEA;AAGA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAIA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAaA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAIA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAIA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAsCA;AAIA;AAAA;;AAEA;;AADA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;AA4EA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAEA;AAAA;;AADA;AAAA;AACA;AAAA;;;;;;;;;;;AAUA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAEA;AAAA;;AADA;AAAA;AACA;AAAA;;;;;;;;;;;AAUA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAEA;AAAA;;AADA;AAAA;AACA;AAAA;;;;;;;;AAMA;AAEA;AAAA;AAAA;AACA;;AACA;AAAA;AAAA;;AACA;;;;;;;;;AAKA;AAnHA;AAAA;;AAEA;AAAA;AAiHA;;AAlHA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;AAwHA;AA9GA;AAAA;;AAEA;AA4GA;;AA7GA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAyIA;AAAA;AACA;AACA;;;;;;;AAOA;AAAA;AAAA;;AAEA;;AADA;AAAA;;;;;;;AAQA;AAAA;AAAA;;AAEA;;AADA;AAAA;;;;;;;AAQA;AAAA;AAAA;;AAEA;;AADA;AAAA;;;;;;;;;;;;;AAkBA;AACA;AAEA;AAAA;AAAA;AAAA;;;;;;;;;;;AASA;AACA;AAEA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACrNA;AACA;AAAA;;;AAEA;AAAA;;AACA;AAAA;;;;;AACA;;;;;AAIA;AACA;AACA;;AACA;;;;AAGA;AAAA;AAAA;AADA;AAAA;AAAA;AAAA;;;;;;AAMA;AAAA;;AACA;AAAA;;;AAsBA;;AAtBA;;AAsBA;;;;;;;;AApBA;AAAA;;;;AACA;AAAA;AAAA;AAxFA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;AAGA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;;;AAGA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;;;;AAGA;;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAEA;AAAA;AAAA;;;AAIA;AAAA;AAAA;AAAA;AAEA;;AAAA;AAAA;AAAA;;;;;;;;;;;AAEA;AAAA;AAAA;;;AAGA;;;;;;;;AACA;AAAA;AAEA;AAAA;;AACA;AAAA;;;;;AACA;AAAA;AAAA;;;;;;;AAEA;;;;AAAA;AACA;;;;;;AAAA;AAAA;AAAA;;AAKA;AAAA;AAAA;AACA;AACA;;;;;AANA;;;;AAkDA;AACA;AAAA;AADA;;;AAeA;;AAbA;;AAaA;;;AATA;AAAA;;AAMA;AACA;;AAEA;;AARA;AAAA;;;AAQA;;AANA;;AAMA;;;;;;;;;;AASA;AACA;AAGA;AACA;;;AAWA;;AANA;;;;;;;AACA;AAAA;;;;;;;;;;;AAEA;;AAGA;;;;;;;;;;;;;;;;;;;;ACgGA;AACA;AAAA;;;;AAUA;;;AACA;;AACA;;;AAGA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;;;;;AAIA;;;;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;AACA;ACvPA;AAAA;AAAA;AD4LA;AC5LA;AACA;AAAA;AAAA;AD2LA;AC3LA;AACA;AAAA;AAAA;AD0LA;AC1LA;AAEA;AAAA;AAAA;ADwLA;ACxLA;AAEA;AAAA;AAAA;ADsLA;ACtLA;AAEA;AAAA;AAAA;ADoLA;ACpLA;AAGA;AAAA;AAAA;ADiLA;ACjLA;AAEA;AAAA;AAAA;AD+KA;AC/KA;AACA;AAAA;AAAA;AD8KA;AC9KA;AAEA;AAAA;AAAA;AD4KA;AC5KA;AAMA;AAAA;AAAA;ADsKA;ACtKA;AAGA;AAAA;AAAA;ADmKA;ACnKA;AAGA;AAAA;AAAA;ADgKA;AChKA;AAYA;AAAA;AAAA;ADoJA;ACpJA;AAIA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;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AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAiGA;AAxGA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAmGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAhBA;AAAA;AAAA;AAgBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;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AA;;;;;AAAA;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;;;;;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAAA;;;;AAAA;;;;;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAAA;;;;;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;;;AAAA;;;;;;AAAA;;;;;;;AAAA;AAAA;;;AAoFA;AAAA;AACA;AAHA;;;;;;;;AAKA;AAAA;;;;;;;AA2BA;;;;;;;;;;;;;;;;;;;;AAxGA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAAA;AAAA;AAAA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;;;;;AAAA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;;;;;;AAAA;;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAAA;;;;;;AAAA;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;;;AAAA;AAAA;AAAA;AAAA;;;;;;;AAAA;;;;;;AAAA;;;;;;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAAA;;;;;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;;;;AAAA;;;;;AAAA;;;;;;;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;AAnBA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAAA;AAAA;AAAA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;;;;;AAAA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;;;;;;AAAA;;AAAA;;;;AAAA;AAAA;AAAA;;AAAA;;;;AAAA;AAAA;;;;;;AAAA;;;;;;AAAA;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;;;;;;AAAA;AAAA;AAAA;;;;AAAA;AAAA;AAAA;;;;;;;;;AAAA;AAAA;AAAA;AAAA;;;;;;;AAAA;;;;;;AAAA;;;;;;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;;;;AAAA;;;;;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;;AAAA;AAAA;;;;;AAAA;AAAA;;;;AAAA;;;;;AAAA;;;;;;;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;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;;;;;;;;AAEA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;;;;;AAqBA;;;;AAEA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AACA;;AAAA;AAAA;AAAA;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AAjCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AALA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AACA;AANA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AACA;AANA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AACA;AANA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;;;;;;;;;AAyBA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAJA;AAIA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAJA;AAIA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAJA;AAIA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;;;ACpGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AADA;AAAA;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;AAKA;;AAAA;AAAA;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA;;AAyHA;;AAvHA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;;AAGA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;AAsBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AARA;AAAA;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;;;;AA1FA;AAmGA;AACA;;;AATA;AAAA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;AAEA;AACA;AAOA;;;;;;;;;;;;;ACjHA;AAAA;AAAA;AAAA;AAAA;;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAtKA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AA2BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AA2BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AA2BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AA2BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AA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;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;AAkLA;;;;;;;;;;;AAvJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;AAuLA;;;;;;;;;;;AA5JA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;AA4LA;;;;;;;;;;;AAjKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;AAiMA;;;;;;;;;;;AAtKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;AAuDA;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;;;;;;;;AACA;AACA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAEA;AAAA;AATA;;;;;;;;;AAzDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;;;;;AA2BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;AACA;AAAA;AAJA;AAAA;;;;;;;;;AA7BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AACA;AAAA;AAAA;AA0MA;;;;;;;;;;;AC3JA;AAAA;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;AAEA;AACA;;;AACA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AAAA;AAAA;;;;;;;AAHA;AACA;;;;;;;;;AAMA;AARA;;;;;;;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIA;AAiBA;AAAA;;AACA;AACA;AAGA;AAGA;AACA;AAEA;AACA;;AARA;AACA;AAGA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;ACxEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;ADCA;ACKA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ADPA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACqBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;;;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;AAsBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AARA;AAAA;;;;;;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAqBA;AACA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAIA;;;;;;AAWA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;;;;;AAWA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;;AACA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;;;;AACA;AAAA;AADA;AAAA;AAAA;;;;;;;;;;;;;;AAMA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;AAaA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAzBA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;AACA;AADA;AAAA;AACA;;;;;;AAOA;AAAA;AAAA;AAAA;AAkBA;AAAA;AA7BA;AAAA;AAAA;;;;;;;AACA;AAAA;AACA;AAAA;AACA;;AAAA;AAAA;AACA;;;;;AAOA;AAAA;AAAA;AAAA;AAkBA;AAAA;AAAA;AA7BA;AAAA;AAAA;;;;;;;;;AACA;AAAA;AACA;AAAA;AACA;;;AAQA;AAAA;AAAA;AAAA;AAqBA;;AA5BA;AADA;AAAA;AACA;;AAOA;AAAA;AAAA;AAAA;AAqBA;;;;;;;AAOA;;;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAAA;AAAA;AADA;AAAA;;;;;;;AAIA;AACA;;;;;;ACiHA;;AAMA;;AAJA;AAEA;AAAA;AACA;AAAA;AACA;;;;;;;;;;;;;;;;;;;AA6FA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAIA;;AAXA;AAcA;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAIA;AAGA;;;;;;;;;AAnCA;AAAA;;;AAsCA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;;;;;;;;;;;AAUA;;AAsCA;;AAnCA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;AAEA;AAEA;;;AAEA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;;;;AAGA;AACA;AAAA;AAAA;AAAA;AAoBA;;;AAdA;;AAAA;AAAA;AAAA;;;AAEA;AACA;AAAA;AAAA;AACA;AACA;AALA;;;;;;;AAAA;AAAA;;;;;AAOA;;AAOA;;AAJA;AAAA;AADA;AAAA;AACA;AAAA;AAAA;AAIA;;;;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AACA;;;;AAqBA;AAGA;;;AAtBA;AAAA;AAAA;AAEA;;AAEA;AACA;AADA;;;;AAGA;;AAEA;AADA;AAAA;;AAIA;AAGA;;;;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAIA;;;;;;;;AAKA;AAGA;;AAYA;;;;;AANA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AADA;;;;;;;;AACA;AAAA;;AAIA;AAEA;;;;;;AAOA;;AAMA;;AAJA;AAEA;AAAA;AACA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;AA8FA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAIA;;AAXA;AAcA;;;;;;;;;AAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;AAJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAIA;AAGA;;;;;;;;;AAnCA;AAAA;;;AAsCA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAIA;;;;;;;;;;;AAUA;;AAsCA;;AAnCA;AAAA;AAAA;AAAA;AAAA;AACA;;;;;AAEA;AAEA;;;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AAAA;;;;AAGA;AACA;AAAA;AAAA;AAAA;AAAA;;AAoBA;;AApBA;AAAA;AAAA;AAAA;AAoBA;;;AAdA;;;AAAA;AAAA;AAAA;;;AAEA;AACA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AACA;AACA;AALA;;;;;;;AAAA;AAAA;;;;;AAOA;;AAOA;;AALA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAIA;;AAJA;AAAA;AAAA;AAAA;AAIA;;;;;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AACA;;;;AAmBA;AAGA;;;AApBA;AAAA;AAAA;AAEA;;AAEA;AAAA;AAAA;;;;AAEA;;AACA;AAAA;AAAA;;AAGA;AAGA;;;;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA;AAIA;;;;;;;;;AAKA;AAGA;;AAYA;;;;;AANA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AADA;;;;;;;;AACA;AAAA;;AAIA;AAEA;;;;;;AAOA;;AAMA;;AAJA;AAEA;AAAA;AACA;AAAA;AACA;;;;;;;;AAiBA;AACA;;;;;;;;;AAKA;AASA;;AAaA;AACA;;;;;AARA;AAAA;AAAA;AAAA;AAAA;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AADA;;;;;;;;;AACA;AAAA;;;AAOA;AACA;;;;;;;ACjyBA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;;;;;AAOA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAGA;;;;AACA;;;;AACA;AAAA;AAAA;AACA;;;AAKA;AAAA;;;;;;AACA;AAAA;AADA;AAAA;;;;;;;;;;AAKA;;AAEA;;AADA;AAAA;AAAA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AALA;AAKA;AAAA;AAAA;AACA;AApGA;AAoGA;AAAA;AAAA;AACA;AACA;;;;;;;;;;;AA1OA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AACA;AACA;AADA;AAEA;AArCA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAGA;;;;AACA;;;;AACA;AAAA;AAAA;AACA;;;AAKA;AAAA;;;;;;AACA;AAAA;AADA;AAAA;;;;;;;;;;AAKA;;AACA;AAAA;AAAA;AAAA;;AAnBA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAGA;;;;;AACA;;;;;AACA;AAAA;AAAA;AACA;AAUA;AACA;AAAA;;;;AAoBA;;;;;AApBA;;;AAAA;AAoBA;;;;;;;;;;AAOA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;;;;;;AC3GA;AAAA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;;;;;AAYA;AAAA;AAAA;AAAA;AAAA;AACA;AAGA;AAAA;AAAA;AAAA;AAEA;;;;AACA;;;;AAIA;AADA;AAFA;AAAA;AAAA;AACA;;;AAOA;;AAAA;AAAA;AAAA;AAAA;;;AACA;AACA;AACA;AAHA;;;;;;;AAAA;;;;;;AAQA;;AAEA;;AADA;AAAA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AAHA;AAGA;AAAA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;;;;;;;;;;;;AAzIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","sourcesContent":["/* $OpenBSD: ssh.c,v 1.451 2017/03/10 04:07:20 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Ssh client program. This program can be used to log into a remote machine.\n * The software supports strong authentication, encryption, and forwarding\n * of X11, TCP/IP, and authentication connections.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n *\n * Copyright (c) 1999 Niels Provos. All rights reserved.\n * Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved.\n *\n * Modified to work with SSL by Niels Provos \n * in Canada (German citizen).\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#ifdef HAVE_SYS_STAT_H\n# include \n#endif\n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#ifdef HAVE_PATHS_H\n#include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n\n#ifdef WITH_OPENSSL\n#include \n#include \n#endif\n#include \"openbsd-compat/openssl-compat.h\"\n#include \"openbsd-compat/sys-queue.h\"\n\n#include \"xmalloc.h\"\n#include \"ssh.h\"\n#include \"ssh1.h\"\n#include \"ssh2.h\"\n#include \"canohost.h\"\n#include \"compat.h\"\n#include \"cipher.h\"\n#include \"digest.h\"\n#include \"packet.h\"\n#include \"buffer.h\"\n#include \"channels.h\"\n#include \"key.h\"\n#include \"authfd.h\"\n#include \"authfile.h\"\n#include \"pathnames.h\"\n#include \"dispatch.h\"\n#include \"clientloop.h\"\n#include \"log.h\"\n#include \"misc.h\"\n#include \"readconf.h\"\n#include \"sshconnect.h\"\n#include \"kex.h\"\n#include \"mac.h\"\n#include \"sshpty.h\"\n#include \"match.h\"\n#include \"msg.h\"\n#include \"uidswap.h\"\n#include \"version.h\"\n#include \"ssherr.h\"\n#include \"myproposal.h\"\n#include \"utf8.h\"\n\n#ifdef ENABLE_PKCS11\n#include \"ssh-pkcs11.h\"\n#endif\n\nstruct passwd* getpwuid(uid_t uid) { // NOLINT(runtime/threadsafe_fn)\n static struct passwd pwd;\n pwd.pw_name = (char*)\"\";\n pwd.pw_passwd = (char*)\"\";\n pwd.pw_uid = 0;\n pwd.pw_gid = 0;\n pwd.pw_gecos = (char*)\"\";\n pwd.pw_dir = (char*)\"\";\n pwd.pw_shell = (char*)\"\";\n return &pwd;\n}\n\nextern char *__progname;\n\n/* Saves a copy of argv for setproctitle emulation */\n#ifndef HAVE_SETPROCTITLE\nstatic char **saved_av;\n#endif\n\n/* Flag indicating whether debug mode is on. May be set on the command line. */\nint debug_flag = 0;\n\n/* Flag indicating whether a tty should be requested */\nint tty_flag = 0;\n\n/* don't exec a shell */\nint no_shell_flag = 0;\n\n/*\n * Flag indicating that nothing should be read from stdin. This can be set\n * on the command line.\n */\nint stdin_null_flag = 0;\n\n/*\n * Flag indicating that the current process should be backgrounded and\n * a new slave launched in the foreground for ControlPersist.\n */\nint need_controlpersist_detach = 0;\n\n/* Copies of flags for ControlPersist foreground slave */\nint ostdin_null_flag, ono_shell_flag, otty_flag, orequest_tty;\n\n/*\n * Flag indicating that ssh should fork after authentication. This is useful\n * so that the passphrase can be entered manually, and then ssh goes to the\n * background.\n */\nint fork_after_authentication_flag = 0;\n\n/*\n * General data structure for command line options and options configurable\n * in configuration files. See readconf.h.\n */\nOptions options;\n\n/* optional user configfile */\nchar *config = NULL;\n\n/*\n * Name of the host we are connecting to. This is the name given on the\n * command line, or the HostName specified for the user-supplied name in a\n * configuration file.\n */\nchar *host;\n\n/* socket address the host resolves to */\nstruct sockaddr_storage hostaddr;\n\n/* Private host keys. */\nSensitive sensitive_data;\n\n/* Original real UID. */\nuid_t original_real_uid;\nuid_t original_effective_uid;\n\n/* command to be executed */\nBuffer command;\n\n/* Should we execute a command or invoke a subsystem? */\nint subsystem_flag = 0;\n\n/* # of replies received for global requests */\nstatic int remote_forward_confirms_received = 0;\n\n/* mux.c */\nextern int muxserver_sock;\nextern u_int muxclient_command;\n\n/* Prints a help message to the user. This function never returns. */\n\nstatic void\nusage(void)\n{\n\tfprintf(stderr,\n\"usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\\n\"\n\" [-D [bind_address:]port] [-E log_file] [-e escape_char]\\n\"\n\" [-F configfile] [-I pkcs11] [-i identity_file]\\n\"\n\" [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\\n\"\n\" [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]\\n\"\n\" [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]\\n\"\n\" [user@]hostname [command]\\n\"\n\t);\n\texit(255);\n}\n\nstatic int ssh_session(void);\nstatic int ssh_session2(void);\nstatic void load_public_identity_files(void);\nstatic void main_sigchld_handler(int);\n\n/* ~/ expand a list of paths. NB. assumes path[n] is heap-allocated. */\nstatic void\ntilde_expand_paths(char **paths, u_int num_paths)\n{\n\tu_int i;\n\tchar *cp;\n\n\tfor (i = 0; i < num_paths; i++) {\n\t\tcp = tilde_expand_filename(paths[i], original_real_uid);\n\t\tfree(paths[i]);\n\t\tpaths[i] = cp;\n\t}\n}\n\n/*\n * Attempt to resolve a host name / port to a set of addresses and\n * optionally return any CNAMEs encountered along the way.\n * Returns NULL on failure.\n * NB. this function must operate with a options having undefined members.\n */\nstatic struct addrinfo *\nresolve_host(const char *name, int port, int logerr, char *cname, size_t clen)\n{\n\tchar strport[NI_MAXSERV];\n\tstruct addrinfo hints, *res;\n\tint gaierr, loglevel = SYSLOG_LEVEL_DEBUG1;\n\n\tif (port <= 0)\n\t\tport = default_ssh_port();\n\n\tsnprintf(strport, sizeof strport, \"%d\", port);\n\tmemset(&hints, 0, sizeof(hints));\n\thints.ai_family = options.address_family == -1 ?\n\t AF_UNSPEC : options.address_family;\n\thints.ai_socktype = SOCK_STREAM;\n\tif (cname != NULL)\n\t\thints.ai_flags = AI_CANONNAME;\n\tif ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) {\n\t\tif (logerr || (gaierr != EAI_NONAME && gaierr != EAI_NODATA))\n\t\t\tloglevel = SYSLOG_LEVEL_ERROR;\n\t\tdo_log2(loglevel, \"%s: Could not resolve hostname %.100s: %s\",\n\t\t __progname, name, ssh_gai_strerror(gaierr));\n\t\treturn NULL;\n\t}\n\tif (cname != NULL && res->ai_canonname != NULL) {\n\t\tif (strlcpy(cname, res->ai_canonname, clen) >= clen) {\n\t\t\terror(\"%s: host \\\"%s\\\" cname \\\"%s\\\" too long (max %lu)\",\n\t\t\t __func__, name, res->ai_canonname, (u_long)clen);\n\t\t\tif (clen > 0)\n\t\t\t\t*cname = '\\0';\n\t\t}\n\t}\n\treturn res;\n}\n\n/*\n * Attempt to resolve a numeric host address / port to a single address.\n * Returns a canonical address string.\n * Returns NULL on failure.\n * NB. this function must operate with a options having undefined members.\n */\nstatic struct addrinfo *\nresolve_addr(const char *name, int port, char *caddr, size_t clen)\n{\n\tchar addr[NI_MAXHOST], strport[NI_MAXSERV];\n\tstruct addrinfo hints, *res;\n\tint gaierr;\n\n\tif (port <= 0)\n\t\tport = default_ssh_port();\n\tsnprintf(strport, sizeof strport, \"%u\", port);\n\tmemset(&hints, 0, sizeof(hints));\n\thints.ai_family = options.address_family == -1 ?\n\t AF_UNSPEC : options.address_family;\n\thints.ai_socktype = SOCK_STREAM;\n\thints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV;\n\tif ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) {\n\t\tdebug2(\"%s: could not resolve name %.100s as address: %s\",\n\t\t __func__, name, ssh_gai_strerror(gaierr));\n\t\treturn NULL;\n\t}\n\tif (res == NULL) {\n\t\tdebug(\"%s: getaddrinfo %.100s returned no addresses\",\n\t\t __func__, name);\n\t\treturn NULL;\n\t}\n\tif (res->ai_next != NULL) {\n\t\tdebug(\"%s: getaddrinfo %.100s returned multiple addresses\",\n\t\t __func__, name);\n\t\tgoto fail;\n\t}\n\tif ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen,\n\t addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) {\n\t\tdebug(\"%s: Could not format address for name %.100s: %s\",\n\t\t __func__, name, ssh_gai_strerror(gaierr));\n\t\tgoto fail;\n\t}\n\tif (strlcpy(caddr, addr, clen) >= clen) {\n\t\terror(\"%s: host \\\"%s\\\" addr \\\"%s\\\" too long (max %lu)\",\n\t\t __func__, name, addr, (u_long)clen);\n\t\tif (clen > 0)\n\t\t\t*caddr = '\\0';\n fail:\n\t\tfreeaddrinfo(res);\n\t\treturn NULL;\n\t}\n\treturn res;\n}\n\n/*\n * Check whether the cname is a permitted replacement for the hostname\n * and perform the replacement if it is.\n * NB. this function must operate with a options having undefined members.\n */\nstatic int\ncheck_follow_cname(int direct, char **namep, const char *cname)\n{\n\tint i;\n\tstruct allowed_cname *rule;\n\n\tif (*cname == '\\0' || options.num_permitted_cnames == 0 ||\n\t strcmp(*namep, cname) == 0)\n\t\treturn 0;\n\tif (options.canonicalize_hostname == SSH_CANONICALISE_NO)\n\t\treturn 0;\n\t/*\n\t * Don't attempt to canonicalize names that will be interpreted by\n\t * a proxy or jump host unless the user specifically requests so.\n\t */\n\tif (!direct &&\n\t options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)\n\t\treturn 0;\n\tdebug3(\"%s: check \\\"%s\\\" CNAME \\\"%s\\\"\", __func__, *namep, cname);\n\tfor (i = 0; i < options.num_permitted_cnames; i++) {\n\t\trule = options.permitted_cnames + i;\n\t\tif (match_pattern_list(*namep, rule->source_list, 1) != 1 ||\n\t\t match_pattern_list(cname, rule->target_list, 1) != 1)\n\t\t\tcontinue;\n\t\tverbose(\"Canonicalized DNS aliased hostname \"\n\t\t \"\\\"%s\\\" => \\\"%s\\\"\", *namep, cname);\n\t\tfree(*namep);\n\t\t*namep = xstrdup(cname);\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n/*\n * Attempt to resolve the supplied hostname after applying the user's\n * canonicalization rules. Returns the address list for the host or NULL\n * if no name was found after canonicalization.\n * NB. this function must operate with a options having undefined members.\n */\nstatic struct addrinfo *\nresolve_canonicalize(char **hostp, int port)\n{\n\tint i, direct, ndots;\n\tchar *cp, *fullhost, newname[NI_MAXHOST];\n\tstruct addrinfo *addrs;\n\n\tif (options.canonicalize_hostname == SSH_CANONICALISE_NO)\n\t\treturn NULL;\n\n\t/*\n\t * Don't attempt to canonicalize names that will be interpreted by\n\t * a proxy unless the user specifically requests so.\n\t */\n\tdirect = option_clear_or_none(options.proxy_command) &&\n\t options.jump_host == NULL;\n\tif (!direct &&\n\t options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)\n\t\treturn NULL;\n\n\t/* Try numeric hostnames first */\n\tif ((addrs = resolve_addr(*hostp, port,\n\t newname, sizeof(newname))) != NULL) {\n\t\tdebug2(\"%s: hostname %.100s is address\", __func__, *hostp);\n\t\tif (strcasecmp(*hostp, newname) != 0) {\n\t\t\tdebug2(\"%s: canonicalised address \\\"%s\\\" => \\\"%s\\\"\",\n\t\t\t __func__, *hostp, newname);\n\t\t\tfree(*hostp);\n\t\t\t*hostp = xstrdup(newname);\n\t\t}\n\t\treturn addrs;\n\t}\n\n\t/* If domain name is anchored, then resolve it now */\n\tif ((*hostp)[strlen(*hostp) - 1] == '.') {\n\t\tdebug3(\"%s: name is fully qualified\", __func__);\n\t\tfullhost = xstrdup(*hostp);\n\t\tif ((addrs = resolve_host(fullhost, port, 0,\n\t\t newname, sizeof(newname))) != NULL)\n\t\t\tgoto found;\n\t\tfree(fullhost);\n\t\tgoto notfound;\n\t}\n\n\t/* Don't apply canonicalization to sufficiently-qualified hostnames */\n\tndots = 0;\n\tfor (cp = *hostp; *cp != '\\0'; cp++) {\n\t\tif (*cp == '.')\n\t\t\tndots++;\n\t}\n\tif (ndots > options.canonicalize_max_dots) {\n\t\tdebug3(\"%s: not canonicalizing hostname \\\"%s\\\" (max dots %d)\",\n\t\t __func__, *hostp, options.canonicalize_max_dots);\n\t\treturn NULL;\n\t}\n\t/* Attempt each supplied suffix */\n\tfor (i = 0; i < options.num_canonical_domains; i++) {\n\t\t*newname = '\\0';\n\t\txasprintf(&fullhost, \"%s.%s.\", *hostp,\n\t\t options.canonical_domains[i]);\n\t\tdebug3(\"%s: attempting \\\"%s\\\" => \\\"%s\\\"\", __func__,\n\t\t *hostp, fullhost);\n\t\tif ((addrs = resolve_host(fullhost, port, 0,\n\t\t newname, sizeof(newname))) == NULL) {\n\t\t\tfree(fullhost);\n\t\t\tcontinue;\n\t\t}\n found:\n\t\t/* Remove trailing '.' */\n\t\tfullhost[strlen(fullhost) - 1] = '\\0';\n\t\t/* Follow CNAME if requested */\n\t\tif (!check_follow_cname(direct, &fullhost, newname)) {\n\t\t\tdebug(\"Canonicalized hostname \\\"%s\\\" => \\\"%s\\\"\",\n\t\t\t *hostp, fullhost);\n\t\t}\n\t\tfree(*hostp);\n\t\t*hostp = fullhost;\n\t\treturn addrs;\n\t}\n notfound:\n\tif (!options.canonicalize_fallback_local)\n\t\tfatal(\"%s: Could not resolve host \\\"%s\\\"\", __progname, *hostp);\n\tdebug2(\"%s: host %s not found in any suffix\", __func__, *hostp);\n\treturn NULL;\n}\n\n/*\n * Read per-user configuration file. Ignore the system wide config\n * file if the user specifies a config file on the command line.\n */\nstatic void\nprocess_config_files(const char *host_arg, struct passwd *pw, int post_canon)\n{\n\tchar buf[PATH_MAX];\n\tint r;\n\n\tif (config != NULL) {\n\t\tif (strcasecmp(config, \"none\") != 0 &&\n\t\t !read_config_file(config, pw, host, host_arg, &options,\n\t\t SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0)))\n\t\t\tfatal(\"Can't open user config file %.100s: \"\n\t\t\t \"%.100s\", config, strerror(errno));\n\t} else {\n\t\tr = snprintf(buf, sizeof buf, \"%s/%s\", pw->pw_dir,\n\t\t _PATH_SSH_USER_CONFFILE);\n\t\tif (r > 0 && (size_t)r < sizeof(buf))\n\t\t\t(void)read_config_file(buf, pw, host, host_arg,\n\t\t\t &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF |\n\t\t\t (post_canon ? SSHCONF_POSTCANON : 0));\n\n\t\t/* Read systemwide configuration file after user config. */\n\t\t(void)read_config_file(_PATH_HOST_CONFIG_FILE, pw,\n\t\t host, host_arg, &options,\n\t\t post_canon ? SSHCONF_POSTCANON : 0);\n\t}\n}\n\n/* Rewrite the port number in an addrinfo list of addresses */\nstatic void\nset_addrinfo_port(struct addrinfo *addrs, int port)\n{\n\tstruct addrinfo *addr;\n\n\tfor (addr = addrs; addr != NULL; addr = addr->ai_next) {\n\t\tswitch (addr->ai_family) {\n\t\tcase AF_INET:\n\t\t\t((struct sockaddr_in *)addr->ai_addr)->\n\t\t\t sin_port = htons(port);\n\t\t\tbreak;\n\t\tcase AF_INET6:\n\t\t\t((struct sockaddr_in6 *)addr->ai_addr)->\n\t\t\t sin6_port = htons(port);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*\n * Main program for the ssh client.\n */\nint\nmain(int ac, char **av)\n{\n\tstruct ssh *ssh = NULL;\n\tint i, r, opt, exit_status, use_syslog, direct, config_test = 0;\n\tchar *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile;\n\tchar thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];\n\tchar cname[NI_MAXHOST], uidstr[32], *conn_hash_hex;\n\tstruct stat st;\n\tstruct passwd *pw;\n\tint timeout_ms;\n\textern int optind, optreset;\n\textern char *optarg;\n\tstruct Forward fwd;\n\tstruct addrinfo *addrs = NULL;\n\tstruct ssh_digest_ctx *md;\n\tu_char conn_hash[SSH_DIGEST_MAX_LENGTH];\n\n\tssh_malloc_init();\t/* must be called before any mallocs */\n\t/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */\n\tsanitise_stdfd();\n\nac = 2;\nav = xcalloc(ac + 1, sizeof(*av));\nav[0] = \"ssh\";\nav[1] = \"localhost\";\nav[2] = NULL;\n\n\t__progname = ssh_get_progname(av[0]);\n\n#ifndef HAVE_SETPROCTITLE\n\t/* Prepare for later setproctitle emulation */\n\t/* Save argv so it isn't clobbered by setproctitle() emulation */\n\tsaved_av = xcalloc(ac + 1, sizeof(*saved_av));\n\tfor (i = 0; i < ac; i++)\n\t\tsaved_av[i] = xstrdup(av[i]);\n\tsaved_av[i] = NULL;\n\tcompat_init_setproctitle(ac, av);\n\tav = saved_av;\n#endif\n\n\t/*\n\t * Discard other fds that are hanging around. These can cause problem\n\t * with backgrounded ssh processes started by ControlPersist.\n\t */\n\tclosefrom(STDERR_FILENO + 1);\n\n\t/*\n\t * Save the original real uid. It will be needed later (uid-swapping\n\t * may clobber the real uid).\n\t */\n\toriginal_real_uid = getuid();\n\toriginal_effective_uid = geteuid();\n\n\t/*\n\t * Use uid-swapping to give up root privileges for the duration of\n\t * option processing. We will re-instantiate the rights when we are\n\t * ready to create the privileged port, and will permanently drop\n\t * them when the port has been created (actually, when the connection\n\t * has been made, as we may need to create the port several times).\n\t */\n\tPRIV_END;\n\n#ifdef HAVE_SETRLIMIT\n\t/* If we are installed setuid root be careful to not drop core. */\n\tif (original_real_uid != original_effective_uid) {\n\t\tstruct rlimit rlim;\n\t\trlim.rlim_cur = rlim.rlim_max = 0;\n\t\tif (setrlimit(RLIMIT_CORE, &rlim) < 0)\n\t\t\tfatal(\"setrlimit failed: %.100s\", strerror(errno));\n\t}\n#endif\n\t/* Get user data. */\n\tpw = getpwuid(original_real_uid);\n\tif (!pw) {\n\t\tlogit(\"No user exists for uid %lu\", (u_long)original_real_uid);\n\t\texit(255);\n\t}\n\t/* Take a copy of the returned structure. */\n\tpw = pwcopy(pw);\n\n\t/*\n\t * Set our umask to something reasonable, as some files are created\n\t * with the default umask. This will make them world-readable but\n\t * writable only by the owner, which is ok for all files for which we\n\t * don't set the modes explicitly.\n\t */\n\tumask(022);\n\n\tmsetlocale();\n\n\t/*\n\t * Initialize option structure to indicate that no values have been\n\t * set.\n\t */\n\tinitialize_options(&options);\n\n\t/* Parse command-line arguments. */\n\thost = NULL;\n\tuse_syslog = 0;\n\tlogfile = NULL;\n\targv0 = av[0];\n\n again:\n\twhile ((opt = getopt(ac, av, \"1246ab:c:e:fgi:kl:m:no:p:qstvx\"\n\t \"ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy\")) != -1) {\n\t\tswitch (opt) {\n\t\tcase '1':\n\t\t\toptions.protocol = SSH_PROTO_1;\n\t\t\tbreak;\n\t\tcase '2':\n\t\t\toptions.protocol = SSH_PROTO_2;\n\t\t\tbreak;\n\t\tcase '4':\n\t\t\toptions.address_family = AF_INET;\n\t\t\tbreak;\n\t\tcase '6':\n\t\t\toptions.address_family = AF_INET6;\n\t\t\tbreak;\n\t\tcase 'n':\n\t\t\tstdin_null_flag = 1;\n\t\t\tbreak;\n\t\tcase 'f':\n\t\t\tfork_after_authentication_flag = 1;\n\t\t\tstdin_null_flag = 1;\n\t\t\tbreak;\n\t\tcase 'x':\n\t\t\toptions.forward_x11 = 0;\n\t\t\tbreak;\n\t\tcase 'X':\n\t\t\toptions.forward_x11 = 1;\n\t\t\tbreak;\n\t\tcase 'y':\n\t\t\tuse_syslog = 1;\n\t\t\tbreak;\n\t\tcase 'E':\n\t\t\tlogfile = optarg;\n\t\t\tbreak;\n\t\tcase 'G':\n\t\t\tconfig_test = 1;\n\t\t\tbreak;\n\t\tcase 'Y':\n\t\t\toptions.forward_x11 = 1;\n\t\t\toptions.forward_x11_trusted = 1;\n\t\t\tbreak;\n\t\tcase 'g':\n\t\t\toptions.fwd_opts.gateway_ports = 1;\n\t\t\tbreak;\n\t\tcase 'O':\n\t\t\tif (options.stdio_forward_host != NULL)\n\t\t\t\tfatal(\"Cannot specify multiplexing \"\n\t\t\t\t \"command with -W\");\n\t\t\telse if (muxclient_command != 0)\n\t\t\t\tfatal(\"Multiplexing command already specified\");\n\t\t\tif (strcmp(optarg, \"check\") == 0)\n\t\t\t\tmuxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;\n\t\t\telse if (strcmp(optarg, \"forward\") == 0)\n\t\t\t\tmuxclient_command = SSHMUX_COMMAND_FORWARD;\n\t\t\telse if (strcmp(optarg, \"exit\") == 0)\n\t\t\t\tmuxclient_command = SSHMUX_COMMAND_TERMINATE;\n\t\t\telse if (strcmp(optarg, \"stop\") == 0)\n\t\t\t\tmuxclient_command = SSHMUX_COMMAND_STOP;\n\t\t\telse if (strcmp(optarg, \"cancel\") == 0)\n\t\t\t\tmuxclient_command = SSHMUX_COMMAND_CANCEL_FWD;\n\t\t\telse if (strcmp(optarg, \"proxy\") == 0)\n\t\t\t\tmuxclient_command = SSHMUX_COMMAND_PROXY;\n\t\t\telse\n\t\t\t\tfatal(\"Invalid multiplex command.\");\n\t\t\tbreak;\n\t\tcase 'P':\t/* deprecated */\n\t\t\toptions.use_privileged_port = 0;\n\t\t\tbreak;\n\t\tcase 'Q':\n\t\t\tcp = NULL;\n\t\t\tif (strcmp(optarg, \"cipher\") == 0)\n\t\t\t\tcp = cipher_alg_list('\\n', 0);\n\t\t\telse if (strcmp(optarg, \"cipher-auth\") == 0)\n\t\t\t\tcp = cipher_alg_list('\\n', 1);\n\t\t\telse if (strcmp(optarg, \"mac\") == 0)\n\t\t\t\tcp = mac_alg_list('\\n');\n\t\t\telse if (strcmp(optarg, \"kex\") == 0)\n\t\t\t\tcp = kex_alg_list('\\n');\n\t\t\telse if (strcmp(optarg, \"key\") == 0)\n\t\t\t\tcp = sshkey_alg_list(0, 0, 0, '\\n');\n\t\t\telse if (strcmp(optarg, \"key-cert\") == 0)\n\t\t\t\tcp = sshkey_alg_list(1, 0, 0, '\\n');\n\t\t\telse if (strcmp(optarg, \"key-plain\") == 0)\n\t\t\t\tcp = sshkey_alg_list(0, 1, 0, '\\n');\n\t\t\telse if (strcmp(optarg, \"protocol-version\") == 0) {\n#ifdef WITH_SSH1\n\t\t\t\tcp = xstrdup(\"1\\n2\");\n#else\n\t\t\t\tcp = xstrdup(\"2\");\n#endif\n\t\t\t}\n\t\t\tif (cp == NULL)\n\t\t\t\tfatal(\"Unsupported query \\\"%s\\\"\", optarg);\n\t\t\tprintf(\"%s\\n\", cp);\n\t\t\tfree(cp);\n\t\t\texit(0);\n\t\t\tbreak;\n\t\tcase 'a':\n\t\t\toptions.forward_agent = 0;\n\t\t\tbreak;\n\t\tcase 'A':\n\t\t\toptions.forward_agent = 1;\n\t\t\tbreak;\n\t\tcase 'k':\n\t\t\toptions.gss_deleg_creds = 0;\n\t\t\tbreak;\n\t\tcase 'K':\n\t\t\toptions.gss_authentication = 1;\n\t\t\toptions.gss_deleg_creds = 1;\n\t\t\tbreak;\n\t\tcase 'i':\n\t\t\tp = tilde_expand_filename(optarg, original_real_uid);\n\t\t\tif (stat(p, &st) < 0)\n\t\t\t\tfprintf(stderr, \"Warning: Identity file %s \"\n\t\t\t\t \"not accessible: %s.\\n\", p,\n\t\t\t\t strerror(errno));\n\t\t\telse\n\t\t\t\tadd_identity_file(&options, NULL, p, 1);\n\t\t\tfree(p);\n\t\t\tbreak;\n\t\tcase 'I':\n#ifdef ENABLE_PKCS11\n\t\t\tfree(options.pkcs11_provider);\n\t\t\toptions.pkcs11_provider = xstrdup(optarg);\n#else\n\t\t\tfprintf(stderr, \"no support for PKCS#11.\\n\");\n#endif\n\t\t\tbreak;\n\t\tcase 'J':\n\t\t\tif (options.jump_host != NULL)\n\t\t\t\tfatal(\"Only a single -J option permitted\");\n\t\t\tif (options.proxy_command != NULL)\n\t\t\t\tfatal(\"Cannot specify -J with ProxyCommand\");\n\t\t\tif (parse_jump(optarg, &options, 1) == -1)\n\t\t\t\tfatal(\"Invalid -J argument\");\n\t\t\toptions.proxy_command = xstrdup(\"none\");\n\t\t\tbreak;\n\t\tcase 't':\n\t\t\tif (options.request_tty == REQUEST_TTY_YES)\n\t\t\t\toptions.request_tty = REQUEST_TTY_FORCE;\n\t\t\telse\n\t\t\t\toptions.request_tty = REQUEST_TTY_YES;\n\t\t\tbreak;\n\t\tcase 'v':\n\t\t\tif (debug_flag == 0) {\n\t\t\t\tdebug_flag = 1;\n\t\t\t\toptions.log_level = SYSLOG_LEVEL_DEBUG1;\n\t\t\t} else {\n\t\t\t\tif (options.log_level < SYSLOG_LEVEL_DEBUG3) {\n\t\t\t\t\tdebug_flag++;\n\t\t\t\t\toptions.log_level++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'V':\n\t\t\tfprintf(stderr, \"%s, %s\\n\",\n\t\t\t SSH_RELEASE,\n#ifdef WITH_OPENSSL\n\t\t\t SSLeay_version(SSLEAY_VERSION)\n#else\n\t\t\t \"without OpenSSL\"\n#endif\n\t\t\t);\n\t\t\tif (opt == 'V')\n\t\t\t\texit(0);\n\t\t\tbreak;\n\t\tcase 'w':\n\t\t\tif (options.tun_open == -1)\n\t\t\t\toptions.tun_open = SSH_TUNMODE_DEFAULT;\n\t\t\toptions.tun_local = a2tun(optarg, &options.tun_remote);\n\t\t\tif (options.tun_local == SSH_TUNID_ERR) {\n\t\t\t\tfprintf(stderr,\n\t\t\t\t \"Bad tun device '%s'\\n\", optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'W':\n\t\t\tif (options.stdio_forward_host != NULL)\n\t\t\t\tfatal(\"stdio forward already specified\");\n\t\t\tif (muxclient_command != 0)\n\t\t\t\tfatal(\"Cannot specify stdio forward with -O\");\n\t\t\tif (parse_forward(&fwd, optarg, 1, 0)) {\n\t\t\t\toptions.stdio_forward_host = fwd.listen_host;\n\t\t\t\toptions.stdio_forward_port = fwd.listen_port;\n\t\t\t\tfree(fwd.connect_host);\n\t\t\t} else {\n\t\t\t\tfprintf(stderr,\n\t\t\t\t \"Bad stdio forwarding specification '%s'\\n\",\n\t\t\t\t optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\toptions.request_tty = REQUEST_TTY_NO;\n\t\t\tno_shell_flag = 1;\n\t\t\tbreak;\n\t\tcase 'q':\n\t\t\toptions.log_level = SYSLOG_LEVEL_QUIET;\n\t\t\tbreak;\n\t\tcase 'e':\n\t\t\tif (optarg[0] == '^' && optarg[2] == 0 &&\n\t\t\t (u_char) optarg[1] >= 64 &&\n\t\t\t (u_char) optarg[1] < 128)\n\t\t\t\toptions.escape_char = (u_char) optarg[1] & 31;\n\t\t\telse if (strlen(optarg) == 1)\n\t\t\t\toptions.escape_char = (u_char) optarg[0];\n\t\t\telse if (strcmp(optarg, \"none\") == 0)\n\t\t\t\toptions.escape_char = SSH_ESCAPECHAR_NONE;\n\t\t\telse {\n\t\t\t\tfprintf(stderr, \"Bad escape character '%s'.\\n\",\n\t\t\t\t optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'c':\n\t\t\tif (ciphers_valid(*optarg == '+' ?\n\t\t\t optarg + 1 : optarg)) {\n\t\t\t\t/* SSH2 only */\n\t\t\t\tfree(options.ciphers);\n\t\t\t\toptions.ciphers = xstrdup(optarg);\n\t\t\t\toptions.cipher = SSH_CIPHER_INVALID;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* SSH1 only */\n\t\t\toptions.cipher = cipher_number(optarg);\n\t\t\tif (options.cipher == -1) {\n\t\t\t\tfprintf(stderr, \"Unknown cipher type '%s'\\n\",\n\t\t\t\t optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tif (options.cipher == SSH_CIPHER_3DES)\n\t\t\t\toptions.ciphers = xstrdup(\"3des-cbc\");\n\t\t\telse if (options.cipher == SSH_CIPHER_BLOWFISH)\n\t\t\t\toptions.ciphers = xstrdup(\"blowfish-cbc\");\n\t\t\telse\n\t\t\t\toptions.ciphers = xstrdup(KEX_CLIENT_ENCRYPT);\n\t\t\tbreak;\n\t\tcase 'm':\n\t\t\tif (mac_valid(optarg)) {\n\t\t\t\tfree(options.macs);\n\t\t\t\toptions.macs = xstrdup(optarg);\n\t\t\t} else {\n\t\t\t\tfprintf(stderr, \"Unknown mac type '%s'\\n\",\n\t\t\t\t optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'M':\n\t\t\tif (options.control_master == SSHCTL_MASTER_YES)\n\t\t\t\toptions.control_master = SSHCTL_MASTER_ASK;\n\t\t\telse\n\t\t\t\toptions.control_master = SSHCTL_MASTER_YES;\n\t\t\tbreak;\n\t\tcase 'p':\n\t\t\toptions.port = a2port(optarg);\n\t\t\tif (options.port <= 0) {\n\t\t\t\tfprintf(stderr, \"Bad port '%s'\\n\", optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'l':\n\t\t\toptions.user = optarg;\n\t\t\tbreak;\n\n\t\tcase 'L':\n\t\t\tif (parse_forward(&fwd, optarg, 0, 0))\n\t\t\t\tadd_local_forward(&options, &fwd);\n\t\t\telse {\n\t\t\t\tfprintf(stderr,\n\t\t\t\t \"Bad local forwarding specification '%s'\\n\",\n\t\t\t\t optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'R':\n\t\t\tif (parse_forward(&fwd, optarg, 0, 1)) {\n\t\t\t\tadd_remote_forward(&options, &fwd);\n\t\t\t} else {\n\t\t\t\tfprintf(stderr,\n\t\t\t\t \"Bad remote forwarding specification \"\n\t\t\t\t \"'%s'\\n\", optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'D':\n\t\t\tif (parse_forward(&fwd, optarg, 1, 0)) {\n\t\t\t\tadd_local_forward(&options, &fwd);\n\t\t\t} else {\n\t\t\t\tfprintf(stderr,\n\t\t\t\t \"Bad dynamic forwarding specification \"\n\t\t\t\t \"'%s'\\n\", optarg);\n\t\t\t\texit(255);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'C':\n\t\t\toptions.compression = 1;\n\t\t\tbreak;\n\t\tcase 'N':\n\t\t\tno_shell_flag = 1;\n\t\t\toptions.request_tty = REQUEST_TTY_NO;\n\t\t\tbreak;\n\t\tcase 'T':\n\t\t\toptions.request_tty = REQUEST_TTY_NO;\n\t\t\tbreak;\n\t\tcase 'o':\n\t\t\tline = xstrdup(optarg);\n\t\t\tif (process_config_line(&options, pw,\n\t\t\t host ? host : \"\", host ? host : \"\", line,\n\t\t\t \"command-line\", 0, NULL, SSHCONF_USERCONF) != 0)\n\t\t\t\texit(255);\n\t\t\tfree(line);\n\t\t\tbreak;\n\t\tcase 's':\n\t\t\tsubsystem_flag = 1;\n\t\t\tbreak;\n\t\tcase 'S':\n\t\t\tfree(options.control_path);\n\t\t\toptions.control_path = xstrdup(optarg);\n\t\t\tbreak;\n\t\tcase 'b':\n\t\t\toptions.bind_address = optarg;\n\t\t\tbreak;\n\t\tcase 'F':\n\t\t\tconfig = optarg;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tusage();\n\t\t}\n\t}\n\n\tac -= optind;\n\tav += optind;\n\n\tif (ac > 0 && !host) {\n\t\tif (strrchr(*av, '@')) {\n\t\t\tp = xstrdup(*av);\n\t\t\tcp = strrchr(p, '@');\n\t\t\tif (cp == NULL || cp == p)\n\t\t\t\tusage();\n\t\t\toptions.user = p;\n\t\t\t*cp = '\\0';\n\t\t\thost = xstrdup(++cp);\n\t\t} else\n\t\t\thost = xstrdup(*av);\n\t\tif (ac > 1) {\n\t\t\toptind = optreset = 1;\n\t\t\tgoto again;\n\t\t}\n\t\tac--, av++;\n\t}\n\n\t/* Check that we got a host name. */\n\tif (!host)\n\t\tusage();\n\n\thost_arg = xstrdup(host);\n\n#ifdef WITH_OPENSSL\n\tOpenSSL_add_all_algorithms();\n\tERR_load_crypto_strings();\n#endif\n\n\t/* Initialize the command to execute on remote host. */\n\tbuffer_init(&command);\n\n\t/*\n\t * Save the command to execute on the remote host in a buffer. There\n\t * is no limit on the length of the command, except by the maximum\n\t * packet size. Also sets the tty flag if there is no command.\n\t */\n\tif (!ac) {\n\t\t/* No command specified - execute shell on a tty. */\n\t\tif (subsystem_flag) {\n\t\t\tfprintf(stderr,\n\t\t\t \"You must specify a subsystem to invoke.\\n\");\n\t\t\tusage();\n\t\t}\n\t} else {\n\t\t/* A command has been specified. Store it into the buffer. */\n\t\tfor (i = 0; i < ac; i++) {\n\t\t\tif (i)\n\t\t\t\tbuffer_append(&command, \" \", 1);\n\t\t\tbuffer_append(&command, av[i], strlen(av[i]));\n\t\t}\n\t}\n\n\t/* Cannot fork to background if no command. */\n\tif (fork_after_authentication_flag && buffer_len(&command) == 0 &&\n\t !no_shell_flag)\n\t\tfatal(\"Cannot fork into background without a command \"\n\t\t \"to execute.\");\n\n\t/*\n\t * Initialize \"log\" output. Since we are the client all output\n\t * goes to stderr unless otherwise specified by -y or -E.\n\t */\n\tif (use_syslog && logfile != NULL)\n\t\tfatal(\"Can't specify both -y and -E\");\n\tif (logfile != NULL)\n\t\tlog_redirect_stderr_to(logfile);\n\tlog_init(argv0,\n\t options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,\n\t SYSLOG_FACILITY_USER, !use_syslog);\n\n\tif (debug_flag)\n\t\tlogit(\"%s, %s\", SSH_RELEASE,\n#ifdef WITH_OPENSSL\n\t\t SSLeay_version(SSLEAY_VERSION)\n#else\n\t\t \"without OpenSSL\"\n#endif\n\t\t);\n\n\t/* Parse the configuration files */\n\tprocess_config_files(host_arg, pw, 0);\n\n\t/* Hostname canonicalisation needs a few options filled. */\n\tfill_default_options_for_canonicalization(&options);\n\n\t/* If the user has replaced the hostname then take it into use now */\n\tif (options.hostname != NULL) {\n\t\t/* NB. Please keep in sync with readconf.c:match_cfg_line() */\n\t\tcp = percent_expand(options.hostname,\n\t\t \"h\", host, (char *)NULL);\n\t\tfree(host);\n\t\thost = cp;\n\t\tfree(options.hostname);\n\t\toptions.hostname = xstrdup(host);\n\t}\n\n\t/* If canonicalization requested then try to apply it */\n\tlowercase(host);\n\tif (options.canonicalize_hostname != SSH_CANONICALISE_NO)\n\t\taddrs = resolve_canonicalize(&host, options.port);\n\n\t/*\n\t * If CanonicalizePermittedCNAMEs have been specified but\n\t * other canonicalization did not happen (by not being requested\n\t * or by failing with fallback) then the hostname may still be changed\n\t * as a result of CNAME following. \n\t *\n\t * Try to resolve the bare hostname name using the system resolver's\n\t * usual search rules and then apply the CNAME follow rules.\n\t *\n\t * Skip the lookup if a ProxyCommand is being used unless the user\n\t * has specifically requested canonicalisation for this case via\n\t * CanonicalizeHostname=always\n\t */\n\tdirect = option_clear_or_none(options.proxy_command) &&\n\t options.jump_host == NULL;\n\tif (addrs == NULL && options.num_permitted_cnames != 0 && (direct ||\n\t options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) {\n\t\tif ((addrs = resolve_host(host, options.port,\n\t\t option_clear_or_none(options.proxy_command),\n\t\t cname, sizeof(cname))) == NULL) {\n\t\t\t/* Don't fatal proxied host names not in the DNS */\n\t\t\tif (option_clear_or_none(options.proxy_command))\n\t\t\t\tcleanup_exit(255); /* logged in resolve_host */\n\t\t} else\n\t\t\tcheck_follow_cname(direct, &host, cname);\n\t}\n\n\t/*\n\t * If canonicalisation is enabled then re-parse the configuration\n\t * files as new stanzas may match.\n\t */\n\tif (options.canonicalize_hostname != 0) {\n\t\tdebug(\"Re-reading configuration after hostname \"\n\t\t \"canonicalisation\");\n\t\tfree(options.hostname);\n\t\toptions.hostname = xstrdup(host);\n\t\tprocess_config_files(host_arg, pw, 1);\n\t\t/*\n\t\t * Address resolution happens early with canonicalisation\n\t\t * enabled and the port number may have changed since, so\n\t\t * reset it in address list\n\t\t */\n\t\tif (addrs != NULL && options.port > 0)\n\t\t\tset_addrinfo_port(addrs, options.port);\n\t}\n\n\t/* Fill configuration defaults. */\n\tfill_default_options(&options);\n\n\t/*\n\t * If ProxyJump option specified, then construct a ProxyCommand now.\n\t */\n\tif (options.jump_host != NULL) {\n\t\tchar port_s[8];\n\n\t\t/* Consistency check */\n\t\tif (options.proxy_command != NULL)\n\t\t\tfatal(\"inconsistent options: ProxyCommand+ProxyJump\");\n\t\t/* Never use FD passing for ProxyJump */\n\t\toptions.proxy_use_fdpass = 0;\n\t\tsnprintf(port_s, sizeof(port_s), \"%d\", options.jump_port);\n\t\txasprintf(&options.proxy_command,\n\t\t \"ssh%s%s%s%s%s%s%s%s%s%.*s -W '[%%h]:%%p' %s\",\n\t\t /* Optional \"-l user\" argument if jump_user set */\n\t\t options.jump_user == NULL ? \"\" : \" -l \",\n\t\t options.jump_user == NULL ? \"\" : options.jump_user,\n\t\t /* Optional \"-p port\" argument if jump_port set */\n\t\t options.jump_port <= 0 ? \"\" : \" -p \",\n\t\t options.jump_port <= 0 ? \"\" : port_s,\n\t\t /* Optional additional jump hosts \",...\" */\n\t\t options.jump_extra == NULL ? \"\" : \" -J \",\n\t\t options.jump_extra == NULL ? \"\" : options.jump_extra,\n\t\t /* Optional \"-F\" argumment if -F specified */\n\t\t config == NULL ? \"\" : \" -F \",\n\t\t config == NULL ? \"\" : config,\n\t\t /* Optional \"-v\" arguments if -v set */\n\t\t debug_flag ? \" -\" : \"\",\n\t\t debug_flag, \"vvv\",\n\t\t /* Mandatory hostname */\n\t\t options.jump_host);\n\t\tdebug(\"Setting implicit ProxyCommand from ProxyJump: %s\",\n\t\t options.proxy_command);\n\t}\n\n\tif (options.port == 0)\n\t\toptions.port = default_ssh_port();\n\tchannel_set_af(options.address_family);\n\n\t/* Tidy and check options */\n\tif (options.host_key_alias != NULL)\n\t\tlowercase(options.host_key_alias);\n\tif (options.proxy_command != NULL &&\n\t strcmp(options.proxy_command, \"-\") == 0 &&\n\t options.proxy_use_fdpass)\n\t\tfatal(\"ProxyCommand=- and ProxyUseFDPass are incompatible\");\n\tif (options.control_persist &&\n\t options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {\n\t\tdebug(\"UpdateHostKeys=ask is incompatible with ControlPersist; \"\n\t\t \"disabling\");\n\t\toptions.update_hostkeys = 0;\n\t}\n\tif (options.connection_attempts <= 0)\n\t\tfatal(\"Invalid number of ConnectionAttempts\");\n#ifndef HAVE_CYGWIN\n\tif (original_effective_uid != 0)\n\t\toptions.use_privileged_port = 0;\n#endif\n\n\t/* reinit */\n\tlog_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);\n\n\tif (options.request_tty == REQUEST_TTY_YES ||\n\t options.request_tty == REQUEST_TTY_FORCE)\n\t\ttty_flag = 1;\n\n\t/* Allocate a tty by default if no command specified. */\n\tif (buffer_len(&command) == 0)\n\t\ttty_flag = options.request_tty != REQUEST_TTY_NO;\n\n\t/* Force no tty */\n\tif (options.request_tty == REQUEST_TTY_NO ||\n\t (muxclient_command && muxclient_command != SSHMUX_COMMAND_PROXY))\n\t\ttty_flag = 0;\n\t/* Do not allocate a tty if stdin is not a tty. */\n\tif ((!isatty(fileno(stdin)) || stdin_null_flag) &&\n\t options.request_tty != REQUEST_TTY_FORCE) {\n\t\tif (tty_flag)\n\t\t\tlogit(\"Pseudo-terminal will not be allocated because \"\n\t\t\t \"stdin is not a terminal.\");\n\t\ttty_flag = 0;\n\t}\n\n\tseed_rng();\n\n\tif (options.user == NULL)\n\t\toptions.user = xstrdup(pw->pw_name);\n\n\tif (gethostname(thishost, sizeof(thishost)) == -1)\n\t\tfatal(\"gethostname: %s\", strerror(errno));\n\tstrlcpy(shorthost, thishost, sizeof(shorthost));\n\tshorthost[strcspn(thishost, \".\")] = '\\0';\n\tsnprintf(portstr, sizeof(portstr), \"%d\", options.port);\n\tsnprintf(uidstr, sizeof(uidstr), \"%d\", pw->pw_uid);\n\n\tif ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL ||\n\t ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||\n\t ssh_digest_update(md, host, strlen(host)) < 0 ||\n\t ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||\n\t ssh_digest_update(md, options.user, strlen(options.user)) < 0 ||\n\t ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)\n\t\tfatal(\"%s: mux digest failed\", __func__);\n\tssh_digest_free(md);\n\tconn_hash_hex = tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA1));\n\n\tif (options.local_command != NULL) {\n\t\tdebug3(\"expanding LocalCommand: %s\", options.local_command);\n\t\tcp = options.local_command;\n\t\toptions.local_command = percent_expand(cp,\n\t\t \"C\", conn_hash_hex,\n\t\t \"L\", shorthost,\n\t\t \"d\", pw->pw_dir,\n\t\t \"h\", host,\n\t\t \"l\", thishost,\n\t\t \"n\", host_arg,\n\t\t \"p\", portstr,\n\t\t \"r\", options.user,\n\t\t \"u\", pw->pw_name,\n\t\t (char *)NULL);\n\t\tdebug3(\"expanded LocalCommand: %s\", options.local_command);\n\t\tfree(cp);\n\t}\n\n\tif (options.control_path != NULL) {\n\t\tcp = tilde_expand_filename(options.control_path,\n\t\t original_real_uid);\n\t\tfree(options.control_path);\n\t\toptions.control_path = percent_expand(cp,\n\t\t \"C\", conn_hash_hex,\n\t\t \"L\", shorthost,\n\t\t \"h\", host,\n\t\t \"l\", thishost,\n\t\t \"n\", host_arg,\n\t\t \"p\", portstr,\n\t\t \"r\", options.user,\n\t\t \"u\", pw->pw_name,\n\t\t \"i\", uidstr,\n\t\t (char *)NULL);\n\t\tfree(cp);\n\t}\n\tfree(conn_hash_hex);\n\n\tif (config_test) {\n\t\tdump_client_config(&options, host);\n\t\texit(0);\n\t}\n\n\tif (muxclient_command != 0 && options.control_path == NULL)\n\t\tfatal(\"No ControlPath specified for \\\"-O\\\" command\");\n\tif (options.control_path != NULL) {\n\t\tint sock;\n\t\tif ((sock = muxclient(options.control_path)) >= 0) {\n\t\t\tpacket_set_connection(sock, sock);\n\t\t\tssh = active_state; /* XXX */\n\t\t\tenable_compat20();\t/* XXX */\n\t\t\tpacket_set_mux();\n\t\t\tgoto skip_connect;\n\t\t}\n\t}\n\n\t/*\n\t * If hostname canonicalisation was not enabled, then we may not\n\t * have yet resolved the hostname. Do so now.\n\t */\n\tif (addrs == NULL && options.proxy_command == NULL) {\n\t\tdebug2(\"resolving \\\"%s\\\" port %d\", host, options.port);\n\t\tif ((addrs = resolve_host(host, options.port, 1,\n\t\t cname, sizeof(cname))) == NULL)\n\t\t\tcleanup_exit(255); /* resolve_host logs the error */\n\t}\n\n\ttimeout_ms = options.connection_timeout * 1000;\n\n\t/* Open a connection to the remote host. */\n\tif (ssh_connect(host, addrs, &hostaddr, options.port,\n\t options.address_family, options.connection_attempts,\n\t &timeout_ms, options.tcp_keep_alive,\n\t options.use_privileged_port) != 0)\n \t\texit(255);\n\n\tif (addrs != NULL)\n\t\tfreeaddrinfo(addrs);\n\n\tpacket_set_timeout(options.server_alive_interval,\n\t options.server_alive_count_max);\n\n\tssh = active_state; /* XXX */\n\n\tif (timeout_ms > 0)\n\t\tdebug3(\"timeout: %d ms remain after connect\", timeout_ms);\n\n\t/*\n\t * If we successfully made the connection, load the host private key\n\t * in case we will need it later for combined rsa-rhosts\n\t * authentication. This must be done before releasing extra\n\t * privileges, because the file is only readable by root.\n\t * If we cannot access the private keys, load the public keys\n\t * instead and try to execute the ssh-keysign helper instead.\n\t */\n\tsensitive_data.nkeys = 0;\n\tsensitive_data.keys = NULL;\n\tsensitive_data.external_keysign = 0;\n\tif (options.rhosts_rsa_authentication ||\n\t options.hostbased_authentication) {\n\t\tsensitive_data.nkeys = 9;\n\t\tsensitive_data.keys = xcalloc(sensitive_data.nkeys,\n\t\t sizeof(Key));\n\t\tfor (i = 0; i < sensitive_data.nkeys; i++)\n\t\t\tsensitive_data.keys[i] = NULL;\n\n\t\tPRIV_START;\n#if WITH_SSH1\n\t\tsensitive_data.keys[0] = key_load_private_type(KEY_RSA1,\n\t\t _PATH_HOST_KEY_FILE, \"\", NULL, NULL);\n#endif\n#ifdef OPENSSL_HAS_ECC\n\t\tsensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA,\n\t\t _PATH_HOST_ECDSA_KEY_FILE, \"\", NULL);\n#endif\n\t\tsensitive_data.keys[2] = key_load_private_cert(KEY_ED25519,\n\t\t _PATH_HOST_ED25519_KEY_FILE, \"\", NULL);\n\t\tsensitive_data.keys[3] = key_load_private_cert(KEY_RSA,\n\t\t _PATH_HOST_RSA_KEY_FILE, \"\", NULL);\n\t\tsensitive_data.keys[4] = key_load_private_cert(KEY_DSA,\n\t\t _PATH_HOST_DSA_KEY_FILE, \"\", NULL);\n#ifdef OPENSSL_HAS_ECC\n\t\tsensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,\n\t\t _PATH_HOST_ECDSA_KEY_FILE, \"\", NULL, NULL);\n#endif\n\t\tsensitive_data.keys[6] = key_load_private_type(KEY_ED25519,\n\t\t _PATH_HOST_ED25519_KEY_FILE, \"\", NULL, NULL);\n\t\tsensitive_data.keys[7] = key_load_private_type(KEY_RSA,\n\t\t _PATH_HOST_RSA_KEY_FILE, \"\", NULL, NULL);\n\t\tsensitive_data.keys[8] = key_load_private_type(KEY_DSA,\n\t\t _PATH_HOST_DSA_KEY_FILE, \"\", NULL, NULL);\n\t\tPRIV_END;\n\n\t\tif (options.hostbased_authentication == 1 &&\n\t\t sensitive_data.keys[0] == NULL &&\n\t\t sensitive_data.keys[5] == NULL &&\n\t\t sensitive_data.keys[6] == NULL &&\n\t\t sensitive_data.keys[7] == NULL &&\n\t\t sensitive_data.keys[8] == NULL) {\n#ifdef OPENSSL_HAS_ECC\n\t\t\tsensitive_data.keys[1] = key_load_cert(\n\t\t\t _PATH_HOST_ECDSA_KEY_FILE);\n#endif\n\t\t\tsensitive_data.keys[2] = key_load_cert(\n\t\t\t _PATH_HOST_ED25519_KEY_FILE);\n\t\t\tsensitive_data.keys[3] = key_load_cert(\n\t\t\t _PATH_HOST_RSA_KEY_FILE);\n\t\t\tsensitive_data.keys[4] = key_load_cert(\n\t\t\t _PATH_HOST_DSA_KEY_FILE);\n#ifdef OPENSSL_HAS_ECC\n\t\t\tsensitive_data.keys[5] = key_load_public(\n\t\t\t _PATH_HOST_ECDSA_KEY_FILE, NULL);\n#endif\n\t\t\tsensitive_data.keys[6] = key_load_public(\n\t\t\t _PATH_HOST_ED25519_KEY_FILE, NULL);\n\t\t\tsensitive_data.keys[7] = key_load_public(\n\t\t\t _PATH_HOST_RSA_KEY_FILE, NULL);\n\t\t\tsensitive_data.keys[8] = key_load_public(\n\t\t\t _PATH_HOST_DSA_KEY_FILE, NULL);\n\t\t\tsensitive_data.external_keysign = 1;\n\t\t}\n\t}\n\t/*\n\t * Get rid of any extra privileges that we may have. We will no\n\t * longer need them. Also, extra privileges could make it very hard\n\t * to read identity files and other non-world-readable files from the\n\t * user's home directory if it happens to be on a NFS volume where\n\t * root is mapped to nobody.\n\t */\n\tif (original_effective_uid == 0) {\n\t\tPRIV_START;\n\t\tpermanently_set_uid(pw);\n\t}\n\n\t/*\n\t * Now that we are back to our own permissions, create ~/.ssh\n\t * directory if it doesn't already exist.\n\t */\n\tif (config == NULL) {\n\t\tr = snprintf(buf, sizeof buf, \"%s%s%s\", pw->pw_dir,\n\t\t strcmp(pw->pw_dir, \"/\") ? \"/\" : \"\", _PATH_SSH_USER_DIR);\n\t\tif (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {\n#ifdef WITH_SELINUX\n\t\t\tssh_selinux_setfscreatecon(buf);\n#endif\n\t\t\tif (mkdir(buf, 0700) < 0)\n\t\t\t\terror(\"Could not create directory '%.200s'.\",\n\t\t\t\t buf);\n#ifdef WITH_SELINUX\n\t\t\tssh_selinux_setfscreatecon(NULL);\n#endif\n\t\t}\n\t}\n\t/* load options.identity_files */\n\tload_public_identity_files();\n\n\t/* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */\n\tif (options.identity_agent &&\n\t strcmp(options.identity_agent, SSH_AUTHSOCKET_ENV_NAME) != 0) {\n\t\tif (strcmp(options.identity_agent, \"none\") == 0) {\n\t\t\tunsetenv(SSH_AUTHSOCKET_ENV_NAME);\n\t\t} else {\n\t\t\tp = tilde_expand_filename(options.identity_agent,\n\t\t\t original_real_uid);\n\t\t\tcp = percent_expand(p, \"d\", pw->pw_dir,\n\t\t\t \"u\", pw->pw_name, \"l\", thishost, \"h\", host,\n\t\t\t \"r\", options.user, (char *)NULL);\n\t\t\tsetenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1);\n\t\t\tfree(cp);\n\t\t\tfree(p);\n\t\t}\n\t}\n\n\t/* Expand ~ in known host file names. */\n\ttilde_expand_paths(options.system_hostfiles,\n\t options.num_system_hostfiles);\n\ttilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);\n\n\tsignal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */\n\tsignal(SIGCHLD, main_sigchld_handler);\n\n\t/* Log into the remote system. Never returns if the login fails. */\n\tssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,\n\t options.port, pw, timeout_ms);\n\n\tif (packet_connection_is_on_socket()) {\n\t\tverbose(\"Authenticated to %s ([%s]:%d).\", host,\n\t\t ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));\n\t} else {\n\t\tverbose(\"Authenticated to %s (via proxy).\", host);\n\t}\n\n\t/* We no longer need the private host keys. Clear them now. */\n\tif (sensitive_data.nkeys != 0) {\n\t\tfor (i = 0; i < sensitive_data.nkeys; i++) {\n\t\t\tif (sensitive_data.keys[i] != NULL) {\n\t\t\t\t/* Destroys contents safely */\n\t\t\t\tdebug3(\"clear hostkey %d\", i);\n\t\t\t\tkey_free(sensitive_data.keys[i]);\n\t\t\t\tsensitive_data.keys[i] = NULL;\n\t\t\t}\n\t\t}\n\t\tfree(sensitive_data.keys);\n\t}\n\tfor (i = 0; i < options.num_identity_files; i++) {\n\t\tfree(options.identity_files[i]);\n\t\toptions.identity_files[i] = NULL;\n\t\tif (options.identity_keys[i]) {\n\t\t\tkey_free(options.identity_keys[i]);\n\t\t\toptions.identity_keys[i] = NULL;\n\t\t}\n\t}\n\tfor (i = 0; i < options.num_certificate_files; i++) {\n\t\tfree(options.certificate_files[i]);\n\t\toptions.certificate_files[i] = NULL;\n\t}\n\n skip_connect:\n\texit_status = compat20 ? ssh_session2() : ssh_session();\n\tpacket_close();\n\n\tif (options.control_path != NULL && muxserver_sock != -1)\n\t\tunlink(options.control_path);\n\n\t/* Kill ProxyCommand if it is running. */\n\tssh_kill_proxy_command();\n\n\treturn exit_status;\n}\n\nstatic void\ncontrol_persist_detach(void)\n{\n\tpid_t pid;\n\tint devnull, keep_stderr;\n\n\tdebug(\"%s: backgrounding master process\", __func__);\n\n \t/*\n \t * master (current process) into the background, and make the\n \t * foreground process a client of the backgrounded master.\n \t */\n\tswitch ((pid = fork())) {\n\tcase -1:\n\t\tfatal(\"%s: fork: %s\", __func__, strerror(errno));\n\tcase 0:\n\t\t/* Child: master process continues mainloop */\n \t\tbreak;\n \tdefault:\n\t\t/* Parent: set up mux slave to connect to backgrounded master */\n\t\tdebug2(\"%s: background process is %ld\", __func__, (long)pid);\n\t\tstdin_null_flag = ostdin_null_flag;\n\t\toptions.request_tty = orequest_tty;\n\t\ttty_flag = otty_flag;\n \t\tclose(muxserver_sock);\n \t\tmuxserver_sock = -1;\n\t\toptions.control_master = SSHCTL_MASTER_NO;\n \t\tmuxclient(options.control_path);\n\t\t/* muxclient() doesn't return on success. */\n \t\tfatal(\"Failed to connect to new control master\");\n \t}\n\tif ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {\n\t\terror(\"%s: open(\\\"/dev/null\\\"): %s\", __func__,\n\t\t strerror(errno));\n\t} else {\n\t\tkeep_stderr = log_is_on_stderr() && debug_flag;\n\t\tif (dup2(devnull, STDIN_FILENO) == -1 ||\n\t\t dup2(devnull, STDOUT_FILENO) == -1 ||\n\t\t (!keep_stderr && dup2(devnull, STDERR_FILENO) == -1))\n\t\t\terror(\"%s: dup2: %s\", __func__, strerror(errno));\n\t\tif (devnull > STDERR_FILENO)\n\t\t\tclose(devnull);\n\t}\n\tdaemon(1, 1);\n\tsetproctitle(\"%s [mux]\", options.control_path);\n}\n\n/* Do fork() after authentication. Used by \"ssh -f\" */\nstatic void\nfork_postauth(void)\n{\n\tif (need_controlpersist_detach)\n\t\tcontrol_persist_detach();\n\tdebug(\"forking to background\");\n\tfork_after_authentication_flag = 0;\n\tif (daemon(1, 1) < 0)\n\t\tfatal(\"daemon() failed: %.200s\", strerror(errno));\n}\n\n/* Callback for remote forward global requests */\nstatic void\nssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct Forward *rfwd = (struct Forward *)ctxt;\n\n\t/* XXX verbose() on failure? */\n\tdebug(\"remote forward %s for: listen %s%s%d, connect %s:%d\",\n\t type == SSH2_MSG_REQUEST_SUCCESS ? \"success\" : \"failure\",\n\t rfwd->listen_path ? rfwd->listen_path :\n\t rfwd->listen_host ? rfwd->listen_host : \"\",\n\t (rfwd->listen_path || rfwd->listen_host) ? \":\" : \"\",\n\t rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :\n\t rfwd->connect_host, rfwd->connect_port);\n\tif (rfwd->listen_path == NULL && rfwd->listen_port == 0) {\n\t\tif (type == SSH2_MSG_REQUEST_SUCCESS) {\n\t\t\trfwd->allocated_port = packet_get_int();\n\t\t\tlogit(\"Allocated port %u for remote forward to %s:%d\",\n\t\t\t rfwd->allocated_port,\n\t\t\t rfwd->connect_host, rfwd->connect_port);\n\t\t\tchannel_update_permitted_opens(rfwd->handle,\n\t\t\t rfwd->allocated_port);\n\t\t} else {\n\t\t\tchannel_update_permitted_opens(rfwd->handle, -1);\n\t\t}\n\t}\n\t\n\tif (type == SSH2_MSG_REQUEST_FAILURE) {\n\t\tif (options.exit_on_forward_failure) {\n\t\t\tif (rfwd->listen_path != NULL)\n\t\t\t\tfatal(\"Error: remote port forwarding failed \"\n\t\t\t\t \"for listen path %s\", rfwd->listen_path);\n\t\t\telse\n\t\t\t\tfatal(\"Error: remote port forwarding failed \"\n\t\t\t\t \"for listen port %d\", rfwd->listen_port);\n\t\t} else {\n\t\t\tif (rfwd->listen_path != NULL)\n\t\t\t\tlogit(\"Warning: remote port forwarding failed \"\n\t\t\t\t \"for listen path %s\", rfwd->listen_path);\n\t\t\telse\n\t\t\t\tlogit(\"Warning: remote port forwarding failed \"\n\t\t\t\t \"for listen port %d\", rfwd->listen_port);\n\t\t}\n\t}\n\tif (++remote_forward_confirms_received == options.num_remote_forwards) {\n\t\tdebug(\"All remote forwarding requests processed\");\n\t\tif (fork_after_authentication_flag)\n\t\t\tfork_postauth();\n\t}\n}\n\nstatic void\nclient_cleanup_stdio_fwd(int id, void *arg)\n{\n\tdebug(\"stdio forwarding: done\");\n\tcleanup_exit(0);\n}\n\nstatic void\nssh_stdio_confirm(int id, int success, void *arg)\n{\n\tif (!success)\n\t\tfatal(\"stdio forwarding failed\");\n}\n\nstatic void\nssh_init_stdio_forwarding(void)\n{\n\tChannel *c;\n\tint in, out;\n\n\tif (options.stdio_forward_host == NULL)\n\t\treturn;\n\tif (!compat20)\n\t\tfatal(\"stdio forwarding require Protocol 2\");\n\n\tdebug3(\"%s: %s:%d\", __func__, options.stdio_forward_host,\n\t options.stdio_forward_port);\n\n\tif ((in = dup(STDIN_FILENO)) < 0 ||\n\t (out = dup(STDOUT_FILENO)) < 0)\n\t\tfatal(\"channel_connect_stdio_fwd: dup() in/out failed\");\n\tif ((c = channel_connect_stdio_fwd(options.stdio_forward_host,\n\t options.stdio_forward_port, in, out)) == NULL)\n\t\tfatal(\"%s: channel_connect_stdio_fwd failed\", __func__);\n\tchannel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);\n\tchannel_register_open_confirm(c->self, ssh_stdio_confirm, NULL);\n}\n\nstatic void\nssh_init_forwarding(void)\n{\n\tint success = 0;\n\tint i;\n\n\t/* Initiate local TCP/IP port forwardings. */\n\tfor (i = 0; i < options.num_local_forwards; i++) {\n\t\tdebug(\"Local connections to %.200s:%d forwarded to remote \"\n\t\t \"address %.200s:%d\",\n\t\t (options.local_forwards[i].listen_path != NULL) ?\n\t\t options.local_forwards[i].listen_path :\n\t\t (options.local_forwards[i].listen_host == NULL) ?\n\t\t (options.fwd_opts.gateway_ports ? \"*\" : \"LOCALHOST\") :\n\t\t options.local_forwards[i].listen_host,\n\t\t options.local_forwards[i].listen_port,\n\t\t (options.local_forwards[i].connect_path != NULL) ?\n\t\t options.local_forwards[i].connect_path :\n\t\t options.local_forwards[i].connect_host,\n\t\t options.local_forwards[i].connect_port);\n\t\tsuccess += channel_setup_local_fwd_listener(\n\t\t &options.local_forwards[i], &options.fwd_opts);\n\t}\n\tif (i > 0 && success != i && options.exit_on_forward_failure)\n\t\tfatal(\"Could not request local forwarding.\");\n\tif (i > 0 && success == 0)\n\t\terror(\"Could not request local forwarding.\");\n\n\t/* Initiate remote TCP/IP port forwardings. */\n\tfor (i = 0; i < options.num_remote_forwards; i++) {\n\t\tdebug(\"Remote connections from %.200s:%d forwarded to \"\n\t\t \"local address %.200s:%d\",\n\t\t (options.remote_forwards[i].listen_path != NULL) ?\n\t\t options.remote_forwards[i].listen_path :\n\t\t (options.remote_forwards[i].listen_host == NULL) ?\n\t\t \"LOCALHOST\" : options.remote_forwards[i].listen_host,\n\t\t options.remote_forwards[i].listen_port,\n\t\t (options.remote_forwards[i].connect_path != NULL) ?\n\t\t options.remote_forwards[i].connect_path :\n\t\t options.remote_forwards[i].connect_host,\n\t\t options.remote_forwards[i].connect_port);\n\t\toptions.remote_forwards[i].handle =\n\t\t channel_request_remote_forwarding(\n\t\t &options.remote_forwards[i]);\n\t\tif (options.remote_forwards[i].handle < 0) {\n\t\t\tif (options.exit_on_forward_failure)\n\t\t\t\tfatal(\"Could not request remote forwarding.\");\n\t\t\telse\n\t\t\t\tlogit(\"Warning: Could not request remote \"\n\t\t\t\t \"forwarding.\");\n\t\t} else {\n\t\t\tclient_register_global_confirm(ssh_confirm_remote_forward,\n\t\t\t &options.remote_forwards[i]);\n\t\t}\n\t}\n\n\t/* Initiate tunnel forwarding. */\n\tif (options.tun_open != SSH_TUNMODE_NO) {\n\t\tif (client_request_tun_fwd(options.tun_open,\n\t\t options.tun_local, options.tun_remote) == -1) {\n\t\t\tif (options.exit_on_forward_failure)\n\t\t\t\tfatal(\"Could not request tunnel forwarding.\");\n\t\t\telse\n\t\t\t\terror(\"Could not request tunnel forwarding.\");\n\t\t}\n\t}\t\t\t\n}\n\nstatic void\ncheck_agent_present(void)\n{\n\tint r;\n\n\tif (options.forward_agent) {\n\t\t/* Clear agent forwarding if we don't have an agent. */\n\t\tif ((r = ssh_get_authentication_socket(NULL)) != 0) {\n\t\t\toptions.forward_agent = 0;\n\t\t\tif (r != SSH_ERR_AGENT_NOT_PRESENT)\n\t\t\t\tdebug(\"ssh_get_authentication_socket: %s\",\n\t\t\t\t ssh_err(r));\n\t\t}\n\t}\n}\n\nstatic int\nssh_session(void)\n{\n\tint type;\n\tint interactive = 0;\n\tint have_tty = 0;\n\tstruct winsize ws;\n\tchar *cp;\n\tconst char *display;\n\tchar *proto = NULL, *data = NULL;\n\n\t/* Enable compression if requested. */\n\tif (options.compression) {\n\t\tdebug(\"Requesting compression at level %d.\",\n\t\t options.compression_level);\n\n\t\tif (options.compression_level < 1 ||\n\t\t options.compression_level > 9)\n\t\t\tfatal(\"Compression level must be from 1 (fast) to \"\n\t\t\t \"9 (slow, best).\");\n\n\t\t/* Send the request. */\n\t\tpacket_start(SSH_CMSG_REQUEST_COMPRESSION);\n\t\tpacket_put_int(options.compression_level);\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\t\ttype = packet_read();\n\t\tif (type == SSH_SMSG_SUCCESS)\n\t\t\tpacket_start_compression(options.compression_level);\n\t\telse if (type == SSH_SMSG_FAILURE)\n\t\t\tlogit(\"Warning: Remote host refused compression.\");\n\t\telse\n\t\t\tpacket_disconnect(\"Protocol error waiting for \"\n\t\t\t \"compression response.\");\n\t}\n\t/* Allocate a pseudo tty if appropriate. */\n\tif (tty_flag) {\n\t\tdebug(\"Requesting pty.\");\n\n\t\t/* Start the packet. */\n\t\tpacket_start(SSH_CMSG_REQUEST_PTY);\n\n\t\t/* Store TERM in the packet. There is no limit on the\n\t\t length of the string. */\n\t\tcp = getenv(\"TERM\");\n\t\tif (!cp)\n\t\t\tcp = \"\";\n\t\tpacket_put_cstring(cp);\n\n\t\t/* Store window size in the packet. */\n\t\tif (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)\n\t\t\tmemset(&ws, 0, sizeof(ws));\n\t\tpacket_put_int((u_int)ws.ws_row);\n\t\tpacket_put_int((u_int)ws.ws_col);\n\t\tpacket_put_int((u_int)ws.ws_xpixel);\n\t\tpacket_put_int((u_int)ws.ws_ypixel);\n\n\t\t/* Store tty modes in the packet. */\n\t\ttty_make_modes(fileno(stdin), NULL);\n\n\t\t/* Send the packet, and wait for it to leave. */\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\n\t\t/* Read response from the server. */\n\t\ttype = packet_read();\n\t\tif (type == SSH_SMSG_SUCCESS) {\n\t\t\tinteractive = 1;\n\t\t\thave_tty = 1;\n\t\t} else if (type == SSH_SMSG_FAILURE)\n\t\t\tlogit(\"Warning: Remote host failed or refused to \"\n\t\t\t \"allocate a pseudo tty.\");\n\t\telse\n\t\t\tpacket_disconnect(\"Protocol error waiting for pty \"\n\t\t\t \"request response.\");\n\t}\n\t/* Request X11 forwarding if enabled and DISPLAY is set. */\n\tdisplay = getenv(\"DISPLAY\");\n\tif (display == NULL && options.forward_x11)\n\t\tdebug(\"X11 forwarding requested but DISPLAY not set\");\n\tif (options.forward_x11 && client_x11_get_proto(display,\n\t options.xauth_location, options.forward_x11_trusted,\n\t options.forward_x11_timeout, &proto, &data) == 0) {\n\t\t/* Request forwarding with authentication spoofing. */\n\t\tdebug(\"Requesting X11 forwarding with authentication \"\n\t\t \"spoofing.\");\n\t\tx11_request_forwarding_with_spoofing(0, display, proto,\n\t\t data, 0);\n\t\t/* Read response from the server. */\n\t\ttype = packet_read();\n\t\tif (type == SSH_SMSG_SUCCESS) {\n\t\t\tinteractive = 1;\n\t\t} else if (type == SSH_SMSG_FAILURE) {\n\t\t\tlogit(\"Warning: Remote host denied X11 forwarding.\");\n\t\t} else {\n\t\t\tpacket_disconnect(\"Protocol error waiting for X11 \"\n\t\t\t \"forwarding\");\n\t\t}\n\t}\n\t/* Tell the packet module whether this is an interactive session. */\n\tpacket_set_interactive(interactive,\n\t options.ip_qos_interactive, options.ip_qos_bulk);\n\n\t/* Request authentication agent forwarding if appropriate. */\n\tcheck_agent_present();\n\n\tif (options.forward_agent) {\n\t\tdebug(\"Requesting authentication agent forwarding.\");\n\t\tauth_request_forwarding();\n\n\t\t/* Read response from the server. */\n\t\ttype = packet_read();\n\t\tpacket_check_eom();\n\t\tif (type != SSH_SMSG_SUCCESS)\n\t\t\tlogit(\"Warning: Remote host denied authentication agent forwarding.\");\n\t}\n\n\t/* Initiate port forwardings. */\n\tssh_init_stdio_forwarding();\n\tssh_init_forwarding();\n\n\t/* Execute a local command */\n\tif (options.local_command != NULL &&\n\t options.permit_local_command)\n\t\tssh_local_cmd(options.local_command);\n\n\t/*\n\t * If requested and we are not interested in replies to remote\n\t * forwarding requests, then let ssh continue in the background.\n\t */\n\tif (fork_after_authentication_flag) {\n\t\tif (options.exit_on_forward_failure &&\n\t\t options.num_remote_forwards > 0) {\n\t\t\tdebug(\"deferring postauth fork until remote forward \"\n\t\t\t \"confirmation received\");\n\t\t} else\n\t\t\tfork_postauth();\n\t}\n\n\t/*\n\t * If a command was specified on the command line, execute the\n\t * command now. Otherwise request the server to start a shell.\n\t */\n\tif (buffer_len(&command) > 0) {\n\t\tint len = buffer_len(&command);\n\t\tif (len > 900)\n\t\t\tlen = 900;\n\t\tdebug(\"Sending command: %.*s\", len,\n\t\t (u_char *)buffer_ptr(&command));\n\t\tpacket_start(SSH_CMSG_EXEC_CMD);\n\t\tpacket_put_string(buffer_ptr(&command), buffer_len(&command));\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\t} else {\n\t\tdebug(\"Requesting shell.\");\n\t\tpacket_start(SSH_CMSG_EXEC_SHELL);\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\t}\n\n\t/* Enter the interactive session. */\n\treturn client_loop(have_tty, tty_flag ?\n\t options.escape_char : SSH_ESCAPECHAR_NONE, 0);\n}\n\n/* request pty/x11/agent/tcpfwd/shell for channel */\nstatic void\nssh_session2_setup(int id, int success, void *arg)\n{\n\textern char **environ;\n\tconst char *display;\n\tint interactive = tty_flag;\n\tchar *proto = NULL, *data = NULL;\n\n\tif (!success)\n\t\treturn; /* No need for error message, channels code sens one */\n\n\tdisplay = getenv(\"DISPLAY\");\n\tif (display == NULL && options.forward_x11)\n\t\tdebug(\"X11 forwarding requested but DISPLAY not set\");\n\tif (options.forward_x11 && client_x11_get_proto(display,\n\t options.xauth_location, options.forward_x11_trusted,\n\t options.forward_x11_timeout, &proto, &data) == 0) {\n\t\t/* Request forwarding with authentication spoofing. */\n\t\tdebug(\"Requesting X11 forwarding with authentication \"\n\t\t \"spoofing.\");\n\t\tx11_request_forwarding_with_spoofing(id, display, proto,\n\t\t data, 1);\n\t\tclient_expect_confirm(id, \"X11 forwarding\", CONFIRM_WARN);\n\t\t/* XXX exit_on_forward_failure */\n\t\tinteractive = 1;\n\t}\n\n\tcheck_agent_present();\n\tif (options.forward_agent) {\n\t\tdebug(\"Requesting authentication agent forwarding.\");\n\t\tchannel_request_start(id, \"auth-agent-req@openssh.com\", 0);\n\t\tpacket_send();\n\t}\n\n\t/* Tell the packet module whether this is an interactive session. */\n\tpacket_set_interactive(interactive,\n\t options.ip_qos_interactive, options.ip_qos_bulk);\n\n\tclient_session2_setup(id, tty_flag, subsystem_flag, getenv(\"TERM\"),\n\t NULL, fileno(stdin), &command, environ);\n}\n\n/* open new channel for a session */\nstatic int\nssh_session2_open(void)\n{\n\tChannel *c;\n\tint window, packetmax, in, out, err;\n\n\tif (stdin_null_flag) {\n\t\tin = open(_PATH_DEVNULL, O_RDONLY);\n\t} else {\n\t\tin = dup(STDIN_FILENO);\n\t}\n\tout = dup(STDOUT_FILENO);\n\terr = dup(STDERR_FILENO);\n\n\tif (in < 0 || out < 0 || err < 0)\n\t\tfatal(\"dup() in/out/err failed\");\n\n\t/* enable nonblocking unless tty */\n\tif (!isatty(in))\n\t\tset_nonblock(in);\n\tif (!isatty(out))\n\t\tset_nonblock(out);\n\tif (!isatty(err))\n\t\tset_nonblock(err);\n\n\twindow = CHAN_SES_WINDOW_DEFAULT;\n\tpacketmax = CHAN_SES_PACKET_DEFAULT;\n\tif (tty_flag) {\n\t\twindow >>= 1;\n\t\tpacketmax >>= 1;\n\t}\n\tc = channel_new(\n\t \"session\", SSH_CHANNEL_OPENING, in, out, err,\n\t window, packetmax, CHAN_EXTENDED_WRITE,\n\t \"client-session\", /*nonblock*/0);\n\n\tdebug3(\"ssh_session2_open: channel_new: %d\", c->self);\n\n\tchannel_send_open(c->self);\n\tif (!no_shell_flag)\n\t\tchannel_register_open_confirm(c->self,\n\t\t ssh_session2_setup, NULL);\n\n\treturn c->self;\n}\n\nstatic int\nssh_session2(void)\n{\n\tint id = -1;\n\n\t/* XXX should be pre-session */\n\tif (!options.control_persist)\n\t\tssh_init_stdio_forwarding();\n\tssh_init_forwarding();\n\n\t/* Start listening for multiplex clients */\n\tif (!packet_get_mux())\n\t\tmuxserver_listen();\n\n \t/*\n\t * If we are in control persist mode and have a working mux listen\n\t * socket, then prepare to background ourselves and have a foreground\n\t * client attach as a control slave.\n\t * NB. we must save copies of the flags that we override for\n\t * the backgrounding, since we defer attachment of the slave until\n\t * after the connection is fully established (in particular,\n\t * async rfwd replies have been received for ExitOnForwardFailure).\n\t */\n \tif (options.control_persist && muxserver_sock != -1) {\n\t\tostdin_null_flag = stdin_null_flag;\n\t\tono_shell_flag = no_shell_flag;\n\t\torequest_tty = options.request_tty;\n\t\totty_flag = tty_flag;\n \t\tstdin_null_flag = 1;\n \t\tno_shell_flag = 1;\n \t\ttty_flag = 0;\n\t\tif (!fork_after_authentication_flag)\n\t\t\tneed_controlpersist_detach = 1;\n\t\tfork_after_authentication_flag = 1;\n \t}\n\t/*\n\t * ControlPersist mux listen socket setup failed, attempt the\n\t * stdio forward setup that we skipped earlier.\n\t */\n\tif (options.control_persist && muxserver_sock == -1)\n\t\tssh_init_stdio_forwarding();\n\n\tif (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))\n\t\tid = ssh_session2_open();\n\telse {\n\t\tpacket_set_interactive(\n\t\t options.control_master == SSHCTL_MASTER_NO,\n\t\t options.ip_qos_interactive, options.ip_qos_bulk);\n\t}\n\n\t/* If we don't expect to open a new session, then disallow it */\n\tif (options.control_master == SSHCTL_MASTER_NO &&\n\t (datafellows & SSH_NEW_OPENSSH)) {\n\t\tdebug(\"Requesting no-more-sessions@openssh.com\");\n\t\tpacket_start(SSH2_MSG_GLOBAL_REQUEST);\n\t\tpacket_put_cstring(\"no-more-sessions@openssh.com\");\n\t\tpacket_put_char(0);\n\t\tpacket_send();\n\t}\n\n\t/* Execute a local command */\n\tif (options.local_command != NULL &&\n\t options.permit_local_command)\n\t\tssh_local_cmd(options.local_command);\n\n\t/*\n\t * If requested and we are not interested in replies to remote\n\t * forwarding requests, then let ssh continue in the background.\n\t */\n\tif (fork_after_authentication_flag) {\n\t\tif (options.exit_on_forward_failure &&\n\t\t options.num_remote_forwards > 0) {\n\t\t\tdebug(\"deferring postauth fork until remote forward \"\n\t\t\t \"confirmation received\");\n\t\t} else\n\t\t\tfork_postauth();\n\t}\n\n\treturn client_loop(tty_flag, tty_flag ?\n\t options.escape_char : SSH_ESCAPECHAR_NONE, id);\n}\n\n/* Loads all IdentityFile and CertificateFile keys */\nstatic void\nload_public_identity_files(void)\n{\n\tchar *filename, *cp, thishost[NI_MAXHOST];\n\tchar *pwdir = NULL, *pwname = NULL;\n\tKey *public;\n\tstruct passwd *pw;\n\tint i;\n\tu_int n_ids, n_certs;\n\tchar *identity_files[SSH_MAX_IDENTITY_FILES];\n\tKey *identity_keys[SSH_MAX_IDENTITY_FILES];\n\tchar *certificate_files[SSH_MAX_CERTIFICATE_FILES];\n\tstruct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];\n#ifdef ENABLE_PKCS11\n\tKey **keys;\n\tint nkeys;\n#endif /* PKCS11 */\n\n\tn_ids = n_certs = 0;\n\tmemset(identity_files, 0, sizeof(identity_files));\n\tmemset(identity_keys, 0, sizeof(identity_keys));\n\tmemset(certificate_files, 0, sizeof(certificate_files));\n\tmemset(certificates, 0, sizeof(certificates));\n\n#ifdef ENABLE_PKCS11\n\tif (options.pkcs11_provider != NULL &&\n\t options.num_identity_files < SSH_MAX_IDENTITY_FILES &&\n\t (pkcs11_init(!options.batch_mode) == 0) &&\n\t (nkeys = pkcs11_add_provider(options.pkcs11_provider, NULL,\n\t &keys)) > 0) {\n\t\tfor (i = 0; i < nkeys; i++) {\n\t\t\tif (n_ids >= SSH_MAX_IDENTITY_FILES) {\n\t\t\t\tkey_free(keys[i]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tidentity_keys[n_ids] = keys[i];\n\t\t\tidentity_files[n_ids] =\n\t\t\t xstrdup(options.pkcs11_provider); /* XXX */\n\t\t\tn_ids++;\n\t\t}\n\t\tfree(keys);\n\t}\n#endif /* ENABLE_PKCS11 */\n\tif ((pw = getpwuid(original_real_uid)) == NULL)\n\t\tfatal(\"load_public_identity_files: getpwuid failed\");\n\tpwname = xstrdup(pw->pw_name);\n\tpwdir = xstrdup(pw->pw_dir);\n\tif (gethostname(thishost, sizeof(thishost)) == -1)\n\t\tfatal(\"load_public_identity_files: gethostname: %s\",\n\t\t strerror(errno));\n\tfor (i = 0; i < options.num_identity_files; i++) {\n\t\tif (n_ids >= SSH_MAX_IDENTITY_FILES ||\n\t\t strcasecmp(options.identity_files[i], \"none\") == 0) {\n\t\t\tfree(options.identity_files[i]);\n\t\t\toptions.identity_files[i] = NULL;\n\t\t\tcontinue;\n\t\t}\n\t\tcp = tilde_expand_filename(options.identity_files[i],\n\t\t original_real_uid);\n\t\tfilename = percent_expand(cp, \"d\", pwdir,\n\t\t \"u\", pwname, \"l\", thishost, \"h\", host,\n\t\t \"r\", options.user, (char *)NULL);\n\t\tfree(cp);\n\t\tpublic = key_load_public(filename, NULL);\n\t\tdebug(\"identity file %s type %d\", filename,\n\t\t public ? public->type : -1);\n\t\tfree(options.identity_files[i]);\n\t\tidentity_files[n_ids] = filename;\n\t\tidentity_keys[n_ids] = public;\n\n\t\tif (++n_ids >= SSH_MAX_IDENTITY_FILES)\n\t\t\tcontinue;\n\n\t\t/*\n\t\t * If no certificates have been explicitly listed then try\n\t\t * to add the default certificate variant too.\n\t\t */\n\t\tif (options.num_certificate_files != 0)\n\t\t\tcontinue;\n\t\txasprintf(&cp, \"%s-cert\", filename);\n\t\tpublic = key_load_public(cp, NULL);\n\t\tdebug(\"identity file %s type %d\", cp,\n\t\t public ? public->type : -1);\n\t\tif (public == NULL) {\n\t\t\tfree(cp);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!key_is_cert(public)) {\n\t\t\tdebug(\"%s: key %s type %s is not a certificate\",\n\t\t\t __func__, cp, key_type(public));\n\t\t\tkey_free(public);\n\t\t\tfree(cp);\n\t\t\tcontinue;\n\t\t}\n\t\t/* NB. leave filename pointing to private key */\n\t\tidentity_files[n_ids] = xstrdup(filename);\n\t\tidentity_keys[n_ids] = public;\n\t\tn_ids++;\n\t}\n\n\tif (options.num_certificate_files > SSH_MAX_CERTIFICATE_FILES)\n\t\tfatal(\"%s: too many certificates\", __func__);\n\tfor (i = 0; i < options.num_certificate_files; i++) {\n\t\tcp = tilde_expand_filename(options.certificate_files[i],\n\t\t original_real_uid);\n\t\tfilename = percent_expand(cp, \"d\", pwdir,\n\t\t \"u\", pwname, \"l\", thishost, \"h\", host,\n\t\t \"r\", options.user, (char *)NULL);\n\t\tfree(cp);\n\n\t\tpublic = key_load_public(filename, NULL);\n\t\tdebug(\"certificate file %s type %d\", filename,\n\t\t public ? public->type : -1);\n\t\tfree(options.certificate_files[i]);\n\t\toptions.certificate_files[i] = NULL;\n\t\tif (public == NULL) {\n\t\t\tfree(filename);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!key_is_cert(public)) {\n\t\t\tdebug(\"%s: key %s type %s is not a certificate\",\n\t\t\t __func__, filename, key_type(public));\n\t\t\tkey_free(public);\n\t\t\tfree(filename);\n\t\t\tcontinue;\n\t\t}\n\t\tcertificate_files[n_certs] = filename;\n\t\tcertificates[n_certs] = public;\n\t\t++n_certs;\n\t}\n\n\toptions.num_identity_files = n_ids;\n\tmemcpy(options.identity_files, identity_files, sizeof(identity_files));\n\tmemcpy(options.identity_keys, identity_keys, sizeof(identity_keys));\n\n\toptions.num_certificate_files = n_certs;\n\tmemcpy(options.certificate_files,\n\t certificate_files, sizeof(certificate_files));\n\tmemcpy(options.certificates, certificates, sizeof(certificates));\n\n\texplicit_bzero(pwname, strlen(pwname));\n\tfree(pwname);\n\texplicit_bzero(pwdir, strlen(pwdir));\n\tfree(pwdir);\n}\n\nstatic void\nmain_sigchld_handler(int sig)\n{\n\tint save_errno = errno;\n\tpid_t pid;\n\tint status;\n\n\twhile ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||\n\t (pid < 0 && errno == EINTR))\n\t\t;\n\n\tsignal(sig, main_sigchld_handler);\n\terrno = save_errno;\n}\n","/* $OpenBSD: readconf.c,v 1.270 2017/03/10 04:27:32 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Functions for reading the configuration files.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#ifdef HAVE_PATHS_H\n# include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef USE_SYSTEM_GLOB\n# include \n#else\n# include \"openbsd-compat/glob.h\"\n#endif\n#ifdef HAVE_UTIL_H\n#include \n#endif\n#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)\n# include \n#endif\n\n#include \"xmalloc.h\"\n#include \"ssh.h\"\n#include \"compat.h\"\n#include \"cipher.h\"\n#include \"pathnames.h\"\n#include \"log.h\"\n#include \"sshkey.h\"\n#include \"misc.h\"\n#include \"readconf.h\"\n#include \"match.h\"\n#include \"kex.h\"\n#include \"mac.h\"\n#include \"uidswap.h\"\n#include \"myproposal.h\"\n#include \"digest.h\"\n\n/* Format of the configuration file:\n\n # Configuration data is parsed as follows:\n # 1. command line options\n # 2. user-specific file\n # 3. system-wide file\n # Any configuration value is only changed the first time it is set.\n # Thus, host-specific definitions should be at the beginning of the\n # configuration file, and defaults at the end.\n\n # Host-specific declarations. These may override anything above. A single\n # host may match multiple declarations; these are processed in the order\n # that they are given in.\n\n Host *.ngs.fi ngs.fi\n User foo\n\n Host fake.com\n HostName another.host.name.real.org\n User blaah\n Port 34289\n ForwardX11 no\n ForwardAgent no\n\n Host books.com\n RemoteForward 9999 shadows.cs.hut.fi:9999\n Ciphers 3des-cbc\n\n Host fascist.blob.com\n Port 23123\n User tylonen\n PasswordAuthentication no\n\n Host puukko.hut.fi\n User t35124p\n ProxyCommand ssh-proxy %h %p\n\n Host *.fr\n PublicKeyAuthentication no\n\n Host *.su\n Ciphers aes128-ctr\n PasswordAuthentication no\n\n Host vpn.fake.com\n Tunnel yes\n TunnelDevice 3\n\n # Defaults for various options\n Host *\n ForwardAgent no\n ForwardX11 no\n PasswordAuthentication yes\n RSAAuthentication yes\n RhostsRSAAuthentication yes\n StrictHostKeyChecking yes\n TcpKeepAlive no\n IdentityFile ~/.ssh/identity\n Port 22\n EscapeChar ~\n\n*/\n\nstatic int read_config_file_depth(const char *filename, struct passwd *pw,\n const char *host, const char *original_host, Options *options,\n int flags, int *activep, int depth);\nstatic int process_config_line_depth(Options *options, struct passwd *pw,\n const char *host, const char *original_host, char *line,\n const char *filename, int linenum, int *activep, int flags, int depth);\n\n/* Keyword tokens. */\n\ntypedef enum {\n\toBadOption,\n\toHost, oMatch, oInclude,\n\toForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,\n\toGatewayPorts, oExitOnForwardFailure,\n\toPasswordAuthentication, oRSAAuthentication,\n\toChallengeResponseAuthentication, oXAuthLocation,\n\toIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,\n\toCertificateFile, oAddKeysToAgent, oIdentityAgent,\n\toUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,\n\toGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,\n\toBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,\n\toCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,\n\toUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,\n\toPubkeyAuthentication,\n\toKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,\n\toDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,\n\toHostKeyAlgorithms, oBindAddress, oPKCS11Provider,\n\toClearAllForwardings, oNoHostAuthenticationForLocalhost,\n\toEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,\n\toAddressFamily, oGssAuthentication, oGssDelegateCreds,\n\toServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,\n\toSendEnv, oControlPath, oControlMaster, oControlPersist,\n\toHashKnownHosts,\n\toTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,\n\toVisualHostKey,\n\toKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,\n\toCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,\n\toCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,\n\toStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,\n\toFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,\n\toPubkeyAcceptedKeyTypes, oProxyJump,\n\toIgnoredUnknownOption, oDeprecated, oUnsupported\n} OpCodes;\n\n/* Textual representations of the tokens. */\n\nstatic struct {\n\tconst char *name;\n\tOpCodes opcode;\n} keywords[] = {\n\t/* Deprecated options */\n\t{ \"fallbacktorsh\", oDeprecated },\n\t{ \"globalknownhostsfile2\", oDeprecated },\n\t{ \"rhostsauthentication\", oDeprecated },\n\t{ \"userknownhostsfile2\", oDeprecated },\n\t{ \"useroaming\", oDeprecated },\n\t{ \"usersh\", oDeprecated },\n\n\t/* Unsupported options */\n\t{ \"afstokenpassing\", oUnsupported },\n\t{ \"kerberosauthentication\", oUnsupported },\n\t{ \"kerberostgtpassing\", oUnsupported },\n\n\t/* Sometimes-unsupported options */\n#if defined(GSSAPI)\n\t{ \"gssapiauthentication\", oGssAuthentication },\n\t{ \"gssapidelegatecredentials\", oGssDelegateCreds },\n# else\n\t{ \"gssapiauthentication\", oUnsupported },\n\t{ \"gssapidelegatecredentials\", oUnsupported },\n#endif\n#ifdef ENABLE_PKCS11\n\t{ \"smartcarddevice\", oPKCS11Provider },\n\t{ \"pkcs11provider\", oPKCS11Provider },\n# else\n\t{ \"smartcarddevice\", oUnsupported },\n\t{ \"pkcs11provider\", oUnsupported },\n#endif\n#ifdef WITH_SSH1\n\t{ \"rsaauthentication\", oRSAAuthentication },\n\t{ \"rhostsrsaauthentication\", oRhostsRSAAuthentication },\n\t{ \"compressionlevel\", oCompressionLevel },\n# else\n\t{ \"rsaauthentication\", oUnsupported },\n\t{ \"rhostsrsaauthentication\", oUnsupported },\n\t{ \"compressionlevel\", oUnsupported },\n#endif\n\n\t{ \"forwardagent\", oForwardAgent },\n\t{ \"forwardx11\", oForwardX11 },\n\t{ \"forwardx11trusted\", oForwardX11Trusted },\n\t{ \"forwardx11timeout\", oForwardX11Timeout },\n\t{ \"exitonforwardfailure\", oExitOnForwardFailure },\n\t{ \"xauthlocation\", oXAuthLocation },\n\t{ \"gatewayports\", oGatewayPorts },\n\t{ \"useprivilegedport\", oUsePrivilegedPort },\n\t{ \"passwordauthentication\", oPasswordAuthentication },\n\t{ \"kbdinteractiveauthentication\", oKbdInteractiveAuthentication },\n\t{ \"kbdinteractivedevices\", oKbdInteractiveDevices },\n\t{ \"pubkeyauthentication\", oPubkeyAuthentication },\n\t{ \"dsaauthentication\", oPubkeyAuthentication },\t\t /* alias */\n\t{ \"hostbasedauthentication\", oHostbasedAuthentication },\n\t{ \"challengeresponseauthentication\", oChallengeResponseAuthentication },\n\t{ \"skeyauthentication\", oChallengeResponseAuthentication }, /* alias */\n\t{ \"tisauthentication\", oChallengeResponseAuthentication }, /* alias */\n\t{ \"identityfile\", oIdentityFile },\n\t{ \"identityfile2\", oIdentityFile },\t\t\t/* obsolete */\n\t{ \"identitiesonly\", oIdentitiesOnly },\n\t{ \"certificatefile\", oCertificateFile },\n\t{ \"addkeystoagent\", oAddKeysToAgent },\n\t{ \"identityagent\", oIdentityAgent },\n\t{ \"hostname\", oHostName },\n\t{ \"hostkeyalias\", oHostKeyAlias },\n\t{ \"proxycommand\", oProxyCommand },\n\t{ \"port\", oPort },\n\t{ \"cipher\", oCipher },\n\t{ \"ciphers\", oCiphers },\n\t{ \"macs\", oMacs },\n\t{ \"protocol\", oProtocol },\n\t{ \"remoteforward\", oRemoteForward },\n\t{ \"localforward\", oLocalForward },\n\t{ \"user\", oUser },\n\t{ \"host\", oHost },\n\t{ \"match\", oMatch },\n\t{ \"escapechar\", oEscapeChar },\n\t{ \"globalknownhostsfile\", oGlobalKnownHostsFile },\n\t{ \"userknownhostsfile\", oUserKnownHostsFile },\n\t{ \"connectionattempts\", oConnectionAttempts },\n\t{ \"batchmode\", oBatchMode },\n\t{ \"checkhostip\", oCheckHostIP },\n\t{ \"stricthostkeychecking\", oStrictHostKeyChecking },\n\t{ \"compression\", oCompression },\n\t{ \"tcpkeepalive\", oTCPKeepAlive },\n\t{ \"keepalive\", oTCPKeepAlive },\t\t\t\t/* obsolete */\n\t{ \"numberofpasswordprompts\", oNumberOfPasswordPrompts },\n\t{ \"loglevel\", oLogLevel },\n\t{ \"dynamicforward\", oDynamicForward },\n\t{ \"preferredauthentications\", oPreferredAuthentications },\n\t{ \"hostkeyalgorithms\", oHostKeyAlgorithms },\n\t{ \"bindaddress\", oBindAddress },\n\t{ \"clearallforwardings\", oClearAllForwardings },\n\t{ \"enablesshkeysign\", oEnableSSHKeysign },\n\t{ \"verifyhostkeydns\", oVerifyHostKeyDNS },\n\t{ \"nohostauthenticationforlocalhost\", oNoHostAuthenticationForLocalhost },\n\t{ \"rekeylimit\", oRekeyLimit },\n\t{ \"connecttimeout\", oConnectTimeout },\n\t{ \"addressfamily\", oAddressFamily },\n\t{ \"serveraliveinterval\", oServerAliveInterval },\n\t{ \"serveralivecountmax\", oServerAliveCountMax },\n\t{ \"sendenv\", oSendEnv },\n\t{ \"controlpath\", oControlPath },\n\t{ \"controlmaster\", oControlMaster },\n\t{ \"controlpersist\", oControlPersist },\n\t{ \"hashknownhosts\", oHashKnownHosts },\n\t{ \"include\", oInclude },\n\t{ \"tunnel\", oTunnel },\n\t{ \"tunneldevice\", oTunnelDevice },\n\t{ \"localcommand\", oLocalCommand },\n\t{ \"permitlocalcommand\", oPermitLocalCommand },\n\t{ \"visualhostkey\", oVisualHostKey },\n\t{ \"kexalgorithms\", oKexAlgorithms },\n\t{ \"ipqos\", oIPQoS },\n\t{ \"requesttty\", oRequestTTY },\n\t{ \"proxyusefdpass\", oProxyUseFdpass },\n\t{ \"canonicaldomains\", oCanonicalDomains },\n\t{ \"canonicalizefallbacklocal\", oCanonicalizeFallbackLocal },\n\t{ \"canonicalizehostname\", oCanonicalizeHostname },\n\t{ \"canonicalizemaxdots\", oCanonicalizeMaxDots },\n\t{ \"canonicalizepermittedcnames\", oCanonicalizePermittedCNAMEs },\n\t{ \"streamlocalbindmask\", oStreamLocalBindMask },\n\t{ \"streamlocalbindunlink\", oStreamLocalBindUnlink },\n\t{ \"revokedhostkeys\", oRevokedHostKeys },\n\t{ \"fingerprinthash\", oFingerprintHash },\n\t{ \"updatehostkeys\", oUpdateHostkeys },\n\t{ \"hostbasedkeytypes\", oHostbasedKeyTypes },\n\t{ \"pubkeyacceptedkeytypes\", oPubkeyAcceptedKeyTypes },\n\t{ \"ignoreunknown\", oIgnoreUnknown },\n\t{ \"proxyjump\", oProxyJump },\n\n\t{ NULL, oBadOption }\n};\n\n/*\n * Adds a local TCP/IP port forward to options. Never returns if there is an\n * error.\n */\n\nvoid\nadd_local_forward(Options *options, const struct Forward *newfwd)\n{\n\tstruct Forward *fwd;\n\textern uid_t original_real_uid;\n\tint i;\n\n\tif (!bind_permitted(newfwd->listen_port, original_real_uid) &&\n\t newfwd->listen_path == NULL)\n\t\tfatal(\"Privileged ports can only be forwarded by root.\");\n\t/* Don't add duplicates */\n\tfor (i = 0; i < options->num_local_forwards; i++) {\n\t\tif (forward_equals(newfwd, options->local_forwards + i))\n\t\t\treturn;\n\t}\n\toptions->local_forwards = xreallocarray(options->local_forwards,\n\t options->num_local_forwards + 1,\n\t sizeof(*options->local_forwards));\n\tfwd = &options->local_forwards[options->num_local_forwards++];\n\n\tfwd->listen_host = newfwd->listen_host;\n\tfwd->listen_port = newfwd->listen_port;\n\tfwd->listen_path = newfwd->listen_path;\n\tfwd->connect_host = newfwd->connect_host;\n\tfwd->connect_port = newfwd->connect_port;\n\tfwd->connect_path = newfwd->connect_path;\n}\n\n/*\n * Adds a remote TCP/IP port forward to options. Never returns if there is\n * an error.\n */\n\nvoid\nadd_remote_forward(Options *options, const struct Forward *newfwd)\n{\n\tstruct Forward *fwd;\n\tint i;\n\n\t/* Don't add duplicates */\n\tfor (i = 0; i < options->num_remote_forwards; i++) {\n\t\tif (forward_equals(newfwd, options->remote_forwards + i))\n\t\t\treturn;\n\t}\n\toptions->remote_forwards = xreallocarray(options->remote_forwards,\n\t options->num_remote_forwards + 1,\n\t sizeof(*options->remote_forwards));\n\tfwd = &options->remote_forwards[options->num_remote_forwards++];\n\n\tfwd->listen_host = newfwd->listen_host;\n\tfwd->listen_port = newfwd->listen_port;\n\tfwd->listen_path = newfwd->listen_path;\n\tfwd->connect_host = newfwd->connect_host;\n\tfwd->connect_port = newfwd->connect_port;\n\tfwd->connect_path = newfwd->connect_path;\n\tfwd->handle = newfwd->handle;\n\tfwd->allocated_port = 0;\n}\n\nstatic void\nclear_forwardings(Options *options)\n{\n\tint i;\n\n\tfor (i = 0; i < options->num_local_forwards; i++) {\n\t\tfree(options->local_forwards[i].listen_host);\n\t\tfree(options->local_forwards[i].listen_path);\n\t\tfree(options->local_forwards[i].connect_host);\n\t\tfree(options->local_forwards[i].connect_path);\n\t}\n\tif (options->num_local_forwards > 0) {\n\t\tfree(options->local_forwards);\n\t\toptions->local_forwards = NULL;\n\t}\n\toptions->num_local_forwards = 0;\n\tfor (i = 0; i < options->num_remote_forwards; i++) {\n\t\tfree(options->remote_forwards[i].listen_host);\n\t\tfree(options->remote_forwards[i].listen_path);\n\t\tfree(options->remote_forwards[i].connect_host);\n\t\tfree(options->remote_forwards[i].connect_path);\n\t}\n\tif (options->num_remote_forwards > 0) {\n\t\tfree(options->remote_forwards);\n\t\toptions->remote_forwards = NULL;\n\t}\n\toptions->num_remote_forwards = 0;\n\toptions->tun_open = SSH_TUNMODE_NO;\n}\n\nvoid\nadd_certificate_file(Options *options, const char *path, int userprovided)\n{\n\tint i;\n\n\tif (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)\n\t\tfatal(\"Too many certificate files specified (max %d)\",\n\t\t SSH_MAX_CERTIFICATE_FILES);\n\n\t/* Avoid registering duplicates */\n\tfor (i = 0; i < options->num_certificate_files; i++) {\n\t\tif (options->certificate_file_userprovided[i] == userprovided &&\n\t\t strcmp(options->certificate_files[i], path) == 0) {\n\t\t\tdebug2(\"%s: ignoring duplicate key %s\", __func__, path);\n\t\t\treturn;\n\t\t}\n\t}\n\n\toptions->certificate_file_userprovided[options->num_certificate_files] =\n\t userprovided;\n\toptions->certificate_files[options->num_certificate_files++] =\n\t xstrdup(path);\n}\n\nvoid\nadd_identity_file(Options *options, const char *dir, const char *filename,\n int userprovided)\n{\n\tchar *path;\n\tint i;\n\n\tif (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)\n\t\tfatal(\"Too many identity files specified (max %d)\",\n\t\t SSH_MAX_IDENTITY_FILES);\n\n\tif (dir == NULL) /* no dir, filename is absolute */\n\t\tpath = xstrdup(filename);\n\telse\n\t\t(void)xasprintf(&path, \"%.100s%.100s\", dir, filename);\n\n\t/* Avoid registering duplicates */\n\tfor (i = 0; i < options->num_identity_files; i++) {\n\t\tif (options->identity_file_userprovided[i] == userprovided &&\n\t\t strcmp(options->identity_files[i], path) == 0) {\n\t\t\tdebug2(\"%s: ignoring duplicate key %s\", __func__, path);\n\t\t\tfree(path);\n\t\t\treturn;\n\t\t}\n\t}\n\n\toptions->identity_file_userprovided[options->num_identity_files] =\n\t userprovided;\n\toptions->identity_files[options->num_identity_files++] = path;\n}\n\nint\ndefault_ssh_port(void)\n{\n\tstatic int port;\n\tstruct servent *sp;\n\n\tif (port == 0) {\n\t\tsp = getservbyname(SSH_SERVICE_NAME, \"tcp\");\n\t\tport = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;\n\t}\n\treturn port;\n}\n\n/*\n * Execute a command in a shell.\n * Return its exit status or -1 on abnormal exit.\n */\nstatic int\nexecute_in_shell(const char *cmd)\n{\n\tchar *shell;\n\tpid_t pid;\n\tint devnull, status;\n\textern uid_t original_real_uid;\n\n\tif ((shell = getenv(\"SHELL\")) == NULL)\n\t\tshell = _PATH_BSHELL;\n\n\t/* Need this to redirect subprocess stdin/out */\n\tif ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)\n\t\tfatal(\"open(/dev/null): %s\", strerror(errno));\n\n\tdebug(\"Executing command: '%.500s'\", cmd);\n\n\t/* Fork and execute the command. */\n\tif ((pid = fork()) == 0) {\n\t\tchar *argv[4];\n\n\t\t/* Child. Permanently give up superuser privileges. */\n\t\tpermanently_drop_suid(original_real_uid);\n\n\t\t/* Redirect child stdin and stdout. Leave stderr */\n\t\tif (dup2(devnull, STDIN_FILENO) == -1)\n\t\t\tfatal(\"dup2: %s\", strerror(errno));\n\t\tif (dup2(devnull, STDOUT_FILENO) == -1)\n\t\t\tfatal(\"dup2: %s\", strerror(errno));\n\t\tif (devnull > STDERR_FILENO)\n\t\t\tclose(devnull);\n\t\tclosefrom(STDERR_FILENO + 1);\n\n\t\targv[0] = shell;\n\t\targv[1] = \"-c\";\n\t\targv[2] = xstrdup(cmd);\n\t\targv[3] = NULL;\n\n\t\texecv(argv[0], argv);\n\t\terror(\"Unable to execute '%.100s': %s\", cmd, strerror(errno));\n\t\t/* Die with signal to make this error apparent to parent. */\n\t\tsignal(SIGTERM, SIG_DFL);\n\t\tkill(getpid(), SIGTERM);\n\t\t_exit(1);\n\t}\n\t/* Parent. */\n\tif (pid < 0)\n\t\tfatal(\"%s: fork: %.100s\", __func__, strerror(errno));\n\n\tclose(devnull);\n\n\twhile (waitpid(pid, &status, 0) == -1) {\n\t\tif (errno != EINTR && errno != EAGAIN)\n\t\t\tfatal(\"%s: waitpid: %s\", __func__, strerror(errno));\n\t}\n\tif (!WIFEXITED(status)) {\n\t\terror(\"command '%.100s' exited abnormally\", cmd);\n\t\treturn -1;\n\t}\n\tdebug3(\"command returned status %d\", WEXITSTATUS(status));\n\treturn WEXITSTATUS(status);\n}\n\n/*\n * Parse and execute a Match directive.\n */\nstatic int\nmatch_cfg_line(Options *options, char **condition, struct passwd *pw,\n const char *host_arg, const char *original_host, int post_canon,\n const char *filename, int linenum)\n{\n\tchar *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;\n\tconst char *ruser;\n\tint r, port, this_result, result = 1, attributes = 0, negate;\n\tchar thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];\n\n\t/*\n\t * Configuration is likely to be incomplete at this point so we\n\t * must be prepared to use default values.\n\t */\n\tport = options->port <= 0 ? default_ssh_port() : options->port;\n\truser = options->user == NULL ? pw->pw_name : options->user;\n\tif (post_canon) {\n\t\thost = xstrdup(options->hostname);\n\t} else if (options->hostname != NULL) {\n\t\t/* NB. Please keep in sync with ssh.c:main() */\n\t\thost = percent_expand(options->hostname,\n\t\t \"h\", host_arg, (char *)NULL);\n\t} else {\n\t\thost = xstrdup(host_arg);\n\t}\n\n\tdebug2(\"checking match for '%s' host %s originally %s\",\n\t cp, host, original_host);\n\twhile ((oattrib = attrib = strdelim(&cp)) && *attrib != '\\0') {\n\t\tcriteria = NULL;\n\t\tthis_result = 1;\n\t\tif ((negate = attrib[0] == '!'))\n\t\t\tattrib++;\n\t\t/* criteria \"all\" and \"canonical\" have no argument */\n\t\tif (strcasecmp(attrib, \"all\") == 0) {\n\t\t\tif (attributes > 1 ||\n\t\t\t ((arg = strdelim(&cp)) != NULL && *arg != '\\0')) {\n\t\t\t\terror(\"%.200s line %d: '%s' cannot be combined \"\n\t\t\t\t \"with other Match attributes\",\n\t\t\t\t filename, linenum, oattrib);\n\t\t\t\tresult = -1;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tif (result)\n\t\t\t\tresult = negate ? 0 : 1;\n\t\t\tgoto out;\n\t\t}\n\t\tattributes++;\n\t\tif (strcasecmp(attrib, \"canonical\") == 0) {\n\t\t\tr = !!post_canon; /* force bitmask member to boolean */\n\t\t\tif (r == (negate ? 1 : 0))\n\t\t\t\tthis_result = result = 0;\n\t\t\tdebug3(\"%.200s line %d: %smatched '%s'\",\n\t\t\t filename, linenum,\n\t\t\t this_result ? \"\" : \"not \", oattrib);\n\t\t\tcontinue;\n\t\t}\n\t\t/* All other criteria require an argument */\n\t\tif ((arg = strdelim(&cp)) == NULL || *arg == '\\0') {\n\t\t\terror(\"Missing Match criteria for %s\", attrib);\n\t\t\tresult = -1;\n\t\t\tgoto out;\n\t\t}\n\t\tif (strcasecmp(attrib, \"host\") == 0) {\n\t\t\tcriteria = xstrdup(host);\n\t\t\tr = match_hostname(host, arg) == 1;\n\t\t\tif (r == (negate ? 1 : 0))\n\t\t\t\tthis_result = result = 0;\n\t\t} else if (strcasecmp(attrib, \"originalhost\") == 0) {\n\t\t\tcriteria = xstrdup(original_host);\n\t\t\tr = match_hostname(original_host, arg) == 1;\n\t\t\tif (r == (negate ? 1 : 0))\n\t\t\t\tthis_result = result = 0;\n\t\t} else if (strcasecmp(attrib, \"user\") == 0) {\n\t\t\tcriteria = xstrdup(ruser);\n\t\t\tr = match_pattern_list(ruser, arg, 0) == 1;\n\t\t\tif (r == (negate ? 1 : 0))\n\t\t\t\tthis_result = result = 0;\n\t\t} else if (strcasecmp(attrib, \"localuser\") == 0) {\n\t\t\tcriteria = xstrdup(pw->pw_name);\n\t\t\tr = match_pattern_list(pw->pw_name, arg, 0) == 1;\n\t\t\tif (r == (negate ? 1 : 0))\n\t\t\t\tthis_result = result = 0;\n\t\t} else if (strcasecmp(attrib, \"exec\") == 0) {\n\t\t\tif (gethostname(thishost, sizeof(thishost)) == -1)\n\t\t\t\tfatal(\"gethostname: %s\", strerror(errno));\n\t\t\tstrlcpy(shorthost, thishost, sizeof(shorthost));\n\t\t\tshorthost[strcspn(thishost, \".\")] = '\\0';\n\t\t\tsnprintf(portstr, sizeof(portstr), \"%d\", port);\n\n\t\t\tcmd = percent_expand(arg,\n\t\t\t \"L\", shorthost,\n\t\t\t \"d\", pw->pw_dir,\n\t\t\t \"h\", host,\n\t\t\t \"l\", thishost,\n\t\t\t \"n\", original_host,\n\t\t\t \"p\", portstr,\n\t\t\t \"r\", ruser,\n\t\t\t \"u\", pw->pw_name,\n\t\t\t (char *)NULL);\n\t\t\tif (result != 1) {\n\t\t\t\t/* skip execution if prior predicate failed */\n\t\t\t\tdebug3(\"%.200s line %d: skipped exec \"\n\t\t\t\t \"\\\"%.100s\\\"\", filename, linenum, cmd);\n\t\t\t\tfree(cmd);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tr = execute_in_shell(cmd);\n\t\t\tif (r == -1) {\n\t\t\t\tfatal(\"%.200s line %d: match exec \"\n\t\t\t\t \"'%.100s' error\", filename,\n\t\t\t\t linenum, cmd);\n\t\t\t}\n\t\t\tcriteria = xstrdup(cmd);\n\t\t\tfree(cmd);\n\t\t\t/* Force exit status to boolean */\n\t\t\tr = r == 0;\n\t\t\tif (r == (negate ? 1 : 0))\n\t\t\t\tthis_result = result = 0;\n\t\t} else {\n\t\t\terror(\"Unsupported Match attribute %s\", attrib);\n\t\t\tresult = -1;\n\t\t\tgoto out;\n\t\t}\n\t\tdebug3(\"%.200s line %d: %smatched '%s \\\"%.100s\\\"' \",\n\t\t filename, linenum, this_result ? \"\": \"not \",\n\t\t oattrib, criteria);\n\t\tfree(criteria);\n\t}\n\tif (attributes == 0) {\n\t\terror(\"One or more attributes required for Match\");\n\t\tresult = -1;\n\t\tgoto out;\n\t}\n out:\n\tif (result != -1)\n\t\tdebug2(\"match %sfound\", result ? \"\" : \"not \");\n\t*condition = cp;\n\tfree(host);\n\treturn result;\n}\n\n/* Check and prepare a domain name: removes trailing '.' and lowercases */\nstatic void\nvalid_domain(char *name, const char *filename, int linenum)\n{\n\tsize_t i, l = strlen(name);\n\tu_char c, last = '\\0';\n\n\tif (l == 0)\n\t\tfatal(\"%s line %d: empty hostname suffix\", filename, linenum);\n\tif (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]))\n\t\tfatal(\"%s line %d: hostname suffix \\\"%.100s\\\" \"\n\t\t \"starts with invalid character\", filename, linenum, name);\n\tfor (i = 0; i < l; i++) {\n\t\tc = tolower((u_char)name[i]);\n\t\tname[i] = (char)c;\n\t\tif (last == '.' && c == '.')\n\t\t\tfatal(\"%s line %d: hostname suffix \\\"%.100s\\\" contains \"\n\t\t\t \"consecutive separators\", filename, linenum, name);\n\t\tif (c != '.' && c != '-' && !isalnum(c) &&\n\t\t c != '_') /* technically invalid, but common */\n\t\t\tfatal(\"%s line %d: hostname suffix \\\"%.100s\\\" contains \"\n\t\t\t \"invalid characters\", filename, linenum, name);\n\t\tlast = c;\n\t}\n\tif (name[l - 1] == '.')\n\t\tname[l - 1] = '\\0';\n}\n\n/*\n * Returns the number of the token pointed to by cp or oBadOption.\n */\nstatic OpCodes\nparse_token(const char *cp, const char *filename, int linenum,\n const char *ignored_unknown)\n{\n\tint i;\n\n\tfor (i = 0; keywords[i].name; i++)\n\t\tif (strcmp(cp, keywords[i].name) == 0)\n\t\t\treturn keywords[i].opcode;\n\tif (ignored_unknown != NULL &&\n\t match_pattern_list(cp, ignored_unknown, 1) == 1)\n\t\treturn oIgnoredUnknownOption;\n\terror(\"%s: line %d: Bad configuration option: %s\",\n\t filename, linenum, cp);\n\treturn oBadOption;\n}\n\n/* Multistate option parsing */\nstruct multistate {\n\tchar *key;\n\tint value;\n};\nstatic const struct multistate multistate_flag[] = {\n\t{ \"true\",\t\t\t1 },\n\t{ \"false\",\t\t\t0 },\n\t{ \"yes\",\t\t\t1 },\n\t{ \"no\",\t\t\t\t0 },\n\t{ NULL, -1 }\n};\nstatic const struct multistate multistate_yesnoask[] = {\n\t{ \"true\",\t\t\t1 },\n\t{ \"false\",\t\t\t0 },\n\t{ \"yes\",\t\t\t1 },\n\t{ \"no\",\t\t\t\t0 },\n\t{ \"ask\",\t\t\t2 },\n\t{ NULL, -1 }\n};\nstatic const struct multistate multistate_yesnoaskconfirm[] = {\n\t{ \"true\",\t\t\t1 },\n\t{ \"false\",\t\t\t0 },\n\t{ \"yes\",\t\t\t1 },\n\t{ \"no\",\t\t\t\t0 },\n\t{ \"ask\",\t\t\t2 },\n\t{ \"confirm\",\t\t\t3 },\n\t{ NULL, -1 }\n};\nstatic const struct multistate multistate_addressfamily[] = {\n\t{ \"inet\",\t\t\tAF_INET },\n\t{ \"inet6\",\t\t\tAF_INET6 },\n\t{ \"any\",\t\t\tAF_UNSPEC },\n\t{ NULL, -1 }\n};\nstatic const struct multistate multistate_controlmaster[] = {\n\t{ \"true\",\t\t\tSSHCTL_MASTER_YES },\n\t{ \"yes\",\t\t\tSSHCTL_MASTER_YES },\n\t{ \"false\",\t\t\tSSHCTL_MASTER_NO },\n\t{ \"no\",\t\t\t\tSSHCTL_MASTER_NO },\n\t{ \"auto\",\t\t\tSSHCTL_MASTER_AUTO },\n\t{ \"ask\",\t\t\tSSHCTL_MASTER_ASK },\n\t{ \"autoask\",\t\t\tSSHCTL_MASTER_AUTO_ASK },\n\t{ NULL, -1 }\n};\nstatic const struct multistate multistate_tunnel[] = {\n\t{ \"ethernet\",\t\t\tSSH_TUNMODE_ETHERNET },\n\t{ \"point-to-point\",\t\tSSH_TUNMODE_POINTOPOINT },\n\t{ \"true\",\t\t\tSSH_TUNMODE_DEFAULT },\n\t{ \"yes\",\t\t\tSSH_TUNMODE_DEFAULT },\n\t{ \"false\",\t\t\tSSH_TUNMODE_NO },\n\t{ \"no\",\t\t\t\tSSH_TUNMODE_NO },\n\t{ NULL, -1 }\n};\nstatic const struct multistate multistate_requesttty[] = {\n\t{ \"true\",\t\t\tREQUEST_TTY_YES },\n\t{ \"yes\",\t\t\tREQUEST_TTY_YES },\n\t{ \"false\",\t\t\tREQUEST_TTY_NO },\n\t{ \"no\",\t\t\t\tREQUEST_TTY_NO },\n\t{ \"force\",\t\t\tREQUEST_TTY_FORCE },\n\t{ \"auto\",\t\t\tREQUEST_TTY_AUTO },\n\t{ NULL, -1 }\n};\nstatic const struct multistate multistate_canonicalizehostname[] = {\n\t{ \"true\",\t\t\tSSH_CANONICALISE_YES },\n\t{ \"false\",\t\t\tSSH_CANONICALISE_NO },\n\t{ \"yes\",\t\t\tSSH_CANONICALISE_YES },\n\t{ \"no\",\t\t\t\tSSH_CANONICALISE_NO },\n\t{ \"always\",\t\t\tSSH_CANONICALISE_ALWAYS },\n\t{ NULL, -1 }\n};\n\n/*\n * Processes a single option line as used in the configuration files. This\n * only sets those values that have not already been set.\n */\nint\nprocess_config_line(Options *options, struct passwd *pw, const char *host,\n const char *original_host, char *line, const char *filename,\n int linenum, int *activep, int flags)\n{\n\treturn process_config_line_depth(options, pw, host, original_host,\n\t line, filename, linenum, activep, flags, 0);\n}\n\n#define WHITESPACE \" \\t\\r\\n\"\nstatic int\nprocess_config_line_depth(Options *options, struct passwd *pw, const char *host,\n const char *original_host, char *line, const char *filename,\n int linenum, int *activep, int flags, int depth)\n{\n\tchar *s, **charptr, *endofnumber, *keyword, *arg, *arg2;\n\tchar **cpptr, fwdarg[256];\n\tu_int i, *uintptr, max_entries = 0;\n\tint r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;\n\tLogLevel *log_level_ptr;\n\tlong long val64;\n\tsize_t len;\n\tstruct Forward fwd;\n\tconst struct multistate *multistate_ptr;\n\tstruct allowed_cname *cname;\n\tglob_t gl;\n\n\tif (activep == NULL) { /* We are processing a command line directive */\n\t\tcmdline = 1;\n\t\tactivep = &cmdline;\n\t}\n\n\t/* Strip trailing whitespace. Allow \\f (form feed) at EOL only */\n\tif ((len = strlen(line)) == 0)\n\t\treturn 0;\n\tfor (len--; len > 0; len--) {\n\t\tif (strchr(WHITESPACE \"\\f\", line[len]) == NULL)\n\t\t\tbreak;\n\t\tline[len] = '\\0';\n\t}\n\n\ts = line;\n\t/* Get the keyword. (Each line is supposed to begin with a keyword). */\n\tif ((keyword = strdelim(&s)) == NULL)\n\t\treturn 0;\n\t/* Ignore leading whitespace. */\n\tif (*keyword == '\\0')\n\t\tkeyword = strdelim(&s);\n\tif (keyword == NULL || !*keyword || *keyword == '\\n' || *keyword == '#')\n\t\treturn 0;\n\t/* Match lowercase keyword */\n\tlowercase(keyword);\n\n\topcode = parse_token(keyword, filename, linenum,\n\t options->ignored_unknown);\n\n\tswitch (opcode) {\n\tcase oBadOption:\n\t\t/* don't panic, but count bad options */\n\t\treturn -1;\n\tcase oIgnoredUnknownOption:\n\t\tdebug(\"%s line %d: Ignored unknown option \\\"%s\\\"\",\n\t\t filename, linenum, keyword);\n\t\treturn 0;\n\tcase oConnectTimeout:\n\t\tintptr = &options->connection_timeout;\nparse_time:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%s line %d: missing time value.\",\n\t\t\t filename, linenum);\n\t\tif (strcmp(arg, \"none\") == 0)\n\t\t\tvalue = -1;\n\t\telse if ((value = convtime(arg)) == -1)\n\t\t\tfatal(\"%s line %d: invalid time value.\",\n\t\t\t filename, linenum);\n\t\tif (*activep && *intptr == -1)\n\t\t\t*intptr = value;\n\t\tbreak;\n\n\tcase oForwardAgent:\n\t\tintptr = &options->forward_agent;\n parse_flag:\n\t\tmultistate_ptr = multistate_flag;\n parse_multistate:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%s line %d: missing argument.\",\n\t\t\t filename, linenum);\n\t\tvalue = -1;\n\t\tfor (i = 0; multistate_ptr[i].key != NULL; i++) {\n\t\t\tif (strcasecmp(arg, multistate_ptr[i].key) == 0) {\n\t\t\t\tvalue = multistate_ptr[i].value;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (value == -1)\n\t\t\tfatal(\"%s line %d: unsupported option \\\"%s\\\".\",\n\t\t\t filename, linenum, arg);\n\t\tif (*activep && *intptr == -1)\n\t\t\t*intptr = value;\n\t\tbreak;\n\n\tcase oForwardX11:\n\t\tintptr = &options->forward_x11;\n\t\tgoto parse_flag;\n\n\tcase oForwardX11Trusted:\n\t\tintptr = &options->forward_x11_trusted;\n\t\tgoto parse_flag;\n\n\tcase oForwardX11Timeout:\n\t\tintptr = &options->forward_x11_timeout;\n\t\tgoto parse_time;\n\n\tcase oGatewayPorts:\n\t\tintptr = &options->fwd_opts.gateway_ports;\n\t\tgoto parse_flag;\n\n\tcase oExitOnForwardFailure:\n\t\tintptr = &options->exit_on_forward_failure;\n\t\tgoto parse_flag;\n\n\tcase oUsePrivilegedPort:\n\t\tintptr = &options->use_privileged_port;\n\t\tgoto parse_flag;\n\n\tcase oPasswordAuthentication:\n\t\tintptr = &options->password_authentication;\n\t\tgoto parse_flag;\n\n\tcase oKbdInteractiveAuthentication:\n\t\tintptr = &options->kbd_interactive_authentication;\n\t\tgoto parse_flag;\n\n\tcase oKbdInteractiveDevices:\n\t\tcharptr = &options->kbd_interactive_devices;\n\t\tgoto parse_string;\n\n\tcase oPubkeyAuthentication:\n\t\tintptr = &options->pubkey_authentication;\n\t\tgoto parse_flag;\n\n\tcase oRSAAuthentication:\n\t\tintptr = &options->rsa_authentication;\n\t\tgoto parse_flag;\n\n\tcase oRhostsRSAAuthentication:\n\t\tintptr = &options->rhosts_rsa_authentication;\n\t\tgoto parse_flag;\n\n\tcase oHostbasedAuthentication:\n\t\tintptr = &options->hostbased_authentication;\n\t\tgoto parse_flag;\n\n\tcase oChallengeResponseAuthentication:\n\t\tintptr = &options->challenge_response_authentication;\n\t\tgoto parse_flag;\n\n\tcase oGssAuthentication:\n\t\tintptr = &options->gss_authentication;\n\t\tgoto parse_flag;\n\n\tcase oGssDelegateCreds:\n\t\tintptr = &options->gss_deleg_creds;\n\t\tgoto parse_flag;\n\n\tcase oBatchMode:\n\t\tintptr = &options->batch_mode;\n\t\tgoto parse_flag;\n\n\tcase oCheckHostIP:\n\t\tintptr = &options->check_host_ip;\n\t\tgoto parse_flag;\n\n\tcase oVerifyHostKeyDNS:\n\t\tintptr = &options->verify_host_key_dns;\n\t\tmultistate_ptr = multistate_yesnoask;\n\t\tgoto parse_multistate;\n\n\tcase oStrictHostKeyChecking:\n\t\tintptr = &options->strict_host_key_checking;\n\t\tmultistate_ptr = multistate_yesnoask;\n\t\tgoto parse_multistate;\n\n\tcase oCompression:\n\t\tintptr = &options->compression;\n\t\tgoto parse_flag;\n\n\tcase oTCPKeepAlive:\n\t\tintptr = &options->tcp_keep_alive;\n\t\tgoto parse_flag;\n\n\tcase oNoHostAuthenticationForLocalhost:\n\t\tintptr = &options->no_host_authentication_for_localhost;\n\t\tgoto parse_flag;\n\n\tcase oNumberOfPasswordPrompts:\n\t\tintptr = &options->number_of_password_prompts;\n\t\tgoto parse_int;\n\n\tcase oCompressionLevel:\n\t\tintptr = &options->compression_level;\n\t\tgoto parse_int;\n\n\tcase oRekeyLimit:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename,\n\t\t\t linenum);\n\t\tif (strcmp(arg, \"default\") == 0) {\n\t\t\tval64 = 0;\n\t\t} else {\n\t\t\tif (scan_scaled(arg, &val64) == -1)\n\t\t\t\tfatal(\"%.200s line %d: Bad number '%s': %s\",\n\t\t\t\t filename, linenum, arg, strerror(errno));\n\t\t\tif (val64 != 0 && val64 < 16)\n\t\t\t\tfatal(\"%.200s line %d: RekeyLimit too small\",\n\t\t\t\t filename, linenum);\n\t\t}\n\t\tif (*activep && options->rekey_limit == -1)\n\t\t\toptions->rekey_limit = val64;\n\t\tif (s != NULL) { /* optional rekey interval present */\n\t\t\tif (strcmp(s, \"none\") == 0) {\n\t\t\t\t(void)strdelim(&s);\t/* discard */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tintptr = &options->rekey_interval;\n\t\t\tgoto parse_time;\n\t\t}\n\t\tbreak;\n\n\tcase oIdentityFile:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tif (*activep) {\n\t\t\tintptr = &options->num_identity_files;\n\t\t\tif (*intptr >= SSH_MAX_IDENTITY_FILES)\n\t\t\t\tfatal(\"%.200s line %d: Too many identity files specified (max %d).\",\n\t\t\t\t filename, linenum, SSH_MAX_IDENTITY_FILES);\n\t\t\tadd_identity_file(options, NULL,\n\t\t\t arg, flags & SSHCONF_USERCONF);\n\t\t}\n\t\tbreak;\n\n\tcase oCertificateFile:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\",\n\t\t\t filename, linenum);\n\t\tif (*activep) {\n\t\t\tintptr = &options->num_certificate_files;\n\t\t\tif (*intptr >= SSH_MAX_CERTIFICATE_FILES) {\n\t\t\t\tfatal(\"%.200s line %d: Too many certificate \"\n\t\t\t\t \"files specified (max %d).\",\n\t\t\t\t filename, linenum,\n\t\t\t\t SSH_MAX_CERTIFICATE_FILES);\n\t\t\t}\n\t\t\tadd_certificate_file(options, arg,\n\t\t\t flags & SSHCONF_USERCONF);\n\t\t}\n\t\tbreak;\n\n\tcase oXAuthLocation:\n\t\tcharptr=&options->xauth_location;\n\t\tgoto parse_string;\n\n\tcase oUser:\n\t\tcharptr = &options->user;\nparse_string:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\",\n\t\t\t filename, linenum);\n\t\tif (*activep && *charptr == NULL)\n\t\t\t*charptr = xstrdup(arg);\n\t\tbreak;\n\n\tcase oGlobalKnownHostsFile:\n\t\tcpptr = (char **)&options->system_hostfiles;\n\t\tuintptr = &options->num_system_hostfiles;\n\t\tmax_entries = SSH_MAX_HOSTS_FILES;\nparse_char_array:\n\t\tif (*activep && *uintptr == 0) {\n\t\t\twhile ((arg = strdelim(&s)) != NULL && *arg != '\\0') {\n\t\t\t\tif ((*uintptr) >= max_entries)\n\t\t\t\t\tfatal(\"%s line %d: \"\n\t\t\t\t\t \"too many authorized keys files.\",\n\t\t\t\t\t filename, linenum);\n\t\t\t\tcpptr[(*uintptr)++] = xstrdup(arg);\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\n\tcase oUserKnownHostsFile:\n\t\tcpptr = (char **)&options->user_hostfiles;\n\t\tuintptr = &options->num_user_hostfiles;\n\t\tmax_entries = SSH_MAX_HOSTS_FILES;\n\t\tgoto parse_char_array;\n\n\tcase oHostName:\n\t\tcharptr = &options->hostname;\n\t\tgoto parse_string;\n\n\tcase oHostKeyAlias:\n\t\tcharptr = &options->host_key_alias;\n\t\tgoto parse_string;\n\n\tcase oPreferredAuthentications:\n\t\tcharptr = &options->preferred_authentications;\n\t\tgoto parse_string;\n\n\tcase oBindAddress:\n\t\tcharptr = &options->bind_address;\n\t\tgoto parse_string;\n\n\tcase oPKCS11Provider:\n\t\tcharptr = &options->pkcs11_provider;\n\t\tgoto parse_string;\n\n\tcase oProxyCommand:\n\t\tcharptr = &options->proxy_command;\n\t\t/* Ignore ProxyCommand if ProxyJump already specified */\n\t\tif (options->jump_host != NULL)\n\t\t\tcharptr = &options->jump_host; /* Skip below */\nparse_command:\n\t\tif (s == NULL)\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tlen = strspn(s, WHITESPACE \"=\");\n\t\tif (*activep && *charptr == NULL)\n\t\t\t*charptr = xstrdup(s + len);\n\t\treturn 0;\n\n\tcase oProxyJump:\n\t\tif (s == NULL) {\n\t\t\tfatal(\"%.200s line %d: Missing argument.\",\n\t\t\t filename, linenum);\n\t\t}\n\t\tlen = strspn(s, WHITESPACE \"=\");\n\t\tif (parse_jump(s + len, options, *activep) == -1) {\n\t\t\tfatal(\"%.200s line %d: Invalid ProxyJump \\\"%s\\\"\",\n\t\t\t filename, linenum, s + len);\n\t\t}\n\t\treturn 0;\n\n\tcase oPort:\n\t\tintptr = &options->port;\nparse_int:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tif (arg[0] < '0' || arg[0] > '9')\n\t\t\tfatal(\"%.200s line %d: Bad number.\", filename, linenum);\n\n\t\t/* Octal, decimal, or hex format? */\n\t\tvalue = strtol(arg, &endofnumber, 0);\n\t\tif (arg == endofnumber)\n\t\t\tfatal(\"%.200s line %d: Bad number.\", filename, linenum);\n\t\tif (*activep && *intptr == -1)\n\t\t\t*intptr = value;\n\t\tbreak;\n\n\tcase oConnectionAttempts:\n\t\tintptr = &options->connection_attempts;\n\t\tgoto parse_int;\n\n\tcase oCipher:\n\t\tintptr = &options->cipher;\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tvalue = cipher_number(arg);\n\t\tif (value == -1)\n\t\t\tfatal(\"%.200s line %d: Bad cipher '%s'.\",\n\t\t\t filename, linenum, arg ? arg : \"\");\n\t\tif (*activep && *intptr == -1)\n\t\t\t*intptr = value;\n\t\tbreak;\n\n\tcase oCiphers:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tif (*arg != '-' && !ciphers_valid(*arg == '+' ? arg + 1 : arg))\n\t\t\tfatal(\"%.200s line %d: Bad SSH2 cipher spec '%s'.\",\n\t\t\t filename, linenum, arg ? arg : \"\");\n\t\tif (*activep && options->ciphers == NULL)\n\t\t\toptions->ciphers = xstrdup(arg);\n\t\tbreak;\n\n\tcase oMacs:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tif (*arg != '-' && !mac_valid(*arg == '+' ? arg + 1 : arg))\n\t\t\tfatal(\"%.200s line %d: Bad SSH2 Mac spec '%s'.\",\n\t\t\t filename, linenum, arg ? arg : \"\");\n\t\tif (*activep && options->macs == NULL)\n\t\t\toptions->macs = xstrdup(arg);\n\t\tbreak;\n\n\tcase oKexAlgorithms:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\",\n\t\t\t filename, linenum);\n\t\tif (*arg != '-' &&\n\t\t !kex_names_valid(*arg == '+' ? arg + 1 : arg))\n\t\t\tfatal(\"%.200s line %d: Bad SSH2 KexAlgorithms '%s'.\",\n\t\t\t filename, linenum, arg ? arg : \"\");\n\t\tif (*activep && options->kex_algorithms == NULL)\n\t\t\toptions->kex_algorithms = xstrdup(arg);\n\t\tbreak;\n\n\tcase oHostKeyAlgorithms:\n\t\tcharptr = &options->hostkeyalgorithms;\nparse_keytypes:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\",\n\t\t\t filename, linenum);\n\t\tif (*arg != '-' &&\n\t\t !sshkey_names_valid2(*arg == '+' ? arg + 1 : arg, 1))\n\t\t\tfatal(\"%s line %d: Bad key types '%s'.\",\n\t\t\t\tfilename, linenum, arg ? arg : \"\");\n\t\tif (*activep && *charptr == NULL)\n\t\t\t*charptr = xstrdup(arg);\n\t\tbreak;\n\n\tcase oProtocol:\n\t\tintptr = &options->protocol;\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tvalue = proto_spec(arg);\n\t\tif (value == SSH_PROTO_UNKNOWN)\n\t\t\tfatal(\"%.200s line %d: Bad protocol spec '%s'.\",\n\t\t\t filename, linenum, arg ? arg : \"\");\n\t\tif (*activep && *intptr == SSH_PROTO_UNKNOWN)\n\t\t\t*intptr = value;\n\t\tbreak;\n\n\tcase oLogLevel:\n\t\tlog_level_ptr = &options->log_level;\n\t\targ = strdelim(&s);\n\t\tvalue = log_level_number(arg);\n\t\tif (value == SYSLOG_LEVEL_NOT_SET)\n\t\t\tfatal(\"%.200s line %d: unsupported log level '%s'\",\n\t\t\t filename, linenum, arg ? arg : \"\");\n\t\tif (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)\n\t\t\t*log_level_ptr = (LogLevel) value;\n\t\tbreak;\n\n\tcase oLocalForward:\n\tcase oRemoteForward:\n\tcase oDynamicForward:\n\t\targ = strdelim(&s);\n\t\tif (arg == NULL || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing port argument.\",\n\t\t\t filename, linenum);\n\n\t\tif (opcode == oLocalForward ||\n\t\t opcode == oRemoteForward) {\n\t\t\targ2 = strdelim(&s);\n\t\t\tif (arg2 == NULL || *arg2 == '\\0')\n\t\t\t\tfatal(\"%.200s line %d: Missing target argument.\",\n\t\t\t\t filename, linenum);\n\n\t\t\t/* construct a string for parse_forward */\n\t\t\tsnprintf(fwdarg, sizeof(fwdarg), \"%s:%s\", arg, arg2);\n\t\t} else if (opcode == oDynamicForward) {\n\t\t\tstrlcpy(fwdarg, arg, sizeof(fwdarg));\n\t\t}\n\n\t\tif (parse_forward(&fwd, fwdarg,\n\t\t opcode == oDynamicForward ? 1 : 0,\n\t\t opcode == oRemoteForward ? 1 : 0) == 0)\n\t\t\tfatal(\"%.200s line %d: Bad forwarding specification.\",\n\t\t\t filename, linenum);\n\n\t\tif (*activep) {\n\t\t\tif (opcode == oLocalForward ||\n\t\t\t opcode == oDynamicForward)\n\t\t\t\tadd_local_forward(options, &fwd);\n\t\t\telse if (opcode == oRemoteForward)\n\t\t\t\tadd_remote_forward(options, &fwd);\n\t\t}\n\t\tbreak;\n\n\tcase oClearAllForwardings:\n\t\tintptr = &options->clear_forwardings;\n\t\tgoto parse_flag;\n\n\tcase oHost:\n\t\tif (cmdline)\n\t\t\tfatal(\"Host directive not supported as a command-line \"\n\t\t\t \"option\");\n\t\t*activep = 0;\n\t\targ2 = NULL;\n\t\twhile ((arg = strdelim(&s)) != NULL && *arg != '\\0') {\n\t\t\tif ((flags & SSHCONF_NEVERMATCH) != 0)\n\t\t\t\tbreak;\n\t\t\tnegated = *arg == '!';\n\t\t\tif (negated)\n\t\t\t\targ++;\n\t\t\tif (match_pattern(host, arg)) {\n\t\t\t\tif (negated) {\n\t\t\t\t\tdebug(\"%.200s line %d: Skipping Host \"\n\t\t\t\t\t \"block because of negated match \"\n\t\t\t\t\t \"for %.100s\", filename, linenum,\n\t\t\t\t\t arg);\n\t\t\t\t\t*activep = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!*activep)\n\t\t\t\t\targ2 = arg; /* logged below */\n\t\t\t\t*activep = 1;\n\t\t\t}\n\t\t}\n\t\tif (*activep)\n\t\t\tdebug(\"%.200s line %d: Applying options for %.100s\",\n\t\t\t filename, linenum, arg2);\n\t\t/* Avoid garbage check below, as strdelim is done. */\n\t\treturn 0;\n\n\tcase oMatch:\n\t\tif (cmdline)\n\t\t\tfatal(\"Host directive not supported as a command-line \"\n\t\t\t \"option\");\n\t\tvalue = match_cfg_line(options, &s, pw, host, original_host,\n\t\t flags & SSHCONF_POSTCANON, filename, linenum);\n\t\tif (value < 0)\n\t\t\tfatal(\"%.200s line %d: Bad Match condition\", filename,\n\t\t\t linenum);\n\t\t*activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value;\n\t\tbreak;\n\n\tcase oEscapeChar:\n\t\tintptr = &options->escape_char;\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tif (strcmp(arg, \"none\") == 0)\n\t\t\tvalue = SSH_ESCAPECHAR_NONE;\n\t\telse if (arg[1] == '\\0')\n\t\t\tvalue = (u_char) arg[0];\n\t\telse if (arg[0] == '^' && arg[2] == 0 &&\n\t\t (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)\n\t\t\tvalue = (u_char) arg[1] & 31;\n\t\telse {\n\t\t\tfatal(\"%.200s line %d: Bad escape character.\",\n\t\t\t filename, linenum);\n\t\t\t/* NOTREACHED */\n\t\t\tvalue = 0;\t/* Avoid compiler warning. */\n\t\t}\n\t\tif (*activep && *intptr == -1)\n\t\t\t*intptr = value;\n\t\tbreak;\n\n\tcase oAddressFamily:\n\t\tintptr = &options->address_family;\n\t\tmultistate_ptr = multistate_addressfamily;\n\t\tgoto parse_multistate;\n\n\tcase oEnableSSHKeysign:\n\t\tintptr = &options->enable_ssh_keysign;\n\t\tgoto parse_flag;\n\n\tcase oIdentitiesOnly:\n\t\tintptr = &options->identities_only;\n\t\tgoto parse_flag;\n\n\tcase oServerAliveInterval:\n\t\tintptr = &options->server_alive_interval;\n\t\tgoto parse_time;\n\n\tcase oServerAliveCountMax:\n\t\tintptr = &options->server_alive_count_max;\n\t\tgoto parse_int;\n\n\tcase oSendEnv:\n\t\twhile ((arg = strdelim(&s)) != NULL && *arg != '\\0') {\n\t\t\tif (strchr(arg, '=') != NULL)\n\t\t\t\tfatal(\"%s line %d: Invalid environment name.\",\n\t\t\t\t filename, linenum);\n\t\t\tif (!*activep)\n\t\t\t\tcontinue;\n\t\t\tif (options->num_send_env >= MAX_SEND_ENV)\n\t\t\t\tfatal(\"%s line %d: too many send env.\",\n\t\t\t\t filename, linenum);\n\t\t\toptions->send_env[options->num_send_env++] =\n\t\t\t xstrdup(arg);\n\t\t}\n\t\tbreak;\n\n\tcase oControlPath:\n\t\tcharptr = &options->control_path;\n\t\tgoto parse_string;\n\n\tcase oControlMaster:\n\t\tintptr = &options->control_master;\n\t\tmultistate_ptr = multistate_controlmaster;\n\t\tgoto parse_multistate;\n\n\tcase oControlPersist:\n\t\t/* no/false/yes/true, or a time spec */\n\t\tintptr = &options->control_persist;\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing ControlPersist\"\n\t\t\t \" argument.\", filename, linenum);\n\t\tvalue = 0;\n\t\tvalue2 = 0;\t/* timeout */\n\t\tif (strcmp(arg, \"no\") == 0 || strcmp(arg, \"false\") == 0)\n\t\t\tvalue = 0;\n\t\telse if (strcmp(arg, \"yes\") == 0 || strcmp(arg, \"true\") == 0)\n\t\t\tvalue = 1;\n\t\telse if ((value2 = convtime(arg)) >= 0)\n\t\t\tvalue = 1;\n\t\telse\n\t\t\tfatal(\"%.200s line %d: Bad ControlPersist argument.\",\n\t\t\t filename, linenum);\n\t\tif (*activep && *intptr == -1) {\n\t\t\t*intptr = value;\n\t\t\toptions->control_persist_timeout = value2;\n\t\t}\n\t\tbreak;\n\n\tcase oHashKnownHosts:\n\t\tintptr = &options->hash_known_hosts;\n\t\tgoto parse_flag;\n\n\tcase oTunnel:\n\t\tintptr = &options->tun_open;\n\t\tmultistate_ptr = multistate_tunnel;\n\t\tgoto parse_multistate;\n\n\tcase oTunnelDevice:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\", filename, linenum);\n\t\tvalue = a2tun(arg, &value2);\n\t\tif (value == SSH_TUNID_ERR)\n\t\t\tfatal(\"%.200s line %d: Bad tun device.\", filename, linenum);\n\t\tif (*activep) {\n\t\t\toptions->tun_local = value;\n\t\t\toptions->tun_remote = value2;\n\t\t}\n\t\tbreak;\n\n\tcase oLocalCommand:\n\t\tcharptr = &options->local_command;\n\t\tgoto parse_command;\n\n\tcase oPermitLocalCommand:\n\t\tintptr = &options->permit_local_command;\n\t\tgoto parse_flag;\n\n\tcase oVisualHostKey:\n\t\tintptr = &options->visual_host_key;\n\t\tgoto parse_flag;\n\n\tcase oInclude:\n\t\tif (cmdline)\n\t\t\tfatal(\"Include directive not supported as a \"\n\t\t\t \"command-line option\");\n\t\tvalue = 0;\n\t\twhile ((arg = strdelim(&s)) != NULL && *arg != '\\0') {\n\t\t\t/*\n\t\t\t * Ensure all paths are anchored. User configuration\n\t\t\t * files may begin with '~/' but system configurations\n\t\t\t * must not. If the path is relative, then treat it\n\t\t\t * as living in ~/.ssh for user configurations or\n\t\t\t * /etc/ssh for system ones.\n\t\t\t */\n\t\t\tif (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)\n\t\t\t\tfatal(\"%.200s line %d: bad include path %s.\",\n\t\t\t\t filename, linenum, arg);\n\t\t\tif (*arg != '/' && *arg != '~') {\n\t\t\t\txasprintf(&arg2, \"%s/%s\",\n\t\t\t\t (flags & SSHCONF_USERCONF) ?\n\t\t\t\t \"~/\" _PATH_SSH_USER_DIR : SSHDIR, arg);\n\t\t\t} else\n\t\t\t\targ2 = xstrdup(arg);\n\t\t\tmemset(&gl, 0, sizeof(gl));\n\t\t\tr = glob(arg2, GLOB_TILDE, NULL, &gl);\n\t\t\tif (r == GLOB_NOMATCH) {\n\t\t\t\tdebug(\"%.200s line %d: include %s matched no \"\n\t\t\t\t \"files\",filename, linenum, arg2);\n\t\t\t\tfree(arg2);\n\t\t\t\tcontinue;\n\t\t\t} else if (r != 0 || gl.gl_pathc < 0)\n\t\t\t\tfatal(\"%.200s line %d: glob failed for %s.\",\n\t\t\t\t filename, linenum, arg2);\n\t\t\tfree(arg2);\n\t\t\toactive = *activep;\n\t\t\tfor (i = 0; i < (u_int)gl.gl_pathc; i++) {\n\t\t\t\tdebug3(\"%.200s line %d: Including file %s \"\n\t\t\t\t \"depth %d%s\", filename, linenum,\n\t\t\t\t gl.gl_pathv[i], depth,\n\t\t\t\t oactive ? \"\" : \" (parse only)\");\n\t\t\t\tr = read_config_file_depth(gl.gl_pathv[i],\n\t\t\t\t pw, host, original_host, options,\n\t\t\t\t flags | SSHCONF_CHECKPERM |\n\t\t\t\t (oactive ? 0 : SSHCONF_NEVERMATCH),\n\t\t\t\t activep, depth + 1);\n\t\t\t\tif (r != 1 && errno != ENOENT) {\n\t\t\t\t\tfatal(\"Can't open user config file \"\n\t\t\t\t\t \"%.100s: %.100s\", gl.gl_pathv[i],\n\t\t\t\t\t strerror(errno));\n\t\t\t\t}\n\t\t\t\t/*\n\t\t\t\t * don't let Match in includes clobber the\n\t\t\t\t * containing file's Match state.\n\t\t\t\t */\n\t\t\t\t*activep = oactive;\n\t\t\t\tif (r != 1)\n\t\t\t\t\tvalue = -1;\n\t\t\t}\n\t\t\tglobfree(&gl);\n\t\t}\n\t\tif (value != 0)\n\t\t\treturn value;\n\t\tbreak;\n\n\tcase oIPQoS:\n\t\targ = strdelim(&s);\n\t\tif ((value = parse_ipqos(arg)) == -1)\n\t\t\tfatal(\"%s line %d: Bad IPQoS value: %s\",\n\t\t\t filename, linenum, arg);\n\t\targ = strdelim(&s);\n\t\tif (arg == NULL)\n\t\t\tvalue2 = value;\n\t\telse if ((value2 = parse_ipqos(arg)) == -1)\n\t\t\tfatal(\"%s line %d: Bad IPQoS value: %s\",\n\t\t\t filename, linenum, arg);\n\t\tif (*activep) {\n\t\t\toptions->ip_qos_interactive = value;\n\t\t\toptions->ip_qos_bulk = value2;\n\t\t}\n\t\tbreak;\n\n\tcase oRequestTTY:\n\t\tintptr = &options->request_tty;\n\t\tmultistate_ptr = multistate_requesttty;\n\t\tgoto parse_multistate;\n\n\tcase oIgnoreUnknown:\n\t\tcharptr = &options->ignored_unknown;\n\t\tgoto parse_string;\n\n\tcase oProxyUseFdpass:\n\t\tintptr = &options->proxy_use_fdpass;\n\t\tgoto parse_flag;\n\n\tcase oCanonicalDomains:\n\t\tvalue = options->num_canonical_domains != 0;\n\t\twhile ((arg = strdelim(&s)) != NULL && *arg != '\\0') {\n\t\t\tvalid_domain(arg, filename, linenum);\n\t\t\tif (!*activep || value)\n\t\t\t\tcontinue;\n\t\t\tif (options->num_canonical_domains >= MAX_CANON_DOMAINS)\n\t\t\t\tfatal(\"%s line %d: too many hostname suffixes.\",\n\t\t\t\t filename, linenum);\n\t\t\toptions->canonical_domains[\n\t\t\t options->num_canonical_domains++] = xstrdup(arg);\n\t\t}\n\t\tbreak;\n\n\tcase oCanonicalizePermittedCNAMEs:\n\t\tvalue = options->num_permitted_cnames != 0;\n\t\twhile ((arg = strdelim(&s)) != NULL && *arg != '\\0') {\n\t\t\t/* Either '*' for everything or 'list:list' */\n\t\t\tif (strcmp(arg, \"*\") == 0)\n\t\t\t\targ2 = arg;\n\t\t\telse {\n\t\t\t\tlowercase(arg);\n\t\t\t\tif ((arg2 = strchr(arg, ':')) == NULL ||\n\t\t\t\t arg2[1] == '\\0') {\n\t\t\t\t\tfatal(\"%s line %d: \"\n\t\t\t\t\t \"Invalid permitted CNAME \\\"%s\\\"\",\n\t\t\t\t\t filename, linenum, arg);\n\t\t\t\t}\n\t\t\t\t*arg2 = '\\0';\n\t\t\t\targ2++;\n\t\t\t}\n\t\t\tif (!*activep || value)\n\t\t\t\tcontinue;\n\t\t\tif (options->num_permitted_cnames >= MAX_CANON_DOMAINS)\n\t\t\t\tfatal(\"%s line %d: too many permitted CNAMEs.\",\n\t\t\t\t filename, linenum);\n\t\t\tcname = options->permitted_cnames +\n\t\t\t options->num_permitted_cnames++;\n\t\t\tcname->source_list = xstrdup(arg);\n\t\t\tcname->target_list = xstrdup(arg2);\n\t\t}\n\t\tbreak;\n\n\tcase oCanonicalizeHostname:\n\t\tintptr = &options->canonicalize_hostname;\n\t\tmultistate_ptr = multistate_canonicalizehostname;\n\t\tgoto parse_multistate;\n\n\tcase oCanonicalizeMaxDots:\n\t\tintptr = &options->canonicalize_max_dots;\n\t\tgoto parse_int;\n\n\tcase oCanonicalizeFallbackLocal:\n\t\tintptr = &options->canonicalize_fallback_local;\n\t\tgoto parse_flag;\n\n\tcase oStreamLocalBindMask:\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing StreamLocalBindMask argument.\", filename, linenum);\n\t\t/* Parse mode in octal format */\n\t\tvalue = strtol(arg, &endofnumber, 8);\n\t\tif (arg == endofnumber || value < 0 || value > 0777)\n\t\t\tfatal(\"%.200s line %d: Bad mask.\", filename, linenum);\n\t\toptions->fwd_opts.streamlocal_bind_mask = (mode_t)value;\n\t\tbreak;\n\n\tcase oStreamLocalBindUnlink:\n\t\tintptr = &options->fwd_opts.streamlocal_bind_unlink;\n\t\tgoto parse_flag;\n\n\tcase oRevokedHostKeys:\n\t\tcharptr = &options->revoked_host_keys;\n\t\tgoto parse_string;\n\n\tcase oFingerprintHash:\n\t\tintptr = &options->fingerprint_hash;\n\t\targ = strdelim(&s);\n\t\tif (!arg || *arg == '\\0')\n\t\t\tfatal(\"%.200s line %d: Missing argument.\",\n\t\t\t filename, linenum);\n\t\tif ((value = ssh_digest_alg_by_name(arg)) == -1)\n\t\t\tfatal(\"%.200s line %d: Invalid hash algorithm \\\"%s\\\".\",\n\t\t\t filename, linenum, arg);\n\t\tif (*activep && *intptr == -1)\n\t\t\t*intptr = value;\n\t\tbreak;\n\n\tcase oUpdateHostkeys:\n\t\tintptr = &options->update_hostkeys;\n\t\tmultistate_ptr = multistate_yesnoask;\n\t\tgoto parse_multistate;\n\n\tcase oHostbasedKeyTypes:\n\t\tcharptr = &options->hostbased_key_types;\n\t\tgoto parse_keytypes;\n\n\tcase oPubkeyAcceptedKeyTypes:\n\t\tcharptr = &options->pubkey_key_types;\n\t\tgoto parse_keytypes;\n\n\tcase oAddKeysToAgent:\n\t\tintptr = &options->add_keys_to_agent;\n\t\tmultistate_ptr = multistate_yesnoaskconfirm;\n\t\tgoto parse_multistate;\n\n\tcase oIdentityAgent:\n\t\tcharptr = &options->identity_agent;\n\t\tgoto parse_string;\n\n\tcase oDeprecated:\n\t\tdebug(\"%s line %d: Deprecated option \\\"%s\\\"\",\n\t\t filename, linenum, keyword);\n\t\treturn 0;\n\n\tcase oUnsupported:\n\t\terror(\"%s line %d: Unsupported option \\\"%s\\\"\",\n\t\t filename, linenum, keyword);\n\t\treturn 0;\n\n\tdefault:\n\t\tfatal(\"%s: Unimplemented opcode %d\", __func__, opcode);\n\t}\n\n\t/* Check that there is no garbage at end of line. */\n\tif ((arg = strdelim(&s)) != NULL && *arg != '\\0') {\n\t\tfatal(\"%.200s line %d: garbage at end of line; \\\"%.200s\\\".\",\n\t\t filename, linenum, arg);\n\t}\n\treturn 0;\n}\n\n/*\n * Reads the config file and modifies the options accordingly. Options\n * should already be initialized before this call. This never returns if\n * there is an error. If the file does not exist, this returns 0.\n */\nint\nread_config_file(const char *filename, struct passwd *pw, const char *host,\n const char *original_host, Options *options, int flags)\n{\n\tint active = 1;\n\n\treturn read_config_file_depth(filename, pw, host, original_host,\n\t options, flags, &active, 0);\n}\n\n#define READCONF_MAX_DEPTH\t16\nstatic int\nread_config_file_depth(const char *filename, struct passwd *pw,\n const char *host, const char *original_host, Options *options,\n int flags, int *activep, int depth)\n{\n\tFILE *f;\n\tchar line[4096];\n\tint linenum;\n\tint bad_options = 0;\n\n\tif (depth < 0 || depth > READCONF_MAX_DEPTH)\n\t\tfatal(\"Too many recursive configuration includes\");\n\n\tif ((f = fopen(filename, \"r\")) == NULL)\n\t\treturn 0;\n\n\tif (flags & SSHCONF_CHECKPERM) {\n\t\tstruct stat sb;\n\n\t\tif (fstat(fileno(f), &sb) == -1)\n\t\t\tfatal(\"fstat %s: %s\", filename, strerror(errno));\n\t\tif (((sb.st_uid != 0 && sb.st_uid != getuid()) ||\n\t\t (sb.st_mode & 022) != 0))\n\t\t\tfatal(\"Bad owner or permissions on %s\", filename);\n\t}\n\n\tdebug(\"Reading configuration data %.200s\", filename);\n\n\t/*\n\t * Mark that we are now processing the options. This flag is turned\n\t * on/off by Host specifications.\n\t */\n\tlinenum = 0;\n\twhile (fgets(line, sizeof(line), f)) {\n\t\t/* Update line number counter. */\n\t\tlinenum++;\n\t\tif (strlen(line) == sizeof(line) - 1)\n\t\t\tfatal(\"%s line %d too long\", filename, linenum);\n\t\tif (process_config_line_depth(options, pw, host, original_host,\n\t\t line, filename, linenum, activep, flags, depth) != 0)\n\t\t\tbad_options++;\n\t}\n\tfclose(f);\n\tif (bad_options > 0)\n\t\tfatal(\"%s: terminating, %d bad configuration options\",\n\t\t filename, bad_options);\n\treturn 1;\n}\n\n/* Returns 1 if a string option is unset or set to \"none\" or 0 otherwise. */\nint\noption_clear_or_none(const char *o)\n{\n\treturn o == NULL || strcasecmp(o, \"none\") == 0;\n}\n\n/*\n * Initializes options to special values that indicate that they have not yet\n * been set. Read_config_file will only set options with this value. Options\n * are processed in the following order: command line, user config file,\n * system config file. Last, fill_default_options is called.\n */\n\nvoid\ninitialize_options(Options * options)\n{\n\tmemset(options, 'X', sizeof(*options));\n\toptions->forward_agent = -1;\n\toptions->forward_x11 = -1;\n\toptions->forward_x11_trusted = -1;\n\toptions->forward_x11_timeout = -1;\n\toptions->stdio_forward_host = NULL;\n\toptions->stdio_forward_port = 0;\n\toptions->clear_forwardings = -1;\n\toptions->exit_on_forward_failure = -1;\n\toptions->xauth_location = NULL;\n\toptions->fwd_opts.gateway_ports = -1;\n\toptions->fwd_opts.streamlocal_bind_mask = (mode_t)-1;\n\toptions->fwd_opts.streamlocal_bind_unlink = -1;\n\toptions->use_privileged_port = -1;\n\toptions->rsa_authentication = -1;\n\toptions->pubkey_authentication = -1;\n\toptions->challenge_response_authentication = -1;\n\toptions->gss_authentication = -1;\n\toptions->gss_deleg_creds = -1;\n\toptions->password_authentication = -1;\n\toptions->kbd_interactive_authentication = -1;\n\toptions->kbd_interactive_devices = NULL;\n\toptions->rhosts_rsa_authentication = -1;\n\toptions->hostbased_authentication = -1;\n\toptions->batch_mode = -1;\n\toptions->check_host_ip = -1;\n\toptions->strict_host_key_checking = -1;\n\toptions->compression = -1;\n\toptions->tcp_keep_alive = -1;\n\toptions->compression_level = -1;\n\toptions->port = -1;\n\toptions->address_family = -1;\n\toptions->connection_attempts = -1;\n\toptions->connection_timeout = -1;\n\toptions->number_of_password_prompts = -1;\n\toptions->cipher = -1;\n\toptions->ciphers = NULL;\n\toptions->macs = NULL;\n\toptions->kex_algorithms = NULL;\n\toptions->hostkeyalgorithms = NULL;\n\toptions->protocol = SSH_PROTO_UNKNOWN;\n\toptions->num_identity_files = 0;\n\toptions->num_certificate_files = 0;\n\toptions->hostname = NULL;\n\toptions->host_key_alias = NULL;\n\toptions->proxy_command = NULL;\n\toptions->jump_user = NULL;\n\toptions->jump_host = NULL;\n\toptions->jump_port = -1;\n\toptions->jump_extra = NULL;\n\toptions->user = NULL;\n\toptions->escape_char = -1;\n\toptions->num_system_hostfiles = 0;\n\toptions->num_user_hostfiles = 0;\n\toptions->local_forwards = NULL;\n\toptions->num_local_forwards = 0;\n\toptions->remote_forwards = NULL;\n\toptions->num_remote_forwards = 0;\n\toptions->log_level = SYSLOG_LEVEL_NOT_SET;\n\toptions->preferred_authentications = NULL;\n\toptions->bind_address = NULL;\n\toptions->pkcs11_provider = NULL;\n\toptions->enable_ssh_keysign = - 1;\n\toptions->no_host_authentication_for_localhost = - 1;\n\toptions->identities_only = - 1;\n\toptions->rekey_limit = - 1;\n\toptions->rekey_interval = -1;\n\toptions->verify_host_key_dns = -1;\n\toptions->server_alive_interval = -1;\n\toptions->server_alive_count_max = -1;\n\toptions->num_send_env = 0;\n\toptions->control_path = NULL;\n\toptions->control_master = -1;\n\toptions->control_persist = -1;\n\toptions->control_persist_timeout = 0;\n\toptions->hash_known_hosts = -1;\n\toptions->tun_open = -1;\n\toptions->tun_local = -1;\n\toptions->tun_remote = -1;\n\toptions->local_command = NULL;\n\toptions->permit_local_command = -1;\n\toptions->add_keys_to_agent = -1;\n\toptions->identity_agent = NULL;\n\toptions->visual_host_key = -1;\n\toptions->ip_qos_interactive = -1;\n\toptions->ip_qos_bulk = -1;\n\toptions->request_tty = -1;\n\toptions->proxy_use_fdpass = -1;\n\toptions->ignored_unknown = NULL;\n\toptions->num_canonical_domains = 0;\n\toptions->num_permitted_cnames = 0;\n\toptions->canonicalize_max_dots = -1;\n\toptions->canonicalize_fallback_local = -1;\n\toptions->canonicalize_hostname = -1;\n\toptions->revoked_host_keys = NULL;\n\toptions->fingerprint_hash = -1;\n\toptions->update_hostkeys = -1;\n\toptions->hostbased_key_types = NULL;\n\toptions->pubkey_key_types = NULL;\n}\n\n/*\n * A petite version of fill_default_options() that just fills the options\n * needed for hostname canonicalization to proceed.\n */\nvoid\nfill_default_options_for_canonicalization(Options *options)\n{\n\tif (options->canonicalize_max_dots == -1)\n\t\toptions->canonicalize_max_dots = 1;\n\tif (options->canonicalize_fallback_local == -1)\n\t\toptions->canonicalize_fallback_local = 1;\n\tif (options->canonicalize_hostname == -1)\n\t\toptions->canonicalize_hostname = SSH_CANONICALISE_NO;\n}\n\n/*\n * Called after processing other sources of option data, this fills those\n * options for which no value has been specified with their default values.\n */\nvoid\nfill_default_options(Options * options)\n{\n\tif (options->forward_agent == -1)\n\t\toptions->forward_agent = 0;\n\tif (options->forward_x11 == -1)\n\t\toptions->forward_x11 = 0;\n\tif (options->forward_x11_trusted == -1)\n\t\toptions->forward_x11_trusted = 0;\n\tif (options->forward_x11_timeout == -1)\n\t\toptions->forward_x11_timeout = 1200;\n\t/*\n\t * stdio forwarding (-W) changes the default for these but we defer\n\t * setting the values so they can be overridden.\n\t */\n\tif (options->exit_on_forward_failure == -1)\n\t\toptions->exit_on_forward_failure =\n\t\t options->stdio_forward_host != NULL ? 1 : 0;\n\tif (options->clear_forwardings == -1)\n\t\toptions->clear_forwardings =\n\t\t options->stdio_forward_host != NULL ? 1 : 0;\n\tif (options->clear_forwardings == 1)\n\t\tclear_forwardings(options);\n\n\tif (options->xauth_location == NULL)\n\t\toptions->xauth_location = _PATH_XAUTH;\n\tif (options->fwd_opts.gateway_ports == -1)\n\t\toptions->fwd_opts.gateway_ports = 0;\n\tif (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)\n\t\toptions->fwd_opts.streamlocal_bind_mask = 0177;\n\tif (options->fwd_opts.streamlocal_bind_unlink == -1)\n\t\toptions->fwd_opts.streamlocal_bind_unlink = 0;\n\tif (options->use_privileged_port == -1)\n\t\toptions->use_privileged_port = 0;\n\tif (options->rsa_authentication == -1)\n\t\toptions->rsa_authentication = 1;\n\tif (options->pubkey_authentication == -1)\n\t\toptions->pubkey_authentication = 1;\n\tif (options->challenge_response_authentication == -1)\n\t\toptions->challenge_response_authentication = 1;\n\tif (options->gss_authentication == -1)\n\t\toptions->gss_authentication = 0;\n\tif (options->gss_deleg_creds == -1)\n\t\toptions->gss_deleg_creds = 0;\n\tif (options->password_authentication == -1)\n\t\toptions->password_authentication = 1;\n\tif (options->kbd_interactive_authentication == -1)\n\t\toptions->kbd_interactive_authentication = 1;\n\tif (options->rhosts_rsa_authentication == -1)\n\t\toptions->rhosts_rsa_authentication = 0;\n\tif (options->hostbased_authentication == -1)\n\t\toptions->hostbased_authentication = 0;\n\tif (options->batch_mode == -1)\n\t\toptions->batch_mode = 0;\n\tif (options->check_host_ip == -1)\n\t\toptions->check_host_ip = 1;\n\tif (options->strict_host_key_checking == -1)\n\t\toptions->strict_host_key_checking = 2;\t/* 2 is default */\n\tif (options->compression == -1)\n\t\toptions->compression = 0;\n\tif (options->tcp_keep_alive == -1)\n\t\toptions->tcp_keep_alive = 1;\n\tif (options->compression_level == -1)\n\t\toptions->compression_level = 6;\n\tif (options->port == -1)\n\t\toptions->port = 0;\t/* Filled in ssh_connect. */\n\tif (options->address_family == -1)\n\t\toptions->address_family = AF_UNSPEC;\n\tif (options->connection_attempts == -1)\n\t\toptions->connection_attempts = 1;\n\tif (options->number_of_password_prompts == -1)\n\t\toptions->number_of_password_prompts = 3;\n\t/* Selected in ssh_login(). */\n\tif (options->cipher == -1)\n\t\toptions->cipher = SSH_CIPHER_NOT_SET;\n\t/* options->hostkeyalgorithms, default set in myproposals.h */\n\tif (options->protocol == SSH_PROTO_UNKNOWN)\n\t\toptions->protocol = SSH_PROTO_2;\n\tif (options->add_keys_to_agent == -1)\n\t\toptions->add_keys_to_agent = 0;\n\tif (options->num_identity_files == 0) {\n\t\tif (options->protocol & SSH_PROTO_1) {\n\t\t\tadd_identity_file(options, \"~/\",\n\t\t\t _PATH_SSH_CLIENT_IDENTITY, 0);\n\t\t}\n\t\tif (options->protocol & SSH_PROTO_2) {\n\t\t\tadd_identity_file(options, \"~/\",\n\t\t\t _PATH_SSH_CLIENT_ID_RSA, 0);\n\t\t\tadd_identity_file(options, \"~/\",\n\t\t\t _PATH_SSH_CLIENT_ID_DSA, 0);\n#ifdef OPENSSL_HAS_ECC\n\t\t\tadd_identity_file(options, \"~/\",\n\t\t\t _PATH_SSH_CLIENT_ID_ECDSA, 0);\n#endif\n\t\t\tadd_identity_file(options, \"~/\",\n\t\t\t _PATH_SSH_CLIENT_ID_ED25519, 0);\n\t\t}\n\t}\n\tif (options->escape_char == -1)\n\t\toptions->escape_char = '~';\n\tif (options->num_system_hostfiles == 0) {\n\t\toptions->system_hostfiles[options->num_system_hostfiles++] =\n\t\t xstrdup(_PATH_SSH_SYSTEM_HOSTFILE);\n\t\toptions->system_hostfiles[options->num_system_hostfiles++] =\n\t\t xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2);\n\t}\n\tif (options->num_user_hostfiles == 0) {\n\t\toptions->user_hostfiles[options->num_user_hostfiles++] =\n\t\t xstrdup(_PATH_SSH_USER_HOSTFILE);\n\t\toptions->user_hostfiles[options->num_user_hostfiles++] =\n\t\t xstrdup(_PATH_SSH_USER_HOSTFILE2);\n\t}\n\tif (options->log_level == SYSLOG_LEVEL_NOT_SET)\n\t\toptions->log_level = SYSLOG_LEVEL_INFO;\n\tif (options->no_host_authentication_for_localhost == - 1)\n\t\toptions->no_host_authentication_for_localhost = 0;\n\tif (options->identities_only == -1)\n\t\toptions->identities_only = 0;\n\tif (options->enable_ssh_keysign == -1)\n\t\toptions->enable_ssh_keysign = 0;\n\tif (options->rekey_limit == -1)\n\t\toptions->rekey_limit = 0;\n\tif (options->rekey_interval == -1)\n\t\toptions->rekey_interval = 0;\n\tif (options->verify_host_key_dns == -1)\n\t\toptions->verify_host_key_dns = 0;\n\tif (options->server_alive_interval == -1)\n\t\toptions->server_alive_interval = 0;\n\tif (options->server_alive_count_max == -1)\n\t\toptions->server_alive_count_max = 3;\n\tif (options->control_master == -1)\n\t\toptions->control_master = 0;\n\tif (options->control_persist == -1) {\n\t\toptions->control_persist = 0;\n\t\toptions->control_persist_timeout = 0;\n\t}\n\tif (options->hash_known_hosts == -1)\n\t\toptions->hash_known_hosts = 0;\n\tif (options->tun_open == -1)\n\t\toptions->tun_open = SSH_TUNMODE_NO;\n\tif (options->tun_local == -1)\n\t\toptions->tun_local = SSH_TUNID_ANY;\n\tif (options->tun_remote == -1)\n\t\toptions->tun_remote = SSH_TUNID_ANY;\n\tif (options->permit_local_command == -1)\n\t\toptions->permit_local_command = 0;\n\tif (options->visual_host_key == -1)\n\t\toptions->visual_host_key = 0;\n\tif (options->ip_qos_interactive == -1)\n\t\toptions->ip_qos_interactive = IPTOS_LOWDELAY;\n\tif (options->ip_qos_bulk == -1)\n\t\toptions->ip_qos_bulk = IPTOS_THROUGHPUT;\n\tif (options->request_tty == -1)\n\t\toptions->request_tty = REQUEST_TTY_AUTO;\n\tif (options->proxy_use_fdpass == -1)\n\t\toptions->proxy_use_fdpass = 0;\n\tif (options->canonicalize_max_dots == -1)\n\t\toptions->canonicalize_max_dots = 1;\n\tif (options->canonicalize_fallback_local == -1)\n\t\toptions->canonicalize_fallback_local = 1;\n\tif (options->canonicalize_hostname == -1)\n\t\toptions->canonicalize_hostname = SSH_CANONICALISE_NO;\n\tif (options->fingerprint_hash == -1)\n\t\toptions->fingerprint_hash = SSH_FP_HASH_DEFAULT;\n\tif (options->update_hostkeys == -1)\n\t\toptions->update_hostkeys = 0;\n\tif (kex_assemble_names(KEX_CLIENT_ENCRYPT, &options->ciphers) != 0 ||\n\t kex_assemble_names(KEX_CLIENT_MAC, &options->macs) != 0 ||\n\t kex_assemble_names(KEX_CLIENT_KEX, &options->kex_algorithms) != 0 ||\n\t kex_assemble_names(KEX_DEFAULT_PK_ALG,\n\t &options->hostbased_key_types) != 0 ||\n\t kex_assemble_names(KEX_DEFAULT_PK_ALG,\n\t &options->pubkey_key_types) != 0)\n\t\tfatal(\"%s: kex_assemble_names failed\", __func__);\n\n#define CLEAR_ON_NONE(v) \\\n\tdo { \\\n\t\tif (option_clear_or_none(v)) { \\\n\t\t\tfree(v); \\\n\t\t\tv = NULL; \\\n\t\t} \\\n\t} while(0)\n\tCLEAR_ON_NONE(options->local_command);\n\tCLEAR_ON_NONE(options->proxy_command);\n\tCLEAR_ON_NONE(options->control_path);\n\tCLEAR_ON_NONE(options->revoked_host_keys);\n\t/* options->identity_agent distinguishes NULL from 'none' */\n\t/* options->user will be set in the main program if appropriate */\n\t/* options->hostname will be set in the main program if appropriate */\n\t/* options->host_key_alias should not be set by default */\n\t/* options->preferred_authentications will be set in ssh */\n}\n\nstruct fwdarg {\n\tchar *arg;\n\tint ispath;\n};\n\n/*\n * parse_fwd_field\n * parses the next field in a port forwarding specification.\n * sets fwd to the parsed field and advances p past the colon\n * or sets it to NULL at end of string.\n * returns 0 on success, else non-zero.\n */\nstatic int\nparse_fwd_field(char **p, struct fwdarg *fwd)\n{\n\tchar *ep, *cp = *p;\n\tint ispath = 0;\n\n\tif (*cp == '\\0') {\n\t\t*p = NULL;\n\t\treturn -1;\t/* end of string */\n\t}\n\n\t/*\n\t * A field escaped with square brackets is used literally.\n\t * XXX - allow ']' to be escaped via backslash?\n\t */\n\tif (*cp == '[') {\n\t\t/* find matching ']' */\n\t\tfor (ep = cp + 1; *ep != ']' && *ep != '\\0'; ep++) {\n\t\t\tif (*ep == '/')\n\t\t\t\tispath = 1;\n\t\t}\n\t\t/* no matching ']' or not at end of field. */\n\t\tif (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\\0'))\n\t\t\treturn -1;\n\t\t/* NUL terminate the field and advance p past the colon */\n\t\t*ep++ = '\\0';\n\t\tif (*ep != '\\0')\n\t\t\t*ep++ = '\\0';\n\t\tfwd->arg = cp + 1;\n\t\tfwd->ispath = ispath;\n\t\t*p = ep;\n\t\treturn 0;\n\t}\n\n\tfor (cp = *p; *cp != '\\0'; cp++) {\n\t\tswitch (*cp) {\n\t\tcase '\\\\':\n\t\t\tmemmove(cp, cp + 1, strlen(cp + 1) + 1);\n\t\t\tif (*cp == '\\0')\n\t\t\t\treturn -1;\n\t\t\tbreak;\n\t\tcase '/':\n\t\t\tispath = 1;\n\t\t\tbreak;\n\t\tcase ':':\n\t\t\t*cp++ = '\\0';\n\t\t\tgoto done;\n\t\t}\n\t}\ndone:\n\tfwd->arg = *p;\n\tfwd->ispath = ispath;\n\t*p = cp;\n\treturn 0;\n}\n\n/*\n * parse_forward\n * parses a string containing a port forwarding specification of the form:\n * dynamicfwd == 0\n *\t[listenhost:]listenport|listenpath:connecthost:connectport|connectpath\n *\tlistenpath:connectpath\n * dynamicfwd == 1\n *\t[listenhost:]listenport\n * returns number of arguments parsed or zero on error\n */\nint\nparse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)\n{\n\tstruct fwdarg fwdargs[4];\n\tchar *p, *cp;\n\tint i;\n\n\tmemset(fwd, 0, sizeof(*fwd));\n\tmemset(fwdargs, 0, sizeof(fwdargs));\n\n\tcp = p = xstrdup(fwdspec);\n\n\t/* skip leading spaces */\n\twhile (isspace((u_char)*cp))\n\t\tcp++;\n\n\tfor (i = 0; i < 4; ++i) {\n\t\tif (parse_fwd_field(&cp, &fwdargs[i]) != 0)\n\t\t\tbreak;\n\t}\n\n\t/* Check for trailing garbage */\n\tif (cp != NULL && *cp != '\\0') {\n\t\ti = 0;\t/* failure */\n\t}\n\n\tswitch (i) {\n\tcase 1:\n\t\tif (fwdargs[0].ispath) {\n\t\t\tfwd->listen_path = xstrdup(fwdargs[0].arg);\n\t\t\tfwd->listen_port = PORT_STREAMLOCAL;\n\t\t} else {\n\t\t\tfwd->listen_host = NULL;\n\t\t\tfwd->listen_port = a2port(fwdargs[0].arg);\n\t\t}\n\t\tfwd->connect_host = xstrdup(\"socks\");\n\t\tbreak;\n\n\tcase 2:\n\t\tif (fwdargs[0].ispath && fwdargs[1].ispath) {\n\t\t\tfwd->listen_path = xstrdup(fwdargs[0].arg);\n\t\t\tfwd->listen_port = PORT_STREAMLOCAL;\n\t\t\tfwd->connect_path = xstrdup(fwdargs[1].arg);\n\t\t\tfwd->connect_port = PORT_STREAMLOCAL;\n\t\t} else if (fwdargs[1].ispath) {\n\t\t\tfwd->listen_host = NULL;\n\t\t\tfwd->listen_port = a2port(fwdargs[0].arg);\n\t\t\tfwd->connect_path = xstrdup(fwdargs[1].arg);\n\t\t\tfwd->connect_port = PORT_STREAMLOCAL;\n\t\t} else {\n\t\t\tfwd->listen_host = xstrdup(fwdargs[0].arg);\n\t\t\tfwd->listen_port = a2port(fwdargs[1].arg);\n\t\t\tfwd->connect_host = xstrdup(\"socks\");\n\t\t}\n\t\tbreak;\n\n\tcase 3:\n\t\tif (fwdargs[0].ispath) {\n\t\t\tfwd->listen_path = xstrdup(fwdargs[0].arg);\n\t\t\tfwd->listen_port = PORT_STREAMLOCAL;\n\t\t\tfwd->connect_host = xstrdup(fwdargs[1].arg);\n\t\t\tfwd->connect_port = a2port(fwdargs[2].arg);\n\t\t} else if (fwdargs[2].ispath) {\n\t\t\tfwd->listen_host = xstrdup(fwdargs[0].arg);\n\t\t\tfwd->listen_port = a2port(fwdargs[1].arg);\n\t\t\tfwd->connect_path = xstrdup(fwdargs[2].arg);\n\t\t\tfwd->connect_port = PORT_STREAMLOCAL;\n\t\t} else {\n\t\t\tfwd->listen_host = NULL;\n\t\t\tfwd->listen_port = a2port(fwdargs[0].arg);\n\t\t\tfwd->connect_host = xstrdup(fwdargs[1].arg);\n\t\t\tfwd->connect_port = a2port(fwdargs[2].arg);\n\t\t}\n\t\tbreak;\n\n\tcase 4:\n\t\tfwd->listen_host = xstrdup(fwdargs[0].arg);\n\t\tfwd->listen_port = a2port(fwdargs[1].arg);\n\t\tfwd->connect_host = xstrdup(fwdargs[2].arg);\n\t\tfwd->connect_port = a2port(fwdargs[3].arg);\n\t\tbreak;\n\tdefault:\n\t\ti = 0; /* failure */\n\t}\n\n\tfree(p);\n\n\tif (dynamicfwd) {\n\t\tif (!(i == 1 || i == 2))\n\t\t\tgoto fail_free;\n\t} else {\n\t\tif (!(i == 3 || i == 4)) {\n\t\t\tif (fwd->connect_path == NULL &&\n\t\t\t fwd->listen_path == NULL)\n\t\t\t\tgoto fail_free;\n\t\t}\n\t\tif (fwd->connect_port <= 0 && fwd->connect_path == NULL)\n\t\t\tgoto fail_free;\n\t}\n\n\tif ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||\n\t (!remotefwd && fwd->listen_port == 0))\n\t\tgoto fail_free;\n\tif (fwd->connect_host != NULL &&\n\t strlen(fwd->connect_host) >= NI_MAXHOST)\n\t\tgoto fail_free;\n\t/* XXX - if connecting to a remote socket, max sun len may not match this host */\n\tif (fwd->connect_path != NULL &&\n\t strlen(fwd->connect_path) >= PATH_MAX_SUN)\n\t\tgoto fail_free;\n\tif (fwd->listen_host != NULL &&\n\t strlen(fwd->listen_host) >= NI_MAXHOST)\n\t\tgoto fail_free;\n\tif (fwd->listen_path != NULL &&\n\t strlen(fwd->listen_path) >= PATH_MAX_SUN)\n\t\tgoto fail_free;\n\n\treturn (i);\n\n fail_free:\n\tfree(fwd->connect_host);\n\tfwd->connect_host = NULL;\n\tfree(fwd->connect_path);\n\tfwd->connect_path = NULL;\n\tfree(fwd->listen_host);\n\tfwd->listen_host = NULL;\n\tfree(fwd->listen_path);\n\tfwd->listen_path = NULL;\n\treturn (0);\n}\n\nint\nparse_jump(const char *s, Options *o, int active)\n{\n\tchar *orig, *sdup, *cp;\n\tchar *host = NULL, *user = NULL;\n\tint ret = -1, port = -1, first;\n\n\tactive &= o->proxy_command == NULL && o->jump_host == NULL;\n\n\torig = sdup = xstrdup(s);\n\tfirst = active;\n\tdo {\n\t\tif ((cp = strrchr(sdup, ',')) == NULL)\n\t\t\tcp = sdup; /* last */\n\t\telse\n\t\t\t*cp++ = '\\0';\n\n\t\tif (first) {\n\t\t\t/* First argument and configuration is active */\n\t\t\tif (parse_user_host_port(cp, &user, &host, &port) != 0)\n\t\t\t\tgoto out;\n\t\t} else {\n\t\t\t/* Subsequent argument or inactive configuration */\n\t\t\tif (parse_user_host_port(cp, NULL, NULL, NULL) != 0)\n\t\t\t\tgoto out;\n\t\t}\n\t\tfirst = 0; /* only check syntax for subsequent hosts */\n\t} while (cp != sdup);\n\t/* success */\n\tif (active) {\n\t\to->jump_user = user;\n\t\to->jump_host = host;\n\t\to->jump_port = port;\n\t\to->proxy_command = xstrdup(\"none\");\n\t\tuser = host = NULL;\n\t\tif ((cp = strrchr(s, ',')) != NULL && cp != s) {\n\t\t\to->jump_extra = xstrdup(s);\n\t\t\to->jump_extra[cp - s] = '\\0';\n\t\t}\n\t}\n\tret = 0;\n out:\n\tfree(orig);\n\tfree(user);\n\tfree(host);\n\treturn ret;\n}\n\n/* XXX the following is a near-vebatim copy from servconf.c; refactor */\nstatic const char *\nfmt_multistate_int(int val, const struct multistate *m)\n{\n\tu_int i;\n\n\tfor (i = 0; m[i].key != NULL; i++) {\n\t\tif (m[i].value == val)\n\t\t\treturn m[i].key;\n\t}\n\treturn \"UNKNOWN\";\n}\n\nstatic const char *\nfmt_intarg(OpCodes code, int val)\n{\n\tif (val == -1)\n\t\treturn \"unset\";\n\tswitch (code) {\n\tcase oAddressFamily:\n\t\treturn fmt_multistate_int(val, multistate_addressfamily);\n\tcase oVerifyHostKeyDNS:\n\tcase oStrictHostKeyChecking:\n\tcase oUpdateHostkeys:\n\t\treturn fmt_multistate_int(val, multistate_yesnoask);\n\tcase oControlMaster:\n\t\treturn fmt_multistate_int(val, multistate_controlmaster);\n\tcase oTunnel:\n\t\treturn fmt_multistate_int(val, multistate_tunnel);\n\tcase oRequestTTY:\n\t\treturn fmt_multistate_int(val, multistate_requesttty);\n\tcase oCanonicalizeHostname:\n\t\treturn fmt_multistate_int(val, multistate_canonicalizehostname);\n\tcase oFingerprintHash:\n\t\treturn ssh_digest_alg_name(val);\n\tcase oProtocol:\n\t\tswitch (val) {\n\t\tcase SSH_PROTO_1:\n\t\t\treturn \"1\";\n\t\tcase SSH_PROTO_2:\n\t\t\treturn \"2\";\n\t\tcase (SSH_PROTO_1|SSH_PROTO_2):\n\t\t\treturn \"2,1\";\n\t\tdefault:\n\t\t\treturn \"UNKNOWN\";\n\t\t}\n\tdefault:\n\t\tswitch (val) {\n\t\tcase 0:\n\t\t\treturn \"no\";\n\t\tcase 1:\n\t\t\treturn \"yes\";\n\t\tdefault:\n\t\t\treturn \"UNKNOWN\";\n\t\t}\n\t}\n}\n\nstatic const char *\nlookup_opcode_name(OpCodes code)\n{\n\tu_int i;\n\n\tfor (i = 0; keywords[i].name != NULL; i++)\n\t\tif (keywords[i].opcode == code)\n\t\t\treturn(keywords[i].name);\n\treturn \"UNKNOWN\";\n}\n\nstatic void\ndump_cfg_int(OpCodes code, int val)\n{\n\tprintf(\"%s %d\\n\", lookup_opcode_name(code), val);\n}\n\nstatic void\ndump_cfg_fmtint(OpCodes code, int val)\n{\n\tprintf(\"%s %s\\n\", lookup_opcode_name(code), fmt_intarg(code, val));\n}\n\nstatic void\ndump_cfg_string(OpCodes code, const char *val)\n{\n\tif (val == NULL)\n\t\treturn;\n\tprintf(\"%s %s\\n\", lookup_opcode_name(code), val);\n}\n\nstatic void\ndump_cfg_strarray(OpCodes code, u_int count, char **vals)\n{\n\tu_int i;\n\n\tfor (i = 0; i < count; i++)\n\t\tprintf(\"%s %s\\n\", lookup_opcode_name(code), vals[i]);\n}\n\nstatic void\ndump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)\n{\n\tu_int i;\n\n\tprintf(\"%s\", lookup_opcode_name(code));\n\tfor (i = 0; i < count; i++)\n\t\tprintf(\" %s\", vals[i]);\n\tprintf(\"\\n\");\n}\n\nstatic void\ndump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)\n{\n\tconst struct Forward *fwd;\n\tu_int i;\n\n\t/* oDynamicForward */\n\tfor (i = 0; i < count; i++) {\n\t\tfwd = &fwds[i];\n\t\tif (code == oDynamicForward && fwd->connect_host != NULL &&\n\t\t strcmp(fwd->connect_host, \"socks\") != 0)\n\t\t\tcontinue;\n\t\tif (code == oLocalForward && fwd->connect_host != NULL &&\n\t\t strcmp(fwd->connect_host, \"socks\") == 0)\n\t\t\tcontinue;\n\t\tprintf(\"%s\", lookup_opcode_name(code));\n\t\tif (fwd->listen_port == PORT_STREAMLOCAL)\n\t\t\tprintf(\" %s\", fwd->listen_path);\n\t\telse if (fwd->listen_host == NULL)\n\t\t\tprintf(\" %d\", fwd->listen_port);\n\t\telse {\n\t\t\tprintf(\" [%s]:%d\",\n\t\t\t fwd->listen_host, fwd->listen_port);\n\t\t}\n\t\tif (code != oDynamicForward) {\n\t\t\tif (fwd->connect_port == PORT_STREAMLOCAL)\n\t\t\t\tprintf(\" %s\", fwd->connect_path);\n\t\t\telse if (fwd->connect_host == NULL)\n\t\t\t\tprintf(\" %d\", fwd->connect_port);\n\t\t\telse {\n\t\t\t\tprintf(\" [%s]:%d\",\n\t\t\t\t fwd->connect_host, fwd->connect_port);\n\t\t\t}\n\t\t}\n\t\tprintf(\"\\n\");\n\t}\n}\n\nvoid\ndump_client_config(Options *o, const char *host)\n{\n\tint i;\n\tchar buf[8];\n\n\t/* This is normally prepared in ssh_kex2 */\n\tif (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)\n\t\tfatal(\"%s: kex_assemble_names failed\", __func__);\n\n\t/* Most interesting options first: user, host, port */\n\tdump_cfg_string(oUser, o->user);\n\tdump_cfg_string(oHostName, host);\n\tdump_cfg_int(oPort, o->port);\n\n\t/* Flag options */\n\tdump_cfg_fmtint(oAddressFamily, o->address_family);\n\tdump_cfg_fmtint(oBatchMode, o->batch_mode);\n\tdump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);\n\tdump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);\n\tdump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication);\n\tdump_cfg_fmtint(oCheckHostIP, o->check_host_ip);\n\tdump_cfg_fmtint(oCompression, o->compression);\n\tdump_cfg_fmtint(oControlMaster, o->control_master);\n\tdump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);\n\tdump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);\n\tdump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);\n\tdump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);\n\tdump_cfg_fmtint(oForwardAgent, o->forward_agent);\n\tdump_cfg_fmtint(oForwardX11, o->forward_x11);\n\tdump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);\n\tdump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);\n#ifdef GSSAPI\n\tdump_cfg_fmtint(oGssAuthentication, o->gss_authentication);\n\tdump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);\n#endif /* GSSAPI */\n\tdump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);\n\tdump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);\n\tdump_cfg_fmtint(oIdentitiesOnly, o->identities_only);\n\tdump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);\n\tdump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);\n\tdump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);\n\tdump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);\n\tdump_cfg_fmtint(oProtocol, o->protocol);\n\tdump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);\n\tdump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);\n\tdump_cfg_fmtint(oRequestTTY, o->request_tty);\n#ifdef WITH_RSA1\n\tdump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);\n\tdump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);\n#endif\n\tdump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);\n\tdump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);\n\tdump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);\n\tdump_cfg_fmtint(oTunnel, o->tun_open);\n\tdump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port);\n\tdump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);\n\tdump_cfg_fmtint(oVisualHostKey, o->visual_host_key);\n\tdump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);\n\n\t/* Integer options */\n\tdump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);\n#ifdef WITH_SSH1\n\tdump_cfg_int(oCompressionLevel, o->compression_level);\n#endif\n\tdump_cfg_int(oConnectionAttempts, o->connection_attempts);\n\tdump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);\n\tdump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);\n\tdump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);\n\tdump_cfg_int(oServerAliveInterval, o->server_alive_interval);\n\n\t/* String options */\n\tdump_cfg_string(oBindAddress, o->bind_address);\n\tdump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);\n\tdump_cfg_string(oControlPath, o->control_path);\n\tdump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);\n\tdump_cfg_string(oHostKeyAlias, o->host_key_alias);\n\tdump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);\n\tdump_cfg_string(oIdentityAgent, o->identity_agent);\n\tdump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);\n\tdump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);\n\tdump_cfg_string(oLocalCommand, o->local_command);\n\tdump_cfg_string(oLogLevel, log_level_name(o->log_level));\n\tdump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);\n#ifdef ENABLE_PKCS11\n\tdump_cfg_string(oPKCS11Provider, o->pkcs11_provider);\n#endif\n\tdump_cfg_string(oPreferredAuthentications, o->preferred_authentications);\n\tdump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);\n\tdump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);\n\tdump_cfg_string(oXAuthLocation, o->xauth_location);\n\n\t/* Forwards */\n\tdump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);\n\tdump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);\n\tdump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);\n\n\t/* String array options */\n\tdump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);\n\tdump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);\n\tdump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);\n\tdump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);\n\tdump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);\n\n\t/* Special cases */\n\n\t/* oConnectTimeout */\n\tif (o->connection_timeout == -1)\n\t\tprintf(\"connecttimeout none\\n\");\n\telse\n\t\tdump_cfg_int(oConnectTimeout, o->connection_timeout);\n\n\t/* oTunnelDevice */\n\tprintf(\"tunneldevice\");\n\tif (o->tun_local == SSH_TUNID_ANY)\n\t\tprintf(\" any\");\n\telse\n\t\tprintf(\" %d\", o->tun_local);\n\tif (o->tun_remote == SSH_TUNID_ANY)\n\t\tprintf(\":any\");\n\telse\n\t\tprintf(\":%d\", o->tun_remote);\n\tprintf(\"\\n\");\n\n\t/* oCanonicalizePermittedCNAMEs */\n\tif ( o->num_permitted_cnames > 0) {\n\t\tprintf(\"canonicalizePermittedcnames\");\n\t\tfor (i = 0; i < o->num_permitted_cnames; i++) {\n\t\t\tprintf(\" %s:%s\", o->permitted_cnames[i].source_list,\n\t\t\t o->permitted_cnames[i].target_list);\n\t\t}\n\t\tprintf(\"\\n\");\n\t}\n\n\t/* oCipher */\n\tif (o->cipher != SSH_CIPHER_NOT_SET)\n\t\tprintf(\"Cipher %s\\n\", cipher_name(o->cipher));\n\n\t/* oControlPersist */\n\tif (o->control_persist == 0 || o->control_persist_timeout == 0)\n\t\tdump_cfg_fmtint(oControlPersist, o->control_persist);\n\telse\n\t\tdump_cfg_int(oControlPersist, o->control_persist_timeout);\n\n\t/* oEscapeChar */\n\tif (o->escape_char == SSH_ESCAPECHAR_NONE)\n\t\tprintf(\"escapechar none\\n\");\n\telse {\n\t\tvis(buf, o->escape_char, VIS_WHITE, 0);\n\t\tprintf(\"escapechar %s\\n\", buf);\n\t}\n\n\t/* oIPQoS */\n\tprintf(\"ipqos %s \", iptos2str(o->ip_qos_interactive));\n\tprintf(\"%s\\n\", iptos2str(o->ip_qos_bulk));\n\n\t/* oRekeyLimit */\n\tprintf(\"rekeylimit %llu %d\\n\",\n\t (unsigned long long)o->rekey_limit, o->rekey_interval);\n\n\t/* oStreamLocalBindMask */\n\tprintf(\"streamlocalbindmask 0%o\\n\",\n\t o->fwd_opts.streamlocal_bind_mask);\n\n\t/* oProxyCommand / oProxyJump */\n\tif (o->jump_host == NULL)\n\t\tdump_cfg_string(oProxyCommand, o->proxy_command);\n\telse {\n\t\t/* Check for numeric addresses */\n\t\ti = strchr(o->jump_host, ':') != NULL ||\n\t\t strspn(o->jump_host, \"1234567890.\") == strlen(o->jump_host);\n\t\tsnprintf(buf, sizeof(buf), \"%d\", o->jump_port);\n\t\tprintf(\"proxyjump %s%s%s%s%s%s%s%s%s\\n\",\n\t\t /* optional additional jump spec */\n\t\t o->jump_extra == NULL ? \"\" : o->jump_extra,\n\t\t o->jump_extra == NULL ? \"\" : \",\",\n\t\t /* optional user */\n\t\t o->jump_user == NULL ? \"\" : o->jump_user,\n\t\t o->jump_user == NULL ? \"\" : \"@\",\n\t\t /* opening [ if hostname is numeric */\n\t\t i ? \"[\" : \"\",\n\t\t /* mandatory hostname */\n\t\t o->jump_host,\n\t\t /* closing ] if hostname is numeric */\n\t\t i ? \"]\" : \"\",\n\t\t /* optional port number */\n\t\t o->jump_port <= 0 ? \"\" : \":\",\n\t\t o->jump_port <= 0 ? \"\" : buf);\n\t}\n}\n","/* $OpenBSD: clientloop.c,v 1.291 2017/03/10 05:01:13 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * The main loop for the interactive session (client side).\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n *\n *\n * Copyright (c) 1999 Theo de Raadt. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n *\n * SSH2 support added by Markus Friedl.\n * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#ifdef HAVE_SYS_STAT_H\n# include \n#endif\n#ifdef HAVE_SYS_TIME_H\n# include \n#endif\n#include \n\n#include \n#include \n#ifdef HAVE_PATHS_H\n#include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"openbsd-compat/sys-queue.h\"\n#include \"xmalloc.h\"\n#include \"ssh.h\"\n#include \"ssh1.h\"\n#include \"ssh2.h\"\n#include \"packet.h\"\n#include \"buffer.h\"\n#include \"compat.h\"\n#include \"channels.h\"\n#include \"dispatch.h\"\n#include \"key.h\"\n#include \"cipher.h\"\n#include \"kex.h\"\n#include \"myproposal.h\"\n#include \"log.h\"\n#include \"misc.h\"\n#include \"readconf.h\"\n#include \"clientloop.h\"\n#include \"sshconnect.h\"\n#include \"authfd.h\"\n#include \"atomicio.h\"\n#include \"sshpty.h\"\n#include \"match.h\"\n#include \"msg.h\"\n#include \"ssherr.h\"\n#include \"hostfile.h\"\n\n/* import options */\nextern Options options;\n\n/* Flag indicating that stdin should be redirected from /dev/null. */\nextern int stdin_null_flag;\n\n/* Flag indicating that no shell has been requested */\nextern int no_shell_flag;\n\n/* Flag indicating that ssh should daemonise after authentication is complete */\nextern int fork_after_authentication_flag;\n\n/* Control socket */\nextern int muxserver_sock; /* XXX use mux_client_cleanup() instead */\n\n/*\n * Name of the host we are connecting to. This is the name given on the\n * command line, or the HostName specified for the user-supplied name in a\n * configuration file.\n */\nextern char *host;\n\n/*\n * Flag to indicate that we have received a window change signal which has\n * not yet been processed. This will cause a message indicating the new\n * window size to be sent to the server a little later. This is volatile\n * because this is updated in a signal handler.\n */\nstatic volatile sig_atomic_t received_window_change_signal = 0;\nstatic volatile sig_atomic_t received_signal = 0;\n\n/* Flag indicating whether the user's terminal is in non-blocking mode. */\nstatic int in_non_blocking_mode = 0;\n\n/* Time when backgrounded control master using ControlPersist should exit */\nstatic time_t control_persist_exit_time = 0;\n\n/* Common data for the client loop code. */\nvolatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */\nstatic int escape_char1;\t/* Escape character. (proto1 only) */\nstatic int escape_pending1;\t/* Last character was an escape (proto1 only) */\nstatic int last_was_cr;\t\t/* Last character was a newline. */\nstatic int exit_status;\t\t/* Used to store the command exit status. */\nstatic int stdin_eof;\t\t/* EOF has been encountered on stderr. */\nstatic Buffer stdin_buffer;\t/* Buffer for stdin data. */\nstatic Buffer stdout_buffer;\t/* Buffer for stdout data. */\nstatic Buffer stderr_buffer;\t/* Buffer for stderr data. */\nstatic u_int buffer_high;\t/* Soft max buffer size. */\nstatic int connection_in;\t/* Connection to server (input). */\nstatic int connection_out;\t/* Connection to server (output). */\nstatic int need_rekeying;\t/* Set to non-zero if rekeying is requested. */\nstatic int session_closed;\t/* In SSH2: login session closed. */\nstatic u_int x11_refuse_time;\t/* If >0, refuse x11 opens after this time. */\n\nstatic void client_init_dispatch(void);\nint\tsession_ident = -1;\n\n/* Track escape per proto2 channel */\nstruct escape_filter_ctx {\n\tint escape_pending;\n\tint escape_char;\n};\n\n/* Context for channel confirmation replies */\nstruct channel_reply_ctx {\n\tconst char *request_type;\n\tint id;\n\tenum confirm_action action;\n};\n\n/* Global request success/failure callbacks */\nstruct global_confirm {\n\tTAILQ_ENTRY(global_confirm) entry;\n\tglobal_confirm_cb *cb;\n\tvoid *ctx;\n\tint ref_count;\n};\nTAILQ_HEAD(global_confirms, global_confirm);\nstatic struct global_confirms global_confirms =\n TAILQ_HEAD_INITIALIZER(global_confirms);\n\nvoid ssh_process_session2_setup(int, int, int, Buffer *);\n\n/* Restores stdin to blocking mode. */\n\nstatic void\nleave_non_blocking(void)\n{\n\tif (in_non_blocking_mode) {\n\t\tunset_nonblock(fileno(stdin));\n\t\tin_non_blocking_mode = 0;\n\t}\n}\n\n/* Puts stdin terminal in non-blocking mode. */\n\nstatic void\nenter_non_blocking(void)\n{\n\tin_non_blocking_mode = 1;\n\tset_nonblock(fileno(stdin));\n}\n\n/*\n * Signal handler for the window change signal (SIGWINCH). This just sets a\n * flag indicating that the window has changed.\n */\n/*ARGSUSED */\nstatic void\nwindow_change_handler(int sig)\n{\n\treceived_window_change_signal = 1;\n\tsignal(SIGWINCH, window_change_handler);\n}\n\n/*\n * Signal handler for signals that cause the program to terminate. These\n * signals must be trapped to restore terminal modes.\n */\n/*ARGSUSED */\nstatic void\nsignal_handler(int sig)\n{\n\treceived_signal = sig;\n\tquit_pending = 1;\n}\n\n/*\n * Returns current time in seconds from Jan 1, 1970 with the maximum\n * available resolution.\n */\n\nstatic double\nget_current_time(void)\n{\n\tstruct timeval tv;\n\tgettimeofday(&tv, NULL);\n\treturn (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;\n}\n\n/*\n * Sets control_persist_exit_time to the absolute time when the\n * backgrounded control master should exit due to expiry of the\n * ControlPersist timeout. Sets it to 0 if we are not a backgrounded\n * control master process, or if there is no ControlPersist timeout.\n */\nstatic void\nset_control_persist_exit_time(void)\n{\n\tif (muxserver_sock == -1 || !options.control_persist\n\t || options.control_persist_timeout == 0) {\n\t\t/* not using a ControlPersist timeout */\n\t\tcontrol_persist_exit_time = 0;\n\t} else if (channel_still_open()) {\n\t\t/* some client connections are still open */\n\t\tif (control_persist_exit_time > 0)\n\t\t\tdebug2(\"%s: cancel scheduled exit\", __func__);\n\t\tcontrol_persist_exit_time = 0;\n\t} else if (control_persist_exit_time <= 0) {\n\t\t/* a client connection has recently closed */\n\t\tcontrol_persist_exit_time = monotime() +\n\t\t\t(time_t)options.control_persist_timeout;\n\t\tdebug2(\"%s: schedule exit in %d seconds\", __func__,\n\t\t options.control_persist_timeout);\n\t}\n\t/* else we are already counting down to the timeout */\n}\n\n#define SSH_X11_VALID_DISPLAY_CHARS \":/.-_\"\nstatic int\nclient_x11_display_valid(const char *display)\n{\n\tsize_t i, dlen;\n\n\tif (display == NULL)\n\t\treturn 0;\n\n\tdlen = strlen(display);\n\tfor (i = 0; i < dlen; i++) {\n\t\tif (!isalnum((u_char)display[i]) &&\n\t\t strchr(SSH_X11_VALID_DISPLAY_CHARS, display[i]) == NULL) {\n\t\t\tdebug(\"Invalid character '%c' in DISPLAY\", display[i]);\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn 1;\n}\n\n#define SSH_X11_PROTO\t\t\"MIT-MAGIC-COOKIE-1\"\n#define X11_TIMEOUT_SLACK\t60\nint\nclient_x11_get_proto(const char *display, const char *xauth_path,\n u_int trusted, u_int timeout, char **_proto, char **_data)\n{\n\tchar cmd[1024], line[512], xdisplay[512];\n\tchar xauthfile[PATH_MAX], xauthdir[PATH_MAX];\n\tstatic char proto[512], data[512];\n\tFILE *f;\n\tint got_data = 0, generated = 0, do_unlink = 0, r;\n\tstruct stat st;\n\tu_int now, x11_timeout_real;\n\n\t*_proto = proto;\n\t*_data = data;\n\tproto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\\0';\n\n\tif (!client_x11_display_valid(display)) {\n\t\tif (display != NULL)\n\t\t\tlogit(\"DISPLAY \\\"%s\\\" invalid; disabling X11 forwarding\",\n\t\t\t display);\n\t\treturn -1;\n\t}\n\tif (xauth_path != NULL && stat(xauth_path, &st) == -1) {\n\t\tdebug(\"No xauth program.\");\n\t\txauth_path = NULL;\n\t}\n\n\tif (xauth_path != NULL) {\n\t\t/*\n\t\t * Handle FamilyLocal case where $DISPLAY does\n\t\t * not match an authorization entry. For this we\n\t\t * just try \"xauth list unix:displaynum.screennum\".\n\t\t * XXX: \"localhost\" match to determine FamilyLocal\n\t\t * is not perfect.\n\t\t */\n\t\tif (strncmp(display, \"localhost:\", 10) == 0) {\n\t\t\tif ((r = snprintf(xdisplay, sizeof(xdisplay), \"unix:%s\",\n\t\t\t display + 10)) < 0 ||\n\t\t\t (size_t)r >= sizeof(xdisplay)) {\n\t\t\t\terror(\"%s: display name too long\", __func__);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tdisplay = xdisplay;\n\t\t}\n\t\tif (trusted == 0) {\n\t\t\t/*\n\t\t\t * Generate an untrusted X11 auth cookie.\n\t\t\t *\n\t\t\t * The authentication cookie should briefly outlive\n\t\t\t * ssh's willingness to forward X11 connections to\n\t\t\t * avoid nasty fail-open behaviour in the X server.\n\t\t\t */\n\t\t\tmktemp_proto(xauthdir, sizeof(xauthdir));\n\t\t\tif (mkdtemp(xauthdir) == NULL) {\n\t\t\t\terror(\"%s: mkdtemp: %s\",\n\t\t\t\t __func__, strerror(errno));\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tdo_unlink = 1;\n\t\t\tif ((r = snprintf(xauthfile, sizeof(xauthfile),\n\t\t\t \"%s/xauthfile\", xauthdir)) < 0 ||\n\t\t\t (size_t)r >= sizeof(xauthfile)) {\n\t\t\t\terror(\"%s: xauthfile path too long\", __func__);\n\t\t\t\tunlink(xauthfile);\n\t\t\t\trmdir(xauthdir);\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tif (timeout >= UINT_MAX - X11_TIMEOUT_SLACK)\n\t\t\t\tx11_timeout_real = UINT_MAX;\n\t\t\telse\n\t\t\t\tx11_timeout_real = timeout + X11_TIMEOUT_SLACK;\n\t\t\tif ((r = snprintf(cmd, sizeof(cmd),\n\t\t\t \"%s -f %s generate %s \" SSH_X11_PROTO\n\t\t\t \" untrusted timeout %u 2>\" _PATH_DEVNULL,\n\t\t\t xauth_path, xauthfile, display,\n\t\t\t x11_timeout_real)) < 0 ||\n\t\t\t (size_t)r >= sizeof(cmd))\n\t\t\t\tfatal(\"%s: cmd too long\", __func__);\n\t\t\tdebug2(\"%s: %s\", __func__, cmd);\n\t\t\tif (x11_refuse_time == 0) {\n\t\t\t\tnow = monotime() + 1;\n\t\t\t\tif (UINT_MAX - timeout < now)\n\t\t\t\t\tx11_refuse_time = UINT_MAX;\n\t\t\t\telse\n\t\t\t\t\tx11_refuse_time = now + timeout;\n\t\t\t\tchannel_set_x11_refuse_time(x11_refuse_time);\n\t\t\t}\n\t\t\tif (system(cmd) == 0)\n\t\t\t\tgenerated = 1;\n\t\t}\n\n\t\t/*\n\t\t * When in untrusted mode, we read the cookie only if it was\n\t\t * successfully generated as an untrusted one in the step\n\t\t * above.\n\t\t */\n\t\tif (trusted || generated) {\n\t\t\tsnprintf(cmd, sizeof(cmd),\n\t\t\t \"%s %s%s list %s 2>\" _PATH_DEVNULL,\n\t\t\t xauth_path,\n\t\t\t generated ? \"-f \" : \"\" ,\n\t\t\t generated ? xauthfile : \"\",\n\t\t\t display);\n\t\t\tdebug2(\"x11_get_proto: %s\", cmd);\n\t\t\tf = popen(cmd, \"r\");\n\t\t\tif (f && fgets(line, sizeof(line), f) &&\n\t\t\t sscanf(line, \"%*s %511s %511s\", proto, data) == 2)\n\t\t\t\tgot_data = 1;\n\t\t\tif (f)\n\t\t\t\tpclose(f);\n\t\t}\n\t}\n\n\tif (do_unlink) {\n\t\tunlink(xauthfile);\n\t\trmdir(xauthdir);\n\t}\n\n\t/* Don't fall back to fake X11 data for untrusted forwarding */\n\tif (!trusted && !got_data) {\n\t\terror(\"Warning: untrusted X11 forwarding setup failed: \"\n\t\t \"xauth key data not generated\");\n\t\treturn -1;\n\t}\n\n\t/*\n\t * If we didn't get authentication data, just make up some\n\t * data. The forwarding code will check the validity of the\n\t * response anyway, and substitute this data. The X11\n\t * server, however, will ignore this fake data and use\n\t * whatever authentication mechanisms it was using otherwise\n\t * for the local connection.\n\t */\n\tif (!got_data) {\n\t\tu_int8_t rnd[16];\n\t\tu_int i;\n\n\t\tlogit(\"Warning: No xauth data; \"\n\t\t \"using fake authentication data for X11 forwarding.\");\n\t\tstrlcpy(proto, SSH_X11_PROTO, sizeof proto);\n\t\tarc4random_buf(rnd, sizeof(rnd));\n\t\tfor (i = 0; i < sizeof(rnd); i++) {\n\t\t\tsnprintf(data + 2 * i, sizeof data - 2 * i, \"%02x\",\n\t\t\t rnd[i]);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n * This is called when the interactive is entered. This checks if there is\n * an EOF coming on stdin. We must check this explicitly, as select() does\n * not appear to wake up when redirecting from /dev/null.\n */\n\nstatic void\nclient_check_initial_eof_on_stdin(void)\n{\n\tint len;\n\tchar buf[1];\n\n\t/*\n\t * If standard input is to be \"redirected from /dev/null\", we simply\n\t * mark that we have seen an EOF and send an EOF message to the\n\t * server. Otherwise, we try to read a single character; it appears\n\t * that for some files, such /dev/null, select() never wakes up for\n\t * read for this descriptor, which means that we never get EOF. This\n\t * way we will get the EOF if stdin comes from /dev/null or similar.\n\t */\n\tif (stdin_null_flag) {\n\t\t/* Fake EOF on stdin. */\n\t\tdebug(\"Sending eof.\");\n\t\tstdin_eof = 1;\n\t\tpacket_start(SSH_CMSG_EOF);\n\t\tpacket_send();\n\t} else {\n\t\tenter_non_blocking();\n\n\t\t/* Check for immediate EOF on stdin. */\n\t\tlen = read(fileno(stdin), buf, 1);\n\t\tif (len == 0) {\n\t\t\t/*\n\t\t\t * EOF. Record that we have seen it and send\n\t\t\t * EOF to server.\n\t\t\t */\n\t\t\tdebug(\"Sending eof.\");\n\t\t\tstdin_eof = 1;\n\t\t\tpacket_start(SSH_CMSG_EOF);\n\t\t\tpacket_send();\n\t\t} else if (len > 0) {\n\t\t\t/*\n\t\t\t * Got data. We must store the data in the buffer,\n\t\t\t * and also process it as an escape character if\n\t\t\t * appropriate.\n\t\t\t */\n\t\t\tif ((u_char) buf[0] == escape_char1)\n\t\t\t\tescape_pending1 = 1;\n\t\t\telse\n\t\t\t\tbuffer_append(&stdin_buffer, buf, 1);\n\t\t}\n\t\tleave_non_blocking();\n\t}\n}\n\n\n/*\n * Make packets from buffered stdin data, and buffer them for sending to the\n * connection.\n */\n\nstatic void\nclient_make_packets_from_stdin_data(void)\n{\n\tu_int len;\n\n\t/* Send buffered stdin data to the server. */\n\twhile (buffer_len(&stdin_buffer) > 0 &&\n\t packet_not_very_much_data_to_write()) {\n\t\tlen = buffer_len(&stdin_buffer);\n\t\t/* Keep the packets at reasonable size. */\n\t\tif (len > packet_get_maxsize())\n\t\t\tlen = packet_get_maxsize();\n\t\tpacket_start(SSH_CMSG_STDIN_DATA);\n\t\tpacket_put_string(buffer_ptr(&stdin_buffer), len);\n\t\tpacket_send();\n\t\tbuffer_consume(&stdin_buffer, len);\n\t\t/* If we have a pending EOF, send it now. */\n\t\tif (stdin_eof && buffer_len(&stdin_buffer) == 0) {\n\t\t\tpacket_start(SSH_CMSG_EOF);\n\t\t\tpacket_send();\n\t\t}\n\t}\n}\n\n/*\n * Checks if the client window has changed, and sends a packet about it to\n * the server if so. The actual change is detected elsewhere (by a software\n * interrupt on Unix); this just checks the flag and sends a message if\n * appropriate.\n */\n\nstatic void\nclient_check_window_change(void)\n{\n\tstruct winsize ws;\n\n\tif (! received_window_change_signal)\n\t\treturn;\n\t/** XXX race */\n\treceived_window_change_signal = 0;\n\n\tdebug2(\"client_check_window_change: changed\");\n\n\tif (compat20) {\n\t\tchannel_send_window_changes();\n\t} else {\n\t\tif (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)\n\t\t\treturn;\n\t\tpacket_start(SSH_CMSG_WINDOW_SIZE);\n\t\tpacket_put_int((u_int)ws.ws_row);\n\t\tpacket_put_int((u_int)ws.ws_col);\n\t\tpacket_put_int((u_int)ws.ws_xpixel);\n\t\tpacket_put_int((u_int)ws.ws_ypixel);\n\t\tpacket_send();\n\t}\n}\n\nstatic int\nclient_global_request_reply(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct global_confirm *gc;\n\n\tif ((gc = TAILQ_FIRST(&global_confirms)) == NULL)\n\t\treturn 0;\n\tif (gc->cb != NULL)\n\t\tgc->cb(type, seq, gc->ctx);\n\tif (--gc->ref_count <= 0) {\n\t\tTAILQ_REMOVE(&global_confirms, gc, entry);\n\t\texplicit_bzero(gc, sizeof(*gc));\n\t\tfree(gc);\n\t}\n\n\tpacket_set_alive_timeouts(0);\n\treturn 0;\n}\n\nstatic void\nserver_alive_check(void)\n{\n\tif (packet_inc_alive_timeouts() > options.server_alive_count_max) {\n\t\tlogit(\"Timeout, server %s not responding.\", host);\n\t\tcleanup_exit(255);\n\t}\n\tpacket_start(SSH2_MSG_GLOBAL_REQUEST);\n\tpacket_put_cstring(\"keepalive@openssh.com\");\n\tpacket_put_char(1); /* boolean: want reply */\n\tpacket_send();\n\t/* Insert an empty placeholder to maintain ordering */\n\tclient_register_global_confirm(NULL, NULL);\n}\n\n/*\n * Waits until the client can do something (some data becomes available on\n * one of the file descriptors).\n */\nstatic void\nclient_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,\n int *maxfdp, u_int *nallocp, int rekeying)\n{\n\tstruct timeval tv, *tvp;\n\tint timeout_secs;\n\ttime_t minwait_secs = 0, server_alive_time = 0, now = monotime();\n\tint ret;\n\n\t/* Add any selections by the channel mechanism. */\n\tchannel_prepare_select(readsetp, writesetp, maxfdp, nallocp,\n\t &minwait_secs, rekeying);\n\n\tif (!compat20) {\n\t\t/* Read from the connection, unless our buffers are full. */\n\t\tif (buffer_len(&stdout_buffer) < buffer_high &&\n\t\t buffer_len(&stderr_buffer) < buffer_high &&\n\t\t channel_not_very_much_buffered_data())\n\t\t\tFD_SET(connection_in, *readsetp);\n\t\t/*\n\t\t * Read from stdin, unless we have seen EOF or have very much\n\t\t * buffered data to send to the server.\n\t\t */\n\t\tif (!stdin_eof && packet_not_very_much_data_to_write())\n\t\t\tFD_SET(fileno(stdin), *readsetp);\n\n\t\t/* Select stdout/stderr if have data in buffer. */\n\t\tif (buffer_len(&stdout_buffer) > 0)\n\t\t\tFD_SET(fileno(stdout), *writesetp);\n\t\tif (buffer_len(&stderr_buffer) > 0)\n\t\t\tFD_SET(fileno(stderr), *writesetp);\n\t} else {\n\t\t/* channel_prepare_select could have closed the last channel */\n\t\tif (session_closed && !channel_still_open() &&\n\t\t !packet_have_data_to_write()) {\n\t\t\t/* clear mask since we did not call select() */\n\t\t\tmemset(*readsetp, 0, *nallocp);\n\t\t\tmemset(*writesetp, 0, *nallocp);\n\t\t\treturn;\n\t\t} else {\n\t\t\tFD_SET(connection_in, *readsetp);\n\t\t}\n\t}\n\n\t/* Select server connection if have data to write to the server. */\n\tif (packet_have_data_to_write())\n\t\tFD_SET(connection_out, *writesetp);\n\n\t/*\n\t * Wait for something to happen. This will suspend the process until\n\t * some selected descriptor can be read, written, or has some other\n\t * event pending, or a timeout expires.\n\t */\n\n\ttimeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */\n\tif (options.server_alive_interval > 0 && compat20) {\n\t\ttimeout_secs = options.server_alive_interval;\n\t\tserver_alive_time = now + options.server_alive_interval;\n\t}\n\tif (options.rekey_interval > 0 && compat20 && !rekeying)\n\t\ttimeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());\n\tset_control_persist_exit_time();\n\tif (control_persist_exit_time > 0) {\n\t\ttimeout_secs = MINIMUM(timeout_secs,\n\t\t\tcontrol_persist_exit_time - now);\n\t\tif (timeout_secs < 0)\n\t\t\ttimeout_secs = 0;\n\t}\n\tif (minwait_secs != 0)\n\t\ttimeout_secs = MINIMUM(timeout_secs, (int)minwait_secs);\n\tif (timeout_secs == INT_MAX)\n\t\ttvp = NULL;\n\telse {\n\t\ttv.tv_sec = timeout_secs;\n\t\ttv.tv_usec = 0;\n\t\ttvp = &tv;\n\t}\n\n\tret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);\n\tif (ret < 0) {\n\t\tchar buf[100];\n\n\t\t/*\n\t\t * We have to clear the select masks, because we return.\n\t\t * We have to return, because the mainloop checks for the flags\n\t\t * set by the signal handlers.\n\t\t */\n\t\tmemset(*readsetp, 0, *nallocp);\n\t\tmemset(*writesetp, 0, *nallocp);\n\n\t\tif (errno == EINTR)\n\t\t\treturn;\n\t\t/* Note: we might still have data in the buffers. */\n\t\tsnprintf(buf, sizeof buf, \"select: %s\\r\\n\", strerror(errno));\n\t\tbuffer_append(&stderr_buffer, buf, strlen(buf));\n\t\tquit_pending = 1;\n\t} else if (ret == 0) {\n\t\t/*\n\t\t * Timeout. Could have been either keepalive or rekeying.\n\t\t * Keepalive we check here, rekeying is checked in clientloop.\n\t\t */\n\t\tif (server_alive_time != 0 && server_alive_time <= monotime())\n\t\t\tserver_alive_check();\n\t}\n\n}\n\nstatic void\nclient_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)\n{\n\t/* Flush stdout and stderr buffers. */\n\tif (buffer_len(bout) > 0)\n\t\tatomicio(vwrite, fileno(stdout), buffer_ptr(bout),\n\t\t buffer_len(bout));\n\tif (buffer_len(berr) > 0)\n\t\tatomicio(vwrite, fileno(stderr), buffer_ptr(berr),\n\t\t buffer_len(berr));\n\n\tleave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\n\t/*\n\t * Free (and clear) the buffer to reduce the amount of data that gets\n\t * written to swap.\n\t */\n\tbuffer_free(bin);\n\tbuffer_free(bout);\n\tbuffer_free(berr);\n\n\t/* Send the suspend signal to the program itself. */\n\tkill(getpid(), SIGTSTP);\n\n\t/* Reset window sizes in case they have changed */\n\treceived_window_change_signal = 1;\n\n\t/* OK, we have been continued by the user. Reinitialize buffers. */\n\tbuffer_init(bin);\n\tbuffer_init(bout);\n\tbuffer_init(berr);\n\n\tenter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n}\n\nstatic void\nclient_process_net_input(fd_set *readset)\n{\n\tint len;\n\tchar buf[SSH_IOBUFSZ];\n\n\t/*\n\t * Read input from the server, and add any such data to the buffer of\n\t * the packet subsystem.\n\t */\n\tif (FD_ISSET(connection_in, readset)) {\n\t\t/* Read as much as possible. */\n\t\tlen = read(connection_in, buf, sizeof(buf));\n\t\tif (len == 0) {\n\t\t\t/*\n\t\t\t * Received EOF. The remote host has closed the\n\t\t\t * connection.\n\t\t\t */\n\t\t\tsnprintf(buf, sizeof buf,\n\t\t\t \"Connection to %.300s closed by remote host.\\r\\n\",\n\t\t\t host);\n\t\t\tbuffer_append(&stderr_buffer, buf, strlen(buf));\n\t\t\tquit_pending = 1;\n\t\t\treturn;\n\t\t}\n\t\t/*\n\t\t * There is a kernel bug on Solaris that causes select to\n\t\t * sometimes wake up even though there is no data available.\n\t\t */\n\t\tif (len < 0 &&\n\t\t (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))\n\t\t\tlen = 0;\n\n\t\tif (len < 0) {\n\t\t\t/*\n\t\t\t * An error has encountered. Perhaps there is a\n\t\t\t * network problem.\n\t\t\t */\n\t\t\tsnprintf(buf, sizeof buf,\n\t\t\t \"Read from remote host %.300s: %.100s\\r\\n\",\n\t\t\t host, strerror(errno));\n\t\t\tbuffer_append(&stderr_buffer, buf, strlen(buf));\n\t\t\tquit_pending = 1;\n\t\t\treturn;\n\t\t}\n\t\tpacket_process_incoming(buf, len);\n\t}\n}\n\nstatic void\nclient_status_confirm(int type, Channel *c, void *ctx)\n{\n\tstruct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx;\n\tchar errmsg[256];\n\tint tochan;\n\n\t/*\n\t * If a TTY was explicitly requested, then a failure to allocate\n\t * one is fatal.\n\t */\n\tif (cr->action == CONFIRM_TTY &&\n\t (options.request_tty == REQUEST_TTY_FORCE ||\n\t options.request_tty == REQUEST_TTY_YES))\n\t\tcr->action = CONFIRM_CLOSE;\n\n\t/* XXX supress on mux _client_ quietmode */\n\ttochan = options.log_level >= SYSLOG_LEVEL_ERROR &&\n\t c->ctl_chan != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;\n\n\tif (type == SSH2_MSG_CHANNEL_SUCCESS) {\n\t\tdebug2(\"%s request accepted on channel %d\",\n\t\t cr->request_type, c->self);\n\t} else if (type == SSH2_MSG_CHANNEL_FAILURE) {\n\t\tif (tochan) {\n\t\t\tsnprintf(errmsg, sizeof(errmsg),\n\t\t\t \"%s request failed\\r\\n\", cr->request_type);\n\t\t} else {\n\t\t\tsnprintf(errmsg, sizeof(errmsg),\n\t\t\t \"%s request failed on channel %d\",\n\t\t\t cr->request_type, c->self);\n\t\t}\n\t\t/* If error occurred on primary session channel, then exit */\n\t\tif (cr->action == CONFIRM_CLOSE && c->self == session_ident)\n\t\t\tfatal(\"%s\", errmsg);\n\t\t/*\n\t\t * If error occurred on mux client, append to\n\t\t * their stderr.\n\t\t */\n\t\tif (tochan) {\n\t\t\tbuffer_append(&c->extended, errmsg,\n\t\t\t strlen(errmsg));\n\t\t} else\n\t\t\terror(\"%s\", errmsg);\n\t\tif (cr->action == CONFIRM_TTY) {\n\t\t\t/*\n\t\t\t * If a TTY allocation error occurred, then arrange\n\t\t\t * for the correct TTY to leave raw mode.\n\t\t\t */\n\t\t\tif (c->self == session_ident)\n\t\t\t\tleave_raw_mode(0);\n\t\t\telse\n\t\t\t\tmux_tty_alloc_failed(c);\n\t\t} else if (cr->action == CONFIRM_CLOSE) {\n\t\t\tchan_read_failed(c);\n\t\t\tchan_write_failed(c);\n\t\t}\n\t}\n\tfree(cr);\n}\n\nstatic void\nclient_abandon_status_confirm(Channel *c, void *ctx)\n{\n\tfree(ctx);\n}\n\nvoid\nclient_expect_confirm(int id, const char *request,\n enum confirm_action action)\n{\n\tstruct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr));\n\n\tcr->request_type = request;\n\tcr->action = action;\n\n\tchannel_register_status_confirm(id, client_status_confirm,\n\t client_abandon_status_confirm, cr);\n}\n\nvoid\nclient_register_global_confirm(global_confirm_cb *cb, void *ctx)\n{\n\tstruct global_confirm *gc, *last_gc;\n\n\t/* Coalesce identical callbacks */\n\tlast_gc = TAILQ_LAST(&global_confirms, global_confirms);\n\tif (last_gc && last_gc->cb == cb && last_gc->ctx == ctx) {\n\t\tif (++last_gc->ref_count >= INT_MAX)\n\t\t\tfatal(\"%s: last_gc->ref_count = %d\",\n\t\t\t __func__, last_gc->ref_count);\n\t\treturn;\n\t}\n\n\tgc = xcalloc(1, sizeof(*gc));\n\tgc->cb = cb;\n\tgc->ctx = ctx;\n\tgc->ref_count = 1;\n\tTAILQ_INSERT_TAIL(&global_confirms, gc, entry);\n}\n\nstatic void\nprocess_cmdline(void)\n{\n\tvoid (*handler)(int);\n\tchar *s, *cmd;\n\tint ok, delete = 0, local = 0, remote = 0, dynamic = 0;\n\tstruct Forward fwd;\n\n\tmemset(&fwd, 0, sizeof(fwd));\n\n\tleave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\thandler = signal(SIGINT, SIG_IGN);\n\tcmd = s = read_passphrase(\"\\r\\nssh> \", RP_ECHO);\n\tif (s == NULL)\n\t\tgoto out;\n\twhile (isspace((u_char)*s))\n\t\ts++;\n\tif (*s == '-')\n\t\ts++;\t/* Skip cmdline '-', if any */\n\tif (*s == '\\0')\n\t\tgoto out;\n\n\tif (*s == 'h' || *s == 'H' || *s == '?') {\n\t\tlogit(\"Commands:\");\n\t\tlogit(\" -L[bind_address:]port:host:hostport \"\n\t\t \"Request local forward\");\n\t\tlogit(\" -R[bind_address:]port:host:hostport \"\n\t\t \"Request remote forward\");\n\t\tlogit(\" -D[bind_address:]port \"\n\t\t \"Request dynamic forward\");\n\t\tlogit(\" -KL[bind_address:]port \"\n\t\t \"Cancel local forward\");\n\t\tlogit(\" -KR[bind_address:]port \"\n\t\t \"Cancel remote forward\");\n\t\tlogit(\" -KD[bind_address:]port \"\n\t\t \"Cancel dynamic forward\");\n\t\tif (!options.permit_local_command)\n\t\t\tgoto out;\n\t\tlogit(\" !args \"\n\t\t \"Execute local command\");\n\t\tgoto out;\n\t}\n\n\tif (*s == '!' && options.permit_local_command) {\n\t\ts++;\n\t\tssh_local_cmd(s);\n\t\tgoto out;\n\t}\n\n\tif (*s == 'K') {\n\t\tdelete = 1;\n\t\ts++;\n\t}\n\tif (*s == 'L')\n\t\tlocal = 1;\n\telse if (*s == 'R')\n\t\tremote = 1;\n\telse if (*s == 'D')\n\t\tdynamic = 1;\n\telse {\n\t\tlogit(\"Invalid command.\");\n\t\tgoto out;\n\t}\n\n\tif (delete && !compat20) {\n\t\tlogit(\"Not supported for SSH protocol version 1.\");\n\t\tgoto out;\n\t}\n\n\twhile (isspace((u_char)*++s))\n\t\t;\n\n\t/* XXX update list of forwards in options */\n\tif (delete) {\n\t\t/* We pass 1 for dynamicfwd to restrict to 1 or 2 fields. */\n\t\tif (!parse_forward(&fwd, s, 1, 0)) {\n\t\t\tlogit(\"Bad forwarding close specification.\");\n\t\t\tgoto out;\n\t\t}\n\t\tif (remote)\n\t\t\tok = channel_request_rforward_cancel(&fwd) == 0;\n\t\telse if (dynamic)\n\t\t\tok = channel_cancel_lport_listener(&fwd,\n\t\t\t 0, &options.fwd_opts) > 0;\n\t\telse\n\t\t\tok = channel_cancel_lport_listener(&fwd,\n\t\t\t CHANNEL_CANCEL_PORT_STATIC,\n\t\t\t &options.fwd_opts) > 0;\n\t\tif (!ok) {\n\t\t\tlogit(\"Unknown port forwarding.\");\n\t\t\tgoto out;\n\t\t}\n\t\tlogit(\"Canceled forwarding.\");\n\t} else {\n\t\tif (!parse_forward(&fwd, s, dynamic, remote)) {\n\t\t\tlogit(\"Bad forwarding specification.\");\n\t\t\tgoto out;\n\t\t}\n\t\tif (local || dynamic) {\n\t\t\tif (!channel_setup_local_fwd_listener(&fwd,\n\t\t\t &options.fwd_opts)) {\n\t\t\t\tlogit(\"Port forwarding failed.\");\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t} else {\n\t\t\tif (channel_request_remote_forwarding(&fwd) < 0) {\n\t\t\t\tlogit(\"Port forwarding failed.\");\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\tlogit(\"Forwarding port.\");\n\t}\n\nout:\n\tsignal(SIGINT, handler);\n\tenter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\tfree(cmd);\n\tfree(fwd.listen_host);\n\tfree(fwd.listen_path);\n\tfree(fwd.connect_host);\n\tfree(fwd.connect_path);\n}\n\n/* reasons to suppress output of an escape command in help output */\n#define SUPPRESS_NEVER\t\t0\t/* never suppress, always show */\n#define SUPPRESS_PROTO1\t\t1\t/* don't show in protocol 1 sessions */\n#define SUPPRESS_MUXCLIENT\t2\t/* don't show in mux client sessions */\n#define SUPPRESS_MUXMASTER\t4\t/* don't show in mux master sessions */\n#define SUPPRESS_SYSLOG\t\t8\t/* don't show when logging to syslog */\nstruct escape_help_text {\n\tconst char *cmd;\n\tconst char *text;\n\tunsigned int flags;\n};\nstatic struct escape_help_text esc_txt[] = {\n {\".\", \"terminate session\", SUPPRESS_MUXMASTER},\n {\".\", \"terminate connection (and any multiplexed sessions)\",\n\tSUPPRESS_MUXCLIENT},\n {\"B\", \"send a BREAK to the remote system\", SUPPRESS_PROTO1},\n {\"C\", \"open a command line\", SUPPRESS_MUXCLIENT},\n {\"R\", \"request rekey\", SUPPRESS_PROTO1},\n {\"V/v\", \"decrease/increase verbosity (LogLevel)\", SUPPRESS_MUXCLIENT},\n {\"^Z\", \"suspend ssh\", SUPPRESS_MUXCLIENT},\n {\"#\", \"list forwarded connections\", SUPPRESS_NEVER},\n {\"&\", \"background ssh (when waiting for connections to terminate)\",\n\tSUPPRESS_MUXCLIENT},\n {\"?\", \"this message\", SUPPRESS_NEVER},\n};\n\nstatic void\nprint_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,\n int using_stderr)\n{\n\tunsigned int i, suppress_flags;\n\tchar string[1024];\n\n\tsnprintf(string, sizeof string, \"%c?\\r\\n\"\n\t \"Supported escape sequences:\\r\\n\", escape_char);\n\tbuffer_append(b, string, strlen(string));\n\n\tsuppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) |\n\t (mux_client ? SUPPRESS_MUXCLIENT : 0) |\n\t (mux_client ? 0 : SUPPRESS_MUXMASTER) |\n\t (using_stderr ? 0 : SUPPRESS_SYSLOG);\n\n\tfor (i = 0; i < sizeof(esc_txt)/sizeof(esc_txt[0]); i++) {\n\t\tif (esc_txt[i].flags & suppress_flags)\n\t\t\tcontinue;\n\t\tsnprintf(string, sizeof string, \" %c%-3s - %s\\r\\n\",\n\t\t escape_char, esc_txt[i].cmd, esc_txt[i].text);\n\t\tbuffer_append(b, string, strlen(string));\n\t}\n\n\tsnprintf(string, sizeof string,\n\t \" %c%c - send the escape character by typing it twice\\r\\n\"\n\t \"(Note that escapes are only recognized immediately after \"\n\t \"newline.)\\r\\n\", escape_char, escape_char);\n\tbuffer_append(b, string, strlen(string));\n}\n\n/* \n * Process the characters one by one, call with c==NULL for proto1 case.\n */\nstatic int\nprocess_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,\n char *buf, int len)\n{\n\tchar string[1024];\n\tpid_t pid;\n\tint bytes = 0;\n\tu_int i;\n\tu_char ch;\n\tchar *s;\n\tint *escape_pendingp, escape_char;\n\tstruct escape_filter_ctx *efc;\n\n\tif (c == NULL) {\n\t\tescape_pendingp = &escape_pending1;\n\t\tescape_char = escape_char1;\n\t} else {\n\t\tif (c->filter_ctx == NULL)\n\t\t\treturn 0;\n\t\tefc = (struct escape_filter_ctx *)c->filter_ctx;\n\t\tescape_pendingp = &efc->escape_pending;\n\t\tescape_char = efc->escape_char;\n\t}\n\t\n\tif (len <= 0)\n\t\treturn (0);\n\n\tfor (i = 0; i < (u_int)len; i++) {\n\t\t/* Get one character at a time. */\n\t\tch = buf[i];\n\n\t\tif (*escape_pendingp) {\n\t\t\t/* We have previously seen an escape character. */\n\t\t\t/* Clear the flag now. */\n\t\t\t*escape_pendingp = 0;\n\n\t\t\t/* Process the escaped character. */\n\t\t\tswitch (ch) {\n\t\t\tcase '.':\n\t\t\t\t/* Terminate the connection. */\n\t\t\t\tsnprintf(string, sizeof string, \"%c.\\r\\n\",\n\t\t\t\t escape_char);\n\t\t\t\tbuffer_append(berr, string, strlen(string));\n\n\t\t\t\tif (c && c->ctl_chan != -1) {\n\t\t\t\t\tchan_read_failed(c);\n\t\t\t\t\tchan_write_failed(c);\n\t\t\t\t\tif (c->detach_user)\n\t\t\t\t\t\tc->detach_user(c->self, NULL);\n\t\t\t\t\tc->type = SSH_CHANNEL_ABANDONED;\n\t\t\t\t\tbuffer_clear(&c->input);\n\t\t\t\t\tchan_ibuf_empty(c);\n\t\t\t\t\treturn 0;\n\t\t\t\t} else\n\t\t\t\t\tquit_pending = 1;\n\t\t\t\treturn -1;\n\n\t\t\tcase 'Z' - 64:\n\t\t\t\t/* XXX support this for mux clients */\n\t\t\t\tif (c && c->ctl_chan != -1) {\n\t\t\t\t\tchar b[16];\n noescape:\n\t\t\t\t\tif (ch == 'Z' - 64)\n\t\t\t\t\t\tsnprintf(b, sizeof b, \"^Z\");\n\t\t\t\t\telse\n\t\t\t\t\t\tsnprintf(b, sizeof b, \"%c\", ch);\n\t\t\t\t\tsnprintf(string, sizeof string,\n\t\t\t\t\t \"%c%s escape not available to \"\n\t\t\t\t\t \"multiplexed sessions\\r\\n\",\n\t\t\t\t\t escape_char, b);\n\t\t\t\t\tbuffer_append(berr, string,\n\t\t\t\t\t strlen(string));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t/* Suspend the program. Inform the user */\n\t\t\t\tsnprintf(string, sizeof string,\n\t\t\t\t \"%c^Z [suspend ssh]\\r\\n\", escape_char);\n\t\t\t\tbuffer_append(berr, string, strlen(string));\n\n\t\t\t\t/* Restore terminal modes and suspend. */\n\t\t\t\tclient_suspend_self(bin, bout, berr);\n\n\t\t\t\t/* We have been continued. */\n\t\t\t\tcontinue;\n\n\t\t\tcase 'B':\n\t\t\t\tif (compat20) {\n\t\t\t\t\tsnprintf(string, sizeof string,\n\t\t\t\t\t \"%cB\\r\\n\", escape_char);\n\t\t\t\t\tbuffer_append(berr, string,\n\t\t\t\t\t strlen(string));\n\t\t\t\t\tchannel_request_start(c->self,\n\t\t\t\t\t \"break\", 0);\n\t\t\t\t\tpacket_put_int(1000);\n\t\t\t\t\tpacket_send();\n\t\t\t\t}\n\t\t\t\tcontinue;\n\n\t\t\tcase 'R':\n\t\t\t\tif (compat20) {\n\t\t\t\t\tif (datafellows & SSH_BUG_NOREKEY)\n\t\t\t\t\t\tlogit(\"Server does not \"\n\t\t\t\t\t\t \"support re-keying\");\n\t\t\t\t\telse\n\t\t\t\t\t\tneed_rekeying = 1;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\n\t\t\tcase 'V':\n\t\t\t\t/* FALLTHROUGH */\n\t\t\tcase 'v':\n\t\t\t\tif (c && c->ctl_chan != -1)\n\t\t\t\t\tgoto noescape;\n\t\t\t\tif (!log_is_on_stderr()) {\n\t\t\t\t\tsnprintf(string, sizeof string,\n\t\t\t\t\t \"%c%c [Logging to syslog]\\r\\n\",\n\t\t\t\t\t escape_char, ch);\n\t\t\t\t\tbuffer_append(berr, string,\n\t\t\t\t\t strlen(string));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (ch == 'V' && options.log_level >\n\t\t\t\t SYSLOG_LEVEL_QUIET)\n\t\t\t\t\tlog_change_level(--options.log_level);\n\t\t\t\tif (ch == 'v' && options.log_level <\n\t\t\t\t SYSLOG_LEVEL_DEBUG3)\n\t\t\t\t\tlog_change_level(++options.log_level);\n\t\t\t\tsnprintf(string, sizeof string,\n\t\t\t\t \"%c%c [LogLevel %s]\\r\\n\", escape_char, ch,\n\t\t\t\t log_level_name(options.log_level));\n\t\t\t\tbuffer_append(berr, string, strlen(string));\n\t\t\t\tcontinue;\n\n\t\t\tcase '&':\n\t\t\t\tif (c && c->ctl_chan != -1)\n\t\t\t\t\tgoto noescape;\n\t\t\t\t/*\n\t\t\t\t * Detach the program (continue to serve\n\t\t\t\t * connections, but put in background and no\n\t\t\t\t * more new connections).\n\t\t\t\t */\n\t\t\t\t/* Restore tty modes. */\n\t\t\t\tleave_raw_mode(\n\t\t\t\t options.request_tty == REQUEST_TTY_FORCE);\n\n\t\t\t\t/* Stop listening for new connections. */\n\t\t\t\tchannel_stop_listening();\n\n\t\t\t\tsnprintf(string, sizeof string,\n\t\t\t\t \"%c& [backgrounded]\\n\", escape_char);\n\t\t\t\tbuffer_append(berr, string, strlen(string));\n\n\t\t\t\t/* Fork into background. */\n\t\t\t\tpid = fork();\n\t\t\t\tif (pid < 0) {\n\t\t\t\t\terror(\"fork: %.100s\", strerror(errno));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (pid != 0) {\t/* This is the parent. */\n\t\t\t\t\t/* The parent just exits. */\n\t\t\t\t\texit(0);\n\t\t\t\t}\n\t\t\t\t/* The child continues serving connections. */\n\t\t\t\tif (compat20) {\n\t\t\t\t\tbuffer_append(bin, \"\\004\", 1);\n\t\t\t\t\t/* fake EOF on stdin */\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (!stdin_eof) {\n\t\t\t\t\t/*\n\t\t\t\t\t * Sending SSH_CMSG_EOF alone does not\n\t\t\t\t\t * always appear to be enough. So we\n\t\t\t\t\t * try to send an EOF character first.\n\t\t\t\t\t */\n\t\t\t\t\tpacket_start(SSH_CMSG_STDIN_DATA);\n\t\t\t\t\tpacket_put_string(\"\\004\", 1);\n\t\t\t\t\tpacket_send();\n\t\t\t\t\t/* Close stdin. */\n\t\t\t\t\tstdin_eof = 1;\n\t\t\t\t\tif (buffer_len(bin) == 0) {\n\t\t\t\t\t\tpacket_start(SSH_CMSG_EOF);\n\t\t\t\t\t\tpacket_send();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue;\n\n\t\t\tcase '?':\n\t\t\t\tprint_escape_help(berr, escape_char, compat20,\n\t\t\t\t (c && c->ctl_chan != -1),\n\t\t\t\t log_is_on_stderr());\n\t\t\t\tcontinue;\n\n\t\t\tcase '#':\n\t\t\t\tsnprintf(string, sizeof string, \"%c#\\r\\n\",\n\t\t\t\t escape_char);\n\t\t\t\tbuffer_append(berr, string, strlen(string));\n\t\t\t\ts = channel_open_message();\n\t\t\t\tbuffer_append(berr, s, strlen(s));\n\t\t\t\tfree(s);\n\t\t\t\tcontinue;\n\n\t\t\tcase 'C':\n\t\t\t\tif (c && c->ctl_chan != -1)\n\t\t\t\t\tgoto noescape;\n\t\t\t\tprocess_cmdline();\n\t\t\t\tcontinue;\n\n\t\t\tdefault:\n\t\t\t\tif (ch != escape_char) {\n\t\t\t\t\tbuffer_put_char(bin, escape_char);\n\t\t\t\t\tbytes++;\n\t\t\t\t}\n\t\t\t\t/* Escaped characters fall through here */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\t/*\n\t\t\t * The previous character was not an escape char.\n\t\t\t * Check if this is an escape.\n\t\t\t */\n\t\t\tif (last_was_cr && ch == escape_char) {\n\t\t\t\t/*\n\t\t\t\t * It is. Set the flag and continue to\n\t\t\t\t * next character.\n\t\t\t\t */\n\t\t\t\t*escape_pendingp = 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * Normal character. Record whether it was a newline,\n\t\t * and append it to the buffer.\n\t\t */\n\t\tlast_was_cr = (ch == '\\r' || ch == '\\n');\n\t\tbuffer_put_char(bin, ch);\n\t\tbytes++;\n\t}\n\treturn bytes;\n}\n\nstatic void\nclient_process_input(fd_set *readset)\n{\n\tint len;\n\tchar buf[SSH_IOBUFSZ];\n\n\t/* Read input from stdin. */\n\tif (FD_ISSET(fileno(stdin), readset)) {\n\t\t/* Read as much as possible. */\n\t\tlen = read(fileno(stdin), buf, sizeof(buf));\n\t\tif (len < 0 &&\n\t\t (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))\n\t\t\treturn;\t\t/* we'll try again later */\n\t\tif (len <= 0) {\n\t\t\t/*\n\t\t\t * Received EOF or error. They are treated\n\t\t\t * similarly, except that an error message is printed\n\t\t\t * if it was an error condition.\n\t\t\t */\n\t\t\tif (len < 0) {\n\t\t\t\tsnprintf(buf, sizeof buf, \"read: %.100s\\r\\n\",\n\t\t\t\t strerror(errno));\n\t\t\t\tbuffer_append(&stderr_buffer, buf, strlen(buf));\n\t\t\t}\n\t\t\t/* Mark that we have seen EOF. */\n\t\t\tstdin_eof = 1;\n\t\t\t/*\n\t\t\t * Send an EOF message to the server unless there is\n\t\t\t * data in the buffer. If there is data in the\n\t\t\t * buffer, no message will be sent now. Code\n\t\t\t * elsewhere will send the EOF when the buffer\n\t\t\t * becomes empty if stdin_eof is set.\n\t\t\t */\n\t\t\tif (buffer_len(&stdin_buffer) == 0) {\n\t\t\t\tpacket_start(SSH_CMSG_EOF);\n\t\t\t\tpacket_send();\n\t\t\t}\n\t\t} else if (escape_char1 == SSH_ESCAPECHAR_NONE) {\n\t\t\t/*\n\t\t\t * Normal successful read, and no escape character.\n\t\t\t * Just append the data to buffer.\n\t\t\t */\n\t\t\tbuffer_append(&stdin_buffer, buf, len);\n\t\t} else {\n\t\t\t/*\n\t\t\t * Normal, successful read. But we have an escape\n\t\t\t * character and have to process the characters one\n\t\t\t * by one.\n\t\t\t */\n\t\t\tif (process_escapes(NULL, &stdin_buffer,\n\t\t\t &stdout_buffer, &stderr_buffer, buf, len) == -1)\n\t\t\t\treturn;\n\t\t}\n\t}\n}\n\nstatic void\nclient_process_output(fd_set *writeset)\n{\n\tint len;\n\tchar buf[100];\n\n\t/* Write buffered output to stdout. */\n\tif (FD_ISSET(fileno(stdout), writeset)) {\n\t\t/* Write as much data as possible. */\n\t\tlen = write(fileno(stdout), buffer_ptr(&stdout_buffer),\n\t\t buffer_len(&stdout_buffer));\n\t\tif (len <= 0) {\n\t\t\tif (errno == EINTR || errno == EAGAIN ||\n\t\t\t errno == EWOULDBLOCK)\n\t\t\t\tlen = 0;\n\t\t\telse {\n\t\t\t\t/*\n\t\t\t\t * An error or EOF was encountered. Put an\n\t\t\t\t * error message to stderr buffer.\n\t\t\t\t */\n\t\t\t\tsnprintf(buf, sizeof buf,\n\t\t\t\t \"write stdout: %.50s\\r\\n\", strerror(errno));\n\t\t\t\tbuffer_append(&stderr_buffer, buf, strlen(buf));\n\t\t\t\tquit_pending = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t/* Consume printed data from the buffer. */\n\t\tbuffer_consume(&stdout_buffer, len);\n\t}\n\t/* Write buffered output to stderr. */\n\tif (FD_ISSET(fileno(stderr), writeset)) {\n\t\t/* Write as much data as possible. */\n\t\tlen = write(fileno(stderr), buffer_ptr(&stderr_buffer),\n\t\t buffer_len(&stderr_buffer));\n\t\tif (len <= 0) {\n\t\t\tif (errno == EINTR || errno == EAGAIN ||\n\t\t\t errno == EWOULDBLOCK)\n\t\t\t\tlen = 0;\n\t\t\telse {\n\t\t\t\t/*\n\t\t\t\t * EOF or error, but can't even print\n\t\t\t\t * error message.\n\t\t\t\t */\n\t\t\t\tquit_pending = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t/* Consume printed characters from the buffer. */\n\t\tbuffer_consume(&stderr_buffer, len);\n\t}\n}\n\n/*\n * Get packets from the connection input buffer, and process them as long as\n * there are packets available.\n *\n * Any unknown packets received during the actual\n * session cause the session to terminate. This is\n * intended to make debugging easier since no\n * confirmations are sent. Any compatible protocol\n * extensions must be negotiated during the\n * preparatory phase.\n */\n\nstatic void\nclient_process_buffered_input_packets(void)\n{\n\tdispatch_run(DISPATCH_NONBLOCK, &quit_pending, active_state);\n}\n\n/* scan buf[] for '~' before sending data to the peer */\n\n/* Helper: allocate a new escape_filter_ctx and fill in its escape char */\nvoid *\nclient_new_escape_filter_ctx(int escape_char)\n{\n\tstruct escape_filter_ctx *ret;\n\n\tret = xcalloc(1, sizeof(*ret));\n\tret->escape_pending = 0;\n\tret->escape_char = escape_char;\n\treturn (void *)ret;\n}\n\n/* Free the escape filter context on channel free */\nvoid\nclient_filter_cleanup(int cid, void *ctx)\n{\n\tfree(ctx);\n}\n\nint\nclient_simple_escape_filter(Channel *c, char *buf, int len)\n{\n\tif (c->extended_usage != CHAN_EXTENDED_WRITE)\n\t\treturn 0;\n\n\treturn process_escapes(c, &c->input, &c->output, &c->extended,\n\t buf, len);\n}\n\nstatic void\nclient_channel_closed(int id, void *arg)\n{\n\tchannel_cancel_cleanup(id);\n\tsession_closed = 1;\n\tleave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n}\n\n/*\n * Implements the interactive session with the server. This is called after\n * the user has been authenticated, and a command has been started on the\n * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character\n * used as an escape character for terminating or suspending the session.\n */\n\nint\nclient_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)\n{\n\tfd_set *readset = NULL, *writeset = NULL;\n\tdouble start_time, total_time;\n\tint r, max_fd = 0, max_fd2 = 0, len;\n\tu_int64_t ibytes, obytes;\n\tu_int nalloc = 0;\n\tchar buf[100];\n\n\tdebug(\"Entering interactive session.\");\n\n\tif (options.control_master &&\n\t !option_clear_or_none(options.control_path)) {\n\t\tdebug(\"pledge: id\");\n\t\tif (pledge(\"stdio rpath wpath cpath unix inet dns recvfd proc exec id tty\",\n\t\t NULL) == -1)\n\t\t\tfatal(\"%s pledge(): %s\", __func__, strerror(errno));\n\n\t} else if (options.forward_x11 || options.permit_local_command) {\n\t\tdebug(\"pledge: exec\");\n\t\tif (pledge(\"stdio rpath wpath cpath unix inet dns proc exec tty\",\n\t\t NULL) == -1)\n\t\t\tfatal(\"%s pledge(): %s\", __func__, strerror(errno));\n\n\t} else if (options.update_hostkeys) {\n\t\tdebug(\"pledge: filesystem full\");\n\t\tif (pledge(\"stdio rpath wpath cpath unix inet dns proc tty\",\n\t\t NULL) == -1)\n\t\t\tfatal(\"%s pledge(): %s\", __func__, strerror(errno));\n\n\t} else if (!option_clear_or_none(options.proxy_command) ||\n\t fork_after_authentication_flag) {\n\t\tdebug(\"pledge: proc\");\n\t\tif (pledge(\"stdio cpath unix inet dns proc tty\", NULL) == -1)\n\t\t\tfatal(\"%s pledge(): %s\", __func__, strerror(errno));\n\n\t} else {\n\t\tdebug(\"pledge: network\");\n\t\tif (pledge(\"stdio unix inet dns tty\", NULL) == -1)\n\t\t\tfatal(\"%s pledge(): %s\", __func__, strerror(errno));\n\t}\n\n\tstart_time = get_current_time();\n\n\t/* Initialize variables. */\n\tescape_pending1 = 0;\n\tlast_was_cr = 1;\n\texit_status = -1;\n\tstdin_eof = 0;\n\tbuffer_high = 64 * 1024;\n\tconnection_in = packet_get_connection_in();\n\tconnection_out = packet_get_connection_out();\n\tmax_fd = MAXIMUM(connection_in, connection_out);\n\n\tif (!compat20) {\n\t\t/* enable nonblocking unless tty */\n\t\tif (!isatty(fileno(stdin)))\n\t\t\tset_nonblock(fileno(stdin));\n\t\tif (!isatty(fileno(stdout)))\n\t\t\tset_nonblock(fileno(stdout));\n\t\tif (!isatty(fileno(stderr)))\n\t\t\tset_nonblock(fileno(stderr));\n\t\tmax_fd = MAXIMUM(max_fd, fileno(stdin));\n\t\tmax_fd = MAXIMUM(max_fd, fileno(stdout));\n\t\tmax_fd = MAXIMUM(max_fd, fileno(stderr));\n\t}\n\tquit_pending = 0;\n\tescape_char1 = escape_char_arg;\n\n\t/* Initialize buffers. */\n\tbuffer_init(&stdin_buffer);\n\tbuffer_init(&stdout_buffer);\n\tbuffer_init(&stderr_buffer);\n\n\tclient_init_dispatch();\n\n\t/*\n\t * Set signal handlers, (e.g. to restore non-blocking mode)\n\t * but don't overwrite SIG_IGN, matches behaviour from rsh(1)\n\t */\n\tif (signal(SIGHUP, SIG_IGN) != SIG_IGN)\n\t\tsignal(SIGHUP, signal_handler);\n\tif (signal(SIGINT, SIG_IGN) != SIG_IGN)\n\t\tsignal(SIGINT, signal_handler);\n\tif (signal(SIGQUIT, SIG_IGN) != SIG_IGN)\n\t\tsignal(SIGQUIT, signal_handler);\n\tif (signal(SIGTERM, SIG_IGN) != SIG_IGN)\n\t\tsignal(SIGTERM, signal_handler);\n\tsignal(SIGWINCH, window_change_handler);\n\n\tif (have_pty)\n\t\tenter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\n\tif (compat20) {\n\t\tsession_ident = ssh2_chan_id;\n\t\tif (session_ident != -1) {\n\t\t\tif (escape_char_arg != SSH_ESCAPECHAR_NONE) {\n\t\t\t\tchannel_register_filter(session_ident,\n\t\t\t\t client_simple_escape_filter, NULL,\n\t\t\t\t client_filter_cleanup,\n\t\t\t\t client_new_escape_filter_ctx(\n\t\t\t\t escape_char_arg));\n\t\t\t}\n\t\t\tchannel_register_cleanup(session_ident,\n\t\t\t client_channel_closed, 0);\n\t\t}\n\t} else {\n\t\t/* Check if we should immediately send eof on stdin. */\n\t\tclient_check_initial_eof_on_stdin();\n\t}\n\n\t/* Main loop of the client for the interactive session mode. */\n\twhile (!quit_pending) {\n\n\t\t/* Process buffered packets sent by the server. */\n\t\tclient_process_buffered_input_packets();\n\n\t\tif (compat20 && session_closed && !channel_still_open())\n\t\t\tbreak;\n\n\t\tif (ssh_packet_is_rekeying(active_state)) {\n\t\t\tdebug(\"rekeying in progress\");\n\t\t} else if (need_rekeying) {\n\t\t\t/* manual rekey request */\n\t\t\tdebug(\"need rekeying\");\n\t\t\tif ((r = kex_start_rekex(active_state)) != 0)\n\t\t\t\tfatal(\"%s: kex_start_rekex: %s\", __func__,\n\t\t\t\t ssh_err(r));\n\t\t\tneed_rekeying = 0;\n\t\t} else {\n\t\t\t/*\n\t\t\t * Make packets of buffered stdin data, and buffer\n\t\t\t * them for sending to the server.\n\t\t\t */\n\t\t\tif (!compat20)\n\t\t\t\tclient_make_packets_from_stdin_data();\n\n\t\t\t/*\n\t\t\t * Make packets from buffered channel data, and\n\t\t\t * enqueue them for sending to the server.\n\t\t\t */\n\t\t\tif (packet_not_very_much_data_to_write())\n\t\t\t\tchannel_output_poll();\n\n\t\t\t/*\n\t\t\t * Check if the window size has changed, and buffer a\n\t\t\t * message about it to the server if so.\n\t\t\t */\n\t\t\tclient_check_window_change();\n\n\t\t\tif (quit_pending)\n\t\t\t\tbreak;\n\t\t}\n\t\t/*\n\t\t * Wait until we have something to do (something becomes\n\t\t * available on one of the descriptors).\n\t\t */\n\t\tmax_fd2 = max_fd;\n\t\tclient_wait_until_can_do_something(&readset, &writeset,\n\t\t &max_fd2, &nalloc, ssh_packet_is_rekeying(active_state));\n\n\t\tif (quit_pending)\n\t\t\tbreak;\n\n\t\t/* Do channel operations unless rekeying in progress. */\n\t\tif (!ssh_packet_is_rekeying(active_state))\n\t\t\tchannel_after_select(readset, writeset);\n\n\t\t/* Buffer input from the connection. */\n\t\tclient_process_net_input(readset);\n\n\t\tif (quit_pending)\n\t\t\tbreak;\n\n\t\tif (!compat20) {\n\t\t\t/* Buffer data from stdin */\n\t\t\tclient_process_input(readset);\n\t\t\t/*\n\t\t\t * Process output to stdout and stderr. Output to\n\t\t\t * the connection is processed elsewhere (above).\n\t\t\t */\n\t\t\tclient_process_output(writeset);\n\t\t}\n\n\t\t/*\n\t\t * Send as much buffered packet data as possible to the\n\t\t * sender.\n\t\t */\n\t\tif (FD_ISSET(connection_out, writeset))\n\t\t\tpacket_write_poll();\n\n\t\t/*\n\t\t * If we are a backgrounded control master, and the\n\t\t * timeout has expired without any active client\n\t\t * connections, then quit.\n\t\t */\n\t\tif (control_persist_exit_time > 0) {\n\t\t\tif (monotime() >= control_persist_exit_time) {\n\t\t\t\tdebug(\"ControlPersist timeout expired\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tfree(readset);\n\tfree(writeset);\n\n\t/* Terminate the session. */\n\n\t/* Stop watching for window change. */\n\tsignal(SIGWINCH, SIG_DFL);\n\n\tif (compat20) {\n\t\tpacket_start(SSH2_MSG_DISCONNECT);\n\t\tpacket_put_int(SSH2_DISCONNECT_BY_APPLICATION);\n\t\tpacket_put_cstring(\"disconnected by user\");\n\t\tpacket_put_cstring(\"\"); /* language tag */\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\t}\n\n\tchannel_free_all();\n\n\tif (have_pty)\n\t\tleave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\n\t/* restore blocking io */\n\tif (!isatty(fileno(stdin)))\n\t\tunset_nonblock(fileno(stdin));\n\tif (!isatty(fileno(stdout)))\n\t\tunset_nonblock(fileno(stdout));\n\tif (!isatty(fileno(stderr)))\n\t\tunset_nonblock(fileno(stderr));\n\n\t/*\n\t * If there was no shell or command requested, there will be no remote\n\t * exit status to be returned. In that case, clear error code if the\n\t * connection was deliberately terminated at this end.\n\t */\n\tif (no_shell_flag && received_signal == SIGTERM) {\n\t\treceived_signal = 0;\n\t\texit_status = 0;\n\t}\n\n\tif (received_signal)\n\t\tfatal(\"Killed by signal %d.\", (int) received_signal);\n\n\t/*\n\t * In interactive mode (with pseudo tty) display a message indicating\n\t * that the connection has been closed.\n\t */\n\tif (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {\n\t\tsnprintf(buf, sizeof buf,\n\t\t \"Connection to %.64s closed.\\r\\n\", host);\n\t\tbuffer_append(&stderr_buffer, buf, strlen(buf));\n\t}\n\n\t/* Output any buffered data for stdout. */\n\tif (buffer_len(&stdout_buffer) > 0) {\n\t\tlen = atomicio(vwrite, fileno(stdout),\n\t\t buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer));\n\t\tif (len < 0 || (u_int)len != buffer_len(&stdout_buffer))\n\t\t\terror(\"Write failed flushing stdout buffer.\");\n\t\telse\n\t\t\tbuffer_consume(&stdout_buffer, len);\n\t}\n\n\t/* Output any buffered data for stderr. */\n\tif (buffer_len(&stderr_buffer) > 0) {\n\t\tlen = atomicio(vwrite, fileno(stderr),\n\t\t buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer));\n\t\tif (len < 0 || (u_int)len != buffer_len(&stderr_buffer))\n\t\t\terror(\"Write failed flushing stderr buffer.\");\n\t\telse\n\t\t\tbuffer_consume(&stderr_buffer, len);\n\t}\n\n\t/* Clear and free any buffers. */\n\texplicit_bzero(buf, sizeof(buf));\n\tbuffer_free(&stdin_buffer);\n\tbuffer_free(&stdout_buffer);\n\tbuffer_free(&stderr_buffer);\n\n\t/* Report bytes transferred, and transfer rates. */\n\ttotal_time = get_current_time() - start_time;\n\tpacket_get_bytes(&ibytes, &obytes);\n\tverbose(\"Transferred: sent %llu, received %llu bytes, in %.1f seconds\",\n\t (unsigned long long)obytes, (unsigned long long)ibytes, total_time);\n\tif (total_time > 0)\n\t\tverbose(\"Bytes per second: sent %.1f, received %.1f\",\n\t\t obytes / total_time, ibytes / total_time);\n\t/* Return the exit status of the program. */\n\tdebug(\"Exit status %d\", exit_status);\n\treturn exit_status;\n}\n\n/*********/\n\nstatic int\nclient_input_stdout_data(int type, u_int32_t seq, void *ctxt)\n{\n\tu_int data_len;\n\tchar *data = packet_get_string(&data_len);\n\tpacket_check_eom();\n\tbuffer_append(&stdout_buffer, data, data_len);\n\texplicit_bzero(data, data_len);\n\tfree(data);\n\treturn 0;\n}\nstatic int\nclient_input_stderr_data(int type, u_int32_t seq, void *ctxt)\n{\n\tu_int data_len;\n\tchar *data = packet_get_string(&data_len);\n\tpacket_check_eom();\n\tbuffer_append(&stderr_buffer, data, data_len);\n\texplicit_bzero(data, data_len);\n\tfree(data);\n\treturn 0;\n}\nstatic int\nclient_input_exit_status(int type, u_int32_t seq, void *ctxt)\n{\n\texit_status = packet_get_int();\n\tpacket_check_eom();\n\t/* Acknowledge the exit. */\n\tpacket_start(SSH_CMSG_EXIT_CONFIRMATION);\n\tpacket_send();\n\t/*\n\t * Must wait for packet to be sent since we are\n\t * exiting the loop.\n\t */\n\tpacket_write_wait();\n\t/* Flag that we want to exit. */\n\tquit_pending = 1;\n\treturn 0;\n}\n\nstatic int\nclient_input_agent_open(int type, u_int32_t seq, void *ctxt)\n{\n\tChannel *c = NULL;\n\tint r, remote_id, sock;\n\n\t/* Read the remote channel number from the message. */\n\tremote_id = packet_get_int();\n\tpacket_check_eom();\n\n\t/*\n\t * Get a connection to the local authentication agent (this may again\n\t * get forwarded).\n\t */\n\tif ((r = ssh_get_authentication_socket(&sock)) != 0 &&\n\t r != SSH_ERR_AGENT_NOT_PRESENT)\n\t\tdebug(\"%s: ssh_get_authentication_socket: %s\",\n\t\t __func__, ssh_err(r));\n\n\n\t/*\n\t * If we could not connect the agent, send an error message back to\n\t * the server. This should never happen unless the agent dies,\n\t * because authentication forwarding is only enabled if we have an\n\t * agent.\n\t */\n\tif (sock >= 0) {\n\t\tc = channel_new(\"\", SSH_CHANNEL_OPEN, sock, sock,\n\t\t -1, 0, 0, 0, \"authentication agent connection\", 1);\n\t\tc->remote_id = remote_id;\n\t\tc->force_drain = 1;\n\t}\n\tif (c == NULL) {\n\t\tpacket_start(SSH_MSG_CHANNEL_OPEN_FAILURE);\n\t\tpacket_put_int(remote_id);\n\t} else {\n\t\t/* Send a confirmation to the remote host. */\n\t\tdebug(\"Forwarding authentication connection.\");\n\t\tpacket_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);\n\t\tpacket_put_int(remote_id);\n\t\tpacket_put_int(c->self);\n\t}\n\tpacket_send();\n\treturn 0;\n}\n\nstatic Channel *\nclient_request_forwarded_tcpip(const char *request_type, int rchan,\n u_int rwindow, u_int rmaxpack)\n{\n\tChannel *c = NULL;\n\tstruct sshbuf *b = NULL;\n\tchar *listen_address, *originator_address;\n\tu_short listen_port, originator_port;\n\tint r;\n\n\t/* Get rest of the packet */\n\tlisten_address = packet_get_string(NULL);\n\tlisten_port = packet_get_int();\n\toriginator_address = packet_get_string(NULL);\n\toriginator_port = packet_get_int();\n\tpacket_check_eom();\n\n\tdebug(\"%s: listen %s port %d, originator %s port %d\", __func__,\n\t listen_address, listen_port, originator_address, originator_port);\n\n\tc = channel_connect_by_listen_address(listen_address, listen_port,\n\t \"forwarded-tcpip\", originator_address);\n\n\tif (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {\n\t\tif ((b = sshbuf_new()) == NULL) {\n\t\t\terror(\"%s: alloc reply\", __func__);\n\t\t\tgoto out;\n\t\t}\n\t\t/* reconstruct and send to muxclient */\n\t\tif ((r = sshbuf_put_u8(b, 0)) != 0 ||\t/* padlen */\n\t\t (r = sshbuf_put_u8(b, SSH2_MSG_CHANNEL_OPEN)) != 0 ||\n\t\t (r = sshbuf_put_cstring(b, request_type)) != 0 ||\n\t\t (r = sshbuf_put_u32(b, rchan)) != 0 ||\n\t\t (r = sshbuf_put_u32(b, rwindow)) != 0 ||\n\t\t (r = sshbuf_put_u32(b, rmaxpack)) != 0 ||\n\t\t (r = sshbuf_put_cstring(b, listen_address)) != 0 ||\n\t\t (r = sshbuf_put_u32(b, listen_port)) != 0 ||\n\t\t (r = sshbuf_put_cstring(b, originator_address)) != 0 ||\n\t\t (r = sshbuf_put_u32(b, originator_port)) != 0 ||\n\t\t (r = sshbuf_put_stringb(&c->output, b)) != 0) {\n\t\t\terror(\"%s: compose for muxclient %s\", __func__,\n\t\t\t ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t}\n\n out:\n\tsshbuf_free(b);\n\tfree(originator_address);\n\tfree(listen_address);\n\treturn c;\n}\n\nstatic Channel *\nclient_request_forwarded_streamlocal(const char *request_type, int rchan)\n{\n\tChannel *c = NULL;\n\tchar *listen_path;\n\n\t/* Get the remote path. */\n\tlisten_path = packet_get_string(NULL);\n\t/* XXX: Skip reserved field for now. */\n\tif (packet_get_string_ptr(NULL) == NULL)\n\t\tfatal(\"%s: packet_get_string_ptr failed\", __func__);\n\tpacket_check_eom();\n\n\tdebug(\"%s: %s\", __func__, listen_path);\n\n\tc = channel_connect_by_listen_path(listen_path,\n\t \"forwarded-streamlocal@openssh.com\", \"forwarded-streamlocal\");\n\tfree(listen_path);\n\treturn c;\n}\n\nstatic Channel *\nclient_request_x11(const char *request_type, int rchan)\n{\n\tChannel *c = NULL;\n\tchar *originator;\n\tu_short originator_port;\n\tint sock;\n\n\tif (!options.forward_x11) {\n\t\terror(\"Warning: ssh server tried X11 forwarding.\");\n\t\terror(\"Warning: this is probably a break-in attempt by a \"\n\t\t \"malicious server.\");\n\t\treturn NULL;\n\t}\n\tif (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) {\n\t\tverbose(\"Rejected X11 connection after ForwardX11Timeout \"\n\t\t \"expired\");\n\t\treturn NULL;\n\t}\n\toriginator = packet_get_string(NULL);\n\tif (datafellows & SSH_BUG_X11FWD) {\n\t\tdebug2(\"buggy server: x11 request w/o originator_port\");\n\t\toriginator_port = 0;\n\t} else {\n\t\toriginator_port = packet_get_int();\n\t}\n\tpacket_check_eom();\n\t/* XXX check permission */\n\tdebug(\"client_request_x11: request from %s %d\", originator,\n\t originator_port);\n\tfree(originator);\n\tsock = x11_connect_display();\n\tif (sock < 0)\n\t\treturn NULL;\n\tc = channel_new(\"x11\",\n\t SSH_CHANNEL_X11_OPEN, sock, sock, -1,\n\t CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, \"x11\", 1);\n\tc->force_drain = 1;\n\treturn c;\n}\n\nstatic Channel *\nclient_request_agent(const char *request_type, int rchan)\n{\n\tChannel *c = NULL;\n\tint r, sock;\n\n\tif (!options.forward_agent) {\n\t\terror(\"Warning: ssh server tried agent forwarding.\");\n\t\terror(\"Warning: this is probably a break-in attempt by a \"\n\t\t \"malicious server.\");\n\t\treturn NULL;\n\t}\n\tif ((r = ssh_get_authentication_socket(&sock)) != 0) {\n\t\tif (r != SSH_ERR_AGENT_NOT_PRESENT)\n\t\t\tdebug(\"%s: ssh_get_authentication_socket: %s\",\n\t\t\t __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\tc = channel_new(\"authentication agent connection\",\n\t SSH_CHANNEL_OPEN, sock, sock, -1,\n\t CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,\n\t \"authentication agent connection\", 1);\n\tc->force_drain = 1;\n\treturn c;\n}\n\nint\nclient_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)\n{\n\tChannel *c;\n\tint fd;\n\n\tif (tun_mode == SSH_TUNMODE_NO)\n\t\treturn 0;\n\n\tif (!compat20) {\n\t\terror(\"Tunnel forwarding is not supported for protocol 1\");\n\t\treturn -1;\n\t}\n\n\tdebug(\"Requesting tun unit %d in mode %d\", local_tun, tun_mode);\n\n\t/* Open local tunnel device */\n\tif ((fd = tun_open(local_tun, tun_mode)) == -1) {\n\t\terror(\"Tunnel device open failed.\");\n\t\treturn -1;\n\t}\n\n\tc = channel_new(\"tun\", SSH_CHANNEL_OPENING, fd, fd, -1,\n\t CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, \"tun\", 1);\n\tc->datagram = 1;\n\n#if defined(SSH_TUN_FILTER)\n\tif (options.tun_open == SSH_TUNMODE_POINTOPOINT)\n\t\tchannel_register_filter(c->self, sys_tun_infilter,\n\t\t sys_tun_outfilter, NULL, NULL);\n#endif\n\n\tpacket_start(SSH2_MSG_CHANNEL_OPEN);\n\tpacket_put_cstring(\"tun@openssh.com\");\n\tpacket_put_int(c->self);\n\tpacket_put_int(c->local_window_max);\n\tpacket_put_int(c->local_maxpacket);\n\tpacket_put_int(tun_mode);\n\tpacket_put_int(remote_tun);\n\tpacket_send();\n\n\treturn 0;\n}\n\n/* XXXX move to generic input handler */\nstatic int\nclient_input_channel_open(int type, u_int32_t seq, void *ctxt)\n{\n\tChannel *c = NULL;\n\tchar *ctype;\n\tint rchan;\n\tu_int rmaxpack, rwindow, len;\n\n\tctype = packet_get_string(&len);\n\trchan = packet_get_int();\n\trwindow = packet_get_int();\n\trmaxpack = packet_get_int();\n\n\tdebug(\"client_input_channel_open: ctype %s rchan %d win %d max %d\",\n\t ctype, rchan, rwindow, rmaxpack);\n\n\tif (strcmp(ctype, \"forwarded-tcpip\") == 0) {\n\t\tc = client_request_forwarded_tcpip(ctype, rchan, rwindow,\n\t\t rmaxpack);\n\t} else if (strcmp(ctype, \"forwarded-streamlocal@openssh.com\") == 0) {\n\t\tc = client_request_forwarded_streamlocal(ctype, rchan);\n\t} else if (strcmp(ctype, \"x11\") == 0) {\n\t\tc = client_request_x11(ctype, rchan);\n\t} else if (strcmp(ctype, \"auth-agent@openssh.com\") == 0) {\n\t\tc = client_request_agent(ctype, rchan);\n\t}\n\tif (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {\n\t\tdebug3(\"proxied to downstream: %s\", ctype);\n\t} else if (c != NULL) {\n\t\tdebug(\"confirm %s\", ctype);\n\t\tc->remote_id = rchan;\n\t\tc->remote_window = rwindow;\n\t\tc->remote_maxpacket = rmaxpack;\n\t\tif (c->type != SSH_CHANNEL_CONNECTING) {\n\t\t\tpacket_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);\n\t\t\tpacket_put_int(c->remote_id);\n\t\t\tpacket_put_int(c->self);\n\t\t\tpacket_put_int(c->local_window);\n\t\t\tpacket_put_int(c->local_maxpacket);\n\t\t\tpacket_send();\n\t\t}\n\t} else {\n\t\tdebug(\"failure %s\", ctype);\n\t\tpacket_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);\n\t\tpacket_put_int(rchan);\n\t\tpacket_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);\n\t\tif (!(datafellows & SSH_BUG_OPENFAILURE)) {\n\t\t\tpacket_put_cstring(\"open failed\");\n\t\t\tpacket_put_cstring(\"\");\n\t\t}\n\t\tpacket_send();\n\t}\n\tfree(ctype);\n\treturn 0;\n}\n\nstatic int\nclient_input_channel_req(int type, u_int32_t seq, void *ctxt)\n{\n\tChannel *c = NULL;\n\tint exitval, id, reply, success = 0;\n\tchar *rtype;\n\n\tid = packet_get_int();\n\tc = channel_lookup(id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\trtype = packet_get_string(NULL);\n\treply = packet_get_char();\n\n\tdebug(\"client_input_channel_req: channel %d rtype %s reply %d\",\n\t id, rtype, reply);\n\n\tif (id == -1) {\n\t\terror(\"client_input_channel_req: request for channel -1\");\n\t} else if (c == NULL) {\n\t\terror(\"client_input_channel_req: channel %d: \"\n\t\t \"unknown channel\", id);\n\t} else if (strcmp(rtype, \"eow@openssh.com\") == 0) {\n\t\tpacket_check_eom();\n\t\tchan_rcvd_eow(c);\n\t} else if (strcmp(rtype, \"exit-status\") == 0) {\n\t\texitval = packet_get_int();\n\t\tif (c->ctl_chan != -1) {\n\t\t\tmux_exit_message(c, exitval);\n\t\t\tsuccess = 1;\n\t\t} else if (id == session_ident) {\n\t\t\t/* Record exit value of local session */\n\t\t\tsuccess = 1;\n\t\t\texit_status = exitval;\n\t\t} else {\n\t\t\t/* Probably for a mux channel that has already closed */\n\t\t\tdebug(\"%s: no sink for exit-status on channel %d\",\n\t\t\t __func__, id);\n\t\t}\n\t\tpacket_check_eom();\n\t}\n\tif (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {\n\t\tpacket_start(success ?\n\t\t SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_send();\n\t}\n\tfree(rtype);\n\treturn 0;\n}\n\nstruct hostkeys_update_ctx {\n\t/* The hostname and (optionally) IP address string for the server */\n\tchar *host_str, *ip_str;\n\n\t/*\n\t * Keys received from the server and a flag for each indicating\n\t * whether they already exist in known_hosts.\n\t * keys_seen is filled in by hostkeys_find() and later (for new\n\t * keys) by client_global_hostkeys_private_confirm().\n\t */\n\tstruct sshkey **keys;\n\tint *keys_seen;\n\tsize_t nkeys;\n\n\tsize_t nnew;\n\n\t/*\n\t * Keys that are in known_hosts, but were not present in the update\n\t * from the server (i.e. scheduled to be deleted).\n\t * Filled in by hostkeys_find().\n\t */\n\tstruct sshkey **old_keys;\n\tsize_t nold;\n};\n\nstatic void\nhostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx)\n{\n\tsize_t i;\n\n\tif (ctx == NULL)\n\t\treturn;\n\tfor (i = 0; i < ctx->nkeys; i++)\n\t\tsshkey_free(ctx->keys[i]);\n\tfree(ctx->keys);\n\tfree(ctx->keys_seen);\n\tfor (i = 0; i < ctx->nold; i++)\n\t\tsshkey_free(ctx->old_keys[i]);\n\tfree(ctx->old_keys);\n\tfree(ctx->host_str);\n\tfree(ctx->ip_str);\n\tfree(ctx);\n}\n\nstatic int\nhostkeys_find(struct hostkey_foreach_line *l, void *_ctx)\n{\n\tstruct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;\n\tsize_t i;\n\tstruct sshkey **tmp;\n\n\tif (l->status != HKF_STATUS_MATCHED || l->key == NULL ||\n\t l->key->type == KEY_RSA1)\n\t\treturn 0;\n\n\t/* Mark off keys we've already seen for this host */\n\tfor (i = 0; i < ctx->nkeys; i++) {\n\t\tif (sshkey_equal(l->key, ctx->keys[i])) {\n\t\t\tdebug3(\"%s: found %s key at %s:%ld\", __func__,\n\t\t\t sshkey_ssh_name(ctx->keys[i]), l->path, l->linenum);\n\t\t\tctx->keys_seen[i] = 1;\n\t\t\treturn 0;\n\t\t}\n\t}\n\t/* This line contained a key that not offered by the server */\n\tdebug3(\"%s: deprecated %s key at %s:%ld\", __func__,\n\t sshkey_ssh_name(l->key), l->path, l->linenum);\n\tif ((tmp = reallocarray(ctx->old_keys, ctx->nold + 1,\n\t sizeof(*ctx->old_keys))) == NULL)\n\t\tfatal(\"%s: reallocarray failed nold = %zu\",\n\t\t __func__, ctx->nold);\n\tctx->old_keys = tmp;\n\tctx->old_keys[ctx->nold++] = l->key;\n\tl->key = NULL;\n\n\treturn 0;\n}\n\nstatic void\nupdate_known_hosts(struct hostkeys_update_ctx *ctx)\n{\n\tint r, was_raw = 0;\n\tint loglevel = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK ?\n\t SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE;\n\tchar *fp, *response;\n\tsize_t i;\n\n\tfor (i = 0; i < ctx->nkeys; i++) {\n\t\tif (ctx->keys_seen[i] != 2)\n\t\t\tcontinue;\n\t\tif ((fp = sshkey_fingerprint(ctx->keys[i],\n\t\t options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)\n\t\t\tfatal(\"%s: sshkey_fingerprint failed\", __func__);\n\t\tdo_log2(loglevel, \"Learned new hostkey: %s %s\",\n\t\t sshkey_type(ctx->keys[i]), fp);\n\t\tfree(fp);\n\t}\n\tfor (i = 0; i < ctx->nold; i++) {\n\t\tif ((fp = sshkey_fingerprint(ctx->old_keys[i],\n\t\t options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)\n\t\t\tfatal(\"%s: sshkey_fingerprint failed\", __func__);\n\t\tdo_log2(loglevel, \"Deprecating obsolete hostkey: %s %s\",\n\t\t sshkey_type(ctx->old_keys[i]), fp);\n\t\tfree(fp);\n\t}\n\tif (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {\n\t\tif (get_saved_tio() != NULL) {\n\t\t\tleave_raw_mode(1);\n\t\t\twas_raw = 1;\n\t\t}\n\t\tresponse = NULL;\n\t\tfor (i = 0; !quit_pending && i < 3; i++) {\n\t\t\tfree(response);\n\t\t\tresponse = read_passphrase(\"Accept updated hostkeys? \"\n\t\t\t \"(yes/no): \", RP_ECHO);\n\t\t\tif (strcasecmp(response, \"yes\") == 0)\n\t\t\t\tbreak;\n\t\t\telse if (quit_pending || response == NULL ||\n\t\t\t strcasecmp(response, \"no\") == 0) {\n\t\t\t\toptions.update_hostkeys = 0;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tdo_log2(loglevel, \"Please enter \"\n\t\t\t\t \"\\\"yes\\\" or \\\"no\\\"\");\n\t\t\t}\n\t\t}\n\t\tif (quit_pending || i >= 3 || response == NULL)\n\t\t\toptions.update_hostkeys = 0;\n\t\tfree(response);\n\t\tif (was_raw)\n\t\t\tenter_raw_mode(1);\n\t}\n\n\t/*\n\t * Now that all the keys are verified, we can go ahead and replace\n\t * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't\n\t * cancel the operation).\n\t */\n\tif (options.update_hostkeys != 0 &&\n\t (r = hostfile_replace_entries(options.user_hostfiles[0],\n\t ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys,\n\t options.hash_known_hosts, 0,\n\t options.fingerprint_hash)) != 0)\n\t\terror(\"%s: hostfile_replace_entries failed: %s\",\n\t\t __func__, ssh_err(r));\n}\n\nstatic void\nclient_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx)\n{\n\tstruct ssh *ssh = active_state; /* XXX */\n\tstruct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;\n\tsize_t i, ndone;\n\tstruct sshbuf *signdata;\n\tint r;\n\tconst u_char *sig;\n\tsize_t siglen;\n\n\tif (ctx->nnew == 0)\n\t\tfatal(\"%s: ctx->nnew == 0\", __func__); /* sanity */\n\tif (type != SSH2_MSG_REQUEST_SUCCESS) {\n\t\terror(\"Server failed to confirm ownership of \"\n\t\t \"private host keys\");\n\t\thostkeys_update_ctx_free(ctx);\n\t\treturn;\n\t}\n\tif ((signdata = sshbuf_new()) == NULL)\n\t\tfatal(\"%s: sshbuf_new failed\", __func__);\n\t/* Don't want to accidentally accept an unbound signature */\n\tif (ssh->kex->session_id_len == 0)\n\t\tfatal(\"%s: ssh->kex->session_id_len == 0\", __func__);\n\t/*\n\t * Expect a signature for each of the ctx->nnew private keys we\n\t * haven't seen before. They will be in the same order as the\n\t * ctx->keys where the corresponding ctx->keys_seen[i] == 0.\n\t */\n\tfor (ndone = i = 0; i < ctx->nkeys; i++) {\n\t\tif (ctx->keys_seen[i])\n\t\t\tcontinue;\n\t\t/* Prepare data to be signed: session ID, unique string, key */\n\t\tsshbuf_reset(signdata);\n\t\tif ( (r = sshbuf_put_cstring(signdata,\n\t\t \"hostkeys-prove-00@openssh.com\")) != 0 ||\n\t\t (r = sshbuf_put_string(signdata, ssh->kex->session_id,\n\t\t ssh->kex->session_id_len)) != 0 ||\n\t\t (r = sshkey_puts(ctx->keys[i], signdata)) != 0)\n\t\t\tfatal(\"%s: failed to prepare signature: %s\",\n\t\t\t __func__, ssh_err(r));\n\t\t/* Extract and verify signature */\n\t\tif ((r = sshpkt_get_string_direct(ssh, &sig, &siglen)) != 0) {\n\t\t\terror(\"%s: couldn't parse message: %s\",\n\t\t\t __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshkey_verify(ctx->keys[i], sig, siglen,\n\t\t sshbuf_ptr(signdata), sshbuf_len(signdata), 0)) != 0) {\n\t\t\terror(\"%s: server gave bad signature for %s key %zu\",\n\t\t\t __func__, sshkey_type(ctx->keys[i]), i);\n\t\t\tgoto out;\n\t\t}\n\t\t/* Key is good. Mark it as 'seen' */\n\t\tctx->keys_seen[i] = 2;\n\t\tndone++;\n\t}\n\tif (ndone != ctx->nnew)\n\t\tfatal(\"%s: ndone != ctx->nnew (%zu / %zu)\", __func__,\n\t\t ndone, ctx->nnew); /* Shouldn't happen */\n\tssh_packet_check_eom(ssh);\n\n\t/* Make the edits to known_hosts */\n\tupdate_known_hosts(ctx);\n out:\n\thostkeys_update_ctx_free(ctx);\n}\n\n/*\n * Returns non-zero if the key is accepted by HostkeyAlgorithms.\n * Made slightly less trivial by the multiple RSA signature algorithm names.\n */\nstatic int\nkey_accepted_by_hostkeyalgs(const struct sshkey *key)\n{\n\tconst char *ktype = sshkey_ssh_name(key);\n\tconst char *hostkeyalgs = options.hostkeyalgorithms != NULL ?\n\t options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG;\n\n\tif (key == NULL || key->type == KEY_UNSPEC)\n\t\treturn 0;\n\tif (key->type == KEY_RSA &&\n\t (match_pattern_list(\"rsa-sha2-256\", hostkeyalgs, 0) == 1 ||\n\t match_pattern_list(\"rsa-sha2-512\", hostkeyalgs, 0) == 1))\n\t\treturn 1;\n\treturn match_pattern_list(ktype, hostkeyalgs, 0) == 1;\n}\n\n/*\n * Handle hostkeys-00@openssh.com global request to inform the client of all\n * the server's hostkeys. The keys are checked against the user's\n * HostkeyAlgorithms preference before they are accepted.\n */\nstatic int\nclient_input_hostkeys(void)\n{\n\tstruct ssh *ssh = active_state; /* XXX */\n\tconst u_char *blob = NULL;\n\tsize_t i, len = 0;\n\tstruct sshbuf *buf = NULL;\n\tstruct sshkey *key = NULL, **tmp;\n\tint r;\n\tchar *fp;\n\tstatic int hostkeys_seen = 0; /* XXX use struct ssh */\n\textern struct sockaddr_storage hostaddr; /* XXX from ssh.c */\n\tstruct hostkeys_update_ctx *ctx = NULL;\n\n\tif (hostkeys_seen)\n\t\tfatal(\"%s: server already sent hostkeys\", __func__);\n\tif (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK &&\n\t options.batch_mode)\n\t\treturn 1; /* won't ask in batchmode, so don't even try */\n\tif (!options.update_hostkeys || options.num_user_hostfiles <= 0)\n\t\treturn 1;\n\n\tctx = xcalloc(1, sizeof(*ctx));\n\twhile (ssh_packet_remaining(ssh) > 0) {\n\t\tsshkey_free(key);\n\t\tkey = NULL;\n\t\tif ((r = sshpkt_get_string_direct(ssh, &blob, &len)) != 0) {\n\t\t\terror(\"%s: couldn't parse message: %s\",\n\t\t\t __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshkey_from_blob(blob, len, &key)) != 0) {\n\t\t\terror(\"%s: parse key: %s\", __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t\tfp = sshkey_fingerprint(key, options.fingerprint_hash,\n\t\t SSH_FP_DEFAULT);\n\t\tdebug3(\"%s: received %s key %s\", __func__,\n\t\t sshkey_type(key), fp);\n\t\tfree(fp);\n\n\t\tif (!key_accepted_by_hostkeyalgs(key)) {\n\t\t\tdebug3(\"%s: %s key not permitted by HostkeyAlgorithms\",\n\t\t\t __func__, sshkey_ssh_name(key));\n\t\t\tcontinue;\n\t\t}\n\t\t/* Skip certs */\n\t\tif (sshkey_is_cert(key)) {\n\t\t\tdebug3(\"%s: %s key is a certificate; skipping\",\n\t\t\t __func__, sshkey_ssh_name(key));\n\t\t\tcontinue;\n\t\t}\n\t\t/* Ensure keys are unique */\n\t\tfor (i = 0; i < ctx->nkeys; i++) {\n\t\t\tif (sshkey_equal(key, ctx->keys[i])) {\n\t\t\t\terror(\"%s: received duplicated %s host key\",\n\t\t\t\t __func__, sshkey_ssh_name(key));\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\t/* Key is good, record it */\n\t\tif ((tmp = reallocarray(ctx->keys, ctx->nkeys + 1,\n\t\t sizeof(*ctx->keys))) == NULL)\n\t\t\tfatal(\"%s: reallocarray failed nkeys = %zu\",\n\t\t\t __func__, ctx->nkeys);\n\t\tctx->keys = tmp;\n\t\tctx->keys[ctx->nkeys++] = key;\n\t\tkey = NULL;\n\t}\n\n\tif (ctx->nkeys == 0) {\n\t\tdebug(\"%s: server sent no hostkeys\", __func__);\n\t\tgoto out;\n\t}\n\n\tif ((ctx->keys_seen = calloc(ctx->nkeys,\n\t sizeof(*ctx->keys_seen))) == NULL)\n\t\tfatal(\"%s: calloc failed\", __func__);\n\n\tget_hostfile_hostname_ipaddr(host,\n\t options.check_host_ip ? (struct sockaddr *)&hostaddr : NULL,\n\t options.port, &ctx->host_str,\n\t options.check_host_ip ? &ctx->ip_str : NULL);\n\n\t/* Find which keys we already know about. */\n\tif ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find,\n\t ctx, ctx->host_str, ctx->ip_str,\n\t HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) {\n\t\terror(\"%s: hostkeys_foreach failed: %s\", __func__, ssh_err(r));\n\t\tgoto out;\n\t}\n\n\t/* Figure out if we have any new keys to add */\n\tctx->nnew = 0;\n\tfor (i = 0; i < ctx->nkeys; i++) {\n\t\tif (!ctx->keys_seen[i])\n\t\t\tctx->nnew++;\n\t}\n\n\tdebug3(\"%s: %zu keys from server: %zu new, %zu retained. %zu to remove\",\n\t __func__, ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold);\n\n\tif (ctx->nnew == 0 && ctx->nold != 0) {\n\t\t/* We have some keys to remove. Just do it. */\n\t\tupdate_known_hosts(ctx);\n\t} else if (ctx->nnew != 0) {\n\t\t/*\n\t\t * We have received hitherto-unseen keys from the server.\n\t\t * Ask the server to confirm ownership of the private halves.\n\t\t */\n\t\tdebug3(\"%s: asking server to prove ownership for %zu keys\",\n\t\t __func__, ctx->nnew);\n\t\tif ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||\n\t\t (r = sshpkt_put_cstring(ssh,\n\t\t \"hostkeys-prove-00@openssh.com\")) != 0 ||\n\t\t (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */\n\t\t\tfatal(\"%s: cannot prepare packet: %s\",\n\t\t\t __func__, ssh_err(r));\n\t\tif ((buf = sshbuf_new()) == NULL)\n\t\t\tfatal(\"%s: sshbuf_new\", __func__);\n\t\tfor (i = 0; i < ctx->nkeys; i++) {\n\t\t\tif (ctx->keys_seen[i])\n\t\t\t\tcontinue;\n\t\t\tsshbuf_reset(buf);\n\t\t\tif ((r = sshkey_putb(ctx->keys[i], buf)) != 0)\n\t\t\t\tfatal(\"%s: sshkey_putb: %s\",\n\t\t\t\t __func__, ssh_err(r));\n\t\t\tif ((r = sshpkt_put_stringb(ssh, buf)) != 0)\n\t\t\t\tfatal(\"%s: sshpkt_put_string: %s\",\n\t\t\t\t __func__, ssh_err(r));\n\t\t}\n\t\tif ((r = sshpkt_send(ssh)) != 0)\n\t\t\tfatal(\"%s: sshpkt_send: %s\", __func__, ssh_err(r));\n\t\tclient_register_global_confirm(\n\t\t client_global_hostkeys_private_confirm, ctx);\n\t\tctx = NULL; /* will be freed in callback */\n\t}\n\n\t/* Success */\n out:\n\thostkeys_update_ctx_free(ctx);\n\tsshkey_free(key);\n\tsshbuf_free(buf);\n\t/*\n\t * NB. Return success for all cases. The server doesn't need to know\n\t * what the client does with its hosts file.\n\t */\n\treturn 1;\n}\n\nstatic int\nclient_input_global_request(int type, u_int32_t seq, void *ctxt)\n{\n\tchar *rtype;\n\tint want_reply;\n\tint success = 0;\n\n\trtype = packet_get_cstring(NULL);\n\twant_reply = packet_get_char();\n\tdebug(\"client_input_global_request: rtype %s want_reply %d\",\n\t rtype, want_reply);\n\tif (strcmp(rtype, \"hostkeys-00@openssh.com\") == 0)\n\t\tsuccess = client_input_hostkeys();\n\tif (want_reply) {\n\t\tpacket_start(success ?\n\t\t SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\t}\n\tfree(rtype);\n\treturn 0;\n}\n\nvoid\nclient_session2_setup(int id, int want_tty, int want_subsystem,\n const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)\n{\n\tint len;\n\tChannel *c = NULL;\n\n\tdebug2(\"%s: id %d\", __func__, id);\n\n\tif ((c = channel_lookup(id)) == NULL)\n\t\tfatal(\"client_session2_setup: channel %d: unknown channel\", id);\n\n\tpacket_set_interactive(want_tty,\n\t options.ip_qos_interactive, options.ip_qos_bulk);\n\n\tif (want_tty) {\n\t\tstruct winsize ws;\n\n\t\t/* Store window size in the packet. */\n\t\tif (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)\n\t\t\tmemset(&ws, 0, sizeof(ws));\n\n\t\tchannel_request_start(id, \"pty-req\", 1);\n\t\tclient_expect_confirm(id, \"PTY allocation\", CONFIRM_TTY);\n\t\tpacket_put_cstring(term != NULL ? term : \"\");\n\t\tpacket_put_int((u_int)ws.ws_col);\n\t\tpacket_put_int((u_int)ws.ws_row);\n\t\tpacket_put_int((u_int)ws.ws_xpixel);\n\t\tpacket_put_int((u_int)ws.ws_ypixel);\n\t\tif (tiop == NULL)\n\t\t\ttiop = get_saved_tio();\n\t\ttty_make_modes(-1, tiop);\n\t\tpacket_send();\n\t\t/* XXX wait for reply */\n\t\tc->client_tty = 1;\n\t}\n\n\t/* Transfer any environment variables from client to server */\n\tif (options.num_send_env != 0 && env != NULL) {\n\t\tint i, j, matched;\n\t\tchar *name, *val;\n\n\t\tdebug(\"Sending environment.\");\n\t\tfor (i = 0; env[i] != NULL; i++) {\n\t\t\t/* Split */\n\t\t\tname = xstrdup(env[i]);\n\t\t\tif ((val = strchr(name, '=')) == NULL) {\n\t\t\t\tfree(name);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t*val++ = '\\0';\n\n\t\t\tmatched = 0;\n\t\t\tfor (j = 0; j < options.num_send_env; j++) {\n\t\t\t\tif (match_pattern(name, options.send_env[j])) {\n\t\t\t\t\tmatched = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!matched) {\n\t\t\t\tdebug3(\"Ignored env %s\", name);\n\t\t\t\tfree(name);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tdebug(\"Sending env %s = %s\", name, val);\n\t\t\tchannel_request_start(id, \"env\", 0);\n\t\t\tpacket_put_cstring(name);\n\t\t\tpacket_put_cstring(val);\n\t\t\tpacket_send();\n\t\t\tfree(name);\n\t\t}\n\t}\n\n\tlen = buffer_len(cmd);\n\tif (len > 0) {\n\t\tif (len > 900)\n\t\t\tlen = 900;\n\t\tif (want_subsystem) {\n\t\t\tdebug(\"Sending subsystem: %.*s\",\n\t\t\t len, (u_char*)buffer_ptr(cmd));\n\t\t\tchannel_request_start(id, \"subsystem\", 1);\n\t\t\tclient_expect_confirm(id, \"subsystem\", CONFIRM_CLOSE);\n\t\t} else {\n\t\t\tdebug(\"Sending command: %.*s\",\n\t\t\t len, (u_char*)buffer_ptr(cmd));\n\t\t\tchannel_request_start(id, \"exec\", 1);\n\t\t\tclient_expect_confirm(id, \"exec\", CONFIRM_CLOSE);\n\t\t}\n\t\tpacket_put_string(buffer_ptr(cmd), buffer_len(cmd));\n\t\tpacket_send();\n\t} else {\n\t\tchannel_request_start(id, \"shell\", 1);\n\t\tclient_expect_confirm(id, \"shell\", CONFIRM_CLOSE);\n\t\tpacket_send();\n\t}\n}\n\nstatic void\nclient_init_dispatch_20(void)\n{\n\tdispatch_init(&dispatch_protocol_error);\n\n\tdispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);\n\tdispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);\n\tdispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);\n\tdispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);\n\tdispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);\n\tdispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);\n\tdispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);\n\tdispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);\n\tdispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);\n\tdispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);\n\tdispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);\n\tdispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);\n\n\t/* rekeying */\n\tdispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);\n\n\t/* global request reply messages */\n\tdispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);\n\tdispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);\n}\n\nstatic void\nclient_init_dispatch_13(void)\n{\n\tdispatch_init(NULL);\n\tdispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);\n\tdispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);\n\tdispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);\n\tdispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);\n\tdispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);\n\tdispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);\n\tdispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);\n\tdispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);\n\tdispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);\n\n\tdispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?\n\t &client_input_agent_open : &deny_input_open);\n\tdispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?\n\t &x11_input_open : &deny_input_open);\n}\n\nstatic void\nclient_init_dispatch_15(void)\n{\n\tclient_init_dispatch_13();\n\tdispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);\n\tdispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);\n}\n\nstatic void\nclient_init_dispatch(void)\n{\n\tif (compat20)\n\t\tclient_init_dispatch_20();\n\telse if (compat13)\n\t\tclient_init_dispatch_13();\n\telse\n\t\tclient_init_dispatch_15();\n}\n\nvoid\nclient_stop_mux(void)\n{\n\tif (options.control_path != NULL && muxserver_sock != -1)\n\t\tunlink(options.control_path);\n\t/*\n\t * If we are in persist mode, or don't have a shell, signal that we\n\t * should close when all active channels are closed.\n\t */\n\tif (options.control_persist || no_shell_flag) {\n\t\tsession_closed = 1;\n\t\tsetproctitle(\"[stopped mux]\");\n\t}\n}\n\n/* client specific fatal cleanup */\nvoid\ncleanup_exit(int i)\n{\n\tleave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\tleave_non_blocking();\n\tif (options.control_path != NULL && muxserver_sock != -1)\n\t\tunlink(options.control_path);\n\tssh_kill_proxy_command();\n\t_exit(i);\n}\n","/* $OpenBSD: sshtty.c,v 1.14 2010/01/09 05:04:24 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n/*\n * Copyright (c) 2001 Markus Friedl. All rights reserved.\n * Copyright (c) 2001 Kevin Steves. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n\n#include \"sshpty.h\"\n\nstatic struct termios _saved_tio;\nstatic int _in_raw_mode = 0;\n\nstruct termios *\nget_saved_tio(void)\n{\n\treturn _in_raw_mode ? &_saved_tio : NULL;\n}\n\nvoid\nleave_raw_mode(int quiet)\n{\n\tif (!_in_raw_mode)\n\t\treturn;\n\tif (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) {\n\t\tif (!quiet)\n\t\t\tperror(\"tcsetattr\");\n\t} else\n\t\t_in_raw_mode = 0;\n}\n\nvoid\nenter_raw_mode(int quiet)\n{\n\tstruct termios tio;\n\n\tif (tcgetattr(fileno(stdin), &tio) == -1) {\n\t\tif (!quiet)\n\t\t\tperror(\"tcgetattr\");\n\t\treturn;\n\t}\n\t_saved_tio = tio;\n\ttio.c_iflag |= IGNPAR;\n\ttio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);\n#ifdef IUCLC\n\ttio.c_iflag &= ~IUCLC;\n#endif\n\ttio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);\n#ifdef IEXTEN\n\ttio.c_lflag &= ~IEXTEN;\n#endif\n\ttio.c_oflag &= ~OPOST;\n\ttio.c_cc[VMIN] = 1;\n\ttio.c_cc[VTIME] = 0;\n\tif (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) {\n\t\tif (!quiet)\n\t\t\tperror(\"tcsetattr\");\n\t} else\n\t\t_in_raw_mode = 1;\n}\n","/* $OpenBSD: sshconnect.c,v 1.273 2017/03/10 03:22:40 dtucker Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Code to connect to a remote host, and to perform the client side of the\n * login (authentication) dialog.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#ifdef HAVE_SYS_TIME_H\n# include \n#endif\n\n#include \n#include \n\n#include \n#include \n#include \n#include \n#ifdef HAVE_PATHS_H\n#include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"key.h\"\n#include \"hostfile.h\"\n#include \"ssh.h\"\n#include \"rsa.h\"\n#include \"buffer.h\"\n#include \"packet.h\"\n#include \"uidswap.h\"\n#include \"compat.h\"\n#include \"key.h\"\n#include \"sshconnect.h\"\n#include \"hostfile.h\"\n#include \"log.h\"\n#include \"misc.h\"\n#include \"readconf.h\"\n#include \"atomicio.h\"\n#include \"dns.h\"\n#include \"monitor_fdpass.h\"\n#include \"ssh2.h\"\n#include \"version.h\"\n#include \"authfile.h\"\n#include \"ssherr.h\"\n#include \"authfd.h\"\n\nchar *client_version_string = NULL;\nchar *server_version_string = NULL;\nKey *previous_host_key = NULL;\n\nstatic int matching_host_key_dns = 0;\n\nstatic pid_t proxy_command_pid = 0;\n\n/* import */\nextern Options options;\nextern char *__progname;\nextern uid_t original_real_uid;\nextern uid_t original_effective_uid;\n\nstatic int show_other_keys(struct hostkeys *, Key *);\nstatic void warn_changed_key(Key *);\n\n/* Expand a proxy command */\nstatic char *\nexpand_proxy_command(const char *proxy_command, const char *user,\n const char *host, int port)\n{\n\tchar *tmp, *ret, strport[NI_MAXSERV];\n\n\tsnprintf(strport, sizeof strport, \"%d\", port);\n\txasprintf(&tmp, \"exec %s\", proxy_command);\n\tret = percent_expand(tmp, \"h\", host, \"p\", strport,\n\t \"r\", options.user, (char *)NULL);\n\tfree(tmp);\n\treturn ret;\n}\n\n/*\n * Connect to the given ssh server using a proxy command that passes a\n * a connected fd back to us.\n */\nstatic int\nssh_proxy_fdpass_connect(const char *host, u_short port,\n const char *proxy_command)\n{\n\tchar *command_string;\n\tint sp[2], sock;\n\tpid_t pid;\n\tchar *shell;\n\n\tif ((shell = getenv(\"SHELL\")) == NULL)\n\t\tshell = _PATH_BSHELL;\n\n\tif (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0)\n\t\tfatal(\"Could not create socketpair to communicate with \"\n\t\t \"proxy dialer: %.100s\", strerror(errno));\n\n\tcommand_string = expand_proxy_command(proxy_command, options.user,\n\t host, port);\n\tdebug(\"Executing proxy dialer command: %.500s\", command_string);\n\n\t/* Fork and execute the proxy command. */\n\tif ((pid = fork()) == 0) {\n\t\tchar *argv[10];\n\n\t\t/* Child. Permanently give up superuser privileges. */\n\t\tpermanently_drop_suid(original_real_uid);\n\n\t\tclose(sp[1]);\n\t\t/* Redirect stdin and stdout. */\n\t\tif (sp[0] != 0) {\n\t\t\tif (dup2(sp[0], 0) < 0)\n\t\t\t\tperror(\"dup2 stdin\");\n\t\t}\n\t\tif (sp[0] != 1) {\n\t\t\tif (dup2(sp[0], 1) < 0)\n\t\t\t\tperror(\"dup2 stdout\");\n\t\t}\n\t\tif (sp[0] >= 2)\n\t\t\tclose(sp[0]);\n\n\t\t/*\n\t\t * Stderr is left as it is so that error messages get\n\t\t * printed on the user's terminal.\n\t\t */\n\t\targv[0] = shell;\n\t\targv[1] = \"-c\";\n\t\targv[2] = command_string;\n\t\targv[3] = NULL;\n\n\t\t/*\n\t\t * Execute the proxy command.\n\t\t * Note that we gave up any extra privileges above.\n\t\t */\n\t\texecv(argv[0], argv);\n\t\tperror(argv[0]);\n\t\texit(1);\n\t}\n\t/* Parent. */\n\tif (pid < 0)\n\t\tfatal(\"fork failed: %.100s\", strerror(errno));\n\tclose(sp[0]);\n\tfree(command_string);\n\n\tif ((sock = mm_receive_fd(sp[1])) == -1)\n\t\tfatal(\"proxy dialer did not pass back a connection\");\n\tclose(sp[1]);\n\n\twhile (waitpid(pid, NULL, 0) == -1)\n\t\tif (errno != EINTR)\n\t\t\tfatal(\"Couldn't wait for child: %s\", strerror(errno));\n\n\t/* Set the connection file descriptors. */\n\tpacket_set_connection(sock, sock);\n\n\treturn 0;\n}\n\n/*\n * Connect to the given ssh server using a proxy command.\n */\nstatic int\nssh_proxy_connect(const char *host, u_short port, const char *proxy_command)\n{\n\tchar *command_string;\n\tint pin[2], pout[2];\n\tpid_t pid;\n\tchar *shell;\n\n\tif ((shell = getenv(\"SHELL\")) == NULL || *shell == '\\0')\n\t\tshell = _PATH_BSHELL;\n\n\t/* Create pipes for communicating with the proxy. */\n\tif (pipe(pin) < 0 || pipe(pout) < 0)\n\t\tfatal(\"Could not create pipes to communicate with the proxy: %.100s\",\n\t\t strerror(errno));\n\n\tcommand_string = expand_proxy_command(proxy_command, options.user,\n\t host, port);\n\tdebug(\"Executing proxy command: %.500s\", command_string);\n\n\t/* Fork and execute the proxy command. */\n\tif ((pid = fork()) == 0) {\n\t\tchar *argv[10];\n\n\t\t/* Child. Permanently give up superuser privileges. */\n\t\tpermanently_drop_suid(original_real_uid);\n\n\t\t/* Redirect stdin and stdout. */\n\t\tclose(pin[1]);\n\t\tif (pin[0] != 0) {\n\t\t\tif (dup2(pin[0], 0) < 0)\n\t\t\t\tperror(\"dup2 stdin\");\n\t\t\tclose(pin[0]);\n\t\t}\n\t\tclose(pout[0]);\n\t\tif (dup2(pout[1], 1) < 0)\n\t\t\tperror(\"dup2 stdout\");\n\t\t/* Cannot be 1 because pin allocated two descriptors. */\n\t\tclose(pout[1]);\n\n\t\t/* Stderr is left as it is so that error messages get\n\t\t printed on the user's terminal. */\n\t\targv[0] = shell;\n\t\targv[1] = \"-c\";\n\t\targv[2] = command_string;\n\t\targv[3] = NULL;\n\n\t\t/* Execute the proxy command. Note that we gave up any\n\t\t extra privileges above. */\n\t\tsignal(SIGPIPE, SIG_DFL);\n\t\texecv(argv[0], argv);\n\t\tperror(argv[0]);\n\t\texit(1);\n\t}\n\t/* Parent. */\n\tif (pid < 0)\n\t\tfatal(\"fork failed: %.100s\", strerror(errno));\n\telse\n\t\tproxy_command_pid = pid; /* save pid to clean up later */\n\n\t/* Close child side of the descriptors. */\n\tclose(pin[0]);\n\tclose(pout[1]);\n\n\t/* Free the command name. */\n\tfree(command_string);\n\n\t/* Set the connection file descriptors. */\n\tpacket_set_connection(pout[0], pin[1]);\n\n\t/* Indicate OK return */\n\treturn 0;\n}\n\nvoid\nssh_kill_proxy_command(void)\n{\n\t/*\n\t * Send SIGHUP to proxy command if used. We don't wait() in\n\t * case it hangs and instead rely on init to reap the child\n\t */\n\tif (proxy_command_pid > 1)\n\t\tkill(proxy_command_pid, SIGHUP);\n}\n\n/*\n * Creates a (possibly privileged) socket for use as the ssh connection.\n */\nstatic int\nssh_create_socket(int privileged, struct addrinfo *ai)\n{\n\tint sock, r, gaierr;\n\tstruct addrinfo hints, *res = NULL;\n\n\tsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);\n\tif (sock < 0) {\n\t\terror(\"socket: %s\", strerror(errno));\n\t\treturn -1;\n\t}\n\tfcntl(sock, F_SETFD, FD_CLOEXEC);\n\n\t/* Bind the socket to an alternative local IP address */\n\tif (options.bind_address == NULL && !privileged)\n\t\treturn sock;\n\n\tif (options.bind_address) {\n\t\tmemset(&hints, 0, sizeof(hints));\n\t\thints.ai_family = ai->ai_family;\n\t\thints.ai_socktype = ai->ai_socktype;\n\t\thints.ai_protocol = ai->ai_protocol;\n\t\thints.ai_flags = AI_PASSIVE;\n\t\tgaierr = getaddrinfo(options.bind_address, NULL, &hints, &res);\n\t\tif (gaierr) {\n\t\t\terror(\"getaddrinfo: %s: %s\", options.bind_address,\n\t\t\t ssh_gai_strerror(gaierr));\n\t\t\tclose(sock);\n\t\t\treturn -1;\n\t\t}\n\t}\n\t/*\n\t * If we are running as root and want to connect to a privileged\n\t * port, bind our own socket to a privileged port.\n\t */\n\tif (privileged) {\n\t\tPRIV_START;\n\t\tr = bindresvport_sa(sock, res ? res->ai_addr : NULL);\n\t\tPRIV_END;\n\t\tif (r < 0) {\n\t\t\terror(\"bindresvport_sa: af=%d %s\", ai->ai_family,\n\t\t\t strerror(errno));\n\t\t\tgoto fail;\n\t\t}\n\t} else {\n\t\tif (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {\n\t\t\terror(\"bind: %s: %s\", options.bind_address,\n\t\t\t strerror(errno));\n fail:\n\t\t\tclose(sock);\n\t\t\tfreeaddrinfo(res);\n\t\t\treturn -1;\n\t\t}\n\t}\n\tif (res != NULL)\n\t\tfreeaddrinfo(res);\n\treturn sock;\n}\n\nstatic int\ntimeout_connect(int sockfd, const struct sockaddr *serv_addr,\n socklen_t addrlen, int *timeoutp)\n{\n\tfd_set *fdset;\n\tstruct timeval tv, t_start;\n\tsocklen_t optlen;\n\tint optval, rc, result = -1;\n\n\tgettimeofday(&t_start, NULL);\n\n\tif (*timeoutp <= 0) {\n\t\tresult = connect(sockfd, serv_addr, addrlen);\n\t\tgoto done;\n\t}\n\n\tset_nonblock(sockfd);\n\trc = connect(sockfd, serv_addr, addrlen);\n\tif (rc == 0) {\n\t\tunset_nonblock(sockfd);\n\t\tresult = 0;\n\t\tgoto done;\n\t}\n\tif (errno != EINPROGRESS) {\n\t\tresult = -1;\n\t\tgoto done;\n\t}\n\n\tfdset = xcalloc(howmany(sockfd + 1, NFDBITS),\n\t sizeof(fd_mask));\n\tFD_SET(sockfd, fdset);\n\tms_to_timeval(&tv, *timeoutp);\n\n\tfor (;;) {\n\t\trc = select(sockfd + 1, NULL, fdset, NULL, &tv);\n\t\tif (rc != -1 || errno != EINTR)\n\t\t\tbreak;\n\t}\n\n\tswitch (rc) {\n\tcase 0:\n\t\t/* Timed out */\n\t\terrno = ETIMEDOUT;\n\t\tbreak;\n\tcase -1:\n\t\t/* Select error */\n\t\tdebug(\"select: %s\", strerror(errno));\n\t\tbreak;\n\tcase 1:\n\t\t/* Completed or failed */\n\t\toptval = 0;\n\t\toptlen = sizeof(optval);\n\t\tif (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,\n\t\t &optlen) == -1) {\n\t\t\tdebug(\"getsockopt: %s\", strerror(errno));\n\t\t\tbreak;\n\t\t}\n\t\tif (optval != 0) {\n\t\t\terrno = optval;\n\t\t\tbreak;\n\t\t}\n\t\tresult = 0;\n\t\tunset_nonblock(sockfd);\n\t\tbreak;\n\tdefault:\n\t\t/* Should not occur */\n\t\tfatal(\"Bogus return (%d) from select()\", rc);\n\t}\n\n\tfree(fdset);\n\n done:\n \tif (result == 0 && *timeoutp > 0) {\n\t\tms_subtract_diff(&t_start, timeoutp);\n\t\tif (*timeoutp <= 0) {\n\t\t\terrno = ETIMEDOUT;\n\t\t\tresult = -1;\n\t\t}\n\t}\n\n\treturn (result);\n}\n\n/*\n * Opens a TCP/IP connection to the remote server on the given host.\n * The address of the remote host will be returned in hostaddr.\n * If port is 0, the default port will be used. If needpriv is true,\n * a privileged port will be allocated to make the connection.\n * This requires super-user privileges if needpriv is true.\n * Connection_attempts specifies the maximum number of tries (one per\n * second). If proxy_command is non-NULL, it specifies the command (with %h\n * and %p substituted for host and port, respectively) to use to contact\n * the daemon.\n */\nstatic int\nssh_connect_direct(const char *host, struct addrinfo *aitop,\n struct sockaddr_storage *hostaddr, u_short port, int family,\n int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)\n{\n\tint on = 1;\n\tint sock = -1, attempt;\n\tchar ntop[NI_MAXHOST], strport[NI_MAXSERV];\n\tstruct addrinfo *ai;\n\n\tdebug2(\"%s: needpriv %d\", __func__, needpriv);\n\tmemset(ntop, 0, sizeof(ntop));\n\tmemset(strport, 0, sizeof(strport));\n\n\tfor (attempt = 0; attempt < connection_attempts; attempt++) {\n\t\tif (attempt > 0) {\n\t\t\t/* Sleep a moment before retrying. */\n\t\t\tsleep(1);\n\t\t\tdebug(\"Trying again...\");\n\t\t}\n\t\t/*\n\t\t * Loop through addresses for this host, and try each one in\n\t\t * sequence until the connection succeeds.\n\t\t */\n\t\tfor (ai = aitop; ai; ai = ai->ai_next) {\n\t\t\tif (ai->ai_family != AF_INET &&\n\t\t\t ai->ai_family != AF_INET6)\n\t\t\t\tcontinue;\n\t\t\tif (getnameinfo(ai->ai_addr, ai->ai_addrlen,\n\t\t\t ntop, sizeof(ntop), strport, sizeof(strport),\n\t\t\t NI_NUMERICHOST|NI_NUMERICSERV) != 0) {\n\t\t\t\terror(\"%s: getnameinfo failed\", __func__);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tdebug(\"Connecting to %.200s [%.100s] port %s.\",\n\t\t\t\thost, ntop, strport);\n\n\t\t\t/* Create a socket for connecting. */\n\t\t\tsock = ssh_create_socket(needpriv, ai);\n\t\t\tif (sock < 0)\n\t\t\t\t/* Any error is already output */\n\t\t\t\tcontinue;\n\n\t\t\tif (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,\n\t\t\t timeout_ms) >= 0) {\n\t\t\t\t/* Successful connection. */\n\t\t\t\tmemcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tdebug(\"connect to address %s port %s: %s\",\n\t\t\t\t ntop, strport, strerror(errno));\n\t\t\t\tclose(sock);\n\t\t\t\tsock = -1;\n\t\t\t}\n\t\t}\n\t\tif (sock != -1)\n\t\t\tbreak;\t/* Successful connection. */\n\t}\n\n\t/* Return failure if we didn't get a successful connection. */\n\tif (sock == -1) {\n\t\terror(\"ssh: connect to host %s port %s: %s\",\n\t\t host, strport, strerror(errno));\n\t\treturn (-1);\n\t}\n\n\tdebug(\"Connection established.\");\n\n\t/* Set SO_KEEPALIVE if requested. */\n\tif (want_keepalive &&\n\t setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,\n\t sizeof(on)) < 0)\n\t\terror(\"setsockopt SO_KEEPALIVE: %.100s\", strerror(errno));\n\n\t/* Set the connection. */\n\tpacket_set_connection(sock, sock);\n\n\treturn 0;\n}\n\nint\nssh_connect(const char *host, struct addrinfo *addrs,\n struct sockaddr_storage *hostaddr, u_short port, int family,\n int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)\n{\n\tif (options.proxy_command == NULL) {\n\t\treturn ssh_connect_direct(host, addrs, hostaddr, port, family,\n\t\t connection_attempts, timeout_ms, want_keepalive, needpriv);\n\t} else if (strcmp(options.proxy_command, \"-\") == 0) {\n\t\tpacket_set_connection(STDIN_FILENO, STDOUT_FILENO);\n\t\treturn 0; /* Always succeeds */\n\t} else if (options.proxy_use_fdpass) {\n\t\treturn ssh_proxy_fdpass_connect(host, port,\n\t\t options.proxy_command);\n\t}\n\treturn ssh_proxy_connect(host, port, options.proxy_command);\n}\n\nstatic void\nsend_client_banner(int connection_out, int minor1)\n{\n\t/* Send our own protocol version identification. */\n\tif (compat20) {\n\t\txasprintf(&client_version_string, \"SSH-%d.%d-%.100s\\r\\n\",\n\t\t PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);\n\t} else {\n\t\txasprintf(&client_version_string, \"SSH-%d.%d-%.100s\\n\",\n\t\t PROTOCOL_MAJOR_1, minor1, SSH_VERSION);\n\t}\n\tif (atomicio(vwrite, connection_out, client_version_string,\n\t strlen(client_version_string)) != strlen(client_version_string))\n\t\tfatal(\"write: %.100s\", strerror(errno));\n\tchop(client_version_string);\n\tdebug(\"Local version string %.100s\", client_version_string);\n}\n\n/*\n * Waits for the server identification string, and sends our own\n * identification string.\n */\nvoid\nssh_exchange_identification(int timeout_ms)\n{\n\tchar buf[256], remote_version[256];\t/* must be same size! */\n\tint remote_major, remote_minor, mismatch;\n\tint connection_in = packet_get_connection_in();\n\tint connection_out = packet_get_connection_out();\n\tint minor1 = PROTOCOL_MINOR_1, client_banner_sent = 0;\n\tu_int i, n;\n\tsize_t len;\n\tint fdsetsz, remaining, rc;\n\tstruct timeval t_start, t_remaining;\n\tfd_set *fdset;\n\n\tfdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);\n\tfdset = xcalloc(1, fdsetsz);\n\n\t/*\n\t * If we are SSH2-only then we can send the banner immediately and\n\t * save a round-trip.\n\t */\n\tif (options.protocol == SSH_PROTO_2) {\n\t\tenable_compat20();\n\t\tsend_client_banner(connection_out, 0);\n\t\tclient_banner_sent = 1;\n\t}\n\n\t/* Read other side's version identification. */\n\tremaining = timeout_ms;\n\tfor (n = 0;;) {\n\t\tfor (i = 0; i < sizeof(buf) - 1; i++) {\n\t\t\tif (timeout_ms > 0) {\n\t\t\t\tgettimeofday(&t_start, NULL);\n\t\t\t\tms_to_timeval(&t_remaining, remaining);\n\t\t\t\tFD_SET(connection_in, fdset);\n\t\t\t\trc = select(connection_in + 1, fdset, NULL,\n\t\t\t\t fdset, &t_remaining);\n\t\t\t\tms_subtract_diff(&t_start, &remaining);\n\t\t\t\tif (rc == 0 || remaining <= 0)\n\t\t\t\t\tfatal(\"Connection timed out during \"\n\t\t\t\t\t \"banner exchange\");\n\t\t\t\tif (rc == -1) {\n\t\t\t\t\tif (errno == EINTR)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tfatal(\"ssh_exchange_identification: \"\n\t\t\t\t\t \"select: %s\", strerror(errno));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlen = atomicio(read, connection_in, &buf[i], 1);\n\n\t\t\tif (len != 1 && errno == EPIPE)\n\t\t\t\tfatal(\"ssh_exchange_identification: \"\n\t\t\t\t \"Connection closed by remote host\");\n\t\t\telse if (len != 1)\n\t\t\t\tfatal(\"ssh_exchange_identification: \"\n\t\t\t\t \"read: %.100s\", strerror(errno));\n\t\t\tif (buf[i] == '\\r') {\n\t\t\t\tbuf[i] = '\\n';\n\t\t\t\tbuf[i + 1] = 0;\n\t\t\t\tcontinue;\t\t/**XXX wait for \\n */\n\t\t\t}\n\t\t\tif (buf[i] == '\\n') {\n\t\t\t\tbuf[i + 1] = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (++n > 65536)\n\t\t\t\tfatal(\"ssh_exchange_identification: \"\n\t\t\t\t \"No banner received\");\n\t\t}\n\t\tbuf[sizeof(buf) - 1] = 0;\n\t\tif (strncmp(buf, \"SSH-\", 4) == 0)\n\t\t\tbreak;\n\t\tdebug(\"ssh_exchange_identification: %s\", buf);\n\t}\n\tserver_version_string = xstrdup(buf);\n\tfree(fdset);\n\n\t/*\n\t * Check that the versions match. In future this might accept\n\t * several versions and set appropriate flags to handle them.\n\t */\n\tif (sscanf(server_version_string, \"SSH-%d.%d-%[^\\n]\\n\",\n\t &remote_major, &remote_minor, remote_version) != 3)\n\t\tfatal(\"Bad remote protocol version identification: '%.100s'\", buf);\n\tdebug(\"Remote protocol version %d.%d, remote software version %.100s\",\n\t remote_major, remote_minor, remote_version);\n\n\tactive_state->compat = compat_datafellows(remote_version);\n\tmismatch = 0;\n\n\tswitch (remote_major) {\n\tcase 1:\n\t\tif (remote_minor == 99 &&\n\t\t (options.protocol & SSH_PROTO_2) &&\n\t\t !(options.protocol & SSH_PROTO_1_PREFERRED)) {\n\t\t\tenable_compat20();\n\t\t\tbreak;\n\t\t}\n\t\tif (!(options.protocol & SSH_PROTO_1)) {\n\t\t\tmismatch = 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (remote_minor < 3) {\n\t\t\tfatal(\"Remote machine has too old SSH software version.\");\n\t\t} else if (remote_minor == 3 || remote_minor == 4) {\n\t\t\t/* We speak 1.3, too. */\n\t\t\tenable_compat13();\n\t\t\tminor1 = 3;\n\t\t\tif (options.forward_agent) {\n\t\t\t\tlogit(\"Agent forwarding disabled for protocol 1.3\");\n\t\t\t\toptions.forward_agent = 0;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase 2:\n\t\tif (options.protocol & SSH_PROTO_2) {\n\t\t\tenable_compat20();\n\t\t\tbreak;\n\t\t}\n\t\t/* FALLTHROUGH */\n\tdefault:\n\t\tmismatch = 1;\n\t\tbreak;\n\t}\n\tif (mismatch)\n\t\tfatal(\"Protocol major versions differ: %d vs. %d\",\n\t\t (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,\n\t\t remote_major);\n\tif ((datafellows & SSH_BUG_DERIVEKEY) != 0)\n\t\tfatal(\"Server version \\\"%.100s\\\" uses unsafe key agreement; \"\n\t\t \"refusing connection\", remote_version);\n\tif ((datafellows & SSH_BUG_RSASIGMD5) != 0)\n\t\tlogit(\"Server version \\\"%.100s\\\" uses unsafe RSA signature \"\n\t\t \"scheme; disabling use of RSA keys\", remote_version);\n\tif (!client_banner_sent)\n\t\tsend_client_banner(connection_out, minor1);\n\tchop(server_version_string);\n}\n\n/* defaults to 'no' */\nstatic int\nconfirm(const char *prompt)\n{\n\tconst char *msg, *again = \"Please type 'yes' or 'no': \";\n\tchar *p;\n\tint ret = -1;\n\n\tif (options.batch_mode)\n\t\treturn 0;\n\tfor (msg = prompt;;msg = again) {\n\t\tp = read_passphrase(msg, RP_ECHO);\n\t\tif (p == NULL ||\n\t\t (p[0] == '\\0') || (p[0] == '\\n') ||\n\t\t strncasecmp(p, \"no\", 2) == 0)\n\t\t\tret = 0;\n\t\tif (p && strncasecmp(p, \"yes\", 3) == 0)\n\t\t\tret = 1;\n\t\tfree(p);\n\t\tif (ret != -1)\n\t\t\treturn ret;\n\t}\n}\n\nstatic int\ncheck_host_cert(const char *host, const Key *host_key)\n{\n\tconst char *reason;\n\n\tif (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) {\n\t\terror(\"%s\", reason);\n\t\treturn 0;\n\t}\n\tif (buffer_len(host_key->cert->critical) != 0) {\n\t\terror(\"Certificate for %s contains unsupported \"\n\t\t \"critical options(s)\", host);\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nstatic int\nsockaddr_is_local(struct sockaddr *hostaddr)\n{\n\tswitch (hostaddr->sa_family) {\n\tcase AF_INET:\n\t\treturn (ntohl(((struct sockaddr_in *)hostaddr)->\n\t\t sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;\n\tcase AF_INET6:\n\t\treturn IN6_IS_ADDR_LOOPBACK(\n\t\t &(((struct sockaddr_in6 *)hostaddr)->sin6_addr));\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\n/*\n * Prepare the hostname and ip address strings that are used to lookup\n * host keys in known_hosts files. These may have a port number appended.\n */\nvoid\nget_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,\n u_short port, char **hostfile_hostname, char **hostfile_ipaddr)\n{\n\tchar ntop[NI_MAXHOST];\n\tsocklen_t addrlen;\n\n\tswitch (hostaddr == NULL ? -1 : hostaddr->sa_family) {\n\tcase -1:\n\t\taddrlen = 0;\n\t\tbreak;\n\tcase AF_INET:\n\t\taddrlen = sizeof(struct sockaddr_in);\n\t\tbreak;\n\tcase AF_INET6:\n\t\taddrlen = sizeof(struct sockaddr_in6);\n\t\tbreak;\n\tdefault:\n\t\taddrlen = sizeof(struct sockaddr);\n\t\tbreak;\n\t}\n\n\t/*\n\t * We don't have the remote ip-address for connections\n\t * using a proxy command\n\t */\n\tif (hostfile_ipaddr != NULL) {\n\t\tif (options.proxy_command == NULL) {\n\t\t\tif (getnameinfo(hostaddr, addrlen,\n\t\t\t ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0)\n\t\t\tfatal(\"%s: getnameinfo failed\", __func__);\n\t\t\t*hostfile_ipaddr = put_host_port(ntop, port);\n\t\t} else {\n\t\t\t*hostfile_ipaddr = xstrdup(\"\");\n\t\t}\n\t}\n\n\t/*\n\t * Allow the user to record the key under a different name or\n\t * differentiate a non-standard port. This is useful for ssh\n\t * tunneling over forwarded connections or if you run multiple\n\t * sshd's on different ports on the same machine.\n\t */\n\tif (hostfile_hostname != NULL) {\n\t\tif (options.host_key_alias != NULL) {\n\t\t\t*hostfile_hostname = xstrdup(options.host_key_alias);\n\t\t\tdebug(\"using hostkeyalias: %s\", *hostfile_hostname);\n\t\t} else {\n\t\t\t*hostfile_hostname = put_host_port(hostname, port);\n\t\t}\n\t}\n}\n\n/*\n * check whether the supplied host key is valid, return -1 if the key\n * is not valid. user_hostfile[0] will not be updated if 'readonly' is true.\n */\n#define RDRW\t0\n#define RDONLY\t1\n#define ROQUIET\t2\nstatic int\ncheck_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,\n Key *host_key, int readonly,\n char **user_hostfiles, u_int num_user_hostfiles,\n char **system_hostfiles, u_int num_system_hostfiles)\n{\n\tHostStatus host_status;\n\tHostStatus ip_status;\n\tKey *raw_key = NULL;\n\tchar *ip = NULL, *host = NULL;\n\tchar hostline[1000], *hostp, *fp, *ra;\n\tchar msg[1024];\n\tconst char *type;\n\tconst struct hostkey_entry *host_found, *ip_found;\n\tint len, cancelled_forwarding = 0;\n\tint local = sockaddr_is_local(hostaddr);\n\tint r, want_cert = key_is_cert(host_key), host_ip_differ = 0;\n\tint hostkey_trusted = 0; /* Known or explicitly accepted by user */\n\tstruct hostkeys *host_hostkeys, *ip_hostkeys;\n\tu_int i;\n\n\t/*\n\t * Force accepting of the host key for loopback/localhost. The\n\t * problem is that if the home directory is NFS-mounted to multiple\n\t * machines, localhost will refer to a different machine in each of\n\t * them, and the user will get bogus HOST_CHANGED warnings. This\n\t * essentially disables host authentication for localhost; however,\n\t * this is probably not a real problem.\n\t */\n\tif (options.no_host_authentication_for_localhost == 1 && local &&\n\t options.host_key_alias == NULL) {\n\t\tdebug(\"Forcing accepting of host key for \"\n\t\t \"loopback/localhost.\");\n\t\treturn 0;\n\t}\n\n\t/*\n\t * Prepare the hostname and address strings used for hostkey lookup.\n\t * In some cases, these will have a port number appended.\n\t */\n\tget_hostfile_hostname_ipaddr(hostname, hostaddr, port, &host, &ip);\n\n\t/*\n\t * Turn off check_host_ip if the connection is to localhost, via proxy\n\t * command or if we don't have a hostname to compare with\n\t */\n\tif (options.check_host_ip && (local ||\n\t strcmp(hostname, ip) == 0 || options.proxy_command != NULL))\n\t\toptions.check_host_ip = 0;\n\n\thost_hostkeys = init_hostkeys();\n\tfor (i = 0; i < num_user_hostfiles; i++)\n\t\tload_hostkeys(host_hostkeys, host, user_hostfiles[i]);\n\tfor (i = 0; i < num_system_hostfiles; i++)\n\t\tload_hostkeys(host_hostkeys, host, system_hostfiles[i]);\n\n\tip_hostkeys = NULL;\n\tif (!want_cert && options.check_host_ip) {\n\t\tip_hostkeys = init_hostkeys();\n\t\tfor (i = 0; i < num_user_hostfiles; i++)\n\t\t\tload_hostkeys(ip_hostkeys, ip, user_hostfiles[i]);\n\t\tfor (i = 0; i < num_system_hostfiles; i++)\n\t\t\tload_hostkeys(ip_hostkeys, ip, system_hostfiles[i]);\n\t}\n\n retry:\n\t/* Reload these as they may have changed on cert->key downgrade */\n\twant_cert = key_is_cert(host_key);\n\ttype = key_type(host_key);\n\n\t/*\n\t * Check if the host key is present in the user's list of known\n\t * hosts or in the systemwide list.\n\t */\n\thost_status = check_key_in_hostkeys(host_hostkeys, host_key,\n\t &host_found);\n\n\t/*\n\t * Also perform check for the ip address, skip the check if we are\n\t * localhost, looking for a certificate, or the hostname was an ip\n\t * address to begin with.\n\t */\n\tif (!want_cert && ip_hostkeys != NULL) {\n\t\tip_status = check_key_in_hostkeys(ip_hostkeys, host_key,\n\t\t &ip_found);\n\t\tif (host_status == HOST_CHANGED &&\n\t\t (ip_status != HOST_CHANGED || \n\t\t (ip_found != NULL &&\n\t\t !key_equal(ip_found->key, host_found->key))))\n\t\t\thost_ip_differ = 1;\n\t} else\n\t\tip_status = host_status;\n\n\tswitch (host_status) {\n\tcase HOST_OK:\n\t\t/* The host is known and the key matches. */\n\t\tdebug(\"Host '%.200s' is known and matches the %s host %s.\",\n\t\t host, type, want_cert ? \"certificate\" : \"key\");\n\t\tdebug(\"Found %s in %s:%lu\", want_cert ? \"CA key\" : \"key\",\n\t\t host_found->file, host_found->line);\n\t\tif (want_cert && !check_host_cert(hostname, host_key))\n\t\t\tgoto fail;\n\t\tif (options.check_host_ip && ip_status == HOST_NEW) {\n\t\t\tif (readonly || want_cert)\n\t\t\t\tlogit(\"%s host key for IP address \"\n\t\t\t\t \"'%.128s' not in list of known hosts.\",\n\t\t\t\t type, ip);\n\t\t\telse if (!add_host_to_hostfile(user_hostfiles[0], ip,\n\t\t\t host_key, options.hash_known_hosts))\n\t\t\t\tlogit(\"Failed to add the %s host key for IP \"\n\t\t\t\t \"address '%.128s' to the list of known \"\n\t\t\t\t \"hosts (%.500s).\", type, ip,\n\t\t\t\t user_hostfiles[0]);\n\t\t\telse\n\t\t\t\tlogit(\"Warning: Permanently added the %s host \"\n\t\t\t\t \"key for IP address '%.128s' to the list \"\n\t\t\t\t \"of known hosts.\", type, ip);\n\t\t} else if (options.visual_host_key) {\n\t\t\tfp = sshkey_fingerprint(host_key,\n\t\t\t options.fingerprint_hash, SSH_FP_DEFAULT);\n\t\t\tra = sshkey_fingerprint(host_key,\n\t\t\t options.fingerprint_hash, SSH_FP_RANDOMART);\n\t\t\tif (fp == NULL || ra == NULL)\n\t\t\t\tfatal(\"%s: sshkey_fingerprint fail\", __func__);\n\t\t\tlogit(\"Host key fingerprint is %s\\n%s\", fp, ra);\n\t\t\tfree(ra);\n\t\t\tfree(fp);\n\t\t}\n\t\thostkey_trusted = 1;\n\t\tbreak;\n\tcase HOST_NEW:\n\t\tif (options.host_key_alias == NULL && port != 0 &&\n\t\t port != SSH_DEFAULT_PORT) {\n\t\t\tdebug(\"checking without port identifier\");\n\t\t\tif (check_host_key(hostname, hostaddr, 0, host_key,\n\t\t\t ROQUIET, user_hostfiles, num_user_hostfiles,\n\t\t\t system_hostfiles, num_system_hostfiles) == 0) {\n\t\t\t\tdebug(\"found matching key w/out port\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (readonly || want_cert)\n\t\t\tgoto fail;\n\t\t/* The host is new. */\n\t\tif (options.strict_host_key_checking == 1) {\n\t\t\t/*\n\t\t\t * User has requested strict host key checking. We\n\t\t\t * will not add the host key automatically. The only\n\t\t\t * alternative left is to abort.\n\t\t\t */\n\t\t\terror(\"No %s host key is known for %.200s and you \"\n\t\t\t \"have requested strict checking.\", type, host);\n\t\t\tgoto fail;\n\t\t} else if (options.strict_host_key_checking == 2) {\n\t\t\tchar msg1[1024], msg2[1024];\n\n\t\t\tif (show_other_keys(host_hostkeys, host_key))\n\t\t\t\tsnprintf(msg1, sizeof(msg1),\n\t\t\t\t \"\\nbut keys of different type are already\"\n\t\t\t\t \" known for this host.\");\n\t\t\telse\n\t\t\t\tsnprintf(msg1, sizeof(msg1), \".\");\n\t\t\t/* The default */\n\t\t\tfp = sshkey_fingerprint(host_key,\n\t\t\t options.fingerprint_hash, SSH_FP_DEFAULT);\n\t\t\tra = sshkey_fingerprint(host_key,\n\t\t\t options.fingerprint_hash, SSH_FP_RANDOMART);\n\t\t\tif (fp == NULL || ra == NULL)\n\t\t\t\tfatal(\"%s: sshkey_fingerprint fail\", __func__);\n\t\t\tmsg2[0] = '\\0';\n\t\t\tif (options.verify_host_key_dns) {\n\t\t\t\tif (matching_host_key_dns)\n\t\t\t\t\tsnprintf(msg2, sizeof(msg2),\n\t\t\t\t\t \"Matching host key fingerprint\"\n\t\t\t\t\t \" found in DNS.\\n\");\n\t\t\t\telse\n\t\t\t\t\tsnprintf(msg2, sizeof(msg2),\n\t\t\t\t\t \"No matching host key fingerprint\"\n\t\t\t\t\t \" found in DNS.\\n\");\n\t\t\t}\n\t\t\tsnprintf(msg, sizeof(msg),\n\t\t\t \"The authenticity of host '%.200s (%s)' can't be \"\n\t\t\t \"established%s\\n\"\n\t\t\t \"%s key fingerprint is %s.%s%s\\n%s\"\n\t\t\t \"Are you sure you want to continue connecting \"\n\t\t\t \"(yes/no)? \",\n\t\t\t host, ip, msg1, type, fp,\n\t\t\t options.visual_host_key ? \"\\n\" : \"\",\n\t\t\t options.visual_host_key ? ra : \"\",\n\t\t\t msg2);\n\t\t\tfree(ra);\n\t\t\tfree(fp);\n\t\t\tif (!confirm(msg))\n\t\t\t\tgoto fail;\n\t\t\thostkey_trusted = 1; /* user explicitly confirmed */\n\t\t}\n\t\t/*\n\t\t * If not in strict mode, add the key automatically to the\n\t\t * local known_hosts file.\n\t\t */\n\t\tif (options.check_host_ip && ip_status == HOST_NEW) {\n\t\t\tsnprintf(hostline, sizeof(hostline), \"%s,%s\", host, ip);\n\t\t\thostp = hostline;\n\t\t\tif (options.hash_known_hosts) {\n\t\t\t\t/* Add hash of host and IP separately */\n\t\t\t\tr = add_host_to_hostfile(user_hostfiles[0],\n\t\t\t\t host, host_key, options.hash_known_hosts) &&\n\t\t\t\t add_host_to_hostfile(user_hostfiles[0], ip,\n\t\t\t\t host_key, options.hash_known_hosts);\n\t\t\t} else {\n\t\t\t\t/* Add unhashed \"host,ip\" */\n\t\t\t\tr = add_host_to_hostfile(user_hostfiles[0],\n\t\t\t\t hostline, host_key,\n\t\t\t\t options.hash_known_hosts);\n\t\t\t}\n\t\t} else {\n\t\t\tr = add_host_to_hostfile(user_hostfiles[0], host,\n\t\t\t host_key, options.hash_known_hosts);\n\t\t\thostp = host;\n\t\t}\n\n\t\tif (!r)\n\t\t\tlogit(\"Failed to add the host to the list of known \"\n\t\t\t \"hosts (%.500s).\", user_hostfiles[0]);\n\t\telse\n\t\t\tlogit(\"Warning: Permanently added '%.200s' (%s) to the \"\n\t\t\t \"list of known hosts.\", hostp, type);\n\t\tbreak;\n\tcase HOST_REVOKED:\n\t\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\t\terror(\"@ WARNING: REVOKED HOST KEY DETECTED! @\");\n\t\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\t\terror(\"The %s host key for %s is marked as revoked.\", type, host);\n\t\terror(\"This could mean that a stolen key is being used to\");\n\t\terror(\"impersonate this host.\");\n\n\t\t/*\n\t\t * If strict host key checking is in use, the user will have\n\t\t * to edit the key manually and we can only abort.\n\t\t */\n\t\tif (options.strict_host_key_checking) {\n\t\t\terror(\"%s host key for %.200s was revoked and you have \"\n\t\t\t \"requested strict checking.\", type, host);\n\t\t\tgoto fail;\n\t\t}\n\t\tgoto continue_unsafe;\n\n\tcase HOST_CHANGED:\n\t\tif (want_cert) {\n\t\t\t/*\n\t\t\t * This is only a debug() since it is valid to have\n\t\t\t * CAs with wildcard DNS matches that don't match\n\t\t\t * all hosts that one might visit.\n\t\t\t */\n\t\t\tdebug(\"Host certificate authority does not \"\n\t\t\t \"match %s in %s:%lu\", CA_MARKER,\n\t\t\t host_found->file, host_found->line);\n\t\t\tgoto fail;\n\t\t}\n\t\tif (readonly == ROQUIET)\n\t\t\tgoto fail;\n\t\tif (options.check_host_ip && host_ip_differ) {\n\t\t\tchar *key_msg;\n\t\t\tif (ip_status == HOST_NEW)\n\t\t\t\tkey_msg = \"is unknown\";\n\t\t\telse if (ip_status == HOST_OK)\n\t\t\t\tkey_msg = \"is unchanged\";\n\t\t\telse\n\t\t\t\tkey_msg = \"has a different value\";\n\t\t\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\t\t\terror(\"@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @\");\n\t\t\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\t\t\terror(\"The %s host key for %s has changed,\", type, host);\n\t\t\terror(\"and the key for the corresponding IP address %s\", ip);\n\t\t\terror(\"%s. This could either mean that\", key_msg);\n\t\t\terror(\"DNS SPOOFING is happening or the IP address for the host\");\n\t\t\terror(\"and its host key have changed at the same time.\");\n\t\t\tif (ip_status != HOST_NEW)\n\t\t\t\terror(\"Offending key for IP in %s:%lu\",\n\t\t\t\t ip_found->file, ip_found->line);\n\t\t}\n\t\t/* The host key has changed. */\n\t\twarn_changed_key(host_key);\n\t\terror(\"Add correct host key in %.100s to get rid of this message.\",\n\t\t user_hostfiles[0]);\n\t\terror(\"Offending %s key in %s:%lu\", key_type(host_found->key),\n\t\t host_found->file, host_found->line);\n\n\t\t/*\n\t\t * If strict host key checking is in use, the user will have\n\t\t * to edit the key manually and we can only abort.\n\t\t */\n\t\tif (options.strict_host_key_checking) {\n\t\t\terror(\"%s host key for %.200s has changed and you have \"\n\t\t\t \"requested strict checking.\", type, host);\n\t\t\tgoto fail;\n\t\t}\n\n continue_unsafe:\n\t\t/*\n\t\t * If strict host key checking has not been requested, allow\n\t\t * the connection but without MITM-able authentication or\n\t\t * forwarding.\n\t\t */\n\t\tif (options.password_authentication) {\n\t\t\terror(\"Password authentication is disabled to avoid \"\n\t\t\t \"man-in-the-middle attacks.\");\n\t\t\toptions.password_authentication = 0;\n\t\t\tcancelled_forwarding = 1;\n\t\t}\n\t\tif (options.kbd_interactive_authentication) {\n\t\t\terror(\"Keyboard-interactive authentication is disabled\"\n\t\t\t \" to avoid man-in-the-middle attacks.\");\n\t\t\toptions.kbd_interactive_authentication = 0;\n\t\t\toptions.challenge_response_authentication = 0;\n\t\t\tcancelled_forwarding = 1;\n\t\t}\n\t\tif (options.challenge_response_authentication) {\n\t\t\terror(\"Challenge/response authentication is disabled\"\n\t\t\t \" to avoid man-in-the-middle attacks.\");\n\t\t\toptions.challenge_response_authentication = 0;\n\t\t\tcancelled_forwarding = 1;\n\t\t}\n\t\tif (options.forward_agent) {\n\t\t\terror(\"Agent forwarding is disabled to avoid \"\n\t\t\t \"man-in-the-middle attacks.\");\n\t\t\toptions.forward_agent = 0;\n\t\t\tcancelled_forwarding = 1;\n\t\t}\n\t\tif (options.forward_x11) {\n\t\t\terror(\"X11 forwarding is disabled to avoid \"\n\t\t\t \"man-in-the-middle attacks.\");\n\t\t\toptions.forward_x11 = 0;\n\t\t\tcancelled_forwarding = 1;\n\t\t}\n\t\tif (options.num_local_forwards > 0 ||\n\t\t options.num_remote_forwards > 0) {\n\t\t\terror(\"Port forwarding is disabled to avoid \"\n\t\t\t \"man-in-the-middle attacks.\");\n\t\t\toptions.num_local_forwards =\n\t\t\t options.num_remote_forwards = 0;\n\t\t\tcancelled_forwarding = 1;\n\t\t}\n\t\tif (options.tun_open != SSH_TUNMODE_NO) {\n\t\t\terror(\"Tunnel forwarding is disabled to avoid \"\n\t\t\t \"man-in-the-middle attacks.\");\n\t\t\toptions.tun_open = SSH_TUNMODE_NO;\n\t\t\tcancelled_forwarding = 1;\n\t\t}\n\t\tif (options.exit_on_forward_failure && cancelled_forwarding)\n\t\t\tfatal(\"Error: forwarding disabled due to host key \"\n\t\t\t \"check failure\");\n\t\t\n\t\t/*\n\t\t * XXX Should permit the user to change to use the new id.\n\t\t * This could be done by converting the host key to an\n\t\t * identifying sentence, tell that the host identifies itself\n\t\t * by that sentence, and ask the user if he/she wishes to\n\t\t * accept the authentication.\n\t\t */\n\t\tbreak;\n\tcase HOST_FOUND:\n\t\tfatal(\"internal error\");\n\t\tbreak;\n\t}\n\n\tif (options.check_host_ip && host_status != HOST_CHANGED &&\n\t ip_status == HOST_CHANGED) {\n\t\tsnprintf(msg, sizeof(msg),\n\t\t \"Warning: the %s host key for '%.200s' \"\n\t\t \"differs from the key for the IP address '%.128s'\"\n\t\t \"\\nOffending key for IP in %s:%lu\",\n\t\t type, host, ip, ip_found->file, ip_found->line);\n\t\tif (host_status == HOST_OK) {\n\t\t\tlen = strlen(msg);\n\t\t\tsnprintf(msg + len, sizeof(msg) - len,\n\t\t\t \"\\nMatching host key in %s:%lu\",\n\t\t\t host_found->file, host_found->line);\n\t\t}\n\t\tif (options.strict_host_key_checking == 1) {\n\t\t\tlogit(\"%s\", msg);\n\t\t\terror(\"Exiting, you have requested strict checking.\");\n\t\t\tgoto fail;\n\t\t} else if (options.strict_host_key_checking == 2) {\n\t\t\tstrlcat(msg, \"\\nAre you sure you want \"\n\t\t\t \"to continue connecting (yes/no)? \", sizeof(msg));\n\t\t\tif (!confirm(msg))\n\t\t\t\tgoto fail;\n\t\t} else {\n\t\t\tlogit(\"%s\", msg);\n\t\t}\n\t}\n\n\tif (!hostkey_trusted && options.update_hostkeys) {\n\t\tdebug(\"%s: hostkey not known or explicitly trusted: \"\n\t\t \"disabling UpdateHostkeys\", __func__);\n\t\toptions.update_hostkeys = 0;\n\t}\n\n\tfree(ip);\n\tfree(host);\n\tif (host_hostkeys != NULL)\n\t\tfree_hostkeys(host_hostkeys);\n\tif (ip_hostkeys != NULL)\n\t\tfree_hostkeys(ip_hostkeys);\n\treturn 0;\n\nfail:\n\tif (want_cert && host_status != HOST_REVOKED) {\n\t\t/*\n\t\t * No matching certificate. Downgrade cert to raw key and\n\t\t * search normally.\n\t\t */\n\t\tdebug(\"No matching CA found. Retry with plain key\");\n\t\traw_key = key_from_private(host_key);\n\t\tif (key_drop_cert(raw_key) != 0)\n\t\t\tfatal(\"Couldn't drop certificate\");\n\t\thost_key = raw_key;\n\t\tgoto retry;\n\t}\n\tif (raw_key != NULL)\n\t\tkey_free(raw_key);\n\tfree(ip);\n\tfree(host);\n\tif (host_hostkeys != NULL)\n\t\tfree_hostkeys(host_hostkeys);\n\tif (ip_hostkeys != NULL)\n\t\tfree_hostkeys(ip_hostkeys);\n\treturn -1;\n}\n\n/* returns 0 if key verifies or -1 if key does NOT verify */\nint\nverify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)\n{\n\tu_int i;\n\tint r = -1, flags = 0;\n\tchar valid[64], *fp = NULL, *cafp = NULL;\n\tstruct sshkey *plain = NULL;\n\n\tif ((fp = sshkey_fingerprint(host_key,\n\t options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {\n\t\terror(\"%s: fingerprint host key: %s\", __func__, ssh_err(r));\n\t\tr = -1;\n\t\tgoto out;\n\t}\n\n\tif (sshkey_is_cert(host_key)) {\n\t\tif ((cafp = sshkey_fingerprint(host_key->cert->signature_key,\n\t\t options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) {\n\t\t\terror(\"%s: fingerprint CA key: %s\",\n\t\t\t __func__, ssh_err(r));\n\t\t\tr = -1;\n\t\t\tgoto out;\n\t\t}\n\t\tsshkey_format_cert_validity(host_key->cert,\n\t\t valid, sizeof(valid));\n\t\tdebug(\"Server host certificate: %s %s, serial %llu \"\n\t\t \"ID \\\"%s\\\" CA %s %s valid %s\",\n\t\t sshkey_ssh_name(host_key), fp,\n\t\t (unsigned long long)host_key->cert->serial,\n\t\t host_key->cert->key_id,\n\t\t sshkey_ssh_name(host_key->cert->signature_key), cafp,\n\t\t valid);\n\t\tfor (i = 0; i < host_key->cert->nprincipals; i++) {\n\t\t\tdebug2(\"Server host certificate hostname: %s\",\n\t\t\t host_key->cert->principals[i]);\n\t\t}\n\t} else {\n\t\tdebug(\"Server host key: %s %s\", compat20 ?\n\t\t sshkey_ssh_name(host_key) : sshkey_type(host_key), fp);\n\t}\n\n\tif (sshkey_equal(previous_host_key, host_key)) {\n\t\tdebug2(\"%s: server host key %s %s matches cached key\",\n\t\t __func__, sshkey_type(host_key), fp);\n\t\tr = 0;\n\t\tgoto out;\n\t}\n\n\t/* Check in RevokedHostKeys file if specified */\n\tif (options.revoked_host_keys != NULL) {\n\t\tr = sshkey_check_revoked(host_key, options.revoked_host_keys);\n\t\tswitch (r) {\n\t\tcase 0:\n\t\t\tbreak; /* not revoked */\n\t\tcase SSH_ERR_KEY_REVOKED:\n\t\t\terror(\"Host key %s %s revoked by file %s\",\n\t\t\t sshkey_type(host_key), fp,\n\t\t\t options.revoked_host_keys);\n\t\t\tr = -1;\n\t\t\tgoto out;\n\t\tdefault:\n\t\t\terror(\"Error checking host key %s %s in \"\n\t\t\t \"revoked keys file %s: %s\", sshkey_type(host_key),\n\t\t\t fp, options.revoked_host_keys, ssh_err(r));\n\t\t\tr = -1;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tif (options.verify_host_key_dns) {\n\t\t/*\n\t\t * XXX certs are not yet supported for DNS, so downgrade\n\t\t * them and try the plain key.\n\t\t */\n\t\tif ((r = sshkey_from_private(host_key, &plain)) != 0)\n\t\t\tgoto out;\n\t\tif (sshkey_is_cert(plain))\n\t\t\tsshkey_drop_cert(plain);\n\t\tif (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {\n\t\t\tif (flags & DNS_VERIFY_FOUND) {\n\t\t\t\tif (options.verify_host_key_dns == 1 &&\n\t\t\t\t flags & DNS_VERIFY_MATCH &&\n\t\t\t\t flags & DNS_VERIFY_SECURE) {\n\t\t\t\t\tr = 0;\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\t\t\t\tif (flags & DNS_VERIFY_MATCH) {\n\t\t\t\t\tmatching_host_key_dns = 1;\n\t\t\t\t} else {\n\t\t\t\t\twarn_changed_key(plain);\n\t\t\t\t\terror(\"Update the SSHFP RR in DNS \"\n\t\t\t\t\t \"with the new host key to get rid \"\n\t\t\t\t\t \"of this message.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tr = check_host_key(host, hostaddr, options.port, host_key, RDRW,\n\t options.user_hostfiles, options.num_user_hostfiles,\n\t options.system_hostfiles, options.num_system_hostfiles);\n\nout:\n\tsshkey_free(plain);\n\tfree(fp);\n\tfree(cafp);\n\tif (r == 0 && host_key != NULL) {\n\t\tkey_free(previous_host_key);\n\t\tprevious_host_key = key_from_private(host_key);\n\t}\n\n\treturn r;\n}\n\n/*\n * Starts a dialog with the server, and authenticates the current user on the\n * server. This does not need any extra privileges. The basic connection\n * to the server must already have been established before this is called.\n * If login fails, this function prints an error and never returns.\n * This function does not require super-user privileges.\n */\nvoid\nssh_login(Sensitive *sensitive, const char *orighost,\n struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms)\n{\n\tchar *host;\n\tchar *server_user, *local_user;\n\n\tlocal_user = xstrdup(pw->pw_name);\n\tserver_user = options.user ? options.user : local_user;\n\n\t/* Convert the user-supplied hostname into all lowercase. */\n\thost = xstrdup(orighost);\n\tlowercase(host);\n\n\t/* Exchange protocol version identification strings with the server. */\n\tssh_exchange_identification(timeout_ms);\n\n\t/* Put the connection into non-blocking mode. */\n\tpacket_set_nonblocking();\n\n\t/* key exchange */\n\t/* authenticate user */\n\tdebug(\"Authenticating to %s:%d as '%s'\", host, port, server_user);\n\tif (compat20) {\n\t\tssh_kex2(host, hostaddr, port);\n\t\tssh_userauth2(local_user, server_user, host, sensitive);\n\t} else {\n#ifdef WITH_SSH1\n\t\tssh_kex(host, hostaddr);\n\t\tssh_userauth1(local_user, server_user, host, sensitive);\n#else\n\t\tfatal(\"ssh1 is not supported\");\n#endif\n\t}\n\tfree(local_user);\n}\n\nvoid\nssh_put_password(char *password)\n{\n\tint size;\n\tchar *padded;\n\n\tif (datafellows & SSH_BUG_PASSWORDPAD) {\n\t\tpacket_put_cstring(password);\n\t\treturn;\n\t}\n\tsize = ROUNDUP(strlen(password) + 1, 32);\n\tpadded = xcalloc(1, size);\n\tstrlcpy(padded, password, size);\n\tpacket_put_string(padded, size);\n\texplicit_bzero(padded, size);\n\tfree(padded);\n}\n\n/* print all known host keys for a given host, but skip keys of given type */\nstatic int\nshow_other_keys(struct hostkeys *hostkeys, Key *key)\n{\n\tint type[] = {\n\t\tKEY_RSA1,\n\t\tKEY_RSA,\n\t\tKEY_DSA,\n\t\tKEY_ECDSA,\n\t\tKEY_ED25519,\n\t\t-1\n\t};\n\tint i, ret = 0;\n\tchar *fp, *ra;\n\tconst struct hostkey_entry *found;\n\n\tfor (i = 0; type[i] != -1; i++) {\n\t\tif (type[i] == key->type)\n\t\t\tcontinue;\n\t\tif (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found))\n\t\t\tcontinue;\n\t\tfp = sshkey_fingerprint(found->key,\n\t\t options.fingerprint_hash, SSH_FP_DEFAULT);\n\t\tra = sshkey_fingerprint(found->key,\n\t\t options.fingerprint_hash, SSH_FP_RANDOMART);\n\t\tif (fp == NULL || ra == NULL)\n\t\t\tfatal(\"%s: sshkey_fingerprint fail\", __func__);\n\t\tlogit(\"WARNING: %s key found for host %s\\n\"\n\t\t \"in %s:%lu\\n\"\n\t\t \"%s key fingerprint %s.\",\n\t\t key_type(found->key),\n\t\t found->host, found->file, found->line,\n\t\t key_type(found->key), fp);\n\t\tif (options.visual_host_key)\n\t\t\tlogit(\"%s\", ra);\n\t\tfree(ra);\n\t\tfree(fp);\n\t\tret = 1;\n\t}\n\treturn ret;\n}\n\nstatic void\nwarn_changed_key(Key *host_key)\n{\n\tchar *fp;\n\n\tfp = sshkey_fingerprint(host_key, options.fingerprint_hash,\n\t SSH_FP_DEFAULT);\n\tif (fp == NULL)\n\t\tfatal(\"%s: sshkey_fingerprint fail\", __func__);\n\n\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\terror(\"@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\");\n\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\terror(\"IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\");\n\terror(\"Someone could be eavesdropping on you right now (man-in-the-middle attack)!\");\n\terror(\"It is also possible that a host key has just been changed.\");\n\terror(\"The fingerprint for the %s key sent by the remote host is\\n%s.\",\n\t key_type(host_key), fp);\n\terror(\"Please contact your system administrator.\");\n\n\tfree(fp);\n}\n\n/*\n * Execute a local command\n */\nint\nssh_local_cmd(const char *args)\n{\n\tchar *shell;\n\tpid_t pid;\n\tint status;\n\tvoid (*osighand)(int);\n\n\tif (!options.permit_local_command ||\n\t args == NULL || !*args)\n\t\treturn (1);\n\n\tif ((shell = getenv(\"SHELL\")) == NULL || *shell == '\\0')\n\t\tshell = _PATH_BSHELL;\n\n\tosighand = signal(SIGCHLD, SIG_DFL);\n\tpid = fork();\n\tif (pid == 0) {\n\t\tsignal(SIGPIPE, SIG_DFL);\n\t\tdebug3(\"Executing %s -c \\\"%s\\\"\", shell, args);\n\t\texecl(shell, shell, \"-c\", args, (char *)NULL);\n\t\terror(\"Couldn't execute %s -c \\\"%s\\\": %s\",\n\t\t shell, args, strerror(errno));\n\t\t_exit(1);\n\t} else if (pid == -1)\n\t\tfatal(\"fork failed: %.100s\", strerror(errno));\n\twhile (waitpid(pid, &status, 0) == -1)\n\t\tif (errno != EINTR)\n\t\t\tfatal(\"Couldn't wait for child: %s\", strerror(errno));\n\tsignal(SIGCHLD, osighand);\n\n\tif (!WIFEXITED(status))\n\t\treturn (1);\n\n\treturn (WEXITSTATUS(status));\n}\n\nvoid\nmaybe_add_key_to_agent(char *authfile, Key *private, char *comment,\n char *passphrase)\n{\n\tint auth_sock = -1, r;\n\n\tif (options.add_keys_to_agent == 0)\n\t\treturn;\n\n\tif ((r = ssh_get_authentication_socket(&auth_sock)) != 0) {\n\t\tdebug3(\"no authentication agent, not adding key\");\n\t\treturn;\n\t}\n\n\tif (options.add_keys_to_agent == 2 &&\n\t !ask_permission(\"Add key %s (%s) to agent?\", authfile, comment)) {\n\t\tdebug3(\"user denied adding this key\");\n\t\tclose(auth_sock);\n\t\treturn;\n\t}\n\n\tif ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0,\n\t (options.add_keys_to_agent == 3))) == 0)\n\t\tdebug(\"identity added to agent: %s\", authfile);\n\telse\n\t\tdebug(\"could not add identity to agent: %s (%d)\", authfile, r);\n\tclose(auth_sock);\n}\n","/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 djm Exp $ */\n/*\n * Copyright (c) 2000 Markus Friedl. All rights reserved.\n * Copyright (c) 2008 Damien Miller. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)\n#include \n#endif\n\n#include \"openbsd-compat/sys-queue.h\"\n\n#include \"xmalloc.h\"\n#include \"ssh.h\"\n#include \"ssh2.h\"\n#include \"buffer.h\"\n#include \"packet.h\"\n#include \"compat.h\"\n#include \"cipher.h\"\n#include \"key.h\"\n#include \"kex.h\"\n#include \"myproposal.h\"\n#include \"sshconnect.h\"\n#include \"authfile.h\"\n#include \"dh.h\"\n#include \"authfd.h\"\n#include \"log.h\"\n#include \"misc.h\"\n#include \"readconf.h\"\n#include \"match.h\"\n#include \"dispatch.h\"\n#include \"canohost.h\"\n#include \"msg.h\"\n#include \"pathnames.h\"\n#include \"uidswap.h\"\n#include \"hostfile.h\"\n#include \"ssherr.h\"\n#include \"utf8.h\"\n\n#ifdef GSSAPI\n#include \"ssh-gss.h\"\n#endif\n\n/* import */\nextern char *client_version_string;\nextern char *server_version_string;\nextern Options options;\n\n/*\n * SSH2 key exchange\n */\n\nu_char *session_id2 = NULL;\nu_int session_id2_len = 0;\n\nchar *xxx_host;\nstruct sockaddr *xxx_hostaddr;\n\nstatic int\nverify_host_key_callback(Key *hostkey, struct ssh *ssh)\n{\n\tif (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)\n\t\tfatal(\"Host key verification failed.\");\n\treturn 0;\n}\n\nstatic char *\norder_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)\n{\n\tchar *oavail, *avail, *first, *last, *alg, *hostname, *ret;\n\tsize_t maxlen;\n\tstruct hostkeys *hostkeys;\n\tint ktype;\n\tu_int i;\n\n\t/* Find all hostkeys for this hostname */\n\tget_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL);\n\thostkeys = init_hostkeys();\n\tfor (i = 0; i < options.num_user_hostfiles; i++)\n\t\tload_hostkeys(hostkeys, hostname, options.user_hostfiles[i]);\n\tfor (i = 0; i < options.num_system_hostfiles; i++)\n\t\tload_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);\n\n\toavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);\n\tmaxlen = strlen(avail) + 1;\n\tfirst = xmalloc(maxlen);\n\tlast = xmalloc(maxlen);\n\t*first = *last = '\\0';\n\n#define ALG_APPEND(to, from) \\\n\tdo { \\\n\t\tif (*to != '\\0') \\\n\t\t\tstrlcat(to, \",\", maxlen); \\\n\t\tstrlcat(to, from, maxlen); \\\n\t} while (0)\n\n\twhile ((alg = strsep(&avail, \",\")) && *alg != '\\0') {\n\t\tif ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)\n\t\t\tfatal(\"%s: unknown alg %s\", __func__, alg);\n\t\tif (lookup_key_in_hostkeys_by_type(hostkeys,\n\t\t sshkey_type_plain(ktype), NULL))\n\t\t\tALG_APPEND(first, alg);\n\t\telse\n\t\t\tALG_APPEND(last, alg);\n\t}\n#undef ALG_APPEND\n\txasprintf(&ret, \"%s%s%s\", first,\n\t (*first == '\\0' || *last == '\\0') ? \"\" : \",\", last);\n\tif (*first != '\\0')\n\t\tdebug3(\"%s: prefer hostkeyalgs: %s\", __func__, first);\n\n\tfree(first);\n\tfree(last);\n\tfree(hostname);\n\tfree(oavail);\n\tfree_hostkeys(hostkeys);\n\n\treturn ret;\n}\n\nvoid\nssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)\n{\n\tchar *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };\n\tchar *s;\n\tstruct kex *kex;\n\tint r;\n\n\txxx_host = host;\n\txxx_hostaddr = hostaddr;\n\n\tif ((s = kex_names_cat(options.kex_algorithms, \"ext-info-c\")) == NULL)\n\t\tfatal(\"%s: kex_names_cat\", __func__);\n\tmyproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s);\n\tmyproposal[PROPOSAL_ENC_ALGS_CTOS] =\n\t compat_cipher_proposal(options.ciphers);\n\tmyproposal[PROPOSAL_ENC_ALGS_STOC] =\n\t compat_cipher_proposal(options.ciphers);\n\tmyproposal[PROPOSAL_COMP_ALGS_CTOS] =\n\t myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ?\n\t \"zlib@openssh.com,zlib,none\" : \"none,zlib@openssh.com,zlib\";\n\tmyproposal[PROPOSAL_MAC_ALGS_CTOS] =\n\t myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;\n\tif (options.hostkeyalgorithms != NULL) {\n\t\tif (kex_assemble_names(KEX_DEFAULT_PK_ALG,\n\t\t &options.hostkeyalgorithms) != 0)\n\t\t\tfatal(\"%s: kex_assemble_namelist\", __func__);\n\t\tmyproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =\n\t\t compat_pkalg_proposal(options.hostkeyalgorithms);\n\t} else {\n\t\t/* Enforce default */\n\t\toptions.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG);\n\t\t/* Prefer algorithms that we already have keys for */\n\t\tmyproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =\n\t\t compat_pkalg_proposal(\n\t\t order_hostkeyalgs(host, hostaddr, port));\n\t}\n\n\tif (options.rekey_limit || options.rekey_interval)\n\t\tpacket_set_rekey_limits(options.rekey_limit,\n\t\t options.rekey_interval);\n\n\t/* start key exchange */\n\tif ((r = kex_setup(active_state, myproposal)) != 0)\n\t\tfatal(\"kex_setup: %s\", ssh_err(r));\n\tkex = active_state->kex;\n#ifdef WITH_OPENSSL\n\tkex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;\n\tkex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;\n\tkex->kex[KEX_DH_GRP14_SHA256] = kexdh_client;\n\tkex->kex[KEX_DH_GRP16_SHA512] = kexdh_client;\n\tkex->kex[KEX_DH_GRP18_SHA512] = kexdh_client;\n\tkex->kex[KEX_DH_GEX_SHA1] = kexgex_client;\n\tkex->kex[KEX_DH_GEX_SHA256] = kexgex_client;\n# ifdef OPENSSL_HAS_ECC\n\tkex->kex[KEX_ECDH_SHA2] = kexecdh_client;\n# endif\n#endif\n\tkex->kex[KEX_C25519_SHA256] = kexc25519_client;\n\tkex->client_version_string=client_version_string;\n\tkex->server_version_string=server_version_string;\n\tkex->verify_host_key=&verify_host_key_callback;\n\n\tdispatch_run(DISPATCH_BLOCK, &kex->done, active_state);\n\n\t/* remove ext-info from the KEX proposals for rekeying */\n\tmyproposal[PROPOSAL_KEX_ALGS] =\n\t compat_kex_proposal(options.kex_algorithms);\n\tif ((r = kex_prop2buf(kex->my, myproposal)) != 0)\n\t\tfatal(\"kex_prop2buf: %s\", ssh_err(r));\n\n\tsession_id2 = kex->session_id;\n\tsession_id2_len = kex->session_id_len;\n\n#ifdef DEBUG_KEXDH\n\t/* send 1st encrypted/maced/compressed message */\n\tpacket_start(SSH2_MSG_IGNORE);\n\tpacket_put_cstring(\"markus\");\n\tpacket_send();\n\tpacket_write_wait();\n#endif\n}\n\n/*\n * Authenticate user\n */\n\ntypedef struct cauthctxt Authctxt;\ntypedef struct cauthmethod Authmethod;\ntypedef struct identity Identity;\ntypedef struct idlist Idlist;\n\nstruct identity {\n\tTAILQ_ENTRY(identity) next;\n\tint\tagent_fd;\t\t/* >=0 if agent supports key */\n\tstruct sshkey\t*key;\t\t/* public/private key */\n\tchar\t*filename;\t\t/* comment for agent-only keys */\n\tint\ttried;\n\tint\tisprivate;\t\t/* key points to the private key */\n\tint\tuserprovided;\n};\nTAILQ_HEAD(idlist, identity);\n\nstruct cauthctxt {\n\tconst char *server_user;\n\tconst char *local_user;\n\tconst char *host;\n\tconst char *service;\n\tstruct cauthmethod *method;\n\tsig_atomic_t success;\n\tchar *authlist;\n\tint attempt;\n\t/* pubkey */\n\tstruct idlist keys;\n\tint agent_fd;\n\t/* hostbased */\n\tSensitive *sensitive;\n\tchar *oktypes, *ktypes;\n\tconst char *active_ktype;\n\t/* kbd-interactive */\n\tint info_req_seen;\n\t/* generic */\n\tvoid *methoddata;\n};\n\nstruct cauthmethod {\n\tchar\t*name;\t\t/* string to compare against server's list */\n\tint\t(*userauth)(Authctxt *authctxt);\n\tvoid\t(*cleanup)(Authctxt *authctxt);\n\tint\t*enabled;\t/* flag in option struct that enables method */\n\tint\t*batch_flag;\t/* flag in option struct that disables method */\n};\n\nint\tinput_userauth_service_accept(int, u_int32_t, void *);\nint\tinput_userauth_ext_info(int, u_int32_t, void *);\nint\tinput_userauth_success(int, u_int32_t, void *);\nint\tinput_userauth_success_unexpected(int, u_int32_t, void *);\nint\tinput_userauth_failure(int, u_int32_t, void *);\nint\tinput_userauth_banner(int, u_int32_t, void *);\nint\tinput_userauth_error(int, u_int32_t, void *);\nint\tinput_userauth_info_req(int, u_int32_t, void *);\nint\tinput_userauth_pk_ok(int, u_int32_t, void *);\nint\tinput_userauth_passwd_changereq(int, u_int32_t, void *);\n\nint\tuserauth_none(Authctxt *);\nint\tuserauth_pubkey(Authctxt *);\nint\tuserauth_passwd(Authctxt *);\nint\tuserauth_kbdint(Authctxt *);\nint\tuserauth_hostbased(Authctxt *);\n\n#ifdef GSSAPI\nint\tuserauth_gssapi(Authctxt *authctxt);\nint\tinput_gssapi_response(int type, u_int32_t, void *);\nint\tinput_gssapi_token(int type, u_int32_t, void *);\nint\tinput_gssapi_hash(int type, u_int32_t, void *);\nint\tinput_gssapi_error(int, u_int32_t, void *);\nint\tinput_gssapi_errtok(int, u_int32_t, void *);\n#endif\n\nvoid\tuserauth(Authctxt *, char *);\n\nstatic int sign_and_send_pubkey(Authctxt *, Identity *);\nstatic void pubkey_prepare(Authctxt *);\nstatic void pubkey_cleanup(Authctxt *);\nstatic void pubkey_reset(Authctxt *);\nstatic Key *load_identity_file(Identity *);\n\nstatic Authmethod *authmethod_get(char *authlist);\nstatic Authmethod *authmethod_lookup(const char *name);\nstatic char *authmethods_get(void);\n\nAuthmethod authmethods[] = {\n#ifdef GSSAPI\n\t{\"gssapi-with-mic\",\n\t\tuserauth_gssapi,\n\t\tNULL,\n\t\t&options.gss_authentication,\n\t\tNULL},\n#endif\n\t{\"hostbased\",\n\t\tuserauth_hostbased,\n\t\tNULL,\n\t\t&options.hostbased_authentication,\n\t\tNULL},\n\t{\"publickey\",\n\t\tuserauth_pubkey,\n\t\tNULL,\n\t\t&options.pubkey_authentication,\n\t\tNULL},\n\t{\"keyboard-interactive\",\n\t\tuserauth_kbdint,\n\t\tNULL,\n\t\t&options.kbd_interactive_authentication,\n\t\t&options.batch_mode},\n\t{\"password\",\n\t\tuserauth_passwd,\n\t\tNULL,\n\t\t&options.password_authentication,\n\t\t&options.batch_mode},\n\t{\"none\",\n\t\tuserauth_none,\n\t\tNULL,\n\t\tNULL,\n\t\tNULL},\n\t{NULL, NULL, NULL, NULL, NULL}\n};\n\nvoid\nssh_userauth2(const char *local_user, const char *server_user, char *host,\n Sensitive *sensitive)\n{\n\tstruct ssh *ssh = active_state;\n\tAuthctxt authctxt;\n\tint r;\n\n\tif (options.challenge_response_authentication)\n\t\toptions.kbd_interactive_authentication = 1;\n\tif (options.preferred_authentications == NULL)\n\t\toptions.preferred_authentications = authmethods_get();\n\n\t/* setup authentication context */\n\tmemset(&authctxt, 0, sizeof(authctxt));\n\tpubkey_prepare(&authctxt);\n\tauthctxt.server_user = server_user;\n\tauthctxt.local_user = local_user;\n\tauthctxt.host = host;\n\tauthctxt.service = \"ssh-connection\";\t\t/* service name */\n\tauthctxt.success = 0;\n\tauthctxt.method = authmethod_lookup(\"none\");\n\tauthctxt.authlist = NULL;\n\tauthctxt.methoddata = NULL;\n\tauthctxt.sensitive = sensitive;\n\tauthctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL;\n\tauthctxt.info_req_seen = 0;\n\tauthctxt.agent_fd = -1;\n\tif (authctxt.method == NULL)\n\t\tfatal(\"ssh_userauth2: internal error: cannot send userauth none request\");\n\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, \"ssh-userauth\")) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\n\tssh_dispatch_init(ssh, &input_userauth_error);\n\tssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info);\n\tssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept);\n\tssh_dispatch_run(ssh, DISPATCH_BLOCK, &authctxt.success, &authctxt);\t/* loop until success */\n\n\tpubkey_cleanup(&authctxt);\n\tssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);\n\n\tif (!authctxt.success)\n\t\tfatal(\"Authentication failed.\");\n\tdebug(\"Authentication succeeded (%s).\", authctxt.method->name);\n}\n\n/* ARGSUSED */\nint\ninput_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tstruct ssh *ssh = active_state;\n\tint r;\n\n\tif (ssh_packet_remaining(ssh) > 0) {\n\t\tchar *reply;\n\n\t\tif ((r = sshpkt_get_cstring(ssh, &reply, NULL)) != 0)\n\t\t\tgoto out;\n\t\tdebug2(\"service_accept: %s\", reply);\n\t\tfree(reply);\n\t} else {\n\t\tdebug2(\"buggy server: service_accept w/o service\");\n\t}\n\tif ((r = sshpkt_get_end(ssh)) != 0)\n\t\tgoto out;\n\tdebug(\"SSH2_MSG_SERVICE_ACCEPT received\");\n\n\t/* initial userauth request */\n\tuserauth_none(authctxt);\n\n\tssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_error);\n\tssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);\n\tssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);\n\tssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);\n\tr = 0;\n out:\n\treturn r;\n}\n\n/* ARGSUSED */\nint\ninput_userauth_ext_info(int type, u_int32_t seqnr, void *ctxt)\n{\n\treturn kex_input_ext_info(type, seqnr, active_state);\n}\n\nvoid\nuserauth(Authctxt *authctxt, char *authlist)\n{\n\tif (authctxt->method != NULL && authctxt->method->cleanup != NULL)\n\t\tauthctxt->method->cleanup(authctxt);\n\n\tfree(authctxt->methoddata);\n\tauthctxt->methoddata = NULL;\n\tif (authlist == NULL) {\n\t\tauthlist = authctxt->authlist;\n\t} else {\n\t\tfree(authctxt->authlist);\n\t\tauthctxt->authlist = authlist;\n\t}\n\tfor (;;) {\n\t\tAuthmethod *method = authmethod_get(authlist);\n\t\tif (method == NULL)\n\t\t\tfatal(\"Permission denied (%s).\", authlist);\n\t\tauthctxt->method = method;\n\n\t\t/* reset the per method handler */\n\t\tdispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN,\n\t\t SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);\n\n\t\t/* and try new method */\n\t\tif (method->userauth(authctxt) != 0) {\n\t\t\tdebug2(\"we sent a %s packet, wait for reply\", method->name);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tdebug2(\"we did not send a packet, disable method\");\n\t\t\tmethod->enabled = NULL;\n\t\t}\n\t}\n}\n\n/* ARGSUSED */\nint\ninput_userauth_error(int type, u_int32_t seq, void *ctxt)\n{\n\tfatal(\"input_userauth_error: bad message during authentication: \"\n\t \"type %d\", type);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\ninput_userauth_banner(int type, u_int32_t seq, void *ctxt)\n{\n\tchar *msg, *lang;\n\tu_int len;\n\n\tdebug3(\"%s\", __func__);\n\tmsg = packet_get_string(&len);\n\tlang = packet_get_string(NULL);\n\tif (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO)\n\t\tfmprintf(stderr, \"%s\", msg);\n\tfree(msg);\n\tfree(lang);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\ninput_userauth_success(int type, u_int32_t seq, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_userauth_success: no authentication context\");\n\tfree(authctxt->authlist);\n\tauthctxt->authlist = NULL;\n\tif (authctxt->method != NULL && authctxt->method->cleanup != NULL)\n\t\tauthctxt->method->cleanup(authctxt);\n\tfree(authctxt->methoddata);\n\tauthctxt->methoddata = NULL;\n\tauthctxt->success = 1;\t\t\t/* break out */\n\treturn 0;\n}\n\nint\ninput_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\n\tif (authctxt == NULL)\n\t\tfatal(\"%s: no authentication context\", __func__);\n\n\tfatal(\"Unexpected authentication success during %s.\",\n\t authctxt->method->name);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\ninput_userauth_failure(int type, u_int32_t seq, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tchar *authlist = NULL;\n\tint partial;\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_userauth_failure: no authentication context\");\n\n\tauthlist = packet_get_string(NULL);\n\tpartial = packet_get_char();\n\tpacket_check_eom();\n\n\tif (partial != 0) {\n\t\tverbose(\"Authenticated with partial success.\");\n\t\t/* reset state */\n\t\tpubkey_reset(authctxt);\n\t}\n\tdebug(\"Authentications that can continue: %s\", authlist);\n\n\tuserauth(authctxt, authlist);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\ninput_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tKey *key = NULL;\n\tIdentity *id = NULL;\n\tBuffer b;\n\tint pktype, sent = 0;\n\tu_int alen, blen;\n\tchar *pkalg, *fp;\n\tu_char *pkblob;\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_userauth_pk_ok: no authentication context\");\n\tif (datafellows & SSH_BUG_PKOK) {\n\t\t/* this is similar to SSH_BUG_PKAUTH */\n\t\tdebug2(\"input_userauth_pk_ok: SSH_BUG_PKOK\");\n\t\tpkblob = packet_get_string(&blen);\n\t\tbuffer_init(&b);\n\t\tbuffer_append(&b, pkblob, blen);\n\t\tpkalg = buffer_get_string(&b, &alen);\n\t\tbuffer_free(&b);\n\t} else {\n\t\tpkalg = packet_get_string(&alen);\n\t\tpkblob = packet_get_string(&blen);\n\t}\n\tpacket_check_eom();\n\n\tdebug(\"Server accepts key: pkalg %s blen %u\", pkalg, blen);\n\n\tif ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {\n\t\tdebug(\"unknown pkalg %s\", pkalg);\n\t\tgoto done;\n\t}\n\tif ((key = key_from_blob(pkblob, blen)) == NULL) {\n\t\tdebug(\"no key from blob. pkalg %s\", pkalg);\n\t\tgoto done;\n\t}\n\tif (key->type != pktype) {\n\t\terror(\"input_userauth_pk_ok: type mismatch \"\n\t\t \"for decoded key (received %d, expected %d)\",\n\t\t key->type, pktype);\n\t\tgoto done;\n\t}\n\tif ((fp = sshkey_fingerprint(key, options.fingerprint_hash,\n\t SSH_FP_DEFAULT)) == NULL)\n\t\tgoto done;\n\tdebug2(\"input_userauth_pk_ok: fp %s\", fp);\n\tfree(fp);\n\n\t/*\n\t * search keys in the reverse order, because last candidate has been\n\t * moved to the end of the queue. this also avoids confusion by\n\t * duplicate keys\n\t */\n\tTAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {\n\t\tif (key_equal(key, id->key)) {\n\t\t\tsent = sign_and_send_pubkey(authctxt, id);\n\t\t\tbreak;\n\t\t}\n\t}\ndone:\n\tif (key != NULL)\n\t\tkey_free(key);\n\tfree(pkalg);\n\tfree(pkblob);\n\n\t/* try another method if we did not send a packet */\n\tif (sent == 0)\n\t\tuserauth(authctxt, NULL);\n\treturn 0;\n}\n\n#ifdef GSSAPI\nint\nuserauth_gssapi(Authctxt *authctxt)\n{\n\tGssctxt *gssctxt = NULL;\n\tstatic gss_OID_set gss_supported = NULL;\n\tstatic u_int mech = 0;\n\tOM_uint32 min;\n\tint ok = 0;\n\n\t/* Try one GSSAPI method at a time, rather than sending them all at\n\t * once. */\n\n\tif (gss_supported == NULL)\n\t\tgss_indicate_mechs(&min, &gss_supported);\n\n\t/* Check to see if the mechanism is usable before we offer it */\n\twhile (mech < gss_supported->count && !ok) {\n\t\t/* My DER encoding requires length<128 */\n\t\tif (gss_supported->elements[mech].length < 128 &&\n\t\t ssh_gssapi_check_mechanism(&gssctxt, \n\t\t &gss_supported->elements[mech], authctxt->host)) {\n\t\t\tok = 1; /* Mechanism works */\n\t\t} else {\n\t\t\tmech++;\n\t\t}\n\t}\n\n\tif (!ok)\n\t\treturn 0;\n\n\tauthctxt->methoddata=(void *)gssctxt;\n\n\tpacket_start(SSH2_MSG_USERAUTH_REQUEST);\n\tpacket_put_cstring(authctxt->server_user);\n\tpacket_put_cstring(authctxt->service);\n\tpacket_put_cstring(authctxt->method->name);\n\n\tpacket_put_int(1);\n\n\tpacket_put_int((gss_supported->elements[mech].length) + 2);\n\tpacket_put_char(SSH_GSS_OIDTYPE);\n\tpacket_put_char(gss_supported->elements[mech].length);\n\tpacket_put_raw(gss_supported->elements[mech].elements,\n\t gss_supported->elements[mech].length);\n\n\tpacket_send();\n\n\tdispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);\n\tdispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);\n\tdispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);\n\tdispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);\n\n\tmech++; /* Move along to next candidate */\n\n\treturn 1;\n}\n\nstatic OM_uint32\nprocess_gssapi_token(void *ctxt, gss_buffer_t recv_tok)\n{\n\tAuthctxt *authctxt = ctxt;\n\tGssctxt *gssctxt = authctxt->methoddata;\n\tgss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;\n\tgss_buffer_desc mic = GSS_C_EMPTY_BUFFER;\n\tgss_buffer_desc gssbuf;\n\tOM_uint32 status, ms, flags;\n\tBuffer b;\n\n\tstatus = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,\n\t recv_tok, &send_tok, &flags);\n\n\tif (send_tok.length > 0) {\n\t\tif (GSS_ERROR(status))\n\t\t\tpacket_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);\n\t\telse\n\t\t\tpacket_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);\n\n\t\tpacket_put_string(send_tok.value, send_tok.length);\n\t\tpacket_send();\n\t\tgss_release_buffer(&ms, &send_tok);\n\t}\n\n\tif (status == GSS_S_COMPLETE) {\n\t\t/* send either complete or MIC, depending on mechanism */\n\t\tif (!(flags & GSS_C_INTEG_FLAG)) {\n\t\t\tpacket_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);\n\t\t\tpacket_send();\n\t\t} else {\n\t\t\tssh_gssapi_buildmic(&b, authctxt->server_user,\n\t\t\t authctxt->service, \"gssapi-with-mic\");\n\n\t\t\tgssbuf.value = buffer_ptr(&b);\n\t\t\tgssbuf.length = buffer_len(&b);\n\n\t\t\tstatus = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);\n\n\t\t\tif (!GSS_ERROR(status)) {\n\t\t\t\tpacket_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);\n\t\t\t\tpacket_put_string(mic.value, mic.length);\n\n\t\t\t\tpacket_send();\n\t\t\t}\n\n\t\t\tbuffer_free(&b);\n\t\t\tgss_release_buffer(&ms, &mic);\n\t\t}\n\t}\n\n\treturn status;\n}\n\n/* ARGSUSED */\nint\ninput_gssapi_response(int type, u_int32_t plen, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tGssctxt *gssctxt;\n\tint oidlen;\n\tchar *oidv;\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_gssapi_response: no authentication context\");\n\tgssctxt = authctxt->methoddata;\n\n\t/* Setup our OID */\n\toidv = packet_get_string(&oidlen);\n\n\tif (oidlen <= 2 ||\n\t oidv[0] != SSH_GSS_OIDTYPE ||\n\t oidv[1] != oidlen - 2) {\n\t\tfree(oidv);\n\t\tdebug(\"Badly encoded mechanism OID received\");\n\t\tuserauth(authctxt, NULL);\n\t\treturn 0;\n\t}\n\n\tif (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2))\n\t\tfatal(\"Server returned different OID than expected\");\n\n\tpacket_check_eom();\n\n\tfree(oidv);\n\n\tif (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) {\n\t\t/* Start again with next method on list */\n\t\tdebug(\"Trying to start again\");\n\t\tuserauth(authctxt, NULL);\n\t\treturn 0;\n\t}\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\ninput_gssapi_token(int type, u_int32_t plen, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tgss_buffer_desc recv_tok;\n\tOM_uint32 status;\n\tu_int slen;\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_gssapi_response: no authentication context\");\n\n\trecv_tok.value = packet_get_string(&slen);\n\trecv_tok.length = slen;\t/* safe typecast */\n\n\tpacket_check_eom();\n\n\tstatus = process_gssapi_token(ctxt, &recv_tok);\n\n\tfree(recv_tok.value);\n\n\tif (GSS_ERROR(status)) {\n\t\t/* Start again with the next method in the list */\n\t\tuserauth(authctxt, NULL);\n\t\treturn 0;\n\t}\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\ninput_gssapi_errtok(int type, u_int32_t plen, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tGssctxt *gssctxt;\n\tgss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;\n\tgss_buffer_desc recv_tok;\n\tOM_uint32 ms;\n\tu_int len;\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_gssapi_response: no authentication context\");\n\tgssctxt = authctxt->methoddata;\n\n\trecv_tok.value = packet_get_string(&len);\n\trecv_tok.length = len;\n\n\tpacket_check_eom();\n\n\t/* Stick it into GSSAPI and see what it says */\n\t(void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,\n\t &recv_tok, &send_tok, NULL);\n\n\tfree(recv_tok.value);\n\tgss_release_buffer(&ms, &send_tok);\n\n\t/* Server will be returning a failed packet after this one */\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\ninput_gssapi_error(int type, u_int32_t plen, void *ctxt)\n{\n\tchar *msg;\n\tchar *lang;\n\n\t/* maj */(void)packet_get_int();\n\t/* min */(void)packet_get_int();\n\tmsg=packet_get_string(NULL);\n\tlang=packet_get_string(NULL);\n\n\tpacket_check_eom();\n\n\tdebug(\"Server GSSAPI Error:\\n%s\", msg);\n\tfree(msg);\n\tfree(lang);\n\treturn 0;\n}\n#endif /* GSSAPI */\n\nint\nuserauth_none(Authctxt *authctxt)\n{\n\t/* initial userauth request */\n\tpacket_start(SSH2_MSG_USERAUTH_REQUEST);\n\tpacket_put_cstring(authctxt->server_user);\n\tpacket_put_cstring(authctxt->service);\n\tpacket_put_cstring(authctxt->method->name);\n\tpacket_send();\n\treturn 1;\n}\n\nint\nuserauth_passwd(Authctxt *authctxt)\n{\n\tstatic int attempt = 0;\n\tchar prompt[150];\n\tchar *password;\n\tconst char *host = options.host_key_alias ? options.host_key_alias :\n\t authctxt->host;\n\n\tif (attempt++ >= options.number_of_password_prompts)\n\t\treturn 0;\n\n\tif (attempt != 1)\n\t\terror(\"Permission denied, please try again.\");\n\n\tsnprintf(prompt, sizeof(prompt), \"%.30s@%.128s's password: \",\n\t authctxt->server_user, host);\n\tpassword = read_passphrase(prompt, 0);\n\tpacket_start(SSH2_MSG_USERAUTH_REQUEST);\n\tpacket_put_cstring(authctxt->server_user);\n\tpacket_put_cstring(authctxt->service);\n\tpacket_put_cstring(authctxt->method->name);\n\tpacket_put_char(0);\n\tpacket_put_cstring(password);\n\texplicit_bzero(password, strlen(password));\n\tfree(password);\n\tpacket_add_padding(64);\n\tpacket_send();\n\n\tdispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,\n\t &input_userauth_passwd_changereq);\n\n\treturn 1;\n}\n\n/*\n * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST\n */\n/* ARGSUSED */\nint\ninput_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tchar *info, *lang, *password = NULL, *retype = NULL;\n\tchar prompt[150];\n\tconst char *host;\n\n\tdebug2(\"input_userauth_passwd_changereq\");\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_userauth_passwd_changereq: \"\n\t\t \"no authentication context\");\n\thost = options.host_key_alias ? options.host_key_alias : authctxt->host;\n\n\tinfo = packet_get_string(NULL);\n\tlang = packet_get_string(NULL);\n\tif (strlen(info) > 0)\n\t\tlogit(\"%s\", info);\n\tfree(info);\n\tfree(lang);\n\tpacket_start(SSH2_MSG_USERAUTH_REQUEST);\n\tpacket_put_cstring(authctxt->server_user);\n\tpacket_put_cstring(authctxt->service);\n\tpacket_put_cstring(authctxt->method->name);\n\tpacket_put_char(1);\t\t\t/* additional info */\n\tsnprintf(prompt, sizeof(prompt),\n\t \"Enter %.30s@%.128s's old password: \",\n\t authctxt->server_user, host);\n\tpassword = read_passphrase(prompt, 0);\n\tpacket_put_cstring(password);\n\texplicit_bzero(password, strlen(password));\n\tfree(password);\n\tpassword = NULL;\n\twhile (password == NULL) {\n\t\tsnprintf(prompt, sizeof(prompt),\n\t\t \"Enter %.30s@%.128s's new password: \",\n\t\t authctxt->server_user, host);\n\t\tpassword = read_passphrase(prompt, RP_ALLOW_EOF);\n\t\tif (password == NULL) {\n\t\t\t/* bail out */\n\t\t\treturn 0;\n\t\t}\n\t\tsnprintf(prompt, sizeof(prompt),\n\t\t \"Retype %.30s@%.128s's new password: \",\n\t\t authctxt->server_user, host);\n\t\tretype = read_passphrase(prompt, 0);\n\t\tif (strcmp(password, retype) != 0) {\n\t\t\texplicit_bzero(password, strlen(password));\n\t\t\tfree(password);\n\t\t\tlogit(\"Mismatch; try again, EOF to quit.\");\n\t\t\tpassword = NULL;\n\t\t}\n\t\texplicit_bzero(retype, strlen(retype));\n\t\tfree(retype);\n\t}\n\tpacket_put_cstring(password);\n\texplicit_bzero(password, strlen(password));\n\tfree(password);\n\tpacket_add_padding(64);\n\tpacket_send();\n\n\tdispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,\n\t &input_userauth_passwd_changereq);\n\treturn 0;\n}\n\nstatic const char *\nkey_sign_encode(const struct sshkey *key)\n{\n\tstruct ssh *ssh = active_state;\n\n\tif (key->type == KEY_RSA) {\n\t\tswitch (ssh->kex->rsa_sha2) {\n\t\tcase 256:\n\t\t\treturn \"rsa-sha2-256\";\n\t\tcase 512:\n\t\t\treturn \"rsa-sha2-512\";\n\t\t}\n\t}\n\treturn key_ssh_name(key);\n}\n\nstatic int\nidentity_sign(struct identity *id, u_char **sigp, size_t *lenp,\n const u_char *data, size_t datalen, u_int compat)\n{\n\tKey *prv;\n\tint ret;\n\n\t/* the agent supports this key */\n\tif (id->key != NULL && id->agent_fd != -1)\n\t\treturn ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,\n\t\t data, datalen, key_sign_encode(id->key), compat);\n\n\t/*\n\t * we have already loaded the private key or\n\t * the private key is stored in external hardware\n\t */\n\tif (id->key != NULL &&\n\t (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)))\n\t\treturn (sshkey_sign(id->key, sigp, lenp, data, datalen,\n\t\t key_sign_encode(id->key), compat));\n\n\t/* load the private key from the file */\n\tif ((prv = load_identity_file(id)) == NULL)\n\t\treturn SSH_ERR_KEY_NOT_FOUND;\n\tret = sshkey_sign(prv, sigp, lenp, data, datalen,\n\t key_sign_encode(prv), compat);\n\tsshkey_free(prv);\n\treturn (ret);\n}\n\nstatic int\nid_filename_matches(Identity *id, Identity *private_id)\n{\n\tconst char *suffixes[] = { \".pub\", \"-cert.pub\", NULL };\n\tsize_t len = strlen(id->filename), plen = strlen(private_id->filename);\n\tsize_t i, slen;\n\n\tif (strcmp(id->filename, private_id->filename) == 0)\n\t\treturn 1;\n\tfor (i = 0; suffixes[i]; i++) {\n\t\tslen = strlen(suffixes[i]);\n\t\tif (len > slen && plen == len - slen &&\n\t\t strcmp(id->filename + (len - slen), suffixes[i]) == 0 &&\n\t\t memcmp(id->filename, private_id->filename, plen) == 0)\n\t\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nstatic int\nsign_and_send_pubkey(Authctxt *authctxt, Identity *id)\n{\n\tBuffer b;\n\tIdentity *private_id;\n\tu_char *blob, *signature;\n\tsize_t slen;\n\tu_int bloblen, skip = 0;\n\tint matched, ret = -1, have_sig = 1;\n\tchar *fp;\n\n\tif ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,\n\t SSH_FP_DEFAULT)) == NULL)\n\t\treturn 0;\n\tdebug3(\"%s: %s %s\", __func__, key_type(id->key), fp);\n\tfree(fp);\n\n\tif (key_to_blob(id->key, &blob, &bloblen) == 0) {\n\t\t/* we cannot handle this key */\n\t\tdebug3(\"sign_and_send_pubkey: cannot handle key\");\n\t\treturn 0;\n\t}\n\t/* data to be signed */\n\tbuffer_init(&b);\n\tif (datafellows & SSH_OLD_SESSIONID) {\n\t\tbuffer_append(&b, session_id2, session_id2_len);\n\t\tskip = session_id2_len;\n\t} else {\n\t\tbuffer_put_string(&b, session_id2, session_id2_len);\n\t\tskip = buffer_len(&b);\n\t}\n\tbuffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);\n\tbuffer_put_cstring(&b, authctxt->server_user);\n\tbuffer_put_cstring(&b,\n\t datafellows & SSH_BUG_PKSERVICE ?\n\t \"ssh-userauth\" :\n\t authctxt->service);\n\tif (datafellows & SSH_BUG_PKAUTH) {\n\t\tbuffer_put_char(&b, have_sig);\n\t} else {\n\t\tbuffer_put_cstring(&b, authctxt->method->name);\n\t\tbuffer_put_char(&b, have_sig);\n\t\tbuffer_put_cstring(&b, key_sign_encode(id->key));\n\t}\n\tbuffer_put_string(&b, blob, bloblen);\n\n\t/*\n\t * If the key is an certificate, try to find a matching private key\n\t * and use it to complete the signature.\n\t * If no such private key exists, fall back to trying the certificate\n\t * key itself in case it has a private half already loaded.\n\t */\n\tif (key_is_cert(id->key)) {\n\t\tmatched = 0;\n\t\tTAILQ_FOREACH(private_id, &authctxt->keys, next) {\n\t\t\tif (sshkey_equal_public(id->key, private_id->key) &&\n\t\t\t id->key->type != private_id->key->type) {\n\t\t\t\tid = private_id;\n\t\t\t\tmatched = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t/*\n\t\t * Exact key matches are preferred, but also allow\n\t\t * filename matches for non-PKCS#11/agent keys that\n\t\t * didn't load public keys. This supports the case\n\t\t * of keeping just a private key file and public\n\t\t * certificate on disk.\n\t\t */\n\t\tif (!matched && !id->isprivate && id->agent_fd == -1 &&\n\t\t (id->key->flags & SSHKEY_FLAG_EXT) == 0) {\n\t\t\tTAILQ_FOREACH(private_id, &authctxt->keys, next) {\n\t\t\t\tif (private_id->key == NULL &&\n\t\t\t\t id_filename_matches(id, private_id)) {\n\t\t\t\t\tid = private_id;\n\t\t\t\t\tmatched = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (matched) {\n\t\t\tdebug2(\"%s: using private key \\\"%s\\\"%s for \"\n\t\t\t \"certificate\", __func__, id->filename,\n\t\t\t id->agent_fd != -1 ? \" from agent\" : \"\");\n\t\t} else {\n\t\t\tdebug(\"%s: no separate private key for certificate \"\n\t\t\t \"\\\"%s\\\"\", __func__, id->filename);\n\t\t}\n\t}\n\n\t/* generate signature */\n\tret = identity_sign(id, &signature, &slen,\n\t buffer_ptr(&b), buffer_len(&b), datafellows);\n\tif (ret != 0) {\n\t\tif (ret != SSH_ERR_KEY_NOT_FOUND)\n\t\t\terror(\"%s: signing failed: %s\", __func__, ssh_err(ret));\n\t\tfree(blob);\n\t\tbuffer_free(&b);\n\t\treturn 0;\n\t}\n#ifdef DEBUG_PK\n\tbuffer_dump(&b);\n#endif\n\tif (datafellows & SSH_BUG_PKSERVICE) {\n\t\tbuffer_clear(&b);\n\t\tbuffer_append(&b, session_id2, session_id2_len);\n\t\tskip = session_id2_len;\n\t\tbuffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);\n\t\tbuffer_put_cstring(&b, authctxt->server_user);\n\t\tbuffer_put_cstring(&b, authctxt->service);\n\t\tbuffer_put_cstring(&b, authctxt->method->name);\n\t\tbuffer_put_char(&b, have_sig);\n\t\tif (!(datafellows & SSH_BUG_PKAUTH))\n\t\t\tbuffer_put_cstring(&b, key_ssh_name(id->key));\n\t\tbuffer_put_string(&b, blob, bloblen);\n\t}\n\tfree(blob);\n\n\t/* append signature */\n\tbuffer_put_string(&b, signature, slen);\n\tfree(signature);\n\n\t/* skip session id and packet type */\n\tif (buffer_len(&b) < skip + 1)\n\t\tfatal(\"userauth_pubkey: internal error\");\n\tbuffer_consume(&b, skip + 1);\n\n\t/* put remaining data from buffer into packet */\n\tpacket_start(SSH2_MSG_USERAUTH_REQUEST);\n\tpacket_put_raw(buffer_ptr(&b), buffer_len(&b));\n\tbuffer_free(&b);\n\tpacket_send();\n\n\treturn 1;\n}\n\nstatic int\nsend_pubkey_test(Authctxt *authctxt, Identity *id)\n{\n\tu_char *blob;\n\tu_int bloblen, have_sig = 0;\n\n\tdebug3(\"send_pubkey_test\");\n\n\tif (key_to_blob(id->key, &blob, &bloblen) == 0) {\n\t\t/* we cannot handle this key */\n\t\tdebug3(\"send_pubkey_test: cannot handle key\");\n\t\treturn 0;\n\t}\n\t/* register callback for USERAUTH_PK_OK message */\n\tdispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);\n\n\tpacket_start(SSH2_MSG_USERAUTH_REQUEST);\n\tpacket_put_cstring(authctxt->server_user);\n\tpacket_put_cstring(authctxt->service);\n\tpacket_put_cstring(authctxt->method->name);\n\tpacket_put_char(have_sig);\n\tif (!(datafellows & SSH_BUG_PKAUTH))\n\t\tpacket_put_cstring(key_sign_encode(id->key));\n\tpacket_put_string(blob, bloblen);\n\tfree(blob);\n\tpacket_send();\n\treturn 1;\n}\n\nstatic Key *\nload_identity_file(Identity *id)\n{\n\tKey *private = NULL;\n\tchar prompt[300], *passphrase, *comment;\n\tint r, perm_ok = 0, quit = 0, i;\n\tstruct stat st;\n\n\tif (stat(id->filename, &st) < 0) {\n\t\t(id->userprovided ? logit : debug3)(\"no such identity: %s: %s\",\n\t\t id->filename, strerror(errno));\n\t\treturn NULL;\n\t}\n\tsnprintf(prompt, sizeof prompt,\n\t \"Enter passphrase for key '%.100s': \", id->filename);\n\tfor (i = 0; i <= options.number_of_password_prompts; i++) {\n\t\tif (i == 0)\n\t\t\tpassphrase = \"\";\n\t\telse {\n\t\t\tpassphrase = read_passphrase(prompt, 0);\n\t\t\tif (*passphrase == '\\0') {\n\t\t\t\tdebug2(\"no passphrase given, try next key\");\n\t\t\t\tfree(passphrase);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tswitch ((r = sshkey_load_private_type(KEY_UNSPEC, id->filename,\n\t\t passphrase, &private, &comment, &perm_ok))) {\n\t\tcase 0:\n\t\t\tbreak;\n\t\tcase SSH_ERR_KEY_WRONG_PASSPHRASE:\n\t\t\tif (options.batch_mode) {\n\t\t\t\tquit = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i != 0)\n\t\t\t\tdebug2(\"bad passphrase given, try again...\");\n\t\t\tbreak;\n\t\tcase SSH_ERR_SYSTEM_ERROR:\n\t\t\tif (errno == ENOENT) {\n\t\t\t\tdebug2(\"Load key \\\"%s\\\": %s\",\n\t\t\t\t id->filename, ssh_err(r));\n\t\t\t\tquit = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* FALLTHROUGH */\n\t\tdefault:\n\t\t\terror(\"Load key \\\"%s\\\": %s\", id->filename, ssh_err(r));\n\t\t\tquit = 1;\n\t\t\tbreak;\n\t\t}\n\t\tif (!quit && private != NULL && id->agent_fd == -1 &&\n\t\t !(id->key && id->isprivate))\n\t\t\tmaybe_add_key_to_agent(id->filename, private, comment,\n\t\t\t passphrase);\n\t\tif (i > 0) {\n\t\t\texplicit_bzero(passphrase, strlen(passphrase));\n\t\t\tfree(passphrase);\n\t\t}\n\t\tfree(comment);\n\t\tif (private != NULL || quit)\n\t\t\tbreak;\n\t}\n\treturn private;\n}\n\n/*\n * try keys in the following order:\n * \t1. certificates listed in the config file\n * \t2. other input certificates\n *\t3. agent keys that are found in the config file\n *\t4. other agent keys\n *\t5. keys that are only listed in the config file\n */\nstatic void\npubkey_prepare(Authctxt *authctxt)\n{\n\tstruct identity *id, *id2, *tmp;\n\tstruct idlist agent, files, *preferred;\n\tstruct sshkey *key;\n\tint agent_fd = -1, i, r, found;\n\tsize_t j;\n\tstruct ssh_identitylist *idlist;\n\n\tTAILQ_INIT(&agent);\t/* keys from the agent */\n\tTAILQ_INIT(&files);\t/* keys from the config file */\n\tpreferred = &authctxt->keys;\n\tTAILQ_INIT(preferred);\t/* preferred order of keys */\n\n\t/* list of keys stored in the filesystem and PKCS#11 */\n\tfor (i = 0; i < options.num_identity_files; i++) {\n\t\tkey = options.identity_keys[i];\n\t\tif (key && key->type == KEY_RSA1)\n\t\t\tcontinue;\n\t\tif (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER)\n\t\t\tcontinue;\n\t\toptions.identity_keys[i] = NULL;\n\t\tid = xcalloc(1, sizeof(*id));\n\t\tid->agent_fd = -1;\n\t\tid->key = key;\n\t\tid->filename = xstrdup(options.identity_files[i]);\n\t\tid->userprovided = options.identity_file_userprovided[i];\n\t\tTAILQ_INSERT_TAIL(&files, id, next);\n\t}\n\t/* list of certificates specified by user */\n\tfor (i = 0; i < options.num_certificate_files; i++) {\n\t\tkey = options.certificates[i];\n\t\tif (!key_is_cert(key) || key->cert == NULL ||\n\t\t key->cert->type != SSH2_CERT_TYPE_USER)\n\t\t\tcontinue;\n\t\tid = xcalloc(1, sizeof(*id));\n\t\tid->agent_fd = -1;\n\t\tid->key = key;\n\t\tid->filename = xstrdup(options.certificate_files[i]);\n\t\tid->userprovided = options.certificate_file_userprovided[i];\n\t\tTAILQ_INSERT_TAIL(preferred, id, next);\n\t}\n\t/* list of keys supported by the agent */\n\tif ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {\n\t\tif (r != SSH_ERR_AGENT_NOT_PRESENT)\n\t\t\tdebug(\"%s: ssh_get_authentication_socket: %s\",\n\t\t\t __func__, ssh_err(r));\n\t} else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) {\n\t\tif (r != SSH_ERR_AGENT_NO_IDENTITIES)\n\t\t\tdebug(\"%s: ssh_fetch_identitylist: %s\",\n\t\t\t __func__, ssh_err(r));\n\t\tclose(agent_fd);\n\t} else {\n\t\tfor (j = 0; j < idlist->nkeys; j++) {\n\t\t\tfound = 0;\n\t\t\tTAILQ_FOREACH(id, &files, next) {\n\t\t\t\t/*\n\t\t\t\t * agent keys from the config file are\n\t\t\t\t * preferred\n\t\t\t\t */\n\t\t\t\tif (sshkey_equal(idlist->keys[j], id->key)) {\n\t\t\t\t\tTAILQ_REMOVE(&files, id, next);\n\t\t\t\t\tTAILQ_INSERT_TAIL(preferred, id, next);\n\t\t\t\t\tid->agent_fd = agent_fd;\n\t\t\t\t\tfound = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found && !options.identities_only) {\n\t\t\t\tid = xcalloc(1, sizeof(*id));\n\t\t\t\t/* XXX \"steals\" key/comment from idlist */\n\t\t\t\tid->key = idlist->keys[j];\n\t\t\t\tid->filename = idlist->comments[j];\n\t\t\t\tidlist->keys[j] = NULL;\n\t\t\t\tidlist->comments[j] = NULL;\n\t\t\t\tid->agent_fd = agent_fd;\n\t\t\t\tTAILQ_INSERT_TAIL(&agent, id, next);\n\t\t\t}\n\t\t}\n\t\tssh_free_identitylist(idlist);\n\t\t/* append remaining agent keys */\n\t\tfor (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {\n\t\t\tTAILQ_REMOVE(&agent, id, next);\n\t\t\tTAILQ_INSERT_TAIL(preferred, id, next);\n\t\t}\n\t\tauthctxt->agent_fd = agent_fd;\n\t}\n\t/* Prefer PKCS11 keys that are explicitly listed */\n\tTAILQ_FOREACH_SAFE(id, &files, next, tmp) {\n\t\tif (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0)\n\t\t\tcontinue;\n\t\tfound = 0;\n\t\tTAILQ_FOREACH(id2, &files, next) {\n\t\t\tif (id2->key == NULL ||\n\t\t\t (id2->key->flags & SSHKEY_FLAG_EXT) == 0)\n\t\t\t\tcontinue;\n\t\t\tif (sshkey_equal(id->key, id2->key)) {\n\t\t\t\tTAILQ_REMOVE(&files, id, next);\n\t\t\t\tTAILQ_INSERT_TAIL(preferred, id, next);\n\t\t\t\tfound = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t/* If IdentitiesOnly set and key not found then don't use it */\n\t\tif (!found && options.identities_only) {\n\t\t\tTAILQ_REMOVE(&files, id, next);\n\t\t\texplicit_bzero(id, sizeof(*id));\n\t\t\tfree(id);\n\t\t}\n\t}\n\t/* append remaining keys from the config file */\n\tfor (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {\n\t\tTAILQ_REMOVE(&files, id, next);\n\t\tTAILQ_INSERT_TAIL(preferred, id, next);\n\t}\n\t/* finally, filter by PubkeyAcceptedKeyTypes */\n\tTAILQ_FOREACH_SAFE(id, preferred, next, id2) {\n\t\tif (id->key != NULL &&\n\t\t match_pattern_list(sshkey_ssh_name(id->key),\n\t\t options.pubkey_key_types, 0) != 1) {\n\t\t\tdebug(\"Skipping %s key %s - \"\n\t\t\t \"not in PubkeyAcceptedKeyTypes\",\n\t\t\t sshkey_ssh_name(id->key), id->filename);\n\t\t\tTAILQ_REMOVE(preferred, id, next);\n\t\t\tsshkey_free(id->key);\n\t\t\tfree(id->filename);\n\t\t\tmemset(id, 0, sizeof(*id));\n\t\t\tcontinue;\n\t\t}\n\t\tdebug2(\"key: %s (%p)%s%s\", id->filename, id->key,\n\t\t id->userprovided ? \", explicit\" : \"\",\n\t\t id->agent_fd != -1 ? \", agent\" : \"\");\n\t}\n}\n\nstatic void\npubkey_cleanup(Authctxt *authctxt)\n{\n\tIdentity *id;\n\n\tif (authctxt->agent_fd != -1)\n\t\tssh_close_authentication_socket(authctxt->agent_fd);\n\tfor (id = TAILQ_FIRST(&authctxt->keys); id;\n\t id = TAILQ_FIRST(&authctxt->keys)) {\n\t\tTAILQ_REMOVE(&authctxt->keys, id, next);\n\t\tsshkey_free(id->key);\n\t\tfree(id->filename);\n\t\tfree(id);\n\t}\n}\n\nstatic void\npubkey_reset(Authctxt *authctxt)\n{\n\tIdentity *id;\n\n\tTAILQ_FOREACH(id, &authctxt->keys, next)\n\t\tid->tried = 0;\n}\n\nstatic int\ntry_identity(Identity *id)\n{\n\tif (!id->key)\n\t\treturn (0);\n\tif (key_type_plain(id->key->type) == KEY_RSA &&\n\t (datafellows & SSH_BUG_RSASIGMD5) != 0) {\n\t\tdebug(\"Skipped %s key %s for RSA/MD5 server\",\n\t\t key_type(id->key), id->filename);\n\t\treturn (0);\n\t}\n\treturn (id->key->type != KEY_RSA1);\n}\n\nint\nuserauth_pubkey(Authctxt *authctxt)\n{\n\tIdentity *id;\n\tint sent = 0;\n\n\twhile ((id = TAILQ_FIRST(&authctxt->keys))) {\n\t\tif (id->tried++)\n\t\t\treturn (0);\n\t\t/* move key to the end of the queue */\n\t\tTAILQ_REMOVE(&authctxt->keys, id, next);\n\t\tTAILQ_INSERT_TAIL(&authctxt->keys, id, next);\n\t\t/*\n\t\t * send a test message if we have the public key. for\n\t\t * encrypted keys we cannot do this and have to load the\n\t\t * private key instead\n\t\t */\n\t\tif (id->key != NULL) {\n\t\t\tif (try_identity(id)) {\n\t\t\t\tdebug(\"Offering %s public key: %s\",\n\t\t\t\t key_type(id->key), id->filename);\n\t\t\t\tsent = send_pubkey_test(authctxt, id);\n\t\t\t}\n\t\t} else {\n\t\t\tdebug(\"Trying private key: %s\", id->filename);\n\t\t\tid->key = load_identity_file(id);\n\t\t\tif (id->key != NULL) {\n\t\t\t\tif (try_identity(id)) {\n\t\t\t\t\tid->isprivate = 1;\n\t\t\t\t\tsent = sign_and_send_pubkey(\n\t\t\t\t\t authctxt, id);\n\t\t\t\t}\n\t\t\t\tkey_free(id->key);\n\t\t\t\tid->key = NULL;\n\t\t\t\tid->isprivate = 0;\n\t\t\t}\n\t\t}\n\t\tif (sent)\n\t\t\treturn (sent);\n\t}\n\treturn (0);\n}\n\n/*\n * Send userauth request message specifying keyboard-interactive method.\n */\nint\nuserauth_kbdint(Authctxt *authctxt)\n{\n\tstatic int attempt = 0;\n\n\tif (attempt++ >= options.number_of_password_prompts)\n\t\treturn 0;\n\t/* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */\n\tif (attempt > 1 && !authctxt->info_req_seen) {\n\t\tdebug3(\"userauth_kbdint: disable: no info_req_seen\");\n\t\tdispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);\n\t\treturn 0;\n\t}\n\n\tdebug2(\"userauth_kbdint\");\n\tpacket_start(SSH2_MSG_USERAUTH_REQUEST);\n\tpacket_put_cstring(authctxt->server_user);\n\tpacket_put_cstring(authctxt->service);\n\tpacket_put_cstring(authctxt->method->name);\n\tpacket_put_cstring(\"\");\t\t\t\t\t/* lang */\n\tpacket_put_cstring(options.kbd_interactive_devices ?\n\t options.kbd_interactive_devices : \"\");\n\tpacket_send();\n\n\tdispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);\n\treturn 1;\n}\n\n/*\n * parse INFO_REQUEST, prompt user and send INFO_RESPONSE\n */\nint\ninput_userauth_info_req(int type, u_int32_t seq, void *ctxt)\n{\n\tAuthctxt *authctxt = ctxt;\n\tchar *name, *inst, *lang, *prompt, *response;\n\tu_int num_prompts, i;\n\tint echo = 0;\n\n\tdebug2(\"input_userauth_info_req\");\n\n\tif (authctxt == NULL)\n\t\tfatal(\"input_userauth_info_req: no authentication context\");\n\n\tauthctxt->info_req_seen = 1;\n\n\tname = packet_get_string(NULL);\n\tinst = packet_get_string(NULL);\n\tlang = packet_get_string(NULL);\n\tif (strlen(name) > 0)\n\t\tlogit(\"%s\", name);\n\tif (strlen(inst) > 0)\n\t\tlogit(\"%s\", inst);\n\tfree(name);\n\tfree(inst);\n\tfree(lang);\n\n\tnum_prompts = packet_get_int();\n\t/*\n\t * Begin to build info response packet based on prompts requested.\n\t * We commit to providing the correct number of responses, so if\n\t * further on we run into a problem that prevents this, we have to\n\t * be sure and clean this up and send a correct error response.\n\t */\n\tpacket_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);\n\tpacket_put_int(num_prompts);\n\n\tdebug2(\"input_userauth_info_req: num_prompts %d\", num_prompts);\n\tfor (i = 0; i < num_prompts; i++) {\n\t\tprompt = packet_get_string(NULL);\n\t\techo = packet_get_char();\n\n\t\tresponse = read_passphrase(prompt, echo ? RP_ECHO : 0);\n\n\t\tpacket_put_cstring(response);\n\t\texplicit_bzero(response, strlen(response));\n\t\tfree(response);\n\t\tfree(prompt);\n\t}\n\tpacket_check_eom(); /* done with parsing incoming message. */\n\n\tpacket_add_padding(64);\n\tpacket_send();\n\treturn 0;\n}\n\nstatic int\nssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp,\n const u_char *data, size_t datalen)\n{\n\tstruct sshbuf *b;\n\tstruct stat st;\n\tpid_t pid;\n\tint i, r, to[2], from[2], status, sock = packet_get_connection_in();\n\tu_char rversion = 0, version = 2;\n\tvoid (*osigchld)(int);\n\n\t*sigp = NULL;\n\t*lenp = 0;\n\n\tif (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {\n\t\terror(\"%s: not installed: %s\", __func__, strerror(errno));\n\t\treturn -1;\n\t}\n\tif (fflush(stdout) != 0) {\n\t\terror(\"%s: fflush: %s\", __func__, strerror(errno));\n\t\treturn -1;\n\t}\n\tif (pipe(to) < 0) {\n\t\terror(\"%s: pipe: %s\", __func__, strerror(errno));\n\t\treturn -1;\n\t}\n\tif (pipe(from) < 0) {\n\t\terror(\"%s: pipe: %s\", __func__, strerror(errno));\n\t\treturn -1;\n\t}\n\tif ((pid = fork()) < 0) {\n\t\terror(\"%s: fork: %s\", __func__, strerror(errno));\n\t\treturn -1;\n\t}\n\tosigchld = signal(SIGCHLD, SIG_DFL);\n\tif (pid == 0) {\n\t\t/* keep the socket on exec */\n\t\tfcntl(sock, F_SETFD, 0);\n\t\tpermanently_drop_suid(getuid());\n\t\tclose(from[0]);\n\t\tif (dup2(from[1], STDOUT_FILENO) < 0)\n\t\t\tfatal(\"%s: dup2: %s\", __func__, strerror(errno));\n\t\tclose(to[1]);\n\t\tif (dup2(to[0], STDIN_FILENO) < 0)\n\t\t\tfatal(\"%s: dup2: %s\", __func__, strerror(errno));\n\t\tclose(from[1]);\n\t\tclose(to[0]);\n\t\t/* Close everything but stdio and the socket */\n\t\tfor (i = STDERR_FILENO + 1; i < sock; i++)\n\t\t\tclose(i);\n\t\tclosefrom(sock + 1);\n\t\tdebug3(\"%s: [child] pid=%ld, exec %s\",\n\t\t __func__, (long)getpid(), _PATH_SSH_KEY_SIGN);\n\t\texecl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *)NULL);\n\t\tfatal(\"%s: exec(%s): %s\", __func__, _PATH_SSH_KEY_SIGN,\n\t\t strerror(errno));\n\t}\n\tclose(from[1]);\n\tclose(to[0]);\n\n\tif ((b = sshbuf_new()) == NULL)\n\t\tfatal(\"%s: sshbuf_new failed\", __func__);\n\t/* send # of sock, data to be signed */\n\tif ((r = sshbuf_put_u32(b, sock)) != 0 ||\n\t (r = sshbuf_put_string(b, data, datalen)) != 0)\n\t\tfatal(\"%s: buffer error: %s\", __func__, ssh_err(r));\n\tif (ssh_msg_send(to[1], version, b) == -1)\n\t\tfatal(\"%s: couldn't send request\", __func__);\n\tsshbuf_reset(b);\n\tr = ssh_msg_recv(from[0], b);\n\tclose(from[0]);\n\tclose(to[1]);\n\tif (r < 0) {\n\t\terror(\"%s: no reply\", __func__);\n\t\tgoto fail;\n\t}\n\n\terrno = 0;\n\twhile (waitpid(pid, &status, 0) < 0) {\n\t\tif (errno != EINTR) {\n\t\t\terror(\"%s: waitpid %ld: %s\",\n\t\t\t __func__, (long)pid, strerror(errno));\n\t\t\tgoto fail;\n\t\t}\n\t}\n\tif (!WIFEXITED(status)) {\n\t\terror(\"%s: exited abnormally\", __func__);\n\t\tgoto fail;\n\t}\n\tif (WEXITSTATUS(status) != 0) {\n\t\terror(\"%s: exited with status %d\",\n\t\t __func__, WEXITSTATUS(status));\n\t\tgoto fail;\n\t}\n\tif ((r = sshbuf_get_u8(b, &rversion)) != 0) {\n\t\terror(\"%s: buffer error: %s\", __func__, ssh_err(r));\n\t\tgoto fail;\n\t}\n\tif (rversion != version) {\n\t\terror(\"%s: bad version\", __func__);\n\t\tgoto fail;\n\t}\n\tif ((r = sshbuf_get_string(b, sigp, lenp)) != 0) {\n\t\terror(\"%s: buffer error: %s\", __func__, ssh_err(r));\n fail:\n\t\tsignal(SIGCHLD, osigchld);\n\t\tsshbuf_free(b);\n\t\treturn -1;\n\t}\n\tsignal(SIGCHLD, osigchld);\n\tsshbuf_free(b);\n\n\treturn 0;\n}\n\nint\nuserauth_hostbased(Authctxt *authctxt)\n{\n\tstruct ssh *ssh = active_state;\n\tstruct sshkey *private = NULL;\n\tstruct sshbuf *b = NULL;\n\tconst char *service;\n\tu_char *sig = NULL, *keyblob = NULL;\n\tchar *fp = NULL, *chost = NULL, *lname = NULL;\n\tsize_t siglen = 0, keylen = 0;\n\tint i, r, success = 0;\n\n\tif (authctxt->ktypes == NULL) {\n\t\tauthctxt->oktypes = xstrdup(options.hostbased_key_types);\n\t\tauthctxt->ktypes = authctxt->oktypes;\n\t}\n\n\t/*\n\t * Work through each listed type pattern in HostbasedKeyTypes,\n\t * trying each hostkey that matches the type in turn.\n\t */\n\tfor (;;) {\n\t\tif (authctxt->active_ktype == NULL)\n\t\t\tauthctxt->active_ktype = strsep(&authctxt->ktypes, \",\");\n\t\tif (authctxt->active_ktype == NULL ||\n\t\t *authctxt->active_ktype == '\\0')\n\t\t\tbreak;\n\t\tdebug3(\"%s: trying key type %s\", __func__,\n\t\t authctxt->active_ktype);\n\n\t\t/* check for a useful key */\n\t\tprivate = NULL;\n\t\tfor (i = 0; i < authctxt->sensitive->nkeys; i++) {\n\t\t\tif (authctxt->sensitive->keys[i] == NULL ||\n\t\t\t authctxt->sensitive->keys[i]->type == KEY_RSA1 ||\n\t\t\t authctxt->sensitive->keys[i]->type == KEY_UNSPEC)\n\t\t\t\tcontinue;\n\t\t\tif (match_pattern_list(\n\t\t\t sshkey_ssh_name(authctxt->sensitive->keys[i]),\n\t\t\t authctxt->active_ktype, 0) != 1)\n\t\t\t\tcontinue;\n\t\t\t/* we take and free the key */\n\t\t\tprivate = authctxt->sensitive->keys[i];\n\t\t\tauthctxt->sensitive->keys[i] = NULL;\n\t\t\tbreak;\n\t\t}\n\t\t/* Found one */\n\t\tif (private != NULL)\n\t\t\tbreak;\n\t\t/* No more keys of this type; advance */\n\t\tauthctxt->active_ktype = NULL;\n\t}\n\tif (private == NULL) {\n\t\tfree(authctxt->oktypes);\n\t\tauthctxt->oktypes = authctxt->ktypes = NULL;\n\t\tauthctxt->active_ktype = NULL;\n\t\tdebug(\"No more client hostkeys for hostbased authentication.\");\n\t\tgoto out;\n\t}\n\n\tif ((fp = sshkey_fingerprint(private, options.fingerprint_hash,\n\t SSH_FP_DEFAULT)) == NULL) {\n\t\terror(\"%s: sshkey_fingerprint failed\", __func__);\n\t\tgoto out;\n\t}\n\tdebug(\"%s: trying hostkey %s %s\",\n\t __func__, sshkey_ssh_name(private), fp);\n\n\t/* figure out a name for the client host */\n\tif ((lname = get_local_name(packet_get_connection_in())) == NULL) {\n\t\terror(\"%s: cannot get local ipaddr/name\", __func__);\n\t\tgoto out;\n\t}\n\n\t/* XXX sshbuf_put_stringf? */\n\txasprintf(&chost, \"%s.\", lname);\n\tdebug2(\"%s: chost %s\", __func__, chost);\n\n\tservice = datafellows & SSH_BUG_HBSERVICE ? \"ssh-userauth\" :\n\t authctxt->service;\n\n\t/* construct data */\n\tif ((b = sshbuf_new()) == NULL) {\n\t\terror(\"%s: sshbuf_new failed\", __func__);\n\t\tgoto out;\n\t}\n\tif ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) {\n\t\terror(\"%s: sshkey_to_blob: %s\", __func__, ssh_err(r));\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||\n\t (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||\n\t (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||\n\t (r = sshbuf_put_cstring(b, service)) != 0 ||\n\t (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 ||\n\t (r = sshbuf_put_cstring(b, key_ssh_name(private))) != 0 ||\n\t (r = sshbuf_put_string(b, keyblob, keylen)) != 0 ||\n\t (r = sshbuf_put_cstring(b, chost)) != 0 ||\n\t (r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) {\n\t\terror(\"%s: buffer error: %s\", __func__, ssh_err(r));\n\t\tgoto out;\n\t}\n\n#ifdef DEBUG_PK\n\tsshbuf_dump(b, stderr);\n#endif\n\tif (authctxt->sensitive->external_keysign)\n\t\tr = ssh_keysign(private, &sig, &siglen,\n\t\t sshbuf_ptr(b), sshbuf_len(b));\n\telse if ((r = sshkey_sign(private, &sig, &siglen,\n\t sshbuf_ptr(b), sshbuf_len(b), NULL, datafellows)) != 0)\n\t\tdebug(\"%s: sshkey_sign: %s\", __func__, ssh_err(r));\n\tif (r != 0) {\n\t\terror(\"sign using hostkey %s %s failed\",\n\t\t sshkey_ssh_name(private), fp);\n\t\tgoto out;\n\t}\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, key_ssh_name(private))) != 0 ||\n\t (r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, chost)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 ||\n\t (r = sshpkt_put_string(ssh, sig, siglen)) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0) {\n\t\terror(\"%s: packet error: %s\", __func__, ssh_err(r));\n\t\tgoto out;\n\t}\n\tsuccess = 1;\n\n out:\n\tif (sig != NULL) {\n\t\texplicit_bzero(sig, siglen);\n\t\tfree(sig);\n\t}\n\tfree(keyblob);\n\tfree(lname);\n\tfree(fp);\n\tfree(chost);\n\tsshkey_free(private);\n\tsshbuf_free(b);\n\n\treturn success;\n}\n\n/* find auth method */\n\n/*\n * given auth method name, if configurable options permit this method fill\n * in auth_ident field and return true, otherwise return false.\n */\nstatic int\nauthmethod_is_enabled(Authmethod *method)\n{\n\tif (method == NULL)\n\t\treturn 0;\n\t/* return false if options indicate this method is disabled */\n\tif (method->enabled == NULL || *method->enabled == 0)\n\t\treturn 0;\n\t/* return false if batch mode is enabled but method needs interactive mode */\n\tif (method->batch_flag != NULL && *method->batch_flag != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\nstatic Authmethod *\nauthmethod_lookup(const char *name)\n{\n\tAuthmethod *method = NULL;\n\tif (name != NULL)\n\t\tfor (method = authmethods; method->name != NULL; method++)\n\t\t\tif (strcmp(name, method->name) == 0)\n\t\t\t\treturn method;\n\tdebug2(\"Unrecognized authentication method name: %s\", name ? name : \"NULL\");\n\treturn NULL;\n}\n\n/* XXX internal state */\nstatic Authmethod *current = NULL;\nstatic char *supported = NULL;\nstatic char *preferred = NULL;\n\n/*\n * Given the authentication method list sent by the server, return the\n * next method we should try. If the server initially sends a nil list,\n * use a built-in default list.\n */\nstatic Authmethod *\nauthmethod_get(char *authlist)\n{\n\tchar *name = NULL;\n\tu_int next;\n\n\t/* Use a suitable default if we're passed a nil list. */\n\tif (authlist == NULL || strlen(authlist) == 0)\n\t\tauthlist = options.preferred_authentications;\n\n\tif (supported == NULL || strcmp(authlist, supported) != 0) {\n\t\tdebug3(\"start over, passed a different list %s\", authlist);\n\t\tfree(supported);\n\t\tsupported = xstrdup(authlist);\n\t\tpreferred = options.preferred_authentications;\n\t\tdebug3(\"preferred %s\", preferred);\n\t\tcurrent = NULL;\n\t} else if (current != NULL && authmethod_is_enabled(current))\n\t\treturn current;\n\n\tfor (;;) {\n\t\tif ((name = match_list(preferred, supported, &next)) == NULL) {\n\t\t\tdebug(\"No more authentication methods to try.\");\n\t\t\tcurrent = NULL;\n\t\t\treturn NULL;\n\t\t}\n\t\tpreferred += next;\n\t\tdebug3(\"authmethod_lookup %s\", name);\n\t\tdebug3(\"remaining preferred: %s\", preferred);\n\t\tif ((current = authmethod_lookup(name)) != NULL &&\n\t\t authmethod_is_enabled(current)) {\n\t\t\tdebug3(\"authmethod_is_enabled %s\", name);\n\t\t\tdebug(\"Next authentication method: %s\", name);\n\t\t\tfree(name);\n\t\t\treturn current;\n\t\t}\n\t\tfree(name);\n\t}\n}\n\nstatic char *\nauthmethods_get(void)\n{\n\tAuthmethod *method = NULL;\n\tBuffer b;\n\tchar *list;\n\n\tbuffer_init(&b);\n\tfor (method = authmethods; method->name != NULL; method++) {\n\t\tif (authmethod_is_enabled(method)) {\n\t\t\tif (buffer_len(&b) > 0)\n\t\t\t\tbuffer_append(&b, \",\", 1);\n\t\t\tbuffer_append(&b, method->name, strlen(method->name));\n\t\t}\n\t}\n\tif ((list = sshbuf_dup_string(&b)) == NULL)\n\t\tfatal(\"%s: sshbuf_dup_string failed\", __func__);\n\tbuffer_free(&b);\n\treturn list;\n}\n\n","/* $OpenBSD: mux.c,v 1.64 2017/01/21 11:32:04 guenther Exp $ */\n/*\n * Copyright (c) 2002-2008 Damien Miller \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/* ssh session multiplexing support */\n\n/*\n * TODO:\n * - Better signalling from master to slave, especially passing of\n * error messages\n * - Better fall-back from mux slave error to new connection.\n * - ExitOnForwardingFailure\n * - Maybe extension mechanisms for multi-X11/multi-agent forwarding\n * - Support ~^Z in mux slaves.\n * - Inspect or control sessions in master.\n * - If we ever support the \"signal\" channel request, send signals on\n * sessions in master.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef HAVE_PATHS_H\n#include \n#endif\n\n#ifdef HAVE_POLL_H\n#include \n#else\n# ifdef HAVE_SYS_POLL_H\n# include \n# endif\n#endif\n\n#ifdef HAVE_UTIL_H\n# include \n#endif\n\n#include \"openbsd-compat/sys-queue.h\"\n#include \"xmalloc.h\"\n#include \"log.h\"\n#include \"ssh.h\"\n#include \"ssh2.h\"\n#include \"pathnames.h\"\n#include \"misc.h\"\n#include \"match.h\"\n#include \"buffer.h\"\n#include \"channels.h\"\n#include \"msg.h\"\n#include \"packet.h\"\n#include \"monitor_fdpass.h\"\n#include \"sshpty.h\"\n#include \"key.h\"\n#include \"readconf.h\"\n#include \"clientloop.h\"\n#include \"ssherr.h\"\n\n/* from ssh.c */\nextern int tty_flag;\nextern Options options;\nextern int stdin_null_flag;\nextern char *host;\nextern int subsystem_flag;\nextern Buffer command;\nextern volatile sig_atomic_t quit_pending;\n\n/* Context for session open confirmation callback */\nstruct mux_session_confirm_ctx {\n\tu_int want_tty;\n\tu_int want_subsys;\n\tu_int want_x_fwd;\n\tu_int want_agent_fwd;\n\tBuffer cmd;\n\tchar *term;\n\tstruct termios tio;\n\tchar **env;\n\tu_int rid;\n};\n\n/* Context for stdio fwd open confirmation callback */\nstruct mux_stdio_confirm_ctx {\n\tu_int rid;\n};\n\n/* Context for global channel callback */\nstruct mux_channel_confirm_ctx {\n\tu_int cid;\t/* channel id */\n\tu_int rid;\t/* request id */\n\tint fid;\t/* forward id */\n};\n\n/* fd to control socket */\nint muxserver_sock = -1;\n\n/* client request id */\nu_int muxclient_request_id = 0;\n\n/* Multiplexing control command */\nu_int muxclient_command = 0;\n\n/* Set when signalled. */\nstatic volatile sig_atomic_t muxclient_terminate = 0;\n\n/* PID of multiplex server */\nstatic u_int muxserver_pid = 0;\n\nstatic Channel *mux_listener_channel = NULL;\n\nstruct mux_master_state {\n\tint hello_rcvd;\n};\n\n/* mux protocol messages */\n#define MUX_MSG_HELLO\t\t0x00000001\n#define MUX_C_NEW_SESSION\t0x10000002\n#define MUX_C_ALIVE_CHECK\t0x10000004\n#define MUX_C_TERMINATE\t\t0x10000005\n#define MUX_C_OPEN_FWD\t\t0x10000006\n#define MUX_C_CLOSE_FWD\t\t0x10000007\n#define MUX_C_NEW_STDIO_FWD\t0x10000008\n#define MUX_C_STOP_LISTENING\t0x10000009\n#define MUX_C_PROXY\t\t0x1000000f\n#define MUX_S_OK\t\t0x80000001\n#define MUX_S_PERMISSION_DENIED\t0x80000002\n#define MUX_S_FAILURE\t\t0x80000003\n#define MUX_S_EXIT_MESSAGE\t0x80000004\n#define MUX_S_ALIVE\t\t0x80000005\n#define MUX_S_SESSION_OPENED\t0x80000006\n#define MUX_S_REMOTE_PORT\t0x80000007\n#define MUX_S_TTY_ALLOC_FAIL\t0x80000008\n#define MUX_S_PROXY\t\t0x8000000f\n\n/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */\n#define MUX_FWD_LOCAL 1\n#define MUX_FWD_REMOTE 2\n#define MUX_FWD_DYNAMIC 3\n\nstatic void mux_session_confirm(int, int, void *);\nstatic void mux_stdio_confirm(int, int, void *);\n\nstatic int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *);\nstatic int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *);\n\nstatic const struct {\n\tu_int type;\n\tint (*handler)(u_int, Channel *, Buffer *, Buffer *);\n} mux_master_handlers[] = {\n\t{ MUX_MSG_HELLO, process_mux_master_hello },\n\t{ MUX_C_NEW_SESSION, process_mux_new_session },\n\t{ MUX_C_ALIVE_CHECK, process_mux_alive_check },\n\t{ MUX_C_TERMINATE, process_mux_terminate },\n\t{ MUX_C_OPEN_FWD, process_mux_open_fwd },\n\t{ MUX_C_CLOSE_FWD, process_mux_close_fwd },\n\t{ MUX_C_NEW_STDIO_FWD, process_mux_stdio_fwd },\n\t{ MUX_C_STOP_LISTENING, process_mux_stop_listening },\n\t{ MUX_C_PROXY, process_mux_proxy },\n\t{ 0, NULL }\n};\n\n/* Cleanup callback fired on closure of mux slave _session_ channel */\n/* ARGSUSED */\nstatic void\nmux_master_session_cleanup_cb(int cid, void *unused)\n{\n\tChannel *cc, *c = channel_by_id(cid);\n\n\tdebug3(\"%s: entering for channel %d\", __func__, cid);\n\tif (c == NULL)\n\t\tfatal(\"%s: channel_by_id(%i) == NULL\", __func__, cid);\n\tif (c->ctl_chan != -1) {\n\t\tif ((cc = channel_by_id(c->ctl_chan)) == NULL)\n\t\t\tfatal(\"%s: channel %d missing control channel %d\",\n\t\t\t __func__, c->self, c->ctl_chan);\n\t\tc->ctl_chan = -1;\n\t\tcc->remote_id = -1;\n\t\tchan_rcvd_oclose(cc);\n\t}\n\tchannel_cancel_cleanup(c->self);\n}\n\n/* Cleanup callback fired on closure of mux slave _control_ channel */\n/* ARGSUSED */\nstatic void\nmux_master_control_cleanup_cb(int cid, void *unused)\n{\n\tChannel *sc, *c = channel_by_id(cid);\n\n\tdebug3(\"%s: entering for channel %d\", __func__, cid);\n\tif (c == NULL)\n\t\tfatal(\"%s: channel_by_id(%i) == NULL\", __func__, cid);\n\tif (c->remote_id != -1) {\n\t\tif ((sc = channel_by_id(c->remote_id)) == NULL)\n\t\t\tfatal(\"%s: channel %d missing session channel %d\",\n\t\t\t __func__, c->self, c->remote_id);\n\t\tc->remote_id = -1;\n\t\tsc->ctl_chan = -1;\n\t\tif (sc->type != SSH_CHANNEL_OPEN &&\n\t\t sc->type != SSH_CHANNEL_OPENING) {\n\t\t\tdebug2(\"%s: channel %d: not open\", __func__, sc->self);\n\t\t\tchan_mark_dead(sc);\n\t\t} else {\n\t\t\tif (sc->istate == CHAN_INPUT_OPEN)\n\t\t\t\tchan_read_failed(sc);\n\t\t\tif (sc->ostate == CHAN_OUTPUT_OPEN)\n\t\t\t\tchan_write_failed(sc);\n\t\t}\n\t}\n\tchannel_cancel_cleanup(c->self);\n}\n\n/* Check mux client environment variables before passing them to mux master. */\nstatic int\nenv_permitted(char *env)\n{\n\tint i, ret;\n\tchar name[1024], *cp;\n\n\tif ((cp = strchr(env, '=')) == NULL || cp == env)\n\t\treturn 0;\n\tret = snprintf(name, sizeof(name), \"%.*s\", (int)(cp - env), env);\n\tif (ret <= 0 || (size_t)ret >= sizeof(name)) {\n\t\terror(\"env_permitted: name '%.100s...' too long\", env);\n\t\treturn 0;\n\t}\n\n\tfor (i = 0; i < options.num_send_env; i++)\n\t\tif (match_pattern(name, options.send_env[i]))\n\t\t\treturn 1;\n\n\treturn 0;\n}\n\n/* Mux master protocol message handlers */\n\nstatic int\nprocess_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tu_int ver;\n\tstruct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;\n\n\tif (state == NULL)\n\t\tfatal(\"%s: channel %d: c->mux_ctx == NULL\", __func__, c->self);\n\tif (state->hello_rcvd) {\n\t\terror(\"%s: HELLO received twice\", __func__);\n\t\treturn -1;\n\t}\n\tif (buffer_get_int_ret(&ver, m) != 0) {\n malf:\n\t\terror(\"%s: malformed message\", __func__);\n\t\treturn -1;\n\t}\n\tif (ver != SSHMUX_VER) {\n\t\terror(\"Unsupported multiplexing protocol version %d \"\n\t\t \"(expected %d)\", ver, SSHMUX_VER);\n\t\treturn -1;\n\t}\n\tdebug2(\"%s: channel %d slave version %u\", __func__, c->self, ver);\n\n\t/* No extensions are presently defined */\n\twhile (buffer_len(m) > 0) {\n\t\tchar *name = buffer_get_string_ret(m, NULL);\n\t\tchar *value = buffer_get_string_ret(m, NULL);\n\n\t\tif (name == NULL || value == NULL) {\n\t\t\tfree(name);\n\t\t\tfree(value);\n\t\t\tgoto malf;\n\t\t}\n\t\tdebug2(\"Unrecognised slave extension \\\"%s\\\"\", name);\n\t\tfree(name);\n\t\tfree(value);\n\t}\n\tstate->hello_rcvd = 1;\n\treturn 0;\n}\n\nstatic int\nprocess_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tChannel *nc;\n\tstruct mux_session_confirm_ctx *cctx;\n\tchar *reserved, *cmd, *cp;\n\tu_int i, j, len, env_len, escape_char, window, packetmax;\n\tint new_fd[3];\n\n\t/* Reply for SSHMUX_COMMAND_OPEN */\n\tcctx = xcalloc(1, sizeof(*cctx));\n\tcctx->term = NULL;\n\tcctx->rid = rid;\n\tcmd = reserved = NULL;\n\tcctx->env = NULL;\n\tenv_len = 0;\n\tif ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||\n\t buffer_get_int_ret(&cctx->want_tty, m) != 0 ||\n\t buffer_get_int_ret(&cctx->want_x_fwd, m) != 0 ||\n\t buffer_get_int_ret(&cctx->want_agent_fwd, m) != 0 ||\n\t buffer_get_int_ret(&cctx->want_subsys, m) != 0 ||\n\t buffer_get_int_ret(&escape_char, m) != 0 ||\n\t (cctx->term = buffer_get_string_ret(m, &len)) == NULL ||\n\t (cmd = buffer_get_string_ret(m, &len)) == NULL) {\n malf:\n\t\tfree(cmd);\n\t\tfree(reserved);\n\t\tfor (j = 0; j < env_len; j++)\n\t\t\tfree(cctx->env[j]);\n\t\tfree(cctx->env);\n\t\tfree(cctx->term);\n\t\tfree(cctx);\n\t\terror(\"%s: malformed message\", __func__);\n\t\treturn -1;\n\t}\n\tfree(reserved);\n\treserved = NULL;\n\n\twhile (buffer_len(m) > 0) {\n#define MUX_MAX_ENV_VARS\t4096\n\t\tif ((cp = buffer_get_string_ret(m, &len)) == NULL)\n\t\t\tgoto malf;\n\t\tif (!env_permitted(cp)) {\n\t\t\tfree(cp);\n\t\t\tcontinue;\n\t\t}\n\t\tcctx->env = xreallocarray(cctx->env, env_len + 2,\n\t\t sizeof(*cctx->env));\n\t\tcctx->env[env_len++] = cp;\n\t\tcctx->env[env_len] = NULL;\n\t\tif (env_len > MUX_MAX_ENV_VARS) {\n\t\t\terror(\">%d environment variables received, ignoring \"\n\t\t\t \"additional\", MUX_MAX_ENV_VARS);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tdebug2(\"%s: channel %d: request tty %d, X %d, agent %d, subsys %d, \"\n\t \"term \\\"%s\\\", cmd \\\"%s\\\", env %u\", __func__, c->self,\n\t cctx->want_tty, cctx->want_x_fwd, cctx->want_agent_fwd,\n\t cctx->want_subsys, cctx->term, cmd, env_len);\n\n\tbuffer_init(&cctx->cmd);\n\tbuffer_append(&cctx->cmd, cmd, strlen(cmd));\n\tfree(cmd);\n\tcmd = NULL;\n\n\t/* Gather fds from client */\n\tfor(i = 0; i < 3; i++) {\n\t\tif ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {\n\t\t\terror(\"%s: failed to receive fd %d from slave\",\n\t\t\t __func__, i);\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tclose(new_fd[j]);\n\t\t\tfor (j = 0; j < env_len; j++)\n\t\t\t\tfree(cctx->env[j]);\n\t\t\tfree(cctx->env);\n\t\t\tfree(cctx->term);\n\t\t\tbuffer_free(&cctx->cmd);\n\t\t\tfree(cctx);\n\n\t\t\t/* prepare reply */\n\t\t\tbuffer_put_int(r, MUX_S_FAILURE);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r,\n\t\t\t \"did not receive file descriptors\");\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tdebug3(\"%s: got fds stdin %d, stdout %d, stderr %d\", __func__,\n\t new_fd[0], new_fd[1], new_fd[2]);\n\n\t/* XXX support multiple child sessions in future */\n\tif (c->remote_id != -1) {\n\t\tdebug2(\"%s: session already open\", __func__);\n\t\t/* prepare reply */\n\t\tbuffer_put_int(r, MUX_S_FAILURE);\n\t\tbuffer_put_int(r, rid);\n\t\tbuffer_put_cstring(r, \"Multiple sessions not supported\");\n cleanup:\n\t\tclose(new_fd[0]);\n\t\tclose(new_fd[1]);\n\t\tclose(new_fd[2]);\n\t\tfree(cctx->term);\n\t\tif (env_len != 0) {\n\t\t\tfor (i = 0; i < env_len; i++)\n\t\t\t\tfree(cctx->env[i]);\n\t\t\tfree(cctx->env);\n\t\t}\n\t\tbuffer_free(&cctx->cmd);\n\t\tfree(cctx);\n\t\treturn 0;\n\t}\n\n\tif (options.control_master == SSHCTL_MASTER_ASK ||\n\t options.control_master == SSHCTL_MASTER_AUTO_ASK) {\n\t\tif (!ask_permission(\"Allow shared connection to %s? \", host)) {\n\t\t\tdebug2(\"%s: session refused by user\", __func__);\n\t\t\t/* prepare reply */\n\t\t\tbuffer_put_int(r, MUX_S_PERMISSION_DENIED);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r, \"Permission denied\");\n\t\t\tgoto cleanup;\n\t\t}\n\t}\n\n\t/* Try to pick up ttymodes from client before it goes raw */\n\tif (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1)\n\t\terror(\"%s: tcgetattr: %s\", __func__, strerror(errno));\n\n\t/* enable nonblocking unless tty */\n\tif (!isatty(new_fd[0]))\n\t\tset_nonblock(new_fd[0]);\n\tif (!isatty(new_fd[1]))\n\t\tset_nonblock(new_fd[1]);\n\tif (!isatty(new_fd[2]))\n\t\tset_nonblock(new_fd[2]);\n\n\twindow = CHAN_SES_WINDOW_DEFAULT;\n\tpacketmax = CHAN_SES_PACKET_DEFAULT;\n\tif (cctx->want_tty) {\n\t\twindow >>= 1;\n\t\tpacketmax >>= 1;\n\t}\n\n\tnc = channel_new(\"session\", SSH_CHANNEL_OPENING,\n\t new_fd[0], new_fd[1], new_fd[2], window, packetmax,\n\t CHAN_EXTENDED_WRITE, \"client-session\", /*nonblock*/0);\n\n\tnc->ctl_chan = c->self;\t\t/* link session -> control channel */\n\tc->remote_id = nc->self; \t/* link control -> session channel */\n\n\tif (cctx->want_tty && escape_char != 0xffffffff) {\n\t\tchannel_register_filter(nc->self,\n\t\t client_simple_escape_filter, NULL,\n\t\t client_filter_cleanup,\n\t\t client_new_escape_filter_ctx((int)escape_char));\n\t}\n\n\tdebug2(\"%s: channel_new: %d linked to control channel %d\",\n\t __func__, nc->self, nc->ctl_chan);\n\n\tchannel_send_open(nc->self);\n\tchannel_register_open_confirm(nc->self, mux_session_confirm, cctx);\n\tc->mux_pause = 1; /* stop handling messages until open_confirm done */\n\tchannel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);\n\n\t/* reply is deferred, sent by mux_session_confirm */\n\treturn 0;\n}\n\nstatic int\nprocess_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tdebug2(\"%s: channel %d: alive check\", __func__, c->self);\n\n\t/* prepare reply */\n\tbuffer_put_int(r, MUX_S_ALIVE);\n\tbuffer_put_int(r, rid);\n\tbuffer_put_int(r, (u_int)getpid());\n\n\treturn 0;\n}\n\nstatic int\nprocess_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tdebug2(\"%s: channel %d: terminate request\", __func__, c->self);\n\n\tif (options.control_master == SSHCTL_MASTER_ASK ||\n\t options.control_master == SSHCTL_MASTER_AUTO_ASK) {\n\t\tif (!ask_permission(\"Terminate shared connection to %s? \",\n\t\t host)) {\n\t\t\tdebug2(\"%s: termination refused by user\", __func__);\n\t\t\tbuffer_put_int(r, MUX_S_PERMISSION_DENIED);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r, \"Permission denied\");\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tquit_pending = 1;\n\tbuffer_put_int(r, MUX_S_OK);\n\tbuffer_put_int(r, rid);\n\t/* XXX exit happens too soon - message never makes it to client */\n\treturn 0;\n}\n\nstatic char *\nformat_forward(u_int ftype, struct Forward *fwd)\n{\n\tchar *ret;\n\n\tswitch (ftype) {\n\tcase MUX_FWD_LOCAL:\n\t\txasprintf(&ret, \"local forward %.200s:%d -> %.200s:%d\",\n\t\t (fwd->listen_path != NULL) ? fwd->listen_path :\n\t\t (fwd->listen_host == NULL) ?\n\t\t (options.fwd_opts.gateway_ports ? \"*\" : \"LOCALHOST\") :\n\t\t fwd->listen_host, fwd->listen_port,\n\t\t (fwd->connect_path != NULL) ? fwd->connect_path :\n\t\t fwd->connect_host, fwd->connect_port);\n\t\tbreak;\n\tcase MUX_FWD_DYNAMIC:\n\t\txasprintf(&ret, \"dynamic forward %.200s:%d -> *\",\n\t\t (fwd->listen_host == NULL) ?\n\t\t (options.fwd_opts.gateway_ports ? \"*\" : \"LOCALHOST\") :\n\t\t fwd->listen_host, fwd->listen_port);\n\t\tbreak;\n\tcase MUX_FWD_REMOTE:\n\t\txasprintf(&ret, \"remote forward %.200s:%d -> %.200s:%d\",\n\t\t (fwd->listen_path != NULL) ? fwd->listen_path :\n\t\t (fwd->listen_host == NULL) ?\n\t\t \"LOCALHOST\" : fwd->listen_host,\n\t\t fwd->listen_port,\n\t\t (fwd->connect_path != NULL) ? fwd->connect_path :\n\t\t fwd->connect_host, fwd->connect_port);\n\t\tbreak;\n\tdefault:\n\t\tfatal(\"%s: unknown forward type %u\", __func__, ftype);\n\t}\n\treturn ret;\n}\n\nstatic int\ncompare_host(const char *a, const char *b)\n{\n\tif (a == NULL && b == NULL)\n\t\treturn 1;\n\tif (a == NULL || b == NULL)\n\t\treturn 0;\n\treturn strcmp(a, b) == 0;\n}\n\nstatic int\ncompare_forward(struct Forward *a, struct Forward *b)\n{\n\tif (!compare_host(a->listen_host, b->listen_host))\n\t\treturn 0;\n\tif (!compare_host(a->listen_path, b->listen_path))\n\t\treturn 0;\n\tif (a->listen_port != b->listen_port)\n\t\treturn 0;\n\tif (!compare_host(a->connect_host, b->connect_host))\n\t\treturn 0;\n\tif (!compare_host(a->connect_path, b->connect_path))\n\t\treturn 0;\n\tif (a->connect_port != b->connect_port)\n\t\treturn 0;\n\n\treturn 1;\n}\n\nstatic void\nmux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct mux_channel_confirm_ctx *fctx = ctxt;\n\tchar *failmsg = NULL;\n\tstruct Forward *rfwd;\n\tChannel *c;\n\tBuffer out;\n\n\tif ((c = channel_by_id(fctx->cid)) == NULL) {\n\t\t/* no channel for reply */\n\t\terror(\"%s: unknown channel\", __func__);\n\t\treturn;\n\t}\n\tbuffer_init(&out);\n\tif (fctx->fid >= options.num_remote_forwards ||\n\t (options.remote_forwards[fctx->fid].connect_path == NULL &&\n\t options.remote_forwards[fctx->fid].connect_host == NULL)) {\n\t\txasprintf(&failmsg, \"unknown forwarding id %d\", fctx->fid);\n\t\tgoto fail;\n\t}\n\trfwd = &options.remote_forwards[fctx->fid];\n\tdebug(\"%s: %s for: listen %d, connect %s:%d\", __func__,\n\t type == SSH2_MSG_REQUEST_SUCCESS ? \"success\" : \"failure\",\n\t rfwd->listen_port, rfwd->connect_path ? rfwd->connect_path :\n\t rfwd->connect_host, rfwd->connect_port);\n\tif (type == SSH2_MSG_REQUEST_SUCCESS) {\n\t\tif (rfwd->listen_port == 0) {\n\t\t\trfwd->allocated_port = packet_get_int();\n\t\t\tdebug(\"Allocated port %u for mux remote forward\"\n\t\t\t \" to %s:%d\", rfwd->allocated_port,\n\t\t\t rfwd->connect_host, rfwd->connect_port);\n\t\t\tbuffer_put_int(&out, MUX_S_REMOTE_PORT);\n\t\t\tbuffer_put_int(&out, fctx->rid);\n\t\t\tbuffer_put_int(&out, rfwd->allocated_port);\n\t\t\tchannel_update_permitted_opens(rfwd->handle,\n\t\t\t rfwd->allocated_port);\n\t\t} else {\n\t\t\tbuffer_put_int(&out, MUX_S_OK);\n\t\t\tbuffer_put_int(&out, fctx->rid);\n\t\t}\n\t\tgoto out;\n\t} else {\n\t\tif (rfwd->listen_port == 0)\n\t\t\tchannel_update_permitted_opens(rfwd->handle, -1);\n\t\tif (rfwd->listen_path != NULL)\n\t\t\txasprintf(&failmsg, \"remote port forwarding failed for \"\n\t\t\t \"listen path %s\", rfwd->listen_path);\n\t\telse\n\t\t\txasprintf(&failmsg, \"remote port forwarding failed for \"\n\t\t\t \"listen port %d\", rfwd->listen_port);\n\n debug2(\"%s: clearing registered forwarding for listen %d, \"\n\t\t \"connect %s:%d\", __func__, rfwd->listen_port,\n\t\t rfwd->connect_path ? rfwd->connect_path :\n\t\t rfwd->connect_host, rfwd->connect_port);\n\n\t\tfree(rfwd->listen_host);\n\t\tfree(rfwd->listen_path);\n\t\tfree(rfwd->connect_host);\n\t\tfree(rfwd->connect_path);\n\t\tmemset(rfwd, 0, sizeof(*rfwd));\n\t}\n fail:\n\terror(\"%s: %s\", __func__, failmsg);\n\tbuffer_put_int(&out, MUX_S_FAILURE);\n\tbuffer_put_int(&out, fctx->rid);\n\tbuffer_put_cstring(&out, failmsg);\n\tfree(failmsg);\n out:\n\tbuffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out));\n\tbuffer_free(&out);\n\tif (c->mux_pause <= 0)\n\t\tfatal(\"%s: mux_pause %d\", __func__, c->mux_pause);\n\tc->mux_pause = 0; /* start processing messages again */\n}\n\nstatic int\nprocess_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tstruct Forward fwd;\n\tchar *fwd_desc = NULL;\n\tchar *listen_addr, *connect_addr;\n\tu_int ftype;\n\tu_int lport, cport;\n\tint i, ret = 0, freefwd = 1;\n\n\tmemset(&fwd, 0, sizeof(fwd));\n\n\t/* XXX - lport/cport check redundant */\n\tif (buffer_get_int_ret(&ftype, m) != 0 ||\n\t (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||\n\t buffer_get_int_ret(&lport, m) != 0 ||\n\t (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||\n\t buffer_get_int_ret(&cport, m) != 0 ||\n\t (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||\n\t (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {\n\t\terror(\"%s: malformed message\", __func__);\n\t\tret = -1;\n\t\tgoto out;\n\t}\n\tif (*listen_addr == '\\0') {\n\t\tfree(listen_addr);\n\t\tlisten_addr = NULL;\n\t}\n\tif (*connect_addr == '\\0') {\n\t\tfree(connect_addr);\n\t\tconnect_addr = NULL;\n\t}\n\n\tmemset(&fwd, 0, sizeof(fwd));\n\tfwd.listen_port = lport;\n\tif (fwd.listen_port == PORT_STREAMLOCAL)\n\t\tfwd.listen_path = listen_addr;\n\telse\n\t\tfwd.listen_host = listen_addr;\n\tfwd.connect_port = cport;\n\tif (fwd.connect_port == PORT_STREAMLOCAL)\n\t\tfwd.connect_path = connect_addr;\n\telse\n\t\tfwd.connect_host = connect_addr;\n\n\tdebug2(\"%s: channel %d: request %s\", __func__, c->self,\n\t (fwd_desc = format_forward(ftype, &fwd)));\n\n\tif (ftype != MUX_FWD_LOCAL && ftype != MUX_FWD_REMOTE &&\n\t ftype != MUX_FWD_DYNAMIC) {\n\t\tlogit(\"%s: invalid forwarding type %u\", __func__, ftype);\n invalid:\n\t\tfree(listen_addr);\n\t\tfree(connect_addr);\n\t\tbuffer_put_int(r, MUX_S_FAILURE);\n\t\tbuffer_put_int(r, rid);\n\t\tbuffer_put_cstring(r, \"Invalid forwarding request\");\n\t\treturn 0;\n\t}\n\tif (ftype == MUX_FWD_DYNAMIC && fwd.listen_path) {\n\t\tlogit(\"%s: streamlocal and dynamic forwards \"\n\t\t \"are mutually exclusive\", __func__);\n\t\tgoto invalid;\n\t}\n\tif (fwd.listen_port != PORT_STREAMLOCAL && fwd.listen_port >= 65536) {\n\t\tlogit(\"%s: invalid listen port %u\", __func__,\n\t\t fwd.listen_port);\n\t\tgoto invalid;\n\t}\n\tif ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536)\n\t || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {\n\t\tlogit(\"%s: invalid connect port %u\", __func__,\n\t\t fwd.connect_port);\n\t\tgoto invalid;\n\t}\n\tif (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) {\n\t\tlogit(\"%s: missing connect host\", __func__);\n\t\tgoto invalid;\n\t}\n\n\t/* Skip forwards that have already been requested */\n\tswitch (ftype) {\n\tcase MUX_FWD_LOCAL:\n\tcase MUX_FWD_DYNAMIC:\n\t\tfor (i = 0; i < options.num_local_forwards; i++) {\n\t\t\tif (compare_forward(&fwd,\n\t\t\t options.local_forwards + i)) {\n exists:\n\t\t\t\tdebug2(\"%s: found existing forwarding\",\n\t\t\t\t __func__);\n\t\t\t\tbuffer_put_int(r, MUX_S_OK);\n\t\t\t\tbuffer_put_int(r, rid);\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase MUX_FWD_REMOTE:\n\t\tfor (i = 0; i < options.num_remote_forwards; i++) {\n\t\t\tif (compare_forward(&fwd,\n\t\t\t options.remote_forwards + i)) {\n\t\t\t\tif (fwd.listen_port != 0)\n\t\t\t\t\tgoto exists;\n\t\t\t\tdebug2(\"%s: found allocated port\",\n\t\t\t\t __func__);\n\t\t\t\tbuffer_put_int(r, MUX_S_REMOTE_PORT);\n\t\t\t\tbuffer_put_int(r, rid);\n\t\t\t\tbuffer_put_int(r,\n\t\t\t\t options.remote_forwards[i].allocated_port);\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (options.control_master == SSHCTL_MASTER_ASK ||\n\t options.control_master == SSHCTL_MASTER_AUTO_ASK) {\n\t\tif (!ask_permission(\"Open %s on %s?\", fwd_desc, host)) {\n\t\t\tdebug2(\"%s: forwarding refused by user\", __func__);\n\t\t\tbuffer_put_int(r, MUX_S_PERMISSION_DENIED);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r, \"Permission denied\");\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tif (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {\n\t\tif (!channel_setup_local_fwd_listener(&fwd,\n\t\t &options.fwd_opts)) {\n fail:\n\t\t\tlogit(\"slave-requested %s failed\", fwd_desc);\n\t\t\tbuffer_put_int(r, MUX_S_FAILURE);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r, \"Port forwarding failed\");\n\t\t\tgoto out;\n\t\t}\n\t\tadd_local_forward(&options, &fwd);\n\t\tfreefwd = 0;\n\t} else {\n\t\tstruct mux_channel_confirm_ctx *fctx;\n\n\t\tfwd.handle = channel_request_remote_forwarding(&fwd);\n\t\tif (fwd.handle < 0)\n\t\t\tgoto fail;\n\t\tadd_remote_forward(&options, &fwd);\n\t\tfctx = xcalloc(1, sizeof(*fctx));\n\t\tfctx->cid = c->self;\n\t\tfctx->rid = rid;\n\t\tfctx->fid = options.num_remote_forwards - 1;\n\t\tclient_register_global_confirm(mux_confirm_remote_forward,\n\t\t fctx);\n\t\tfreefwd = 0;\n\t\tc->mux_pause = 1; /* wait for mux_confirm_remote_forward */\n\t\t/* delayed reply in mux_confirm_remote_forward */\n\t\tgoto out;\n\t}\n\tbuffer_put_int(r, MUX_S_OK);\n\tbuffer_put_int(r, rid);\n out:\n\tfree(fwd_desc);\n\tif (freefwd) {\n\t\tfree(fwd.listen_host);\n\t\tfree(fwd.listen_path);\n\t\tfree(fwd.connect_host);\n\t\tfree(fwd.connect_path);\n\t}\n\treturn ret;\n}\n\nstatic int\nprocess_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tstruct Forward fwd, *found_fwd;\n\tchar *fwd_desc = NULL;\n\tconst char *error_reason = NULL;\n\tchar *listen_addr = NULL, *connect_addr = NULL;\n\tu_int ftype;\n\tint i, ret = 0;\n\tu_int lport, cport;\n\n\tmemset(&fwd, 0, sizeof(fwd));\n\n\tif (buffer_get_int_ret(&ftype, m) != 0 ||\n\t (listen_addr = buffer_get_string_ret(m, NULL)) == NULL ||\n\t buffer_get_int_ret(&lport, m) != 0 ||\n\t (connect_addr = buffer_get_string_ret(m, NULL)) == NULL ||\n\t buffer_get_int_ret(&cport, m) != 0 ||\n\t (lport != (u_int)PORT_STREAMLOCAL && lport > 65535) ||\n\t (cport != (u_int)PORT_STREAMLOCAL && cport > 65535)) {\n\t\terror(\"%s: malformed message\", __func__);\n\t\tret = -1;\n\t\tgoto out;\n\t}\n\n\tif (*listen_addr == '\\0') {\n\t\tfree(listen_addr);\n\t\tlisten_addr = NULL;\n\t}\n\tif (*connect_addr == '\\0') {\n\t\tfree(connect_addr);\n\t\tconnect_addr = NULL;\n\t}\n\n\tmemset(&fwd, 0, sizeof(fwd));\n\tfwd.listen_port = lport;\n\tif (fwd.listen_port == PORT_STREAMLOCAL)\n\t\tfwd.listen_path = listen_addr;\n\telse\n\t\tfwd.listen_host = listen_addr;\n\tfwd.connect_port = cport;\n\tif (fwd.connect_port == PORT_STREAMLOCAL)\n\t\tfwd.connect_path = connect_addr;\n\telse\n\t\tfwd.connect_host = connect_addr;\n\n\tdebug2(\"%s: channel %d: request cancel %s\", __func__, c->self,\n\t (fwd_desc = format_forward(ftype, &fwd)));\n\n\t/* make sure this has been requested */\n\tfound_fwd = NULL;\n\tswitch (ftype) {\n\tcase MUX_FWD_LOCAL:\n\tcase MUX_FWD_DYNAMIC:\n\t\tfor (i = 0; i < options.num_local_forwards; i++) {\n\t\t\tif (compare_forward(&fwd,\n\t\t\t options.local_forwards + i)) {\n\t\t\t\tfound_fwd = options.local_forwards + i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase MUX_FWD_REMOTE:\n\t\tfor (i = 0; i < options.num_remote_forwards; i++) {\n\t\t\tif (compare_forward(&fwd,\n\t\t\t options.remote_forwards + i)) {\n\t\t\t\tfound_fwd = options.remote_forwards + i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tbreak;\n\t}\n\n\tif (found_fwd == NULL)\n\t\terror_reason = \"port not forwarded\";\n\telse if (ftype == MUX_FWD_REMOTE) {\n\t\t/*\n\t\t * This shouldn't fail unless we confused the host/port\n\t\t * between options.remote_forwards and permitted_opens.\n\t\t * However, for dynamic allocated listen ports we need\n\t\t * to use the actual listen port.\n\t\t */\n\t\tif (channel_request_rforward_cancel(found_fwd) == -1)\n\t\t\terror_reason = \"port not in permitted opens\";\n\t} else {\t/* local and dynamic forwards */\n\t\t/* Ditto */\n\t\tif (channel_cancel_lport_listener(&fwd, fwd.connect_port,\n\t\t &options.fwd_opts) == -1)\n\t\t\terror_reason = \"port not found\";\n\t}\n\n\tif (error_reason == NULL) {\n\t\tbuffer_put_int(r, MUX_S_OK);\n\t\tbuffer_put_int(r, rid);\n\n\t\tfree(found_fwd->listen_host);\n\t\tfree(found_fwd->listen_path);\n\t\tfree(found_fwd->connect_host);\n\t\tfree(found_fwd->connect_path);\n\t\tfound_fwd->listen_host = found_fwd->connect_host = NULL;\n\t\tfound_fwd->listen_path = found_fwd->connect_path = NULL;\n\t\tfound_fwd->listen_port = found_fwd->connect_port = 0;\n\t} else {\n\t\tbuffer_put_int(r, MUX_S_FAILURE);\n\t\tbuffer_put_int(r, rid);\n\t\tbuffer_put_cstring(r, error_reason);\n\t}\n out:\n\tfree(fwd_desc);\n\tfree(listen_addr);\n\tfree(connect_addr);\n\n\treturn ret;\n}\n\nstatic int\nprocess_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tChannel *nc;\n\tchar *reserved, *chost;\n\tu_int cport, i, j;\n\tint new_fd[2];\n\tstruct mux_stdio_confirm_ctx *cctx;\n\n\tchost = reserved = NULL;\n\tif ((reserved = buffer_get_string_ret(m, NULL)) == NULL ||\n\t (chost = buffer_get_string_ret(m, NULL)) == NULL ||\n\t buffer_get_int_ret(&cport, m) != 0) {\n\t\tfree(reserved);\n\t\tfree(chost);\n\t\terror(\"%s: malformed message\", __func__);\n\t\treturn -1;\n\t}\n\tfree(reserved);\n\n\tdebug2(\"%s: channel %d: request stdio fwd to %s:%u\",\n\t __func__, c->self, chost, cport);\n\n\t/* Gather fds from client */\n\tfor(i = 0; i < 2; i++) {\n\t\tif ((new_fd[i] = mm_receive_fd(c->sock)) == -1) {\n\t\t\terror(\"%s: failed to receive fd %d from slave\",\n\t\t\t __func__, i);\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tclose(new_fd[j]);\n\t\t\tfree(chost);\n\n\t\t\t/* prepare reply */\n\t\t\tbuffer_put_int(r, MUX_S_FAILURE);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r,\n\t\t\t \"did not receive file descriptors\");\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tdebug3(\"%s: got fds stdin %d, stdout %d\", __func__,\n\t new_fd[0], new_fd[1]);\n\n\t/* XXX support multiple child sessions in future */\n\tif (c->remote_id != -1) {\n\t\tdebug2(\"%s: session already open\", __func__);\n\t\t/* prepare reply */\n\t\tbuffer_put_int(r, MUX_S_FAILURE);\n\t\tbuffer_put_int(r, rid);\n\t\tbuffer_put_cstring(r, \"Multiple sessions not supported\");\n cleanup:\n\t\tclose(new_fd[0]);\n\t\tclose(new_fd[1]);\n\t\tfree(chost);\n\t\treturn 0;\n\t}\n\n\tif (options.control_master == SSHCTL_MASTER_ASK ||\n\t options.control_master == SSHCTL_MASTER_AUTO_ASK) {\n\t\tif (!ask_permission(\"Allow forward to %s:%u? \",\n\t\t chost, cport)) {\n\t\t\tdebug2(\"%s: stdio fwd refused by user\", __func__);\n\t\t\t/* prepare reply */\n\t\t\tbuffer_put_int(r, MUX_S_PERMISSION_DENIED);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r, \"Permission denied\");\n\t\t\tgoto cleanup;\n\t\t}\n\t}\n\n\t/* enable nonblocking unless tty */\n\tif (!isatty(new_fd[0]))\n\t\tset_nonblock(new_fd[0]);\n\tif (!isatty(new_fd[1]))\n\t\tset_nonblock(new_fd[1]);\n\n\tnc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]);\n\n\tnc->ctl_chan = c->self;\t\t/* link session -> control channel */\n\tc->remote_id = nc->self; \t/* link control -> session channel */\n\n\tdebug2(\"%s: channel_new: %d linked to control channel %d\",\n\t __func__, nc->self, nc->ctl_chan);\n\n\tchannel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);\n\n\tcctx = xcalloc(1, sizeof(*cctx));\n\tcctx->rid = rid;\n\tchannel_register_open_confirm(nc->self, mux_stdio_confirm, cctx);\n\tc->mux_pause = 1; /* stop handling messages until open_confirm done */\n\n\t/* reply is deferred, sent by mux_session_confirm */\n\treturn 0;\n}\n\n/* Callback on open confirmation in mux master for a mux stdio fwd session. */\nstatic void\nmux_stdio_confirm(int id, int success, void *arg)\n{\n\tstruct mux_stdio_confirm_ctx *cctx = arg;\n\tChannel *c, *cc;\n\tBuffer reply;\n\n\tif (cctx == NULL)\n\t\tfatal(\"%s: cctx == NULL\", __func__);\n\tif ((c = channel_by_id(id)) == NULL)\n\t\tfatal(\"%s: no channel for id %d\", __func__, id);\n\tif ((cc = channel_by_id(c->ctl_chan)) == NULL)\n\t\tfatal(\"%s: channel %d lacks control channel %d\", __func__,\n\t\t id, c->ctl_chan);\n\n\tif (!success) {\n\t\tdebug3(\"%s: sending failure reply\", __func__);\n\t\t/* prepare reply */\n\t\tbuffer_init(&reply);\n\t\tbuffer_put_int(&reply, MUX_S_FAILURE);\n\t\tbuffer_put_int(&reply, cctx->rid);\n\t\tbuffer_put_cstring(&reply, \"Session open refused by peer\");\n\t\tgoto done;\n\t}\n\n\tdebug3(\"%s: sending success reply\", __func__);\n\t/* prepare reply */\n\tbuffer_init(&reply);\n\tbuffer_put_int(&reply, MUX_S_SESSION_OPENED);\n\tbuffer_put_int(&reply, cctx->rid);\n\tbuffer_put_int(&reply, c->self);\n\n done:\n\t/* Send reply */\n\tbuffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));\n\tbuffer_free(&reply);\n\n\tif (cc->mux_pause <= 0)\n\t\tfatal(\"%s: mux_pause %d\", __func__, cc->mux_pause);\n\tcc->mux_pause = 0; /* start processing messages again */\n\tc->open_confirm_ctx = NULL;\n\tfree(cctx);\n}\n\nstatic int\nprocess_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tdebug(\"%s: channel %d: stop listening\", __func__, c->self);\n\n\tif (options.control_master == SSHCTL_MASTER_ASK ||\n\t options.control_master == SSHCTL_MASTER_AUTO_ASK) {\n\t\tif (!ask_permission(\"Disable further multiplexing on shared \"\n\t\t \"connection to %s? \", host)) {\n\t\t\tdebug2(\"%s: stop listen refused by user\", __func__);\n\t\t\tbuffer_put_int(r, MUX_S_PERMISSION_DENIED);\n\t\t\tbuffer_put_int(r, rid);\n\t\t\tbuffer_put_cstring(r, \"Permission denied\");\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tif (mux_listener_channel != NULL) {\n\t\tchannel_free(mux_listener_channel);\n\t\tclient_stop_mux();\n\t\tfree(options.control_path);\n\t\toptions.control_path = NULL;\n\t\tmux_listener_channel = NULL;\n\t\tmuxserver_sock = -1;\n\t}\n\n\t/* prepare reply */\n\tbuffer_put_int(r, MUX_S_OK);\n\tbuffer_put_int(r, rid);\n\n\treturn 0;\n}\n\nstatic int\nprocess_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r)\n{\n\tdebug(\"%s: channel %d: proxy request\", __func__, c->self);\n\n\tc->mux_rcb = channel_proxy_downstream;\n\tbuffer_put_int(r, MUX_S_PROXY);\n\tbuffer_put_int(r, rid);\n\n\treturn 0;\n}\n\n/* Channel callbacks fired on read/write from mux slave fd */\nstatic int\nmux_master_read_cb(Channel *c)\n{\n\tstruct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;\n\tBuffer in, out;\n\tconst u_char *ptr;\n\tu_int type, rid, have, i;\n\tint ret = -1;\n\n\t/* Setup ctx and */\n\tif (c->mux_ctx == NULL) {\n\t\tstate = xcalloc(1, sizeof(*state));\n\t\tc->mux_ctx = state;\n\t\tchannel_register_cleanup(c->self,\n\t\t mux_master_control_cleanup_cb, 0);\n\n\t\t/* Send hello */\n\t\tbuffer_init(&out);\n\t\tbuffer_put_int(&out, MUX_MSG_HELLO);\n\t\tbuffer_put_int(&out, SSHMUX_VER);\n\t\t/* no extensions */\n\t\tbuffer_put_string(&c->output, buffer_ptr(&out),\n\t\t buffer_len(&out));\n\t\tbuffer_free(&out);\n\t\tdebug3(\"%s: channel %d: hello sent\", __func__, c->self);\n\t\treturn 0;\n\t}\n\n\tbuffer_init(&in);\n\tbuffer_init(&out);\n\n\t/* Channel code ensures that we receive whole packets */\n\tif ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) {\n malf:\n\t\terror(\"%s: malformed message\", __func__);\n\t\tgoto out;\n\t}\n\tbuffer_append(&in, ptr, have);\n\n\tif (buffer_get_int_ret(&type, &in) != 0)\n\t\tgoto malf;\n\tdebug3(\"%s: channel %d packet type 0x%08x len %u\",\n\t __func__, c->self, type, buffer_len(&in));\n\n\tif (type == MUX_MSG_HELLO)\n\t\trid = 0;\n\telse {\n\t\tif (!state->hello_rcvd) {\n\t\t\terror(\"%s: expected MUX_MSG_HELLO(0x%08x), \"\n\t\t\t \"received 0x%08x\", __func__, MUX_MSG_HELLO, type);\n\t\t\tgoto out;\n\t\t}\n\t\tif (buffer_get_int_ret(&rid, &in) != 0)\n\t\t\tgoto malf;\n\t}\n\n\tfor (i = 0; mux_master_handlers[i].handler != NULL; i++) {\n\t\tif (type == mux_master_handlers[i].type) {\n\t\t\tret = mux_master_handlers[i].handler(rid, c, &in, &out);\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (mux_master_handlers[i].handler == NULL) {\n\t\terror(\"%s: unsupported mux message 0x%08x\", __func__, type);\n\t\tbuffer_put_int(&out, MUX_S_FAILURE);\n\t\tbuffer_put_int(&out, rid);\n\t\tbuffer_put_cstring(&out, \"unsupported request\");\n\t\tret = 0;\n\t}\n\t/* Enqueue reply packet */\n\tif (buffer_len(&out) != 0) {\n\t\tbuffer_put_string(&c->output, buffer_ptr(&out),\n\t\t buffer_len(&out));\n\t}\n out:\n\tbuffer_free(&in);\n\tbuffer_free(&out);\n\treturn ret;\n}\n\nvoid\nmux_exit_message(Channel *c, int exitval)\n{\n\tBuffer m;\n\tChannel *mux_chan;\n\n\tdebug3(\"%s: channel %d: exit message, exitval %d\", __func__, c->self,\n\t exitval);\n\n\tif ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)\n\t\tfatal(\"%s: channel %d missing mux channel %d\",\n\t\t __func__, c->self, c->ctl_chan);\n\n\t/* Append exit message packet to control socket output queue */\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_S_EXIT_MESSAGE);\n\tbuffer_put_int(&m, c->self);\n\tbuffer_put_int(&m, exitval);\n\n\tbuffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));\n\tbuffer_free(&m);\n}\n\nvoid\nmux_tty_alloc_failed(Channel *c)\n{\n\tBuffer m;\n\tChannel *mux_chan;\n\n\tdebug3(\"%s: channel %d: TTY alloc failed\", __func__, c->self);\n\n\tif ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)\n\t\tfatal(\"%s: channel %d missing mux channel %d\",\n\t\t __func__, c->self, c->ctl_chan);\n\n\t/* Append exit message packet to control socket output queue */\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL);\n\tbuffer_put_int(&m, c->self);\n\n\tbuffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));\n\tbuffer_free(&m);\n}\n\n/* Prepare a mux master to listen on a Unix domain socket. */\nvoid\nmuxserver_listen(void)\n{\n\tmode_t old_umask;\n\tchar *orig_control_path = options.control_path;\n\tchar rbuf[16+1];\n\tu_int i, r;\n\tint oerrno;\n\n\tif (options.control_path == NULL ||\n\t options.control_master == SSHCTL_MASTER_NO)\n\t\treturn;\n\n\tdebug(\"setting up multiplex master socket\");\n\n\t/*\n\t * Use a temporary path before listen so we can pseudo-atomically\n\t * establish the listening socket in its final location to avoid\n\t * other processes racing in between bind() and listen() and hitting\n\t * an unready socket.\n\t */\n\tfor (i = 0; i < sizeof(rbuf) - 1; i++) {\n\t\tr = arc4random_uniform(26+26+10);\n\t\trbuf[i] = (r < 26) ? 'a' + r :\n\t\t (r < 26*2) ? 'A' + r - 26 :\n\t\t '0' + r - 26 - 26;\n\t}\n\trbuf[sizeof(rbuf) - 1] = '\\0';\n\toptions.control_path = NULL;\n\txasprintf(&options.control_path, \"%s.%s\", orig_control_path, rbuf);\n\tdebug3(\"%s: temporary control path %s\", __func__, options.control_path);\n\n\told_umask = umask(0177);\n\tmuxserver_sock = unix_listener(options.control_path, 64, 0);\n\toerrno = errno;\n\tumask(old_umask);\n\tif (muxserver_sock < 0) {\n\t\tif (oerrno == EINVAL || oerrno == EADDRINUSE) {\n\t\t\terror(\"ControlSocket %s already exists, \"\n\t\t\t \"disabling multiplexing\", options.control_path);\n disable_mux_master:\n\t\t\tif (muxserver_sock != -1) {\n\t\t\t\tclose(muxserver_sock);\n\t\t\t\tmuxserver_sock = -1;\n\t\t\t}\n\t\t\tfree(orig_control_path);\n\t\t\tfree(options.control_path);\n\t\t\toptions.control_path = NULL;\n\t\t\toptions.control_master = SSHCTL_MASTER_NO;\n\t\t\treturn;\n\t\t} else {\n\t\t\t/* unix_listener() logs the error */\n\t\t\tcleanup_exit(255);\n\t\t}\n\t}\n\n\t/* Now atomically \"move\" the mux socket into position */\n\tif (link(options.control_path, orig_control_path) != 0) {\n\t\tif (errno != EEXIST) {\n\t\t\tfatal(\"%s: link mux listener %s => %s: %s\", __func__,\n\t\t\t options.control_path, orig_control_path,\n\t\t\t strerror(errno));\n\t\t}\n\t\terror(\"ControlSocket %s already exists, disabling multiplexing\",\n\t\t orig_control_path);\n\t\tunlink(options.control_path);\n\t\tgoto disable_mux_master;\n\t}\n\tunlink(options.control_path);\n\tfree(options.control_path);\n\toptions.control_path = orig_control_path;\n\n\tset_nonblock(muxserver_sock);\n\n\tmux_listener_channel = channel_new(\"mux listener\",\n\t SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,\n\t CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,\n\t 0, options.control_path, 1);\n\tmux_listener_channel->mux_rcb = mux_master_read_cb;\n\tdebug3(\"%s: mux listener channel %d fd %d\", __func__,\n\t mux_listener_channel->self, mux_listener_channel->sock);\n}\n\n/* Callback on open confirmation in mux master for a mux client session. */\nstatic void\nmux_session_confirm(int id, int success, void *arg)\n{\n\tstruct mux_session_confirm_ctx *cctx = arg;\n\tconst char *display;\n\tChannel *c, *cc;\n\tint i;\n\tBuffer reply;\n\n\tif (cctx == NULL)\n\t\tfatal(\"%s: cctx == NULL\", __func__);\n\tif ((c = channel_by_id(id)) == NULL)\n\t\tfatal(\"%s: no channel for id %d\", __func__, id);\n\tif ((cc = channel_by_id(c->ctl_chan)) == NULL)\n\t\tfatal(\"%s: channel %d lacks control channel %d\", __func__,\n\t\t id, c->ctl_chan);\n\n\tif (!success) {\n\t\tdebug3(\"%s: sending failure reply\", __func__);\n\t\t/* prepare reply */\n\t\tbuffer_init(&reply);\n\t\tbuffer_put_int(&reply, MUX_S_FAILURE);\n\t\tbuffer_put_int(&reply, cctx->rid);\n\t\tbuffer_put_cstring(&reply, \"Session open refused by peer\");\n\t\tgoto done;\n\t}\n\n\tdisplay = getenv(\"DISPLAY\");\n\tif (cctx->want_x_fwd && options.forward_x11 && display != NULL) {\n\t\tchar *proto, *data;\n\n\t\t/* Get reasonable local authentication information. */\n\t\tif (client_x11_get_proto(display, options.xauth_location,\n\t\t options.forward_x11_trusted, options.forward_x11_timeout,\n\t\t &proto, &data) == 0) {\n\t\t\t/* Request forwarding with authentication spoofing. */\n\t\t\tdebug(\"Requesting X11 forwarding with authentication \"\n\t\t\t \"spoofing.\");\n\t\t\tx11_request_forwarding_with_spoofing(id, display, proto,\n\t\t\t data, 1);\n\t\t\t/* XXX exit_on_forward_failure */\n\t\t\tclient_expect_confirm(id, \"X11 forwarding\",\n\t\t\t CONFIRM_WARN);\n\t\t}\n\t}\n\n\tif (cctx->want_agent_fwd && options.forward_agent) {\n\t\tdebug(\"Requesting authentication agent forwarding.\");\n\t\tchannel_request_start(id, \"auth-agent-req@openssh.com\", 0);\n\t\tpacket_send();\n\t}\n\n\tclient_session2_setup(id, cctx->want_tty, cctx->want_subsys,\n\t cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);\n\n\tdebug3(\"%s: sending success reply\", __func__);\n\t/* prepare reply */\n\tbuffer_init(&reply);\n\tbuffer_put_int(&reply, MUX_S_SESSION_OPENED);\n\tbuffer_put_int(&reply, cctx->rid);\n\tbuffer_put_int(&reply, c->self);\n\n done:\n\t/* Send reply */\n\tbuffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));\n\tbuffer_free(&reply);\n\n\tif (cc->mux_pause <= 0)\n\t\tfatal(\"%s: mux_pause %d\", __func__, cc->mux_pause);\n\tcc->mux_pause = 0; /* start processing messages again */\n\tc->open_confirm_ctx = NULL;\n\tbuffer_free(&cctx->cmd);\n\tfree(cctx->term);\n\tif (cctx->env != NULL) {\n\t\tfor (i = 0; cctx->env[i] != NULL; i++)\n\t\t\tfree(cctx->env[i]);\n\t\tfree(cctx->env);\n\t}\n\tfree(cctx);\n}\n\n/* ** Multiplexing client support */\n\n/* Exit signal handler */\nstatic void\ncontrol_client_sighandler(int signo)\n{\n\tmuxclient_terminate = signo;\n}\n\n/*\n * Relay signal handler - used to pass some signals from mux client to\n * mux master.\n */\nstatic void\ncontrol_client_sigrelay(int signo)\n{\n\tint save_errno = errno;\n\n\tif (muxserver_pid > 1)\n\t\tkill(muxserver_pid, signo);\n\n\terrno = save_errno;\n}\n\nstatic int\nmux_client_read(int fd, Buffer *b, u_int need)\n{\n\tu_int have;\n\tssize_t len;\n\tu_char *p;\n\tstruct pollfd pfd;\n\n\tpfd.fd = fd;\n\tpfd.events = POLLIN;\n\tp = buffer_append_space(b, need);\n\tfor (have = 0; have < need; ) {\n\t\tif (muxclient_terminate) {\n\t\t\terrno = EINTR;\n\t\t\treturn -1;\n\t\t}\n\t\tlen = read(fd, p + have, need - have);\n\t\tif (len < 0) {\n\t\t\tswitch (errno) {\n#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)\n\t\t\tcase EWOULDBLOCK:\n#endif\n\t\t\tcase EAGAIN:\n\t\t\t\t(void)poll(&pfd, 1, -1);\n\t\t\t\t/* FALLTHROUGH */\n\t\t\tcase EINTR:\n\t\t\t\tcontinue;\n\t\t\tdefault:\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tif (len == 0) {\n\t\t\terrno = EPIPE;\n\t\t\treturn -1;\n\t\t}\n\t\thave += (u_int)len;\n\t}\n\treturn 0;\n}\n\nstatic int\nmux_client_write_packet(int fd, Buffer *m)\n{\n\tBuffer queue;\n\tu_int have, need;\n\tint oerrno, len;\n\tu_char *ptr;\n\tstruct pollfd pfd;\n\n\tpfd.fd = fd;\n\tpfd.events = POLLOUT;\n\tbuffer_init(&queue);\n\tbuffer_put_string(&queue, buffer_ptr(m), buffer_len(m));\n\n\tneed = buffer_len(&queue);\n\tptr = buffer_ptr(&queue);\n\n\tfor (have = 0; have < need; ) {\n\t\tif (muxclient_terminate) {\n\t\t\tbuffer_free(&queue);\n\t\t\terrno = EINTR;\n\t\t\treturn -1;\n\t\t}\n\t\tlen = write(fd, ptr + have, need - have);\n\t\tif (len < 0) {\n\t\t\tswitch (errno) {\n#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)\n\t\t\tcase EWOULDBLOCK:\n#endif\n\t\t\tcase EAGAIN:\n\t\t\t\t(void)poll(&pfd, 1, -1);\n\t\t\t\t/* FALLTHROUGH */\n\t\t\tcase EINTR:\n\t\t\t\tcontinue;\n\t\t\tdefault:\n\t\t\t\toerrno = errno;\n\t\t\t\tbuffer_free(&queue);\n\t\t\t\terrno = oerrno;\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tif (len == 0) {\n\t\t\tbuffer_free(&queue);\n\t\t\terrno = EPIPE;\n\t\t\treturn -1;\n\t\t}\n\t\thave += (u_int)len;\n\t}\n\tbuffer_free(&queue);\n\treturn 0;\n}\n\nstatic int\nmux_client_read_packet(int fd, Buffer *m)\n{\n\tBuffer queue;\n\tu_int need, have;\n\tconst u_char *ptr;\n\tint oerrno;\n\n\tbuffer_init(&queue);\n\tif (mux_client_read(fd, &queue, 4) != 0) {\n\t\tif ((oerrno = errno) == EPIPE)\n\t\t\tdebug3(\"%s: read header failed: %s\", __func__,\n\t\t\t strerror(errno));\n\t\tbuffer_free(&queue);\n\t\terrno = oerrno;\n\t\treturn -1;\n\t}\n\tneed = get_u32(buffer_ptr(&queue));\n\tif (mux_client_read(fd, &queue, need) != 0) {\n\t\toerrno = errno;\n\t\tdebug3(\"%s: read body failed: %s\", __func__, strerror(errno));\n\t\tbuffer_free(&queue);\n\t\terrno = oerrno;\n\t\treturn -1;\n\t}\n\tptr = buffer_get_string_ptr(&queue, &have);\n\tbuffer_append(m, ptr, have);\n\tbuffer_free(&queue);\n\treturn 0;\n}\n\nstatic int\nmux_client_hello_exchange(int fd)\n{\n\tBuffer m;\n\tu_int type, ver;\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_MSG_HELLO);\n\tbuffer_put_int(&m, SSHMUX_VER);\n\t/* no extensions */\n\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\tbuffer_clear(&m);\n\n\t/* Read their HELLO */\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\tbuffer_free(&m);\n\t\treturn -1;\n\t}\n\n\ttype = buffer_get_int(&m);\n\tif (type != MUX_MSG_HELLO)\n\t\tfatal(\"%s: expected HELLO (%u) received %u\",\n\t\t __func__, MUX_MSG_HELLO, type);\n\tver = buffer_get_int(&m);\n\tif (ver != SSHMUX_VER)\n\t\tfatal(\"Unsupported multiplexing protocol version %d \"\n\t\t \"(expected %d)\", ver, SSHMUX_VER);\n\tdebug2(\"%s: master version %u\", __func__, ver);\n\t/* No extensions are presently defined */\n\twhile (buffer_len(&m) > 0) {\n\t\tchar *name = buffer_get_string(&m, NULL);\n\t\tchar *value = buffer_get_string(&m, NULL);\n\n\t\tdebug2(\"Unrecognised master extension \\\"%s\\\"\", name);\n\t\tfree(name);\n\t\tfree(value);\n\t}\n\tbuffer_free(&m);\n\treturn 0;\n}\n\nstatic u_int\nmux_client_request_alive(int fd)\n{\n\tBuffer m;\n\tchar *e;\n\tu_int pid, type, rid;\n\n\tdebug3(\"%s: entering\", __func__);\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_C_ALIVE_CHECK);\n\tbuffer_put_int(&m, muxclient_request_id);\n\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\tbuffer_clear(&m);\n\n\t/* Read their reply */\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\tbuffer_free(&m);\n\t\treturn 0;\n\t}\n\n\ttype = buffer_get_int(&m);\n\tif (type != MUX_S_ALIVE) {\n\t\te = buffer_get_string(&m, NULL);\n\t\tfatal(\"%s: master returned error: %s\", __func__, e);\n\t}\n\n\tif ((rid = buffer_get_int(&m)) != muxclient_request_id)\n\t\tfatal(\"%s: out of sequence reply: my id %u theirs %u\",\n\t\t __func__, muxclient_request_id, rid);\n\tpid = buffer_get_int(&m);\n\tbuffer_free(&m);\n\n\tdebug3(\"%s: done pid = %u\", __func__, pid);\n\n\tmuxclient_request_id++;\n\n\treturn pid;\n}\n\nstatic void\nmux_client_request_terminate(int fd)\n{\n\tBuffer m;\n\tchar *e;\n\tu_int type, rid;\n\n\tdebug3(\"%s: entering\", __func__);\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_C_TERMINATE);\n\tbuffer_put_int(&m, muxclient_request_id);\n\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\tbuffer_clear(&m);\n\n\t/* Read their reply */\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\t/* Remote end exited already */\n\t\tif (errno == EPIPE) {\n\t\t\tbuffer_free(&m);\n\t\t\treturn;\n\t\t}\n\t\tfatal(\"%s: read from master failed: %s\",\n\t\t __func__, strerror(errno));\n\t}\n\n\ttype = buffer_get_int(&m);\n\tif ((rid = buffer_get_int(&m)) != muxclient_request_id)\n\t\tfatal(\"%s: out of sequence reply: my id %u theirs %u\",\n\t\t __func__, muxclient_request_id, rid);\n\tswitch (type) {\n\tcase MUX_S_OK:\n\t\tbreak;\n\tcase MUX_S_PERMISSION_DENIED:\n\t\te = buffer_get_string(&m, NULL);\n\t\tfatal(\"Master refused termination request: %s\", e);\n\tcase MUX_S_FAILURE:\n\t\te = buffer_get_string(&m, NULL);\n\t\tfatal(\"%s: termination request failed: %s\", __func__, e);\n\tdefault:\n\t\tfatal(\"%s: unexpected response from master 0x%08x\",\n\t\t __func__, type);\n\t}\n\tbuffer_free(&m);\n\tmuxclient_request_id++;\n}\n\nstatic int\nmux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd)\n{\n\tBuffer m;\n\tchar *e, *fwd_desc;\n\tu_int type, rid;\n\n\tfwd_desc = format_forward(ftype, fwd);\n\tdebug(\"Requesting %s %s\",\n\t cancel_flag ? \"cancellation of\" : \"forwarding of\", fwd_desc);\n\tfree(fwd_desc);\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, cancel_flag ? MUX_C_CLOSE_FWD : MUX_C_OPEN_FWD);\n\tbuffer_put_int(&m, muxclient_request_id);\n\tbuffer_put_int(&m, ftype);\n\tif (fwd->listen_path != NULL) {\n\t\tbuffer_put_cstring(&m, fwd->listen_path);\n\t} else {\n\t\tbuffer_put_cstring(&m,\n\t\t fwd->listen_host == NULL ? \"\" :\n\t\t (*fwd->listen_host == '\\0' ? \"*\" : fwd->listen_host));\n\t}\n\tbuffer_put_int(&m, fwd->listen_port);\n\tif (fwd->connect_path != NULL) {\n\t\tbuffer_put_cstring(&m, fwd->connect_path);\n\t} else {\n\t\tbuffer_put_cstring(&m,\n\t\t fwd->connect_host == NULL ? \"\" : fwd->connect_host);\n\t}\n\tbuffer_put_int(&m, fwd->connect_port);\n\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\tbuffer_clear(&m);\n\n\t/* Read their reply */\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\tbuffer_free(&m);\n\t\treturn -1;\n\t}\n\n\ttype = buffer_get_int(&m);\n\tif ((rid = buffer_get_int(&m)) != muxclient_request_id)\n\t\tfatal(\"%s: out of sequence reply: my id %u theirs %u\",\n\t\t __func__, muxclient_request_id, rid);\n\tswitch (type) {\n\tcase MUX_S_OK:\n\t\tbreak;\n\tcase MUX_S_REMOTE_PORT:\n\t\tif (cancel_flag)\n\t\t\tfatal(\"%s: got MUX_S_REMOTE_PORT for cancel\", __func__);\n\t\tfwd->allocated_port = buffer_get_int(&m);\n\t\tverbose(\"Allocated port %u for remote forward to %s:%d\",\n\t\t fwd->allocated_port,\n\t\t fwd->connect_host ? fwd->connect_host : \"\",\n\t\t fwd->connect_port);\n\t\tif (muxclient_command == SSHMUX_COMMAND_FORWARD)\n\t\t\tfprintf(stdout, \"%i\\n\", fwd->allocated_port);\n\t\tbreak;\n\tcase MUX_S_PERMISSION_DENIED:\n\t\te = buffer_get_string(&m, NULL);\n\t\tbuffer_free(&m);\n\t\terror(\"Master refused forwarding request: %s\", e);\n\t\treturn -1;\n\tcase MUX_S_FAILURE:\n\t\te = buffer_get_string(&m, NULL);\n\t\tbuffer_free(&m);\n\t\terror(\"%s: forwarding request failed: %s\", __func__, e);\n\t\treturn -1;\n\tdefault:\n\t\tfatal(\"%s: unexpected response from master 0x%08x\",\n\t\t __func__, type);\n\t}\n\tbuffer_free(&m);\n\n\tmuxclient_request_id++;\n\treturn 0;\n}\n\nstatic int\nmux_client_forwards(int fd, int cancel_flag)\n{\n\tint i, ret = 0;\n\n\tdebug3(\"%s: %s forwardings: %d local, %d remote\", __func__,\n\t cancel_flag ? \"cancel\" : \"request\",\n\t options.num_local_forwards, options.num_remote_forwards);\n\n\t/* XXX ExitOnForwardingFailure */\n\tfor (i = 0; i < options.num_local_forwards; i++) {\n\t\tif (mux_client_forward(fd, cancel_flag,\n\t\t options.local_forwards[i].connect_port == 0 ?\n\t\t MUX_FWD_DYNAMIC : MUX_FWD_LOCAL,\n\t\t options.local_forwards + i) != 0)\n\t\t\tret = -1;\n\t}\n\tfor (i = 0; i < options.num_remote_forwards; i++) {\n\t\tif (mux_client_forward(fd, cancel_flag, MUX_FWD_REMOTE,\n\t\t options.remote_forwards + i) != 0)\n\t\t\tret = -1;\n\t}\n\treturn ret;\n}\n\nstatic int\nmux_client_request_session(int fd)\n{\n\tBuffer m;\n\tchar *e, *term;\n\tu_int i, rid, sid, esid, exitval, type, exitval_seen;\n\textern char **environ;\n\tint devnull, rawmode;\n\n\tdebug3(\"%s: entering\", __func__);\n\n\tif ((muxserver_pid = mux_client_request_alive(fd)) == 0) {\n\t\terror(\"%s: master alive request failed\", __func__);\n\t\treturn -1;\n\t}\n\n\tsignal(SIGPIPE, SIG_IGN);\n\n\tif (stdin_null_flag) {\n\t\tif ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)\n\t\t\tfatal(\"open(/dev/null): %s\", strerror(errno));\n\t\tif (dup2(devnull, STDIN_FILENO) == -1)\n\t\t\tfatal(\"dup2: %s\", strerror(errno));\n\t\tif (devnull > STDERR_FILENO)\n\t\t\tclose(devnull);\n\t}\n\n\tterm = getenv(\"TERM\");\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_C_NEW_SESSION);\n\tbuffer_put_int(&m, muxclient_request_id);\n\tbuffer_put_cstring(&m, \"\"); /* reserved */\n\tbuffer_put_int(&m, tty_flag);\n\tbuffer_put_int(&m, options.forward_x11);\n\tbuffer_put_int(&m, options.forward_agent);\n\tbuffer_put_int(&m, subsystem_flag);\n\tbuffer_put_int(&m, options.escape_char == SSH_ESCAPECHAR_NONE ?\n\t 0xffffffff : (u_int)options.escape_char);\n\tbuffer_put_cstring(&m, term == NULL ? \"\" : term);\n\tbuffer_put_string(&m, buffer_ptr(&command), buffer_len(&command));\n\n\tif (options.num_send_env > 0 && environ != NULL) {\n\t\t/* Pass environment */\n\t\tfor (i = 0; environ[i] != NULL; i++) {\n\t\t\tif (env_permitted(environ[i])) {\n\t\t\t\tbuffer_put_cstring(&m, environ[i]);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\t/* Send the stdio file descriptors */\n\tif (mm_send_fd(fd, STDIN_FILENO) == -1 ||\n\t mm_send_fd(fd, STDOUT_FILENO) == -1 ||\n\t mm_send_fd(fd, STDERR_FILENO) == -1)\n\t\tfatal(\"%s: send fds failed\", __func__);\n\n\tdebug3(\"%s: session request sent\", __func__);\n\n\t/* Read their reply */\n\tbuffer_clear(&m);\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\terror(\"%s: read from master failed: %s\",\n\t\t __func__, strerror(errno));\n\t\tbuffer_free(&m);\n\t\treturn -1;\n\t}\n\n\ttype = buffer_get_int(&m);\n\tif ((rid = buffer_get_int(&m)) != muxclient_request_id)\n\t\tfatal(\"%s: out of sequence reply: my id %u theirs %u\",\n\t\t __func__, muxclient_request_id, rid);\n\tswitch (type) {\n\tcase MUX_S_SESSION_OPENED:\n\t\tsid = buffer_get_int(&m);\n\t\tdebug(\"%s: master session id: %u\", __func__, sid);\n\t\tbreak;\n\tcase MUX_S_PERMISSION_DENIED:\n\t\te = buffer_get_string(&m, NULL);\n\t\tbuffer_free(&m);\n\t\terror(\"Master refused session request: %s\", e);\n\t\treturn -1;\n\tcase MUX_S_FAILURE:\n\t\te = buffer_get_string(&m, NULL);\n\t\tbuffer_free(&m);\n\t\terror(\"%s: session request failed: %s\", __func__, e);\n\t\treturn -1;\n\tdefault:\n\t\tbuffer_free(&m);\n\t\terror(\"%s: unexpected response from master 0x%08x\",\n\t\t __func__, type);\n\t\treturn -1;\n\t}\n\tmuxclient_request_id++;\n\n\tif (pledge(\"stdio proc tty\", NULL) == -1)\n\t\tfatal(\"%s pledge(): %s\", __func__, strerror(errno));\n\tplatform_pledge_mux();\n\n\tsignal(SIGHUP, control_client_sighandler);\n\tsignal(SIGINT, control_client_sighandler);\n\tsignal(SIGTERM, control_client_sighandler);\n\tsignal(SIGWINCH, control_client_sigrelay);\n\n\trawmode = tty_flag;\n\tif (tty_flag)\n\t\tenter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\n\t/*\n\t * Stick around until the controlee closes the client_fd.\n\t * Before it does, it is expected to write an exit message.\n\t * This process must read the value and wait for the closure of\n\t * the client_fd; if this one closes early, the multiplex master will\n\t * terminate early too (possibly losing data).\n\t */\n\tfor (exitval = 255, exitval_seen = 0;;) {\n\t\tbuffer_clear(&m);\n\t\tif (mux_client_read_packet(fd, &m) != 0)\n\t\t\tbreak;\n\t\ttype = buffer_get_int(&m);\n\t\tswitch (type) {\n\t\tcase MUX_S_TTY_ALLOC_FAIL:\n\t\t\tif ((esid = buffer_get_int(&m)) != sid)\n\t\t\t\tfatal(\"%s: tty alloc fail on unknown session: \"\n\t\t\t\t \"my id %u theirs %u\",\n\t\t\t\t __func__, sid, esid);\n\t\t\tleave_raw_mode(options.request_tty ==\n\t\t\t REQUEST_TTY_FORCE);\n\t\t\trawmode = 0;\n\t\t\tcontinue;\n\t\tcase MUX_S_EXIT_MESSAGE:\n\t\t\tif ((esid = buffer_get_int(&m)) != sid)\n\t\t\t\tfatal(\"%s: exit on unknown session: \"\n\t\t\t\t \"my id %u theirs %u\",\n\t\t\t\t __func__, sid, esid);\n\t\t\tif (exitval_seen)\n\t\t\t\tfatal(\"%s: exitval sent twice\", __func__);\n\t\t\texitval = buffer_get_int(&m);\n\t\t\texitval_seen = 1;\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\te = buffer_get_string(&m, NULL);\n\t\t\tfatal(\"%s: master returned error: %s\", __func__, e);\n\t\t}\n\t}\n\n\tclose(fd);\n\tif (rawmode)\n\t\tleave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);\n\n\tif (muxclient_terminate) {\n\t\tdebug2(\"Exiting on signal %d\", muxclient_terminate);\n\t\texitval = 255;\n\t} else if (!exitval_seen) {\n\t\tdebug2(\"Control master terminated unexpectedly\");\n\t\texitval = 255;\n\t} else\n\t\tdebug2(\"Received exit status from master %d\", exitval);\n\n\tif (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)\n\t\tfprintf(stderr, \"Shared connection to %s closed.\\r\\n\", host);\n\n\texit(exitval);\n}\n\nstatic int\nmux_client_proxy(int fd)\n{\n\tBuffer m;\n\tchar *e;\n\tu_int type, rid;\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_C_PROXY);\n\tbuffer_put_int(&m, muxclient_request_id);\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\tbuffer_clear(&m);\n\n\t/* Read their reply */\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\tbuffer_free(&m);\n\t\treturn 0;\n\t}\n\ttype = buffer_get_int(&m);\n\tif (type != MUX_S_PROXY) {\n\t\te = buffer_get_string(&m, NULL);\n\t\tfatal(\"%s: master returned error: %s\", __func__, e);\n\t}\n\tif ((rid = buffer_get_int(&m)) != muxclient_request_id)\n\t\tfatal(\"%s: out of sequence reply: my id %u theirs %u\",\n\t\t __func__, muxclient_request_id, rid);\n\tbuffer_free(&m);\n\n\tdebug3(\"%s: done\", __func__);\n\tmuxclient_request_id++;\n\treturn 0;\n}\n\nstatic int\nmux_client_request_stdio_fwd(int fd)\n{\n\tBuffer m;\n\tchar *e;\n\tu_int type, rid, sid;\n\tint devnull;\n\n\tdebug3(\"%s: entering\", __func__);\n\n\tif ((muxserver_pid = mux_client_request_alive(fd)) == 0) {\n\t\terror(\"%s: master alive request failed\", __func__);\n\t\treturn -1;\n\t}\n\n\tsignal(SIGPIPE, SIG_IGN);\n\n\tif (stdin_null_flag) {\n\t\tif ((devnull = open(_PATH_DEVNULL, O_RDONLY)) == -1)\n\t\t\tfatal(\"open(/dev/null): %s\", strerror(errno));\n\t\tif (dup2(devnull, STDIN_FILENO) == -1)\n\t\t\tfatal(\"dup2: %s\", strerror(errno));\n\t\tif (devnull > STDERR_FILENO)\n\t\t\tclose(devnull);\n\t}\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_C_NEW_STDIO_FWD);\n\tbuffer_put_int(&m, muxclient_request_id);\n\tbuffer_put_cstring(&m, \"\"); /* reserved */\n\tbuffer_put_cstring(&m, options.stdio_forward_host);\n\tbuffer_put_int(&m, options.stdio_forward_port);\n\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\t/* Send the stdio file descriptors */\n\tif (mm_send_fd(fd, STDIN_FILENO) == -1 ||\n\t mm_send_fd(fd, STDOUT_FILENO) == -1)\n\t\tfatal(\"%s: send fds failed\", __func__);\n\n\tif (pledge(\"stdio proc tty\", NULL) == -1)\n\t\tfatal(\"%s pledge(): %s\", __func__, strerror(errno));\n\tplatform_pledge_mux();\n\n\tdebug3(\"%s: stdio forward request sent\", __func__);\n\n\t/* Read their reply */\n\tbuffer_clear(&m);\n\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\terror(\"%s: read from master failed: %s\",\n\t\t __func__, strerror(errno));\n\t\tbuffer_free(&m);\n\t\treturn -1;\n\t}\n\n\ttype = buffer_get_int(&m);\n\tif ((rid = buffer_get_int(&m)) != muxclient_request_id)\n\t\tfatal(\"%s: out of sequence reply: my id %u theirs %u\",\n\t\t __func__, muxclient_request_id, rid);\n\tswitch (type) {\n\tcase MUX_S_SESSION_OPENED:\n\t\tsid = buffer_get_int(&m);\n\t\tdebug(\"%s: master session id: %u\", __func__, sid);\n\t\tbreak;\n\tcase MUX_S_PERMISSION_DENIED:\n\t\te = buffer_get_string(&m, NULL);\n\t\tbuffer_free(&m);\n\t\tfatal(\"Master refused stdio forwarding request: %s\", e);\n\tcase MUX_S_FAILURE:\n\t\te = buffer_get_string(&m, NULL);\n\t\tbuffer_free(&m);\n\t\tfatal(\"Stdio forwarding request failed: %s\", e);\n\tdefault:\n\t\tbuffer_free(&m);\n\t\terror(\"%s: unexpected response from master 0x%08x\",\n\t\t __func__, type);\n\t\treturn -1;\n\t}\n\tmuxclient_request_id++;\n\n\tsignal(SIGHUP, control_client_sighandler);\n\tsignal(SIGINT, control_client_sighandler);\n\tsignal(SIGTERM, control_client_sighandler);\n\tsignal(SIGWINCH, control_client_sigrelay);\n\n\t/*\n\t * Stick around until the controlee closes the client_fd.\n\t */\n\tbuffer_clear(&m);\n\tif (mux_client_read_packet(fd, &m) != 0) {\n\t\tif (errno == EPIPE ||\n\t\t (errno == EINTR && muxclient_terminate != 0))\n\t\t\treturn 0;\n\t\tfatal(\"%s: mux_client_read_packet: %s\",\n\t\t __func__, strerror(errno));\n\t}\n\tfatal(\"%s: master returned unexpected message %u\", __func__, type);\n}\n\nstatic void\nmux_client_request_stop_listening(int fd)\n{\n\tBuffer m;\n\tchar *e;\n\tu_int type, rid;\n\n\tdebug3(\"%s: entering\", __func__);\n\n\tbuffer_init(&m);\n\tbuffer_put_int(&m, MUX_C_STOP_LISTENING);\n\tbuffer_put_int(&m, muxclient_request_id);\n\n\tif (mux_client_write_packet(fd, &m) != 0)\n\t\tfatal(\"%s: write packet: %s\", __func__, strerror(errno));\n\n\tbuffer_clear(&m);\n\n\t/* Read their reply */\n\tif (mux_client_read_packet(fd, &m) != 0)\n\t\tfatal(\"%s: read from master failed: %s\",\n\t\t __func__, strerror(errno));\n\n\ttype = buffer_get_int(&m);\n\tif ((rid = buffer_get_int(&m)) != muxclient_request_id)\n\t\tfatal(\"%s: out of sequence reply: my id %u theirs %u\",\n\t\t __func__, muxclient_request_id, rid);\n\tswitch (type) {\n\tcase MUX_S_OK:\n\t\tbreak;\n\tcase MUX_S_PERMISSION_DENIED:\n\t\te = buffer_get_string(&m, NULL);\n\t\tfatal(\"Master refused stop listening request: %s\", e);\n\tcase MUX_S_FAILURE:\n\t\te = buffer_get_string(&m, NULL);\n\t\tfatal(\"%s: stop listening request failed: %s\", __func__, e);\n\tdefault:\n\t\tfatal(\"%s: unexpected response from master 0x%08x\",\n\t\t __func__, type);\n\t}\n\tbuffer_free(&m);\n\tmuxclient_request_id++;\n}\n\n/* Multiplex client main loop. */\nint\nmuxclient(const char *path)\n{\n\tstruct sockaddr_un addr;\n\tint sock;\n\tu_int pid;\n\n\tif (muxclient_command == 0) {\n\t\tif (options.stdio_forward_host != NULL)\n\t\t\tmuxclient_command = SSHMUX_COMMAND_STDIO_FWD;\n\t\telse\n\t\t\tmuxclient_command = SSHMUX_COMMAND_OPEN;\n\t}\n\n\tswitch (options.control_master) {\n\tcase SSHCTL_MASTER_AUTO:\n\tcase SSHCTL_MASTER_AUTO_ASK:\n\t\tdebug(\"auto-mux: Trying existing master\");\n\t\t/* FALLTHROUGH */\n\tcase SSHCTL_MASTER_NO:\n\t\tbreak;\n\tdefault:\n\t\treturn -1;\n\t}\n\n\tmemset(&addr, '\\0', sizeof(addr));\n\taddr.sun_family = AF_UNIX;\n\n\tif (strlcpy(addr.sun_path, path,\n\t sizeof(addr.sun_path)) >= sizeof(addr.sun_path))\n\t\tfatal(\"ControlPath too long ('%s' >= %u bytes)\", path,\n\t\t (unsigned int)sizeof(addr.sun_path));\n\n\tif ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)\n\t\tfatal(\"%s socket(): %s\", __func__, strerror(errno));\n\n\tif (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {\n\t\tswitch (muxclient_command) {\n\t\tcase SSHMUX_COMMAND_OPEN:\n\t\tcase SSHMUX_COMMAND_STDIO_FWD:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfatal(\"Control socket connect(%.100s): %s\", path,\n\t\t\t strerror(errno));\n\t\t}\n\t\tif (errno == ECONNREFUSED &&\n\t\t options.control_master != SSHCTL_MASTER_NO) {\n\t\t\tdebug(\"Stale control socket %.100s, unlinking\", path);\n\t\t\tunlink(path);\n\t\t} else if (errno == ENOENT) {\n\t\t\tdebug(\"Control socket \\\"%.100s\\\" does not exist\", path);\n\t\t} else {\n\t\t\terror(\"Control socket connect(%.100s): %s\", path,\n\t\t\t strerror(errno));\n\t\t}\n\t\tclose(sock);\n\t\treturn -1;\n\t}\n\tset_nonblock(sock);\n\n\tif (mux_client_hello_exchange(sock) != 0) {\n\t\terror(\"%s: master hello exchange failed\", __func__);\n\t\tclose(sock);\n\t\treturn -1;\n\t}\n\n\tswitch (muxclient_command) {\n\tcase SSHMUX_COMMAND_ALIVE_CHECK:\n\t\tif ((pid = mux_client_request_alive(sock)) == 0)\n\t\t\tfatal(\"%s: master alive check failed\", __func__);\n\t\tfprintf(stderr, \"Master running (pid=%u)\\r\\n\", pid);\n\t\texit(0);\n\tcase SSHMUX_COMMAND_TERMINATE:\n\t\tmux_client_request_terminate(sock);\n\t\tif (options.log_level != SYSLOG_LEVEL_QUIET)\n\t\t\tfprintf(stderr, \"Exit request sent.\\r\\n\");\n\t\texit(0);\n\tcase SSHMUX_COMMAND_FORWARD:\n\t\tif (mux_client_forwards(sock, 0) != 0)\n\t\t\tfatal(\"%s: master forward request failed\", __func__);\n\t\texit(0);\n\tcase SSHMUX_COMMAND_OPEN:\n\t\tif (mux_client_forwards(sock, 0) != 0) {\n\t\t\terror(\"%s: master forward request failed\", __func__);\n\t\t\treturn -1;\n\t\t}\n\t\tmux_client_request_session(sock);\n\t\treturn -1;\n\tcase SSHMUX_COMMAND_STDIO_FWD:\n\t\tmux_client_request_stdio_fwd(sock);\n\t\texit(0);\n\tcase SSHMUX_COMMAND_STOP:\n\t\tmux_client_request_stop_listening(sock);\n\t\tif (options.log_level != SYSLOG_LEVEL_QUIET)\n\t\t\tfprintf(stderr, \"Stop listening request sent.\\r\\n\");\n\t\texit(0);\n\tcase SSHMUX_COMMAND_CANCEL_FWD:\n\t\tif (mux_client_forwards(sock, 1) != 0)\n\t\t\terror(\"%s: master cancel forward request failed\",\n\t\t\t __func__);\n\t\texit(0);\n\tcase SSHMUX_COMMAND_PROXY:\n\t\tmux_client_proxy(sock);\n\t\treturn (sock);\n\tdefault:\n\t\tfatal(\"unrecognised muxclient_command %d\", muxclient_command);\n\t}\n}\n","/*\t$OpenBSD: ssherr.c,v 1.5 2015/09/13 14:39:16 tim Exp $\t*/\n/*\n * Copyright (c) 2011 Damien Miller\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \n#include \n#include \"ssherr.h\"\n\nconst char *\nssh_err(int n)\n{\n\tswitch (n) {\n\tcase SSH_ERR_SUCCESS:\n\t\treturn \"success\";\n\tcase SSH_ERR_INTERNAL_ERROR:\n\t\treturn \"unexpected internal error\";\n\tcase SSH_ERR_ALLOC_FAIL:\n\t\treturn \"memory allocation failed\";\n\tcase SSH_ERR_MESSAGE_INCOMPLETE:\n\t\treturn \"incomplete message\";\n\tcase SSH_ERR_INVALID_FORMAT:\n\t\treturn \"invalid format\";\n\tcase SSH_ERR_BIGNUM_IS_NEGATIVE:\n\t\treturn \"bignum is negative\";\n\tcase SSH_ERR_STRING_TOO_LARGE:\n\t\treturn \"string is too large\";\n\tcase SSH_ERR_BIGNUM_TOO_LARGE:\n\t\treturn \"bignum is too large\";\n\tcase SSH_ERR_ECPOINT_TOO_LARGE:\n\t\treturn \"elliptic curve point is too large\";\n\tcase SSH_ERR_NO_BUFFER_SPACE:\n\t\treturn \"insufficient buffer space\";\n\tcase SSH_ERR_INVALID_ARGUMENT:\n\t\treturn \"invalid argument\";\n\tcase SSH_ERR_KEY_BITS_MISMATCH:\n\t\treturn \"key bits do not match\";\n\tcase SSH_ERR_EC_CURVE_INVALID:\n\t\treturn \"invalid elliptic curve\";\n\tcase SSH_ERR_KEY_TYPE_MISMATCH:\n\t\treturn \"key type does not match\";\n\tcase SSH_ERR_KEY_TYPE_UNKNOWN:\n\t\treturn \"unknown or unsupported key type\";\n\tcase SSH_ERR_EC_CURVE_MISMATCH:\n\t\treturn \"elliptic curve does not match\";\n\tcase SSH_ERR_EXPECTED_CERT:\n\t\treturn \"plain key provided where certificate required\";\n\tcase SSH_ERR_KEY_LACKS_CERTBLOB:\n\t\treturn \"key lacks certificate data\";\n\tcase SSH_ERR_KEY_CERT_UNKNOWN_TYPE:\n\t\treturn \"unknown/unsupported certificate type\";\n\tcase SSH_ERR_KEY_CERT_INVALID_SIGN_KEY:\n\t\treturn \"invalid certificate signing key\";\n\tcase SSH_ERR_KEY_INVALID_EC_VALUE:\n\t\treturn \"invalid elliptic curve value\";\n\tcase SSH_ERR_SIGNATURE_INVALID:\n\t\treturn \"incorrect signature\";\n\tcase SSH_ERR_LIBCRYPTO_ERROR:\n\t\treturn \"error in libcrypto\"; /* XXX fetch and return */\n\tcase SSH_ERR_UNEXPECTED_TRAILING_DATA:\n\t\treturn \"unexpected bytes remain after decoding\";\n\tcase SSH_ERR_SYSTEM_ERROR:\n\t\treturn strerror(errno);\n\tcase SSH_ERR_KEY_CERT_INVALID:\n\t\treturn \"invalid certificate\";\n\tcase SSH_ERR_AGENT_COMMUNICATION:\n\t\treturn \"communication with agent failed\";\n\tcase SSH_ERR_AGENT_FAILURE:\n\t\treturn \"agent refused operation\";\n\tcase SSH_ERR_DH_GEX_OUT_OF_RANGE:\n\t\treturn \"DH GEX group out of range\";\n\tcase SSH_ERR_DISCONNECTED:\n\t\treturn \"disconnected\";\n\tcase SSH_ERR_MAC_INVALID:\n\t\treturn \"message authentication code incorrect\";\n\tcase SSH_ERR_NO_CIPHER_ALG_MATCH:\n\t\treturn \"no matching cipher found\";\n\tcase SSH_ERR_NO_MAC_ALG_MATCH:\n\t\treturn \"no matching MAC found\";\n\tcase SSH_ERR_NO_COMPRESS_ALG_MATCH:\n\t\treturn \"no matching compression method found\";\n\tcase SSH_ERR_NO_KEX_ALG_MATCH:\n\t\treturn \"no matching key exchange method found\";\n\tcase SSH_ERR_NO_HOSTKEY_ALG_MATCH:\n\t\treturn \"no matching host key type found\";\n\tcase SSH_ERR_PROTOCOL_MISMATCH:\n\t\treturn \"protocol version mismatch\";\n\tcase SSH_ERR_NO_PROTOCOL_VERSION:\n\t\treturn \"could not read protocol version\";\n\tcase SSH_ERR_NO_HOSTKEY_LOADED:\n\t\treturn \"could not load host key\";\n\tcase SSH_ERR_NEED_REKEY:\n\t\treturn \"rekeying not supported by peer\";\n\tcase SSH_ERR_PASSPHRASE_TOO_SHORT:\n\t\treturn \"passphrase is too short (minimum five characters)\";\n\tcase SSH_ERR_FILE_CHANGED:\n\t\treturn \"file changed while reading\";\n\tcase SSH_ERR_KEY_UNKNOWN_CIPHER:\n\t\treturn \"key encrypted using unsupported cipher\";\n\tcase SSH_ERR_KEY_WRONG_PASSPHRASE:\n\t\treturn \"incorrect passphrase supplied to decrypt private key\";\n\tcase SSH_ERR_KEY_BAD_PERMISSIONS:\n\t\treturn \"bad permissions\";\n\tcase SSH_ERR_KEY_CERT_MISMATCH:\n\t\treturn \"certificate does not match key\";\n\tcase SSH_ERR_KEY_NOT_FOUND:\n\t\treturn \"key not found\";\n\tcase SSH_ERR_AGENT_NOT_PRESENT:\n\t\treturn \"agent not present\";\n\tcase SSH_ERR_AGENT_NO_IDENTITIES:\n\t\treturn \"agent contains no identities\";\n\tcase SSH_ERR_BUFFER_READ_ONLY:\n\t\treturn \"internal error: buffer is read-only\";\n\tcase SSH_ERR_KRL_BAD_MAGIC:\n\t\treturn \"KRL file has invalid magic number\";\n\tcase SSH_ERR_KEY_REVOKED:\n\t\treturn \"Key is revoked\";\n\tcase SSH_ERR_CONN_CLOSED:\n\t\treturn \"Connection closed\";\n\tcase SSH_ERR_CONN_TIMEOUT:\n\t\treturn \"Connection timed out\";\n\tcase SSH_ERR_CONN_CORRUPT:\n\t\treturn \"Connection corrupted\";\n\tcase SSH_ERR_PROTOCOL_ERROR:\n\t\treturn \"Protocol error\";\n\tdefault:\n\t\treturn \"unknown error\";\n\t}\n}\n","/*\t$OpenBSD: sshbuf.c,v 1.8 2016/11/25 23:22:04 djm Exp $\t*/\n/*\n * Copyright (c) 2011 Damien Miller\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#define SSHBUF_INTERNAL\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#include \n\n#include \"ssherr.h\"\n#include \"sshbuf.h\"\n#include \"misc.h\"\n\nstatic inline int\nsshbuf_check_sanity(const struct sshbuf *buf)\n{\n\tSSHBUF_TELL(\"sanity\");\n\tif (__predict_false(buf == NULL ||\n\t (!buf->readonly && buf->d != buf->cd) ||\n\t buf->refcount < 1 || buf->refcount > SSHBUF_REFS_MAX ||\n\t buf->cd == NULL ||\n\t (buf->dont_free && (buf->readonly || buf->parent != NULL)) ||\n\t buf->max_size > SSHBUF_SIZE_MAX ||\n\t buf->alloc > buf->max_size ||\n\t buf->size > buf->alloc ||\n\t buf->off > buf->size)) {\n\t\t/* Do not try to recover from corrupted buffer internals */\n\t\tSSHBUF_DBG((\"SSH_ERR_INTERNAL_ERROR\"));\n\t\tsignal(SIGSEGV, SIG_DFL);\n\t\traise(SIGSEGV);\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\treturn 0;\n}\n\nstatic void\nsshbuf_maybe_pack(struct sshbuf *buf, int force)\n{\n\tSSHBUF_DBG((\"force %d\", force));\n\tSSHBUF_TELL(\"pre-pack\");\n\tif (buf->off == 0 || buf->readonly || buf->refcount > 1)\n\t\treturn;\n\tif (force ||\n\t (buf->off >= SSHBUF_PACK_MIN && buf->off >= buf->size / 2)) {\n\t\tmemmove(buf->d, buf->d + buf->off, buf->size - buf->off);\n\t\tbuf->size -= buf->off;\n\t\tbuf->off = 0;\n\t\tSSHBUF_TELL(\"packed\");\n\t}\n}\n\nstruct sshbuf *\nsshbuf_new(void)\n{\n\tstruct sshbuf *ret;\n\n\tif ((ret = calloc(sizeof(*ret), 1)) == NULL)\n\t\treturn NULL;\n\tret->alloc = SSHBUF_SIZE_INIT;\n\tret->max_size = SSHBUF_SIZE_MAX;\n\tret->readonly = 0;\n\tret->refcount = 1;\n\tret->parent = NULL;\n\tif ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL) {\n\t\tfree(ret);\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nstruct sshbuf *\nsshbuf_from(const void *blob, size_t len)\n{\n\tstruct sshbuf *ret;\n\n\tif (blob == NULL || len > SSHBUF_SIZE_MAX ||\n\t (ret = calloc(sizeof(*ret), 1)) == NULL)\n\t\treturn NULL;\n\tret->alloc = ret->size = ret->max_size = len;\n\tret->readonly = 1;\n\tret->refcount = 1;\n\tret->parent = NULL;\n\tret->cd = blob;\n\tret->d = NULL;\n\treturn ret;\n}\n\nint\nsshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent)\n{\n\tint r;\n\n\tif ((r = sshbuf_check_sanity(child)) != 0 ||\n\t (r = sshbuf_check_sanity(parent)) != 0)\n\t\treturn r;\n\tchild->parent = parent;\n\tchild->parent->refcount++;\n\treturn 0;\n}\n\nstruct sshbuf *\nsshbuf_fromb(struct sshbuf *buf)\n{\n\tstruct sshbuf *ret;\n\n\tif (sshbuf_check_sanity(buf) != 0)\n\t\treturn NULL;\n\tif ((ret = sshbuf_from(sshbuf_ptr(buf), sshbuf_len(buf))) == NULL)\n\t\treturn NULL;\n\tif (sshbuf_set_parent(ret, buf) != 0) {\n\t\tsshbuf_free(ret);\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nvoid\nsshbuf_init(struct sshbuf *ret)\n{\n\texplicit_bzero(ret, sizeof(*ret));\n\tret->alloc = SSHBUF_SIZE_INIT;\n\tret->max_size = SSHBUF_SIZE_MAX;\n\tret->readonly = 0;\n\tret->dont_free = 1;\n\tret->refcount = 1;\n\tif ((ret->cd = ret->d = calloc(1, ret->alloc)) == NULL)\n\t\tret->alloc = 0;\n}\n\nvoid\nsshbuf_free(struct sshbuf *buf)\n{\n\tint dont_free = 0;\n\n\tif (buf == NULL)\n\t\treturn;\n\t/*\n\t * The following will leak on insane buffers, but this is the safest\n\t * course of action - an invalid pointer or already-freed pointer may\n\t * have been passed to us and continuing to scribble over memory would\n\t * be bad.\n\t */\n\tif (sshbuf_check_sanity(buf) != 0)\n\t\treturn;\n\t/*\n\t * If we are a child, the free our parent to decrement its reference\n\t * count and possibly free it.\n\t */\n\tsshbuf_free(buf->parent);\n\tbuf->parent = NULL;\n\t/*\n\t * If we are a parent with still-extant children, then don't free just\n\t * yet. The last child's call to sshbuf_free should decrement our\n\t * refcount to 0 and trigger the actual free.\n\t */\n\tbuf->refcount--;\n\tif (buf->refcount > 0)\n\t\treturn;\n\tdont_free = buf->dont_free;\n\tif (!buf->readonly) {\n\t\texplicit_bzero(buf->d, buf->alloc);\n\t\tfree(buf->d);\n\t}\n\texplicit_bzero(buf, sizeof(*buf));\n\tif (!dont_free)\n\t\tfree(buf);\n}\n\nvoid\nsshbuf_reset(struct sshbuf *buf)\n{\n\tu_char *d;\n\n\tif (buf->readonly || buf->refcount > 1) {\n\t\t/* Nonsensical. Just make buffer appear empty */\n\t\tbuf->off = buf->size;\n\t\treturn;\n\t}\n\tif (sshbuf_check_sanity(buf) == 0)\n\t\texplicit_bzero(buf->d, buf->alloc);\n\tbuf->off = buf->size = 0;\n\tif (buf->alloc != SSHBUF_SIZE_INIT) {\n\t\tif ((d = realloc(buf->d, SSHBUF_SIZE_INIT)) != NULL) {\n\t\t\tbuf->cd = buf->d = d;\n\t\t\tbuf->alloc = SSHBUF_SIZE_INIT;\n\t\t}\n\t}\n}\n\nsize_t\nsshbuf_max_size(const struct sshbuf *buf)\n{\n\treturn buf->max_size;\n}\n\nsize_t\nsshbuf_alloc(const struct sshbuf *buf)\n{\n\treturn buf->alloc;\n}\n\nconst struct sshbuf *\nsshbuf_parent(const struct sshbuf *buf)\n{\n\treturn buf->parent;\n}\n\nu_int\nsshbuf_refcount(const struct sshbuf *buf)\n{\n\treturn buf->refcount;\n}\n\nint\nsshbuf_set_max_size(struct sshbuf *buf, size_t max_size)\n{\n\tsize_t rlen;\n\tu_char *dp;\n\tint r;\n\n\tSSHBUF_DBG((\"set max buf = %p len = %zu\", buf, max_size));\n\tif ((r = sshbuf_check_sanity(buf)) != 0)\n\t\treturn r;\n\tif (max_size == buf->max_size)\n\t\treturn 0;\n\tif (buf->readonly || buf->refcount > 1)\n\t\treturn SSH_ERR_BUFFER_READ_ONLY;\n\tif (max_size > SSHBUF_SIZE_MAX)\n\t\treturn SSH_ERR_NO_BUFFER_SPACE;\n\t/* pack and realloc if necessary */\n\tsshbuf_maybe_pack(buf, max_size < buf->size);\n\tif (max_size < buf->alloc && max_size > buf->size) {\n\t\tif (buf->size < SSHBUF_SIZE_INIT)\n\t\t\trlen = SSHBUF_SIZE_INIT;\n\t\telse\n\t\t\trlen = ROUNDUP(buf->size, SSHBUF_SIZE_INC);\n\t\tif (rlen > max_size)\n\t\t\trlen = max_size;\n\t\texplicit_bzero(buf->d + buf->size, buf->alloc - buf->size);\n\t\tSSHBUF_DBG((\"new alloc = %zu\", rlen));\n\t\tif ((dp = realloc(buf->d, rlen)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tbuf->cd = buf->d = dp;\n\t\tbuf->alloc = rlen;\n\t}\n\tSSHBUF_TELL(\"new-max\");\n\tif (max_size < buf->alloc)\n\t\treturn SSH_ERR_NO_BUFFER_SPACE;\n\tbuf->max_size = max_size;\n\treturn 0;\n}\n\nsize_t\nsshbuf_len(const struct sshbuf *buf)\n{\n\tif (sshbuf_check_sanity(buf) != 0)\n\t\treturn 0;\n\treturn buf->size - buf->off;\n}\n\nsize_t\nsshbuf_avail(const struct sshbuf *buf)\n{\n\tif (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1)\n\t\treturn 0;\n\treturn buf->max_size - (buf->size - buf->off);\n}\n\nconst u_char *\nsshbuf_ptr(const struct sshbuf *buf)\n{\n\tif (sshbuf_check_sanity(buf) != 0)\n\t\treturn NULL;\n\treturn buf->cd + buf->off;\n}\n\nu_char *\nsshbuf_mutable_ptr(const struct sshbuf *buf)\n{\n\tif (sshbuf_check_sanity(buf) != 0 || buf->readonly || buf->refcount > 1)\n\t\treturn NULL;\n\treturn buf->d + buf->off;\n}\n\nint\nsshbuf_check_reserve(const struct sshbuf *buf, size_t len)\n{\n\tint r;\n\n\tif ((r = sshbuf_check_sanity(buf)) != 0)\n\t\treturn r;\n\tif (buf->readonly || buf->refcount > 1)\n\t\treturn SSH_ERR_BUFFER_READ_ONLY;\n\tSSHBUF_TELL(\"check\");\n\t/* Check that len is reasonable and that max_size + available < len */\n\tif (len > buf->max_size || buf->max_size - len < buf->size - buf->off)\n\t\treturn SSH_ERR_NO_BUFFER_SPACE;\n\treturn 0;\n}\n\nint\nsshbuf_allocate(struct sshbuf *buf, size_t len)\n{\n\tsize_t rlen, need;\n\tu_char *dp;\n\tint r;\n\n\tSSHBUF_DBG((\"allocate buf = %p len = %zu\", buf, len));\n\tif ((r = sshbuf_check_reserve(buf, len)) != 0)\n\t\treturn r;\n\t/*\n\t * If the requested allocation appended would push us past max_size\n\t * then pack the buffer, zeroing buf->off.\n\t */\n\tsshbuf_maybe_pack(buf, buf->size + len > buf->max_size);\n\tSSHBUF_TELL(\"allocate\");\n\tif (len + buf->size <= buf->alloc)\n\t\treturn 0; /* already have it. */\n\n\t/*\n\t * Prefer to alloc in SSHBUF_SIZE_INC units, but\n\t * allocate less if doing so would overflow max_size.\n\t */\n\tneed = len + buf->size - buf->alloc;\n\trlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC);\n\tSSHBUF_DBG((\"need %zu initial rlen %zu\", need, rlen));\n\tif (rlen > buf->max_size)\n\t\trlen = buf->alloc + need;\n\tSSHBUF_DBG((\"adjusted rlen %zu\", rlen));\n\tif ((dp = realloc(buf->d, rlen)) == NULL) {\n\t\tSSHBUF_DBG((\"realloc fail\"));\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\t}\n\tbuf->alloc = rlen;\n\tbuf->cd = buf->d = dp;\n\tif ((r = sshbuf_check_reserve(buf, len)) < 0) {\n\t\t/* shouldn't fail */\n\t\treturn r;\n\t}\n\tSSHBUF_TELL(\"done\");\n\treturn 0;\n}\n\nint\nsshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp)\n{\n\tu_char *dp;\n\tint r;\n\n\tif (dpp != NULL)\n\t\t*dpp = NULL;\n\n\tSSHBUF_DBG((\"reserve buf = %p len = %zu\", buf, len));\n\tif ((r = sshbuf_allocate(buf, len)) != 0)\n\t\treturn r;\n\n\tdp = buf->d + buf->size;\n\tbuf->size += len;\n\tif (dpp != NULL)\n\t\t*dpp = dp;\n\treturn 0;\n}\n\nint\nsshbuf_consume(struct sshbuf *buf, size_t len)\n{\n\tint r;\n\n\tSSHBUF_DBG((\"len = %zu\", len));\n\tif ((r = sshbuf_check_sanity(buf)) != 0)\n\t\treturn r;\n\tif (len == 0)\n\t\treturn 0;\n\tif (len > sshbuf_len(buf))\n\t\treturn SSH_ERR_MESSAGE_INCOMPLETE;\n\tbuf->off += len;\n\tSSHBUF_TELL(\"done\");\n\treturn 0;\n}\n\nint\nsshbuf_consume_end(struct sshbuf *buf, size_t len)\n{\n\tint r;\n\n\tSSHBUF_DBG((\"len = %zu\", len));\n\tif ((r = sshbuf_check_sanity(buf)) != 0)\n\t\treturn r;\n\tif (len == 0)\n\t\treturn 0;\n\tif (len > sshbuf_len(buf))\n\t\treturn SSH_ERR_MESSAGE_INCOMPLETE;\n\tbuf->size -= len;\n\tSSHBUF_TELL(\"done\");\n\treturn 0;\n}\n\n","/* $OpenBSD: sshkey.c,v 1.45 2017/03/10 04:07:20 djm Exp $ */\n/*\n * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.\n * Copyright (c) 2008 Alexander von Gernler. All rights reserved.\n * Copyright (c) 2010,2011 Damien Miller. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#ifdef WITH_OPENSSL\n#include \n#include \n#include \n#endif\n\n#include \"crypto_api.h\"\n\n#include \n#include \n#include \n#include \n#include \n#ifdef HAVE_UTIL_H\n#include \n#endif /* HAVE_UTIL_H */\n\n#include \"ssh2.h\"\n#include \"ssherr.h\"\n#include \"misc.h\"\n#include \"sshbuf.h\"\n#include \"rsa.h\"\n#include \"cipher.h\"\n#include \"digest.h\"\n#define SSHKEY_INTERNAL\n#include \"sshkey.h\"\n#include \"match.h\"\n\n/* openssh private key file format */\n#define MARK_BEGIN\t\t\"-----BEGIN OPENSSH PRIVATE KEY-----\\n\"\n#define MARK_END\t\t\"-----END OPENSSH PRIVATE KEY-----\\n\"\n#define MARK_BEGIN_LEN\t\t(sizeof(MARK_BEGIN) - 1)\n#define MARK_END_LEN\t\t(sizeof(MARK_END) - 1)\n#define KDFNAME\t\t\t\"bcrypt\"\n#define AUTH_MAGIC\t\t\"openssh-key-v1\"\n#define SALT_LEN\t\t16\n#define DEFAULT_CIPHERNAME\t\"aes256-cbc\"\n#define\tDEFAULT_ROUNDS\t\t16\n\n/* Version identification string for SSH v1 identity files. */\n#define LEGACY_BEGIN\t\t\"SSH PRIVATE KEY FILE FORMAT 1.1\\n\"\n\nstatic int sshkey_from_blob_internal(struct sshbuf *buf,\n struct sshkey **keyp, int allow_cert);\n\n/* Supported key types */\nstruct keytype {\n\tconst char *name;\n\tconst char *shortname;\n\tint type;\n\tint nid;\n\tint cert;\n\tint sigonly;\n};\nstatic const struct keytype keytypes[] = {\n\t{ \"ssh-ed25519\", \"ED25519\", KEY_ED25519, 0, 0, 0 },\n\t{ \"ssh-ed25519-cert-v01@openssh.com\", \"ED25519-CERT\",\n\t KEY_ED25519_CERT, 0, 1, 0 },\n#ifdef WITH_OPENSSL\n# ifdef WITH_SSH1\n\t{ NULL, \"RSA1\", KEY_RSA1, 0, 0, 0 },\n# endif\n\t{ \"ssh-rsa\", \"RSA\", KEY_RSA, 0, 0, 0 },\n\t{ \"rsa-sha2-256\", \"RSA\", KEY_RSA, 0, 0, 1 },\n\t{ \"rsa-sha2-512\", \"RSA\", KEY_RSA, 0, 0, 1 },\n\t{ \"ssh-dss\", \"DSA\", KEY_DSA, 0, 0, 0 },\n# ifdef OPENSSL_HAS_ECC\n\t{ \"ecdsa-sha2-nistp256\", \"ECDSA\", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 },\n\t{ \"ecdsa-sha2-nistp384\", \"ECDSA\", KEY_ECDSA, NID_secp384r1, 0, 0 },\n# ifdef OPENSSL_HAS_NISTP521\n\t{ \"ecdsa-sha2-nistp521\", \"ECDSA\", KEY_ECDSA, NID_secp521r1, 0, 0 },\n# endif /* OPENSSL_HAS_NISTP521 */\n# endif /* OPENSSL_HAS_ECC */\n\t{ \"ssh-rsa-cert-v01@openssh.com\", \"RSA-CERT\", KEY_RSA_CERT, 0, 1, 0 },\n\t{ \"ssh-dss-cert-v01@openssh.com\", \"DSA-CERT\", KEY_DSA_CERT, 0, 1, 0 },\n# ifdef OPENSSL_HAS_ECC\n\t{ \"ecdsa-sha2-nistp256-cert-v01@openssh.com\", \"ECDSA-CERT\",\n\t KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 },\n\t{ \"ecdsa-sha2-nistp384-cert-v01@openssh.com\", \"ECDSA-CERT\",\n\t KEY_ECDSA_CERT, NID_secp384r1, 1, 0 },\n# ifdef OPENSSL_HAS_NISTP521\n\t{ \"ecdsa-sha2-nistp521-cert-v01@openssh.com\", \"ECDSA-CERT\",\n\t KEY_ECDSA_CERT, NID_secp521r1, 1, 0 },\n# endif /* OPENSSL_HAS_NISTP521 */\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\t{ NULL, NULL, -1, -1, 0, 0 }\n};\n\nconst char *\nsshkey_type(const struct sshkey *k)\n{\n\tconst struct keytype *kt;\n\n\tfor (kt = keytypes; kt->type != -1; kt++) {\n\t\tif (kt->type == k->type)\n\t\t\treturn kt->shortname;\n\t}\n\treturn \"unknown\";\n}\n\nstatic const char *\nsshkey_ssh_name_from_type_nid(int type, int nid)\n{\n\tconst struct keytype *kt;\n\n\tfor (kt = keytypes; kt->type != -1; kt++) {\n\t\tif (kt->type == type && (kt->nid == 0 || kt->nid == nid))\n\t\t\treturn kt->name;\n\t}\n\treturn \"ssh-unknown\";\n}\n\nint\nsshkey_type_is_cert(int type)\n{\n\tconst struct keytype *kt;\n\n\tfor (kt = keytypes; kt->type != -1; kt++) {\n\t\tif (kt->type == type)\n\t\t\treturn kt->cert;\n\t}\n\treturn 0;\n}\n\nconst char *\nsshkey_ssh_name(const struct sshkey *k)\n{\n\treturn sshkey_ssh_name_from_type_nid(k->type, k->ecdsa_nid);\n}\n\nconst char *\nsshkey_ssh_name_plain(const struct sshkey *k)\n{\n\treturn sshkey_ssh_name_from_type_nid(sshkey_type_plain(k->type),\n\t k->ecdsa_nid);\n}\n\nint\nsshkey_type_from_name(const char *name)\n{\n\tconst struct keytype *kt;\n\n\tfor (kt = keytypes; kt->type != -1; kt++) {\n\t\t/* Only allow shortname matches for plain key types */\n\t\tif ((kt->name != NULL && strcmp(name, kt->name) == 0) ||\n\t\t (!kt->cert && strcasecmp(kt->shortname, name) == 0))\n\t\t\treturn kt->type;\n\t}\n\treturn KEY_UNSPEC;\n}\n\nint\nsshkey_ecdsa_nid_from_name(const char *name)\n{\n\tconst struct keytype *kt;\n\n\tfor (kt = keytypes; kt->type != -1; kt++) {\n\t\tif (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT)\n\t\t\tcontinue;\n\t\tif (kt->name != NULL && strcmp(name, kt->name) == 0)\n\t\t\treturn kt->nid;\n\t}\n\treturn -1;\n}\n\nchar *\nsshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)\n{\n\tchar *tmp, *ret = NULL;\n\tsize_t nlen, rlen = 0;\n\tconst struct keytype *kt;\n\n\tfor (kt = keytypes; kt->type != -1; kt++) {\n\t\tif (kt->name == NULL)\n\t\t\tcontinue;\n\t\tif (!include_sigonly && kt->sigonly)\n\t\t\tcontinue;\n\t\tif ((certs_only && !kt->cert) || (plain_only && kt->cert))\n\t\t\tcontinue;\n\t\tif (ret != NULL)\n\t\t\tret[rlen++] = sep;\n\t\tnlen = strlen(kt->name);\n\t\tif ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {\n\t\t\tfree(ret);\n\t\t\treturn NULL;\n\t\t}\n\t\tret = tmp;\n\t\tmemcpy(ret + rlen, kt->name, nlen + 1);\n\t\trlen += nlen;\n\t}\n\treturn ret;\n}\n\nint\nsshkey_names_valid2(const char *names, int allow_wildcard)\n{\n\tchar *s, *cp, *p;\n\tconst struct keytype *kt;\n\tint type;\n\n\tif (names == NULL || strcmp(names, \"\") == 0)\n\t\treturn 0;\n\tif ((s = cp = strdup(names)) == NULL)\n\t\treturn 0;\n\tfor ((p = strsep(&cp, \",\")); p && *p != '\\0';\n\t (p = strsep(&cp, \",\"))) {\n\t\ttype = sshkey_type_from_name(p);\n\t\tif (type == KEY_RSA1) {\n\t\t\tfree(s);\n\t\t\treturn 0;\n\t\t}\n\t\tif (type == KEY_UNSPEC) {\n\t\t\tif (allow_wildcard) {\n\t\t\t\t/*\n\t\t\t\t * Try matching key types against the string.\n\t\t\t\t * If any has a positive or negative match then\n\t\t\t\t * the component is accepted.\n\t\t\t\t */\n\t\t\t\tfor (kt = keytypes; kt->type != -1; kt++) {\n\t\t\t\t\tif (kt->type == KEY_RSA1)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif (match_pattern_list(kt->name,\n\t\t\t\t\t p, 0) != 0)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (kt->type != -1)\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfree(s);\n\t\t\treturn 0;\n\t\t}\n\t}\n\tfree(s);\n\treturn 1;\n}\n\nu_int\nsshkey_size(const struct sshkey *k)\n{\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA1:\n\tcase KEY_RSA:\n\tcase KEY_RSA_CERT:\n\t\treturn BN_num_bits(k->rsa->n);\n\tcase KEY_DSA:\n\tcase KEY_DSA_CERT:\n\t\treturn BN_num_bits(k->dsa->p);\n\tcase KEY_ECDSA:\n\tcase KEY_ECDSA_CERT:\n\t\treturn sshkey_curve_nid_to_bits(k->ecdsa_nid);\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\treturn 256;\t/* XXX */\n\t}\n\treturn 0;\n}\n\nstatic int\nsshkey_type_is_valid_ca(int type)\n{\n\tswitch (type) {\n\tcase KEY_RSA:\n\tcase KEY_DSA:\n\tcase KEY_ECDSA:\n\tcase KEY_ED25519:\n\t\treturn 1;\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nint\nsshkey_is_cert(const struct sshkey *k)\n{\n\tif (k == NULL)\n\t\treturn 0;\n\treturn sshkey_type_is_cert(k->type);\n}\n\n/* Return the cert-less equivalent to a certified key type */\nint\nsshkey_type_plain(int type)\n{\n\tswitch (type) {\n\tcase KEY_RSA_CERT:\n\t\treturn KEY_RSA;\n\tcase KEY_DSA_CERT:\n\t\treturn KEY_DSA;\n\tcase KEY_ECDSA_CERT:\n\t\treturn KEY_ECDSA;\n\tcase KEY_ED25519_CERT:\n\t\treturn KEY_ED25519;\n\tdefault:\n\t\treturn type;\n\t}\n}\n\n#ifdef WITH_OPENSSL\n/* XXX: these are really begging for a table-driven approach */\nint\nsshkey_curve_name_to_nid(const char *name)\n{\n\tif (strcmp(name, \"nistp256\") == 0)\n\t\treturn NID_X9_62_prime256v1;\n\telse if (strcmp(name, \"nistp384\") == 0)\n\t\treturn NID_secp384r1;\n# ifdef OPENSSL_HAS_NISTP521\n\telse if (strcmp(name, \"nistp521\") == 0)\n\t\treturn NID_secp521r1;\n# endif /* OPENSSL_HAS_NISTP521 */\n\telse\n\t\treturn -1;\n}\n\nu_int\nsshkey_curve_nid_to_bits(int nid)\n{\n\tswitch (nid) {\n\tcase NID_X9_62_prime256v1:\n\t\treturn 256;\n\tcase NID_secp384r1:\n\t\treturn 384;\n# ifdef OPENSSL_HAS_NISTP521\n\tcase NID_secp521r1:\n\t\treturn 521;\n# endif /* OPENSSL_HAS_NISTP521 */\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nint\nsshkey_ecdsa_bits_to_nid(int bits)\n{\n\tswitch (bits) {\n\tcase 256:\n\t\treturn NID_X9_62_prime256v1;\n\tcase 384:\n\t\treturn NID_secp384r1;\n# ifdef OPENSSL_HAS_NISTP521\n\tcase 521:\n\t\treturn NID_secp521r1;\n# endif /* OPENSSL_HAS_NISTP521 */\n\tdefault:\n\t\treturn -1;\n\t}\n}\n\nconst char *\nsshkey_curve_nid_to_name(int nid)\n{\n\tswitch (nid) {\n\tcase NID_X9_62_prime256v1:\n\t\treturn \"nistp256\";\n\tcase NID_secp384r1:\n\t\treturn \"nistp384\";\n# ifdef OPENSSL_HAS_NISTP521\n\tcase NID_secp521r1:\n\t\treturn \"nistp521\";\n# endif /* OPENSSL_HAS_NISTP521 */\n\tdefault:\n\t\treturn NULL;\n\t}\n}\n\nint\nsshkey_ec_nid_to_hash_alg(int nid)\n{\n\tint kbits = sshkey_curve_nid_to_bits(nid);\n\n\tif (kbits <= 0)\n\t\treturn -1;\n\n\t/* RFC5656 section 6.2.1 */\n\tif (kbits <= 256)\n\t\treturn SSH_DIGEST_SHA256;\n\telse if (kbits <= 384)\n\t\treturn SSH_DIGEST_SHA384;\n\telse\n\t\treturn SSH_DIGEST_SHA512;\n}\n#endif /* WITH_OPENSSL */\n\nstatic void\ncert_free(struct sshkey_cert *cert)\n{\n\tu_int i;\n\n\tif (cert == NULL)\n\t\treturn;\n\tsshbuf_free(cert->certblob);\n\tsshbuf_free(cert->critical);\n\tsshbuf_free(cert->extensions);\n\tfree(cert->key_id);\n\tfor (i = 0; i < cert->nprincipals; i++)\n\t\tfree(cert->principals[i]);\n\tfree(cert->principals);\n\tsshkey_free(cert->signature_key);\n\texplicit_bzero(cert, sizeof(*cert));\n\tfree(cert);\n}\n\nstatic struct sshkey_cert *\ncert_new(void)\n{\n\tstruct sshkey_cert *cert;\n\n\tif ((cert = calloc(1, sizeof(*cert))) == NULL)\n\t\treturn NULL;\n\tif ((cert->certblob = sshbuf_new()) == NULL ||\n\t (cert->critical = sshbuf_new()) == NULL ||\n\t (cert->extensions = sshbuf_new()) == NULL) {\n\t\tcert_free(cert);\n\t\treturn NULL;\n\t}\n\tcert->key_id = NULL;\n\tcert->principals = NULL;\n\tcert->signature_key = NULL;\n\treturn cert;\n}\n\nstruct sshkey *\nsshkey_new(int type)\n{\n\tstruct sshkey *k;\n#ifdef WITH_OPENSSL\n\tRSA *rsa;\n\tDSA *dsa;\n#endif /* WITH_OPENSSL */\n\n\tif ((k = calloc(1, sizeof(*k))) == NULL)\n\t\treturn NULL;\n\tk->type = type;\n\tk->ecdsa = NULL;\n\tk->ecdsa_nid = -1;\n\tk->dsa = NULL;\n\tk->rsa = NULL;\n\tk->cert = NULL;\n\tk->ed25519_sk = NULL;\n\tk->ed25519_pk = NULL;\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA1:\n\tcase KEY_RSA:\n\tcase KEY_RSA_CERT:\n\t\tif ((rsa = RSA_new()) == NULL ||\n\t\t (rsa->n = BN_new()) == NULL ||\n\t\t (rsa->e = BN_new()) == NULL) {\n\t\t\tif (rsa != NULL)\n\t\t\t\tRSA_free(rsa);\n\t\t\tfree(k);\n\t\t\treturn NULL;\n\t\t}\n\t\tk->rsa = rsa;\n\t\tbreak;\n\tcase KEY_DSA:\n\tcase KEY_DSA_CERT:\n\t\tif ((dsa = DSA_new()) == NULL ||\n\t\t (dsa->p = BN_new()) == NULL ||\n\t\t (dsa->q = BN_new()) == NULL ||\n\t\t (dsa->g = BN_new()) == NULL ||\n\t\t (dsa->pub_key = BN_new()) == NULL) {\n\t\t\tif (dsa != NULL)\n\t\t\t\tDSA_free(dsa);\n\t\t\tfree(k);\n\t\t\treturn NULL;\n\t\t}\n\t\tk->dsa = dsa;\n\t\tbreak;\n\tcase KEY_ECDSA:\n\tcase KEY_ECDSA_CERT:\n\t\t/* Cannot do anything until we know the group */\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\t/* no need to prealloc */\n\t\tbreak;\n\tcase KEY_UNSPEC:\n\t\tbreak;\n\tdefault:\n\t\tfree(k);\n\t\treturn NULL;\n\t}\n\n\tif (sshkey_is_cert(k)) {\n\t\tif ((k->cert = cert_new()) == NULL) {\n\t\t\tsshkey_free(k);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\treturn k;\n}\n\nint\nsshkey_add_private(struct sshkey *k)\n{\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA1:\n\tcase KEY_RSA:\n\tcase KEY_RSA_CERT:\n#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)\n\t\tif (bn_maybe_alloc_failed(k->rsa->d) ||\n\t\t bn_maybe_alloc_failed(k->rsa->iqmp) ||\n\t\t bn_maybe_alloc_failed(k->rsa->q) ||\n\t\t bn_maybe_alloc_failed(k->rsa->p) ||\n\t\t bn_maybe_alloc_failed(k->rsa->dmq1) ||\n\t\t bn_maybe_alloc_failed(k->rsa->dmp1))\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tbreak;\n\tcase KEY_DSA:\n\tcase KEY_DSA_CERT:\n\t\tif (bn_maybe_alloc_failed(k->dsa->priv_key))\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tbreak;\n#undef bn_maybe_alloc_failed\n\tcase KEY_ECDSA:\n\tcase KEY_ECDSA_CERT:\n\t\t/* Cannot do anything until we know the group */\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\t/* no need to prealloc */\n\t\tbreak;\n\tcase KEY_UNSPEC:\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n\treturn 0;\n}\n\nstruct sshkey *\nsshkey_new_private(int type)\n{\n\tstruct sshkey *k = sshkey_new(type);\n\n\tif (k == NULL)\n\t\treturn NULL;\n\tif (sshkey_add_private(k) != 0) {\n\t\tsshkey_free(k);\n\t\treturn NULL;\n\t}\n\treturn k;\n}\n\nvoid\nsshkey_free(struct sshkey *k)\n{\n\tif (k == NULL)\n\t\treturn;\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA1:\n\tcase KEY_RSA:\n\tcase KEY_RSA_CERT:\n\t\tif (k->rsa != NULL)\n\t\t\tRSA_free(k->rsa);\n\t\tk->rsa = NULL;\n\t\tbreak;\n\tcase KEY_DSA:\n\tcase KEY_DSA_CERT:\n\t\tif (k->dsa != NULL)\n\t\t\tDSA_free(k->dsa);\n\t\tk->dsa = NULL;\n\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\tcase KEY_ECDSA_CERT:\n\t\tif (k->ecdsa != NULL)\n\t\t\tEC_KEY_free(k->ecdsa);\n\t\tk->ecdsa = NULL;\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\tif (k->ed25519_pk) {\n\t\t\texplicit_bzero(k->ed25519_pk, ED25519_PK_SZ);\n\t\t\tfree(k->ed25519_pk);\n\t\t\tk->ed25519_pk = NULL;\n\t\t}\n\t\tif (k->ed25519_sk) {\n\t\t\texplicit_bzero(k->ed25519_sk, ED25519_SK_SZ);\n\t\t\tfree(k->ed25519_sk);\n\t\t\tk->ed25519_sk = NULL;\n\t\t}\n\t\tbreak;\n\tcase KEY_UNSPEC:\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\tif (sshkey_is_cert(k))\n\t\tcert_free(k->cert);\n\texplicit_bzero(k, sizeof(*k));\n\tfree(k);\n}\n\nstatic int\ncert_compare(struct sshkey_cert *a, struct sshkey_cert *b)\n{\n\tif (a == NULL && b == NULL)\n\t\treturn 1;\n\tif (a == NULL || b == NULL)\n\t\treturn 0;\n\tif (sshbuf_len(a->certblob) != sshbuf_len(b->certblob))\n\t\treturn 0;\n\tif (timingsafe_bcmp(sshbuf_ptr(a->certblob), sshbuf_ptr(b->certblob),\n\t sshbuf_len(a->certblob)) != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\n/*\n * Compare public portions of key only, allowing comparisons between\n * certificates and plain keys too.\n */\nint\nsshkey_equal_public(const struct sshkey *a, const struct sshkey *b)\n{\n#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)\n\tBN_CTX *bnctx;\n#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */\n\n\tif (a == NULL || b == NULL ||\n\t sshkey_type_plain(a->type) != sshkey_type_plain(b->type))\n\t\treturn 0;\n\n\tswitch (a->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA1:\n\tcase KEY_RSA_CERT:\n\tcase KEY_RSA:\n\t\treturn a->rsa != NULL && b->rsa != NULL &&\n\t\t BN_cmp(a->rsa->e, b->rsa->e) == 0 &&\n\t\t BN_cmp(a->rsa->n, b->rsa->n) == 0;\n\tcase KEY_DSA_CERT:\n\tcase KEY_DSA:\n\t\treturn a->dsa != NULL && b->dsa != NULL &&\n\t\t BN_cmp(a->dsa->p, b->dsa->p) == 0 &&\n\t\t BN_cmp(a->dsa->q, b->dsa->q) == 0 &&\n\t\t BN_cmp(a->dsa->g, b->dsa->g) == 0 &&\n\t\t BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA_CERT:\n\tcase KEY_ECDSA:\n\t\tif (a->ecdsa == NULL || b->ecdsa == NULL ||\n\t\t EC_KEY_get0_public_key(a->ecdsa) == NULL ||\n\t\t EC_KEY_get0_public_key(b->ecdsa) == NULL)\n\t\t\treturn 0;\n\t\tif ((bnctx = BN_CTX_new()) == NULL)\n\t\t\treturn 0;\n\t\tif (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa),\n\t\t EC_KEY_get0_group(b->ecdsa), bnctx) != 0 ||\n\t\t EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa),\n\t\t EC_KEY_get0_public_key(a->ecdsa),\n\t\t EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) {\n\t\t\tBN_CTX_free(bnctx);\n\t\t\treturn 0;\n\t\t}\n\t\tBN_CTX_free(bnctx);\n\t\treturn 1;\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\treturn a->ed25519_pk != NULL && b->ed25519_pk != NULL &&\n\t\t memcmp(a->ed25519_pk, b->ed25519_pk, ED25519_PK_SZ) == 0;\n\tdefault:\n\t\treturn 0;\n\t}\n\t/* NOTREACHED */\n}\n\nint\nsshkey_equal(const struct sshkey *a, const struct sshkey *b)\n{\n\tif (a == NULL || b == NULL || a->type != b->type)\n\t\treturn 0;\n\tif (sshkey_is_cert(a)) {\n\t\tif (!cert_compare(a->cert, b->cert))\n\t\t\treturn 0;\n\t}\n\treturn sshkey_equal_public(a, b);\n}\n\nstatic int\nto_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain)\n{\n\tint type, ret = SSH_ERR_INTERNAL_ERROR;\n\tconst char *typename;\n\n\tif (key == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\n\tif (sshkey_is_cert(key)) {\n\t\tif (key->cert == NULL)\n\t\t\treturn SSH_ERR_EXPECTED_CERT;\n\t\tif (sshbuf_len(key->cert->certblob) == 0)\n\t\t\treturn SSH_ERR_KEY_LACKS_CERTBLOB;\n\t}\n\ttype = force_plain ? sshkey_type_plain(key->type) : key->type;\n\ttypename = sshkey_ssh_name_from_type_nid(type, key->ecdsa_nid);\n\n\tswitch (type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA_CERT:\n\tcase KEY_ECDSA_CERT:\n\tcase KEY_RSA_CERT:\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519_CERT:\n\t\t/* Use the existing blob */\n\t\t/* XXX modified flag? */\n\t\tif ((ret = sshbuf_putb(b, key->cert->certblob)) != 0)\n\t\t\treturn ret;\n\t\tbreak;\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA:\n\t\tif (key->dsa == NULL)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\tif ((ret = sshbuf_put_cstring(b, typename)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0)\n\t\t\treturn ret;\n\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\t\tif (key->ecdsa == NULL)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\tif ((ret = sshbuf_put_cstring(b, typename)) != 0 ||\n\t\t (ret = sshbuf_put_cstring(b,\n\t\t sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||\n\t\t (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0)\n\t\t\treturn ret;\n\t\tbreak;\n# endif\n\tcase KEY_RSA:\n\t\tif (key->rsa == NULL)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\tif ((ret = sshbuf_put_cstring(b, typename)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0)\n\t\t\treturn ret;\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\t\tif (key->ed25519_pk == NULL)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\tif ((ret = sshbuf_put_cstring(b, typename)) != 0 ||\n\t\t (ret = sshbuf_put_string(b,\n\t\t key->ed25519_pk, ED25519_PK_SZ)) != 0)\n\t\t\treturn ret;\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\t}\n\treturn 0;\n}\n\nint\nsshkey_putb(const struct sshkey *key, struct sshbuf *b)\n{\n\treturn to_blob_buf(key, b, 0);\n}\n\nint\nsshkey_puts(const struct sshkey *key, struct sshbuf *b)\n{\n\tstruct sshbuf *tmp;\n\tint r;\n\n\tif ((tmp = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tr = to_blob_buf(key, tmp, 0);\n\tif (r == 0)\n\t\tr = sshbuf_put_stringb(b, tmp);\n\tsshbuf_free(tmp);\n\treturn r;\n}\n\nint\nsshkey_putb_plain(const struct sshkey *key, struct sshbuf *b)\n{\n\treturn to_blob_buf(key, b, 1);\n}\n\nstatic int\nto_blob(const struct sshkey *key, u_char **blobp, size_t *lenp, int force_plain)\n{\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\tsize_t len;\n\tstruct sshbuf *b = NULL;\n\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif (blobp != NULL)\n\t\t*blobp = NULL;\n\tif ((b = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((ret = to_blob_buf(key, b, force_plain)) != 0)\n\t\tgoto out;\n\tlen = sshbuf_len(b);\n\tif (lenp != NULL)\n\t\t*lenp = len;\n\tif (blobp != NULL) {\n\t\tif ((*blobp = malloc(len)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tmemcpy(*blobp, sshbuf_ptr(b), len);\n\t}\n\tret = 0;\n out:\n\tsshbuf_free(b);\n\treturn ret;\n}\n\nint\nsshkey_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)\n{\n\treturn to_blob(key, blobp, lenp, 0);\n}\n\nint\nsshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp)\n{\n\treturn to_blob(key, blobp, lenp, 1);\n}\n\nint\nsshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,\n u_char **retp, size_t *lenp)\n{\n\tu_char *blob = NULL, *ret = NULL;\n\tsize_t blob_len = 0;\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\tif (retp != NULL)\n\t\t*retp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif (ssh_digest_bytes(dgst_alg) == 0) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\n\tif (k->type == KEY_RSA1) {\n#ifdef WITH_OPENSSL\n\t\tint nlen = BN_num_bytes(k->rsa->n);\n\t\tint elen = BN_num_bytes(k->rsa->e);\n\n\t\tif (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tblob_len = nlen + elen;\n\t\tif ((blob = malloc(blob_len)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tBN_bn2bin(k->rsa->n, blob);\n\t\tBN_bn2bin(k->rsa->e, blob + nlen);\n#endif /* WITH_OPENSSL */\n\t} else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0)\n\t\tgoto out;\n\tif ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = ssh_digest_memory(dgst_alg, blob, blob_len,\n\t ret, SSH_DIGEST_MAX_LENGTH)) != 0)\n\t\tgoto out;\n\t/* success */\n\tif (retp != NULL) {\n\t\t*retp = ret;\n\t\tret = NULL;\n\t}\n\tif (lenp != NULL)\n\t\t*lenp = ssh_digest_bytes(dgst_alg);\n\tr = 0;\n out:\n\tfree(ret);\n\tif (blob != NULL) {\n\t\texplicit_bzero(blob, blob_len);\n\t\tfree(blob);\n\t}\n\treturn r;\n}\n\nstatic char *\nfingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)\n{\n\tchar *ret;\n\tsize_t plen = strlen(alg) + 1;\n\tsize_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1;\n\tint r;\n\n\tif (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL)\n\t\treturn NULL;\n\tstrlcpy(ret, alg, rlen);\n\tstrlcat(ret, \":\", rlen);\n\tif (dgst_raw_len == 0)\n\t\treturn ret;\n\tif ((r = b64_ntop(dgst_raw, dgst_raw_len,\n\t ret + plen, rlen - plen)) == -1) {\n\t\texplicit_bzero(ret, rlen);\n\t\tfree(ret);\n\t\treturn NULL;\n\t}\n\t/* Trim padding characters from end */\n\tret[strcspn(ret, \"=\")] = '\\0';\n\treturn ret;\n}\n\nstatic char *\nfingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len)\n{\n\tchar *retval, hex[5];\n\tsize_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2;\n\n\tif (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL)\n\t\treturn NULL;\n\tstrlcpy(retval, alg, rlen);\n\tstrlcat(retval, \":\", rlen);\n\tfor (i = 0; i < dgst_raw_len; i++) {\n\t\tsnprintf(hex, sizeof(hex), \"%s%02x\",\n\t\t i > 0 ? \":\" : \"\", dgst_raw[i]);\n\t\tstrlcat(retval, hex, rlen);\n\t}\n\treturn retval;\n}\n\nstatic char *\nfingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len)\n{\n\tchar vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };\n\tchar consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',\n\t 'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };\n\tu_int i, j = 0, rounds, seed = 1;\n\tchar *retval;\n\n\trounds = (dgst_raw_len / 2) + 1;\n\tif ((retval = calloc(rounds, 6)) == NULL)\n\t\treturn NULL;\n\tretval[j++] = 'x';\n\tfor (i = 0; i < rounds; i++) {\n\t\tu_int idx0, idx1, idx2, idx3, idx4;\n\t\tif ((i + 1 < rounds) || (dgst_raw_len % 2 != 0)) {\n\t\t\tidx0 = (((((u_int)(dgst_raw[2 * i])) >> 6) & 3) +\n\t\t\t seed) % 6;\n\t\t\tidx1 = (((u_int)(dgst_raw[2 * i])) >> 2) & 15;\n\t\t\tidx2 = ((((u_int)(dgst_raw[2 * i])) & 3) +\n\t\t\t (seed / 6)) % 6;\n\t\t\tretval[j++] = vowels[idx0];\n\t\t\tretval[j++] = consonants[idx1];\n\t\t\tretval[j++] = vowels[idx2];\n\t\t\tif ((i + 1) < rounds) {\n\t\t\t\tidx3 = (((u_int)(dgst_raw[(2 * i) + 1])) >> 4) & 15;\n\t\t\t\tidx4 = (((u_int)(dgst_raw[(2 * i) + 1]))) & 15;\n\t\t\t\tretval[j++] = consonants[idx3];\n\t\t\t\tretval[j++] = '-';\n\t\t\t\tretval[j++] = consonants[idx4];\n\t\t\t\tseed = ((seed * 5) +\n\t\t\t\t ((((u_int)(dgst_raw[2 * i])) * 7) +\n\t\t\t\t ((u_int)(dgst_raw[(2 * i) + 1])))) % 36;\n\t\t\t}\n\t\t} else {\n\t\t\tidx0 = seed % 6;\n\t\t\tidx1 = 16;\n\t\t\tidx2 = seed / 6;\n\t\t\tretval[j++] = vowels[idx0];\n\t\t\tretval[j++] = consonants[idx1];\n\t\t\tretval[j++] = vowels[idx2];\n\t\t}\n\t}\n\tretval[j++] = 'x';\n\tretval[j++] = '\\0';\n\treturn retval;\n}\n\n/*\n * Draw an ASCII-Art representing the fingerprint so human brain can\n * profit from its built-in pattern recognition ability.\n * This technique is called \"random art\" and can be found in some\n * scientific publications like this original paper:\n *\n * \"Hash Visualization: a New Technique to improve Real-World Security\",\n * Perrig A. and Song D., 1999, International Workshop on Cryptographic\n * Techniques and E-Commerce (CrypTEC '99)\n * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf\n *\n * The subject came up in a talk by Dan Kaminsky, too.\n *\n * If you see the picture is different, the key is different.\n * If the picture looks the same, you still know nothing.\n *\n * The algorithm used here is a worm crawling over a discrete plane,\n * leaving a trace (augmenting the field) everywhere it goes.\n * Movement is taken from dgst_raw 2bit-wise. Bumping into walls\n * makes the respective movement vector be ignored for this turn.\n * Graphs are not unambiguous, because circles in graphs can be\n * walked in either direction.\n */\n\n/*\n * Field sizes for the random art. Have to be odd, so the starting point\n * can be in the exact middle of the picture, and FLDBASE should be >=8 .\n * Else pictures would be too dense, and drawing the frame would\n * fail, too, because the key type would not fit in anymore.\n */\n#define\tFLDBASE\t\t8\n#define\tFLDSIZE_Y\t(FLDBASE + 1)\n#define\tFLDSIZE_X\t(FLDBASE * 2 + 1)\nstatic char *\nfingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len,\n const struct sshkey *k)\n{\n\t/*\n\t * Chars to be used after each other every time the worm\n\t * intersects with itself. Matter of taste.\n\t */\n\tchar\t*augmentation_string = \" .o+=*BOX@%&#/^SE\";\n\tchar\t*retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X];\n\tu_char\t field[FLDSIZE_X][FLDSIZE_Y];\n\tsize_t\t i, tlen, hlen;\n\tu_int\t b;\n\tint\t x, y, r;\n\tsize_t\t len = strlen(augmentation_string) - 1;\n\n\tif ((retval = calloc((FLDSIZE_X + 3), (FLDSIZE_Y + 2))) == NULL)\n\t\treturn NULL;\n\n\t/* initialize field */\n\tmemset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));\n\tx = FLDSIZE_X / 2;\n\ty = FLDSIZE_Y / 2;\n\n\t/* process raw key */\n\tfor (i = 0; i < dgst_raw_len; i++) {\n\t\tint input;\n\t\t/* each byte conveys four 2-bit move commands */\n\t\tinput = dgst_raw[i];\n\t\tfor (b = 0; b < 4; b++) {\n\t\t\t/* evaluate 2 bit, rest is shifted later */\n\t\t\tx += (input & 0x1) ? 1 : -1;\n\t\t\ty += (input & 0x2) ? 1 : -1;\n\n\t\t\t/* assure we are still in bounds */\n\t\t\tx = MAXIMUM(x, 0);\n\t\t\ty = MAXIMUM(y, 0);\n\t\t\tx = MINIMUM(x, FLDSIZE_X - 1);\n\t\t\ty = MINIMUM(y, FLDSIZE_Y - 1);\n\n\t\t\t/* augment the field */\n\t\t\tif (field[x][y] < len - 2)\n\t\t\t\tfield[x][y]++;\n\t\t\tinput = input >> 2;\n\t\t}\n\t}\n\n\t/* mark starting point and end point*/\n\tfield[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;\n\tfield[x][y] = len;\n\n\t/* assemble title */\n\tr = snprintf(title, sizeof(title), \"[%s %u]\",\n\t\tsshkey_type(k), sshkey_size(k));\n\t/* If [type size] won't fit, then try [type]; fits \"[ED25519-CERT]\" */\n\tif (r < 0 || r > (int)sizeof(title))\n\t\tr = snprintf(title, sizeof(title), \"[%s]\", sshkey_type(k));\n\ttlen = (r <= 0) ? 0 : strlen(title);\n\n\t/* assemble hash ID. */\n\tr = snprintf(hash, sizeof(hash), \"[%s]\", alg);\n\thlen = (r <= 0) ? 0 : strlen(hash);\n\n\t/* output upper border */\n\tp = retval;\n\t*p++ = '+';\n\tfor (i = 0; i < (FLDSIZE_X - tlen) / 2; i++)\n\t\t*p++ = '-';\n\tmemcpy(p, title, tlen);\n\tp += tlen;\n\tfor (i += tlen; i < FLDSIZE_X; i++)\n\t\t*p++ = '-';\n\t*p++ = '+';\n\t*p++ = '\\n';\n\n\t/* output content */\n\tfor (y = 0; y < FLDSIZE_Y; y++) {\n\t\t*p++ = '|';\n\t\tfor (x = 0; x < FLDSIZE_X; x++)\n\t\t\t*p++ = augmentation_string[MINIMUM(field[x][y], len)];\n\t\t*p++ = '|';\n\t\t*p++ = '\\n';\n\t}\n\n\t/* output lower border */\n\t*p++ = '+';\n\tfor (i = 0; i < (FLDSIZE_X - hlen) / 2; i++)\n\t\t*p++ = '-';\n\tmemcpy(p, hash, hlen);\n\tp += hlen;\n\tfor (i += hlen; i < FLDSIZE_X; i++)\n\t\t*p++ = '-';\n\t*p++ = '+';\n\n\treturn retval;\n}\n\nchar *\nsshkey_fingerprint(const struct sshkey *k, int dgst_alg,\n enum sshkey_fp_rep dgst_rep)\n{\n\tchar *retval = NULL;\n\tu_char *dgst_raw;\n\tsize_t dgst_raw_len;\n\n\tif (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0)\n\t\treturn NULL;\n\tswitch (dgst_rep) {\n\tcase SSH_FP_DEFAULT:\n\t\tif (dgst_alg == SSH_DIGEST_MD5) {\n\t\t\tretval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),\n\t\t\t dgst_raw, dgst_raw_len);\n\t\t} else {\n\t\t\tretval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),\n\t\t\t dgst_raw, dgst_raw_len);\n\t\t}\n\t\tbreak;\n\tcase SSH_FP_HEX:\n\t\tretval = fingerprint_hex(ssh_digest_alg_name(dgst_alg),\n\t\t dgst_raw, dgst_raw_len);\n\t\tbreak;\n\tcase SSH_FP_BASE64:\n\t\tretval = fingerprint_b64(ssh_digest_alg_name(dgst_alg),\n\t\t dgst_raw, dgst_raw_len);\n\t\tbreak;\n\tcase SSH_FP_BUBBLEBABBLE:\n\t\tretval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len);\n\t\tbreak;\n\tcase SSH_FP_RANDOMART:\n\t\tretval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg),\n\t\t dgst_raw, dgst_raw_len, k);\n\t\tbreak;\n\tdefault:\n\t\texplicit_bzero(dgst_raw, dgst_raw_len);\n\t\tfree(dgst_raw);\n\t\treturn NULL;\n\t}\n\texplicit_bzero(dgst_raw, dgst_raw_len);\n\tfree(dgst_raw);\n\treturn retval;\n}\n\n#ifdef WITH_SSH1\n/*\n * Reads a multiple-precision integer in decimal from the buffer, and advances\n * the pointer. The integer must already be initialized. This function is\n * permitted to modify the buffer. This leaves *cpp to point just beyond the\n * last processed character.\n */\nstatic int\nread_decimal_bignum(char **cpp, BIGNUM *v)\n{\n\tchar *cp;\n\tsize_t e;\n\tint skip = 1;\t/* skip white space */\n\n\tcp = *cpp;\n\twhile (*cp == ' ' || *cp == '\\t')\n\t\tcp++;\n\te = strspn(cp, \"0123456789\");\n\tif (e == 0)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\tif (e > SSHBUF_MAX_BIGNUM * 3)\n\t\treturn SSH_ERR_BIGNUM_TOO_LARGE;\n\tif (cp[e] == '\\0')\n\t\tskip = 0;\n\telse if (strchr(\" \\t\\r\\n\", cp[e]) == NULL)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\tcp[e] = '\\0';\n\tif (BN_dec2bn(&v, cp) <= 0)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\t*cpp = cp + e + skip;\n\treturn 0;\n}\n#endif /* WITH_SSH1 */\n\n/* returns 0 ok, and < 0 error */\nint\nsshkey_read(struct sshkey *ret, char **cpp)\n{\n\tstruct sshkey *k;\n\tint retval = SSH_ERR_INVALID_FORMAT;\n\tchar *ep, *cp, *space;\n\tint r, type, curve_nid = -1;\n\tstruct sshbuf *blob;\n#ifdef WITH_SSH1\n\tu_long bits;\n#endif /* WITH_SSH1 */\n\n\tif (ret == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\n\tcp = *cpp;\n\n\tswitch (ret->type) {\n\tcase KEY_RSA1:\n#ifdef WITH_SSH1\n\t\t/* Get number of bits. */\n\t\tbits = strtoul(cp, &ep, 10);\n\t\tif (*cp == '\\0' || strchr(\" \\t\\r\\n\", *ep) == NULL ||\n\t\t bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8)\n\t\t\treturn SSH_ERR_INVALID_FORMAT;\t/* Bad bit count... */\n\t\t/* Get public exponent, public modulus. */\n\t\tif ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0)\n\t\t\treturn r;\n\t\tif ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0)\n\t\t\treturn r;\n\t\t/* validate the claimed number of bits */\n\t\tif (BN_num_bits(ret->rsa->n) != (int)bits)\n\t\t\treturn SSH_ERR_KEY_BITS_MISMATCH;\n\t\t*cpp = ep;\n\t\tretval = 0;\n#endif /* WITH_SSH1 */\n\t\tbreak;\n\tcase KEY_UNSPEC:\n\tcase KEY_RSA:\n\tcase KEY_DSA:\n\tcase KEY_ECDSA:\n\tcase KEY_ED25519:\n\tcase KEY_DSA_CERT:\n\tcase KEY_ECDSA_CERT:\n\tcase KEY_RSA_CERT:\n\tcase KEY_ED25519_CERT:\n\t\tspace = strchr(cp, ' ');\n\t\tif (space == NULL)\n\t\t\treturn SSH_ERR_INVALID_FORMAT;\n\t\t*space = '\\0';\n\t\ttype = sshkey_type_from_name(cp);\n\t\tif (sshkey_type_plain(type) == KEY_ECDSA &&\n\t\t (curve_nid = sshkey_ecdsa_nid_from_name(cp)) == -1)\n\t\t\treturn SSH_ERR_EC_CURVE_INVALID;\n\t\t*space = ' ';\n\t\tif (type == KEY_UNSPEC)\n\t\t\treturn SSH_ERR_INVALID_FORMAT;\n\t\tcp = space+1;\n\t\tif (*cp == '\\0')\n\t\t\treturn SSH_ERR_INVALID_FORMAT;\n\t\tif (ret->type != KEY_UNSPEC && ret->type != type)\n\t\t\treturn SSH_ERR_KEY_TYPE_MISMATCH;\n\t\tif ((blob = sshbuf_new()) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t/* trim comment */\n\t\tspace = strchr(cp, ' ');\n\t\tif (space) {\n\t\t\t/* advance 'space': skip whitespace */\n\t\t\t*space++ = '\\0';\n\t\t\twhile (*space == ' ' || *space == '\\t')\n\t\t\t\tspace++;\n\t\t\tep = space;\n\t\t} else\n\t\t\tep = cp + strlen(cp);\n\t\tif ((r = sshbuf_b64tod(blob, cp)) != 0) {\n\t\t\tsshbuf_free(blob);\n\t\t\treturn r;\n\t\t}\n\t\tif ((r = sshkey_from_blob(sshbuf_ptr(blob),\n\t\t sshbuf_len(blob), &k)) != 0) {\n\t\t\tsshbuf_free(blob);\n\t\t\treturn r;\n\t\t}\n\t\tsshbuf_free(blob);\n\t\tif (k->type != type) {\n\t\t\tsshkey_free(k);\n\t\t\treturn SSH_ERR_KEY_TYPE_MISMATCH;\n\t\t}\n\t\tif (sshkey_type_plain(type) == KEY_ECDSA &&\n\t\t curve_nid != k->ecdsa_nid) {\n\t\t\tsshkey_free(k);\n\t\t\treturn SSH_ERR_EC_CURVE_MISMATCH;\n\t\t}\n\t\tret->type = type;\n\t\tif (sshkey_is_cert(ret)) {\n\t\t\tif (!sshkey_is_cert(k)) {\n\t\t\t\tsshkey_free(k);\n\t\t\t\treturn SSH_ERR_EXPECTED_CERT;\n\t\t\t}\n\t\t\tif (ret->cert != NULL)\n\t\t\t\tcert_free(ret->cert);\n\t\t\tret->cert = k->cert;\n\t\t\tk->cert = NULL;\n\t\t}\n\t\tswitch (sshkey_type_plain(ret->type)) {\n#ifdef WITH_OPENSSL\n\t\tcase KEY_RSA:\n\t\t\tif (ret->rsa != NULL)\n\t\t\t\tRSA_free(ret->rsa);\n\t\t\tret->rsa = k->rsa;\n\t\t\tk->rsa = NULL;\n#ifdef DEBUG_PK\n\t\t\tRSA_print_fp(stderr, ret->rsa, 8);\n#endif\n\t\t\tbreak;\n\t\tcase KEY_DSA:\n\t\t\tif (ret->dsa != NULL)\n\t\t\t\tDSA_free(ret->dsa);\n\t\t\tret->dsa = k->dsa;\n\t\t\tk->dsa = NULL;\n#ifdef DEBUG_PK\n\t\t\tDSA_print_fp(stderr, ret->dsa, 8);\n#endif\n\t\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\t\tcase KEY_ECDSA:\n\t\t\tif (ret->ecdsa != NULL)\n\t\t\t\tEC_KEY_free(ret->ecdsa);\n\t\t\tret->ecdsa = k->ecdsa;\n\t\t\tret->ecdsa_nid = k->ecdsa_nid;\n\t\t\tk->ecdsa = NULL;\n\t\t\tk->ecdsa_nid = -1;\n#ifdef DEBUG_PK\n\t\t\tsshkey_dump_ec_key(ret->ecdsa);\n#endif\n\t\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\t\tcase KEY_ED25519:\n\t\t\tfree(ret->ed25519_pk);\n\t\t\tret->ed25519_pk = k->ed25519_pk;\n\t\t\tk->ed25519_pk = NULL;\n#ifdef DEBUG_PK\n\t\t\t/* XXX */\n#endif\n\t\t\tbreak;\n\t\t}\n\t\t*cpp = ep;\n\t\tretval = 0;\n/*XXXX*/\n\t\tsshkey_free(k);\n\t\tif (retval != 0)\n\t\t\tbreak;\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n\treturn retval;\n}\n\nint\nsshkey_to_base64(const struct sshkey *key, char **b64p)\n{\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\tstruct sshbuf *b = NULL;\n\tchar *uu = NULL;\n\n\tif (b64p != NULL)\n\t\t*b64p = NULL;\n\tif ((b = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshkey_putb(key, b)) != 0)\n\t\tgoto out;\n\tif ((uu = sshbuf_dtob64(b)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\t/* Success */\n\tif (b64p != NULL) {\n\t\t*b64p = uu;\n\t\tuu = NULL;\n\t}\n\tr = 0;\n out:\n\tsshbuf_free(b);\n\tfree(uu);\n\treturn r;\n}\n\nstatic int\nsshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b)\n{\n\tint r = SSH_ERR_INTERNAL_ERROR;\n#ifdef WITH_SSH1\n\tu_int bits = 0;\n\tchar *dec_e = NULL, *dec_n = NULL;\n\n\tif (key->rsa == NULL || key->rsa->e == NULL ||\n\t key->rsa->n == NULL) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\tif ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||\n\t (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\t/* size of modulus 'n' */\n\tif ((bits = BN_num_bits(key->rsa->n)) <= 0) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_putf(b, \"%u %s %s\", bits, dec_e, dec_n)) != 0)\n\t\tgoto out;\n\n\t/* Success */\n\tr = 0;\n out:\n\tif (dec_e != NULL)\n\t\tOPENSSL_free(dec_e);\n\tif (dec_n != NULL)\n\t\tOPENSSL_free(dec_n);\n#endif /* WITH_SSH1 */\n\n\treturn r;\n}\n\nstatic int\nsshkey_format_text(const struct sshkey *key, struct sshbuf *b)\n{\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\tchar *uu = NULL;\n\n\tif (key->type == KEY_RSA1) {\n\t\tif ((r = sshkey_format_rsa1(key, b)) != 0)\n\t\t\tgoto out;\n\t} else {\n\t\t/* Unsupported key types handled in sshkey_to_base64() */\n\t\tif ((r = sshkey_to_base64(key, &uu)) != 0)\n\t\t\tgoto out;\n\t\tif ((r = sshbuf_putf(b, \"%s %s\",\n\t\t sshkey_ssh_name(key), uu)) != 0)\n\t\t\tgoto out;\n\t}\n\tr = 0;\n out:\n\tfree(uu);\n\treturn r;\n}\n\nint\nsshkey_write(const struct sshkey *key, FILE *f)\n{\n\tstruct sshbuf *b = NULL;\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\tif ((b = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshkey_format_text(key, b)) != 0)\n\t\tgoto out;\n\tif (fwrite(sshbuf_ptr(b), sshbuf_len(b), 1, f) != 1) {\n\t\tif (feof(f))\n\t\t\terrno = EPIPE;\n\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\tgoto out;\n\t}\n\t/* Success */\n\tr = 0;\n out:\n\tsshbuf_free(b);\n\treturn r;\n}\n\nconst char *\nsshkey_cert_type(const struct sshkey *k)\n{\n\tswitch (k->cert->type) {\n\tcase SSH2_CERT_TYPE_USER:\n\t\treturn \"user\";\n\tcase SSH2_CERT_TYPE_HOST:\n\t\treturn \"host\";\n\tdefault:\n\t\treturn \"unknown\";\n\t}\n}\n\n#ifdef WITH_OPENSSL\nstatic int\nrsa_generate_private_key(u_int bits, RSA **rsap)\n{\n\tRSA *private = NULL;\n\tBIGNUM *f4 = NULL;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\tif (rsap == NULL ||\n\t bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||\n\t bits > SSHBUF_MAX_BIGNUM * 8)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t*rsap = NULL;\n\tif ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (!BN_set_word(f4, RSA_F4) ||\n\t !RSA_generate_key_ex(private, bits, f4, NULL)) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\t*rsap = private;\n\tprivate = NULL;\n\tret = 0;\n out:\n\tif (private != NULL)\n\t\tRSA_free(private);\n\tif (f4 != NULL)\n\t\tBN_free(f4);\n\treturn ret;\n}\n\nstatic int\ndsa_generate_private_key(u_int bits, DSA **dsap)\n{\n\tDSA *private;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\tif (dsap == NULL || bits != 1024)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif ((private = DSA_new()) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\t*dsap = NULL;\n\tif (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,\n\t NULL, NULL) || !DSA_generate_key(private)) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\t*dsap = private;\n\tprivate = NULL;\n\tret = 0;\n out:\n\tif (private != NULL)\n\t\tDSA_free(private);\n\treturn ret;\n}\n\n# ifdef OPENSSL_HAS_ECC\nint\nsshkey_ecdsa_key_to_nid(EC_KEY *k)\n{\n\tEC_GROUP *eg;\n\tint nids[] = {\n\t\tNID_X9_62_prime256v1,\n\t\tNID_secp384r1,\n# ifdef OPENSSL_HAS_NISTP521\n\t\tNID_secp521r1,\n# endif /* OPENSSL_HAS_NISTP521 */\n\t\t-1\n\t};\n\tint nid;\n\tu_int i;\n\tBN_CTX *bnctx;\n\tconst EC_GROUP *g = EC_KEY_get0_group(k);\n\n\t/*\n\t * The group may be stored in a ASN.1 encoded private key in one of two\n\t * ways: as a \"named group\", which is reconstituted by ASN.1 object ID\n\t * or explicit group parameters encoded into the key blob. Only the\n\t * \"named group\" case sets the group NID for us, but we can figure\n\t * it out for the other case by comparing against all the groups that\n\t * are supported.\n\t */\n\tif ((nid = EC_GROUP_get_curve_name(g)) > 0)\n\t\treturn nid;\n\tif ((bnctx = BN_CTX_new()) == NULL)\n\t\treturn -1;\n\tfor (i = 0; nids[i] != -1; i++) {\n\t\tif ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) {\n\t\t\tBN_CTX_free(bnctx);\n\t\t\treturn -1;\n\t\t}\n\t\tif (EC_GROUP_cmp(g, eg, bnctx) == 0)\n\t\t\tbreak;\n\t\tEC_GROUP_free(eg);\n\t}\n\tBN_CTX_free(bnctx);\n\tif (nids[i] != -1) {\n\t\t/* Use the group with the NID attached */\n\t\tEC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE);\n\t\tif (EC_KEY_set_group(k, eg) != 1) {\n\t\t\tEC_GROUP_free(eg);\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn nids[i];\n}\n\nstatic int\necdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)\n{\n\tEC_KEY *private;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\tif (nid == NULL || ecdsap == NULL ||\n\t (*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t*ecdsap = NULL;\n\tif ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (EC_KEY_generate_key(private) != 1) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tEC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);\n\t*ecdsap = private;\n\tprivate = NULL;\n\tret = 0;\n out:\n\tif (private != NULL)\n\t\tEC_KEY_free(private);\n\treturn ret;\n}\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\nint\nsshkey_generate(int type, u_int bits, struct sshkey **keyp)\n{\n\tstruct sshkey *k;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\tif (keyp == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t*keyp = NULL;\n\tif ((k = sshkey_new(KEY_UNSPEC)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tswitch (type) {\n\tcase KEY_ED25519:\n\t\tif ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||\n\t\t (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tbreak;\n\t\t}\n\t\tcrypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);\n\t\tret = 0;\n\t\tbreak;\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA:\n\t\tret = dsa_generate_private_key(bits, &k->dsa);\n\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\t\tret = ecdsa_generate_private_key(bits, &k->ecdsa_nid,\n\t\t &k->ecdsa);\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n\tcase KEY_RSA:\n\tcase KEY_RSA1:\n\t\tret = rsa_generate_private_key(bits, &k->rsa);\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tdefault:\n\t\tret = SSH_ERR_INVALID_ARGUMENT;\n\t}\n\tif (ret == 0) {\n\t\tk->type = type;\n\t\t*keyp = k;\n\t} else\n\t\tsshkey_free(k);\n\treturn ret;\n}\n\nint\nsshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key)\n{\n\tu_int i;\n\tconst struct sshkey_cert *from;\n\tstruct sshkey_cert *to;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\tif (to_key->cert != NULL) {\n\t\tcert_free(to_key->cert);\n\t\tto_key->cert = NULL;\n\t}\n\n\tif ((from = from_key->cert) == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\n\tif ((to = to_key->cert = cert_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\tif ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 ||\n\t (ret = sshbuf_putb(to->critical, from->critical)) != 0 ||\n\t (ret = sshbuf_putb(to->extensions, from->extensions)) != 0)\n\t\treturn ret;\n\n\tto->serial = from->serial;\n\tto->type = from->type;\n\tif (from->key_id == NULL)\n\t\tto->key_id = NULL;\n\telse if ((to->key_id = strdup(from->key_id)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tto->valid_after = from->valid_after;\n\tto->valid_before = from->valid_before;\n\tif (from->signature_key == NULL)\n\t\tto->signature_key = NULL;\n\telse if ((ret = sshkey_from_private(from->signature_key,\n\t &to->signature_key)) != 0)\n\t\treturn ret;\n\n\tif (from->nprincipals > SSHKEY_CERT_MAX_PRINCIPALS)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif (from->nprincipals > 0) {\n\t\tif ((to->principals = calloc(from->nprincipals,\n\t\t sizeof(*to->principals))) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tfor (i = 0; i < from->nprincipals; i++) {\n\t\t\tto->principals[i] = strdup(from->principals[i]);\n\t\t\tif (to->principals[i] == NULL) {\n\t\t\t\tto->nprincipals = i;\n\t\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\tto->nprincipals = from->nprincipals;\n\treturn 0;\n}\n\nint\nsshkey_from_private(const struct sshkey *k, struct sshkey **pkp)\n{\n\tstruct sshkey *n = NULL;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\t*pkp = NULL;\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA:\n\tcase KEY_DSA_CERT:\n\t\tif ((n = sshkey_new(k->type)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tif ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||\n\t\t (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||\n\t\t (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||\n\t\t (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {\n\t\t\tsshkey_free(n);\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t}\n\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\tcase KEY_ECDSA_CERT:\n\t\tif ((n = sshkey_new(k->type)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tn->ecdsa_nid = k->ecdsa_nid;\n\t\tn->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);\n\t\tif (n->ecdsa == NULL) {\n\t\t\tsshkey_free(n);\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t}\n\t\tif (EC_KEY_set_public_key(n->ecdsa,\n\t\t EC_KEY_get0_public_key(k->ecdsa)) != 1) {\n\t\t\tsshkey_free(n);\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t\t}\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n\tcase KEY_RSA:\n\tcase KEY_RSA1:\n\tcase KEY_RSA_CERT:\n\t\tif ((n = sshkey_new(k->type)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tif ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||\n\t\t (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {\n\t\t\tsshkey_free(n);\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t}\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\tif ((n = sshkey_new(k->type)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tif (k->ed25519_pk != NULL) {\n\t\t\tif ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {\n\t\t\t\tsshkey_free(n);\n\t\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t\t}\n\t\t\tmemcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\t}\n\tif (sshkey_is_cert(k)) {\n\t\tif ((ret = sshkey_cert_copy(k, n)) != 0) {\n\t\t\tsshkey_free(n);\n\t\t\treturn ret;\n\t\t}\n\t}\n\t*pkp = n;\n\treturn 0;\n}\n\nstatic int\ncert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)\n{\n\tstruct sshbuf *principals = NULL, *crit = NULL;\n\tstruct sshbuf *exts = NULL, *ca = NULL;\n\tu_char *sig = NULL;\n\tsize_t signed_len = 0, slen = 0, kidlen = 0;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\t/* Copy the entire key blob for verification and later serialisation */\n\tif ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0)\n\t\treturn ret;\n\n\t/* Parse body of certificate up to signature */\n\tif ((ret = sshbuf_get_u64(b, &key->cert->serial)) != 0 ||\n\t (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 ||\n\t (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 ||\n\t (ret = sshbuf_froms(b, &principals)) != 0 ||\n\t (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 ||\n\t (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 ||\n\t (ret = sshbuf_froms(b, &crit)) != 0 ||\n\t (ret = sshbuf_froms(b, &exts)) != 0 ||\n\t (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 ||\n\t (ret = sshbuf_froms(b, &ca)) != 0) {\n\t\t/* XXX debug print error for ret */\n\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\t/* Signature is left in the buffer so we can calculate this length */\n\tsigned_len = sshbuf_len(key->cert->certblob) - sshbuf_len(b);\n\n\tif ((ret = sshbuf_get_string(b, &sig, &slen)) != 0) {\n\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\tif (key->cert->type != SSH2_CERT_TYPE_USER &&\n\t key->cert->type != SSH2_CERT_TYPE_HOST) {\n\t\tret = SSH_ERR_KEY_CERT_UNKNOWN_TYPE;\n\t\tgoto out;\n\t}\n\n\t/* Parse principals section */\n\twhile (sshbuf_len(principals) > 0) {\n\t\tchar *principal = NULL;\n\t\tchar **oprincipals = NULL;\n\n\t\tif (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((ret = sshbuf_get_cstring(principals, &principal,\n\t\t NULL)) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\toprincipals = key->cert->principals;\n\t\tkey->cert->principals = reallocarray(key->cert->principals,\n\t\t key->cert->nprincipals + 1, sizeof(*key->cert->principals));\n\t\tif (key->cert->principals == NULL) {\n\t\t\tfree(principal);\n\t\t\tkey->cert->principals = oprincipals;\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tkey->cert->principals[key->cert->nprincipals++] = principal;\n\t}\n\n\t/*\n\t * Stash a copies of the critical options and extensions sections\n\t * for later use.\n\t */\n\tif ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 ||\n\t (exts != NULL &&\n\t (ret = sshbuf_putb(key->cert->extensions, exts)) != 0))\n\t\tgoto out;\n\n\t/*\n\t * Validate critical options and extensions sections format.\n\t */\n\twhile (sshbuf_len(crit) != 0) {\n\t\tif ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 ||\n\t\t (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) {\n\t\t\tsshbuf_reset(key->cert->critical);\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t}\n\twhile (exts != NULL && sshbuf_len(exts) != 0) {\n\t\tif ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 ||\n\t\t (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) {\n\t\t\tsshbuf_reset(key->cert->extensions);\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\t/* Parse CA key and check signature */\n\tif (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) {\n\t\tret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;\n\t\tgoto out;\n\t}\n\tif (!sshkey_type_is_valid_ca(key->cert->signature_key->type)) {\n\t\tret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;\n\t\tgoto out;\n\t}\n\tif ((ret = sshkey_verify(key->cert->signature_key, sig, slen,\n\t sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0)\n\t\tgoto out;\n\n\t/* Success */\n\tret = 0;\n out:\n\tsshbuf_free(ca);\n\tsshbuf_free(crit);\n\tsshbuf_free(exts);\n\tsshbuf_free(principals);\n\tfree(sig);\n\treturn ret;\n}\n\nstatic int\nsshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,\n int allow_cert)\n{\n\tint type, ret = SSH_ERR_INTERNAL_ERROR;\n\tchar *ktype = NULL, *curve = NULL;\n\tstruct sshkey *key = NULL;\n\tsize_t len;\n\tu_char *pk = NULL;\n\tstruct sshbuf *copy;\n#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)\n\tEC_POINT *q = NULL;\n#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */\n\n#ifdef DEBUG_PK /* XXX */\n\tsshbuf_dump(b, stderr);\n#endif\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif ((copy = sshbuf_fromb(b)) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (sshbuf_get_cstring(b, &ktype, NULL) != 0) {\n\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\ttype = sshkey_type_from_name(ktype);\n\tif (!allow_cert && sshkey_type_is_cert(type)) {\n\t\tret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;\n\t\tgoto out;\n\t}\n\tswitch (type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA_CERT:\n\t\t/* Skip nonce */\n\t\tif (sshbuf_get_string_direct(b, NULL, NULL) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\t/* FALLTHROUGH */\n\tcase KEY_RSA:\n\t\tif ((key = sshkey_new(type)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif (sshbuf_get_bignum2(b, key->rsa->e) != 0 ||\n\t\t sshbuf_get_bignum2(b, key->rsa->n) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n#ifdef DEBUG_PK\n\t\tRSA_print_fp(stderr, key->rsa, 8);\n#endif\n\t\tbreak;\n\tcase KEY_DSA_CERT:\n\t\t/* Skip nonce */\n\t\tif (sshbuf_get_string_direct(b, NULL, NULL) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\t/* FALLTHROUGH */\n\tcase KEY_DSA:\n\t\tif ((key = sshkey_new(type)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif (sshbuf_get_bignum2(b, key->dsa->p) != 0 ||\n\t\t sshbuf_get_bignum2(b, key->dsa->q) != 0 ||\n\t\t sshbuf_get_bignum2(b, key->dsa->g) != 0 ||\n\t\t sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n#ifdef DEBUG_PK\n\t\tDSA_print_fp(stderr, key->dsa, 8);\n#endif\n\t\tbreak;\n\tcase KEY_ECDSA_CERT:\n\t\t/* Skip nonce */\n\t\tif (sshbuf_get_string_direct(b, NULL, NULL) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\t/* FALLTHROUGH */\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\t\tif ((key = sshkey_new(type)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tkey->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype);\n\t\tif (sshbuf_get_cstring(b, &curve, NULL) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tif (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {\n\t\t\tret = SSH_ERR_EC_CURVE_MISMATCH;\n\t\t\tgoto out;\n\t\t}\n\t\tif (key->ecdsa != NULL)\n\t\t\tEC_KEY_free(key->ecdsa);\n\t\tif ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid))\n\t\t == NULL) {\n\t\t\tret = SSH_ERR_EC_CURVE_INVALID;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tif (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa),\n\t\t q) != 0) {\n\t\t\tret = SSH_ERR_KEY_INVALID_EC_VALUE;\n\t\t\tgoto out;\n\t\t}\n\t\tif (EC_KEY_set_public_key(key->ecdsa, q) != 1) {\n\t\t\t/* XXX assume it is a allocation error */\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n#ifdef DEBUG_PK\n\t\tsshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q);\n#endif\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519_CERT:\n\t\t/* Skip nonce */\n\t\tif (sshbuf_get_string_direct(b, NULL, NULL) != 0) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\t/* FALLTHROUGH */\n\tcase KEY_ED25519:\n\t\tif ((ret = sshbuf_get_string(b, &pk, &len)) != 0)\n\t\t\tgoto out;\n\t\tif (len != ED25519_PK_SZ) {\n\t\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((key = sshkey_new(type)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tkey->ed25519_pk = pk;\n\t\tpk = NULL;\n\t\tbreak;\n\tcase KEY_UNSPEC:\n\t\tif ((key = sshkey_new(type)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tret = SSH_ERR_KEY_TYPE_UNKNOWN;\n\t\tgoto out;\n\t}\n\n\t/* Parse certificate potion */\n\tif (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0)\n\t\tgoto out;\n\n\tif (key != NULL && sshbuf_len(b) != 0) {\n\t\tret = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tret = 0;\n\tif (keyp != NULL) {\n\t\t*keyp = key;\n\t\tkey = NULL;\n\t}\n out:\n\tsshbuf_free(copy);\n\tsshkey_free(key);\n\tfree(ktype);\n\tfree(curve);\n\tfree(pk);\n#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)\n\tif (q != NULL)\n\t\tEC_POINT_free(q);\n#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */\n\treturn ret;\n}\n\nint\nsshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp)\n{\n\tstruct sshbuf *b;\n\tint r;\n\n\tif ((b = sshbuf_from(blob, blen)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tr = sshkey_from_blob_internal(b, keyp, 1);\n\tsshbuf_free(b);\n\treturn r;\n}\n\nint\nsshkey_fromb(struct sshbuf *b, struct sshkey **keyp)\n{\n\treturn sshkey_from_blob_internal(b, keyp, 1);\n}\n\nint\nsshkey_froms(struct sshbuf *buf, struct sshkey **keyp)\n{\n\tstruct sshbuf *b;\n\tint r;\n\n\tif ((r = sshbuf_froms(buf, &b)) != 0)\n\t\treturn r;\n\tr = sshkey_from_blob_internal(b, keyp, 1);\n\tsshbuf_free(b);\n\treturn r;\n}\n\nint\nsshkey_sign(const struct sshkey *key,\n u_char **sigp, size_t *lenp,\n const u_char *data, size_t datalen, const char *alg, u_int compat)\n{\n\tif (sigp != NULL)\n\t\t*sigp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tswitch (key->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA_CERT:\n\tcase KEY_DSA:\n\t\treturn ssh_dss_sign(key, sigp, lenp, data, datalen, compat);\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA_CERT:\n\tcase KEY_ECDSA:\n\t\treturn ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat);\n# endif /* OPENSSL_HAS_ECC */\n\tcase KEY_RSA_CERT:\n\tcase KEY_RSA:\n\t\treturn ssh_rsa_sign(key, sigp, lenp, data, datalen, alg);\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\treturn ssh_ed25519_sign(key, sigp, lenp, data, datalen, compat);\n\tdefault:\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\t}\n}\n\n/*\n * ssh_key_verify returns 0 for a correct signature and < 0 on error.\n */\nint\nsshkey_verify(const struct sshkey *key,\n const u_char *sig, size_t siglen,\n const u_char *data, size_t dlen, u_int compat)\n{\n\tif (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tswitch (key->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA_CERT:\n\tcase KEY_DSA:\n\t\treturn ssh_dss_verify(key, sig, siglen, data, dlen, compat);\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA_CERT:\n\tcase KEY_ECDSA:\n\t\treturn ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat);\n# endif /* OPENSSL_HAS_ECC */\n\tcase KEY_RSA_CERT:\n\tcase KEY_RSA:\n\t\treturn ssh_rsa_verify(key, sig, siglen, data, dlen);\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\treturn ssh_ed25519_verify(key, sig, siglen, data, dlen, compat);\n\tdefault:\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\t}\n}\n\n/* Converts a private to a public key */\nint\nsshkey_demote(const struct sshkey *k, struct sshkey **dkp)\n{\n\tstruct sshkey *pk;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\n\t*dkp = NULL;\n\tif ((pk = calloc(1, sizeof(*pk))) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tpk->type = k->type;\n\tpk->flags = k->flags;\n\tpk->ecdsa_nid = k->ecdsa_nid;\n\tpk->dsa = NULL;\n\tpk->ecdsa = NULL;\n\tpk->rsa = NULL;\n\tpk->ed25519_pk = NULL;\n\tpk->ed25519_sk = NULL;\n\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA_CERT:\n\t\tif ((ret = sshkey_cert_copy(k, pk)) != 0)\n\t\t\tgoto fail;\n\t\t/* FALLTHROUGH */\n\tcase KEY_RSA1:\n\tcase KEY_RSA:\n\t\tif ((pk->rsa = RSA_new()) == NULL ||\n\t\t (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||\n\t\t (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto fail;\n\t\t\t}\n\t\tbreak;\n\tcase KEY_DSA_CERT:\n\t\tif ((ret = sshkey_cert_copy(k, pk)) != 0)\n\t\t\tgoto fail;\n\t\t/* FALLTHROUGH */\n\tcase KEY_DSA:\n\t\tif ((pk->dsa = DSA_new()) == NULL ||\n\t\t (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||\n\t\t (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||\n\t\t (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||\n\t\t (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto fail;\n\t\t}\n\t\tbreak;\n\tcase KEY_ECDSA_CERT:\n\t\tif ((ret = sshkey_cert_copy(k, pk)) != 0)\n\t\t\tgoto fail;\n\t\t/* FALLTHROUGH */\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\t\tpk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);\n\t\tif (pk->ecdsa == NULL) {\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto fail;\n\t\t}\n\t\tif (EC_KEY_set_public_key(pk->ecdsa,\n\t\t EC_KEY_get0_public_key(k->ecdsa)) != 1) {\n\t\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto fail;\n\t\t}\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519_CERT:\n\t\tif ((ret = sshkey_cert_copy(k, pk)) != 0)\n\t\t\tgoto fail;\n\t\t/* FALLTHROUGH */\n\tcase KEY_ED25519:\n\t\tif (k->ed25519_pk != NULL) {\n\t\t\tif ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {\n\t\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tmemcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tret = SSH_ERR_KEY_TYPE_UNKNOWN;\n fail:\n\t\tsshkey_free(pk);\n\t\treturn ret;\n\t}\n\t*dkp = pk;\n\treturn 0;\n}\n\n/* Convert a plain key to their _CERT equivalent */\nint\nsshkey_to_certified(struct sshkey *k)\n{\n\tint newtype;\n\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA:\n\t\tnewtype = KEY_RSA_CERT;\n\t\tbreak;\n\tcase KEY_DSA:\n\t\tnewtype = KEY_DSA_CERT;\n\t\tbreak;\n\tcase KEY_ECDSA:\n\t\tnewtype = KEY_ECDSA_CERT;\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\t\tnewtype = KEY_ED25519_CERT;\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n\tif ((k->cert = cert_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tk->type = newtype;\n\treturn 0;\n}\n\n/* Convert a certificate to its raw key equivalent */\nint\nsshkey_drop_cert(struct sshkey *k)\n{\n\tif (!sshkey_type_is_cert(k->type))\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\tcert_free(k->cert);\n\tk->cert = NULL;\n\tk->type = sshkey_type_plain(k->type);\n\treturn 0;\n}\n\n/* Sign a certified key, (re-)generating the signed certblob. */\nint\nsshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)\n{\n\tstruct sshbuf *principals = NULL;\n\tu_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];\n\tsize_t i, ca_len, sig_len;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n\tstruct sshbuf *cert;\n\n\tif (k == NULL || k->cert == NULL ||\n\t k->cert->certblob == NULL || ca == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif (!sshkey_is_cert(k))\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\tif (!sshkey_type_is_valid_ca(ca->type))\n\t\treturn SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;\n\n\tif ((ret = sshkey_to_blob(ca, &ca_blob, &ca_len)) != 0)\n\t\treturn SSH_ERR_KEY_CERT_INVALID_SIGN_KEY;\n\n\tcert = k->cert->certblob; /* for readability */\n\tsshbuf_reset(cert);\n\tif ((ret = sshbuf_put_cstring(cert, sshkey_ssh_name(k))) != 0)\n\t\tgoto out;\n\n\t/* -v01 certs put nonce first */\n\tarc4random_buf(&nonce, sizeof(nonce));\n\tif ((ret = sshbuf_put_string(cert, nonce, sizeof(nonce))) != 0)\n\t\tgoto out;\n\n\t/* XXX this substantially duplicates to_blob(); refactor */\n\tswitch (k->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA_CERT:\n\t\tif ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA_CERT:\n\t\tif ((ret = sshbuf_put_cstring(cert,\n\t\t sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 ||\n\t\t (ret = sshbuf_put_ec(cert,\n\t\t EC_KEY_get0_public_key(k->ecdsa),\n\t\t EC_KEY_get0_group(k->ecdsa))) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n\tcase KEY_RSA_CERT:\n\t\tif ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||\n\t\t (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519_CERT:\n\t\tif ((ret = sshbuf_put_string(cert,\n\t\t k->ed25519_pk, ED25519_PK_SZ)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tdefault:\n\t\tret = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\n\tif ((ret = sshbuf_put_u64(cert, k->cert->serial)) != 0 ||\n\t (ret = sshbuf_put_u32(cert, k->cert->type)) != 0 ||\n\t (ret = sshbuf_put_cstring(cert, k->cert->key_id)) != 0)\n\t\tgoto out;\n\n\tif ((principals = sshbuf_new()) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tfor (i = 0; i < k->cert->nprincipals; i++) {\n\t\tif ((ret = sshbuf_put_cstring(principals,\n\t\t k->cert->principals[i])) != 0)\n\t\t\tgoto out;\n\t}\n\tif ((ret = sshbuf_put_stringb(cert, principals)) != 0 ||\n\t (ret = sshbuf_put_u64(cert, k->cert->valid_after)) != 0 ||\n\t (ret = sshbuf_put_u64(cert, k->cert->valid_before)) != 0 ||\n\t (ret = sshbuf_put_stringb(cert, k->cert->critical)) != 0 ||\n\t (ret = sshbuf_put_stringb(cert, k->cert->extensions)) != 0 ||\n\t (ret = sshbuf_put_string(cert, NULL, 0)) != 0 || /* Reserved */\n\t (ret = sshbuf_put_string(cert, ca_blob, ca_len)) != 0)\n\t\tgoto out;\n\n\t/* Sign the whole mess */\n\tif ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),\n\t sshbuf_len(cert), alg, 0)) != 0)\n\t\tgoto out;\n\n\t/* Append signature and we are done */\n\tif ((ret = sshbuf_put_string(cert, sig_blob, sig_len)) != 0)\n\t\tgoto out;\n\tret = 0;\n out:\n\tif (ret != 0)\n\t\tsshbuf_reset(cert);\n\tfree(sig_blob);\n\tfree(ca_blob);\n\tsshbuf_free(principals);\n\treturn ret;\n}\n\nint\nsshkey_cert_check_authority(const struct sshkey *k,\n int want_host, int require_principal,\n const char *name, const char **reason)\n{\n\tu_int i, principal_matches;\n\ttime_t now = time(NULL);\n\n\tif (reason != NULL)\n\t\t*reason = NULL;\n\n\tif (want_host) {\n\t\tif (k->cert->type != SSH2_CERT_TYPE_HOST) {\n\t\t\t*reason = \"Certificate invalid: not a host certificate\";\n\t\t\treturn SSH_ERR_KEY_CERT_INVALID;\n\t\t}\n\t} else {\n\t\tif (k->cert->type != SSH2_CERT_TYPE_USER) {\n\t\t\t*reason = \"Certificate invalid: not a user certificate\";\n\t\t\treturn SSH_ERR_KEY_CERT_INVALID;\n\t\t}\n\t}\n\tif (now < 0) {\n\t\t/* yikes - system clock before epoch! */\n\t\t*reason = \"Certificate invalid: not yet valid\";\n\t\treturn SSH_ERR_KEY_CERT_INVALID;\n\t}\n\tif ((u_int64_t)now < k->cert->valid_after) {\n\t\t*reason = \"Certificate invalid: not yet valid\";\n\t\treturn SSH_ERR_KEY_CERT_INVALID;\n\t}\n\tif ((u_int64_t)now >= k->cert->valid_before) {\n\t\t*reason = \"Certificate invalid: expired\";\n\t\treturn SSH_ERR_KEY_CERT_INVALID;\n\t}\n\tif (k->cert->nprincipals == 0) {\n\t\tif (require_principal) {\n\t\t\t*reason = \"Certificate lacks principal list\";\n\t\t\treturn SSH_ERR_KEY_CERT_INVALID;\n\t\t}\n\t} else if (name != NULL) {\n\t\tprincipal_matches = 0;\n\t\tfor (i = 0; i < k->cert->nprincipals; i++) {\n\t\t\tif (strcmp(name, k->cert->principals[i]) == 0) {\n\t\t\t\tprincipal_matches = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!principal_matches) {\n\t\t\t*reason = \"Certificate invalid: name is not a listed \"\n\t\t\t \"principal\";\n\t\t\treturn SSH_ERR_KEY_CERT_INVALID;\n\t\t}\n\t}\n\treturn 0;\n}\n\nsize_t\nsshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l)\n{\n\tchar from[32], to[32], ret[64];\n\ttime_t tt;\n\tstruct tm *tm;\n\n\t*from = *to = '\\0';\n\tif (cert->valid_after == 0 &&\n\t cert->valid_before == 0xffffffffffffffffULL)\n\t\treturn strlcpy(s, \"forever\", l);\n\n\tif (cert->valid_after != 0) {\n\t\t/* XXX revisit INT_MAX in 2038 :) */\n\t\ttt = cert->valid_after > INT_MAX ?\n\t\t INT_MAX : cert->valid_after;\n\t\ttm = localtime(&tt);\n\t\tstrftime(from, sizeof(from), \"%Y-%m-%dT%H:%M:%S\", tm);\n\t}\n\tif (cert->valid_before != 0xffffffffffffffffULL) {\n\t\t/* XXX revisit INT_MAX in 2038 :) */\n\t\ttt = cert->valid_before > INT_MAX ?\n\t\t INT_MAX : cert->valid_before;\n\t\ttm = localtime(&tt);\n\t\tstrftime(to, sizeof(to), \"%Y-%m-%dT%H:%M:%S\", tm);\n\t}\n\n\tif (cert->valid_after == 0)\n\t\tsnprintf(ret, sizeof(ret), \"before %s\", to);\n\telse if (cert->valid_before == 0xffffffffffffffffULL)\n\t\tsnprintf(ret, sizeof(ret), \"after %s\", from);\n\telse\n\t\tsnprintf(ret, sizeof(ret), \"from %s to %s\", from, to);\n\n\treturn strlcpy(s, ret, l);\n}\n\nint\nsshkey_private_serialize(const struct sshkey *key, struct sshbuf *b)\n{\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\tif ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)\n\t\tgoto out;\n\tswitch (key->type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA:\n\t\tif ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_RSA_CERT:\n\t\tif (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {\n\t\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_DSA:\n\t\tif ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_DSA_CERT:\n\t\tif (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {\n\t\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\t\tif ((r = sshbuf_put_cstring(b,\n\t\t sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 ||\n\t\t (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b,\n\t\t EC_KEY_get0_private_key(key->ecdsa))) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_ECDSA_CERT:\n\t\tif (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {\n\t\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||\n\t\t (r = sshbuf_put_bignum2(b,\n\t\t EC_KEY_get0_private_key(key->ecdsa))) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\t\tif ((r = sshbuf_put_string(b, key->ed25519_pk,\n\t\t ED25519_PK_SZ)) != 0 ||\n\t\t (r = sshbuf_put_string(b, key->ed25519_sk,\n\t\t ED25519_SK_SZ)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_ED25519_CERT:\n\t\tif (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {\n\t\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||\n\t\t (r = sshbuf_put_string(b, key->ed25519_pk,\n\t\t ED25519_PK_SZ)) != 0 ||\n\t\t (r = sshbuf_put_string(b, key->ed25519_sk,\n\t\t ED25519_SK_SZ)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tdefault:\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\t/* success */\n\tr = 0;\n out:\n\treturn r;\n}\n\nint\nsshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)\n{\n\tchar *tname = NULL, *curve = NULL;\n\tstruct sshkey *k = NULL;\n\tsize_t pklen = 0, sklen = 0;\n\tint type, r = SSH_ERR_INTERNAL_ERROR;\n\tu_char *ed25519_pk = NULL, *ed25519_sk = NULL;\n#ifdef WITH_OPENSSL\n\tBIGNUM *exponent = NULL;\n#endif /* WITH_OPENSSL */\n\n\tif (kp != NULL)\n\t\t*kp = NULL;\n\tif ((r = sshbuf_get_cstring(buf, &tname, NULL)) != 0)\n\t\tgoto out;\n\ttype = sshkey_type_from_name(tname);\n\tswitch (type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA:\n\t\tif ((k = sshkey_new_private(type)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_DSA_CERT:\n\t\tif ((r = sshkey_froms(buf, &k)) != 0 ||\n\t\t (r = sshkey_add_private(k)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n# ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\t\tif ((k = sshkey_new_private(type)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((k->ecdsa_nid = sshkey_ecdsa_nid_from_name(tname)) == -1) {\n\t\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_cstring(buf, &curve, NULL)) != 0)\n\t\t\tgoto out;\n\t\tif (k->ecdsa_nid != sshkey_curve_name_to_nid(curve)) {\n\t\t\tr = SSH_ERR_EC_CURVE_MISMATCH;\n\t\t\tgoto out;\n\t\t}\n\t\tk->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);\n\t\tif (k->ecdsa == NULL || (exponent = BN_new()) == NULL) {\n\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, exponent)))\n\t\t\tgoto out;\n\t\tif (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {\n\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),\n\t\t EC_KEY_get0_public_key(k->ecdsa))) != 0 ||\n\t\t (r = sshkey_ec_validate_private(k->ecdsa)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_ECDSA_CERT:\n\t\tif ((exponent = BN_new()) == NULL) {\n\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshkey_froms(buf, &k)) != 0 ||\n\t\t (r = sshkey_add_private(k)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, exponent)) != 0)\n\t\t\tgoto out;\n\t\tif (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {\n\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa),\n\t\t EC_KEY_get0_public_key(k->ecdsa))) != 0 ||\n\t\t (r = sshkey_ec_validate_private(k->ecdsa)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n# endif /* OPENSSL_HAS_ECC */\n\tcase KEY_RSA:\n\t\tif ((k = sshkey_new_private(type)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||\n\t\t (r = rsa_generate_additional_parameters(k->rsa)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tcase KEY_RSA_CERT:\n\t\tif ((r = sshkey_froms(buf, &k)) != 0 ||\n\t\t (r = sshkey_add_private(k)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||\n\t\t (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||\n\t\t (r = rsa_generate_additional_parameters(k->rsa)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\t\tif ((k = sshkey_new_private(type)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||\n\t\t (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)\n\t\t\tgoto out;\n\t\tif (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tk->ed25519_pk = ed25519_pk;\n\t\tk->ed25519_sk = ed25519_sk;\n\t\ted25519_pk = ed25519_sk = NULL;\n\t\tbreak;\n\tcase KEY_ED25519_CERT:\n\t\tif ((r = sshkey_froms(buf, &k)) != 0 ||\n\t\t (r = sshkey_add_private(k)) != 0 ||\n\t\t (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||\n\t\t (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)\n\t\t\tgoto out;\n\t\tif (pklen != ED25519_PK_SZ || sklen != ED25519_SK_SZ) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tk->ed25519_pk = ed25519_pk;\n\t\tk->ed25519_sk = ed25519_sk;\n\t\ted25519_pk = ed25519_sk = NULL;\n\t\tbreak;\n\tdefault:\n\t\tr = SSH_ERR_KEY_TYPE_UNKNOWN;\n\t\tgoto out;\n\t}\n#ifdef WITH_OPENSSL\n\t/* enable blinding */\n\tswitch (k->type) {\n\tcase KEY_RSA:\n\tcase KEY_RSA_CERT:\n\tcase KEY_RSA1:\n\t\tif (RSA_blinding_on(k->rsa, NULL) != 1) {\n\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tbreak;\n\t}\n#endif /* WITH_OPENSSL */\n\t/* success */\n\tr = 0;\n\tif (kp != NULL) {\n\t\t*kp = k;\n\t\tk = NULL;\n\t}\n out:\n\tfree(tname);\n\tfree(curve);\n#ifdef WITH_OPENSSL\n\tif (exponent != NULL)\n\t\tBN_clear_free(exponent);\n#endif /* WITH_OPENSSL */\n\tsshkey_free(k);\n\tif (ed25519_pk != NULL) {\n\t\texplicit_bzero(ed25519_pk, pklen);\n\t\tfree(ed25519_pk);\n\t}\n\tif (ed25519_sk != NULL) {\n\t\texplicit_bzero(ed25519_sk, sklen);\n\t\tfree(ed25519_sk);\n\t}\n\treturn r;\n}\n\n#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)\nint\nsshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)\n{\n\tBN_CTX *bnctx;\n\tEC_POINT *nq = NULL;\n\tBIGNUM *order, *x, *y, *tmp;\n\tint ret = SSH_ERR_KEY_INVALID_EC_VALUE;\n\n\t/*\n\t * NB. This assumes OpenSSL has already verified that the public\n\t * point lies on the curve. This is done by EC_POINT_oct2point()\n\t * implicitly calling EC_POINT_is_on_curve(). If this code is ever\n\t * reachable with public points not unmarshalled using\n\t * EC_POINT_oct2point then the caller will need to explicitly check.\n\t */\n\n\tif ((bnctx = BN_CTX_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tBN_CTX_start(bnctx);\n\n\t/*\n\t * We shouldn't ever hit this case because bignum_get_ecpoint()\n\t * refuses to load GF2m points.\n\t */\n\tif (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=\n\t NID_X9_62_prime_field)\n\t\tgoto out;\n\n\t/* Q != infinity */\n\tif (EC_POINT_is_at_infinity(group, public))\n\t\tgoto out;\n\n\tif ((x = BN_CTX_get(bnctx)) == NULL ||\n\t (y = BN_CTX_get(bnctx)) == NULL ||\n\t (order = BN_CTX_get(bnctx)) == NULL ||\n\t (tmp = BN_CTX_get(bnctx)) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\n\t/* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */\n\tif (EC_GROUP_get_order(group, order, bnctx) != 1 ||\n\t EC_POINT_get_affine_coordinates_GFp(group, public,\n\t x, y, bnctx) != 1) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif (BN_num_bits(x) <= BN_num_bits(order) / 2 ||\n\t BN_num_bits(y) <= BN_num_bits(order) / 2)\n\t\tgoto out;\n\n\t/* nQ == infinity (n == order of subgroup) */\n\tif ((nq = EC_POINT_new(group)) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif (EC_POINT_is_at_infinity(group, nq) != 1)\n\t\tgoto out;\n\n\t/* x < order - 1, y < order - 1 */\n\tif (!BN_sub(tmp, order, BN_value_one())) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif (BN_cmp(x, tmp) >= 0 || BN_cmp(y, tmp) >= 0)\n\t\tgoto out;\n\tret = 0;\n out:\n\tBN_CTX_free(bnctx);\n\tif (nq != NULL)\n\t\tEC_POINT_free(nq);\n\treturn ret;\n}\n\nint\nsshkey_ec_validate_private(const EC_KEY *key)\n{\n\tBN_CTX *bnctx;\n\tBIGNUM *order, *tmp;\n\tint ret = SSH_ERR_KEY_INVALID_EC_VALUE;\n\n\tif ((bnctx = BN_CTX_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tBN_CTX_start(bnctx);\n\n\tif ((order = BN_CTX_get(bnctx)) == NULL ||\n\t (tmp = BN_CTX_get(bnctx)) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\n\t/* log2(private) > log2(order)/2 */\n\tif (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif (BN_num_bits(EC_KEY_get0_private_key(key)) <=\n\t BN_num_bits(order) / 2)\n\t\tgoto out;\n\n\t/* private < order - 1 */\n\tif (!BN_sub(tmp, order, BN_value_one())) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0)\n\t\tgoto out;\n\tret = 0;\n out:\n\tBN_CTX_free(bnctx);\n\treturn ret;\n}\n\nvoid\nsshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)\n{\n\tBIGNUM *x, *y;\n\tBN_CTX *bnctx;\n\n\tif (point == NULL) {\n\t\tfputs(\"point=(NULL)\\n\", stderr);\n\t\treturn;\n\t}\n\tif ((bnctx = BN_CTX_new()) == NULL) {\n\t\tfprintf(stderr, \"%s: BN_CTX_new failed\\n\", __func__);\n\t\treturn;\n\t}\n\tBN_CTX_start(bnctx);\n\tif ((x = BN_CTX_get(bnctx)) == NULL ||\n\t (y = BN_CTX_get(bnctx)) == NULL) {\n\t\tfprintf(stderr, \"%s: BN_CTX_get failed\\n\", __func__);\n\t\treturn;\n\t}\n\tif (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=\n\t NID_X9_62_prime_field) {\n\t\tfprintf(stderr, \"%s: group is not a prime field\\n\", __func__);\n\t\treturn;\n\t}\n\tif (EC_POINT_get_affine_coordinates_GFp(group, point, x, y,\n\t bnctx) != 1) {\n\t\tfprintf(stderr, \"%s: EC_POINT_get_affine_coordinates_GFp\\n\",\n\t\t __func__);\n\t\treturn;\n\t}\n\tfputs(\"x=\", stderr);\n\tBN_print_fp(stderr, x);\n\tfputs(\"\\ny=\", stderr);\n\tBN_print_fp(stderr, y);\n\tfputs(\"\\n\", stderr);\n\tBN_CTX_free(bnctx);\n}\n\nvoid\nsshkey_dump_ec_key(const EC_KEY *key)\n{\n\tconst BIGNUM *exponent;\n\n\tsshkey_dump_ec_point(EC_KEY_get0_group(key),\n\t EC_KEY_get0_public_key(key));\n\tfputs(\"exponent=\", stderr);\n\tif ((exponent = EC_KEY_get0_private_key(key)) == NULL)\n\t\tfputs(\"(NULL)\", stderr);\n\telse\n\t\tBN_print_fp(stderr, EC_KEY_get0_private_key(key));\n\tfputs(\"\\n\", stderr);\n}\n#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */\n\nstatic int\nsshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,\n const char *passphrase, const char *comment, const char *ciphername,\n int rounds)\n{\n\tu_char *cp, *key = NULL, *pubkeyblob = NULL;\n\tu_char salt[SALT_LEN];\n\tchar *b64 = NULL;\n\tsize_t i, pubkeylen, keylen, ivlen, blocksize, authlen;\n\tu_int check;\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\tstruct sshcipher_ctx *ciphercontext = NULL;\n\tconst struct sshcipher *cipher;\n\tconst char *kdfname = KDFNAME;\n\tstruct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL;\n\n\tif (rounds <= 0)\n\t\trounds = DEFAULT_ROUNDS;\n\tif (passphrase == NULL || !strlen(passphrase)) {\n\t\tciphername = \"none\";\n\t\tkdfname = \"none\";\n\t} else if (ciphername == NULL)\n\t\tciphername = DEFAULT_CIPHERNAME;\n\telse if (cipher_number(ciphername) != SSH_CIPHER_SSH2) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\tif ((cipher = cipher_by_name(ciphername)) == NULL) {\n\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\tgoto out;\n\t}\n\n\tif ((kdf = sshbuf_new()) == NULL ||\n\t (encoded = sshbuf_new()) == NULL ||\n\t (encrypted = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tblocksize = cipher_blocksize(cipher);\n\tkeylen = cipher_keylen(cipher);\n\tivlen = cipher_ivlen(cipher);\n\tauthlen = cipher_authlen(cipher);\n\tif ((key = calloc(1, keylen + ivlen)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (strcmp(kdfname, \"bcrypt\") == 0) {\n\t\tarc4random_buf(salt, SALT_LEN);\n\t\tif (bcrypt_pbkdf(passphrase, strlen(passphrase),\n\t\t salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) {\n\t\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_put_string(kdf, salt, SALT_LEN)) != 0 ||\n\t\t (r = sshbuf_put_u32(kdf, rounds)) != 0)\n\t\t\tgoto out;\n\t} else if (strcmp(kdfname, \"none\") != 0) {\n\t\t/* Unsupported KDF type */\n\t\tr = SSH_ERR_KEY_UNKNOWN_CIPHER;\n\t\tgoto out;\n\t}\n\tif ((r = cipher_init(&ciphercontext, cipher, key, keylen,\n\t key + keylen, ivlen, 1)) != 0)\n\t\tgoto out;\n\n\tif ((r = sshbuf_put(encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC))) != 0 ||\n\t (r = sshbuf_put_cstring(encoded, ciphername)) != 0 ||\n\t (r = sshbuf_put_cstring(encoded, kdfname)) != 0 ||\n\t (r = sshbuf_put_stringb(encoded, kdf)) != 0 ||\n\t (r = sshbuf_put_u32(encoded, 1)) != 0 ||\t/* number of keys */\n\t (r = sshkey_to_blob(prv, &pubkeyblob, &pubkeylen)) != 0 ||\n\t (r = sshbuf_put_string(encoded, pubkeyblob, pubkeylen)) != 0)\n\t\tgoto out;\n\n\t/* set up the buffer that will be encrypted */\n\n\t/* Random check bytes */\n\tcheck = arc4random();\n\tif ((r = sshbuf_put_u32(encrypted, check)) != 0 ||\n\t (r = sshbuf_put_u32(encrypted, check)) != 0)\n\t\tgoto out;\n\n\t/* append private key and comment*/\n\tif ((r = sshkey_private_serialize(prv, encrypted)) != 0 ||\n\t (r = sshbuf_put_cstring(encrypted, comment)) != 0)\n\t\tgoto out;\n\n\t/* padding */\n\ti = 0;\n\twhile (sshbuf_len(encrypted) % blocksize) {\n\t\tif ((r = sshbuf_put_u8(encrypted, ++i & 0xff)) != 0)\n\t\t\tgoto out;\n\t}\n\n\t/* length in destination buffer */\n\tif ((r = sshbuf_put_u32(encoded, sshbuf_len(encrypted))) != 0)\n\t\tgoto out;\n\n\t/* encrypt */\n\tif ((r = sshbuf_reserve(encoded,\n\t sshbuf_len(encrypted) + authlen, &cp)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(ciphercontext, 0, cp,\n\t sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0)\n\t\tgoto out;\n\n\t/* uuencode */\n\tif ((b64 = sshbuf_dtob64(encoded)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\n\tsshbuf_reset(blob);\n\tif ((r = sshbuf_put(blob, MARK_BEGIN, MARK_BEGIN_LEN)) != 0)\n\t\tgoto out;\n\tfor (i = 0; i < strlen(b64); i++) {\n\t\tif ((r = sshbuf_put_u8(blob, b64[i])) != 0)\n\t\t\tgoto out;\n\t\t/* insert line breaks */\n\t\tif (i % 70 == 69 && (r = sshbuf_put_u8(blob, '\\n')) != 0)\n\t\t\tgoto out;\n\t}\n\tif (i % 70 != 69 && (r = sshbuf_put_u8(blob, '\\n')) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_put(blob, MARK_END, MARK_END_LEN)) != 0)\n\t\tgoto out;\n\n\t/* success */\n\tr = 0;\n\n out:\n\tsshbuf_free(kdf);\n\tsshbuf_free(encoded);\n\tsshbuf_free(encrypted);\n\tcipher_free(ciphercontext);\n\texplicit_bzero(salt, sizeof(salt));\n\tif (key != NULL) {\n\t\texplicit_bzero(key, keylen + ivlen);\n\t\tfree(key);\n\t}\n\tif (pubkeyblob != NULL) {\n\t\texplicit_bzero(pubkeyblob, pubkeylen);\n\t\tfree(pubkeyblob);\n\t}\n\tif (b64 != NULL) {\n\t\texplicit_bzero(b64, strlen(b64));\n\t\tfree(b64);\n\t}\n\treturn r;\n}\n\nstatic int\nsshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,\n struct sshkey **keyp, char **commentp)\n{\n\tchar *comment = NULL, *ciphername = NULL, *kdfname = NULL;\n\tconst struct sshcipher *cipher = NULL;\n\tconst u_char *cp;\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\tsize_t encoded_len;\n\tsize_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0;\n\tstruct sshbuf *encoded = NULL, *decoded = NULL;\n\tstruct sshbuf *kdf = NULL, *decrypted = NULL;\n\tstruct sshcipher_ctx *ciphercontext = NULL;\n\tstruct sshkey *k = NULL;\n\tu_char *key = NULL, *salt = NULL, *dp, pad, last;\n\tu_int blocksize, rounds, nkeys, encrypted_len, check1, check2;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\tif ((encoded = sshbuf_new()) == NULL ||\n\t (decoded = sshbuf_new()) == NULL ||\n\t (decrypted = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\n\t/* check preamble */\n\tcp = sshbuf_ptr(blob);\n\tencoded_len = sshbuf_len(blob);\n\tif (encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) ||\n\t memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tcp += MARK_BEGIN_LEN;\n\tencoded_len -= MARK_BEGIN_LEN;\n\n\t/* Look for end marker, removing whitespace as we go */\n\twhile (encoded_len > 0) {\n\t\tif (*cp != '\\n' && *cp != '\\r') {\n\t\t\tif ((r = sshbuf_put_u8(encoded, *cp)) != 0)\n\t\t\t\tgoto out;\n\t\t}\n\t\tlast = *cp;\n\t\tencoded_len--;\n\t\tcp++;\n\t\tif (last == '\\n') {\n\t\t\tif (encoded_len >= MARK_END_LEN &&\n\t\t\t memcmp(cp, MARK_END, MARK_END_LEN) == 0) {\n\t\t\t\t/* \\0 terminate */\n\t\t\t\tif ((r = sshbuf_put_u8(encoded, 0)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif (encoded_len == 0) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\t/* decode base64 */\n\tif ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0)\n\t\tgoto out;\n\n\t/* check magic */\n\tif (sshbuf_len(decoded) < sizeof(AUTH_MAGIC) ||\n\t memcmp(sshbuf_ptr(decoded), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\t/* parse public portion of key */\n\tif ((r = sshbuf_consume(decoded, sizeof(AUTH_MAGIC))) != 0 ||\n\t (r = sshbuf_get_cstring(decoded, &ciphername, NULL)) != 0 ||\n\t (r = sshbuf_get_cstring(decoded, &kdfname, NULL)) != 0 ||\n\t (r = sshbuf_froms(decoded, &kdf)) != 0 ||\n\t (r = sshbuf_get_u32(decoded, &nkeys)) != 0 ||\n\t (r = sshbuf_skip_string(decoded)) != 0 || /* pubkey */\n\t (r = sshbuf_get_u32(decoded, &encrypted_len)) != 0)\n\t\tgoto out;\n\n\tif ((cipher = cipher_by_name(ciphername)) == NULL) {\n\t\tr = SSH_ERR_KEY_UNKNOWN_CIPHER;\n\t\tgoto out;\n\t}\n\tif ((passphrase == NULL || strlen(passphrase) == 0) &&\n\t strcmp(ciphername, \"none\") != 0) {\n\t\t/* passphrase required */\n\t\tr = SSH_ERR_KEY_WRONG_PASSPHRASE;\n\t\tgoto out;\n\t}\n\tif (strcmp(kdfname, \"none\") != 0 && strcmp(kdfname, \"bcrypt\") != 0) {\n\t\tr = SSH_ERR_KEY_UNKNOWN_CIPHER;\n\t\tgoto out;\n\t}\n\tif (!strcmp(kdfname, \"none\") && strcmp(ciphername, \"none\") != 0) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tif (nkeys != 1) {\n\t\t/* XXX only one key supported */\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\t/* check size of encrypted key blob */\n\tblocksize = cipher_blocksize(cipher);\n\tif (encrypted_len < blocksize || (encrypted_len % blocksize) != 0) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\t/* setup key */\n\tkeylen = cipher_keylen(cipher);\n\tivlen = cipher_ivlen(cipher);\n\tauthlen = cipher_authlen(cipher);\n\tif ((key = calloc(1, keylen + ivlen)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (strcmp(kdfname, \"bcrypt\") == 0) {\n\t\tif ((r = sshbuf_get_string(kdf, &salt, &slen)) != 0 ||\n\t\t (r = sshbuf_get_u32(kdf, &rounds)) != 0)\n\t\t\tgoto out;\n\t\tif (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,\n\t\t key, keylen + ivlen, rounds) < 0) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\t/* check that an appropriate amount of auth data is present */\n\tif (sshbuf_len(decoded) < encrypted_len + authlen) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\t/* decrypt private portion of key */\n\tif ((r = sshbuf_reserve(decrypted, encrypted_len, &dp)) != 0 ||\n\t (r = cipher_init(&ciphercontext, cipher, key, keylen,\n\t key + keylen, ivlen, 0)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded),\n\t encrypted_len, 0, authlen)) != 0) {\n\t\t/* an integrity error here indicates an incorrect passphrase */\n\t\tif (r == SSH_ERR_MAC_INVALID)\n\t\t\tr = SSH_ERR_KEY_WRONG_PASSPHRASE;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_consume(decoded, encrypted_len + authlen)) != 0)\n\t\tgoto out;\n\t/* there should be no trailing data */\n\tif (sshbuf_len(decoded) != 0) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\t/* check check bytes */\n\tif ((r = sshbuf_get_u32(decrypted, &check1)) != 0 ||\n\t (r = sshbuf_get_u32(decrypted, &check2)) != 0)\n\t\tgoto out;\n\tif (check1 != check2) {\n\t\tr = SSH_ERR_KEY_WRONG_PASSPHRASE;\n\t\tgoto out;\n\t}\n\n\t/* Load the private key and comment */\n\tif ((r = sshkey_private_deserialize(decrypted, &k)) != 0 ||\n\t (r = sshbuf_get_cstring(decrypted, &comment, NULL)) != 0)\n\t\tgoto out;\n\n\t/* Check deterministic padding */\n\ti = 0;\n\twhile (sshbuf_len(decrypted)) {\n\t\tif ((r = sshbuf_get_u8(decrypted, &pad)) != 0)\n\t\t\tgoto out;\n\t\tif (pad != (++i & 0xff)) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\t/* XXX decode pubkey and check against private */\n\n\t/* success */\n\tr = 0;\n\tif (keyp != NULL) {\n\t\t*keyp = k;\n\t\tk = NULL;\n\t}\n\tif (commentp != NULL) {\n\t\t*commentp = comment;\n\t\tcomment = NULL;\n\t}\n out:\n\tpad = 0;\n\tcipher_free(ciphercontext);\n\tfree(ciphername);\n\tfree(kdfname);\n\tfree(comment);\n\tif (salt != NULL) {\n\t\texplicit_bzero(salt, slen);\n\t\tfree(salt);\n\t}\n\tif (key != NULL) {\n\t\texplicit_bzero(key, keylen + ivlen);\n\t\tfree(key);\n\t}\n\tsshbuf_free(encoded);\n\tsshbuf_free(decoded);\n\tsshbuf_free(kdf);\n\tsshbuf_free(decrypted);\n\tsshkey_free(k);\n\treturn r;\n}\n\n#if WITH_SSH1\n/*\n * Serialises the authentication (private) key to a blob, encrypting it with\n * passphrase. The identification of the blob (lowest 64 bits of n) will\n * precede the key to provide identification of the key without needing a\n * passphrase.\n */\nstatic int\nsshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob,\n const char *passphrase, const char *comment)\n{\n\tstruct sshbuf *buffer = NULL, *encrypted = NULL;\n\tu_char buf[8];\n\tint r, cipher_num;\n\tstruct sshcipher_ctx *ciphercontext = NULL;\n\tconst struct sshcipher *cipher;\n\tu_char *cp;\n\n\t/*\n\t * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting\n\t * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.\n\t */\n\tcipher_num = (strcmp(passphrase, \"\") == 0) ?\n\t SSH_CIPHER_NONE : SSH_CIPHER_3DES;\n\tif ((cipher = cipher_by_number(cipher_num)) == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\n\t/* This buffer is used to build the secret part of the private key. */\n\tif ((buffer = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\t/* Put checkbytes for checking passphrase validity. */\n\tif ((r = sshbuf_reserve(buffer, 4, &cp)) != 0)\n\t\tgoto out;\n\tarc4random_buf(cp, 2);\n\tmemcpy(cp + 2, cp, 2);\n\n\t/*\n\t * Store the private key (n and e will not be stored because they\n\t * will be stored in plain text, and storing them also in encrypted\n\t * format would just give known plaintext).\n\t * Note: q and p are stored in reverse order to SSL.\n\t */\n\tif ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 ||\n\t (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 ||\n\t (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 ||\n\t (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0)\n\t\tgoto out;\n\n\t/* Pad the part to be encrypted to a size that is a multiple of 8. */\n\texplicit_bzero(buf, 8);\n\tif ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0)\n\t\tgoto out;\n\n\t/* This buffer will be used to contain the data in the file. */\n\tif ((encrypted = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\n\t/* First store keyfile id string. */\n\tif ((r = sshbuf_put(encrypted, LEGACY_BEGIN,\n\t sizeof(LEGACY_BEGIN))) != 0)\n\t\tgoto out;\n\n\t/* Store cipher type and \"reserved\" field. */\n\tif ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 ||\n\t (r = sshbuf_put_u32(encrypted, 0)) != 0)\n\t\tgoto out;\n\n\t/* Store public key. This will be in plain text. */\n\tif ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||\n\t (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 ||\n\t (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 ||\n\t (r = sshbuf_put_cstring(encrypted, comment)) != 0)\n\t\tgoto out;\n\n\t/* Allocate space for the private part of the key in the buffer. */\n\tif ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0)\n\t\tgoto out;\n\n\tif ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,\n\t CIPHER_ENCRYPT)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(ciphercontext, 0, cp,\n\t sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0)\n\t\tgoto out;\n\n\tr = sshbuf_putb(blob, encrypted);\n\n out:\n\tcipher_free(ciphercontext);\n\texplicit_bzero(buf, sizeof(buf));\n\tsshbuf_free(buffer);\n\tsshbuf_free(encrypted);\n\n\treturn r;\n}\n#endif /* WITH_SSH1 */\n\n#ifdef WITH_OPENSSL\n/* convert SSH v2 key in OpenSSL PEM format */\nstatic int\nsshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,\n const char *_passphrase, const char *comment)\n{\n\tint success, r;\n\tint blen, len = strlen(_passphrase);\n\tu_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;\n#if (OPENSSL_VERSION_NUMBER < 0x00907000L)\n\tconst EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;\n#else\n \tconst EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;\n#endif\n\tconst u_char *bptr;\n\tBIO *bio = NULL;\n\n\tif (len > 0 && len <= 4)\n\t\treturn SSH_ERR_PASSPHRASE_TOO_SHORT;\n\tif ((bio = BIO_new(BIO_s_mem())) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\tswitch (key->type) {\n\tcase KEY_DSA:\n\t\tsuccess = PEM_write_bio_DSAPrivateKey(bio, key->dsa,\n\t\t cipher, passphrase, len, NULL, NULL);\n\t\tbreak;\n#ifdef OPENSSL_HAS_ECC\n\tcase KEY_ECDSA:\n\t\tsuccess = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,\n\t\t cipher, passphrase, len, NULL, NULL);\n\t\tbreak;\n#endif\n\tcase KEY_RSA:\n\t\tsuccess = PEM_write_bio_RSAPrivateKey(bio, key->rsa,\n\t\t cipher, passphrase, len, NULL, NULL);\n\t\tbreak;\n\tdefault:\n\t\tsuccess = 0;\n\t\tbreak;\n\t}\n\tif (success == 0) {\n\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) {\n\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_put(blob, bptr, blen)) != 0)\n\t\tgoto out;\n\tr = 0;\n out:\n\tBIO_free(bio);\n\treturn r;\n}\n#endif /* WITH_OPENSSL */\n\n/* Serialise \"key\" to buffer \"blob\" */\nint\nsshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,\n const char *passphrase, const char *comment,\n int force_new_format, const char *new_format_cipher, int new_format_rounds)\n{\n\tswitch (key->type) {\n#ifdef WITH_SSH1\n\tcase KEY_RSA1:\n\t\treturn sshkey_private_rsa1_to_blob(key, blob,\n\t\t passphrase, comment);\n#endif /* WITH_SSH1 */\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA:\n\tcase KEY_ECDSA:\n\tcase KEY_RSA:\n\t\tif (force_new_format) {\n\t\t\treturn sshkey_private_to_blob2(key, blob, passphrase,\n\t\t\t comment, new_format_cipher, new_format_rounds);\n\t\t}\n\t\treturn sshkey_private_pem_to_blob(key, blob,\n\t\t passphrase, comment);\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\t\treturn sshkey_private_to_blob2(key, blob, passphrase,\n\t\t comment, new_format_cipher, new_format_rounds);\n\tdefault:\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\t}\n}\n\n#ifdef WITH_SSH1\n/*\n * Parse the public, unencrypted portion of a RSA1 key.\n */\nint\nsshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,\n struct sshkey **keyp, char **commentp)\n{\n\tint r;\n\tstruct sshkey *pub = NULL;\n\tstruct sshbuf *copy = NULL;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\t/* Check that it is at least big enough to contain the ID string. */\n\tif (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\n\t/*\n\t * Make sure it begins with the id string. Consume the id string\n\t * from the buffer.\n\t */\n\tif (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\t/* Make a working copy of the keyblob and skip past the magic */\n\tif ((copy = sshbuf_fromb(blob)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)\n\t\tgoto out;\n\n\t/* Skip cipher type, reserved data and key bits. */\n\tif ((r = sshbuf_get_u8(copy, NULL)) != 0 ||\t/* cipher type */\n\t (r = sshbuf_get_u32(copy, NULL)) != 0 ||\t/* reserved */\n\t (r = sshbuf_get_u32(copy, NULL)) != 0)\t/* key bits */\n\t\tgoto out;\n\n\t/* Read the public key from the buffer. */\n\tif ((pub = sshkey_new(KEY_RSA1)) == NULL ||\n\t (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 ||\n\t (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0)\n\t\tgoto out;\n\n\t/* Finally, the comment */\n\tif ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0)\n\t\tgoto out;\n\n\t/* The encrypted private part is not parsed by this function. */\n\n\tr = 0;\n\tif (keyp != NULL) {\n\t\t*keyp = pub;\n\t\tpub = NULL;\n\t}\n out:\n\tsshbuf_free(copy);\n\tsshkey_free(pub);\n\treturn r;\n}\n\nstatic int\nsshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase,\n struct sshkey **keyp, char **commentp)\n{\n\tint r;\n\tu_int16_t check1, check2;\n\tu_int8_t cipher_type;\n\tstruct sshbuf *decrypted = NULL, *copy = NULL;\n\tu_char *cp;\n\tchar *comment = NULL;\n\tstruct sshcipher_ctx *ciphercontext = NULL;\n\tconst struct sshcipher *cipher;\n\tstruct sshkey *prv = NULL;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\t/* Check that it is at least big enough to contain the ID string. */\n\tif (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\n\t/*\n\t * Make sure it begins with the id string. Consume the id string\n\t * from the buffer.\n\t */\n\tif (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\n\tif ((prv = sshkey_new_private(KEY_RSA1)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((copy = sshbuf_fromb(blob)) == NULL ||\n\t (decrypted = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)\n\t\tgoto out;\n\n\t/* Read cipher type. */\n\tif ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 ||\n\t (r = sshbuf_get_u32(copy, NULL)) != 0)\t/* reserved */\n\t\tgoto out;\n\n\t/* Read the public key and comment from the buffer. */\n\tif ((r = sshbuf_get_u32(copy, NULL)) != 0 ||\t/* key bits */\n\t (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 ||\n\t (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 ||\n\t (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0)\n\t\tgoto out;\n\n\t/* Check that it is a supported cipher. */\n\tcipher = cipher_by_number(cipher_type);\n\tif (cipher == NULL) {\n\t\tr = SSH_ERR_KEY_UNKNOWN_CIPHER;\n\t\tgoto out;\n\t}\n\t/* Initialize space for decrypted data. */\n\tif ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0)\n\t\tgoto out;\n\n\t/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */\n\tif ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,\n\t CIPHER_DECRYPT)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(ciphercontext, 0, cp,\n\t sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0)\n\t\tgoto out;\n\n\tif ((r = sshbuf_get_u16(decrypted, &check1)) != 0 ||\n\t (r = sshbuf_get_u16(decrypted, &check2)) != 0)\n\t\tgoto out;\n\tif (check1 != check2) {\n\t\tr = SSH_ERR_KEY_WRONG_PASSPHRASE;\n\t\tgoto out;\n\t}\n\n\t/* Read the rest of the private key. */\n\tif ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 ||\n\t (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 ||\n\t (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 ||\n\t (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0)\n\t\tgoto out;\n\n\t/* calculate p-1 and q-1 */\n\tif ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)\n\t\tgoto out;\n\n\t/* enable blinding */\n\tif (RSA_blinding_on(prv->rsa, NULL) != 1) {\n\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tr = 0;\n\tif (keyp != NULL) {\n\t\t*keyp = prv;\n\t\tprv = NULL;\n\t}\n\tif (commentp != NULL) {\n\t\t*commentp = comment;\n\t\tcomment = NULL;\n\t}\n out:\n\tcipher_free(ciphercontext);\n\tfree(comment);\n\tsshkey_free(prv);\n\tsshbuf_free(copy);\n\tsshbuf_free(decrypted);\n\treturn r;\n}\n#endif /* WITH_SSH1 */\n\n#ifdef WITH_OPENSSL\nstatic int\nsshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,\n const char *passphrase, struct sshkey **keyp)\n{\n\tEVP_PKEY *pk = NULL;\n\tstruct sshkey *prv = NULL;\n\tBIO *bio = NULL;\n\tint r;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\n\tif ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif (BIO_write(bio, sshbuf_ptr(blob), sshbuf_len(blob)) !=\n\t (int)sshbuf_len(blob)) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\n\tif ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,\n\t (char *)passphrase)) == NULL) {\n\t\tunsigned long pem_err = ERR_peek_last_error();\n\t\tint pem_reason = ERR_GET_REASON(pem_err);\n\n\t\t/*\n\t\t * Translate OpenSSL error codes to determine whether\n\t\t * passphrase is required/incorrect.\n\t\t */\n\t\tswitch (ERR_GET_LIB(pem_err)) {\n\t\tcase ERR_LIB_PEM:\n\t\t\tswitch (pem_reason) {\n\t\t\tcase PEM_R_BAD_PASSWORD_READ:\n\t\t\tcase PEM_R_PROBLEMS_GETTING_PASSWORD:\n\t\t\tcase PEM_R_BAD_DECRYPT:\n\t\t\t\tr = SSH_ERR_KEY_WRONG_PASSPHRASE;\n\t\t\t\tgoto out;\n\t\t\tdefault:\n\t\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\tcase ERR_LIB_EVP:\n\t\t\tswitch (pem_reason) {\n\t\t\tcase EVP_R_BAD_DECRYPT:\n\t\t\t\tr = SSH_ERR_KEY_WRONG_PASSPHRASE;\n\t\t\t\tgoto out;\n\t\t\tcase EVP_R_BN_DECODE_ERROR:\n\t\t\tcase EVP_R_DECODE_ERROR:\n#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR\n\t\t\tcase EVP_R_PRIVATE_KEY_DECODE_ERROR:\n#endif\n\t\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\t\tgoto out;\n\t\t\tdefault:\n\t\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\tcase ERR_LIB_ASN1:\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif (pk->type == EVP_PKEY_RSA &&\n\t (type == KEY_UNSPEC || type == KEY_RSA)) {\n\t\tif ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tprv->rsa = EVP_PKEY_get1_RSA(pk);\n\t\tprv->type = KEY_RSA;\n#ifdef DEBUG_PK\n\t\tRSA_print_fp(stderr, prv->rsa, 8);\n#endif\n\t\tif (RSA_blinding_on(prv->rsa, NULL) != 1) {\n\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t} else if (pk->type == EVP_PKEY_DSA &&\n\t (type == KEY_UNSPEC || type == KEY_DSA)) {\n\t\tif ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tprv->dsa = EVP_PKEY_get1_DSA(pk);\n\t\tprv->type = KEY_DSA;\n#ifdef DEBUG_PK\n\t\tDSA_print_fp(stderr, prv->dsa, 8);\n#endif\n#ifdef OPENSSL_HAS_ECC\n\t} else if (pk->type == EVP_PKEY_EC &&\n\t (type == KEY_UNSPEC || type == KEY_ECDSA)) {\n\t\tif ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tprv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);\n\t\tprv->type = KEY_ECDSA;\n\t\tprv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa);\n\t\tif (prv->ecdsa_nid == -1 ||\n\t\t sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL ||\n\t\t sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),\n\t\t EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||\n\t\t sshkey_ec_validate_private(prv->ecdsa) != 0) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n# ifdef DEBUG_PK\n\t\tif (prv != NULL && prv->ecdsa != NULL)\n\t\t\tsshkey_dump_ec_key(prv->ecdsa);\n# endif\n#endif /* OPENSSL_HAS_ECC */\n\t} else {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tr = 0;\n\tif (keyp != NULL) {\n\t\t*keyp = prv;\n\t\tprv = NULL;\n\t}\n out:\n\tBIO_free(bio);\n\tif (pk != NULL)\n\t\tEVP_PKEY_free(pk);\n\tsshkey_free(prv);\n\treturn r;\n}\n#endif /* WITH_OPENSSL */\n\nint\nsshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,\n const char *passphrase, struct sshkey **keyp, char **commentp)\n{\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\tswitch (type) {\n#ifdef WITH_SSH1\n\tcase KEY_RSA1:\n\t\treturn sshkey_parse_private_rsa1(blob, passphrase,\n\t\t keyp, commentp);\n#endif /* WITH_SSH1 */\n#ifdef WITH_OPENSSL\n\tcase KEY_DSA:\n\tcase KEY_ECDSA:\n\tcase KEY_RSA:\n\t\treturn sshkey_parse_private_pem_fileblob(blob, type,\n\t\t passphrase, keyp);\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\t\treturn sshkey_parse_private2(blob, type, passphrase,\n\t\t keyp, commentp);\n\tcase KEY_UNSPEC:\n\t\tr = sshkey_parse_private2(blob, type, passphrase, keyp,\n\t\t commentp);\n\t\t/* Do not fallback to PEM parser if only passphrase is wrong. */\n\t\tif (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE)\n\t\t\treturn r;\n#ifdef WITH_OPENSSL\n\t\treturn sshkey_parse_private_pem_fileblob(blob, type,\n\t\t passphrase, keyp);\n#else\n\t\treturn SSH_ERR_INVALID_FORMAT;\n#endif /* WITH_OPENSSL */\n\tdefault:\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\t}\n}\n\nint\nsshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,\n struct sshkey **keyp, char **commentp)\n{\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n#ifdef WITH_SSH1\n\t/* it's a SSH v1 key if the public key part is readable */\n\tif (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) {\n\t\treturn sshkey_parse_private_fileblob_type(buffer, KEY_RSA1,\n\t\t passphrase, keyp, commentp);\n\t}\n#endif /* WITH_SSH1 */\n\treturn sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,\n\t passphrase, keyp, commentp);\n}\n","/*\t$OpenBSD: sshbuf-getput-basic.c,v 1.6 2016/06/16 11:00:17 dtucker Exp $\t*/\n/*\n * Copyright (c) 2011 Damien Miller\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#define SSHBUF_INTERNAL\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n#include \n#include \n\n#include \"ssherr.h\"\n#include \"sshbuf.h\"\n\nint\nsshbuf_get(struct sshbuf *buf, void *v, size_t len)\n{\n\tconst u_char *p = sshbuf_ptr(buf);\n\tint r;\n\n\tif ((r = sshbuf_consume(buf, len)) < 0)\n\t\treturn r;\n\tif (v != NULL && len != 0)\n\t\tmemcpy(v, p, len);\n\treturn 0;\n}\n\nint\nsshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp)\n{\n\tconst u_char *p = sshbuf_ptr(buf);\n\tint r;\n\n\tif ((r = sshbuf_consume(buf, 8)) < 0)\n\t\treturn r;\n\tif (valp != NULL)\n\t\t*valp = PEEK_U64(p);\n\treturn 0;\n}\n\nint\nsshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp)\n{\n\tconst u_char *p = sshbuf_ptr(buf);\n\tint r;\n\n\tif ((r = sshbuf_consume(buf, 4)) < 0)\n\t\treturn r;\n\tif (valp != NULL)\n\t\t*valp = PEEK_U32(p);\n\treturn 0;\n}\n\nint\nsshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp)\n{\n\tconst u_char *p = sshbuf_ptr(buf);\n\tint r;\n\n\tif ((r = sshbuf_consume(buf, 2)) < 0)\n\t\treturn r;\n\tif (valp != NULL)\n\t\t*valp = PEEK_U16(p);\n\treturn 0;\n}\n\nint\nsshbuf_get_u8(struct sshbuf *buf, u_char *valp)\n{\n\tconst u_char *p = sshbuf_ptr(buf);\n\tint r;\n\n\tif ((r = sshbuf_consume(buf, 1)) < 0)\n\t\treturn r;\n\tif (valp != NULL)\n\t\t*valp = (u_int8_t)*p;\n\treturn 0;\n}\n\nint\nsshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp)\n{\n\tconst u_char *val;\n\tsize_t len;\n\tint r;\n\n\tif (valp != NULL)\n\t\t*valp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif ((r = sshbuf_get_string_direct(buf, &val, &len)) < 0)\n\t\treturn r;\n\tif (valp != NULL) {\n\t\tif ((*valp = malloc(len + 1)) == NULL) {\n\t\t\tSSHBUF_DBG((\"SSH_ERR_ALLOC_FAIL\"));\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t}\n\t\tif (len != 0)\n\t\t\tmemcpy(*valp, val, len);\n\t\t(*valp)[len] = '\\0';\n\t}\n\tif (lenp != NULL)\n\t\t*lenp = len;\n\treturn 0;\n}\n\nint\nsshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp)\n{\n\tsize_t len;\n\tconst u_char *p;\n\tint r;\n\n\tif (valp != NULL)\n\t\t*valp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif ((r = sshbuf_peek_string_direct(buf, &p, &len)) < 0)\n\t\treturn r;\n\tif (valp != NULL)\n\t\t*valp = p;\n\tif (lenp != NULL)\n\t\t*lenp = len;\n\tif (sshbuf_consume(buf, len + 4) != 0) {\n\t\t/* Shouldn't happen */\n\t\tSSHBUF_DBG((\"SSH_ERR_INTERNAL_ERROR\"));\n\t\tSSHBUF_ABORT();\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\treturn 0;\n}\n\nint\nsshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,\n size_t *lenp)\n{\n\tu_int32_t len;\n\tconst u_char *p = sshbuf_ptr(buf);\n\n\tif (valp != NULL)\n\t\t*valp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif (sshbuf_len(buf) < 4) {\n\t\tSSHBUF_DBG((\"SSH_ERR_MESSAGE_INCOMPLETE\"));\n\t\treturn SSH_ERR_MESSAGE_INCOMPLETE;\n\t}\n\tlen = PEEK_U32(p);\n\tif (len > SSHBUF_SIZE_MAX - 4) {\n\t\tSSHBUF_DBG((\"SSH_ERR_STRING_TOO_LARGE\"));\n\t\treturn SSH_ERR_STRING_TOO_LARGE;\n\t}\n\tif (sshbuf_len(buf) - 4 < len) {\n\t\tSSHBUF_DBG((\"SSH_ERR_MESSAGE_INCOMPLETE\"));\n\t\treturn SSH_ERR_MESSAGE_INCOMPLETE;\n\t}\n\tif (valp != NULL)\n\t\t*valp = p + 4;\n\tif (lenp != NULL)\n\t\t*lenp = len;\n\treturn 0;\n}\n\nint\nsshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp)\n{\n\tsize_t len;\n\tconst u_char *p, *z;\n\tint r;\n\n\tif (valp != NULL)\n\t\t*valp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0)\n\t\treturn r;\n\t/* Allow a \\0 only at the end of the string */\n\tif (len > 0 &&\n\t (z = memchr(p , '\\0', len)) != NULL && z < p + len - 1) {\n\t\tSSHBUF_DBG((\"SSH_ERR_INVALID_FORMAT\"));\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\t}\n\tif ((r = sshbuf_skip_string(buf)) != 0)\n\t\treturn -1;\n\tif (valp != NULL) {\n\t\tif ((*valp = malloc(len + 1)) == NULL) {\n\t\t\tSSHBUF_DBG((\"SSH_ERR_ALLOC_FAIL\"));\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\t}\n\t\tif (len != 0)\n\t\t\tmemcpy(*valp, p, len);\n\t\t(*valp)[len] = '\\0';\n\t}\n\tif (lenp != NULL)\n\t\t*lenp = (size_t)len;\n\treturn 0;\n}\n\nint\nsshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v)\n{\n\tu_int32_t len;\n\tu_char *p;\n\tint r;\n\n\t/*\n\t * Use sshbuf_peek_string_direct() to figure out if there is\n\t * a complete string in 'buf' and copy the string directly\n\t * into 'v'.\n\t */\n\tif ((r = sshbuf_peek_string_direct(buf, NULL, NULL)) != 0 ||\n\t (r = sshbuf_get_u32(buf, &len)) != 0 ||\n\t (r = sshbuf_reserve(v, len, &p)) != 0 ||\n\t (r = sshbuf_get(buf, p, len)) != 0)\n\t\treturn r;\n\treturn 0;\n}\n\nint\nsshbuf_put(struct sshbuf *buf, const void *v, size_t len)\n{\n\tu_char *p;\n\tint r;\n\n\tif ((r = sshbuf_reserve(buf, len, &p)) < 0)\n\t\treturn r;\n\tif (len != 0)\n\t\tmemcpy(p, v, len);\n\treturn 0;\n}\n\nint\nsshbuf_putb(struct sshbuf *buf, const struct sshbuf *v)\n{\n\treturn sshbuf_put(buf, sshbuf_ptr(v), sshbuf_len(v));\n}\n\nint\nsshbuf_putf(struct sshbuf *buf, const char *fmt, ...)\n{\n\tva_list ap;\n\tint r;\n\n\tva_start(ap, fmt);\n\tr = sshbuf_putfv(buf, fmt, ap);\n\tva_end(ap);\n\treturn r;\n}\n\nint\nsshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap)\n{\n\tva_list ap2;\n\tint r, len;\n\tu_char *p;\n\n\tVA_COPY(ap2, ap);\n\tif ((len = vsnprintf(NULL, 0, fmt, ap2)) < 0) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\tif (len == 0) {\n\t\tr = 0;\n\t\tgoto out; /* Nothing to do */\n\t}\n\tva_end(ap2);\n\tVA_COPY(ap2, ap);\n\tif ((r = sshbuf_reserve(buf, (size_t)len + 1, &p)) < 0)\n\t\tgoto out;\n\tif ((r = vsnprintf((char *)p, len + 1, fmt, ap2)) != len) {\n\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\tgoto out; /* Shouldn't happen */\n\t}\n\t/* Consume terminating \\0 */\n\tif ((r = sshbuf_consume_end(buf, 1)) != 0)\n\t\tgoto out;\n\tr = 0;\n out:\n\tva_end(ap2);\n\treturn r;\n}\n\nint\nsshbuf_put_u64(struct sshbuf *buf, u_int64_t val)\n{\n\tu_char *p;\n\tint r;\n\n\tif ((r = sshbuf_reserve(buf, 8, &p)) < 0)\n\t\treturn r;\n\tPOKE_U64(p, val);\n\treturn 0;\n}\n\nint\nsshbuf_put_u32(struct sshbuf *buf, u_int32_t val)\n{\n\tu_char *p;\n\tint r;\n\n\tif ((r = sshbuf_reserve(buf, 4, &p)) < 0)\n\t\treturn r;\n\tPOKE_U32(p, val);\n\treturn 0;\n}\n\nint\nsshbuf_put_u16(struct sshbuf *buf, u_int16_t val)\n{\n\tu_char *p;\n\tint r;\n\n\tif ((r = sshbuf_reserve(buf, 2, &p)) < 0)\n\t\treturn r;\n\tPOKE_U16(p, val);\n\treturn 0;\n}\n\nint\nsshbuf_put_u8(struct sshbuf *buf, u_char val)\n{\n\tu_char *p;\n\tint r;\n\n\tif ((r = sshbuf_reserve(buf, 1, &p)) < 0)\n\t\treturn r;\n\tp[0] = val;\n\treturn 0;\n}\n\nint\nsshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)\n{\n\tu_char *d;\n\tint r;\n\n\tif (len > SSHBUF_SIZE_MAX - 4) {\n\t\tSSHBUF_DBG((\"SSH_ERR_NO_BUFFER_SPACE\"));\n\t\treturn SSH_ERR_NO_BUFFER_SPACE;\n\t}\n\tif ((r = sshbuf_reserve(buf, len + 4, &d)) < 0)\n\t\treturn r;\n\tPOKE_U32(d, len);\n\tif (len != 0)\n\t\tmemcpy(d + 4, v, len);\n\treturn 0;\n}\n\nint\nsshbuf_put_cstring(struct sshbuf *buf, const char *v)\n{\n\treturn sshbuf_put_string(buf, (u_char *)v, v == NULL ? 0 : strlen(v));\n}\n\nint\nsshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v)\n{\n\treturn sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v));\n}\n\nint\nsshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp)\n{\n\tconst u_char *p;\n\tsize_t len;\n\tstruct sshbuf *ret;\n\tint r;\n\n\tif (buf == NULL || bufp == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t*bufp = NULL;\n\tif ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0)\n\t\treturn r;\n\tif ((ret = sshbuf_from(p, len)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_consume(buf, len + 4)) != 0 || /* Shouldn't happen */\n\t (r = sshbuf_set_parent(ret, buf)) != 0) {\n\t\tsshbuf_free(ret);\n\t\treturn r;\n\t}\n\t*bufp = ret;\n\treturn 0;\n}\n\nint\nsshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len)\n{\n\tu_char *d;\n\tconst u_char *s = (const u_char *)v;\n\tint r, prepend;\n\n\tif (len > SSHBUF_SIZE_MAX - 5) {\n\t\tSSHBUF_DBG((\"SSH_ERR_NO_BUFFER_SPACE\"));\n\t\treturn SSH_ERR_NO_BUFFER_SPACE;\n\t}\n\t/* Skip leading zero bytes */\n\tfor (; len > 0 && *s == 0; len--, s++)\n\t\t;\n\t/*\n\t * If most significant bit is set then prepend a zero byte to\n\t * avoid interpretation as a negative number.\n\t */\n\tprepend = len > 0 && (s[0] & 0x80) != 0;\n\tif ((r = sshbuf_reserve(buf, len + 4 + prepend, &d)) < 0)\n\t\treturn r;\n\tPOKE_U32(d, len + prepend);\n\tif (prepend)\n\t\td[4] = 0;\n\tif (len != 0)\n\t\tmemcpy(d + 4 + prepend, s, len);\n\treturn 0;\n}\n\nint\nsshbuf_get_bignum2_bytes_direct(struct sshbuf *buf,\n const u_char **valp, size_t *lenp)\n{\n\tconst u_char *d;\n\tsize_t len, olen;\n\tint r;\n\n\tif ((r = sshbuf_peek_string_direct(buf, &d, &olen)) < 0)\n\t\treturn r;\n\tlen = olen;\n\t/* Refuse negative (MSB set) bignums */\n\tif ((len != 0 && (*d & 0x80) != 0))\n\t\treturn SSH_ERR_BIGNUM_IS_NEGATIVE;\n\t/* Refuse overlong bignums, allow prepended \\0 to avoid MSB set */\n\tif (len > SSHBUF_MAX_BIGNUM + 1 ||\n\t (len == SSHBUF_MAX_BIGNUM + 1 && *d != 0))\n\t\treturn SSH_ERR_BIGNUM_TOO_LARGE;\n\t/* Trim leading zeros */\n\twhile (len > 0 && *d == 0x00) {\n\t\td++;\n\t\tlen--;\n\t}\n\tif (valp != NULL)\n\t\t*valp = d;\n\tif (lenp != NULL)\n\t\t*lenp = len;\n\tif (sshbuf_consume(buf, olen + 4) != 0) {\n\t\t/* Shouldn't happen */\n\t\tSSHBUF_DBG((\"SSH_ERR_INTERNAL_ERROR\"));\n\t\tSSHBUF_ABORT();\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\treturn 0;\n}\n","/*\t$OpenBSD: sshbuf-misc.c,v 1.6 2016/05/02 08:49:03 djm Exp $\t*/\n/*\n * Copyright (c) 2011 Damien Miller\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#include \n#ifdef HAVE_STDINT_H\n#include \n#endif\n#include \n#include \n#include \n#include \n#include \n\n#include \"ssherr.h\"\n#define SSHBUF_INTERNAL\n#include \"sshbuf.h\"\n\nvoid\nsshbuf_dump_data(const void *s, size_t len, FILE *f)\n{\n\tsize_t i, j;\n\tconst u_char *p = (const u_char *)s;\n\n\tfor (i = 0; i < len; i += 16) {\n\t\tfprintf(f, \"%.4zu: \", i);\n\t\tfor (j = i; j < i + 16; j++) {\n\t\t\tif (j < len)\n\t\t\t\tfprintf(f, \"%02x \", p[j]);\n\t\t\telse\n\t\t\t\tfprintf(f, \" \");\n\t\t}\n\t\tfprintf(f, \" \");\n\t\tfor (j = i; j < i + 16; j++) {\n\t\t\tif (j < len) {\n\t\t\t\tif (isascii(p[j]) && isprint(p[j]))\n\t\t\t\t\tfprintf(f, \"%c\", p[j]);\n\t\t\t\telse\n\t\t\t\t\tfprintf(f, \".\");\n\t\t\t}\n\t\t}\n\t\tfprintf(f, \"\\n\");\n\t}\n}\n\nvoid\nsshbuf_dump(struct sshbuf *buf, FILE *f)\n{\n\tfprintf(f, \"buffer %p len = %zu\\n\", buf, sshbuf_len(buf));\n\tsshbuf_dump_data(sshbuf_ptr(buf), sshbuf_len(buf), f);\n}\n\nchar *\nsshbuf_dtob16(struct sshbuf *buf)\n{\n\tsize_t i, j, len = sshbuf_len(buf);\n\tconst u_char *p = sshbuf_ptr(buf);\n\tchar *ret;\n\tconst char hex[] = \"0123456789abcdef\";\n\n\tif (len == 0)\n\t\treturn strdup(\"\");\n\tif (SIZE_MAX / 2 <= len || (ret = malloc(len * 2 + 1)) == NULL)\n\t\treturn NULL;\n\tfor (i = j = 0; i < len; i++) {\n\t\tret[j++] = hex[(p[i] >> 4) & 0xf];\n\t\tret[j++] = hex[p[i] & 0xf];\n\t}\n\tret[j] = '\\0';\n\treturn ret;\n}\n\nchar *\nsshbuf_dtob64(struct sshbuf *buf)\n{\n\tsize_t len = sshbuf_len(buf), plen;\n\tconst u_char *p = sshbuf_ptr(buf);\n\tchar *ret;\n\tint r;\n\n\tif (len == 0)\n\t\treturn strdup(\"\");\n\tplen = ((len + 2) / 3) * 4 + 1;\n\tif (SIZE_MAX / 2 <= len || (ret = malloc(plen)) == NULL)\n\t\treturn NULL;\n\tif ((r = b64_ntop(p, len, ret, plen)) == -1) {\n\t\texplicit_bzero(ret, plen);\n\t\tfree(ret);\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nint\nsshbuf_b64tod(struct sshbuf *buf, const char *b64)\n{\n\tsize_t plen = strlen(b64);\n\tint nlen, r;\n\tu_char *p;\n\n\tif (plen == 0)\n\t\treturn 0;\n\tif ((p = malloc(plen)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((nlen = b64_pton(b64, p, plen)) < 0) {\n\t\texplicit_bzero(p, plen);\n\t\tfree(p);\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\t}\n\tif ((r = sshbuf_put(buf, p, nlen)) < 0) {\n\t\texplicit_bzero(p, plen);\n\t\tfree(p);\n\t\treturn r;\n\t}\n\texplicit_bzero(p, plen);\n\tfree(p);\n\treturn 0;\n}\n\nchar *\nsshbuf_dup_string(struct sshbuf *buf)\n{\n\tconst u_char *p = NULL, *s = sshbuf_ptr(buf);\n\tsize_t l = sshbuf_len(buf);\n\tchar *r;\n\n\tif (s == NULL || l > SIZE_MAX)\n\t\treturn NULL;\n\t/* accept a nul only as the last character in the buffer */\n\tif (l > 0 && (p = memchr(s, '\\0', l)) != NULL) {\n\t\tif (p != s + l - 1)\n\t\t\treturn NULL;\n\t\tl--; /* the nul is put back below */\n\t}\n\tif ((r = malloc(l + 1)) == NULL)\n\t\treturn NULL;\n\tif (l > 0)\n\t\tmemcpy(r, s, l);\n\tr[l] = '\\0';\n\treturn r;\n}\n\n","/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Functions for connecting the local authentication agent.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n *\n * SSH2 implementation,\n * Copyright (c) 2000 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"ssh.h\"\n#include \"rsa.h\"\n#include \"sshbuf.h\"\n#include \"sshkey.h\"\n#include \"authfd.h\"\n#include \"cipher.h\"\n#include \"compat.h\"\n#include \"log.h\"\n#include \"atomicio.h\"\n#include \"misc.h\"\n#include \"ssherr.h\"\n\n#define MAX_AGENT_IDENTITIES\t2048\t\t/* Max keys in agent reply */\n#define MAX_AGENT_REPLY_LEN\t(256 * 1024) \t/* Max bytes in agent reply */\n\n/* macro to check for \"agent failure\" message */\n#define agent_failed(x) \\\n ((x == SSH_AGENT_FAILURE) || \\\n (x == SSH_COM_AGENT2_FAILURE) || \\\n (x == SSH2_AGENT_FAILURE))\n\n/* Convert success/failure response from agent to a err.h status */\nstatic int\ndecode_reply(u_char type)\n{\n\tif (agent_failed(type))\n\t\treturn SSH_ERR_AGENT_FAILURE;\n\telse if (type == SSH_AGENT_SUCCESS)\n\t\treturn 0;\n\telse\n\t\treturn SSH_ERR_INVALID_FORMAT;\n}\n\n/* Returns the number of the authentication fd, or -1 if there is none. */\nint\nssh_get_authentication_socket(int *fdp)\n{\n\tconst char *authsocket;\n\tint sock, oerrno;\n\tstruct sockaddr_un sunaddr;\n\n\tif (fdp != NULL)\n\t\t*fdp = -1;\n\n\tauthsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);\n\tif (!authsocket)\n\t\treturn SSH_ERR_AGENT_NOT_PRESENT;\n\n\tmemset(&sunaddr, 0, sizeof(sunaddr));\n\tsunaddr.sun_family = AF_UNIX;\n\tstrlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));\n\n\tif ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\n\t/* close on exec */\n\tif (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1 ||\n\t connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {\n\t\toerrno = errno;\n\t\tclose(sock);\n\t\terrno = oerrno;\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\t}\n\tif (fdp != NULL)\n\t\t*fdp = sock;\n\telse\n\t\tclose(sock);\n\treturn 0;\n}\n\n/* Communicate with agent: send request and read reply */\nstatic int\nssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply)\n{\n\tint r;\n\tsize_t l, len;\n\tchar buf[1024];\n\n\t/* Get the length of the message, and format it in the buffer. */\n\tlen = sshbuf_len(request);\n\tput_u32(buf, len);\n\n\t/* Send the length and then the packet to the agent. */\n\tif (atomicio(vwrite, sock, buf, 4) != 4 ||\n\t atomicio(vwrite, sock, (u_char *)sshbuf_ptr(request),\n\t sshbuf_len(request)) != sshbuf_len(request))\n\t\treturn SSH_ERR_AGENT_COMMUNICATION;\n\t/*\n\t * Wait for response from the agent. First read the length of the\n\t * response packet.\n\t */\n\tif (atomicio(read, sock, buf, 4) != 4)\n\t return SSH_ERR_AGENT_COMMUNICATION;\n\n\t/* Extract the length, and check it for sanity. */\n\tlen = get_u32(buf);\n\tif (len > MAX_AGENT_REPLY_LEN)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\n\t/* Read the rest of the response in to the buffer. */\n\tsshbuf_reset(reply);\n\twhile (len > 0) {\n\t\tl = len;\n\t\tif (l > sizeof(buf))\n\t\t\tl = sizeof(buf);\n\t\tif (atomicio(read, sock, buf, l) != l)\n\t\t\treturn SSH_ERR_AGENT_COMMUNICATION;\n\t\tif ((r = sshbuf_put(reply, buf, l)) != 0)\n\t\t\treturn r;\n\t\tlen -= l;\n\t}\n\treturn 0;\n}\n\n/*\n * Closes the agent socket if it should be closed (depends on how it was\n * obtained). The argument must have been returned by\n * ssh_get_authentication_socket().\n */\nvoid\nssh_close_authentication_socket(int sock)\n{\n\tif (getenv(SSH_AUTHSOCKET_ENV_NAME))\n\t\tclose(sock);\n}\n\n/* Lock/unlock agent */\nint\nssh_lock_agent(int sock, int lock, const char *password)\n{\n\tint r;\n\tu_char type = lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK;\n\tstruct sshbuf *msg;\n\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_put_u8(msg, type)) != 0 ||\n\t (r = sshbuf_put_cstring(msg, password)) != 0)\n\t\tgoto out;\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tr = decode_reply(type);\n out:\n\tsshbuf_free(msg);\n\treturn r;\n}\n\n#ifdef WITH_SSH1\nstatic int\ndeserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp)\n{\n\tstruct sshkey *key;\n\tint r, keybits;\n\tu_int32_t bits;\n\tchar *comment = NULL;\n\n\tif ((key = sshkey_new(KEY_RSA1)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_get_u32(ids, &bits)) != 0 ||\n\t (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 ||\n\t (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 ||\n\t (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)\n\t\tgoto out;\n\tkeybits = BN_num_bits(key->rsa->n);\n\t/* XXX previously we just warned here. I think we should be strict */\n\tif (keybits < 0 || bits != (u_int)keybits) {\n\t\tr = SSH_ERR_KEY_BITS_MISMATCH;\n\t\tgoto out;\n\t}\n\tif (keyp != NULL) {\n\t\t*keyp = key;\n\t\tkey = NULL;\n\t}\n\tif (commentp != NULL) {\n\t\t*commentp = comment;\n\t\tcomment = NULL;\n\t}\n\tr = 0;\n out:\n\tsshkey_free(key);\n\tfree(comment);\n\treturn r;\n}\n#endif\n\nstatic int\ndeserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)\n{\n\tint r;\n\tchar *comment = NULL;\n\tconst u_char *blob;\n\tsize_t blen;\n\n\tif ((r = sshbuf_get_string_direct(ids, &blob, &blen)) != 0 ||\n\t (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)\n\t\tgoto out;\n\tif ((r = sshkey_from_blob(blob, blen, keyp)) != 0)\n\t\tgoto out;\n\tif (commentp != NULL) {\n\t\t*commentp = comment;\n\t\tcomment = NULL;\n\t}\n\tr = 0;\n out:\n\tfree(comment);\n\treturn r;\n}\n\n/*\n * Fetch list of identities held by the agent.\n */\nint\nssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)\n{\n\tu_char type, code1 = 0, code2 = 0;\n\tu_int32_t num, i;\n\tstruct sshbuf *msg;\n\tstruct ssh_identitylist *idl = NULL;\n\tint r;\n\n\t/* Determine request and expected response types */\n\tswitch (version) {\n\tcase 1:\n\t\tcode1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;\n\t\tcode2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;\n\t\tbreak;\n\tcase 2:\n\t\tcode1 = SSH2_AGENTC_REQUEST_IDENTITIES;\n\t\tcode2 = SSH2_AGENT_IDENTITIES_ANSWER;\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n\n\t/*\n\t * Send a message to the agent requesting for a list of the\n\t * identities it can represent.\n\t */\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_put_u8(msg, code1)) != 0)\n\t\tgoto out;\n\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\n\t/* Get message type, and verify that we got a proper answer. */\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tif (agent_failed(type)) {\n\t\tr = SSH_ERR_AGENT_FAILURE;\n\t\tgoto out;\n\t} else if (type != code2) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\n\t/* Get the number of entries in the response and check it for sanity. */\n\tif ((r = sshbuf_get_u32(msg, &num)) != 0)\n\t\tgoto out;\n\tif (num > MAX_AGENT_IDENTITIES) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tif (num == 0) {\n\t\tr = SSH_ERR_AGENT_NO_IDENTITIES;\n\t\tgoto out;\n\t}\n\n\t/* Deserialise the response into a list of keys/comments */\n\tif ((idl = calloc(1, sizeof(*idl))) == NULL ||\n\t (idl->keys = calloc(num, sizeof(*idl->keys))) == NULL ||\n\t (idl->comments = calloc(num, sizeof(*idl->comments))) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tfor (i = 0; i < num;) {\n\t\tswitch (version) {\n\t\tcase 1:\n#ifdef WITH_SSH1\n\t\t\tif ((r = deserialise_identity1(msg,\n\t\t\t &(idl->keys[i]), &(idl->comments[i]))) != 0)\n\t\t\t\tgoto out;\n#endif\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif ((r = deserialise_identity2(msg,\n\t\t\t &(idl->keys[i]), &(idl->comments[i]))) != 0) {\n\t\t\t\tif (r == SSH_ERR_KEY_TYPE_UNKNOWN) {\n\t\t\t\t\t/* Gracefully skip unknown key types */\n\t\t\t\t\tnum--;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else\n\t\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n\tidl->nkeys = num;\n\t*idlp = idl;\n\tidl = NULL;\n\tr = 0;\n out:\n\tsshbuf_free(msg);\n\tif (idl != NULL)\n\t\tssh_free_identitylist(idl);\n\treturn r;\n}\n\nvoid\nssh_free_identitylist(struct ssh_identitylist *idl)\n{\n\tsize_t i;\n\n\tif (idl == NULL)\n\t\treturn;\n\tfor (i = 0; i < idl->nkeys; i++) {\n\t\tif (idl->keys != NULL)\n\t\t\tsshkey_free(idl->keys[i]);\n\t\tif (idl->comments != NULL)\n\t\t\tfree(idl->comments[i]);\n\t}\n\tfree(idl);\n}\n\n/*\n * Sends a challenge (typically from a server via ssh(1)) to the agent,\n * and waits for a response from the agent.\n * Returns true (non-zero) if the agent gave the correct answer, zero\n * otherwise.\n */\n\n#ifdef WITH_SSH1\nint\nssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,\n u_char session_id[16], u_char response[16])\n{\n\tstruct sshbuf *msg;\n\tint r;\n\tu_char type;\n\n\tif (key->type != KEY_RSA1)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||\n\t (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||\n\t (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||\n\t (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||\n\t (r = sshbuf_put_bignum1(msg, challenge)) != 0 ||\n\t (r = sshbuf_put(msg, session_id, 16)) != 0 ||\n\t (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */\n\t\tgoto out;\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tif (agent_failed(type)) {\n\t\tr = SSH_ERR_AGENT_FAILURE;\n\t\tgoto out;\n\t} else if (type != SSH_AGENT_RSA_RESPONSE) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_get(msg, response, 16)) != 0)\n\t\tgoto out;\n\tr = 0;\n out:\n\tsshbuf_free(msg);\n\treturn r;\n}\n#endif\n\n/* encode signature algoritm in flag bits, so we can keep the msg format */\nstatic u_int\nagent_encode_alg(struct sshkey *key, const char *alg)\n{\n\tif (alg != NULL && key->type == KEY_RSA) {\n\t\tif (strcmp(alg, \"rsa-sha2-256\") == 0)\n\t\t\treturn SSH_AGENT_RSA_SHA2_256;\n\t\telse if (strcmp(alg, \"rsa-sha2-512\") == 0)\n\t\t\treturn SSH_AGENT_RSA_SHA2_512;\n\t}\n\treturn 0;\n}\n\n/* ask agent to sign data, returns err.h code on error, 0 on success */\nint\nssh_agent_sign(int sock, struct sshkey *key,\n u_char **sigp, size_t *lenp,\n const u_char *data, size_t datalen, const char *alg, u_int compat)\n{\n\tstruct sshbuf *msg;\n\tu_char *blob = NULL, type;\n\tsize_t blen = 0, len = 0;\n\tu_int flags = 0;\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\t*sigp = NULL;\n\t*lenp = 0;\n\n\tif (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif (compat & SSH_BUG_SIGBLOB)\n\t\tflags |= SSH_AGENT_OLD_SIGNATURE;\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshkey_to_blob(key, &blob, &blen)) != 0)\n\t\tgoto out;\n\tflags |= agent_encode_alg(key, alg);\n\tif ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||\n\t (r = sshbuf_put_string(msg, blob, blen)) != 0 ||\n\t (r = sshbuf_put_string(msg, data, datalen)) != 0 ||\n\t (r = sshbuf_put_u32(msg, flags)) != 0)\n\t\tgoto out;\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tif (agent_failed(type)) {\n\t\tr = SSH_ERR_AGENT_FAILURE;\n\t\tgoto out;\n\t} else if (type != SSH2_AGENT_SIGN_RESPONSE) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_get_string(msg, sigp, &len)) != 0)\n\t\tgoto out;\n\t*lenp = len;\n\tr = 0;\n out:\n\tif (blob != NULL) {\n\t\texplicit_bzero(blob, blen);\n\t\tfree(blob);\n\t}\n\tsshbuf_free(msg);\n\treturn r;\n}\n\n/* Encode key for a message to the agent. */\n\n#ifdef WITH_SSH1\nstatic int\nssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)\n{\n\tint r;\n\n\t/* To keep within the protocol: p < q for ssh. in SSL p > q */\n\tif ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 ||\n\t (r = sshbuf_put_bignum1(b, key->n)) != 0 ||\n\t (r = sshbuf_put_bignum1(b, key->e)) != 0 ||\n\t (r = sshbuf_put_bignum1(b, key->d)) != 0 ||\n\t (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 ||\n\t (r = sshbuf_put_bignum1(b, key->q)) != 0 ||\n\t (r = sshbuf_put_bignum1(b, key->p)) != 0 ||\n\t (r = sshbuf_put_cstring(b, comment)) != 0)\n\t\treturn r;\n\treturn 0;\n}\n#endif\n\nstatic int\nssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key,\n const char *comment)\n{\n\tint r;\n\n\tif ((r = sshkey_private_serialize(key, b)) != 0 ||\n\t (r = sshbuf_put_cstring(b, comment)) != 0)\n\t\treturn r;\n\treturn 0;\n}\n\nstatic int\nencode_constraints(struct sshbuf *m, u_int life, u_int confirm)\n{\n\tint r;\n\n\tif (life != 0) {\n\t\tif ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_LIFETIME)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, life)) != 0)\n\t\t\tgoto out;\n\t}\n\tif (confirm != 0) {\n\t\tif ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_CONFIRM)) != 0)\n\t\t\tgoto out;\n\t}\n\tr = 0;\n out:\n\treturn r;\n}\n\n/*\n * Adds an identity to the authentication server.\n * This call is intended only for use by ssh-add(1) and like applications.\n */\nint\nssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment,\n u_int life, u_int confirm)\n{\n\tstruct sshbuf *msg;\n\tint r, constrained = (life || confirm);\n\tu_char type;\n\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\tswitch (key->type) {\n#ifdef WITH_SSH1\n\tcase KEY_RSA1:\n\t\ttype = constrained ?\n\t\t SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :\n\t\t SSH_AGENTC_ADD_RSA_IDENTITY;\n\t\tif ((r = sshbuf_put_u8(msg, type)) != 0 ||\n\t\t (r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n#endif\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA:\n\tcase KEY_RSA_CERT:\n\tcase KEY_DSA:\n\tcase KEY_DSA_CERT:\n\tcase KEY_ECDSA:\n\tcase KEY_ECDSA_CERT:\n#endif\n\tcase KEY_ED25519:\n\tcase KEY_ED25519_CERT:\n\t\ttype = constrained ?\n\t\t SSH2_AGENTC_ADD_ID_CONSTRAINED :\n\t\t SSH2_AGENTC_ADD_IDENTITY;\n\t\tif ((r = sshbuf_put_u8(msg, type)) != 0 ||\n\t\t (r = ssh_encode_identity_ssh2(msg, key, comment)) != 0)\n\t\t\tgoto out;\n\t\tbreak;\n\tdefault:\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\tif (constrained &&\n\t (r = encode_constraints(msg, life, confirm)) != 0)\n\t\tgoto out;\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tr = decode_reply(type);\n out:\n\tsshbuf_free(msg);\n\treturn r;\n}\n\n/*\n * Removes an identity from the authentication server.\n * This call is intended only for use by ssh-add(1) and like applications.\n */\nint\nssh_remove_identity(int sock, struct sshkey *key)\n{\n\tstruct sshbuf *msg;\n\tint r;\n\tu_char type, *blob = NULL;\n\tsize_t blen;\n\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n#ifdef WITH_SSH1\n\tif (key->type == KEY_RSA1) {\n\t\tif ((r = sshbuf_put_u8(msg,\n\t\t SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||\n\t\t (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||\n\t\t (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||\n\t\t (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)\n\t\t\tgoto out;\n\t} else\n#endif\n\tif (key->type != KEY_UNSPEC) {\n\t\tif ((r = sshkey_to_blob(key, &blob, &blen)) != 0)\n\t\t\tgoto out;\n\t\tif ((r = sshbuf_put_u8(msg,\n\t\t SSH2_AGENTC_REMOVE_IDENTITY)) != 0 ||\n\t\t (r = sshbuf_put_string(msg, blob, blen)) != 0)\n\t\t\tgoto out;\n\t} else {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tr = decode_reply(type);\n out:\n\tif (blob != NULL) {\n\t\texplicit_bzero(blob, blen);\n\t\tfree(blob);\n\t}\n\tsshbuf_free(msg);\n\treturn r;\n}\n\n/*\n * Add/remove an token-based identity from the authentication server.\n * This call is intended only for use by ssh-add(1) and like applications.\n */\nint\nssh_update_card(int sock, int add, const char *reader_id, const char *pin,\n u_int life, u_int confirm)\n{\n\tstruct sshbuf *msg;\n\tint r, constrained = (life || confirm);\n\tu_char type;\n\n\tif (add) {\n\t\ttype = constrained ?\n\t\t SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED :\n\t\t SSH_AGENTC_ADD_SMARTCARD_KEY;\n\t} else\n\t\ttype = SSH_AGENTC_REMOVE_SMARTCARD_KEY;\n\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_put_u8(msg, type)) != 0 ||\n\t (r = sshbuf_put_cstring(msg, reader_id)) != 0 ||\n\t (r = sshbuf_put_cstring(msg, pin)) != 0)\n\t\tgoto out;\n\tif (constrained &&\n\t (r = encode_constraints(msg, life, confirm)) != 0)\n\t\tgoto out;\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tr = decode_reply(type);\n out:\n\tsshbuf_free(msg);\n\treturn r;\n}\n\n/*\n * Removes all identities from the agent.\n * This call is intended only for use by ssh-add(1) and like applications.\n */\nint\nssh_remove_all_identities(int sock, int version)\n{\n\tstruct sshbuf *msg;\n\tu_char type = (version == 1) ?\n\t SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES :\n\t SSH2_AGENTC_REMOVE_ALL_IDENTITIES;\n\tint r;\n\n\tif ((msg = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_put_u8(msg, type)) != 0)\n\t\tgoto out;\n\tif ((r = ssh_request_reply(sock, msg, msg)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_get_u8(msg, &type)) != 0)\n\t\tgoto out;\n\tr = decode_reply(type);\n out:\n\tsshbuf_free(msg);\n\treturn r;\n}\n","/* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */\n/*\n * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"cipher.h\"\n#include \"ssh.h\"\n#include \"log.h\"\n#include \"authfile.h\"\n#include \"rsa.h\"\n#include \"misc.h\"\n#include \"atomicio.h\"\n#include \"sshkey.h\"\n#include \"sshbuf.h\"\n#include \"ssherr.h\"\n#include \"krl.h\"\n\n#define MAX_KEY_FILE_SIZE\t(1024 * 1024)\n\n/* Save a key blob to a file */\nstatic int\nsshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)\n{\n\tint fd, oerrno;\n\n\tif ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\tif (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(keybuf),\n\t sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {\n\t\toerrno = errno;\n\t\tclose(fd);\n\t\tunlink(filename);\n\t\terrno = oerrno;\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\t}\n\tclose(fd);\n\treturn 0;\n}\n\nint\nsshkey_save_private(struct sshkey *key, const char *filename,\n const char *passphrase, const char *comment,\n int force_new_format, const char *new_format_cipher, int new_format_rounds)\n{\n\tstruct sshbuf *keyblob = NULL;\n\tint r;\n\n\tif ((keyblob = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,\n\t force_new_format, new_format_cipher, new_format_rounds)) != 0)\n\t\tgoto out;\n\tif ((r = sshkey_save_private_blob(keyblob, filename)) != 0)\n\t\tgoto out;\n\tr = 0;\n out:\n\tsshbuf_free(keyblob);\n\treturn r;\n}\n\n/* Load a key from a fd into a buffer */\nint\nsshkey_load_file(int fd, struct sshbuf *blob)\n{\n\tu_char buf[1024];\n\tsize_t len;\n\tstruct stat st;\n\tint r, dontmax = 0;\n\n\tif (fstat(fd, &st) < 0)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\tif ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&\n\t st.st_size > MAX_KEY_FILE_SIZE)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\t/*\n\t * Pre-allocate the buffer used for the key contents and clamp its\n\t * maximum size. This ensures that key contents are never leaked via\n\t * implicit realloc() in the sshbuf code.\n\t */\n\tif ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) {\n\t\tst.st_size = 64*1024; /* 64k should be enough for anyone :) */\n\t\tdontmax = 1;\n\t}\n\tif ((r = sshbuf_allocate(blob, st.st_size)) != 0 ||\n\t (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0))\n\t\treturn r;\n\tfor (;;) {\n\t\tif ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {\n\t\t\tif (errno == EPIPE)\n\t\t\t\tbreak;\n\t\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_put(blob, buf, len)) != 0)\n\t\t\tgoto out;\n\t\tif (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t}\n\tif ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&\n\t st.st_size != (off_t)sshbuf_len(blob)) {\n\t\tr = SSH_ERR_FILE_CHANGED;\n\t\tgoto out;\n\t}\n\tr = 0;\n\n out:\n\texplicit_bzero(buf, sizeof(buf));\n\tif (r != 0)\n\t\tsshbuf_reset(blob);\n\treturn r;\n}\n\n#ifdef WITH_SSH1\n/*\n * Loads the public part of the ssh v1 key file. Returns NULL if an error was\n * encountered (the file does not exist or is not readable), and the key\n * otherwise.\n */\nstatic int\nsshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)\n{\n\tstruct sshbuf *b = NULL;\n\tint r;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\tif ((b = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshkey_load_file(fd, b)) != 0)\n\t\tgoto out;\n\tif ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)\n\t\tgoto out;\n\tr = 0;\n out:\n\tsshbuf_free(b);\n\treturn r;\n}\n#endif /* WITH_SSH1 */\n\n/* XXX remove error() calls from here? */\nint\nsshkey_perm_ok(int fd, const char *filename)\n{\n\tstruct stat st;\n\n\tif (fstat(fd, &st) < 0)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\t/*\n\t * if a key owned by the user is accessed, then we check the\n\t * permissions of the file. if the key owned by a different user,\n\t * then we don't care.\n\t */\n#ifdef HAVE_CYGWIN\n\tif (check_ntsec(filename))\n#endif\n\tif ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {\n\t\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\t\terror(\"@ WARNING: UNPROTECTED PRIVATE KEY FILE! @\");\n\t\terror(\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\");\n\t\terror(\"Permissions 0%3.3o for '%s' are too open.\",\n\t\t (u_int)st.st_mode & 0777, filename);\n\t\terror(\"It is required that your private key files are NOT accessible by others.\");\n\t\terror(\"This private key will be ignored.\");\n\t\treturn SSH_ERR_KEY_BAD_PERMISSIONS;\n\t}\n\treturn 0;\n}\n\n/* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */\nint\nsshkey_load_private_type(int type, const char *filename, const char *passphrase,\n struct sshkey **keyp, char **commentp, int *perm_ok)\n{\n\tint fd, r;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\tif ((fd = open(filename, O_RDONLY)) < 0) {\n\t\tif (perm_ok != NULL)\n\t\t\t*perm_ok = 0;\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\t}\n\tif (sshkey_perm_ok(fd, filename) != 0) {\n\t\tif (perm_ok != NULL)\n\t\t\t*perm_ok = 0;\n\t\tr = SSH_ERR_KEY_BAD_PERMISSIONS;\n\t\tgoto out;\n\t}\n\tif (perm_ok != NULL)\n\t\t*perm_ok = 1;\n\n\tr = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp);\n out:\n\tclose(fd);\n\treturn r;\n}\n\nint\nsshkey_load_private_type_fd(int fd, int type, const char *passphrase,\n struct sshkey **keyp, char **commentp)\n{\n\tstruct sshbuf *buffer = NULL;\n\tint r;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif ((buffer = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshkey_load_file(fd, buffer)) != 0 ||\n\t (r = sshkey_parse_private_fileblob_type(buffer, type,\n\t passphrase, keyp, commentp)) != 0)\n\t\tgoto out;\n\n\t/* success */\n\tr = 0;\n out:\n\tsshbuf_free(buffer);\n\treturn r;\n}\n\n/* XXX this is almost identical to sshkey_load_private_type() */\nint\nsshkey_load_private(const char *filename, const char *passphrase,\n struct sshkey **keyp, char **commentp)\n{\n\tstruct sshbuf *buffer = NULL;\n\tint r, fd;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\tif ((fd = open(filename, O_RDONLY)) < 0)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\tif (sshkey_perm_ok(fd, filename) != 0) {\n\t\tr = SSH_ERR_KEY_BAD_PERMISSIONS;\n\t\tgoto out;\n\t}\n\n\tif ((buffer = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshkey_load_file(fd, buffer)) != 0 ||\n\t (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp,\n\t commentp)) != 0)\n\t\tgoto out;\n\tr = 0;\n out:\n\tclose(fd);\n\tsshbuf_free(buffer);\n\treturn r;\n}\n\nstatic int\nsshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)\n{\n\tFILE *f;\n\tchar line[SSH_MAX_PUBKEY_BYTES];\n\tchar *cp;\n\tu_long linenum = 0;\n\tint r;\n\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\tif ((f = fopen(filename, \"r\")) == NULL)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\twhile (read_keyfile_line(f, filename, line, sizeof(line),\n\t\t &linenum) != -1) {\n\t\tcp = line;\n\t\tswitch (*cp) {\n\t\tcase '#':\n\t\tcase '\\n':\n\t\tcase '\\0':\n\t\t\tcontinue;\n\t\t}\n\t\t/* Abort loading if this looks like a private key */\n\t\tif (strncmp(cp, \"-----BEGIN\", 10) == 0 ||\n\t\t strcmp(cp, \"SSH PRIVATE KEY FILE\") == 0)\n\t\t\tbreak;\n\t\t/* Skip leading whitespace. */\n\t\tfor (; *cp && (*cp == ' ' || *cp == '\\t'); cp++)\n\t\t\t;\n\t\tif (*cp) {\n\t\t\tif ((r = sshkey_read(k, &cp)) == 0) {\n\t\t\t\tcp[strcspn(cp, \"\\r\\n\")] = '\\0';\n\t\t\t\tif (commentp) {\n\t\t\t\t\t*commentp = strdup(*cp ?\n\t\t\t\t\t cp : filename);\n\t\t\t\t\tif (*commentp == NULL)\n\t\t\t\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\t\t}\n\t\t\t\tfclose(f);\n\t\t\t\treturn r;\n\t\t\t}\n\t\t}\n\t}\n\tfclose(f);\n\treturn SSH_ERR_INVALID_FORMAT;\n}\n\n/* load public key from ssh v1 private or any pubkey file */\nint\nsshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)\n{\n\tstruct sshkey *pub = NULL;\n\tchar file[PATH_MAX];\n\tint r, fd;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\tif (commentp != NULL)\n\t\t*commentp = NULL;\n\n\t/* XXX should load file once and attempt to parse each format */\n\n\tif ((fd = open(filename, O_RDONLY)) < 0)\n\t\tgoto skip;\n#ifdef WITH_SSH1\n\t/* try rsa1 private key */\n\tr = sshkey_load_public_rsa1(fd, keyp, commentp);\n\tclose(fd);\n\tswitch (r) {\n\tcase SSH_ERR_INTERNAL_ERROR:\n\tcase SSH_ERR_ALLOC_FAIL:\n\tcase SSH_ERR_INVALID_ARGUMENT:\n\tcase SSH_ERR_SYSTEM_ERROR:\n\tcase 0:\n\t\treturn r;\n\t}\n#else /* WITH_SSH1 */\n\tclose(fd);\n#endif /* WITH_SSH1 */\n\n\t/* try ssh2 public key */\n\tif ((pub = sshkey_new(KEY_UNSPEC)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {\n\t\tif (keyp != NULL)\n\t\t\t*keyp = pub;\n\t\treturn 0;\n\t}\n\tsshkey_free(pub);\n\n#ifdef WITH_SSH1\n\t/* try rsa1 public key */\n\tif ((pub = sshkey_new(KEY_RSA1)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {\n\t\tif (keyp != NULL)\n\t\t\t*keyp = pub;\n\t\treturn 0;\n\t}\n\tsshkey_free(pub);\n#endif /* WITH_SSH1 */\n\n skip:\n\t/* try .pub suffix */\n\tif ((pub = sshkey_new(KEY_UNSPEC)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tr = SSH_ERR_ALLOC_FAIL;\t/* in case strlcpy or strlcat fail */\n\tif ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&\n\t (strlcat(file, \".pub\", sizeof file) < sizeof(file)) &&\n\t (r = sshkey_try_load_public(pub, file, commentp)) == 0) {\n\t\tif (keyp != NULL)\n\t\t\t*keyp = pub;\n\t\treturn 0;\n\t}\n\tsshkey_free(pub);\n\n\treturn r;\n}\n\n/* Load the certificate associated with the named private key */\nint\nsshkey_load_cert(const char *filename, struct sshkey **keyp)\n{\n\tstruct sshkey *pub = NULL;\n\tchar *file = NULL;\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\n\tif (asprintf(&file, \"%s-cert.pub\", filename) == -1)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\tif ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {\n\t\tgoto out;\n\t}\n\tif ((r = sshkey_try_load_public(pub, file, NULL)) != 0)\n\t\tgoto out;\n\t/* success */\n\tif (keyp != NULL) {\n\t\t*keyp = pub;\n\t\tpub = NULL;\n\t}\n\tr = 0;\n out:\n\tfree(file);\n\tsshkey_free(pub);\n\treturn r;\n}\n\n/* Load private key and certificate */\nint\nsshkey_load_private_cert(int type, const char *filename, const char *passphrase,\n struct sshkey **keyp, int *perm_ok)\n{\n\tstruct sshkey *key = NULL, *cert = NULL;\n\tint r;\n\n\tif (keyp != NULL)\n\t\t*keyp = NULL;\n\n\tswitch (type) {\n#ifdef WITH_OPENSSL\n\tcase KEY_RSA:\n\tcase KEY_DSA:\n\tcase KEY_ECDSA:\n#endif /* WITH_OPENSSL */\n\tcase KEY_ED25519:\n\tcase KEY_UNSPEC:\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_KEY_TYPE_UNKNOWN;\n\t}\n\n\tif ((r = sshkey_load_private_type(type, filename,\n\t passphrase, &key, NULL, perm_ok)) != 0 ||\n\t (r = sshkey_load_cert(filename, &cert)) != 0)\n\t\tgoto out;\n\n\t/* Make sure the private key matches the certificate */\n\tif (sshkey_equal_public(key, cert) == 0) {\n\t\tr = SSH_ERR_KEY_CERT_MISMATCH;\n\t\tgoto out;\n\t}\n\n\tif ((r = sshkey_to_certified(key)) != 0 ||\n\t (r = sshkey_cert_copy(cert, key)) != 0)\n\t\tgoto out;\n\tr = 0;\n\tif (keyp != NULL) {\n\t\t*keyp = key;\n\t\tkey = NULL;\n\t}\n out:\n\tsshkey_free(key);\n\tsshkey_free(cert);\n\treturn r;\n}\n\n/*\n * Returns success if the specified \"key\" is listed in the file \"filename\",\n * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error.\n * If \"strict_type\" is set then the key type must match exactly,\n * otherwise a comparison that ignores certficiate data is performed.\n * If \"check_ca\" is set and \"key\" is a certificate, then its CA key is\n * also checked and sshkey_in_file() will return success if either is found.\n */\nint\nsshkey_in_file(struct sshkey *key, const char *filename, int strict_type,\n int check_ca)\n{\n\tFILE *f;\n\tchar line[SSH_MAX_PUBKEY_BYTES];\n\tchar *cp;\n\tu_long linenum = 0;\n\tint r = 0;\n\tstruct sshkey *pub = NULL;\n\tint (*sshkey_compare)(const struct sshkey *, const struct sshkey *) =\n\t strict_type ? sshkey_equal : sshkey_equal_public;\n\n\tif ((f = fopen(filename, \"r\")) == NULL)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\n\twhile (read_keyfile_line(f, filename, line, sizeof(line),\n\t &linenum) != -1) {\n\t\tcp = line;\n\n\t\t/* Skip leading whitespace. */\n\t\tfor (; *cp && (*cp == ' ' || *cp == '\\t'); cp++)\n\t\t\t;\n\n\t\t/* Skip comments and empty lines */\n\t\tswitch (*cp) {\n\t\tcase '#':\n\t\tcase '\\n':\n\t\tcase '\\0':\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshkey_read(pub, &cp)) != 0)\n\t\t\tgoto out;\n\t\tif (sshkey_compare(key, pub) ||\n\t\t (check_ca && sshkey_is_cert(key) &&\n\t\t sshkey_compare(key->cert->signature_key, pub))) {\n\t\t\tr = 0;\n\t\t\tgoto out;\n\t\t}\n\t\tsshkey_free(pub);\n\t\tpub = NULL;\n\t}\n\tr = SSH_ERR_KEY_NOT_FOUND;\n out:\n\tsshkey_free(pub);\n\tfclose(f);\n\treturn r;\n}\n\n/*\n * Checks whether the specified key is revoked, returning 0 if not,\n * SSH_ERR_KEY_REVOKED if it is or another error code if something\n * unexpected happened.\n * This will check both the key and, if it is a certificate, its CA key too.\n * \"revoked_keys_file\" may be a KRL or a one-per-line list of public keys.\n */\nint\nsshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file)\n{\n\tint r;\n\n\tr = ssh_krl_file_contains_key(revoked_keys_file, key);\n\t/* If this was not a KRL to begin with then continue below */\n\tif (r != SSH_ERR_KRL_BAD_MAGIC)\n\t\treturn r;\n\n\t/*\n\t * If the file is not a KRL or we can't handle KRLs then attempt to\n\t * parse the file as a flat list of keys.\n\t */\n\tswitch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) {\n\tcase 0:\n\t\t/* Key found => revoked */\n\t\treturn SSH_ERR_KEY_REVOKED;\n\tcase SSH_ERR_KEY_NOT_FOUND:\n\t\t/* Key not found => not revoked */\n\t\treturn 0;\n\tdefault:\n\t\t/* Some other error occurred */\n\t\treturn r;\n\t}\n}\n\n","/* $OpenBSD: bufaux.c,v 1.60 2014/04/30 05:29:56 djm Exp $ */\n/*\n * Copyright (c) 2012 Damien Miller \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */\n\n#include \"includes.h\"\n\n#include \n\n#include \"buffer.h\"\n#include \"log.h\"\n#include \"ssherr.h\"\n\nint\nbuffer_get_short_ret(u_short *v, Buffer *buffer)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_get_u16(buffer, v)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nu_short\nbuffer_get_short(Buffer *buffer)\n{\n\tu_short ret;\n\n\tif (buffer_get_short_ret(&ret, buffer) == -1)\n\t\tfatal(\"%s: buffer error\", __func__);\n\n\treturn (ret);\n}\n\nint\nbuffer_get_int_ret(u_int *v, Buffer *buffer)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_get_u32(buffer, v)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nu_int\nbuffer_get_int(Buffer *buffer)\n{\n\tu_int ret;\n\n\tif (buffer_get_int_ret(&ret, buffer) == -1)\n\t\tfatal(\"%s: buffer error\", __func__);\n\n\treturn (ret);\n}\n\nint\nbuffer_get_int64_ret(u_int64_t *v, Buffer *buffer)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_get_u64(buffer, v)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nu_int64_t\nbuffer_get_int64(Buffer *buffer)\n{\n\tu_int64_t ret;\n\n\tif (buffer_get_int64_ret(&ret, buffer) == -1)\n\t\tfatal(\"%s: buffer error\", __func__);\n\n\treturn (ret);\n}\n\nvoid\nbuffer_put_short(Buffer *buffer, u_short value)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put_u16(buffer, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid\nbuffer_put_int(Buffer *buffer, u_int value)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put_u32(buffer, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid\nbuffer_put_int64(Buffer *buffer, u_int64_t value)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put_u64(buffer, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid *\nbuffer_get_string_ret(Buffer *buffer, u_int *length_ptr)\n{\n\tsize_t len;\n\tint ret;\n\tu_char *value;\n\n\tif ((ret = sshbuf_get_string(buffer, &value, &len)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn NULL;\n\t}\n\tif (length_ptr != NULL)\n\t\t*length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */\n\treturn value;\n}\n\nvoid *\nbuffer_get_string(Buffer *buffer, u_int *length_ptr)\n{\n\tvoid *ret;\n\n\tif ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL)\n\t\tfatal(\"%s: buffer error\", __func__);\n\treturn (ret);\n}\n\nchar *\nbuffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)\n{\n\tsize_t len;\n\tint ret;\n\tchar *value;\n\n\tif ((ret = sshbuf_get_cstring(buffer, &value, &len)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn NULL;\n\t}\n\tif (length_ptr != NULL)\n\t\t*length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */\n\treturn value;\n}\n\nchar *\nbuffer_get_cstring(Buffer *buffer, u_int *length_ptr)\n{\n\tchar *ret;\n\n\tif ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL)\n\t\tfatal(\"%s: buffer error\", __func__);\n\treturn ret;\n}\n\nconst void *\nbuffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)\n{\n\tsize_t len;\n\tint ret;\n\tconst u_char *value;\n\n\tif ((ret = sshbuf_get_string_direct(buffer, &value, &len)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn NULL;\n\t}\n\tif (length_ptr != NULL)\n\t\t*length_ptr = len; /* Safe: sshbuf never stores len > 2^31 */\n\treturn value;\n}\n\nconst void *\nbuffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)\n{\n\tconst void *ret;\n\n\tif ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL)\n\t\tfatal(\"%s: buffer error\", __func__);\n\treturn (ret);\n}\n\nvoid\nbuffer_put_string(Buffer *buffer, const void *buf, u_int len)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put_string(buffer, buf, len)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid\nbuffer_put_cstring(Buffer *buffer, const char *s)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put_cstring(buffer, s)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nint\nbuffer_get_char_ret(char *v, Buffer *buffer)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_get_u8(buffer, (u_char *)v)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nint\nbuffer_get_char(Buffer *buffer)\n{\n\tchar ch;\n\n\tif (buffer_get_char_ret(&ch, buffer) == -1)\n\t\tfatal(\"%s: buffer error\", __func__);\n\treturn (u_char) ch;\n}\n\nvoid\nbuffer_put_char(Buffer *buffer, int value)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put_u8(buffer, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid\nbuffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put_bignum2_bytes(buffer, s, l)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\n","/* $OpenBSD: buffer.c,v 1.36 2014/04/30 05:29:56 djm Exp $ */\n\n/*\n * Copyright (c) 2012 Damien Miller \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/* Emulation wrappers for legacy OpenSSH buffer API atop sshbuf */\n\n#include \"includes.h\"\n\n#include \n\n#include \"buffer.h\"\n#include \"log.h\"\n#include \"ssherr.h\"\n\nvoid\nbuffer_append(Buffer *buffer, const void *data, u_int len)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_put(buffer, data, len)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid *\nbuffer_append_space(Buffer *buffer, u_int len)\n{\n\tint ret;\n\tu_char *p;\n\n\tif ((ret = sshbuf_reserve(buffer, len, &p)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n\treturn p;\n}\n\nint\nbuffer_check_alloc(Buffer *buffer, u_int len)\n{\n\tint ret = sshbuf_check_reserve(buffer, len);\n\n\tif (ret == 0)\n\t\treturn 1;\n\tif (ret == SSH_ERR_NO_BUFFER_SPACE)\n\t\treturn 0;\n\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nint\nbuffer_get_ret(Buffer *buffer, void *buf, u_int len)\n{\n\tint ret;\n\n\tif ((ret = sshbuf_get(buffer, buf, len)) != 0) {\n\t\terror(\"%s: %s\", __func__, ssh_err(ret));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nvoid\nbuffer_get(Buffer *buffer, void *buf, u_int len)\n{\n\tif (buffer_get_ret(buffer, buf, len) == -1)\n\t\tfatal(\"%s: buffer error\", __func__);\n}\n\nint\nbuffer_consume_ret(Buffer *buffer, u_int bytes)\n{\n\tint ret = sshbuf_consume(buffer, bytes);\n\n\tif (ret == 0)\n\t\treturn 0;\n\tif (ret == SSH_ERR_MESSAGE_INCOMPLETE)\n\t\treturn -1;\n\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid\nbuffer_consume(Buffer *buffer, u_int bytes)\n{\n\tif (buffer_consume_ret(buffer, bytes) == -1)\n\t\tfatal(\"%s: buffer error\", __func__);\n}\n\nint\nbuffer_consume_end_ret(Buffer *buffer, u_int bytes)\n{\n\tint ret = sshbuf_consume_end(buffer, bytes);\n\n\tif (ret == 0)\n\t\treturn 0;\n\tif (ret == SSH_ERR_MESSAGE_INCOMPLETE)\n\t\treturn -1;\n\tfatal(\"%s: %s\", __func__, ssh_err(ret));\n}\n\nvoid\nbuffer_consume_end(Buffer *buffer, u_int bytes)\n{\n\tif (buffer_consume_end_ret(buffer, bytes) == -1)\n\t\tfatal(\"%s: buffer error\", __func__);\n}\n\n\n","/* $OpenBSD: canohost.c,v 1.73 2016/03/07 19:02:43 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Functions for returning the canonical host name of the remote site.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n\n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"packet.h\"\n#include \"log.h\"\n#include \"canohost.h\"\n#include \"misc.h\"\n\nvoid\nipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)\n{\n\tstruct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;\n\tstruct sockaddr_in *a4 = (struct sockaddr_in *)addr;\n\tstruct in_addr inaddr;\n\tu_int16_t port;\n\n\tif (addr->ss_family != AF_INET6 ||\n\t !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))\n\t\treturn;\n\n\tdebug3(\"Normalising mapped IPv4 in IPv6 address\");\n\n\tmemcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));\n\tport = a6->sin6_port;\n\n\tmemset(a4, 0, sizeof(*a4));\n\n\ta4->sin_family = AF_INET;\n\t*len = sizeof(*a4);\n\tmemcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));\n\ta4->sin_port = port;\n}\n\n/*\n * Returns the local/remote IP-address/hostname of socket as a string.\n * The returned string must be freed.\n */\nstatic char *\nget_socket_address(int sock, int remote, int flags)\n{\n\tstruct sockaddr_storage addr;\n\tsocklen_t addrlen;\n\tchar ntop[NI_MAXHOST];\n\tint r;\n\n\t/* Get IP address of client. */\n\taddrlen = sizeof(addr);\n\tmemset(&addr, 0, sizeof(addr));\n\n\tif (remote) {\n\t\tif (getpeername(sock, (struct sockaddr *)&addr, &addrlen) != 0)\n\t\t\treturn NULL;\n\t} else {\n\t\tif (getsockname(sock, (struct sockaddr *)&addr, &addrlen) != 0)\n\t\t\treturn NULL;\n\t}\n\n\t/* Work around Linux IPv6 weirdness */\n\tif (addr.ss_family == AF_INET6) {\n\t\taddrlen = sizeof(struct sockaddr_in6);\n\t\tipv64_normalise_mapped(&addr, &addrlen);\n\t}\n\n\tswitch (addr.ss_family) {\n\tcase AF_INET:\n\tcase AF_INET6:\n\t\t/* Get the address in ascii. */\n\t\tif ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,\n\t\t sizeof(ntop), NULL, 0, flags)) != 0) {\n\t\t\terror(\"%s: getnameinfo %d failed: %s\", __func__,\n\t\t\t flags, ssh_gai_strerror(r));\n\t\t\treturn NULL;\n\t\t}\n\t\treturn xstrdup(ntop);\n\tcase AF_UNIX:\n\t\t/* Get the Unix domain socket path. */\n\t\treturn xstrdup(((struct sockaddr_un *)&addr)->sun_path);\n\tdefault:\n\t\t/* We can't look up remote Unix domain sockets. */\n\t\treturn NULL;\n\t}\n}\n\nchar *\nget_peer_ipaddr(int sock)\n{\n\tchar *p;\n\n\tif ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)\n\t\treturn p;\n\treturn xstrdup(\"UNKNOWN\");\n}\n\nchar *\nget_local_ipaddr(int sock)\n{\n\tchar *p;\n\n\tif ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)\n\t\treturn p;\n\treturn xstrdup(\"UNKNOWN\");\n}\n\nchar *\nget_local_name(int fd)\n{\n\tchar *host, myname[NI_MAXHOST];\n\n\t/* Assume we were passed a socket */\n\tif ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL)\n\t\treturn host;\n\n\t/* Handle the case where we were passed a pipe */\n\tif (gethostname(myname, sizeof(myname)) == -1) {\n\t\tverbose(\"%s: gethostname: %s\", __func__, strerror(errno));\n\t\thost = xstrdup(\"UNKNOWN\");\n\t} else {\n\t\thost = xstrdup(myname);\n\t}\n\n\treturn host;\n}\n\n/* Returns the local/remote port for the socket. */\n\nstatic int\nget_sock_port(int sock, int local)\n{\n\tstruct sockaddr_storage from;\n\tsocklen_t fromlen;\n\tchar strport[NI_MAXSERV];\n\tint r;\n\n\t/* Get IP address of client. */\n\tfromlen = sizeof(from);\n\tmemset(&from, 0, sizeof(from));\n\tif (local) {\n\t\tif (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) {\n\t\t\terror(\"getsockname failed: %.100s\", strerror(errno));\n\t\t\treturn 0;\n\t\t}\n\t} else {\n\t\tif (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {\n\t\t\tdebug(\"getpeername failed: %.100s\", strerror(errno));\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\t/* Work around Linux IPv6 weirdness */\n\tif (from.ss_family == AF_INET6)\n\t\tfromlen = sizeof(struct sockaddr_in6);\n\n\t/* Non-inet sockets don't have a port number. */\n\tif (from.ss_family != AF_INET && from.ss_family != AF_INET6)\n\t\treturn 0;\n\n\t/* Return port number. */\n\tif ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,\n\t strport, sizeof(strport), NI_NUMERICSERV)) != 0)\n\t\tfatal(\"%s: getnameinfo NI_NUMERICSERV failed: %s\", __func__,\n\t\t ssh_gai_strerror(r));\n\treturn atoi(strport);\n}\n\nint\nget_peer_port(int sock)\n{\n\treturn get_sock_port(sock, 0);\n}\n\nint\nget_local_port(int sock)\n{\n\treturn get_sock_port(sock, 1);\n}\n","/* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * This file contains functions for generic socket connection forwarding.\n * There is also code for initiating connection forwarding for X11 connections,\n * arbitrary tcp/ip connections, and the authentication agent connection.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n *\n * SSH2 support added by Markus Friedl.\n * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.\n * Copyright (c) 1999 Dug Song. All rights reserved.\n * Copyright (c) 1999 Theo de Raadt. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#include \n#ifdef HAVE_SYS_TIME_H\n# include \n#endif\n\n#include \n#include \n\n#include \n#include \n#include \n#ifdef HAVE_STDINT_H\n#include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"openbsd-compat/sys-queue.h\"\n#include \"xmalloc.h\"\n#include \"ssh.h\"\n#include \"ssh1.h\"\n#include \"ssh2.h\"\n#include \"ssherr.h\"\n#include \"packet.h\"\n#include \"log.h\"\n#include \"misc.h\"\n#include \"buffer.h\"\n#include \"channels.h\"\n#include \"compat.h\"\n#include \"canohost.h\"\n#include \"key.h\"\n#include \"authfd.h\"\n#include \"pathnames.h\"\n\n/* -- channel core */\n\n/*\n * Pointer to an array containing all allocated channels. The array is\n * dynamically extended as needed.\n */\nstatic Channel **channels = NULL;\n\n/*\n * Size of the channel array. All slots of the array must always be\n * initialized (at least the type field); unused slots set to NULL\n */\nstatic u_int channels_alloc = 0;\n\n/*\n * Maximum file descriptor value used in any of the channels. This is\n * updated in channel_new.\n */\nstatic int channel_max_fd = 0;\n\n\n/* -- tcp forwarding */\n\n/*\n * Data structure for storing which hosts are permitted for forward requests.\n * The local sides of any remote forwards are stored in this array to prevent\n * a corrupt remote server from accessing arbitrary TCP/IP ports on our local\n * network (which might be behind a firewall).\n */\n/* XXX: streamlocal wants a path instead of host:port */\n/* Overload host_to_connect; we could just make this match Forward */\n/*\tXXX - can we use listen_host instead of listen_path? */\ntypedef struct {\n\tchar *host_to_connect;\t\t/* Connect to 'host'. */\n\tint port_to_connect;\t\t/* Connect to 'port'. */\n\tchar *listen_host;\t\t/* Remote side should listen address. */\n\tchar *listen_path;\t\t/* Remote side should listen path. */\n\tint listen_port;\t\t/* Remote side should listen port. */\n\tChannel *downstream;\t\t/* Downstream mux*/\n} ForwardPermission;\n\n/* List of all permitted host/port pairs to connect by the user. */\nstatic ForwardPermission *permitted_opens = NULL;\n\n/* List of all permitted host/port pairs to connect by the admin. */\nstatic ForwardPermission *permitted_adm_opens = NULL;\n\n/* Number of permitted host/port pairs in the array permitted by the user. */\nstatic int num_permitted_opens = 0;\n\n/* Number of permitted host/port pair in the array permitted by the admin. */\nstatic int num_adm_permitted_opens = 0;\n\n/* special-case port number meaning allow any port */\n#define FWD_PERMIT_ANY_PORT\t0\n\n/* special-case wildcard meaning allow any host */\n#define FWD_PERMIT_ANY_HOST\t\"*\"\n\n/*\n * If this is true, all opens are permitted. This is the case on the server\n * on which we have to trust the client anyway, and the user could do\n * anything after logging in anyway.\n */\nstatic int all_opens_permitted = 0;\n\n\n/* -- X11 forwarding */\n\n/* Maximum number of fake X11 displays to try. */\n#define MAX_DISPLAYS 1000\n\n/* Saved X11 local (client) display. */\nstatic char *x11_saved_display = NULL;\n\n/* Saved X11 authentication protocol name. */\nstatic char *x11_saved_proto = NULL;\n\n/* Saved X11 authentication data. This is the real data. */\nstatic char *x11_saved_data = NULL;\nstatic u_int x11_saved_data_len = 0;\n\n/* Deadline after which all X11 connections are refused */\nstatic u_int x11_refuse_time;\n\n/*\n * Fake X11 authentication data. This is what the server will be sending us;\n * we should replace any occurrences of this by the real data.\n */\nstatic u_char *x11_fake_data = NULL;\nstatic u_int x11_fake_data_len;\n\n\n/* -- agent forwarding */\n\n#define\tNUM_SOCKS\t10\n\n/* AF_UNSPEC or AF_INET or AF_INET6 */\nstatic int IPv4or6 = AF_UNSPEC;\n\n/* helper */\nstatic void port_open_helper(Channel *c, char *rtype);\nstatic const char *channel_rfwd_bind_host(const char *listen_host);\n\n/* non-blocking connect helpers */\nstatic int connect_next(struct channel_connect *);\nstatic void channel_connect_ctx_free(struct channel_connect *);\n\n/* -- channel core */\n\nChannel *\nchannel_by_id(int id)\n{\n\tChannel *c;\n\n\tif (id < 0 || (u_int)id >= channels_alloc) {\n\t\tlogit(\"channel_by_id: %d: bad id\", id);\n\t\treturn NULL;\n\t}\n\tc = channels[id];\n\tif (c == NULL) {\n\t\tlogit(\"channel_by_id: %d: bad id: channel free\", id);\n\t\treturn NULL;\n\t}\n\treturn c;\n}\n\nChannel *\nchannel_by_remote_id(int remote_id)\n{\n\tChannel *c;\n\tu_int i;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c != NULL && c->remote_id == remote_id)\n\t\t\treturn c;\n\t}\n\treturn NULL;\n}\n\n/*\n * Returns the channel if it is allowed to receive protocol messages.\n * Private channels, like listening sockets, may not receive messages.\n */\nChannel *\nchannel_lookup(int id)\n{\n\tChannel *c;\n\n\tif ((c = channel_by_id(id)) == NULL)\n\t\treturn (NULL);\n\n\tswitch (c->type) {\n\tcase SSH_CHANNEL_X11_OPEN:\n\tcase SSH_CHANNEL_LARVAL:\n\tcase SSH_CHANNEL_CONNECTING:\n\tcase SSH_CHANNEL_DYNAMIC:\n\tcase SSH_CHANNEL_OPENING:\n\tcase SSH_CHANNEL_OPEN:\n\tcase SSH_CHANNEL_INPUT_DRAINING:\n\tcase SSH_CHANNEL_OUTPUT_DRAINING:\n\tcase SSH_CHANNEL_ABANDONED:\n\tcase SSH_CHANNEL_MUX_PROXY:\n\t\treturn (c);\n\t}\n\tlogit(\"Non-public channel %d, type %d.\", id, c->type);\n\treturn (NULL);\n}\n\n/*\n * Register filedescriptors for a channel, used when allocating a channel or\n * when the channel consumer/producer is ready, e.g. shell exec'd\n */\nstatic void\nchannel_register_fds(Channel *c, int rfd, int wfd, int efd,\n int extusage, int nonblock, int is_tty)\n{\n\t/* Update the maximum file descriptor value. */\n\tchannel_max_fd = MAXIMUM(channel_max_fd, rfd);\n\tchannel_max_fd = MAXIMUM(channel_max_fd, wfd);\n\tchannel_max_fd = MAXIMUM(channel_max_fd, efd);\n\n\tif (rfd != -1)\n\t\tfcntl(rfd, F_SETFD, FD_CLOEXEC);\n\tif (wfd != -1 && wfd != rfd)\n\t\tfcntl(wfd, F_SETFD, FD_CLOEXEC);\n\tif (efd != -1 && efd != rfd && efd != wfd)\n\t\tfcntl(efd, F_SETFD, FD_CLOEXEC);\n\n\tc->rfd = rfd;\n\tc->wfd = wfd;\n\tc->sock = (rfd == wfd) ? rfd : -1;\n\tc->efd = efd;\n\tc->extended_usage = extusage;\n\n\tif ((c->isatty = is_tty) != 0)\n\t\tdebug2(\"channel %d: rfd %d isatty\", c->self, c->rfd);\n#ifdef _AIX\n\t/* XXX: Later AIX versions can't push as much data to tty */\n\tc->wfd_isatty = is_tty || isatty(c->wfd);\n#endif\n\n\t/* enable nonblocking mode */\n\tif (nonblock) {\n\t\tif (rfd != -1)\n\t\t\tset_nonblock(rfd);\n\t\tif (wfd != -1)\n\t\t\tset_nonblock(wfd);\n\t\tif (efd != -1)\n\t\t\tset_nonblock(efd);\n\t}\n}\n\n/*\n * Allocate a new channel object and set its type and socket. This will cause\n * remote_name to be freed.\n */\nChannel *\nchannel_new(char *ctype, int type, int rfd, int wfd, int efd,\n u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)\n{\n\tint found;\n\tu_int i;\n\tChannel *c;\n\n\t/* Do initial allocation if this is the first call. */\n\tif (channels_alloc == 0) {\n\t\tchannels_alloc = 10;\n\t\tchannels = xcalloc(channels_alloc, sizeof(Channel *));\n\t\tfor (i = 0; i < channels_alloc; i++)\n\t\t\tchannels[i] = NULL;\n\t}\n\t/* Try to find a free slot where to put the new channel. */\n\tfor (found = -1, i = 0; i < channels_alloc; i++)\n\t\tif (channels[i] == NULL) {\n\t\t\t/* Found a free slot. */\n\t\t\tfound = (int)i;\n\t\t\tbreak;\n\t\t}\n\tif (found < 0) {\n\t\t/* There are no free slots. Take last+1 slot and expand the array. */\n\t\tfound = channels_alloc;\n\t\tif (channels_alloc > 10000)\n\t\t\tfatal(\"channel_new: internal error: channels_alloc %d \"\n\t\t\t \"too big.\", channels_alloc);\n\t\tchannels = xreallocarray(channels, channels_alloc + 10,\n\t\t sizeof(Channel *));\n\t\tchannels_alloc += 10;\n\t\tdebug2(\"channel: expanding %d\", channels_alloc);\n\t\tfor (i = found; i < channels_alloc; i++)\n\t\t\tchannels[i] = NULL;\n\t}\n\t/* Initialize and return new channel. */\n\tc = channels[found] = xcalloc(1, sizeof(Channel));\n\tbuffer_init(&c->input);\n\tbuffer_init(&c->output);\n\tbuffer_init(&c->extended);\n\tc->path = NULL;\n\tc->listening_addr = NULL;\n\tc->listening_port = 0;\n\tc->ostate = CHAN_OUTPUT_OPEN;\n\tc->istate = CHAN_INPUT_OPEN;\n\tc->flags = 0;\n\tchannel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0);\n\tc->notbefore = 0;\n\tc->self = found;\n\tc->type = type;\n\tc->ctype = ctype;\n\tc->local_window = window;\n\tc->local_window_max = window;\n\tc->local_consumed = 0;\n\tc->local_maxpacket = maxpack;\n\tc->remote_id = -1;\n\tc->remote_name = xstrdup(remote_name);\n\tc->remote_window = 0;\n\tc->remote_maxpacket = 0;\n\tc->force_drain = 0;\n\tc->single_connection = 0;\n\tc->detach_user = NULL;\n\tc->detach_close = 0;\n\tc->open_confirm = NULL;\n\tc->open_confirm_ctx = NULL;\n\tc->input_filter = NULL;\n\tc->output_filter = NULL;\n\tc->filter_ctx = NULL;\n\tc->filter_cleanup = NULL;\n\tc->ctl_chan = -1;\n\tc->mux_rcb = NULL;\n\tc->mux_ctx = NULL;\n\tc->mux_pause = 0;\n\tc->delayed = 1;\t\t/* prevent call to channel_post handler */\n\tTAILQ_INIT(&c->status_confirms);\n\tdebug(\"channel %d: new [%s]\", found, remote_name);\n\treturn c;\n}\n\nstatic int\nchannel_find_maxfd(void)\n{\n\tu_int i;\n\tint max = 0;\n\tChannel *c;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c != NULL) {\n\t\t\tmax = MAXIMUM(max, c->rfd);\n\t\t\tmax = MAXIMUM(max, c->wfd);\n\t\t\tmax = MAXIMUM(max, c->efd);\n\t\t}\n\t}\n\treturn max;\n}\n\nint\nchannel_close_fd(int *fdp)\n{\n\tint ret = 0, fd = *fdp;\n\n\tif (fd != -1) {\n\t\tret = close(fd);\n\t\t*fdp = -1;\n\t\tif (fd == channel_max_fd)\n\t\t\tchannel_max_fd = channel_find_maxfd();\n\t}\n\treturn ret;\n}\n\n/* Close all channel fd/socket. */\nstatic void\nchannel_close_fds(Channel *c)\n{\n\tchannel_close_fd(&c->sock);\n\tchannel_close_fd(&c->rfd);\n\tchannel_close_fd(&c->wfd);\n\tchannel_close_fd(&c->efd);\n}\n\n/* Free the channel and close its fd/socket. */\nvoid\nchannel_free(Channel *c)\n{\n\tchar *s;\n\tu_int i, n;\n\tChannel *other;\n\tstruct channel_confirm *cc;\n\n\tfor (n = 0, i = 0; i < channels_alloc; i++) {\n\t\tif ((other = channels[i]) != NULL) {\n\t\t\tn++;\n\n\t\t\t/* detach from mux client and prepare for closing */\n\t\t\tif (c->type == SSH_CHANNEL_MUX_CLIENT &&\n\t\t\t other->type == SSH_CHANNEL_MUX_PROXY &&\n\t\t\t other->mux_ctx == c) {\n\t\t\t\tother->mux_ctx = NULL;\n\t\t\t\tother->type = SSH_CHANNEL_OPEN;\n\t\t\t\tother->istate = CHAN_INPUT_CLOSED;\n\t\t\t\tother->ostate = CHAN_OUTPUT_CLOSED;\n\t\t\t}\n\t\t}\n\t}\n\tdebug(\"channel %d: free: %s, nchannels %u\", c->self,\n\t c->remote_name ? c->remote_name : \"???\", n);\n\n\t/* XXX more MUX cleanup: remove remote forwardings */\n\tif (c->type == SSH_CHANNEL_MUX_CLIENT) {\n\t\tfor (i = 0; i < (u_int)num_permitted_opens; i++) {\n\t\t\tif (permitted_opens[i].downstream != c)\n\t\t\t\tcontinue;\n\t\t\t/* cancel on the server, since mux client is gone */\n\t\t\tdebug(\"channel %d: cleanup remote forward for %s:%u\",\n\t\t\t c->self,\n\t\t\t permitted_opens[i].listen_host,\n\t\t\t permitted_opens[i].listen_port);\n\t\t\tpacket_start(SSH2_MSG_GLOBAL_REQUEST);\n\t\t\tpacket_put_cstring(\"cancel-tcpip-forward\");\n\t\t\tpacket_put_char(0);\n\t\t\tpacket_put_cstring(channel_rfwd_bind_host(\n\t\t\t permitted_opens[i].listen_host));\n\t\t\tpacket_put_int(permitted_opens[i].listen_port);\n\t\t\tpacket_send();\n\t\t\t/* unregister */\n\t\t\tpermitted_opens[i].listen_port = 0;\n\t\t\tpermitted_opens[i].port_to_connect = 0;\n\t\t\tfree(permitted_opens[i].host_to_connect);\n\t\t\tpermitted_opens[i].host_to_connect = NULL;\n\t\t\tfree(permitted_opens[i].listen_host);\n\t\t\tpermitted_opens[i].listen_host = NULL;\n\t\t\tpermitted_opens[i].listen_path = NULL;\n\t\t\tpermitted_opens[i].downstream = NULL;\n\t\t}\n\t}\n\n\ts = channel_open_message();\n\tdebug3(\"channel %d: status: %s\", c->self, s);\n\tfree(s);\n\n\tif (c->sock != -1)\n\t\tshutdown(c->sock, SHUT_RDWR);\n\tchannel_close_fds(c);\n\tbuffer_free(&c->input);\n\tbuffer_free(&c->output);\n\tbuffer_free(&c->extended);\n\tfree(c->remote_name);\n\tc->remote_name = NULL;\n\tfree(c->path);\n\tc->path = NULL;\n\tfree(c->listening_addr);\n\tc->listening_addr = NULL;\n\twhile ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {\n\t\tif (cc->abandon_cb != NULL)\n\t\t\tcc->abandon_cb(c, cc->ctx);\n\t\tTAILQ_REMOVE(&c->status_confirms, cc, entry);\n\t\texplicit_bzero(cc, sizeof(*cc));\n\t\tfree(cc);\n\t}\n\tif (c->filter_cleanup != NULL && c->filter_ctx != NULL)\n\t\tc->filter_cleanup(c->self, c->filter_ctx);\n\tchannels[c->self] = NULL;\n\tfree(c);\n}\n\nvoid\nchannel_free_all(void)\n{\n\tu_int i;\n\n\tfor (i = 0; i < channels_alloc; i++)\n\t\tif (channels[i] != NULL)\n\t\t\tchannel_free(channels[i]);\n}\n\n/*\n * Closes the sockets/fds of all channels. This is used to close extra file\n * descriptors after a fork.\n */\nvoid\nchannel_close_all(void)\n{\n\tu_int i;\n\n\tfor (i = 0; i < channels_alloc; i++)\n\t\tif (channels[i] != NULL)\n\t\t\tchannel_close_fds(channels[i]);\n}\n\n/*\n * Stop listening to channels.\n */\nvoid\nchannel_stop_listening(void)\n{\n\tu_int i;\n\tChannel *c;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c != NULL) {\n\t\t\tswitch (c->type) {\n\t\t\tcase SSH_CHANNEL_AUTH_SOCKET:\n\t\t\tcase SSH_CHANNEL_PORT_LISTENER:\n\t\t\tcase SSH_CHANNEL_RPORT_LISTENER:\n\t\t\tcase SSH_CHANNEL_X11_LISTENER:\n\t\t\tcase SSH_CHANNEL_UNIX_LISTENER:\n\t\t\tcase SSH_CHANNEL_RUNIX_LISTENER:\n\t\t\t\tchannel_close_fd(&c->sock);\n\t\t\t\tchannel_free(c);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*\n * Returns true if no channel has too much buffered data, and false if one or\n * more channel is overfull.\n */\nint\nchannel_not_very_much_buffered_data(void)\n{\n\tu_int i;\n\tChannel *c;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c != NULL && c->type == SSH_CHANNEL_OPEN) {\n#if 0\n\t\t\tif (!compat20 &&\n\t\t\t buffer_len(&c->input) > packet_get_maxsize()) {\n\t\t\t\tdebug2(\"channel %d: big input buffer %d\",\n\t\t\t\t c->self, buffer_len(&c->input));\n\t\t\t\treturn 0;\n\t\t\t}\n#endif\n\t\t\tif (buffer_len(&c->output) > packet_get_maxsize()) {\n\t\t\t\tdebug2(\"channel %d: big output buffer %u > %u\",\n\t\t\t\t c->self, buffer_len(&c->output),\n\t\t\t\t packet_get_maxsize());\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n\treturn 1;\n}\n\n/* Returns true if any channel is still open. */\nint\nchannel_still_open(void)\n{\n\tu_int i;\n\tChannel *c;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c == NULL)\n\t\t\tcontinue;\n\t\tswitch (c->type) {\n\t\tcase SSH_CHANNEL_X11_LISTENER:\n\t\tcase SSH_CHANNEL_PORT_LISTENER:\n\t\tcase SSH_CHANNEL_RPORT_LISTENER:\n\t\tcase SSH_CHANNEL_MUX_LISTENER:\n\t\tcase SSH_CHANNEL_CLOSED:\n\t\tcase SSH_CHANNEL_AUTH_SOCKET:\n\t\tcase SSH_CHANNEL_DYNAMIC:\n\t\tcase SSH_CHANNEL_CONNECTING:\n\t\tcase SSH_CHANNEL_ZOMBIE:\n\t\tcase SSH_CHANNEL_ABANDONED:\n\t\tcase SSH_CHANNEL_UNIX_LISTENER:\n\t\tcase SSH_CHANNEL_RUNIX_LISTENER:\n\t\t\tcontinue;\n\t\tcase SSH_CHANNEL_LARVAL:\n\t\t\tif (!compat20)\n\t\t\t\tfatal(\"cannot happen: SSH_CHANNEL_LARVAL\");\n\t\t\tcontinue;\n\t\tcase SSH_CHANNEL_OPENING:\n\t\tcase SSH_CHANNEL_OPEN:\n\t\tcase SSH_CHANNEL_X11_OPEN:\n\t\tcase SSH_CHANNEL_MUX_CLIENT:\n\t\tcase SSH_CHANNEL_MUX_PROXY:\n\t\t\treturn 1;\n\t\tcase SSH_CHANNEL_INPUT_DRAINING:\n\t\tcase SSH_CHANNEL_OUTPUT_DRAINING:\n\t\t\tif (!compat13)\n\t\t\t\tfatal(\"cannot happen: OUT_DRAIN\");\n\t\t\treturn 1;\n\t\tdefault:\n\t\t\tfatal(\"channel_still_open: bad channel type %d\", c->type);\n\t\t\t/* NOTREACHED */\n\t\t}\n\t}\n\treturn 0;\n}\n\n/* Returns the id of an open channel suitable for keepaliving */\nint\nchannel_find_open(void)\n{\n\tu_int i;\n\tChannel *c;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c == NULL || c->remote_id < 0)\n\t\t\tcontinue;\n\t\tswitch (c->type) {\n\t\tcase SSH_CHANNEL_CLOSED:\n\t\tcase SSH_CHANNEL_DYNAMIC:\n\t\tcase SSH_CHANNEL_X11_LISTENER:\n\t\tcase SSH_CHANNEL_PORT_LISTENER:\n\t\tcase SSH_CHANNEL_RPORT_LISTENER:\n\t\tcase SSH_CHANNEL_MUX_LISTENER:\n\t\tcase SSH_CHANNEL_MUX_CLIENT:\n\t\tcase SSH_CHANNEL_MUX_PROXY:\n\t\tcase SSH_CHANNEL_OPENING:\n\t\tcase SSH_CHANNEL_CONNECTING:\n\t\tcase SSH_CHANNEL_ZOMBIE:\n\t\tcase SSH_CHANNEL_ABANDONED:\n\t\tcase SSH_CHANNEL_UNIX_LISTENER:\n\t\tcase SSH_CHANNEL_RUNIX_LISTENER:\n\t\t\tcontinue;\n\t\tcase SSH_CHANNEL_LARVAL:\n\t\tcase SSH_CHANNEL_AUTH_SOCKET:\n\t\tcase SSH_CHANNEL_OPEN:\n\t\tcase SSH_CHANNEL_X11_OPEN:\n\t\t\treturn i;\n\t\tcase SSH_CHANNEL_INPUT_DRAINING:\n\t\tcase SSH_CHANNEL_OUTPUT_DRAINING:\n\t\t\tif (!compat13)\n\t\t\t\tfatal(\"cannot happen: OUT_DRAIN\");\n\t\t\treturn i;\n\t\tdefault:\n\t\t\tfatal(\"channel_find_open: bad channel type %d\", c->type);\n\t\t\t/* NOTREACHED */\n\t\t}\n\t}\n\treturn -1;\n}\n\n/*\n * Returns a message describing the currently open forwarded connections,\n * suitable for sending to the client. The message contains crlf pairs for\n * newlines.\n */\nchar *\nchannel_open_message(void)\n{\n\tBuffer buffer;\n\tChannel *c;\n\tchar buf[1024], *cp;\n\tu_int i;\n\n\tbuffer_init(&buffer);\n\tsnprintf(buf, sizeof buf, \"The following connections are open:\\r\\n\");\n\tbuffer_append(&buffer, buf, strlen(buf));\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c == NULL)\n\t\t\tcontinue;\n\t\tswitch (c->type) {\n\t\tcase SSH_CHANNEL_X11_LISTENER:\n\t\tcase SSH_CHANNEL_PORT_LISTENER:\n\t\tcase SSH_CHANNEL_RPORT_LISTENER:\n\t\tcase SSH_CHANNEL_CLOSED:\n\t\tcase SSH_CHANNEL_AUTH_SOCKET:\n\t\tcase SSH_CHANNEL_ZOMBIE:\n\t\tcase SSH_CHANNEL_ABANDONED:\n\t\tcase SSH_CHANNEL_MUX_LISTENER:\n\t\tcase SSH_CHANNEL_UNIX_LISTENER:\n\t\tcase SSH_CHANNEL_RUNIX_LISTENER:\n\t\t\tcontinue;\n\t\tcase SSH_CHANNEL_LARVAL:\n\t\tcase SSH_CHANNEL_OPENING:\n\t\tcase SSH_CHANNEL_CONNECTING:\n\t\tcase SSH_CHANNEL_DYNAMIC:\n\t\tcase SSH_CHANNEL_OPEN:\n\t\tcase SSH_CHANNEL_X11_OPEN:\n\t\tcase SSH_CHANNEL_INPUT_DRAINING:\n\t\tcase SSH_CHANNEL_OUTPUT_DRAINING:\n\t\tcase SSH_CHANNEL_MUX_PROXY:\n\t\tcase SSH_CHANNEL_MUX_CLIENT:\n\t\t\tsnprintf(buf, sizeof buf,\n\t\t\t \" #%d %.300s (t%d r%d i%u/%d o%u/%d fd %d/%d cc %d)\\r\\n\",\n\t\t\t c->self, c->remote_name,\n\t\t\t c->type, c->remote_id,\n\t\t\t c->istate, buffer_len(&c->input),\n\t\t\t c->ostate, buffer_len(&c->output),\n\t\t\t c->rfd, c->wfd, c->ctl_chan);\n\t\t\tbuffer_append(&buffer, buf, strlen(buf));\n\t\t\tcontinue;\n\t\tdefault:\n\t\t\tfatal(\"channel_open_message: bad channel type %d\", c->type);\n\t\t\t/* NOTREACHED */\n\t\t}\n\t}\n\tbuffer_append(&buffer, \"\\0\", 1);\n\tcp = xstrdup((char *)buffer_ptr(&buffer));\n\tbuffer_free(&buffer);\n\treturn cp;\n}\n\nvoid\nchannel_send_open(int id)\n{\n\tChannel *c = channel_lookup(id);\n\n\tif (c == NULL) {\n\t\tlogit(\"channel_send_open: %d: bad id\", id);\n\t\treturn;\n\t}\n\tdebug2(\"channel %d: send open\", id);\n\tpacket_start(SSH2_MSG_CHANNEL_OPEN);\n\tpacket_put_cstring(c->ctype);\n\tpacket_put_int(c->self);\n\tpacket_put_int(c->local_window);\n\tpacket_put_int(c->local_maxpacket);\n\tpacket_send();\n}\n\nvoid\nchannel_request_start(int id, char *service, int wantconfirm)\n{\n\tChannel *c = channel_lookup(id);\n\n\tif (c == NULL) {\n\t\tlogit(\"channel_request_start: %d: unknown channel id\", id);\n\t\treturn;\n\t}\n\tdebug2(\"channel %d: request %s confirm %d\", id, service, wantconfirm);\n\tpacket_start(SSH2_MSG_CHANNEL_REQUEST);\n\tpacket_put_int(c->remote_id);\n\tpacket_put_cstring(service);\n\tpacket_put_char(wantconfirm);\n}\n\nvoid\nchannel_register_status_confirm(int id, channel_confirm_cb *cb,\n channel_confirm_abandon_cb *abandon_cb, void *ctx)\n{\n\tstruct channel_confirm *cc;\n\tChannel *c;\n\n\tif ((c = channel_lookup(id)) == NULL)\n\t\tfatal(\"channel_register_expect: %d: bad id\", id);\n\n\tcc = xcalloc(1, sizeof(*cc));\n\tcc->cb = cb;\n\tcc->abandon_cb = abandon_cb;\n\tcc->ctx = ctx;\n\tTAILQ_INSERT_TAIL(&c->status_confirms, cc, entry);\n}\n\nvoid\nchannel_register_open_confirm(int id, channel_open_fn *fn, void *ctx)\n{\n\tChannel *c = channel_lookup(id);\n\n\tif (c == NULL) {\n\t\tlogit(\"channel_register_open_confirm: %d: bad id\", id);\n\t\treturn;\n\t}\n\tc->open_confirm = fn;\n\tc->open_confirm_ctx = ctx;\n}\n\nvoid\nchannel_register_cleanup(int id, channel_callback_fn *fn, int do_close)\n{\n\tChannel *c = channel_by_id(id);\n\n\tif (c == NULL) {\n\t\tlogit(\"channel_register_cleanup: %d: bad id\", id);\n\t\treturn;\n\t}\n\tc->detach_user = fn;\n\tc->detach_close = do_close;\n}\n\nvoid\nchannel_cancel_cleanup(int id)\n{\n\tChannel *c = channel_by_id(id);\n\n\tif (c == NULL) {\n\t\tlogit(\"channel_cancel_cleanup: %d: bad id\", id);\n\t\treturn;\n\t}\n\tc->detach_user = NULL;\n\tc->detach_close = 0;\n}\n\nvoid\nchannel_register_filter(int id, channel_infilter_fn *ifn,\n channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx)\n{\n\tChannel *c = channel_lookup(id);\n\n\tif (c == NULL) {\n\t\tlogit(\"channel_register_filter: %d: bad id\", id);\n\t\treturn;\n\t}\n\tc->input_filter = ifn;\n\tc->output_filter = ofn;\n\tc->filter_ctx = ctx;\n\tc->filter_cleanup = cfn;\n}\n\nvoid\nchannel_set_fds(int id, int rfd, int wfd, int efd,\n int extusage, int nonblock, int is_tty, u_int window_max)\n{\n\tChannel *c = channel_lookup(id);\n\n\tif (c == NULL || c->type != SSH_CHANNEL_LARVAL)\n\t\tfatal(\"channel_activate for non-larval channel %d.\", id);\n\tchannel_register_fds(c, rfd, wfd, efd, extusage, nonblock, is_tty);\n\tc->type = SSH_CHANNEL_OPEN;\n\tc->local_window = c->local_window_max = window_max;\n\tpacket_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);\n\tpacket_put_int(c->remote_id);\n\tpacket_put_int(c->local_window);\n\tpacket_send();\n}\n\n/*\n * 'channel_pre*' are called just before select() to add any bits relevant to\n * channels in the select bitmasks.\n */\n/*\n * 'channel_post*': perform any appropriate operations for channels which\n * have events pending.\n */\ntypedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset);\nchan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];\nchan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];\n\n/* ARGSUSED */\nstatic void\nchannel_pre_listener(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tFD_SET(c->sock, readset);\n}\n\n/* ARGSUSED */\nstatic void\nchannel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tdebug3(\"channel %d: waiting for connection\", c->self);\n\tFD_SET(c->sock, writeset);\n}\n\nstatic void\nchannel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tif (buffer_len(&c->input) < packet_get_maxsize())\n\t\tFD_SET(c->sock, readset);\n\tif (buffer_len(&c->output) > 0)\n\t\tFD_SET(c->sock, writeset);\n}\n\nstatic void\nchannel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tu_int limit = compat20 ? c->remote_window : packet_get_maxsize();\n\n\tif (c->istate == CHAN_INPUT_OPEN &&\n\t limit > 0 &&\n\t buffer_len(&c->input) < limit &&\n\t buffer_check_alloc(&c->input, CHAN_RBUF))\n\t\tFD_SET(c->rfd, readset);\n\tif (c->ostate == CHAN_OUTPUT_OPEN ||\n\t c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {\n\t\tif (buffer_len(&c->output) > 0) {\n\t\t\tFD_SET(c->wfd, writeset);\n\t\t} else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {\n\t\t\tif (CHANNEL_EFD_OUTPUT_ACTIVE(c))\n\t\t\t\tdebug2(\"channel %d: obuf_empty delayed efd %d/(%d)\",\n\t\t\t\t c->self, c->efd, buffer_len(&c->extended));\n\t\t\telse\n\t\t\t\tchan_obuf_empty(c);\n\t\t}\n\t}\n\t/** XXX check close conditions, too */\n\tif (compat20 && c->efd != -1 && \n\t !(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) {\n\t\tif (c->extended_usage == CHAN_EXTENDED_WRITE &&\n\t\t buffer_len(&c->extended) > 0)\n\t\t\tFD_SET(c->efd, writeset);\n\t\telse if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) &&\n\t\t (c->extended_usage == CHAN_EXTENDED_READ ||\n\t\t c->extended_usage == CHAN_EXTENDED_IGNORE) &&\n\t\t buffer_len(&c->extended) < c->remote_window)\n\t\t\tFD_SET(c->efd, readset);\n\t}\n\t/* XXX: What about efd? races? */\n}\n\n/* ARGSUSED */\nstatic void\nchannel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tif (buffer_len(&c->input) == 0) {\n\t\tpacket_start(SSH_MSG_CHANNEL_CLOSE);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_send();\n\t\tc->type = SSH_CHANNEL_CLOSED;\n\t\tdebug2(\"channel %d: closing after input drain.\", c->self);\n\t}\n}\n\n/* ARGSUSED */\nstatic void\nchannel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tif (buffer_len(&c->output) == 0)\n\t\tchan_mark_dead(c);\n\telse\n\t\tFD_SET(c->sock, writeset);\n}\n\n/*\n * This is a special state for X11 authentication spoofing. An opened X11\n * connection (when authentication spoofing is being done) remains in this\n * state until the first packet has been completely read. The authentication\n * data in that packet is then substituted by the real data if it matches the\n * fake data, and the channel is put into normal mode.\n * XXX All this happens at the client side.\n * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok\n */\nstatic int\nx11_open_helper(Buffer *b)\n{\n\tu_char *ucp;\n\tu_int proto_len, data_len;\n\n\t/* Is this being called after the refusal deadline? */\n\tif (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) {\n\t\tverbose(\"Rejected X11 connection after ForwardX11Timeout \"\n\t\t \"expired\");\n\t\treturn -1;\n\t}\n\n\t/* Check if the fixed size part of the packet is in buffer. */\n\tif (buffer_len(b) < 12)\n\t\treturn 0;\n\n\t/* Parse the lengths of variable-length fields. */\n\tucp = buffer_ptr(b);\n\tif (ucp[0] == 0x42) {\t/* Byte order MSB first. */\n\t\tproto_len = 256 * ucp[6] + ucp[7];\n\t\tdata_len = 256 * ucp[8] + ucp[9];\n\t} else if (ucp[0] == 0x6c) {\t/* Byte order LSB first. */\n\t\tproto_len = ucp[6] + 256 * ucp[7];\n\t\tdata_len = ucp[8] + 256 * ucp[9];\n\t} else {\n\t\tdebug2(\"Initial X11 packet contains bad byte order byte: 0x%x\",\n\t\t ucp[0]);\n\t\treturn -1;\n\t}\n\n\t/* Check if the whole packet is in buffer. */\n\tif (buffer_len(b) <\n\t 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))\n\t\treturn 0;\n\n\t/* Check if authentication protocol matches. */\n\tif (proto_len != strlen(x11_saved_proto) ||\n\t memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) {\n\t\tdebug2(\"X11 connection uses different authentication protocol.\");\n\t\treturn -1;\n\t}\n\t/* Check if authentication data matches our fake data. */\n\tif (data_len != x11_fake_data_len ||\n\t timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3),\n\t\tx11_fake_data, x11_fake_data_len) != 0) {\n\t\tdebug2(\"X11 auth data does not match fake data.\");\n\t\treturn -1;\n\t}\n\t/* Check fake data length */\n\tif (x11_fake_data_len != x11_saved_data_len) {\n\t\terror(\"X11 fake_data_len %d != saved_data_len %d\",\n\t\t x11_fake_data_len, x11_saved_data_len);\n\t\treturn -1;\n\t}\n\t/*\n\t * Received authentication protocol and data match\n\t * our fake data. Substitute the fake data with real\n\t * data.\n\t */\n\tmemcpy(ucp + 12 + ((proto_len + 3) & ~3),\n\t x11_saved_data, x11_saved_data_len);\n\treturn 1;\n}\n\nstatic void\nchannel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tint ret = x11_open_helper(&c->output);\n\n\tif (ret == 1) {\n\t\t/* Start normal processing for the channel. */\n\t\tc->type = SSH_CHANNEL_OPEN;\n\t\tchannel_pre_open_13(c, readset, writeset);\n\t} else if (ret == -1) {\n\t\t/*\n\t\t * We have received an X11 connection that has bad\n\t\t * authentication information.\n\t\t */\n\t\tlogit(\"X11 connection rejected because of wrong authentication.\");\n\t\tbuffer_clear(&c->input);\n\t\tbuffer_clear(&c->output);\n\t\tchannel_close_fd(&c->sock);\n\t\tc->sock = -1;\n\t\tc->type = SSH_CHANNEL_CLOSED;\n\t\tpacket_start(SSH_MSG_CHANNEL_CLOSE);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_send();\n\t}\n}\n\nstatic void\nchannel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tint ret = x11_open_helper(&c->output);\n\n\t/* c->force_drain = 1; */\n\n\tif (ret == 1) {\n\t\tc->type = SSH_CHANNEL_OPEN;\n\t\tchannel_pre_open(c, readset, writeset);\n\t} else if (ret == -1) {\n\t\tlogit(\"X11 connection rejected because of wrong authentication.\");\n\t\tdebug2(\"X11 rejected %d i%d/o%d\", c->self, c->istate, c->ostate);\n\t\tchan_read_failed(c);\n\t\tbuffer_clear(&c->input);\n\t\tchan_ibuf_empty(c);\n\t\tbuffer_clear(&c->output);\n\t\t/* for proto v1, the peer will send an IEOF */\n\t\tif (compat20)\n\t\t\tchan_write_failed(c);\n\t\telse\n\t\t\tc->type = SSH_CHANNEL_OPEN;\n\t\tdebug2(\"X11 closed %d i%d/o%d\", c->self, c->istate, c->ostate);\n\t}\n}\n\nstatic void\nchannel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tif (c->istate == CHAN_INPUT_OPEN && !c->mux_pause &&\n\t buffer_check_alloc(&c->input, CHAN_RBUF))\n\t\tFD_SET(c->rfd, readset);\n\tif (c->istate == CHAN_INPUT_WAIT_DRAIN) {\n\t\t/* clear buffer immediately (discard any partial packet) */\n\t\tbuffer_clear(&c->input);\n\t\tchan_ibuf_empty(c);\n\t\t/* Start output drain. XXX just kill chan? */\n\t\tchan_rcvd_oclose(c);\n\t}\n\tif (c->ostate == CHAN_OUTPUT_OPEN ||\n\t c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {\n\t\tif (buffer_len(&c->output) > 0)\n\t\t\tFD_SET(c->wfd, writeset);\n\t\telse if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN)\n\t\t\tchan_obuf_empty(c);\n\t}\n}\n\n/* try to decode a socks4 header */\n/* ARGSUSED */\nstatic int\nchannel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tchar *p, *host;\n\tu_int len, have, i, found, need;\n\tchar username[256];\n\tstruct {\n\t\tu_int8_t version;\n\t\tu_int8_t command;\n\t\tu_int16_t dest_port;\n\t\tstruct in_addr dest_addr;\n\t} s4_req, s4_rsp;\n\n\tdebug2(\"channel %d: decode socks4\", c->self);\n\n\thave = buffer_len(&c->input);\n\tlen = sizeof(s4_req);\n\tif (have < len)\n\t\treturn 0;\n\tp = (char *)buffer_ptr(&c->input);\n\n\tneed = 1;\n\t/* SOCKS4A uses an invalid IP address 0.0.0.x */\n\tif (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) {\n\t\tdebug2(\"channel %d: socks4a request\", c->self);\n\t\t/* ... and needs an extra string (the hostname) */\n\t\tneed = 2;\n\t}\n\t/* Check for terminating NUL on the string(s) */\n\tfor (found = 0, i = len; i < have; i++) {\n\t\tif (p[i] == '\\0') {\n\t\t\tfound++;\n\t\t\tif (found == need)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (i > 1024) {\n\t\t\t/* the peer is probably sending garbage */\n\t\t\tdebug(\"channel %d: decode socks4: too long\",\n\t\t\t c->self);\n\t\t\treturn -1;\n\t\t}\n\t}\n\tif (found < need)\n\t\treturn 0;\n\tbuffer_get(&c->input, (char *)&s4_req.version, 1);\n\tbuffer_get(&c->input, (char *)&s4_req.command, 1);\n\tbuffer_get(&c->input, (char *)&s4_req.dest_port, 2);\n\tbuffer_get(&c->input, (char *)&s4_req.dest_addr, 4);\n\thave = buffer_len(&c->input);\n\tp = (char *)buffer_ptr(&c->input);\n\tif (memchr(p, '\\0', have) == NULL)\n\t\tfatal(\"channel %d: decode socks4: user not nul terminated\",\n\t\t c->self);\n\tlen = strlen(p);\n\tdebug2(\"channel %d: decode socks4: user %s/%d\", c->self, p, len);\n\tlen++;\t\t\t\t\t/* trailing '\\0' */\n\tif (len > have)\n\t\tfatal(\"channel %d: decode socks4: len %d > have %d\",\n\t\t c->self, len, have);\n\tstrlcpy(username, p, sizeof(username));\n\tbuffer_consume(&c->input, len);\n\n\tfree(c->path);\n\tc->path = NULL;\n\tif (need == 1) {\t\t\t/* SOCKS4: one string */\n\t\thost = inet_ntoa(s4_req.dest_addr);\n\t\tc->path = xstrdup(host);\n\t} else {\t\t\t\t/* SOCKS4A: two strings */\n\t\thave = buffer_len(&c->input);\n\t\tp = (char *)buffer_ptr(&c->input);\n\t\tlen = strlen(p);\n\t\tdebug2(\"channel %d: decode socks4a: host %s/%d\",\n\t\t c->self, p, len);\n\t\tlen++;\t\t\t\t/* trailing '\\0' */\n\t\tif (len > have)\n\t\t\tfatal(\"channel %d: decode socks4a: len %d > have %d\",\n\t\t\t c->self, len, have);\n\t\tif (len > NI_MAXHOST) {\n\t\t\terror(\"channel %d: hostname \\\"%.100s\\\" too long\",\n\t\t\t c->self, p);\n\t\t\treturn -1;\n\t\t}\n\t\tc->path = xstrdup(p);\n\t\tbuffer_consume(&c->input, len);\n\t}\n\tc->host_port = ntohs(s4_req.dest_port);\n\n\tdebug2(\"channel %d: dynamic request: socks4 host %s port %u command %u\",\n\t c->self, c->path, c->host_port, s4_req.command);\n\n\tif (s4_req.command != 1) {\n\t\tdebug(\"channel %d: cannot handle: %s cn %d\",\n\t\t c->self, need == 1 ? \"SOCKS4\" : \"SOCKS4A\", s4_req.command);\n\t\treturn -1;\n\t}\n\ts4_rsp.version = 0;\t\t\t/* vn: 0 for reply */\n\ts4_rsp.command = 90;\t\t\t/* cd: req granted */\n\ts4_rsp.dest_port = 0;\t\t\t/* ignored */\n\ts4_rsp.dest_addr.s_addr = INADDR_ANY;\t/* ignored */\n\tbuffer_append(&c->output, &s4_rsp, sizeof(s4_rsp));\n\treturn 1;\n}\n\n/* try to decode a socks5 header */\n#define SSH_SOCKS5_AUTHDONE\t0x1000\n#define SSH_SOCKS5_NOAUTH\t0x00\n#define SSH_SOCKS5_IPV4\t\t0x01\n#define SSH_SOCKS5_DOMAIN\t0x03\n#define SSH_SOCKS5_IPV6\t\t0x04\n#define SSH_SOCKS5_CONNECT\t0x01\n#define SSH_SOCKS5_SUCCESS\t0x00\n\n/* ARGSUSED */\nstatic int\nchannel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tstruct {\n\t\tu_int8_t version;\n\t\tu_int8_t command;\n\t\tu_int8_t reserved;\n\t\tu_int8_t atyp;\n\t} s5_req, s5_rsp;\n\tu_int16_t dest_port;\n\tchar dest_addr[255+1], ntop[INET6_ADDRSTRLEN];\n\tu_char *p;\n\tu_int have, need, i, found, nmethods, addrlen, af;\n\n\tdebug2(\"channel %d: decode socks5\", c->self);\n\tp = buffer_ptr(&c->input);\n\tif (p[0] != 0x05)\n\t\treturn -1;\n\thave = buffer_len(&c->input);\n\tif (!(c->flags & SSH_SOCKS5_AUTHDONE)) {\n\t\t/* format: ver | nmethods | methods */\n\t\tif (have < 2)\n\t\t\treturn 0;\n\t\tnmethods = p[1];\n\t\tif (have < nmethods + 2)\n\t\t\treturn 0;\n\t\t/* look for method: \"NO AUTHENTICATION REQUIRED\" */\n\t\tfor (found = 0, i = 2; i < nmethods + 2; i++) {\n\t\t\tif (p[i] == SSH_SOCKS5_NOAUTH) {\n\t\t\t\tfound = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!found) {\n\t\t\tdebug(\"channel %d: method SSH_SOCKS5_NOAUTH not found\",\n\t\t\t c->self);\n\t\t\treturn -1;\n\t\t}\n\t\tbuffer_consume(&c->input, nmethods + 2);\n\t\tbuffer_put_char(&c->output, 0x05);\t\t/* version */\n\t\tbuffer_put_char(&c->output, SSH_SOCKS5_NOAUTH);\t/* method */\n\t\tFD_SET(c->sock, writeset);\n\t\tc->flags |= SSH_SOCKS5_AUTHDONE;\n\t\tdebug2(\"channel %d: socks5 auth done\", c->self);\n\t\treturn 0;\t\t\t\t/* need more */\n\t}\n\tdebug2(\"channel %d: socks5 post auth\", c->self);\n\tif (have < sizeof(s5_req)+1)\n\t\treturn 0;\t\t\t/* need more */\n\tmemcpy(&s5_req, p, sizeof(s5_req));\n\tif (s5_req.version != 0x05 ||\n\t s5_req.command != SSH_SOCKS5_CONNECT ||\n\t s5_req.reserved != 0x00) {\n\t\tdebug2(\"channel %d: only socks5 connect supported\", c->self);\n\t\treturn -1;\n\t}\n\tswitch (s5_req.atyp){\n\tcase SSH_SOCKS5_IPV4:\n\t\taddrlen = 4;\n\t\taf = AF_INET;\n\t\tbreak;\n\tcase SSH_SOCKS5_DOMAIN:\n\t\taddrlen = p[sizeof(s5_req)];\n\t\taf = -1;\n\t\tbreak;\n\tcase SSH_SOCKS5_IPV6:\n\t\taddrlen = 16;\n\t\taf = AF_INET6;\n\t\tbreak;\n\tdefault:\n\t\tdebug2(\"channel %d: bad socks5 atyp %d\", c->self, s5_req.atyp);\n\t\treturn -1;\n\t}\n\tneed = sizeof(s5_req) + addrlen + 2;\n\tif (s5_req.atyp == SSH_SOCKS5_DOMAIN)\n\t\tneed++;\n\tif (have < need)\n\t\treturn 0;\n\tbuffer_consume(&c->input, sizeof(s5_req));\n\tif (s5_req.atyp == SSH_SOCKS5_DOMAIN)\n\t\tbuffer_consume(&c->input, 1); /* host string length */\n\tbuffer_get(&c->input, &dest_addr, addrlen);\n\tbuffer_get(&c->input, (char *)&dest_port, 2);\n\tdest_addr[addrlen] = '\\0';\n\tfree(c->path);\n\tc->path = NULL;\n\tif (s5_req.atyp == SSH_SOCKS5_DOMAIN) {\n\t\tif (addrlen >= NI_MAXHOST) {\n\t\t\terror(\"channel %d: dynamic request: socks5 hostname \"\n\t\t\t \"\\\"%.100s\\\" too long\", c->self, dest_addr);\n\t\t\treturn -1;\n\t\t}\n\t\tc->path = xstrdup(dest_addr);\n\t} else {\n\t\tif (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL)\n\t\t\treturn -1;\n\t\tc->path = xstrdup(ntop);\n\t}\n\tc->host_port = ntohs(dest_port);\n\n\tdebug2(\"channel %d: dynamic request: socks5 host %s port %u command %u\",\n\t c->self, c->path, c->host_port, s5_req.command);\n\n\ts5_rsp.version = 0x05;\n\ts5_rsp.command = SSH_SOCKS5_SUCCESS;\n\ts5_rsp.reserved = 0;\t\t\t/* ignored */\n\ts5_rsp.atyp = SSH_SOCKS5_IPV4;\n\tdest_port = 0;\t\t\t\t/* ignored */\n\n\tbuffer_append(&c->output, &s5_rsp, sizeof(s5_rsp));\n\tbuffer_put_int(&c->output, ntohl(INADDR_ANY)); /* bind address */\n\tbuffer_append(&c->output, &dest_port, sizeof(dest_port));\n\treturn 1;\n}\n\nChannel *\nchannel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect,\n int in, int out)\n{\n\tChannel *c;\n\n\tdebug(\"channel_connect_stdio_fwd %s:%d\", host_to_connect,\n\t port_to_connect);\n\n\tc = channel_new(\"stdio-forward\", SSH_CHANNEL_OPENING, in, out,\n\t -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,\n\t 0, \"stdio-forward\", /*nonblock*/0);\n\n\tc->path = xstrdup(host_to_connect);\n\tc->host_port = port_to_connect;\n\tc->listening_port = 0;\n\tc->force_drain = 1;\n\n\tchannel_register_fds(c, in, out, -1, 0, 1, 0);\n\tport_open_helper(c, \"direct-tcpip\");\n\n\treturn c;\n}\n\n/* dynamic port forwarding */\nstatic void\nchannel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tu_char *p;\n\tu_int have;\n\tint ret;\n\n\thave = buffer_len(&c->input);\n\tdebug2(\"channel %d: pre_dynamic: have %d\", c->self, have);\n\t/* buffer_dump(&c->input); */\n\t/* check if the fixed size part of the packet is in buffer. */\n\tif (have < 3) {\n\t\t/* need more */\n\t\tFD_SET(c->sock, readset);\n\t\treturn;\n\t}\n\t/* try to guess the protocol */\n\tp = buffer_ptr(&c->input);\n\tswitch (p[0]) {\n\tcase 0x04:\n\t\tret = channel_decode_socks4(c, readset, writeset);\n\t\tbreak;\n\tcase 0x05:\n\t\tret = channel_decode_socks5(c, readset, writeset);\n\t\tbreak;\n\tdefault:\n\t\tret = -1;\n\t\tbreak;\n\t}\n\tif (ret < 0) {\n\t\tchan_mark_dead(c);\n\t} else if (ret == 0) {\n\t\tdebug2(\"channel %d: pre_dynamic: need more\", c->self);\n\t\t/* need more */\n\t\tFD_SET(c->sock, readset);\n\t} else {\n\t\t/* switch to the next state */\n\t\tc->type = SSH_CHANNEL_OPENING;\n\t\tport_open_helper(c, \"direct-tcpip\");\n\t}\n}\n\n/* This is our fake X11 server socket. */\n/* ARGSUSED */\nstatic void\nchannel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tChannel *nc;\n\tstruct sockaddr_storage addr;\n\tint newsock, oerrno;\n\tsocklen_t addrlen;\n\tchar buf[16384], *remote_ipaddr;\n\tint remote_port;\n\n\tif (FD_ISSET(c->sock, readset)) {\n\t\tdebug(\"X11 connection requested.\");\n\t\taddrlen = sizeof(addr);\n\t\tnewsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);\n\t\tif (c->single_connection) {\n\t\t\toerrno = errno;\n\t\t\tdebug2(\"single_connection: closing X11 listener.\");\n\t\t\tchannel_close_fd(&c->sock);\n\t\t\tchan_mark_dead(c);\n\t\t\terrno = oerrno;\n\t\t}\n\t\tif (newsock < 0) {\n\t\t\tif (errno != EINTR && errno != EWOULDBLOCK &&\n\t\t\t errno != ECONNABORTED)\n\t\t\t\terror(\"accept: %.100s\", strerror(errno));\n\t\t\tif (errno == EMFILE || errno == ENFILE)\n\t\t\t\tc->notbefore = monotime() + 1;\n\t\t\treturn;\n\t\t}\n\t\tset_nodelay(newsock);\n\t\tremote_ipaddr = get_peer_ipaddr(newsock);\n\t\tremote_port = get_peer_port(newsock);\n\t\tsnprintf(buf, sizeof buf, \"X11 connection from %.200s port %d\",\n\t\t remote_ipaddr, remote_port);\n\n\t\tnc = channel_new(\"accepted x11 socket\",\n\t\t SSH_CHANNEL_OPENING, newsock, newsock, -1,\n\t\t c->local_window_max, c->local_maxpacket, 0, buf, 1);\n\t\tif (compat20) {\n\t\t\tpacket_start(SSH2_MSG_CHANNEL_OPEN);\n\t\t\tpacket_put_cstring(\"x11\");\n\t\t\tpacket_put_int(nc->self);\n\t\t\tpacket_put_int(nc->local_window_max);\n\t\t\tpacket_put_int(nc->local_maxpacket);\n\t\t\t/* originator ipaddr and port */\n\t\t\tpacket_put_cstring(remote_ipaddr);\n\t\t\tif (datafellows & SSH_BUG_X11FWD) {\n\t\t\t\tdebug2(\"ssh2 x11 bug compat mode\");\n\t\t\t} else {\n\t\t\t\tpacket_put_int(remote_port);\n\t\t\t}\n\t\t\tpacket_send();\n\t\t} else {\n\t\t\tpacket_start(SSH_SMSG_X11_OPEN);\n\t\t\tpacket_put_int(nc->self);\n\t\t\tif (packet_get_protocol_flags() &\n\t\t\t SSH_PROTOFLAG_HOST_IN_FWD_OPEN)\n\t\t\t\tpacket_put_cstring(buf);\n\t\t\tpacket_send();\n\t\t}\n\t\tfree(remote_ipaddr);\n\t}\n}\n\nstatic void\nport_open_helper(Channel *c, char *rtype)\n{\n\tchar buf[1024];\n\tchar *local_ipaddr = get_local_ipaddr(c->sock);\n\tint local_port = c->sock == -1 ? 65536 : get_local_port(c->sock);\n\tchar *remote_ipaddr = get_peer_ipaddr(c->sock);\n\tint remote_port = get_peer_port(c->sock);\n\n\tif (remote_port == -1) {\n\t\t/* Fake addr/port to appease peers that validate it (Tectia) */\n\t\tfree(remote_ipaddr);\n\t\tremote_ipaddr = xstrdup(\"127.0.0.1\");\n\t\tremote_port = 65535;\n\t}\n\n\tsnprintf(buf, sizeof buf,\n\t \"%s: listening port %d for %.100s port %d, \"\n\t \"connect from %.200s port %d to %.100s port %d\",\n\t rtype, c->listening_port, c->path, c->host_port,\n\t remote_ipaddr, remote_port, local_ipaddr, local_port);\n\n\tfree(c->remote_name);\n\tc->remote_name = xstrdup(buf);\n\n\tif (compat20) {\n\t\tpacket_start(SSH2_MSG_CHANNEL_OPEN);\n\t\tpacket_put_cstring(rtype);\n\t\tpacket_put_int(c->self);\n\t\tpacket_put_int(c->local_window_max);\n\t\tpacket_put_int(c->local_maxpacket);\n\t\tif (strcmp(rtype, \"direct-tcpip\") == 0) {\n\t\t\t/* target host, port */\n\t\t\tpacket_put_cstring(c->path);\n\t\t\tpacket_put_int(c->host_port);\n\t\t} else if (strcmp(rtype, \"direct-streamlocal@openssh.com\") == 0) {\n\t\t\t/* target path */\n\t\t\tpacket_put_cstring(c->path);\n\t\t} else if (strcmp(rtype, \"forwarded-streamlocal@openssh.com\") == 0) {\n\t\t\t/* listen path */\n\t\t\tpacket_put_cstring(c->path);\n\t\t} else {\n\t\t\t/* listen address, port */\n\t\t\tpacket_put_cstring(c->path);\n\t\t\tpacket_put_int(local_port);\n\t\t}\n\t\tif (strcmp(rtype, \"forwarded-streamlocal@openssh.com\") == 0) {\n\t\t\t/* reserved for future owner/mode info */\n\t\t\tpacket_put_cstring(\"\");\n\t\t} else {\n\t\t\t/* originator host and port */\n\t\t\tpacket_put_cstring(remote_ipaddr);\n\t\t\tpacket_put_int((u_int)remote_port);\n\t\t}\n\t\tpacket_send();\n\t} else {\n\t\tpacket_start(SSH_MSG_PORT_OPEN);\n\t\tpacket_put_int(c->self);\n\t\tpacket_put_cstring(c->path);\n\t\tpacket_put_int(c->host_port);\n\t\tif (packet_get_protocol_flags() &\n\t\t SSH_PROTOFLAG_HOST_IN_FWD_OPEN)\n\t\t\tpacket_put_cstring(c->remote_name);\n\t\tpacket_send();\n\t}\n\tfree(remote_ipaddr);\n\tfree(local_ipaddr);\n}\n\nstatic void\nchannel_set_reuseaddr(int fd)\n{\n\tint on = 1;\n\n\t/*\n\t * Set socket options.\n\t * Allow local port reuse in TIME_WAIT.\n\t */\n\tif (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)\n\t\terror(\"setsockopt SO_REUSEADDR fd %d: %s\", fd, strerror(errno));\n}\n\nvoid\nchannel_set_x11_refuse_time(u_int refuse_time)\n{\n\tx11_refuse_time = refuse_time;\n}\n\n/*\n * This socket is listening for connections to a forwarded TCP/IP port.\n */\n/* ARGSUSED */\nstatic void\nchannel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tChannel *nc;\n\tstruct sockaddr_storage addr;\n\tint newsock, nextstate;\n\tsocklen_t addrlen;\n\tchar *rtype;\n\n\tif (FD_ISSET(c->sock, readset)) {\n\t\tdebug(\"Connection to port %d forwarding \"\n\t\t \"to %.100s port %d requested.\",\n\t\t c->listening_port, c->path, c->host_port);\n\n\t\tif (c->type == SSH_CHANNEL_RPORT_LISTENER) {\n\t\t\tnextstate = SSH_CHANNEL_OPENING;\n\t\t\trtype = \"forwarded-tcpip\";\n\t\t} else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) {\n\t\t\tnextstate = SSH_CHANNEL_OPENING;\n\t\t\trtype = \"forwarded-streamlocal@openssh.com\";\n\t\t} else if (c->host_port == PORT_STREAMLOCAL) {\n\t\t\tnextstate = SSH_CHANNEL_OPENING;\n\t\t\trtype = \"direct-streamlocal@openssh.com\";\n\t\t} else if (c->host_port == 0) {\n\t\t\tnextstate = SSH_CHANNEL_DYNAMIC;\n\t\t\trtype = \"dynamic-tcpip\";\n\t\t} else {\n\t\t\tnextstate = SSH_CHANNEL_OPENING;\n\t\t\trtype = \"direct-tcpip\";\n\t\t}\n\n\t\taddrlen = sizeof(addr);\n\t\tnewsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);\n\t\tif (newsock < 0) {\n\t\t\tif (errno != EINTR && errno != EWOULDBLOCK &&\n\t\t\t errno != ECONNABORTED)\n\t\t\t\terror(\"accept: %.100s\", strerror(errno));\n\t\t\tif (errno == EMFILE || errno == ENFILE)\n\t\t\t\tc->notbefore = monotime() + 1;\n\t\t\treturn;\n\t\t}\n\t\tif (c->host_port != PORT_STREAMLOCAL)\n\t\t\tset_nodelay(newsock);\n\t\tnc = channel_new(rtype, nextstate, newsock, newsock, -1,\n\t\t c->local_window_max, c->local_maxpacket, 0, rtype, 1);\n\t\tnc->listening_port = c->listening_port;\n\t\tnc->host_port = c->host_port;\n\t\tif (c->path != NULL)\n\t\t\tnc->path = xstrdup(c->path);\n\n\t\tif (nextstate != SSH_CHANNEL_DYNAMIC)\n\t\t\tport_open_helper(nc, rtype);\n\t}\n}\n\n/*\n * This is the authentication agent socket listening for connections from\n * clients.\n */\n/* ARGSUSED */\nstatic void\nchannel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tChannel *nc;\n\tint newsock;\n\tstruct sockaddr_storage addr;\n\tsocklen_t addrlen;\n\n\tif (FD_ISSET(c->sock, readset)) {\n\t\taddrlen = sizeof(addr);\n\t\tnewsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);\n\t\tif (newsock < 0) {\n\t\t\terror(\"accept from auth socket: %.100s\",\n\t\t\t strerror(errno));\n\t\t\tif (errno == EMFILE || errno == ENFILE)\n\t\t\t\tc->notbefore = monotime() + 1;\n\t\t\treturn;\n\t\t}\n\t\tnc = channel_new(\"accepted auth socket\",\n\t\t SSH_CHANNEL_OPENING, newsock, newsock, -1,\n\t\t c->local_window_max, c->local_maxpacket,\n\t\t 0, \"accepted auth socket\", 1);\n\t\tif (compat20) {\n\t\t\tpacket_start(SSH2_MSG_CHANNEL_OPEN);\n\t\t\tpacket_put_cstring(\"auth-agent@openssh.com\");\n\t\t\tpacket_put_int(nc->self);\n\t\t\tpacket_put_int(c->local_window_max);\n\t\t\tpacket_put_int(c->local_maxpacket);\n\t\t} else {\n\t\t\tpacket_start(SSH_SMSG_AGENT_OPEN);\n\t\t\tpacket_put_int(nc->self);\n\t\t}\n\t\tpacket_send();\n\t}\n}\n\n/* ARGSUSED */\nstatic void\nchannel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tint err = 0, sock;\n\tsocklen_t sz = sizeof(err);\n\n\tif (FD_ISSET(c->sock, writeset)) {\n\t\tif (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {\n\t\t\terr = errno;\n\t\t\terror(\"getsockopt SO_ERROR failed\");\n\t\t}\n\t\tif (err == 0) {\n\t\t\tdebug(\"channel %d: connected to %s port %d\",\n\t\t\t c->self, c->connect_ctx.host, c->connect_ctx.port);\n\t\t\tchannel_connect_ctx_free(&c->connect_ctx);\n\t\t\tc->type = SSH_CHANNEL_OPEN;\n\t\t\tif (compat20) {\n\t\t\t\tpacket_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);\n\t\t\t\tpacket_put_int(c->remote_id);\n\t\t\t\tpacket_put_int(c->self);\n\t\t\t\tpacket_put_int(c->local_window);\n\t\t\t\tpacket_put_int(c->local_maxpacket);\n\t\t\t} else {\n\t\t\t\tpacket_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);\n\t\t\t\tpacket_put_int(c->remote_id);\n\t\t\t\tpacket_put_int(c->self);\n\t\t\t}\n\t\t} else {\n\t\t\tdebug(\"channel %d: connection failed: %s\",\n\t\t\t c->self, strerror(err));\n\t\t\t/* Try next address, if any */\n\t\t\tif ((sock = connect_next(&c->connect_ctx)) > 0) {\n\t\t\t\tclose(c->sock);\n\t\t\t\tc->sock = c->rfd = c->wfd = sock;\n\t\t\t\tchannel_max_fd = channel_find_maxfd();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t/* Exhausted all addresses */\n\t\t\terror(\"connect_to %.100s port %d: failed.\",\n\t\t\t c->connect_ctx.host, c->connect_ctx.port);\n\t\t\tchannel_connect_ctx_free(&c->connect_ctx);\n\t\t\tif (compat20) {\n\t\t\t\tpacket_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);\n\t\t\t\tpacket_put_int(c->remote_id);\n\t\t\t\tpacket_put_int(SSH2_OPEN_CONNECT_FAILED);\n\t\t\t\tif (!(datafellows & SSH_BUG_OPENFAILURE)) {\n\t\t\t\t\tpacket_put_cstring(strerror(err));\n\t\t\t\t\tpacket_put_cstring(\"\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpacket_start(SSH_MSG_CHANNEL_OPEN_FAILURE);\n\t\t\t\tpacket_put_int(c->remote_id);\n\t\t\t}\n\t\t\tchan_mark_dead(c);\n\t\t}\n\t\tpacket_send();\n\t}\n}\n\n/* ARGSUSED */\nstatic int\nchannel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tchar buf[CHAN_RBUF];\n\tint len, force;\n\n\tforce = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;\n\tif (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) {\n\t\terrno = 0;\n\t\tlen = read(c->rfd, buf, sizeof(buf));\n\t\tif (len < 0 && (errno == EINTR ||\n\t\t ((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))\n\t\t\treturn 1;\n#ifndef PTY_ZEROREAD\n\t\tif (len <= 0) {\n#else\n\t\tif ((!c->isatty && len <= 0) ||\n\t\t (c->isatty && (len < 0 || (len == 0 && errno != 0)))) {\n#endif\n\t\t\tdebug2(\"channel %d: read<=0 rfd %d len %d\",\n\t\t\t c->self, c->rfd, len);\n\t\t\tif (c->type != SSH_CHANNEL_OPEN) {\n\t\t\t\tdebug2(\"channel %d: not open\", c->self);\n\t\t\t\tchan_mark_dead(c);\n\t\t\t\treturn -1;\n\t\t\t} else if (compat13) {\n\t\t\t\tbuffer_clear(&c->output);\n\t\t\t\tc->type = SSH_CHANNEL_INPUT_DRAINING;\n\t\t\t\tdebug2(\"channel %d: input draining.\", c->self);\n\t\t\t} else {\n\t\t\t\tchan_read_failed(c);\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\t\tif (c->input_filter != NULL) {\n\t\t\tif (c->input_filter(c, buf, len) == -1) {\n\t\t\t\tdebug2(\"channel %d: filter stops\", c->self);\n\t\t\t\tchan_read_failed(c);\n\t\t\t}\n\t\t} else if (c->datagram) {\n\t\t\tbuffer_put_string(&c->input, buf, len);\n\t\t} else {\n\t\t\tbuffer_append(&c->input, buf, len);\n\t\t}\n\t}\n\treturn 1;\n}\n\n/* ARGSUSED */\nstatic int\nchannel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tstruct termios tio;\n\tu_char *data = NULL, *buf;\n\tu_int dlen, olen = 0;\n\tint len;\n\n\t/* Send buffered output data to the socket. */\n\tif (c->wfd != -1 &&\n\t FD_ISSET(c->wfd, writeset) &&\n\t buffer_len(&c->output) > 0) {\n\t\tolen = buffer_len(&c->output);\n\t\tif (c->output_filter != NULL) {\n\t\t\tif ((buf = c->output_filter(c, &data, &dlen)) == NULL) {\n\t\t\t\tdebug2(\"channel %d: filter stops\", c->self);\n\t\t\t\tif (c->type != SSH_CHANNEL_OPEN)\n\t\t\t\t\tchan_mark_dead(c);\n\t\t\t\telse\n\t\t\t\t\tchan_write_failed(c);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t} else if (c->datagram) {\n\t\t\tbuf = data = buffer_get_string(&c->output, &dlen);\n\t\t} else {\n\t\t\tbuf = data = buffer_ptr(&c->output);\n\t\t\tdlen = buffer_len(&c->output);\n\t\t}\n\n\t\tif (c->datagram) {\n\t\t\t/* ignore truncated writes, datagrams might get lost */\n\t\t\tlen = write(c->wfd, buf, dlen);\n\t\t\tfree(data);\n\t\t\tif (len < 0 && (errno == EINTR || errno == EAGAIN ||\n\t\t\t errno == EWOULDBLOCK))\n\t\t\t\treturn 1;\n\t\t\tif (len <= 0) {\n\t\t\t\tif (c->type != SSH_CHANNEL_OPEN)\n\t\t\t\t\tchan_mark_dead(c);\n\t\t\t\telse\n\t\t\t\t\tchan_write_failed(c);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tgoto out;\n\t\t}\n#ifdef _AIX\n\t\t/* XXX: Later AIX versions can't push as much data to tty */\n\t\tif (compat20 && c->wfd_isatty)\n\t\t\tdlen = MIN(dlen, 8*1024);\n#endif\n\n\t\tlen = write(c->wfd, buf, dlen);\n\t\tif (len < 0 &&\n\t\t (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))\n\t\t\treturn 1;\n\t\tif (len <= 0) {\n\t\t\tif (c->type != SSH_CHANNEL_OPEN) {\n\t\t\t\tdebug2(\"channel %d: not open\", c->self);\n\t\t\t\tchan_mark_dead(c);\n\t\t\t\treturn -1;\n\t\t\t} else if (compat13) {\n\t\t\t\tbuffer_clear(&c->output);\n\t\t\t\tdebug2(\"channel %d: input draining.\", c->self);\n\t\t\t\tc->type = SSH_CHANNEL_INPUT_DRAINING;\n\t\t\t} else {\n\t\t\t\tchan_write_failed(c);\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n#ifndef BROKEN_TCGETATTR_ICANON\n\t\tif (compat20 && c->isatty && dlen >= 1 && buf[0] != '\\r') {\n\t\t\tif (tcgetattr(c->wfd, &tio) == 0 &&\n\t\t\t !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {\n\t\t\t\t/*\n\t\t\t\t * Simulate echo to reduce the impact of\n\t\t\t\t * traffic analysis. We need to match the\n\t\t\t\t * size of a SSH2_MSG_CHANNEL_DATA message\n\t\t\t\t * (4 byte channel id + buf)\n\t\t\t\t */\n\t\t\t\tpacket_send_ignore(4 + len);\n\t\t\t\tpacket_send();\n\t\t\t}\n\t\t}\n#endif\n\t\tbuffer_consume(&c->output, len);\n\t}\n out:\n\tif (compat20 && olen > 0)\n\t\tc->local_consumed += olen - buffer_len(&c->output);\n\treturn 1;\n}\n\nstatic int\nchannel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tchar buf[CHAN_RBUF];\n\tint len;\n\n/** XXX handle drain efd, too */\n\tif (c->efd != -1) {\n\t\tif (c->extended_usage == CHAN_EXTENDED_WRITE &&\n\t\t FD_ISSET(c->efd, writeset) &&\n\t\t buffer_len(&c->extended) > 0) {\n\t\t\tlen = write(c->efd, buffer_ptr(&c->extended),\n\t\t\t buffer_len(&c->extended));\n\t\t\tdebug2(\"channel %d: written %d to efd %d\",\n\t\t\t c->self, len, c->efd);\n\t\t\tif (len < 0 && (errno == EINTR || errno == EAGAIN ||\n\t\t\t errno == EWOULDBLOCK))\n\t\t\t\treturn 1;\n\t\t\tif (len <= 0) {\n\t\t\t\tdebug2(\"channel %d: closing write-efd %d\",\n\t\t\t\t c->self, c->efd);\n\t\t\t\tchannel_close_fd(&c->efd);\n\t\t\t} else {\n\t\t\t\tbuffer_consume(&c->extended, len);\n\t\t\t\tc->local_consumed += len;\n\t\t\t}\n\t\t} else if (c->efd != -1 &&\n\t\t (c->extended_usage == CHAN_EXTENDED_READ ||\n\t\t c->extended_usage == CHAN_EXTENDED_IGNORE) &&\n\t\t (c->detach_close || FD_ISSET(c->efd, readset))) {\n\t\t\tlen = read(c->efd, buf, sizeof(buf));\n\t\t\tdebug2(\"channel %d: read %d from efd %d\",\n\t\t\t c->self, len, c->efd);\n\t\t\tif (len < 0 && (errno == EINTR || ((errno == EAGAIN ||\n\t\t\t errno == EWOULDBLOCK) && !c->detach_close)))\n\t\t\t\treturn 1;\n\t\t\tif (len <= 0) {\n\t\t\t\tdebug2(\"channel %d: closing read-efd %d\",\n\t\t\t\t c->self, c->efd);\n\t\t\t\tchannel_close_fd(&c->efd);\n\t\t\t} else {\n\t\t\t\tif (c->extended_usage == CHAN_EXTENDED_IGNORE) {\n\t\t\t\t\tdebug3(\"channel %d: discard efd\",\n\t\t\t\t\t c->self);\n\t\t\t\t} else\n\t\t\t\t\tbuffer_append(&c->extended, buf, len);\n\t\t\t}\n\t\t}\n\t}\n\treturn 1;\n}\n\nstatic int\nchannel_check_window(Channel *c)\n{\n\tif (c->type == SSH_CHANNEL_OPEN &&\n\t !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&\n\t ((c->local_window_max - c->local_window >\n\t c->local_maxpacket*3) ||\n\t c->local_window < c->local_window_max/2) &&\n\t c->local_consumed > 0) {\n\t\tpacket_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_put_int(c->local_consumed);\n\t\tpacket_send();\n\t\tdebug2(\"channel %d: window %d sent adjust %d\",\n\t\t c->self, c->local_window,\n\t\t c->local_consumed);\n\t\tc->local_window += c->local_consumed;\n\t\tc->local_consumed = 0;\n\t}\n\treturn 1;\n}\n\nstatic void\nchannel_post_open(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tchannel_handle_rfd(c, readset, writeset);\n\tchannel_handle_wfd(c, readset, writeset);\n\tif (!compat20)\n\t\treturn;\n\tchannel_handle_efd(c, readset, writeset);\n\tchannel_check_window(c);\n}\n\nstatic u_int\nread_mux(Channel *c, u_int need)\n{\n\tchar buf[CHAN_RBUF];\n\tint len;\n\tu_int rlen;\n\n\tif (buffer_len(&c->input) < need) {\n\t\trlen = need - buffer_len(&c->input);\n\t\tlen = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF));\n\t\tif (len < 0 && (errno == EINTR || errno == EAGAIN))\n\t\t\treturn buffer_len(&c->input);\n\t\tif (len <= 0) {\n\t\t\tdebug2(\"channel %d: ctl read<=0 rfd %d len %d\",\n\t\t\t c->self, c->rfd, len);\n\t\t\tchan_read_failed(c);\n\t\t\treturn 0;\n\t\t} else\n\t\t\tbuffer_append(&c->input, buf, len);\n\t}\n\treturn buffer_len(&c->input);\n}\n\nstatic void\nchannel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tu_int need;\n\tssize_t len;\n\n\tif (!compat20)\n\t\tfatal(\"%s: entered with !compat20\", __func__);\n\n\tif (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) &&\n\t (c->istate == CHAN_INPUT_OPEN ||\n\t c->istate == CHAN_INPUT_WAIT_DRAIN)) {\n\t\t/*\n\t\t * Don't not read past the precise end of packets to\n\t\t * avoid disrupting fd passing.\n\t\t */\n\t\tif (read_mux(c, 4) < 4) /* read header */\n\t\t\treturn;\n\t\tneed = get_u32(buffer_ptr(&c->input));\n#define CHANNEL_MUX_MAX_PACKET\t(256 * 1024)\n\t\tif (need > CHANNEL_MUX_MAX_PACKET) {\n\t\t\tdebug2(\"channel %d: packet too big %u > %u\",\n\t\t\t c->self, CHANNEL_MUX_MAX_PACKET, need);\n\t\t\tchan_rcvd_oclose(c);\n\t\t\treturn;\n\t\t}\n\t\tif (read_mux(c, need + 4) < need + 4) /* read body */\n\t\t\treturn;\n\t\tif (c->mux_rcb(c) != 0) {\n\t\t\tdebug(\"channel %d: mux_rcb failed\", c->self);\n\t\t\tchan_mark_dead(c);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (c->wfd != -1 && FD_ISSET(c->wfd, writeset) &&\n\t buffer_len(&c->output) > 0) {\n\t\tlen = write(c->wfd, buffer_ptr(&c->output),\n\t\t buffer_len(&c->output));\n\t\tif (len < 0 && (errno == EINTR || errno == EAGAIN))\n\t\t\treturn;\n\t\tif (len <= 0) {\n\t\t\tchan_mark_dead(c);\n\t\t\treturn;\n\t\t}\n\t\tbuffer_consume(&c->output, len);\n\t}\n}\n\nstatic void\nchannel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tChannel *nc;\n\tstruct sockaddr_storage addr;\n\tsocklen_t addrlen;\n\tint newsock;\n\tuid_t euid;\n\tgid_t egid;\n\n\tif (!FD_ISSET(c->sock, readset))\n\t\treturn;\n\n\tdebug(\"multiplexing control connection\");\n\n\t/*\n\t * Accept connection on control socket\n\t */\n\tmemset(&addr, 0, sizeof(addr));\n\taddrlen = sizeof(addr);\n\tif ((newsock = accept(c->sock, (struct sockaddr*)&addr,\n\t &addrlen)) == -1) {\n\t\terror(\"%s accept: %s\", __func__, strerror(errno));\n\t\tif (errno == EMFILE || errno == ENFILE)\n\t\t\tc->notbefore = monotime() + 1;\n\t\treturn;\n\t}\n\n\tif (getpeereid(newsock, &euid, &egid) < 0) {\n\t\terror(\"%s getpeereid failed: %s\", __func__,\n\t\t strerror(errno));\n\t\tclose(newsock);\n\t\treturn;\n\t}\n\tif ((euid != 0) && (getuid() != euid)) {\n\t\terror(\"multiplex uid mismatch: peer euid %u != uid %u\",\n\t\t (u_int)euid, (u_int)getuid());\n\t\tclose(newsock);\n\t\treturn;\n\t}\n\tnc = channel_new(\"multiplex client\", SSH_CHANNEL_MUX_CLIENT,\n\t newsock, newsock, -1, c->local_window_max,\n\t c->local_maxpacket, 0, \"mux-control\", 1);\n\tnc->mux_rcb = c->mux_rcb;\n\tdebug3(\"%s: new mux channel %d fd %d\", __func__,\n\t nc->self, nc->sock);\n\t/* establish state */\n\tnc->mux_rcb(nc);\n\t/* mux state transitions must not elicit protocol messages */\n\tnc->flags |= CHAN_LOCAL;\n}\n\n/* ARGSUSED */\nstatic void\nchannel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)\n{\n\tint len;\n\n\t/* Send buffered output data to the socket. */\n\tif (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {\n\t\tlen = write(c->sock, buffer_ptr(&c->output),\n\t\t\t buffer_len(&c->output));\n\t\tif (len <= 0)\n\t\t\tbuffer_clear(&c->output);\n\t\telse\n\t\t\tbuffer_consume(&c->output, len);\n\t}\n}\n\nstatic void\nchannel_handler_init_20(void)\n{\n\tchannel_pre[SSH_CHANNEL_OPEN] =\t\t\t&channel_pre_open;\n\tchannel_pre[SSH_CHANNEL_X11_OPEN] =\t\t&channel_pre_x11_open;\n\tchannel_pre[SSH_CHANNEL_PORT_LISTENER] =\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_RPORT_LISTENER] =\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_UNIX_LISTENER] =\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_RUNIX_LISTENER] =\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_X11_LISTENER] =\t\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_AUTH_SOCKET] =\t\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_CONNECTING] =\t\t&channel_pre_connecting;\n\tchannel_pre[SSH_CHANNEL_DYNAMIC] =\t\t&channel_pre_dynamic;\n\tchannel_pre[SSH_CHANNEL_MUX_LISTENER] =\t\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_MUX_CLIENT] =\t\t&channel_pre_mux_client;\n\n\tchannel_post[SSH_CHANNEL_OPEN] =\t\t&channel_post_open;\n\tchannel_post[SSH_CHANNEL_PORT_LISTENER] =\t&channel_post_port_listener;\n\tchannel_post[SSH_CHANNEL_RPORT_LISTENER] =\t&channel_post_port_listener;\n\tchannel_post[SSH_CHANNEL_UNIX_LISTENER] =\t&channel_post_port_listener;\n\tchannel_post[SSH_CHANNEL_RUNIX_LISTENER] =\t&channel_post_port_listener;\n\tchannel_post[SSH_CHANNEL_X11_LISTENER] =\t&channel_post_x11_listener;\n\tchannel_post[SSH_CHANNEL_AUTH_SOCKET] =\t\t&channel_post_auth_listener;\n\tchannel_post[SSH_CHANNEL_CONNECTING] =\t\t&channel_post_connecting;\n\tchannel_post[SSH_CHANNEL_DYNAMIC] =\t\t&channel_post_open;\n\tchannel_post[SSH_CHANNEL_MUX_LISTENER] =\t&channel_post_mux_listener;\n\tchannel_post[SSH_CHANNEL_MUX_CLIENT] =\t\t&channel_post_mux_client;\n}\n\nstatic void\nchannel_handler_init_13(void)\n{\n\tchannel_pre[SSH_CHANNEL_OPEN] =\t\t\t&channel_pre_open_13;\n\tchannel_pre[SSH_CHANNEL_X11_OPEN] =\t\t&channel_pre_x11_open_13;\n\tchannel_pre[SSH_CHANNEL_X11_LISTENER] =\t\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_PORT_LISTENER] =\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_AUTH_SOCKET] =\t\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_INPUT_DRAINING] =\t&channel_pre_input_draining;\n\tchannel_pre[SSH_CHANNEL_OUTPUT_DRAINING] =\t&channel_pre_output_draining;\n\tchannel_pre[SSH_CHANNEL_CONNECTING] =\t\t&channel_pre_connecting;\n\tchannel_pre[SSH_CHANNEL_DYNAMIC] =\t\t&channel_pre_dynamic;\n\n\tchannel_post[SSH_CHANNEL_OPEN] =\t\t&channel_post_open;\n\tchannel_post[SSH_CHANNEL_X11_LISTENER] =\t&channel_post_x11_listener;\n\tchannel_post[SSH_CHANNEL_PORT_LISTENER] =\t&channel_post_port_listener;\n\tchannel_post[SSH_CHANNEL_AUTH_SOCKET] =\t\t&channel_post_auth_listener;\n\tchannel_post[SSH_CHANNEL_OUTPUT_DRAINING] =\t&channel_post_output_drain_13;\n\tchannel_post[SSH_CHANNEL_CONNECTING] =\t\t&channel_post_connecting;\n\tchannel_post[SSH_CHANNEL_DYNAMIC] =\t\t&channel_post_open;\n}\n\nstatic void\nchannel_handler_init_15(void)\n{\n\tchannel_pre[SSH_CHANNEL_OPEN] =\t\t\t&channel_pre_open;\n\tchannel_pre[SSH_CHANNEL_X11_OPEN] =\t\t&channel_pre_x11_open;\n\tchannel_pre[SSH_CHANNEL_X11_LISTENER] =\t\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_PORT_LISTENER] =\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_AUTH_SOCKET] =\t\t&channel_pre_listener;\n\tchannel_pre[SSH_CHANNEL_CONNECTING] =\t\t&channel_pre_connecting;\n\tchannel_pre[SSH_CHANNEL_DYNAMIC] =\t\t&channel_pre_dynamic;\n\n\tchannel_post[SSH_CHANNEL_X11_LISTENER] =\t&channel_post_x11_listener;\n\tchannel_post[SSH_CHANNEL_PORT_LISTENER] =\t&channel_post_port_listener;\n\tchannel_post[SSH_CHANNEL_AUTH_SOCKET] =\t\t&channel_post_auth_listener;\n\tchannel_post[SSH_CHANNEL_OPEN] =\t\t&channel_post_open;\n\tchannel_post[SSH_CHANNEL_CONNECTING] =\t\t&channel_post_connecting;\n\tchannel_post[SSH_CHANNEL_DYNAMIC] =\t\t&channel_post_open;\n}\n\nstatic void\nchannel_handler_init(void)\n{\n\tint i;\n\n\tfor (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {\n\t\tchannel_pre[i] = NULL;\n\t\tchannel_post[i] = NULL;\n\t}\n\tif (compat20)\n\t\tchannel_handler_init_20();\n\telse if (compat13)\n\t\tchannel_handler_init_13();\n\telse\n\t\tchannel_handler_init_15();\n}\n\n/* gc dead channels */\nstatic void\nchannel_garbage_collect(Channel *c)\n{\n\tif (c == NULL)\n\t\treturn;\n\tif (c->detach_user != NULL) {\n\t\tif (!chan_is_dead(c, c->detach_close))\n\t\t\treturn;\n\t\tdebug2(\"channel %d: gc: notify user\", c->self);\n\t\tc->detach_user(c->self, NULL);\n\t\t/* if we still have a callback */\n\t\tif (c->detach_user != NULL)\n\t\t\treturn;\n\t\tdebug2(\"channel %d: gc: user detached\", c->self);\n\t}\n\tif (!chan_is_dead(c, 1))\n\t\treturn;\n\tdebug2(\"channel %d: garbage collecting\", c->self);\n\tchannel_free(c);\n}\n\nstatic void\nchannel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset,\n time_t *unpause_secs)\n{\n\tstatic int did_init = 0;\n\tu_int i, oalloc;\n\tChannel *c;\n\ttime_t now;\n\n\tif (!did_init) {\n\t\tchannel_handler_init();\n\t\tdid_init = 1;\n\t}\n\tnow = monotime();\n\tif (unpause_secs != NULL)\n\t\t*unpause_secs = 0;\n\tfor (i = 0, oalloc = channels_alloc; i < oalloc; i++) {\n\t\tc = channels[i];\n\t\tif (c == NULL)\n\t\t\tcontinue;\n\t\tif (c->delayed) {\n\t\t\tif (ftab == channel_pre)\n\t\t\t\tc->delayed = 0;\n\t\t\telse\n\t\t\t\tcontinue;\n\t\t}\n\t\tif (ftab[c->type] != NULL) {\n\t\t\t/*\n\t\t\t * Run handlers that are not paused.\n\t\t\t */\n\t\t\tif (c->notbefore <= now)\n\t\t\t\t(*ftab[c->type])(c, readset, writeset);\n\t\t\telse if (unpause_secs != NULL) {\n\t\t\t\t/*\n\t\t\t\t * Collect the time that the earliest\n\t\t\t\t * channel comes off pause.\n\t\t\t\t */\n\t\t\t\tdebug3(\"%s: chan %d: skip for %d more seconds\",\n\t\t\t\t __func__, c->self,\n\t\t\t\t (int)(c->notbefore - now));\n\t\t\t\tif (*unpause_secs == 0 ||\n\t\t\t\t (c->notbefore - now) < *unpause_secs)\n\t\t\t\t\t*unpause_secs = c->notbefore - now;\n\t\t\t}\n\t\t}\n\t\tchannel_garbage_collect(c);\n\t}\n\tif (unpause_secs != NULL && *unpause_secs != 0)\n\t\tdebug3(\"%s: first channel unpauses in %d seconds\",\n\t\t __func__, (int)*unpause_secs);\n}\n\n/*\n * Allocate/update select bitmasks and add any bits relevant to channels in\n * select bitmasks.\n */\nvoid\nchannel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,\n u_int *nallocp, time_t *minwait_secs, int rekeying)\n{\n\tu_int n, sz, nfdset;\n\n\tn = MAXIMUM(*maxfdp, channel_max_fd);\n\n\tnfdset = howmany(n+1, NFDBITS);\n\t/* Explicitly test here, because xrealloc isn't always called */\n\tif (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask))\n\t\tfatal(\"channel_prepare_select: max_fd (%d) is too large\", n);\n\tsz = nfdset * sizeof(fd_mask);\n\n\t/* perhaps check sz < nalloc/2 and shrink? */\n\tif (*readsetp == NULL || sz > *nallocp) {\n\t\t*readsetp = xreallocarray(*readsetp, nfdset, sizeof(fd_mask));\n\t\t*writesetp = xreallocarray(*writesetp, nfdset, sizeof(fd_mask));\n\t\t*nallocp = sz;\n\t}\n\t*maxfdp = n;\n\tmemset(*readsetp, 0, sz);\n\tmemset(*writesetp, 0, sz);\n\n\tif (!rekeying)\n\t\tchannel_handler(channel_pre, *readsetp, *writesetp,\n\t\t minwait_secs);\n}\n\n/*\n * After select, perform any appropriate operations for channels which have\n * events pending.\n */\nvoid\nchannel_after_select(fd_set *readset, fd_set *writeset)\n{\n\tchannel_handler(channel_post, readset, writeset, NULL);\n}\n\n\n/* If there is data to send to the connection, enqueue some of it now. */\nvoid\nchannel_output_poll(void)\n{\n\tChannel *c;\n\tu_int i, len;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tc = channels[i];\n\t\tif (c == NULL)\n\t\t\tcontinue;\n\n\t\t/*\n\t\t * We are only interested in channels that can have buffered\n\t\t * incoming data.\n\t\t */\n\t\tif (compat13) {\n\t\t\tif (c->type != SSH_CHANNEL_OPEN &&\n\t\t\t c->type != SSH_CHANNEL_INPUT_DRAINING)\n\t\t\t\tcontinue;\n\t\t} else {\n\t\t\tif (c->type != SSH_CHANNEL_OPEN)\n\t\t\t\tcontinue;\n\t\t}\n\t\tif (compat20 &&\n\t\t (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {\n\t\t\t/* XXX is this true? */\n\t\t\tdebug3(\"channel %d: will not send data after close\", c->self);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Get the amount of buffered data for this channel. */\n\t\tif ((c->istate == CHAN_INPUT_OPEN ||\n\t\t c->istate == CHAN_INPUT_WAIT_DRAIN) &&\n\t\t (len = buffer_len(&c->input)) > 0) {\n\t\t\tif (c->datagram) {\n\t\t\t\tif (len > 0) {\n\t\t\t\t\tu_char *data;\n\t\t\t\t\tu_int dlen;\n\n\t\t\t\t\tdata = buffer_get_string(&c->input,\n\t\t\t\t\t &dlen);\n\t\t\t\t\tif (dlen > c->remote_window ||\n\t\t\t\t\t dlen > c->remote_maxpacket) {\n\t\t\t\t\t\tdebug(\"channel %d: datagram \"\n\t\t\t\t\t\t \"too big for channel\",\n\t\t\t\t\t\t c->self);\n\t\t\t\t\t\tfree(data);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tpacket_start(SSH2_MSG_CHANNEL_DATA);\n\t\t\t\t\tpacket_put_int(c->remote_id);\n\t\t\t\t\tpacket_put_string(data, dlen);\n\t\t\t\t\tpacket_send();\n\t\t\t\t\tc->remote_window -= dlen;\n\t\t\t\t\tfree(data);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t/*\n\t\t\t * Send some data for the other side over the secure\n\t\t\t * connection.\n\t\t\t */\n\t\t\tif (compat20) {\n\t\t\t\tif (len > c->remote_window)\n\t\t\t\t\tlen = c->remote_window;\n\t\t\t\tif (len > c->remote_maxpacket)\n\t\t\t\t\tlen = c->remote_maxpacket;\n\t\t\t} else {\n\t\t\t\tif (packet_is_interactive()) {\n\t\t\t\t\tif (len > 1024)\n\t\t\t\t\t\tlen = 512;\n\t\t\t\t} else {\n\t\t\t\t\t/* Keep the packets at reasonable size. */\n\t\t\t\t\tif (len > packet_get_maxsize()/2)\n\t\t\t\t\t\tlen = packet_get_maxsize()/2;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (len > 0) {\n\t\t\t\tpacket_start(compat20 ?\n\t\t\t\t SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);\n\t\t\t\tpacket_put_int(c->remote_id);\n\t\t\t\tpacket_put_string(buffer_ptr(&c->input), len);\n\t\t\t\tpacket_send();\n\t\t\t\tbuffer_consume(&c->input, len);\n\t\t\t\tc->remote_window -= len;\n\t\t\t}\n\t\t} else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {\n\t\t\tif (compat13)\n\t\t\t\tfatal(\"cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3\");\n\t\t\t/*\n\t\t\t * input-buffer is empty and read-socket shutdown:\n\t\t\t * tell peer, that we will not send more data: send IEOF.\n\t\t\t * hack for extended data: delay EOF if EFD still in use.\n\t\t\t */\n\t\t\tif (CHANNEL_EFD_INPUT_ACTIVE(c))\n\t\t\t\tdebug2(\"channel %d: ibuf_empty delayed efd %d/(%d)\",\n\t\t\t\t c->self, c->efd, buffer_len(&c->extended));\n\t\t\telse\n\t\t\t\tchan_ibuf_empty(c);\n\t\t}\n\t\t/* Send extended data, i.e. stderr */\n\t\tif (compat20 &&\n\t\t !(c->flags & CHAN_EOF_SENT) &&\n\t\t c->remote_window > 0 &&\n\t\t (len = buffer_len(&c->extended)) > 0 &&\n\t\t c->extended_usage == CHAN_EXTENDED_READ) {\n\t\t\tdebug2(\"channel %d: rwin %u elen %u euse %d\",\n\t\t\t c->self, c->remote_window, buffer_len(&c->extended),\n\t\t\t c->extended_usage);\n\t\t\tif (len > c->remote_window)\n\t\t\t\tlen = c->remote_window;\n\t\t\tif (len > c->remote_maxpacket)\n\t\t\t\tlen = c->remote_maxpacket;\n\t\t\tpacket_start(SSH2_MSG_CHANNEL_EXTENDED_DATA);\n\t\t\tpacket_put_int(c->remote_id);\n\t\t\tpacket_put_int(SSH2_EXTENDED_DATA_STDERR);\n\t\t\tpacket_put_string(buffer_ptr(&c->extended), len);\n\t\t\tpacket_send();\n\t\t\tbuffer_consume(&c->extended, len);\n\t\t\tc->remote_window -= len;\n\t\t\tdebug2(\"channel %d: sent ext data %d\", c->self, len);\n\t\t}\n\t}\n}\n\n/* -- mux proxy support */\n\n/*\n * When multiplexing channel messages for mux clients we have to deal\n * with downstream messages from the mux client and upstream messages\n * from the ssh server:\n * 1) Handling downstream messages is straightforward and happens\n * in channel_proxy_downstream():\n * - We forward all messages (mostly) unmodified to the server.\n * - However, in order to route messages from upstream to the correct\n * downstream client, we have to replace the channel IDs used by the\n * mux clients with a unique channel ID because the mux clients might\n * use conflicting channel IDs.\n * - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and\n * SSH2_MSG_CHANNEL_OPEN_CONFIRMATION messages, create a local\n * SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID\n * with the newly allocated channel ID.\n * 2) Upstream messages are received by matching SSH_CHANNEL_MUX_PROXY\n * channels and procesed by channel_proxy_upstream(). The local channel ID\n * is then translated back to the original mux client ID.\n * 3) In both cases we need to keep track of matching SSH2_MSG_CHANNEL_CLOSE\n * messages so we can clean up SSH_CHANNEL_MUX_PROXY channels.\n * 4) The SSH_CHANNEL_MUX_PROXY channels also need to closed when the\n * downstream mux client are removed.\n * 5) Handling SSH2_MSG_CHANNEL_OPEN messages from the upstream server\n * requires more work, because they are not addressed to a specific\n * channel. E.g. client_request_forwarded_tcpip() needs to figure\n * out whether the request is addressed to the local client or a\n * specific downstream client based on the listen-address/port.\n * 6) Agent and X11-Forwarding have a similar problem and are currenly\n * not supported as the matching session/channel cannot be identified\n * easily.\n */\n\n/*\n * receive packets from downstream mux clients:\n * channel callback fired on read from mux client, creates\n * SSH_CHANNEL_MUX_PROXY channels and translates channel IDs\n * on channel creation.\n */\nint\nchannel_proxy_downstream(Channel *downstream)\n{\n\tChannel *c = NULL;\n\tstruct ssh *ssh = active_state;\n\tstruct sshbuf *original = NULL, *modified = NULL;\n\tconst u_char *cp;\n\tchar *ctype = NULL, *listen_host = NULL;\n\tu_char type;\n\tsize_t have;\n\tint ret = -1, r, idx;\n\tu_int id, remote_id, listen_port;\n\n\t/* sshbuf_dump(&downstream->input, stderr); */\n\tif ((r = sshbuf_get_string_direct(&downstream->input, &cp, &have))\n\t != 0) {\n\t\terror(\"%s: malformed message: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\tif (have < 2) {\n\t\terror(\"%s: short message\", __func__);\n\t\treturn -1;\n\t}\n\ttype = cp[1];\n\t/* skip padlen + type */\n\tcp += 2;\n\thave -= 2;\n\tif (ssh_packet_log_type(type))\n\t\tdebug3(\"%s: channel %u: down->up: type %u\", __func__,\n\t\t downstream->self, type);\n\n\tswitch (type) {\n\tcase SSH2_MSG_CHANNEL_OPEN:\n\t\tif ((original = sshbuf_from(cp, have)) == NULL ||\n\t\t (modified = sshbuf_new()) == NULL) {\n\t\t\terror(\"%s: alloc\", __func__);\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 ||\n\t\t (r = sshbuf_get_u32(original, &id)) != 0) {\n\t\t\terror(\"%s: parse error %s\", __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t\tc = channel_new(\"mux proxy\", SSH_CHANNEL_MUX_PROXY,\n\t\t -1, -1, -1, 0, 0, 0, ctype, 1);\n\t\tc->mux_ctx = downstream;\t/* point to mux client */\n\t\tc->mux_downstream_id = id;\t/* original downstream id */\n\t\tif ((r = sshbuf_put_cstring(modified, ctype)) != 0 ||\n\t\t (r = sshbuf_put_u32(modified, c->self)) != 0 ||\n\t\t (r = sshbuf_putb(modified, original)) != 0) {\n\t\t\terror(\"%s: compose error %s\", __func__, ssh_err(r));\n\t\t\tchannel_free(c);\n\t\t\tgoto out;\n\t\t}\n\t\tbreak;\n\tcase SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:\n\t\t/*\n\t\t * Almost the same as SSH2_MSG_CHANNEL_OPEN, except then we\n\t\t * need to parse 'remote_id' instead of 'ctype'.\n\t\t */\n\t\tif ((original = sshbuf_from(cp, have)) == NULL ||\n\t\t (modified = sshbuf_new()) == NULL) {\n\t\t\terror(\"%s: alloc\", __func__);\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_u32(original, &remote_id)) != 0 ||\n\t\t (r = sshbuf_get_u32(original, &id)) != 0) {\n\t\t\terror(\"%s: parse error %s\", __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t\tc = channel_new(\"mux proxy\", SSH_CHANNEL_MUX_PROXY,\n\t\t -1, -1, -1, 0, 0, 0, \"mux-down-connect\", 1);\n\t\tc->mux_ctx = downstream;\t/* point to mux client */\n\t\tc->mux_downstream_id = id;\n\t\tc->remote_id = remote_id;\n\t\tif ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||\n\t\t (r = sshbuf_put_u32(modified, c->self)) != 0 ||\n\t\t (r = sshbuf_putb(modified, original)) != 0) {\n\t\t\terror(\"%s: compose error %s\", __func__, ssh_err(r));\n\t\t\tchannel_free(c);\n\t\t\tgoto out;\n\t\t}\n\t\tbreak;\n\tcase SSH2_MSG_GLOBAL_REQUEST:\n\t\tif ((original = sshbuf_from(cp, have)) == NULL) {\n\t\t\terror(\"%s: alloc\", __func__);\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) {\n\t\t\terror(\"%s: parse error %s\", __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t\tif (strcmp(ctype, \"tcpip-forward\") != 0) {\n\t\t\terror(\"%s: unsupported request %s\", __func__, ctype);\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = sshbuf_get_u8(original, NULL)) != 0 ||\n\t\t (r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 ||\n\t\t (r = sshbuf_get_u32(original, &listen_port)) != 0) {\n\t\t\terror(\"%s: parse error %s\", __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t\tif (listen_port > 65535) {\n\t\t\terror(\"%s: tcpip-forward for %s: bad port %u\",\n\t\t\t __func__, listen_host, listen_port);\n\t\t\tgoto out;\n\t\t}\n\t\t/* Record that connection to this host/port is permitted. */\n\t\tpermitted_opens = xreallocarray(permitted_opens,\n\t\t num_permitted_opens + 1, sizeof(*permitted_opens));\n\t\tidx = num_permitted_opens++;\n\t\tpermitted_opens[idx].host_to_connect = xstrdup(\"\");\n\t\tpermitted_opens[idx].port_to_connect = -1;\n\t\tpermitted_opens[idx].listen_host = listen_host;\n\t\tpermitted_opens[idx].listen_port = (int)listen_port;\n\t\tpermitted_opens[idx].downstream = downstream;\n\t\tlisten_host = NULL;\n\t\tbreak;\n\tcase SSH2_MSG_CHANNEL_CLOSE:\n\t\tif (have < 4)\n\t\t\tbreak;\n\t\tremote_id = PEEK_U32(cp);\n\t\tif ((c = channel_by_remote_id(remote_id)) != NULL) {\n\t\t\tif (c->flags & CHAN_CLOSE_RCVD)\n\t\t\t\tchannel_free(c);\n\t\t\telse\n\t\t\t\tc->flags |= CHAN_CLOSE_SENT;\n\t\t}\n\t\tbreak;\n\t}\n\tif (modified) {\n\t\tif ((r = sshpkt_start(ssh, type)) != 0 ||\n\t\t (r = sshpkt_putb(ssh, modified)) != 0 ||\n\t\t (r = sshpkt_send(ssh)) != 0) {\n\t\t\terror(\"%s: send %s\", __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t} else {\n\t\tif ((r = sshpkt_start(ssh, type)) != 0 ||\n\t\t (r = sshpkt_put(ssh, cp, have)) != 0 ||\n\t\t (r = sshpkt_send(ssh)) != 0) {\n\t\t\terror(\"%s: send %s\", __func__, ssh_err(r));\n\t\t\tgoto out;\n\t\t}\n\t}\n\tret = 0;\n out:\n\tfree(ctype);\n\tfree(listen_host);\n\tsshbuf_free(original);\n\tsshbuf_free(modified);\n\treturn ret;\n}\n\n/*\n * receive packets from upstream server and de-multiplex packets\n * to correct downstream:\n * implemented as a helper for channel input handlers,\n * replaces local (proxy) channel ID with downstream channel ID.\n */\nint\nchannel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt)\n{\n\tstruct ssh *ssh = active_state;\n\tstruct sshbuf *b = NULL;\n\tChannel *downstream;\n\tconst u_char *cp = NULL;\n\tsize_t len;\n\tint r;\n\n\t/*\n\t * When receiving packets from the peer we need to check whether we\n\t * need to forward the packets to the mux client. In this case we\n\t * restore the orignal channel id and keep track of CLOSE messages,\n\t * so we can cleanup the channel.\n\t */\n\tif (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY)\n\t\treturn 0;\n\tif ((downstream = c->mux_ctx) == NULL)\n\t\treturn 0;\n\tswitch (type) {\n\tcase SSH2_MSG_CHANNEL_CLOSE:\n\tcase SSH2_MSG_CHANNEL_DATA:\n\tcase SSH2_MSG_CHANNEL_EOF:\n\tcase SSH2_MSG_CHANNEL_EXTENDED_DATA:\n\tcase SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:\n\tcase SSH2_MSG_CHANNEL_OPEN_FAILURE:\n\tcase SSH2_MSG_CHANNEL_WINDOW_ADJUST:\n\tcase SSH2_MSG_CHANNEL_SUCCESS:\n\tcase SSH2_MSG_CHANNEL_FAILURE:\n\tcase SSH2_MSG_CHANNEL_REQUEST:\n\t\tbreak;\n\tdefault:\n\t\tdebug2(\"%s: channel %u: unsupported type %u\", __func__,\n\t\t c->self, type);\n\t\treturn 0;\n\t}\n\tif ((b = sshbuf_new()) == NULL) {\n\t\terror(\"%s: alloc reply\", __func__);\n\t\tgoto out;\n\t}\n\t/* get remaining payload (after id) */\n\tcp = sshpkt_ptr(ssh, &len);\n\tif (cp == NULL) {\n\t\terror(\"%s: no packet\", __func__);\n\t\tgoto out;\n\t}\n\t/* translate id and send to muxclient */\n\tif ((r = sshbuf_put_u8(b, 0)) != 0 ||\t/* padlen */\n\t (r = sshbuf_put_u8(b, type)) != 0 ||\n\t (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||\n\t (r = sshbuf_put(b, cp, len)) != 0 ||\n\t (r = sshbuf_put_stringb(&downstream->output, b)) != 0) {\n\t\terror(\"%s: compose for muxclient %s\", __func__, ssh_err(r));\n\t\tgoto out;\n\t}\n\t/* sshbuf_dump(b, stderr); */\n\tif (ssh_packet_log_type(type))\n\t\tdebug3(\"%s: channel %u: up->down: type %u\", __func__, c->self,\n\t\t type);\n out:\n\t/* update state */\n\tswitch (type) {\n\tcase SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:\n\t\t/* record remote_id for SSH2_MSG_CHANNEL_CLOSE */\n\t\tif (cp && len > 4)\n\t\t\tc->remote_id = PEEK_U32(cp);\n\t\tbreak;\n\tcase SSH2_MSG_CHANNEL_CLOSE:\n\t\tif (c->flags & CHAN_CLOSE_SENT)\n\t\t\tchannel_free(c);\n\t\telse\n\t\t\tc->flags |= CHAN_CLOSE_RCVD;\n\t\tbreak;\n\t}\n\tsshbuf_free(b);\n\treturn 1;\n}\n\n/* -- protocol input */\n\n/* ARGSUSED */\nint\nchannel_input_data(int type, u_int32_t seq, void *ctxt)\n{\n\tint id;\n\tconst u_char *data;\n\tu_int data_len, win_len;\n\tChannel *c;\n\n\t/* Get the channel number and verify it. */\n\tid = packet_get_int();\n\tc = channel_lookup(id);\n\tif (c == NULL)\n\t\tpacket_disconnect(\"Received data for nonexistent channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\n\t/* Ignore any data for non-open channels (might happen on close) */\n\tif (c->type != SSH_CHANNEL_OPEN &&\n\t c->type != SSH_CHANNEL_X11_OPEN)\n\t\treturn 0;\n\n\t/* Get the data. */\n\tdata = packet_get_string_ptr(&data_len);\n\twin_len = data_len;\n\tif (c->datagram)\n\t\twin_len += 4; /* string length header */\n\n\t/*\n\t * Ignore data for protocol > 1.3 if output end is no longer open.\n\t * For protocol 2 the sending side is reducing its window as it sends\n\t * data, so we must 'fake' consumption of the data in order to ensure\n\t * that window updates are sent back. Otherwise the connection might\n\t * deadlock.\n\t */\n\tif (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) {\n\t\tif (compat20) {\n\t\t\tc->local_window -= win_len;\n\t\t\tc->local_consumed += win_len;\n\t\t}\n\t\treturn 0;\n\t}\n\n\tif (compat20) {\n\t\tif (win_len > c->local_maxpacket) {\n\t\t\tlogit(\"channel %d: rcvd big packet %d, maxpack %d\",\n\t\t\t c->self, win_len, c->local_maxpacket);\n\t\t}\n\t\tif (win_len > c->local_window) {\n\t\t\tlogit(\"channel %d: rcvd too much data %d, win %d\",\n\t\t\t c->self, win_len, c->local_window);\n\t\t\treturn 0;\n\t\t}\n\t\tc->local_window -= win_len;\n\t}\n\tif (c->datagram)\n\t\tbuffer_put_string(&c->output, data, data_len);\n\telse\n\t\tbuffer_append(&c->output, data, data_len);\n\tpacket_check_eom();\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_extended_data(int type, u_int32_t seq, void *ctxt)\n{\n\tint id;\n\tchar *data;\n\tu_int data_len, tcode;\n\tChannel *c;\n\n\t/* Get the channel number and verify it. */\n\tid = packet_get_int();\n\tc = channel_lookup(id);\n\n\tif (c == NULL)\n\t\tpacket_disconnect(\"Received extended_data for bad channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tif (c->type != SSH_CHANNEL_OPEN) {\n\t\tlogit(\"channel %d: ext data for non open\", id);\n\t\treturn 0;\n\t}\n\tif (c->flags & CHAN_EOF_RCVD) {\n\t\tif (datafellows & SSH_BUG_EXTEOF)\n\t\t\tdebug(\"channel %d: accepting ext data after eof\", id);\n\t\telse\n\t\t\tpacket_disconnect(\"Received extended_data after EOF \"\n\t\t\t \"on channel %d.\", id);\n\t}\n\ttcode = packet_get_int();\n\tif (c->efd == -1 ||\n\t c->extended_usage != CHAN_EXTENDED_WRITE ||\n\t tcode != SSH2_EXTENDED_DATA_STDERR) {\n\t\tlogit(\"channel %d: bad ext data\", c->self);\n\t\treturn 0;\n\t}\n\tdata = packet_get_string(&data_len);\n\tpacket_check_eom();\n\tif (data_len > c->local_window) {\n\t\tlogit(\"channel %d: rcvd too much extended_data %d, win %d\",\n\t\t c->self, data_len, c->local_window);\n\t\tfree(data);\n\t\treturn 0;\n\t}\n\tdebug2(\"channel %d: rcvd ext data %d\", c->self, data_len);\n\tc->local_window -= data_len;\n\tbuffer_append(&c->extended, data, data_len);\n\tfree(data);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_ieof(int type, u_int32_t seq, void *ctxt)\n{\n\tint id;\n\tChannel *c;\n\n\tid = packet_get_int();\n\tpacket_check_eom();\n\tc = channel_lookup(id);\n\tif (c == NULL)\n\t\tpacket_disconnect(\"Received ieof for nonexistent channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tchan_rcvd_ieof(c);\n\n\t/* XXX force input close */\n\tif (c->force_drain && c->istate == CHAN_INPUT_OPEN) {\n\t\tdebug(\"channel %d: FORCE input drain\", c->self);\n\t\tc->istate = CHAN_INPUT_WAIT_DRAIN;\n\t\tif (buffer_len(&c->input) == 0)\n\t\t\tchan_ibuf_empty(c);\n\t}\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_close(int type, u_int32_t seq, void *ctxt)\n{\n\tint id;\n\tChannel *c;\n\n\tid = packet_get_int();\n\tpacket_check_eom();\n\tc = channel_lookup(id);\n\tif (c == NULL)\n\t\tpacket_disconnect(\"Received close for nonexistent channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\t/*\n\t * Send a confirmation that we have closed the channel and no more\n\t * data is coming for it.\n\t */\n\tpacket_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);\n\tpacket_put_int(c->remote_id);\n\tpacket_send();\n\n\t/*\n\t * If the channel is in closed state, we have sent a close request,\n\t * and the other side will eventually respond with a confirmation.\n\t * Thus, we cannot free the channel here, because then there would be\n\t * no-one to receive the confirmation. The channel gets freed when\n\t * the confirmation arrives.\n\t */\n\tif (c->type != SSH_CHANNEL_CLOSED) {\n\t\t/*\n\t\t * Not a closed channel - mark it as draining, which will\n\t\t * cause it to be freed later.\n\t\t */\n\t\tbuffer_clear(&c->input);\n\t\tc->type = SSH_CHANNEL_OUTPUT_DRAINING;\n\t}\n\treturn 0;\n}\n\n/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */\n/* ARGSUSED */\nint\nchannel_input_oclose(int type, u_int32_t seq, void *ctxt)\n{\n\tint id = packet_get_int();\n\tChannel *c = channel_lookup(id);\n\n\tif (c == NULL)\n\t\tpacket_disconnect(\"Received oclose for nonexistent channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tpacket_check_eom();\n\tchan_rcvd_oclose(c);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)\n{\n\tint id = packet_get_int();\n\tChannel *c = channel_lookup(id);\n\n\tif (c == NULL)\n\t\tpacket_disconnect(\"Received close confirmation for \"\n\t\t \"out-of-range channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tpacket_check_eom();\n\tif (c->type != SSH_CHANNEL_CLOSED && c->type != SSH_CHANNEL_ABANDONED)\n\t\tpacket_disconnect(\"Received close confirmation for \"\n\t\t \"non-closed channel %d (type %d).\", id, c->type);\n\tchannel_free(c);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)\n{\n\tint id, remote_id;\n\tChannel *c;\n\n\tid = packet_get_int();\n\tc = channel_lookup(id);\n\n\tif (c==NULL)\n\t\tpacket_disconnect(\"Received open confirmation for \"\n\t\t \"unknown channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tif (c->type != SSH_CHANNEL_OPENING)\n\t\tpacket_disconnect(\"Received open confirmation for \"\n\t\t \"non-opening channel %d.\", id);\n\tremote_id = packet_get_int();\n\t/* Record the remote channel number and mark that the channel is now open. */\n\tc->remote_id = remote_id;\n\tc->type = SSH_CHANNEL_OPEN;\n\n\tif (compat20) {\n\t\tc->remote_window = packet_get_int();\n\t\tc->remote_maxpacket = packet_get_int();\n\t\tif (c->open_confirm) {\n\t\t\tdebug2(\"callback start\");\n\t\t\tc->open_confirm(c->self, 1, c->open_confirm_ctx);\n\t\t\tdebug2(\"callback done\");\n\t\t}\n\t\tdebug2(\"channel %d: open confirm rwindow %u rmax %u\", c->self,\n\t\t c->remote_window, c->remote_maxpacket);\n\t}\n\tpacket_check_eom();\n\treturn 0;\n}\n\nstatic char *\nreason2txt(int reason)\n{\n\tswitch (reason) {\n\tcase SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED:\n\t\treturn \"administratively prohibited\";\n\tcase SSH2_OPEN_CONNECT_FAILED:\n\t\treturn \"connect failed\";\n\tcase SSH2_OPEN_UNKNOWN_CHANNEL_TYPE:\n\t\treturn \"unknown channel type\";\n\tcase SSH2_OPEN_RESOURCE_SHORTAGE:\n\t\treturn \"resource shortage\";\n\t}\n\treturn \"unknown reason\";\n}\n\n/* ARGSUSED */\nint\nchannel_input_open_failure(int type, u_int32_t seq, void *ctxt)\n{\n\tint id, reason;\n\tchar *msg = NULL, *lang = NULL;\n\tChannel *c;\n\n\tid = packet_get_int();\n\tc = channel_lookup(id);\n\n\tif (c==NULL)\n\t\tpacket_disconnect(\"Received open failure for \"\n\t\t \"unknown channel %d.\", id);\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tif (c->type != SSH_CHANNEL_OPENING)\n\t\tpacket_disconnect(\"Received open failure for \"\n\t\t \"non-opening channel %d.\", id);\n\tif (compat20) {\n\t\treason = packet_get_int();\n\t\tif (!(datafellows & SSH_BUG_OPENFAILURE)) {\n\t\t\tmsg = packet_get_string(NULL);\n\t\t\tlang = packet_get_string(NULL);\n\t\t}\n\t\tlogit(\"channel %d: open failed: %s%s%s\", id,\n\t\t reason2txt(reason), msg ? \": \": \"\", msg ? msg : \"\");\n\t\tfree(msg);\n\t\tfree(lang);\n\t\tif (c->open_confirm) {\n\t\t\tdebug2(\"callback start\");\n\t\t\tc->open_confirm(c->self, 0, c->open_confirm_ctx);\n\t\t\tdebug2(\"callback done\");\n\t\t}\n\t}\n\tpacket_check_eom();\n\t/* Schedule the channel for cleanup/deletion. */\n\tchan_mark_dead(c);\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_window_adjust(int type, u_int32_t seq, void *ctxt)\n{\n\tChannel *c;\n\tint id;\n\tu_int adjust, tmp;\n\n\tif (!compat20)\n\t\treturn 0;\n\n\t/* Get the channel number and verify it. */\n\tid = packet_get_int();\n\tc = channel_lookup(id);\n\n\tif (c == NULL) {\n\t\tlogit(\"Received window adjust for non-open channel %d.\", id);\n\t\treturn 0;\n\t}\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tadjust = packet_get_int();\n\tpacket_check_eom();\n\tdebug2(\"channel %d: rcvd adjust %u\", id, adjust);\n\tif ((tmp = c->remote_window + adjust) < c->remote_window)\n\t\tfatal(\"channel %d: adjust %u overflows remote window %u\",\n\t\t id, adjust, c->remote_window);\n\tc->remote_window = tmp;\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_port_open(int type, u_int32_t seq, void *ctxt)\n{\n\tChannel *c = NULL;\n\tu_short host_port;\n\tchar *host, *originator_string;\n\tint remote_id;\n\n\tremote_id = packet_get_int();\n\thost = packet_get_string(NULL);\n\thost_port = packet_get_int();\n\n\tif (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {\n\t\toriginator_string = packet_get_string(NULL);\n\t} else {\n\t\toriginator_string = xstrdup(\"unknown (remote did not supply name)\");\n\t}\n\tpacket_check_eom();\n\tc = channel_connect_to_port(host, host_port,\n\t \"connected socket\", originator_string, NULL, NULL);\n\tfree(originator_string);\n\tfree(host);\n\tif (c == NULL) {\n\t\tpacket_start(SSH_MSG_CHANNEL_OPEN_FAILURE);\n\t\tpacket_put_int(remote_id);\n\t\tpacket_send();\n\t} else\n\t\tc->remote_id = remote_id;\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nchannel_input_status_confirm(int type, u_int32_t seq, void *ctxt)\n{\n\tChannel *c;\n\tstruct channel_confirm *cc;\n\tint id;\n\n\t/* Reset keepalive timeout */\n\tpacket_set_alive_timeouts(0);\n\n\tid = packet_get_int();\n\tdebug2(\"channel_input_status_confirm: type %d id %d\", type, id);\n\n\tif ((c = channel_lookup(id)) == NULL) {\n\t\tlogit(\"channel_input_status_confirm: %d: unknown\", id);\n\t\treturn 0;\n\t}\t\n\tif (channel_proxy_upstream(c, type, seq, ctxt))\n\t\treturn 0;\n\tpacket_check_eom();\n\tif ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)\n\t\treturn 0;\n\tcc->cb(type, c, cc->ctx);\n\tTAILQ_REMOVE(&c->status_confirms, cc, entry);\n\texplicit_bzero(cc, sizeof(*cc));\n\tfree(cc);\n\treturn 0;\n}\n\n/* -- tcp forwarding */\n\nvoid\nchannel_set_af(int af)\n{\n\tIPv4or6 = af;\n}\n\n\n/*\n * Determine whether or not a port forward listens to loopback, the\n * specified address or wildcard. On the client, a specified bind\n * address will always override gateway_ports. On the server, a\n * gateway_ports of 1 (``yes'') will override the client's specification\n * and force a wildcard bind, whereas a value of 2 (``clientspecified'')\n * will bind to whatever address the client asked for.\n *\n * Special-case listen_addrs are:\n *\n * \"0.0.0.0\" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR\n * \"\" (empty string), \"*\" -> wildcard v4/v6\n * \"localhost\" -> loopback v4/v6\n * \"127.0.0.1\" / \"::1\" -> accepted even if gateway_ports isn't set\n */\nstatic const char *\nchannel_fwd_bind_addr(const char *listen_addr, int *wildcardp,\n int is_client, struct ForwardOptions *fwd_opts)\n{\n\tconst char *addr = NULL;\n\tint wildcard = 0;\n\n\tif (listen_addr == NULL) {\n\t\t/* No address specified: default to gateway_ports setting */\n\t\tif (fwd_opts->gateway_ports)\n\t\t\twildcard = 1;\n\t} else if (fwd_opts->gateway_ports || is_client) {\n\t\tif (((datafellows & SSH_OLD_FORWARD_ADDR) &&\n\t\t strcmp(listen_addr, \"0.0.0.0\") == 0 && is_client == 0) ||\n\t\t *listen_addr == '\\0' || strcmp(listen_addr, \"*\") == 0 ||\n\t\t (!is_client && fwd_opts->gateway_ports == 1)) {\n\t\t\twildcard = 1;\n\t\t\t/*\n\t\t\t * Notify client if they requested a specific listen\n\t\t\t * address and it was overridden.\n\t\t\t */\n\t\t\tif (*listen_addr != '\\0' &&\n\t\t\t strcmp(listen_addr, \"0.0.0.0\") != 0 &&\n\t\t\t strcmp(listen_addr, \"*\") != 0) {\n\t\t\t\tpacket_send_debug(\"Forwarding listen address \"\n\t\t\t\t \"\\\"%s\\\" overridden by server \"\n\t\t\t\t \"GatewayPorts\", listen_addr);\n\t\t\t}\n\t\t} else if (strcmp(listen_addr, \"localhost\") != 0 ||\n\t\t strcmp(listen_addr, \"127.0.0.1\") == 0 ||\n\t\t strcmp(listen_addr, \"::1\") == 0) {\n\t\t\t/* Accept localhost address when GatewayPorts=yes */\n\t\t\taddr = listen_addr;\n\t\t}\n\t} else if (strcmp(listen_addr, \"127.0.0.1\") == 0 ||\n\t strcmp(listen_addr, \"::1\") == 0) {\n\t\t/*\n\t\t * If a specific IPv4/IPv6 localhost address has been\n\t\t * requested then accept it even if gateway_ports is in\n\t\t * effect. This allows the client to prefer IPv4 or IPv6.\n\t\t */\n\t\taddr = listen_addr;\n\t}\n\tif (wildcardp != NULL)\n\t\t*wildcardp = wildcard;\n\treturn addr;\n}\n\nstatic int\nchannel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,\n int *allocated_listen_port, struct ForwardOptions *fwd_opts)\n{\n\tChannel *c;\n\tint sock, r, success = 0, wildcard = 0, is_client;\n\tstruct addrinfo hints, *ai, *aitop;\n\tconst char *host, *addr;\n\tchar ntop[NI_MAXHOST], strport[NI_MAXSERV];\n\tin_port_t *lport_p;\n\n\tis_client = (type == SSH_CHANNEL_PORT_LISTENER);\n\n\tif (is_client && fwd->connect_path != NULL) {\n\t\thost = fwd->connect_path;\n\t} else {\n\t\thost = (type == SSH_CHANNEL_RPORT_LISTENER) ?\n\t\t fwd->listen_host : fwd->connect_host;\n\t\tif (host == NULL) {\n\t\t\terror(\"No forward host name.\");\n\t\t\treturn 0;\n\t\t}\n\t\tif (strlen(host) >= NI_MAXHOST) {\n\t\t\terror(\"Forward host name too long.\");\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* Determine the bind address, cf. channel_fwd_bind_addr() comment */\n\taddr = channel_fwd_bind_addr(fwd->listen_host, &wildcard,\n\t is_client, fwd_opts);\n\tdebug3(\"%s: type %d wildcard %d addr %s\", __func__,\n\t type, wildcard, (addr == NULL) ? \"NULL\" : addr);\n\n\t/*\n\t * getaddrinfo returns a loopback address if the hostname is\n\t * set to NULL and hints.ai_flags is not AI_PASSIVE\n\t */\n\tmemset(&hints, 0, sizeof(hints));\n\thints.ai_family = IPv4or6;\n\thints.ai_flags = wildcard ? AI_PASSIVE : 0;\n\thints.ai_socktype = SOCK_STREAM;\n\tsnprintf(strport, sizeof strport, \"%d\", fwd->listen_port);\n\tif ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {\n\t\tif (addr == NULL) {\n\t\t\t/* This really shouldn't happen */\n\t\t\tpacket_disconnect(\"getaddrinfo: fatal error: %s\",\n\t\t\t ssh_gai_strerror(r));\n\t\t} else {\n\t\t\terror(\"%s: getaddrinfo(%.64s): %s\", __func__, addr,\n\t\t\t ssh_gai_strerror(r));\n\t\t}\n\t\treturn 0;\n\t}\n\tif (allocated_listen_port != NULL)\n\t\t*allocated_listen_port = 0;\n\tfor (ai = aitop; ai; ai = ai->ai_next) {\n\t\tswitch (ai->ai_family) {\n\t\tcase AF_INET:\n\t\t\tlport_p = &((struct sockaddr_in *)ai->ai_addr)->\n\t\t\t sin_port;\n\t\t\tbreak;\n\t\tcase AF_INET6:\n\t\t\tlport_p = &((struct sockaddr_in6 *)ai->ai_addr)->\n\t\t\t sin6_port;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcontinue;\n\t\t}\n\t\t/*\n\t\t * If allocating a port for -R forwards, then use the\n\t\t * same port for all address families.\n\t\t */\n\t\tif (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 &&\n\t\t allocated_listen_port != NULL && *allocated_listen_port > 0)\n\t\t\t*lport_p = htons(*allocated_listen_port);\n\n\t\tif (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),\n\t\t strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {\n\t\t\terror(\"%s: getnameinfo failed\", __func__);\n\t\t\tcontinue;\n\t\t}\n\t\t/* Create a port to listen for the host. */\n\t\tsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);\n\t\tif (sock < 0) {\n\t\t\t/* this is no error since kernel may not support ipv6 */\n\t\t\tverbose(\"socket: %.100s\", strerror(errno));\n\t\t\tcontinue;\n\t\t}\n\n\t\tchannel_set_reuseaddr(sock);\n\t\tif (ai->ai_family == AF_INET6)\n\t\t\tsock_set_v6only(sock);\n\n\t\tdebug(\"Local forwarding listening on %s port %s.\",\n\t\t ntop, strport);\n\n\t\t/* Bind the socket to the address. */\n\t\tif (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {\n\t\t\t/* address can be in use ipv6 address is already bound */\n\t\t\tif (!ai->ai_next)\n\t\t\t\terror(\"bind: %.100s\", strerror(errno));\n\t\t\telse\n\t\t\t\tverbose(\"bind: %.100s\", strerror(errno));\n\n\t\t\tclose(sock);\n\t\t\tcontinue;\n\t\t}\n\t\t/* Start listening for connections on the socket. */\n\t\tif (listen(sock, SSH_LISTEN_BACKLOG) < 0) {\n\t\t\terror(\"listen: %.100s\", strerror(errno));\n\t\t\tclose(sock);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/*\n\t\t * fwd->listen_port == 0 requests a dynamically allocated port -\n\t\t * record what we got.\n\t\t */\n\t\tif (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 &&\n\t\t allocated_listen_port != NULL &&\n\t\t *allocated_listen_port == 0) {\n\t\t\t*allocated_listen_port = get_local_port(sock);\n\t\t\tdebug(\"Allocated listen port %d\",\n\t\t\t *allocated_listen_port);\n\t\t}\n\n\t\t/* Allocate a channel number for the socket. */\n\t\tc = channel_new(\"port listener\", type, sock, sock, -1,\n\t\t CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,\n\t\t 0, \"port listener\", 1);\n\t\tc->path = xstrdup(host);\n\t\tc->host_port = fwd->connect_port;\n\t\tc->listening_addr = addr == NULL ? NULL : xstrdup(addr);\n\t\tif (fwd->listen_port == 0 && allocated_listen_port != NULL &&\n\t\t !(datafellows & SSH_BUG_DYNAMIC_RPORT))\n\t\t\tc->listening_port = *allocated_listen_port;\n\t\telse\n\t\t\tc->listening_port = fwd->listen_port;\n\t\tsuccess = 1;\n\t}\n\tif (success == 0)\n\t\terror(\"%s: cannot listen to port: %d\", __func__,\n\t\t fwd->listen_port);\n\tfreeaddrinfo(aitop);\n\treturn success;\n}\n\nstatic int\nchannel_setup_fwd_listener_streamlocal(int type, struct Forward *fwd,\n struct ForwardOptions *fwd_opts)\n{\n\tstruct sockaddr_un sunaddr;\n\tconst char *path;\n\tChannel *c;\n\tint port, sock;\n\tmode_t omask;\n\n\tswitch (type) {\n\tcase SSH_CHANNEL_UNIX_LISTENER:\n\t\tif (fwd->connect_path != NULL) {\n\t\t\tif (strlen(fwd->connect_path) > sizeof(sunaddr.sun_path)) {\n\t\t\t\terror(\"Local connecting path too long: %s\",\n\t\t\t\t fwd->connect_path);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tpath = fwd->connect_path;\n\t\t\tport = PORT_STREAMLOCAL;\n\t\t} else {\n\t\t\tif (fwd->connect_host == NULL) {\n\t\t\t\terror(\"No forward host name.\");\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (strlen(fwd->connect_host) >= NI_MAXHOST) {\n\t\t\t\terror(\"Forward host name too long.\");\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tpath = fwd->connect_host;\n\t\t\tport = fwd->connect_port;\n\t\t}\n\t\tbreak;\n\tcase SSH_CHANNEL_RUNIX_LISTENER:\n\t\tpath = fwd->listen_path;\n\t\tport = PORT_STREAMLOCAL;\n\t\tbreak;\n\tdefault:\n\t\terror(\"%s: unexpected channel type %d\", __func__, type);\n\t\treturn 0;\n\t}\n\n\tif (fwd->listen_path == NULL) {\n\t\terror(\"No forward path name.\");\n\t\treturn 0;\n\t}\n\tif (strlen(fwd->listen_path) > sizeof(sunaddr.sun_path)) {\n\t\terror(\"Local listening path too long: %s\", fwd->listen_path);\n\t\treturn 0;\n\t}\n\n\tdebug3(\"%s: type %d path %s\", __func__, type, fwd->listen_path);\n\n\t/* Start a Unix domain listener. */\n\tomask = umask(fwd_opts->streamlocal_bind_mask);\n\tsock = unix_listener(fwd->listen_path, SSH_LISTEN_BACKLOG,\n\t fwd_opts->streamlocal_bind_unlink);\n\tumask(omask);\n\tif (sock < 0)\n\t\treturn 0;\n\n\tdebug(\"Local forwarding listening on path %s.\", fwd->listen_path);\n\n\t/* Allocate a channel number for the socket. */\n\tc = channel_new(\"unix listener\", type, sock, sock, -1,\n\t CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,\n\t 0, \"unix listener\", 1);\n\tc->path = xstrdup(path);\n\tc->host_port = port;\n\tc->listening_port = PORT_STREAMLOCAL;\n\tc->listening_addr = xstrdup(fwd->listen_path);\n\treturn 1;\n}\n\nstatic int\nchannel_cancel_rport_listener_tcpip(const char *host, u_short port)\n{\n\tu_int i;\n\tint found = 0;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tChannel *c = channels[i];\n\t\tif (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)\n\t\t\tcontinue;\n\t\tif (strcmp(c->path, host) == 0 && c->listening_port == port) {\n\t\t\tdebug2(\"%s: close channel %d\", __func__, i);\n\t\t\tchannel_free(c);\n\t\t\tfound = 1;\n\t\t}\n\t}\n\n\treturn (found);\n}\n\nstatic int\nchannel_cancel_rport_listener_streamlocal(const char *path)\n{\n\tu_int i;\n\tint found = 0;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tChannel *c = channels[i];\n\t\tif (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER)\n\t\t\tcontinue;\n\t\tif (c->path == NULL)\n\t\t\tcontinue;\n\t\tif (strcmp(c->path, path) == 0) {\n\t\t\tdebug2(\"%s: close channel %d\", __func__, i);\n\t\t\tchannel_free(c);\n\t\t\tfound = 1;\n\t\t}\n\t}\n\n\treturn (found);\n}\n\nint\nchannel_cancel_rport_listener(struct Forward *fwd)\n{\n\tif (fwd->listen_path != NULL)\n\t\treturn channel_cancel_rport_listener_streamlocal(fwd->listen_path);\n\telse\n\t\treturn channel_cancel_rport_listener_tcpip(fwd->listen_host, fwd->listen_port);\n}\n\nstatic int\nchannel_cancel_lport_listener_tcpip(const char *lhost, u_short lport,\n int cport, struct ForwardOptions *fwd_opts)\n{\n\tu_int i;\n\tint found = 0;\n\tconst char *addr = channel_fwd_bind_addr(lhost, NULL, 1, fwd_opts);\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tChannel *c = channels[i];\n\t\tif (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER)\n\t\t\tcontinue;\n\t\tif (c->listening_port != lport)\n\t\t\tcontinue;\n\t\tif (cport == CHANNEL_CANCEL_PORT_STATIC) {\n\t\t\t/* skip dynamic forwardings */\n\t\t\tif (c->host_port == 0)\n\t\t\t\tcontinue;\n\t\t} else {\n\t\t\tif (c->host_port != cport)\n\t\t\t\tcontinue;\n\t\t}\n\t\tif ((c->listening_addr == NULL && addr != NULL) ||\n\t\t (c->listening_addr != NULL && addr == NULL))\n\t\t\tcontinue;\n\t\tif (addr == NULL || strcmp(c->listening_addr, addr) == 0) {\n\t\t\tdebug2(\"%s: close channel %d\", __func__, i);\n\t\t\tchannel_free(c);\n\t\t\tfound = 1;\n\t\t}\n\t}\n\n\treturn (found);\n}\n\nstatic int\nchannel_cancel_lport_listener_streamlocal(const char *path)\n{\n\tu_int i;\n\tint found = 0;\n\n\tif (path == NULL) {\n\t\terror(\"%s: no path specified.\", __func__);\n\t\treturn 0;\n\t}\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tChannel *c = channels[i];\n\t\tif (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER)\n\t\t\tcontinue;\n\t\tif (c->listening_addr == NULL)\n\t\t\tcontinue;\n\t\tif (strcmp(c->listening_addr, path) == 0) {\n\t\t\tdebug2(\"%s: close channel %d\", __func__, i);\n\t\t\tchannel_free(c);\n\t\t\tfound = 1;\n\t\t}\n\t}\n\n\treturn (found);\n}\n\nint\nchannel_cancel_lport_listener(struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts)\n{\n\tif (fwd->listen_path != NULL)\n\t\treturn channel_cancel_lport_listener_streamlocal(fwd->listen_path);\n\telse\n\t\treturn channel_cancel_lport_listener_tcpip(fwd->listen_host, fwd->listen_port, cport, fwd_opts);\n}\n\n/* protocol local port fwd, used by ssh (and sshd in v1) */\nint\nchannel_setup_local_fwd_listener(struct Forward *fwd, struct ForwardOptions *fwd_opts)\n{\n\tif (fwd->listen_path != NULL) {\n\t\treturn channel_setup_fwd_listener_streamlocal(\n\t\t SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts);\n\t} else {\n\t\treturn channel_setup_fwd_listener_tcpip(SSH_CHANNEL_PORT_LISTENER,\n\t\t fwd, NULL, fwd_opts);\n\t}\n}\n\n/* protocol v2 remote port fwd, used by sshd */\nint\nchannel_setup_remote_fwd_listener(struct Forward *fwd,\n int *allocated_listen_port, struct ForwardOptions *fwd_opts)\n{\n\tif (fwd->listen_path != NULL) {\n\t\treturn channel_setup_fwd_listener_streamlocal(\n\t\t SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts);\n\t} else {\n\t\treturn channel_setup_fwd_listener_tcpip(\n\t\t SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port,\n\t\t fwd_opts);\n\t}\n}\n\n/*\n * Translate the requested rfwd listen host to something usable for\n * this server.\n */\nstatic const char *\nchannel_rfwd_bind_host(const char *listen_host)\n{\n\tif (listen_host == NULL) {\n\t\tif (datafellows & SSH_BUG_RFWD_ADDR)\n\t\t\treturn \"127.0.0.1\";\n\t\telse\n\t\t\treturn \"localhost\";\n\t} else if (*listen_host == '\\0' || strcmp(listen_host, \"*\") == 0) {\n\t\tif (datafellows & SSH_BUG_RFWD_ADDR)\n\t\t\treturn \"0.0.0.0\";\n\t\telse\n\t\t\treturn \"\";\n\t} else\n\t\treturn listen_host;\n}\n\n/*\n * Initiate forwarding of connections to port \"port\" on remote host through\n * the secure channel to host:port from local side.\n * Returns handle (index) for updating the dynamic listen port with\n * channel_update_permitted_opens().\n */\nint\nchannel_request_remote_forwarding(struct Forward *fwd)\n{\n\tint type, success = 0, idx = -1;\n\n\t/* Send the forward request to the remote side. */\n\tif (compat20) {\n\t\tpacket_start(SSH2_MSG_GLOBAL_REQUEST);\n\t\tif (fwd->listen_path != NULL) {\n\t\t packet_put_cstring(\"streamlocal-forward@openssh.com\");\n\t\t packet_put_char(1);\t\t/* boolean: want reply */\n\t\t packet_put_cstring(fwd->listen_path);\n\t\t} else {\n\t\t packet_put_cstring(\"tcpip-forward\");\n\t\t packet_put_char(1);\t\t/* boolean: want reply */\n\t\t packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host));\n\t\t packet_put_int(fwd->listen_port);\n\t\t}\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\t\t/* Assume that server accepts the request */\n\t\tsuccess = 1;\n\t} else if (fwd->listen_path == NULL) {\n\t\tpacket_start(SSH_CMSG_PORT_FORWARD_REQUEST);\n\t\tpacket_put_int(fwd->listen_port);\n\t\tpacket_put_cstring(fwd->connect_host);\n\t\tpacket_put_int(fwd->connect_port);\n\t\tpacket_send();\n\t\tpacket_write_wait();\n\n\t\t/* Wait for response from the remote side. */\n\t\ttype = packet_read();\n\t\tswitch (type) {\n\t\tcase SSH_SMSG_SUCCESS:\n\t\t\tsuccess = 1;\n\t\t\tbreak;\n\t\tcase SSH_SMSG_FAILURE:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* Unknown packet */\n\t\t\tpacket_disconnect(\"Protocol error for port forward request:\"\n\t\t\t \"received packet type %d.\", type);\n\t\t}\n\t} else {\n\t\tlogit(\"Warning: Server does not support remote stream local forwarding.\");\n\t}\n\tif (success) {\n\t\t/* Record that connection to this host/port is permitted. */\n\t\tpermitted_opens = xreallocarray(permitted_opens,\n\t\t num_permitted_opens + 1, sizeof(*permitted_opens));\n\t\tidx = num_permitted_opens++;\n\t\tif (fwd->connect_path != NULL) {\n\t\t\tpermitted_opens[idx].host_to_connect =\n\t\t\t xstrdup(fwd->connect_path);\n\t\t\tpermitted_opens[idx].port_to_connect =\n\t\t\t PORT_STREAMLOCAL;\n\t\t} else {\n\t\t\tpermitted_opens[idx].host_to_connect =\n\t\t\t xstrdup(fwd->connect_host);\n\t\t\tpermitted_opens[idx].port_to_connect =\n\t\t\t fwd->connect_port;\n\t\t}\n\t\tif (fwd->listen_path != NULL) {\n\t\t\tpermitted_opens[idx].listen_host = NULL;\n\t\t\tpermitted_opens[idx].listen_path =\n\t\t\t xstrdup(fwd->listen_path);\n\t\t\tpermitted_opens[idx].listen_port = PORT_STREAMLOCAL;\n\t\t} else {\n\t\t\tpermitted_opens[idx].listen_host =\n\t\t\t fwd->listen_host ? xstrdup(fwd->listen_host) : NULL;\n\t\t\tpermitted_opens[idx].listen_path = NULL;\n\t\t\tpermitted_opens[idx].listen_port = fwd->listen_port;\n\t\t}\n\t\tpermitted_opens[idx].downstream = NULL;\n\t}\n\treturn (idx);\n}\n\nstatic int\nopen_match(ForwardPermission *allowed_open, const char *requestedhost,\n int requestedport)\n{\n\tif (allowed_open->host_to_connect == NULL)\n\t\treturn 0;\n\tif (allowed_open->port_to_connect != FWD_PERMIT_ANY_PORT &&\n\t allowed_open->port_to_connect != requestedport)\n\t\treturn 0;\n\tif (strcmp(allowed_open->host_to_connect, FWD_PERMIT_ANY_HOST) != 0 &&\n\t strcmp(allowed_open->host_to_connect, requestedhost) != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\n/*\n * Note that in the listen host/port case\n * we don't support FWD_PERMIT_ANY_PORT and\n * need to translate between the configured-host (listen_host)\n * and what we've sent to the remote server (channel_rfwd_bind_host)\n */\nstatic int\nopen_listen_match_tcpip(ForwardPermission *allowed_open,\n const char *requestedhost, u_short requestedport, int translate)\n{\n\tconst char *allowed_host;\n\n\tif (allowed_open->host_to_connect == NULL)\n\t\treturn 0;\n\tif (allowed_open->listen_port != requestedport)\n\t\treturn 0;\n\tif (!translate && allowed_open->listen_host == NULL &&\n\t requestedhost == NULL)\n\t\treturn 1;\n\tallowed_host = translate ?\n\t channel_rfwd_bind_host(allowed_open->listen_host) :\n\t allowed_open->listen_host;\n\tif (allowed_host == NULL ||\n\t strcmp(allowed_host, requestedhost) != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\nstatic int\nopen_listen_match_streamlocal(ForwardPermission *allowed_open,\n const char *requestedpath)\n{\n\tif (allowed_open->host_to_connect == NULL)\n\t\treturn 0;\n\tif (allowed_open->listen_port != PORT_STREAMLOCAL)\n\t\treturn 0;\n\tif (allowed_open->listen_path == NULL ||\n\t strcmp(allowed_open->listen_path, requestedpath) != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\n/*\n * Request cancellation of remote forwarding of connection host:port from\n * local side.\n */\nstatic int\nchannel_request_rforward_cancel_tcpip(const char *host, u_short port)\n{\n\tint i;\n\n\tif (!compat20)\n\t\treturn -1;\n\n\tfor (i = 0; i < num_permitted_opens; i++) {\n\t\tif (open_listen_match_tcpip(&permitted_opens[i], host, port, 0))\n\t\t\tbreak;\n\t}\n\tif (i >= num_permitted_opens) {\n\t\tdebug(\"%s: requested forward not found\", __func__);\n\t\treturn -1;\n\t}\n\tpacket_start(SSH2_MSG_GLOBAL_REQUEST);\n\tpacket_put_cstring(\"cancel-tcpip-forward\");\n\tpacket_put_char(0);\n\tpacket_put_cstring(channel_rfwd_bind_host(host));\n\tpacket_put_int(port);\n\tpacket_send();\n\n\tpermitted_opens[i].listen_port = 0;\n\tpermitted_opens[i].port_to_connect = 0;\n\tfree(permitted_opens[i].host_to_connect);\n\tpermitted_opens[i].host_to_connect = NULL;\n\tfree(permitted_opens[i].listen_host);\n\tpermitted_opens[i].listen_host = NULL;\n\tpermitted_opens[i].listen_path = NULL;\n\tpermitted_opens[i].downstream = NULL;\n\n\treturn 0;\n}\n\n/*\n * Request cancellation of remote forwarding of Unix domain socket\n * path from local side.\n */\nstatic int\nchannel_request_rforward_cancel_streamlocal(const char *path)\n{\n\tint i;\n\n\tif (!compat20)\n\t\treturn -1;\n\n\tfor (i = 0; i < num_permitted_opens; i++) {\n\t\tif (open_listen_match_streamlocal(&permitted_opens[i], path))\n\t\t\tbreak;\n\t}\n\tif (i >= num_permitted_opens) {\n\t\tdebug(\"%s: requested forward not found\", __func__);\n\t\treturn -1;\n\t}\n\tpacket_start(SSH2_MSG_GLOBAL_REQUEST);\n\tpacket_put_cstring(\"cancel-streamlocal-forward@openssh.com\");\n\tpacket_put_char(0);\n\tpacket_put_cstring(path);\n\tpacket_send();\n\n\tpermitted_opens[i].listen_port = 0;\n\tpermitted_opens[i].port_to_connect = 0;\n\tfree(permitted_opens[i].host_to_connect);\n\tpermitted_opens[i].host_to_connect = NULL;\n\tpermitted_opens[i].listen_host = NULL;\n\tfree(permitted_opens[i].listen_path);\n\tpermitted_opens[i].listen_path = NULL;\n\tpermitted_opens[i].downstream = NULL;\n\n\treturn 0;\n}\n \n/*\n * Request cancellation of remote forwarding of a connection from local side.\n */\nint\nchannel_request_rforward_cancel(struct Forward *fwd)\n{\n\tif (fwd->listen_path != NULL) {\n\t\treturn (channel_request_rforward_cancel_streamlocal(\n\t\t fwd->listen_path));\n\t} else {\n\t\treturn (channel_request_rforward_cancel_tcpip(fwd->listen_host,\n\t\t fwd->listen_port ? fwd->listen_port : fwd->allocated_port));\n\t}\n}\n\n/*\n * Permits opening to any host/port if permitted_opens[] is empty. This is\n * usually called by the server, because the user could connect to any port\n * anyway, and the server has no way to know but to trust the client anyway.\n */\nvoid\nchannel_permit_all_opens(void)\n{\n\tif (num_permitted_opens == 0)\n\t\tall_opens_permitted = 1;\n}\n\nvoid\nchannel_add_permitted_opens(char *host, int port)\n{\n\tdebug(\"allow port forwarding to host %s port %d\", host, port);\n\n\tpermitted_opens = xreallocarray(permitted_opens,\n\t num_permitted_opens + 1, sizeof(*permitted_opens));\n\tpermitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);\n\tpermitted_opens[num_permitted_opens].port_to_connect = port;\n\tpermitted_opens[num_permitted_opens].listen_host = NULL;\n\tpermitted_opens[num_permitted_opens].listen_path = NULL;\n\tpermitted_opens[num_permitted_opens].listen_port = 0;\n\tpermitted_opens[num_permitted_opens].downstream = NULL;\n\tnum_permitted_opens++;\n\n\tall_opens_permitted = 0;\n}\n\n/*\n * Update the listen port for a dynamic remote forward, after\n * the actual 'newport' has been allocated. If 'newport' < 0 is\n * passed then they entry will be invalidated.\n */\nvoid\nchannel_update_permitted_opens(int idx, int newport)\n{\n\tif (idx < 0 || idx >= num_permitted_opens) {\n\t\tdebug(\"channel_update_permitted_opens: index out of range:\"\n\t\t \" %d num_permitted_opens %d\", idx, num_permitted_opens);\n\t\treturn;\n\t}\n\tdebug(\"%s allowed port %d for forwarding to host %s port %d\",\n\t newport > 0 ? \"Updating\" : \"Removing\",\n\t newport,\n\t permitted_opens[idx].host_to_connect,\n\t permitted_opens[idx].port_to_connect);\n\tif (newport >= 0) {\n\t\tpermitted_opens[idx].listen_port = \n\t\t (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;\n\t} else {\n\t\tpermitted_opens[idx].listen_port = 0;\n\t\tpermitted_opens[idx].port_to_connect = 0;\n\t\tfree(permitted_opens[idx].host_to_connect);\n\t\tpermitted_opens[idx].host_to_connect = NULL;\n\t\tfree(permitted_opens[idx].listen_host);\n\t\tpermitted_opens[idx].listen_host = NULL;\n\t\tfree(permitted_opens[idx].listen_path);\n\t\tpermitted_opens[idx].listen_path = NULL;\n\t}\n}\n\nint\nchannel_add_adm_permitted_opens(char *host, int port)\n{\n\tdebug(\"config allows port forwarding to host %s port %d\", host, port);\n\n\tpermitted_adm_opens = xreallocarray(permitted_adm_opens,\n\t num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens));\n\tpermitted_adm_opens[num_adm_permitted_opens].host_to_connect\n\t = xstrdup(host);\n\tpermitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;\n\tpermitted_adm_opens[num_adm_permitted_opens].listen_host = NULL;\n\tpermitted_adm_opens[num_adm_permitted_opens].listen_path = NULL;\n\tpermitted_adm_opens[num_adm_permitted_opens].listen_port = 0;\n\treturn ++num_adm_permitted_opens;\n}\n\nvoid\nchannel_disable_adm_local_opens(void)\n{\n\tchannel_clear_adm_permitted_opens();\n\tpermitted_adm_opens = xcalloc(sizeof(*permitted_adm_opens), 1);\n\tpermitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL;\n\tnum_adm_permitted_opens = 1;\n}\n\nvoid\nchannel_clear_permitted_opens(void)\n{\n\tint i;\n\n\tfor (i = 0; i < num_permitted_opens; i++) {\n\t\tfree(permitted_opens[i].host_to_connect);\n\t\tfree(permitted_opens[i].listen_host);\n\t\tfree(permitted_opens[i].listen_path);\n\t}\n\tfree(permitted_opens);\n\tpermitted_opens = NULL;\n\tnum_permitted_opens = 0;\n}\n\nvoid\nchannel_clear_adm_permitted_opens(void)\n{\n\tint i;\n\n\tfor (i = 0; i < num_adm_permitted_opens; i++) {\n\t\tfree(permitted_adm_opens[i].host_to_connect);\n\t\tfree(permitted_adm_opens[i].listen_host);\n\t\tfree(permitted_adm_opens[i].listen_path);\n\t}\n\tfree(permitted_adm_opens);\n\tpermitted_adm_opens = NULL;\n\tnum_adm_permitted_opens = 0;\n}\n\nvoid\nchannel_print_adm_permitted_opens(void)\n{\n\tint i;\n\n\tprintf(\"permitopen\");\n\tif (num_adm_permitted_opens == 0) {\n\t\tprintf(\" any\\n\");\n\t\treturn;\n\t}\n\tfor (i = 0; i < num_adm_permitted_opens; i++)\n\t\tif (permitted_adm_opens[i].host_to_connect == NULL)\n\t\t\tprintf(\" none\");\n\t\telse\n\t\t\tprintf(\" %s:%d\", permitted_adm_opens[i].host_to_connect,\n\t\t\t permitted_adm_opens[i].port_to_connect);\n\tprintf(\"\\n\");\n}\n\n/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */\nint\npermitopen_port(const char *p)\n{\n\tint port;\n\n\tif (strcmp(p, \"*\") == 0)\n\t\treturn FWD_PERMIT_ANY_PORT;\n\tif ((port = a2port(p)) > 0)\n\t\treturn port;\n\treturn -1;\n}\n\n/* Try to start non-blocking connect to next host in cctx list */\nstatic int\nconnect_next(struct channel_connect *cctx)\n{\n\tint sock, saved_errno;\n\tstruct sockaddr_un *sunaddr;\n\tchar ntop[NI_MAXHOST], strport[MAXIMUM(NI_MAXSERV,sizeof(sunaddr->sun_path))];\n\n\tfor (; cctx->ai; cctx->ai = cctx->ai->ai_next) {\n\t\tswitch (cctx->ai->ai_family) {\n\t\tcase AF_UNIX:\n\t\t\t/* unix:pathname instead of host:port */\n\t\t\tsunaddr = (struct sockaddr_un *)cctx->ai->ai_addr;\n\t\t\tstrlcpy(ntop, \"unix\", sizeof(ntop));\n\t\t\tstrlcpy(strport, sunaddr->sun_path, sizeof(strport));\n\t\t\tbreak;\n\t\tcase AF_INET:\n\t\tcase AF_INET6:\n\t\t\tif (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen,\n\t\t\t ntop, sizeof(ntop), strport, sizeof(strport),\n\t\t\t NI_NUMERICHOST|NI_NUMERICSERV) != 0) {\n\t\t\t\terror(\"connect_next: getnameinfo failed\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcontinue;\n\t\t}\n\t\tif ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype,\n\t\t cctx->ai->ai_protocol)) == -1) {\n\t\t\tif (cctx->ai->ai_next == NULL)\n\t\t\t\terror(\"socket: %.100s\", strerror(errno));\n\t\t\telse\n\t\t\t\tverbose(\"socket: %.100s\", strerror(errno));\n\t\t\tcontinue;\n\t\t}\n\t\tif (set_nonblock(sock) == -1)\n\t\t\tfatal(\"%s: set_nonblock(%d)\", __func__, sock);\n\t\tif (connect(sock, cctx->ai->ai_addr,\n\t\t cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) {\n\t\t\tdebug(\"connect_next: host %.100s ([%.100s]:%s): \"\n\t\t\t \"%.100s\", cctx->host, ntop, strport,\n\t\t\t strerror(errno));\n\t\t\tsaved_errno = errno;\n\t\t\tclose(sock);\n\t\t\terrno = saved_errno;\n\t\t\tcontinue;\t/* fail -- try next */\n\t\t}\n\t\tif (cctx->ai->ai_family != AF_UNIX)\n\t\t\tset_nodelay(sock);\n\t\tdebug(\"connect_next: host %.100s ([%.100s]:%s) \"\n\t\t \"in progress, fd=%d\", cctx->host, ntop, strport, sock);\n\t\tcctx->ai = cctx->ai->ai_next;\n\t\treturn sock;\n\t}\n\treturn -1;\n}\n\nstatic void\nchannel_connect_ctx_free(struct channel_connect *cctx)\n{\n\tfree(cctx->host);\n\tif (cctx->aitop) {\n\t\tif (cctx->aitop->ai_family == AF_UNIX)\n\t\t\tfree(cctx->aitop);\n\t\telse\n\t\t\tfreeaddrinfo(cctx->aitop);\n\t}\n\tmemset(cctx, 0, sizeof(*cctx));\n}\n\n/*\n * Return CONNECTING channel to remote host:port or local socket path,\n * passing back the failure reason if appropriate.\n */\nstatic Channel *\nconnect_to_reason(const char *name, int port, char *ctype, char *rname,\n int *reason, const char **errmsg)\n{\n\tstruct addrinfo hints;\n\tint gaierr;\n\tint sock = -1;\n\tchar strport[NI_MAXSERV];\n\tstruct channel_connect cctx;\n\tChannel *c;\n\n\tmemset(&cctx, 0, sizeof(cctx));\n\n\tif (port == PORT_STREAMLOCAL) {\n\t\tstruct sockaddr_un *sunaddr;\n\t\tstruct addrinfo *ai;\n\n\t\tif (strlen(name) > sizeof(sunaddr->sun_path)) {\n\t\t\terror(\"%.100s: %.100s\", name, strerror(ENAMETOOLONG));\n\t\t\treturn (NULL);\n\t\t}\n\n\t\t/*\n\t\t * Fake up a struct addrinfo for AF_UNIX connections.\n\t\t * channel_connect_ctx_free() must check ai_family\n\t\t * and use free() not freeaddirinfo() for AF_UNIX.\n\t\t */\n\t\tai = xmalloc(sizeof(*ai) + sizeof(*sunaddr));\n\t\tmemset(ai, 0, sizeof(*ai) + sizeof(*sunaddr));\n\t\tai->ai_addr = (struct sockaddr *)(ai + 1);\n\t\tai->ai_addrlen = sizeof(*sunaddr);\n\t\tai->ai_family = AF_UNIX;\n\t\tai->ai_socktype = SOCK_STREAM;\n\t\tai->ai_protocol = PF_UNSPEC;\n\t\tsunaddr = (struct sockaddr_un *)ai->ai_addr;\n\t\tsunaddr->sun_family = AF_UNIX;\n\t\tstrlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path));\n\t\tcctx.aitop = ai;\n\t} else {\n\t\tmemset(&hints, 0, sizeof(hints));\n\t\thints.ai_family = IPv4or6;\n\t\thints.ai_socktype = SOCK_STREAM;\n\t\tsnprintf(strport, sizeof strport, \"%d\", port);\n\t\tif ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop))\n\t\t != 0) {\n\t\t\tif (errmsg != NULL)\n\t\t\t\t*errmsg = ssh_gai_strerror(gaierr);\n\t\t\tif (reason != NULL)\n\t\t\t\t*reason = SSH2_OPEN_CONNECT_FAILED;\n\t\t\terror(\"connect_to %.100s: unknown host (%s)\", name,\n\t\t\t ssh_gai_strerror(gaierr));\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tcctx.host = xstrdup(name);\n\tcctx.port = port;\n\tcctx.ai = cctx.aitop;\n\n\tif ((sock = connect_next(&cctx)) == -1) {\n\t\terror(\"connect to %.100s port %d failed: %s\",\n\t\t name, port, strerror(errno));\n\t\tchannel_connect_ctx_free(&cctx);\n\t\treturn NULL;\n\t}\n\tc = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,\n\t CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);\n\tc->connect_ctx = cctx;\n\treturn c;\n}\n\n/* Return CONNECTING channel to remote host:port or local socket path */\nstatic Channel *\nconnect_to(const char *name, int port, char *ctype, char *rname)\n{\n\treturn connect_to_reason(name, port, ctype, rname, NULL, NULL);\n}\n\n/*\n * returns either the newly connected channel or the downstream channel\n * that needs to deal with this connection.\n */\nChannel *\nchannel_connect_by_listen_address(const char *listen_host,\n u_short listen_port, char *ctype, char *rname)\n{\n\tint i;\n\n\tfor (i = 0; i < num_permitted_opens; i++) {\n\t\tif (open_listen_match_tcpip(&permitted_opens[i], listen_host,\n\t\t listen_port, 1)) {\n\t\t\tif (permitted_opens[i].downstream)\n\t\t\t\treturn permitted_opens[i].downstream;\n\t\t\treturn connect_to(\n\t\t\t permitted_opens[i].host_to_connect,\n\t\t\t permitted_opens[i].port_to_connect, ctype, rname);\n\t\t}\n\t}\n\terror(\"WARNING: Server requests forwarding for unknown listen_port %d\",\n\t listen_port);\n\treturn NULL;\n}\n\nChannel *\nchannel_connect_by_listen_path(const char *path, char *ctype, char *rname)\n{\n\tint i;\n\n\tfor (i = 0; i < num_permitted_opens; i++) {\n\t\tif (open_listen_match_streamlocal(&permitted_opens[i], path)) {\n\t\t\treturn connect_to(\n\t\t\t permitted_opens[i].host_to_connect,\n\t\t\t permitted_opens[i].port_to_connect, ctype, rname);\n\t\t}\n\t}\n\terror(\"WARNING: Server requests forwarding for unknown path %.100s\",\n\t path);\n\treturn NULL;\n}\n\n/* Check if connecting to that port is permitted and connect. */\nChannel *\nchannel_connect_to_port(const char *host, u_short port, char *ctype,\n char *rname, int *reason, const char **errmsg)\n{\n\tint i, permit, permit_adm = 1;\n\n\tpermit = all_opens_permitted;\n\tif (!permit) {\n\t\tfor (i = 0; i < num_permitted_opens; i++)\n\t\t\tif (open_match(&permitted_opens[i], host, port)) {\n\t\t\t\tpermit = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\tif (num_adm_permitted_opens > 0) {\n\t\tpermit_adm = 0;\n\t\tfor (i = 0; i < num_adm_permitted_opens; i++)\n\t\t\tif (open_match(&permitted_adm_opens[i], host, port)) {\n\t\t\t\tpermit_adm = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\tif (!permit || !permit_adm) {\n\t\tlogit(\"Received request to connect to host %.100s port %d, \"\n\t\t \"but the request was denied.\", host, port);\n\t\tif (reason != NULL)\n\t\t\t*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;\n\t\treturn NULL;\n\t}\n\treturn connect_to_reason(host, port, ctype, rname, reason, errmsg);\n}\n\n/* Check if connecting to that path is permitted and connect. */\nChannel *\nchannel_connect_to_path(const char *path, char *ctype, char *rname)\n{\n\tint i, permit, permit_adm = 1;\n\n\tpermit = all_opens_permitted;\n\tif (!permit) {\n\t\tfor (i = 0; i < num_permitted_opens; i++)\n\t\t\tif (open_match(&permitted_opens[i], path, PORT_STREAMLOCAL)) {\n\t\t\t\tpermit = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\tif (num_adm_permitted_opens > 0) {\n\t\tpermit_adm = 0;\n\t\tfor (i = 0; i < num_adm_permitted_opens; i++)\n\t\t\tif (open_match(&permitted_adm_opens[i], path, PORT_STREAMLOCAL)) {\n\t\t\t\tpermit_adm = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t}\n\n\tif (!permit || !permit_adm) {\n\t\tlogit(\"Received request to connect to path %.100s, \"\n\t\t \"but the request was denied.\", path);\n\t\treturn NULL;\n\t}\n\treturn connect_to(path, PORT_STREAMLOCAL, ctype, rname);\n}\n\nvoid\nchannel_send_window_changes(void)\n{\n\tu_int i;\n\tstruct winsize ws;\n\n\tfor (i = 0; i < channels_alloc; i++) {\n\t\tif (channels[i] == NULL || !channels[i]->client_tty ||\n\t\t channels[i]->type != SSH_CHANNEL_OPEN)\n\t\t\tcontinue;\n\t\tif (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)\n\t\t\tcontinue;\n\t\tchannel_request_start(i, \"window-change\", 0);\n\t\tpacket_put_int((u_int)ws.ws_col);\n\t\tpacket_put_int((u_int)ws.ws_row);\n\t\tpacket_put_int((u_int)ws.ws_xpixel);\n\t\tpacket_put_int((u_int)ws.ws_ypixel);\n\t\tpacket_send();\n\t}\n}\n\n/* -- X11 forwarding */\n\n/*\n * Creates an internet domain socket for listening for X11 connections.\n * Returns 0 and a suitable display number for the DISPLAY variable\n * stored in display_numberp , or -1 if an error occurs.\n */\nint\nx11_create_display_inet(int x11_display_offset, int x11_use_localhost,\n int single_connection, u_int *display_numberp, int **chanids)\n{\n\tChannel *nc = NULL;\n\tint display_number, sock;\n\tu_short port;\n\tstruct addrinfo hints, *ai, *aitop;\n\tchar strport[NI_MAXSERV];\n\tint gaierr, n, num_socks = 0, socks[NUM_SOCKS];\n\n\tif (chanids == NULL)\n\t\treturn -1;\n\n\tfor (display_number = x11_display_offset;\n\t display_number < MAX_DISPLAYS;\n\t display_number++) {\n\t\tport = 6000 + display_number;\n\t\tmemset(&hints, 0, sizeof(hints));\n\t\thints.ai_family = IPv4or6;\n\t\thints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;\n\t\thints.ai_socktype = SOCK_STREAM;\n\t\tsnprintf(strport, sizeof strport, \"%d\", port);\n\t\tif ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {\n\t\t\terror(\"getaddrinfo: %.100s\", ssh_gai_strerror(gaierr));\n\t\t\treturn -1;\n\t\t}\n\t\tfor (ai = aitop; ai; ai = ai->ai_next) {\n\t\t\tif (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)\n\t\t\t\tcontinue;\n\t\t\tsock = socket(ai->ai_family, ai->ai_socktype,\n\t\t\t ai->ai_protocol);\n\t\t\tif (sock < 0) {\n\t\t\t\tif ((errno != EINVAL) && (errno != EAFNOSUPPORT)\n#ifdef EPFNOSUPPORT\n\t\t\t\t && (errno != EPFNOSUPPORT)\n#endif \n\t\t\t\t ) {\n\t\t\t\t\terror(\"socket: %.100s\", strerror(errno));\n\t\t\t\t\tfreeaddrinfo(aitop);\n\t\t\t\t\treturn -1;\n\t\t\t\t} else {\n\t\t\t\t\tdebug(\"x11_create_display_inet: Socket family %d not supported\",\n\t\t\t\t\t\t ai->ai_family);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (ai->ai_family == AF_INET6)\n\t\t\t\tsock_set_v6only(sock);\n\t\t\tif (x11_use_localhost)\n\t\t\t\tchannel_set_reuseaddr(sock);\n\t\t\tif (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {\n\t\t\t\tdebug2(\"bind port %d: %.100s\", port, strerror(errno));\n\t\t\t\tclose(sock);\n\n\t\t\t\tfor (n = 0; n < num_socks; n++) {\n\t\t\t\t\tclose(socks[n]);\n\t\t\t\t}\n\t\t\t\tnum_socks = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tsocks[num_socks++] = sock;\n\t\t\tif (num_socks == NUM_SOCKS)\n\t\t\t\tbreak;\n\t\t}\n\t\tfreeaddrinfo(aitop);\n\t\tif (num_socks > 0)\n\t\t\tbreak;\n\t}\n\tif (display_number >= MAX_DISPLAYS) {\n\t\terror(\"Failed to allocate internet-domain X11 display socket.\");\n\t\treturn -1;\n\t}\n\t/* Start listening for connections on the socket. */\n\tfor (n = 0; n < num_socks; n++) {\n\t\tsock = socks[n];\n\t\tif (listen(sock, SSH_LISTEN_BACKLOG) < 0) {\n\t\t\terror(\"listen: %.100s\", strerror(errno));\n\t\t\tclose(sock);\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\t/* Allocate a channel for each socket. */\n\t*chanids = xcalloc(num_socks + 1, sizeof(**chanids));\n\tfor (n = 0; n < num_socks; n++) {\n\t\tsock = socks[n];\n\t\tnc = channel_new(\"x11 listener\",\n\t\t SSH_CHANNEL_X11_LISTENER, sock, sock, -1,\n\t\t CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,\n\t\t 0, \"X11 inet listener\", 1);\n\t\tnc->single_connection = single_connection;\n\t\t(*chanids)[n] = nc->self;\n\t}\n\t(*chanids)[n] = -1;\n\n\t/* Return the display number for the DISPLAY environment variable. */\n\t*display_numberp = display_number;\n\treturn (0);\n}\n\nstatic int\nconnect_local_xsocket_path(const char *pathname)\n{\n\tint sock;\n\tstruct sockaddr_un addr;\n\n\tsock = socket(AF_UNIX, SOCK_STREAM, 0);\n\tif (sock < 0)\n\t\terror(\"socket: %.100s\", strerror(errno));\n\tmemset(&addr, 0, sizeof(addr));\n\taddr.sun_family = AF_UNIX;\n\tstrlcpy(addr.sun_path, pathname, sizeof addr.sun_path);\n\tif (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)\n\t\treturn sock;\n\tclose(sock);\n\terror(\"connect %.100s: %.100s\", addr.sun_path, strerror(errno));\n\treturn -1;\n}\n\nstatic int\nconnect_local_xsocket(u_int dnr)\n{\n\tchar buf[1024];\n\tsnprintf(buf, sizeof buf, _PATH_UNIX_X, dnr);\n\treturn connect_local_xsocket_path(buf);\n}\n\n#ifdef __APPLE__\nstatic int\nis_path_to_xsocket(const char *display, char *path, size_t pathlen)\n{\n\tstruct stat sbuf;\n\n\tif (strlcpy(path, display, pathlen) >= pathlen) {\n\t\terror(\"%s: display path too long\", __func__);\n\t\treturn 0;\n\t}\n\tif (display[0] != '/')\n\t\treturn 0;\n\tif (stat(path, &sbuf) == 0) {\n\t\treturn 1;\n\t} else {\n\t\tchar *dot = strrchr(path, '.');\n\t\tif (dot != NULL) {\n\t\t\t*dot = '\\0';\n\t\t\tif (stat(path, &sbuf) == 0) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn 0;\n}\n#endif\n\nint\nx11_connect_display(void)\n{\n\tu_int display_number;\n\tconst char *display;\n\tchar buf[1024], *cp;\n\tstruct addrinfo hints, *ai, *aitop;\n\tchar strport[NI_MAXSERV];\n\tint gaierr, sock = 0;\n\n\t/* Try to open a socket for the local X server. */\n\tdisplay = getenv(\"DISPLAY\");\n\tif (!display) {\n\t\terror(\"DISPLAY not set.\");\n\t\treturn -1;\n\t}\n\t/*\n\t * Now we decode the value of the DISPLAY variable and make a\n\t * connection to the real X server.\n\t */\n\n#ifdef __APPLE__\n\t/* Check if display is a path to a socket (as set by launchd). */\n\t{\n\t\tchar path[PATH_MAX];\n\n\t\tif (is_path_to_xsocket(display, path, sizeof(path))) {\n\t\t\tdebug(\"x11_connect_display: $DISPLAY is launchd\");\n\n\t\t\t/* Create a socket. */\n\t\t\tsock = connect_local_xsocket_path(path);\n\t\t\tif (sock < 0)\n\t\t\t\treturn -1;\n\n\t\t\t/* OK, we now have a connection to the display. */\n\t\t\treturn sock;\n\t\t}\n\t}\n#endif\n\t/*\n\t * Check if it is a unix domain socket. Unix domain displays are in\n\t * one of the following formats: unix:d[.s], :d[.s], ::d[.s]\n\t */\n\tif (strncmp(display, \"unix:\", 5) == 0 ||\n\t display[0] == ':') {\n\t\t/* Connect to the unix domain socket. */\n\t\tif (sscanf(strrchr(display, ':') + 1, \"%u\", &display_number) != 1) {\n\t\t\terror(\"Could not parse display number from DISPLAY: %.100s\",\n\t\t\t display);\n\t\t\treturn -1;\n\t\t}\n\t\t/* Create a socket. */\n\t\tsock = connect_local_xsocket(display_number);\n\t\tif (sock < 0)\n\t\t\treturn -1;\n\n\t\t/* OK, we now have a connection to the display. */\n\t\treturn sock;\n\t}\n\t/*\n\t * Connect to an inet socket. The DISPLAY value is supposedly\n\t * hostname:d[.s], where hostname may also be numeric IP address.\n\t */\n\tstrlcpy(buf, display, sizeof(buf));\n\tcp = strchr(buf, ':');\n\tif (!cp) {\n\t\terror(\"Could not find ':' in DISPLAY: %.100s\", display);\n\t\treturn -1;\n\t}\n\t*cp = 0;\n\t/* buf now contains the host name. But first we parse the display number. */\n\tif (sscanf(cp + 1, \"%u\", &display_number) != 1) {\n\t\terror(\"Could not parse display number from DISPLAY: %.100s\",\n\t\t display);\n\t\treturn -1;\n\t}\n\n\t/* Look up the host address */\n\tmemset(&hints, 0, sizeof(hints));\n\thints.ai_family = IPv4or6;\n\thints.ai_socktype = SOCK_STREAM;\n\tsnprintf(strport, sizeof strport, \"%u\", 6000 + display_number);\n\tif ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {\n\t\terror(\"%.100s: unknown host. (%s)\", buf,\n\t\tssh_gai_strerror(gaierr));\n\t\treturn -1;\n\t}\n\tfor (ai = aitop; ai; ai = ai->ai_next) {\n\t\t/* Create a socket. */\n\t\tsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);\n\t\tif (sock < 0) {\n\t\t\tdebug2(\"socket: %.100s\", strerror(errno));\n\t\t\tcontinue;\n\t\t}\n\t\t/* Connect it to the display. */\n\t\tif (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {\n\t\t\tdebug2(\"connect %.100s port %u: %.100s\", buf,\n\t\t\t 6000 + display_number, strerror(errno));\n\t\t\tclose(sock);\n\t\t\tcontinue;\n\t\t}\n\t\t/* Success */\n\t\tbreak;\n\t}\n\tfreeaddrinfo(aitop);\n\tif (!ai) {\n\t\terror(\"connect %.100s port %u: %.100s\", buf, 6000 + display_number,\n\t\t strerror(errno));\n\t\treturn -1;\n\t}\n\tset_nodelay(sock);\n\treturn sock;\n}\n\n/*\n * This is called when SSH_SMSG_X11_OPEN is received. The packet contains\n * the remote channel number. We should do whatever we want, and respond\n * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.\n */\n\n/* ARGSUSED */\nint\nx11_input_open(int type, u_int32_t seq, void *ctxt)\n{\n\tChannel *c = NULL;\n\tint remote_id, sock = 0;\n\tchar *remote_host;\n\n\tdebug(\"Received X11 open request.\");\n\n\tremote_id = packet_get_int();\n\n\tif (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {\n\t\tremote_host = packet_get_string(NULL);\n\t} else {\n\t\tremote_host = xstrdup(\"unknown (remote did not supply name)\");\n\t}\n\tpacket_check_eom();\n\n\t/* Obtain a connection to the real X display. */\n\tsock = x11_connect_display();\n\tif (sock != -1) {\n\t\t/* Allocate a channel for this connection. */\n\t\tc = channel_new(\"connected x11 socket\",\n\t\t SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,\n\t\t remote_host, 1);\n\t\tc->remote_id = remote_id;\n\t\tc->force_drain = 1;\n\t}\n\tfree(remote_host);\n\tif (c == NULL) {\n\t\t/* Send refusal to the remote host. */\n\t\tpacket_start(SSH_MSG_CHANNEL_OPEN_FAILURE);\n\t\tpacket_put_int(remote_id);\n\t} else {\n\t\t/* Send a confirmation to the remote host. */\n\t\tpacket_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);\n\t\tpacket_put_int(remote_id);\n\t\tpacket_put_int(c->self);\n\t}\n\tpacket_send();\n\treturn 0;\n}\n\n/* dummy protocol handler that denies SSH-1 requests (agent/x11) */\n/* ARGSUSED */\nint\ndeny_input_open(int type, u_int32_t seq, void *ctxt)\n{\n\tint rchan = packet_get_int();\n\n\tswitch (type) {\n\tcase SSH_SMSG_AGENT_OPEN:\n\t\terror(\"Warning: ssh server tried agent forwarding.\");\n\t\tbreak;\n\tcase SSH_SMSG_X11_OPEN:\n\t\terror(\"Warning: ssh server tried X11 forwarding.\");\n\t\tbreak;\n\tdefault:\n\t\terror(\"deny_input_open: type %d\", type);\n\t\tbreak;\n\t}\n\terror(\"Warning: this is probably a break-in attempt by a malicious server.\");\n\tpacket_start(SSH_MSG_CHANNEL_OPEN_FAILURE);\n\tpacket_put_int(rchan);\n\tpacket_send();\n\treturn 0;\n}\n\n/*\n * Requests forwarding of X11 connections, generates fake authentication\n * data, and enables authentication spoofing.\n * This should be called in the client only.\n */\nvoid\nx11_request_forwarding_with_spoofing(int client_session_id, const char *disp,\n const char *proto, const char *data, int want_reply)\n{\n\tu_int data_len = (u_int) strlen(data) / 2;\n\tu_int i, value;\n\tchar *new_data;\n\tint screen_number;\n\tconst char *cp;\n\n\tif (x11_saved_display == NULL)\n\t\tx11_saved_display = xstrdup(disp);\n\telse if (strcmp(disp, x11_saved_display) != 0) {\n\t\terror(\"x11_request_forwarding_with_spoofing: different \"\n\t\t \"$DISPLAY already forwarded\");\n\t\treturn;\n\t}\n\n\tcp = strchr(disp, ':');\n\tif (cp)\n\t\tcp = strchr(cp, '.');\n\tif (cp)\n\t\tscreen_number = (u_int)strtonum(cp + 1, 0, 400, NULL);\n\telse\n\t\tscreen_number = 0;\n\n\tif (x11_saved_proto == NULL) {\n\t\t/* Save protocol name. */\n\t\tx11_saved_proto = xstrdup(proto);\n\n\t\t/* Extract real authentication data. */\n\t\tx11_saved_data = xmalloc(data_len);\n\t\tfor (i = 0; i < data_len; i++) {\n\t\t\tif (sscanf(data + 2 * i, \"%2x\", &value) != 1)\n\t\t\t\tfatal(\"x11_request_forwarding: bad \"\n\t\t\t\t \"authentication data: %.100s\", data);\n\t\t\tx11_saved_data[i] = value;\n\t\t}\n\t\tx11_saved_data_len = data_len;\n\n\t\t/* Generate fake data of the same length. */\n\t\tx11_fake_data = xmalloc(data_len);\n\t\tarc4random_buf(x11_fake_data, data_len);\n\t\tx11_fake_data_len = data_len;\n\t}\n\n\t/* Convert the fake data into hex. */\n\tnew_data = tohex(x11_fake_data, data_len);\n\n\t/* Send the request packet. */\n\tif (compat20) {\n\t\tchannel_request_start(client_session_id, \"x11-req\", want_reply);\n\t\tpacket_put_char(0);\t/* XXX bool single connection */\n\t} else {\n\t\tpacket_start(SSH_CMSG_X11_REQUEST_FORWARDING);\n\t}\n\tpacket_put_cstring(proto);\n\tpacket_put_cstring(new_data);\n\tpacket_put_int(screen_number);\n\tpacket_send();\n\tpacket_write_wait();\n\tfree(new_data);\n}\n\n\n/* -- agent forwarding */\n\n/* Sends a message to the server to request authentication fd forwarding. */\n\nvoid\nauth_request_forwarding(void)\n{\n\tpacket_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);\n\tpacket_send();\n\tpacket_write_wait();\n}\n","/* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n *\n *\n * Copyright (c) 1999 Niels Provos. All rights reserved.\n * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n#include \n\n#include \"cipher.h\"\n#include \"misc.h\"\n#include \"sshbuf.h\"\n#include \"ssherr.h\"\n#include \"digest.h\"\n\n#include \"openbsd-compat/openssl-compat.h\"\n\n#ifdef WITH_SSH1\nextern const EVP_CIPHER *evp_ssh1_bf(void);\nextern const EVP_CIPHER *evp_ssh1_3des(void);\nextern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);\n#endif\n\nstruct sshcipher_ctx {\n\tint\tplaintext;\n\tint\tencrypt;\n\tEVP_CIPHER_CTX *evp;\n\tstruct chachapoly_ctx cp_ctx; /* XXX union with evp? */\n\tstruct aesctr_ctx ac_ctx; /* XXX union with evp? */\n\tconst struct sshcipher *cipher;\n};\n\nstruct sshcipher {\n\tchar\t*name;\n\tint\tnumber;\t\t/* for ssh1 only */\n\tu_int\tblock_size;\n\tu_int\tkey_len;\n\tu_int\tiv_len;\t\t/* defaults to block_size */\n\tu_int\tauth_len;\n\tu_int\tdiscard_len;\n\tu_int\tflags;\n#define CFLAG_CBC\t\t(1<<0)\n#define CFLAG_CHACHAPOLY\t(1<<1)\n#define CFLAG_AESCTR\t\t(1<<2)\n#define CFLAG_NONE\t\t(1<<3)\n#ifdef WITH_OPENSSL\n\tconst EVP_CIPHER\t*(*evptype)(void);\n#else\n\tvoid\t*ignored;\n#endif\n};\n\nstatic const struct sshcipher ciphers[] = {\n#ifdef WITH_SSH1\n\t{ \"des\",\tSSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },\n\t{ \"3des\",\tSSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },\n# ifndef OPENSSL_NO_BF\n\t{ \"blowfish\",\tSSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },\n# endif /* OPENSSL_NO_BF */\n#endif /* WITH_SSH1 */\n#ifdef WITH_OPENSSL\n\t{ \"none\",\tSSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },\n\t{ \"3des-cbc\",\tSSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },\n# ifndef OPENSSL_NO_BF\n\t{ \"blowfish-cbc\",\n\t\t\tSSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },\n# endif /* OPENSSL_NO_BF */\n# ifndef OPENSSL_NO_CAST\n\t{ \"cast128-cbc\",\n\t\t\tSSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc },\n# endif /* OPENSSL_NO_CAST */\n# ifndef OPENSSL_NO_RC4\n\t{ \"arcfour\",\tSSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 },\n\t{ \"arcfour128\",\tSSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 },\n\t{ \"arcfour256\",\tSSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 },\n# endif /* OPENSSL_NO_RC4 */\n\t{ \"aes128-cbc\",\tSSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },\n\t{ \"aes192-cbc\",\tSSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },\n\t{ \"aes256-cbc\",\tSSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },\n\t{ \"rijndael-cbc@lysator.liu.se\",\n\t\t\tSSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },\n\t{ \"aes128-ctr\",\tSSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },\n\t{ \"aes192-ctr\",\tSSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },\n\t{ \"aes256-ctr\",\tSSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },\n# ifdef OPENSSL_HAVE_EVPGCM\n\t{ \"aes128-gcm@openssh.com\",\n\t\t\tSSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },\n\t{ \"aes256-gcm@openssh.com\",\n\t\t\tSSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },\n# endif /* OPENSSL_HAVE_EVPGCM */\n#else /* WITH_OPENSSL */\n\t{ \"aes128-ctr\",\tSSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },\n\t{ \"aes192-ctr\",\tSSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },\n\t{ \"aes256-ctr\",\tSSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL },\n\t{ \"none\",\tSSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL },\n#endif /* WITH_OPENSSL */\n\t{ \"chacha20-poly1305@openssh.com\",\n\t\t\tSSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },\n\n\t{ NULL,\t\tSSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }\n};\n\n/*--*/\n\n/* Returns a comma-separated list of supported ciphers. */\nchar *\ncipher_alg_list(char sep, int auth_only)\n{\n\tchar *tmp, *ret = NULL;\n\tsize_t nlen, rlen = 0;\n\tconst struct sshcipher *c;\n\n\tfor (c = ciphers; c->name != NULL; c++) {\n\t\tif (c->number != SSH_CIPHER_SSH2)\n\t\t\tcontinue;\n\t\tif (auth_only && c->auth_len == 0)\n\t\t\tcontinue;\n\t\tif (ret != NULL)\n\t\t\tret[rlen++] = sep;\n\t\tnlen = strlen(c->name);\n\t\tif ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {\n\t\t\tfree(ret);\n\t\t\treturn NULL;\n\t\t}\n\t\tret = tmp;\n\t\tmemcpy(ret + rlen, c->name, nlen + 1);\n\t\trlen += nlen;\n\t}\n\treturn ret;\n}\n\nu_int\ncipher_blocksize(const struct sshcipher *c)\n{\n\treturn (c->block_size);\n}\n\nu_int\ncipher_keylen(const struct sshcipher *c)\n{\n\treturn (c->key_len);\n}\n\nu_int\ncipher_seclen(const struct sshcipher *c)\n{\n\tif (strcmp(\"3des-cbc\", c->name) == 0)\n\t\treturn 14;\n\treturn cipher_keylen(c);\n}\n\nu_int\ncipher_authlen(const struct sshcipher *c)\n{\n\treturn (c->auth_len);\n}\n\nu_int\ncipher_ivlen(const struct sshcipher *c)\n{\n\t/*\n\t * Default is cipher block size, except for chacha20+poly1305 that\n\t * needs no IV. XXX make iv_len == -1 default?\n\t */\n\treturn (c->iv_len != 0 || (c->flags & CFLAG_CHACHAPOLY) != 0) ?\n\t c->iv_len : c->block_size;\n}\n\nu_int\ncipher_get_number(const struct sshcipher *c)\n{\n\treturn (c->number);\n}\n\nu_int\ncipher_is_cbc(const struct sshcipher *c)\n{\n\treturn (c->flags & CFLAG_CBC) != 0;\n}\n\nu_int\ncipher_ctx_is_plaintext(struct sshcipher_ctx *cc)\n{\n\treturn cc->plaintext;\n}\n\nu_int\ncipher_ctx_get_number(struct sshcipher_ctx *cc)\n{\n\treturn cc->cipher->number;\n}\n\nu_int\ncipher_mask_ssh1(int client)\n{\n\tu_int mask = 0;\n\tmask |= 1 << SSH_CIPHER_3DES;\t\t/* Mandatory */\n\tmask |= 1 << SSH_CIPHER_BLOWFISH;\n\tif (client) {\n\t\tmask |= 1 << SSH_CIPHER_DES;\n\t}\n\treturn mask;\n}\n\nconst struct sshcipher *\ncipher_by_name(const char *name)\n{\n\tconst struct sshcipher *c;\n\tfor (c = ciphers; c->name != NULL; c++)\n\t\tif (strcmp(c->name, name) == 0)\n\t\t\treturn c;\n\treturn NULL;\n}\n\nconst struct sshcipher *\ncipher_by_number(int id)\n{\n\tconst struct sshcipher *c;\n\tfor (c = ciphers; c->name != NULL; c++)\n\t\tif (c->number == id)\n\t\t\treturn c;\n\treturn NULL;\n}\n\n#define\tCIPHER_SEP\t\",\"\nint\nciphers_valid(const char *names)\n{\n\tconst struct sshcipher *c;\n\tchar *cipher_list, *cp;\n\tchar *p;\n\n\tif (names == NULL || strcmp(names, \"\") == 0)\n\t\treturn 0;\n\tif ((cipher_list = cp = strdup(names)) == NULL)\n\t\treturn 0;\n\tfor ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\\0';\n\t (p = strsep(&cp, CIPHER_SEP))) {\n\t\tc = cipher_by_name(p);\n\t\tif (c == NULL || c->number != SSH_CIPHER_SSH2) {\n\t\t\tfree(cipher_list);\n\t\t\treturn 0;\n\t\t}\n\t}\n\tfree(cipher_list);\n\treturn 1;\n}\n\n/*\n * Parses the name of the cipher. Returns the number of the corresponding\n * cipher, or -1 on error.\n */\n\nint\ncipher_number(const char *name)\n{\n\tconst struct sshcipher *c;\n\tif (name == NULL)\n\t\treturn -1;\n\tfor (c = ciphers; c->name != NULL; c++)\n\t\tif (strcasecmp(c->name, name) == 0)\n\t\t\treturn c->number;\n\treturn -1;\n}\n\nchar *\ncipher_name(int id)\n{\n\tconst struct sshcipher *c = cipher_by_number(id);\n\treturn (c==NULL) ? \"\" : c->name;\n}\n\nconst char *\ncipher_warning_message(const struct sshcipher_ctx *cc)\n{\n\tif (cc == NULL || cc->cipher == NULL)\n\t\treturn NULL;\n\tif (cc->cipher->number == SSH_CIPHER_DES)\n\t\treturn \"use of DES is strongly discouraged due to \"\n\t\t \"cryptographic weaknesses\";\n\treturn NULL;\n}\n\nint\ncipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,\n const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,\n int do_encrypt)\n{\n\tstruct sshcipher_ctx *cc = NULL;\n\tint ret = SSH_ERR_INTERNAL_ERROR;\n#ifdef WITH_OPENSSL\n\tconst EVP_CIPHER *type;\n\tint klen;\n\tu_char *junk, *discard;\n#endif\n\n\t*ccp = NULL;\n\tif ((cc = calloc(sizeof(*cc), 1)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\tif (cipher->number == SSH_CIPHER_DES) {\n\t\tif (keylen > 8)\n\t\t\tkeylen = 8;\n\t}\n\n\tcc->plaintext = (cipher->number == SSH_CIPHER_NONE);\n\tcc->encrypt = do_encrypt;\n\n\tif (keylen < cipher->key_len ||\n\t (iv != NULL && ivlen < cipher_ivlen(cipher))) {\n\t\tret = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\n\tcc->cipher = cipher;\n\tif ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {\n\t\tret = chachapoly_init(&cc->cp_ctx, key, keylen);\n\t\tgoto out;\n\t}\n#ifndef WITH_OPENSSL\n\tif ((cc->cipher->flags & CFLAG_AESCTR) != 0) {\n\t\taesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);\n\t\taesctr_ivsetup(&cc->ac_ctx, iv);\n\t\tret = 0;\n\t\tgoto out;\n\t}\n\tif ((cc->cipher->flags & CFLAG_NONE) != 0) {\n\t\tret = 0;\n\t\tgoto out;\n\t}\n\tret = SSH_ERR_INVALID_ARGUMENT;\n\tgoto out;\n#else /* WITH_OPENSSL */\n\ttype = (*cipher->evptype)();\n\tif ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) {\n\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,\n\t (do_encrypt == CIPHER_ENCRYPT)) == 0) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif (cipher_authlen(cipher) &&\n\t !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,\n\t -1, (u_char *)iv)) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tklen = EVP_CIPHER_CTX_key_length(cc->evp);\n\tif (klen > 0 && keylen != (u_int)klen) {\n\t\tif (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) {\n\t\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t}\n\tif (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {\n\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\n\tif (cipher->discard_len > 0) {\n\t\tif ((junk = malloc(cipher->discard_len)) == NULL ||\n\t\t (discard = malloc(cipher->discard_len)) == NULL) {\n\t\t\tfree(junk);\n\t\t\tret = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len);\n\t\texplicit_bzero(discard, cipher->discard_len);\n\t\tfree(junk);\n\t\tfree(discard);\n\t\tif (ret != 1) {\n\t\t\tret = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t}\n\tret = 0;\n#endif /* WITH_OPENSSL */\n out:\n\tif (ret == 0) {\n\t\t/* success */\n\t\t*ccp = cc;\n\t} else {\n\t\tif (cc != NULL) {\n#ifdef WITH_OPENSSL\n\t\t\tif (cc->evp != NULL)\n\t\t\t\tEVP_CIPHER_CTX_free(cc->evp);\n#endif /* WITH_OPENSSL */\n\t\t\texplicit_bzero(cc, sizeof(*cc));\n\t\t\tfree(cc);\n\t\t}\n\t}\n\treturn ret;\n}\n\n/*\n * cipher_crypt() operates as following:\n * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.\n * Theses bytes are treated as additional authenticated data for\n * authenticated encryption modes.\n * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.\n * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.\n * This tag is written on encryption and verified on decryption.\n * Both 'aadlen' and 'authlen' can be set to 0.\n */\nint\ncipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,\n const u_char *src, u_int len, u_int aadlen, u_int authlen)\n{\n\tif ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {\n\t\treturn chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,\n\t\t len, aadlen, authlen, cc->encrypt);\n\t}\n#ifndef WITH_OPENSSL\n\tif ((cc->cipher->flags & CFLAG_AESCTR) != 0) {\n\t\tif (aadlen)\n\t\t\tmemcpy(dest, src, aadlen);\n\t\taesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen,\n\t\t dest + aadlen, len);\n\t\treturn 0;\n\t}\n\tif ((cc->cipher->flags & CFLAG_NONE) != 0) {\n\t\tmemcpy(dest, src, aadlen + len);\n\t\treturn 0;\n\t}\n\treturn SSH_ERR_INVALID_ARGUMENT;\n#else\n\tif (authlen) {\n\t\tu_char lastiv[1];\n\n\t\tif (authlen != cipher_authlen(cc->cipher))\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\t/* increment IV */\n\t\tif (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,\n\t\t 1, lastiv))\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t\t/* set tag on decyption */\n\t\tif (!cc->encrypt &&\n\t\t !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG,\n\t\t authlen, (u_char *)src + aadlen + len))\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t}\n\tif (aadlen) {\n\t\tif (authlen &&\n\t\t EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0)\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t\tmemcpy(dest, src, aadlen);\n\t}\n\tif (len % cc->cipher->block_size)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen,\n\t len) < 0)\n\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\tif (authlen) {\n\t\t/* compute tag (on encrypt) or verify tag (on decrypt) */\n\t\tif (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0)\n\t\t\treturn cc->encrypt ?\n\t\t\t SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID;\n\t\tif (cc->encrypt &&\n\t\t !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG,\n\t\t authlen, dest + aadlen + len))\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t}\n\treturn 0;\n#endif\n}\n\n/* Extract the packet length, including any decryption necessary beforehand */\nint\ncipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr,\n const u_char *cp, u_int len)\n{\n\tif ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)\n\t\treturn chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,\n\t\t cp, len);\n\tif (len < 4)\n\t\treturn SSH_ERR_MESSAGE_INCOMPLETE;\n\t*plenp = get_u32(cp);\n\treturn 0;\n}\n\nvoid\ncipher_free(struct sshcipher_ctx *cc)\n{\n\tif (cc == NULL)\n\t\treturn;\n\tif ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)\n\t\texplicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));\n\telse if ((cc->cipher->flags & CFLAG_AESCTR) != 0)\n\t\texplicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx));\n#ifdef WITH_OPENSSL\n\tif (cc->evp != NULL) {\n\t\tEVP_CIPHER_CTX_free(cc->evp);\n\t\tcc->evp = NULL;\n\t}\n#endif\n\texplicit_bzero(cc, sizeof(*cc));\n\tfree(cc);\n}\n\n/*\n * Selects the cipher, and keys if by computing the MD5 checksum of the\n * passphrase and using the resulting 16 bytes as the key.\n */\nint\ncipher_set_key_string(struct sshcipher_ctx **ccp,\n const struct sshcipher *cipher, const char *passphrase, int do_encrypt)\n{\n\tu_char digest[16];\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\tif ((r = ssh_digest_memory(SSH_DIGEST_MD5,\n\t passphrase, strlen(passphrase),\n\t digest, sizeof(digest))) != 0)\n\t\tgoto out;\n\n\tr = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt);\n out:\n\texplicit_bzero(digest, sizeof(digest));\n\treturn r;\n}\n\n/*\n * Exports an IV from the sshcipher_ctx required to export the key\n * state back from the unprivileged child to the privileged parent\n * process.\n */\nint\ncipher_get_keyiv_len(const struct sshcipher_ctx *cc)\n{\n\tconst struct sshcipher *c = cc->cipher;\n\tint ivlen = 0;\n\n\tif (c->number == SSH_CIPHER_3DES)\n\t\tivlen = 24;\n\telse if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)\n\t\tivlen = 0;\n\telse if ((cc->cipher->flags & CFLAG_AESCTR) != 0)\n\t\tivlen = sizeof(cc->ac_ctx.ctr);\n#ifdef WITH_OPENSSL\n\telse\n\t\tivlen = EVP_CIPHER_CTX_iv_length(cc->evp);\n#endif /* WITH_OPENSSL */\n\treturn (ivlen);\n}\n\nint\ncipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)\n{\n\tconst struct sshcipher *c = cc->cipher;\n#ifdef WITH_OPENSSL\n \tint evplen;\n#endif\n\n\tif ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {\n\t\tif (len != 0)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\treturn 0;\n\t}\n\tif ((cc->cipher->flags & CFLAG_AESCTR) != 0) {\n\t\tif (len != sizeof(cc->ac_ctx.ctr))\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\tmemcpy(iv, cc->ac_ctx.ctr, len);\n\t\treturn 0;\n\t}\n\tif ((cc->cipher->flags & CFLAG_NONE) != 0)\n\t\treturn 0;\n\n\tswitch (c->number) {\n#ifdef WITH_OPENSSL\n\tcase SSH_CIPHER_SSH2:\n\tcase SSH_CIPHER_DES:\n\tcase SSH_CIPHER_BLOWFISH:\n\t\tevplen = EVP_CIPHER_CTX_iv_length(cc->evp);\n\t\tif (evplen == 0)\n\t\t\treturn 0;\n\t\telse if (evplen < 0)\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t\tif ((u_int)evplen != len)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n#ifndef OPENSSL_HAVE_EVPCTR\n\t\tif (c->evptype == evp_aes_128_ctr)\n\t\t\tssh_aes_ctr_iv(cc->evp, 0, iv, len);\n\t\telse\n#endif\n\t\tif (cipher_authlen(c)) {\n\t\t\tif (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,\n\t\t\t len, iv))\n\t\t\t return SSH_ERR_LIBCRYPTO_ERROR;\n\t\t} else\n\t\t\tmemcpy(iv, cc->evp->iv, len);\n\t\tbreak;\n#endif\n#ifdef WITH_SSH1\n\tcase SSH_CIPHER_3DES:\n\t\treturn ssh1_3des_iv(cc->evp, 0, iv, 24);\n#endif\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n\treturn 0;\n}\n\nint\ncipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)\n{\n\tconst struct sshcipher *c = cc->cipher;\n#ifdef WITH_OPENSSL\n \tint evplen = 0;\n#endif\n\n\tif ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)\n\t\treturn 0;\n\tif ((cc->cipher->flags & CFLAG_NONE) != 0)\n\t\treturn 0;\n\n\tswitch (c->number) {\n#ifdef WITH_OPENSSL\n\tcase SSH_CIPHER_SSH2:\n\tcase SSH_CIPHER_DES:\n\tcase SSH_CIPHER_BLOWFISH:\n\t\tevplen = EVP_CIPHER_CTX_iv_length(cc->evp);\n\t\tif (evplen <= 0)\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n#ifndef OPENSSL_HAVE_EVPCTR\n\t\t/* XXX iv arg is const, but ssh_aes_ctr_iv isn't */\n\t\tif (c->evptype == evp_aes_128_ctr)\n\t\t\tssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen);\n\t\telse\n#endif\n\t\tif (cipher_authlen(c)) {\n\t\t\t/* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */\n\t\t\tif (!EVP_CIPHER_CTX_ctrl(cc->evp,\n\t\t\t EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))\n\t\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t\t} else\n\t\t\tmemcpy(cc->evp->iv, iv, evplen);\n\t\tbreak;\n#endif\n#ifdef WITH_SSH1\n\tcase SSH_CIPHER_3DES:\n\t\treturn ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24);\n#endif\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n\treturn 0;\n}\n\n#ifdef WITH_OPENSSL\n#define EVP_X_STATE(evp)\t(evp)->cipher_data\n#define EVP_X_STATE_LEN(evp)\t(evp)->cipher->ctx_size\n#endif\n\nint\ncipher_get_keycontext(const struct sshcipher_ctx *cc, u_char *dat)\n{\n#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4)\n\tconst struct sshcipher *c = cc->cipher;\n\tint plen = 0;\n\n\tif (c->evptype == EVP_rc4) {\n\t\tplen = EVP_X_STATE_LEN(cc->evp);\n\t\tif (dat == NULL)\n\t\t\treturn (plen);\n\t\tmemcpy(dat, EVP_X_STATE(cc->evp), plen);\n\t}\n\treturn (plen);\n#else\n\treturn 0;\n#endif\n}\n\nvoid\ncipher_set_keycontext(struct sshcipher_ctx *cc, const u_char *dat)\n{\n#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4)\n\tconst struct sshcipher *c = cc->cipher;\n\tint plen;\n\n\tif (c->evptype == EVP_rc4) {\n\t\tplen = EVP_X_STATE_LEN(cc->evp);\n\t\tmemcpy(EVP_X_STATE(cc->evp), dat, plen);\n\t}\n#endif\n}\n","/* $OpenBSD: cipher-aesctr.c,v 1.2 2015/01/14 10:24:42 markus Exp $ */\n/*\n * Copyright (c) 2003 Markus Friedl. All rights reserved.\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#ifndef WITH_OPENSSL\n\n#include \"cipher-aesctr.h\"\n\n/*\n * increment counter 'ctr',\n * the counter is of size 'len' bytes and stored in network-byte-order.\n * (LSB at ctr[len-1], MSB at ctr[0])\n */\nstatic inline void\naesctr_inc(u8 *ctr, u32 len)\n{\n\tssize_t i;\n\n#ifndef CONSTANT_TIME_INCREMENT\n\tfor (i = len - 1; i >= 0; i--)\n\t\tif (++ctr[i])\t/* continue on overflow */\n\t\t\treturn;\n#else\n\tu8 x, add = 1;\n\n\tfor (i = len - 1; i >= 0; i--) {\n\t\tctr[i] += add;\n\t\t/* constant time for: x = ctr[i] ? 1 : 0 */\n\t\tx = ctr[i];\n\t\tx = (x | (x >> 4)) & 0xf;\n\t\tx = (x | (x >> 2)) & 0x3;\n\t\tx = (x | (x >> 1)) & 0x1;\n\t\tadd *= (x^1);\n\t}\n#endif\n}\n\nvoid\naesctr_keysetup(aesctr_ctx *x,const u8 *k,u32 kbits,u32 ivbits)\n{\n\tx->rounds = rijndaelKeySetupEnc(x->ek, k, kbits);\n}\n\nvoid\naesctr_ivsetup(aesctr_ctx *x,const u8 *iv)\n{\n\tmemcpy(x->ctr, iv, AES_BLOCK_SIZE);\n}\n\nvoid\naesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes)\n{\n\tu32 n = 0;\n\tu8 buf[AES_BLOCK_SIZE];\n\n\twhile ((bytes--) > 0) {\n\t\tif (n == 0) {\n\t\t\trijndaelEncrypt(x->ek, x->rounds, x->ctr, buf);\n\t\t\taesctr_inc(x->ctr, AES_BLOCK_SIZE);\n\t\t}\n\t\t*(c++) = *(m++) ^ buf[n];\n\t\tn = (n + 1) % AES_BLOCK_SIZE;\n\t}\n}\n#endif /* !WITH_OPENSSL */\n","/* $OpenBSD: compat.c,v 1.100 2017/02/03 23:01:19 djm Exp $ */\n/*\n * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"buffer.h\"\n#include \"packet.h\"\n#include \"compat.h\"\n#include \"log.h\"\n#include \"match.h\"\n#include \"kex.h\"\n\nint compat13 = 0;\nint compat20 = 0;\nint datafellows = 0;\n\nvoid\nenable_compat20(void)\n{\n\tif (compat20)\n\t\treturn;\n\tdebug(\"Enabling compatibility mode for protocol 2.0\");\n\tcompat20 = 1;\n}\nvoid\nenable_compat13(void)\n{\n\tdebug(\"Enabling compatibility mode for protocol 1.3\");\n\tcompat13 = 1;\n}\n/* datafellows bug compatibility */\nu_int\ncompat_datafellows(const char *version)\n{\n\tint i;\n\tstatic struct {\n\t\tchar\t*pat;\n\t\tint\tbugs;\n\t} check[] = {\n\t\t{ \"OpenSSH-2.0*,\"\n\t\t \"OpenSSH-2.1*,\"\n\t\t \"OpenSSH_2.1*,\"\n\t\t \"OpenSSH_2.2*\",\tSSH_OLD_SESSIONID|SSH_BUG_BANNER|\n\t\t\t\t\tSSH_OLD_DHGEX|SSH_BUG_NOREKEY|\n\t\t\t\t\tSSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},\n\t\t{ \"OpenSSH_2.3.0*\",\tSSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|\n\t\t\t\t\tSSH_OLD_DHGEX|SSH_BUG_NOREKEY|\n\t\t\t\t\tSSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},\n\t\t{ \"OpenSSH_2.3.*\",\tSSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|\n\t\t\t\t\tSSH_BUG_NOREKEY|SSH_BUG_EXTEOF|\n\t\t\t\t\tSSH_OLD_FORWARD_ADDR},\n\t\t{ \"OpenSSH_2.5.0p1*,\"\n\t\t \"OpenSSH_2.5.1p1*\",\n\t\t\t\t\tSSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|\n\t\t\t\t\tSSH_BUG_NOREKEY|SSH_BUG_EXTEOF|\n\t\t\t\t\tSSH_OLD_FORWARD_ADDR},\n\t\t{ \"OpenSSH_2.5.0*,\"\n\t\t \"OpenSSH_2.5.1*,\"\n\t\t \"OpenSSH_2.5.2*\",\tSSH_OLD_DHGEX|SSH_BUG_NOREKEY|\n\t\t\t\t\tSSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},\n\t\t{ \"OpenSSH_2.5.3*\",\tSSH_BUG_NOREKEY|SSH_BUG_EXTEOF|\n\t\t\t\t\tSSH_OLD_FORWARD_ADDR},\n\t\t{ \"OpenSSH_2.*,\"\n\t\t \"OpenSSH_3.0*,\"\n\t\t \"OpenSSH_3.1*\",\tSSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},\n\t\t{ \"OpenSSH_3.*\",\tSSH_OLD_FORWARD_ADDR },\n\t\t{ \"Sun_SSH_1.0*\",\tSSH_BUG_NOREKEY|SSH_BUG_EXTEOF},\n\t\t{ \"OpenSSH_4*\",\t\t0 },\n\t\t{ \"OpenSSH_5*\",\t\tSSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT},\n\t\t{ \"OpenSSH_6.6.1*\",\tSSH_NEW_OPENSSH},\n\t\t{ \"OpenSSH_6.5*,\"\n\t\t \"OpenSSH_6.6*\",\tSSH_NEW_OPENSSH|SSH_BUG_CURVE25519PAD},\n\t\t{ \"OpenSSH*\",\t\tSSH_NEW_OPENSSH },\n\t\t{ \"*MindTerm*\",\t\t0 },\n\t\t{ \"2.1.0*\",\t\tSSH_BUG_SIGBLOB|SSH_BUG_HMAC|\n\t\t\t\t\tSSH_OLD_SESSIONID|SSH_BUG_DEBUG|\n\t\t\t\t\tSSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE|\n\t\t\t\t\tSSH_BUG_FIRSTKEX },\n\t\t{ \"2.1 *\",\t\tSSH_BUG_SIGBLOB|SSH_BUG_HMAC|\n\t\t\t\t\tSSH_OLD_SESSIONID|SSH_BUG_DEBUG|\n\t\t\t\t\tSSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE|\n\t\t\t\t\tSSH_BUG_FIRSTKEX },\n\t\t{ \"2.0.13*,\"\n\t\t \"2.0.14*,\"\n\t\t \"2.0.15*,\"\n\t\t \"2.0.16*,\"\n\t\t \"2.0.17*,\"\n\t\t \"2.0.18*,\"\n\t\t \"2.0.19*\",\t\tSSH_BUG_SIGBLOB|SSH_BUG_HMAC|\n\t\t\t\t\tSSH_OLD_SESSIONID|SSH_BUG_DEBUG|\n\t\t\t\t\tSSH_BUG_PKSERVICE|SSH_BUG_X11FWD|\n\t\t\t\t\tSSH_BUG_PKOK|SSH_BUG_RSASIGMD5|\n\t\t\t\t\tSSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE|\n\t\t\t\t\tSSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX },\n\t\t{ \"2.0.11*,\"\n\t\t \"2.0.12*\",\t\tSSH_BUG_SIGBLOB|SSH_BUG_HMAC|\n\t\t\t\t\tSSH_OLD_SESSIONID|SSH_BUG_DEBUG|\n\t\t\t\t\tSSH_BUG_PKSERVICE|SSH_BUG_X11FWD|\n\t\t\t\t\tSSH_BUG_PKAUTH|SSH_BUG_PKOK|\n\t\t\t\t\tSSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|\n\t\t\t\t\tSSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX },\n\t\t{ \"2.0.*\",\t\tSSH_BUG_SIGBLOB|SSH_BUG_HMAC|\n\t\t\t\t\tSSH_OLD_SESSIONID|SSH_BUG_DEBUG|\n\t\t\t\t\tSSH_BUG_PKSERVICE|SSH_BUG_X11FWD|\n\t\t\t\t\tSSH_BUG_PKAUTH|SSH_BUG_PKOK|\n\t\t\t\t\tSSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|\n\t\t\t\t\tSSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN|\n\t\t\t\t\tSSH_BUG_FIRSTKEX },\n\t\t{ \"2.2.0*,\"\n\t\t \"2.3.0*\",\t\tSSH_BUG_HMAC|SSH_BUG_DEBUG|\n\t\t\t\t\tSSH_BUG_RSASIGMD5|SSH_BUG_FIRSTKEX },\n\t\t{ \"2.3.*\",\t\tSSH_BUG_DEBUG|SSH_BUG_RSASIGMD5|\n\t\t\t\t\tSSH_BUG_FIRSTKEX },\n\t\t{ \"2.4\",\t\tSSH_OLD_SESSIONID },\t/* Van Dyke */\n\t\t{ \"2.*\",\t\tSSH_BUG_DEBUG|SSH_BUG_FIRSTKEX|\n\t\t\t\t\tSSH_BUG_RFWD_ADDR },\n\t\t{ \"3.0.*\",\t\tSSH_BUG_DEBUG },\n\t\t{ \"3.0 SecureCRT*\",\tSSH_OLD_SESSIONID },\n\t\t{ \"1.7 SecureFX*\",\tSSH_OLD_SESSIONID },\n\t\t{ \"1.2.18*,\"\n\t\t \"1.2.19*,\"\n\t\t \"1.2.20*,\"\n\t\t \"1.2.21*,\"\n\t\t \"1.2.22*\",\t\tSSH_BUG_IGNOREMSG },\n\t\t{ \"1.3.2*\",\t\t/* F-Secure */\n\t\t\t\t\tSSH_BUG_IGNOREMSG },\n\t\t{ \"Cisco-1.*\",\t\tSSH_BUG_DHGEX_LARGE|\n\t\t\t\t\tSSH_BUG_HOSTKEYS },\n\t\t{ \"*SSH Compatible Server*\",\t\t\t/* Netscreen */\n\t\t\t\t\tSSH_BUG_PASSWORDPAD },\n\t\t{ \"*OSU_0*,\"\n\t\t \"OSU_1.0*,\"\n\t\t \"OSU_1.1*,\"\n\t\t \"OSU_1.2*,\"\n\t\t \"OSU_1.3*,\"\n\t\t \"OSU_1.4*,\"\n\t\t \"OSU_1.5alpha1*,\"\n\t\t \"OSU_1.5alpha2*,\"\n\t\t \"OSU_1.5alpha3*\",\tSSH_BUG_PASSWORDPAD },\n\t\t{ \"*SSH_Version_Mapper*\",\n\t\t\t\t\tSSH_BUG_SCANNER },\n\t\t{ \"PuTTY_Local:*,\"\t/* dev versions < Sep 2014 */\n\t\t \"PuTTY-Release-0.5*,\" /* 0.50-0.57, DH-GEX in >=0.52 */\n\t\t \"PuTTY_Release_0.5*,\"\t/* 0.58-0.59 */\n\t\t \"PuTTY_Release_0.60*,\"\n\t\t \"PuTTY_Release_0.61*,\"\n\t\t \"PuTTY_Release_0.62*,\"\n\t\t \"PuTTY_Release_0.63*,\"\n\t\t \"PuTTY_Release_0.64*\",\n\t\t\t\t\tSSH_OLD_DHGEX },\n\t\t{ \"FuTTY*\",\t\tSSH_OLD_DHGEX }, /* Putty Fork */\n\t\t{ \"Probe-*\",\n\t\t\t\t\tSSH_BUG_PROBE },\n\t\t{ \"TeraTerm SSH*,\"\n\t\t \"TTSSH/1.5.*,\"\n\t\t \"TTSSH/2.1*,\"\n\t\t \"TTSSH/2.2*,\"\n\t\t \"TTSSH/2.3*,\"\n\t\t \"TTSSH/2.4*,\"\n\t\t \"TTSSH/2.5*,\"\n\t\t \"TTSSH/2.6*,\"\n\t\t \"TTSSH/2.70*,\"\n\t\t \"TTSSH/2.71*,\"\n\t\t \"TTSSH/2.72*\",\tSSH_BUG_HOSTKEYS },\n\t\t{ \"WinSCP_release_4*,\"\n\t\t \"WinSCP_release_5.0*,\"\n\t\t \"WinSCP_release_5.1*,\"\n\t\t \"WinSCP_release_5.5*,\"\n\t\t \"WinSCP_release_5.6*,\"\n\t\t \"WinSCP_release_5.7,\"\n\t\t \"WinSCP_release_5.7.1,\"\n\t\t \"WinSCP_release_5.7.2,\"\n\t\t \"WinSCP_release_5.7.3,\"\n\t\t \"WinSCP_release_5.7.4\",\n\t\t\t\t\tSSH_OLD_DHGEX },\n\t\t{ NULL,\t\t\t0 }\n\t};\n\n\t/* process table, return first match */\n\tfor (i = 0; check[i].pat; i++) {\n\t\tif (match_pattern_list(version, check[i].pat, 0) == 1) {\n\t\t\tdebug(\"match: %s pat %s compat 0x%08x\",\n\t\t\t version, check[i].pat, check[i].bugs);\n\t\t\tdatafellows = check[i].bugs;\t/* XXX for now */\n\t\t\treturn check[i].bugs;\n\t\t}\n\t}\n\tdebug(\"no match: %s\", version);\n\treturn 0;\n}\n\n#define\tSEP\t\",\"\nint\nproto_spec(const char *spec)\n{\n\tchar *s, *p, *q;\n\tint ret = SSH_PROTO_UNKNOWN;\n\n\tif (spec == NULL)\n\t\treturn ret;\n\tq = s = strdup(spec);\n\tif (s == NULL)\n\t\treturn ret;\n\tfor ((p = strsep(&q, SEP)); p && *p != '\\0'; (p = strsep(&q, SEP))) {\n\t\tswitch (atoi(p)) {\n\t\tcase 1:\n#ifdef WITH_SSH1\n\t\t\tif (ret == SSH_PROTO_UNKNOWN)\n\t\t\t\tret |= SSH_PROTO_1_PREFERRED;\n\t\t\tret |= SSH_PROTO_1;\n#endif\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tret |= SSH_PROTO_2;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tlogit(\"ignoring bad proto spec: '%s'.\", p);\n\t\t\tbreak;\n\t\t}\n\t}\n\tfree(s);\n\treturn ret;\n}\n\nchar *\ncompat_cipher_proposal(char *cipher_prop)\n{\n\tif (!(datafellows & SSH_BUG_BIGENDIANAES))\n\t\treturn cipher_prop;\n\tdebug2(\"%s: original cipher proposal: %s\", __func__, cipher_prop);\n\tif ((cipher_prop = match_filter_list(cipher_prop, \"aes*\")) == NULL)\n\t\tfatal(\"match_filter_list failed\");\n\tdebug2(\"%s: compat cipher proposal: %s\", __func__, cipher_prop);\n\tif (*cipher_prop == '\\0')\n\t\tfatal(\"No supported ciphers found\");\n\treturn cipher_prop;\n}\n\nchar *\ncompat_pkalg_proposal(char *pkalg_prop)\n{\n\tif (!(datafellows & SSH_BUG_RSASIGMD5))\n\t\treturn pkalg_prop;\n\tdebug2(\"%s: original public key proposal: %s\", __func__, pkalg_prop);\n\tif ((pkalg_prop = match_filter_list(pkalg_prop, \"ssh-rsa\")) == NULL)\n\t\tfatal(\"match_filter_list failed\");\n\tdebug2(\"%s: compat public key proposal: %s\", __func__, pkalg_prop);\n\tif (*pkalg_prop == '\\0')\n\t\tfatal(\"No supported PK algorithms found\");\n\treturn pkalg_prop;\n}\n\nchar *\ncompat_kex_proposal(char *p)\n{\n\tif ((datafellows & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0)\n\t\treturn p;\n\tdebug2(\"%s: original KEX proposal: %s\", __func__, p);\n\tif ((datafellows & SSH_BUG_CURVE25519PAD) != 0)\n\t\tif ((p = match_filter_list(p,\n\t\t \"curve25519-sha256@libssh.org\")) == NULL)\n\t\t\tfatal(\"match_filter_list failed\");\n\tif ((datafellows & SSH_OLD_DHGEX) != 0) {\n\t\tif ((p = match_filter_list(p,\n\t\t \"diffie-hellman-group-exchange-sha256,\"\n\t\t \"diffie-hellman-group-exchange-sha1\")) == NULL)\n\t\t\tfatal(\"match_filter_list failed\");\n\t}\n\tdebug2(\"%s: compat KEX proposal: %s\", __func__, p);\n\tif (*p == '\\0')\n\t\tfatal(\"No supported key exchange algorithms found\");\n\treturn p;\n}\n\n","/* $OpenBSD: fatal.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */\n/*\n * Copyright (c) 2002 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n\n#include \"log.h\"\n\n/* Fatal messages. This function never returns. */\n\nvoid\nfatal(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_FATAL, fmt, args);\n\tva_end(args);\n\tcleanup_exit(255);\n}\n","/* $OpenBSD: hostfile.c,v 1.68 2017/03/10 04:26:06 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Functions for manipulating the known hosts files.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n *\n *\n * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved.\n * Copyright (c) 1999 Niels Provos. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"match.h\"\n#include \"sshkey.h\"\n#include \"hostfile.h\"\n#include \"log.h\"\n#include \"misc.h\"\n#include \"ssherr.h\"\n#include \"digest.h\"\n#include \"hmac.h\"\n\nstruct hostkeys {\n\tstruct hostkey_entry *entries;\n\tu_int num_entries;\n};\n\n/* XXX hmac is too easy to dictionary attack; use bcrypt? */\n\nstatic int\nextract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)\n{\n\tchar *p, *b64salt;\n\tu_int b64len;\n\tint ret;\n\n\tif (l < sizeof(HASH_MAGIC) - 1) {\n\t\tdebug2(\"extract_salt: string too short\");\n\t\treturn (-1);\n\t}\n\tif (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) {\n\t\tdebug2(\"extract_salt: invalid magic identifier\");\n\t\treturn (-1);\n\t}\n\ts += sizeof(HASH_MAGIC) - 1;\n\tl -= sizeof(HASH_MAGIC) - 1;\n\tif ((p = memchr(s, HASH_DELIM, l)) == NULL) {\n\t\tdebug2(\"extract_salt: missing salt termination character\");\n\t\treturn (-1);\n\t}\n\n\tb64len = p - s;\n\t/* Sanity check */\n\tif (b64len == 0 || b64len > 1024) {\n\t\tdebug2(\"extract_salt: bad encoded salt length %u\", b64len);\n\t\treturn (-1);\n\t}\n\tb64salt = xmalloc(1 + b64len);\n\tmemcpy(b64salt, s, b64len);\n\tb64salt[b64len] = '\\0';\n\n\tret = __b64_pton(b64salt, salt, salt_len);\n\tfree(b64salt);\n\tif (ret == -1) {\n\t\tdebug2(\"extract_salt: salt decode error\");\n\t\treturn (-1);\n\t}\n\tif (ret != (int)ssh_hmac_bytes(SSH_DIGEST_SHA1)) {\n\t\tdebug2(\"extract_salt: expected salt len %zd, got %d\",\n\t\t ssh_hmac_bytes(SSH_DIGEST_SHA1), ret);\n\t\treturn (-1);\n\t}\n\n\treturn (0);\n}\n\nchar *\nhost_hash(const char *host, const char *name_from_hostfile, u_int src_len)\n{\n\tstruct ssh_hmac_ctx *ctx;\n\tu_char salt[256], result[256];\n\tchar uu_salt[512], uu_result[512];\n\tstatic char encoded[1024];\n\tu_int len;\n\n\tlen = ssh_digest_bytes(SSH_DIGEST_SHA1);\n\n\tif (name_from_hostfile == NULL) {\n\t\t/* Create new salt */\n\t\tarc4random_buf(salt, len);\n\t} else {\n\t\t/* Extract salt from known host entry */\n\t\tif (extract_salt(name_from_hostfile, src_len, salt,\n\t\t sizeof(salt)) == -1)\n\t\t\treturn (NULL);\n\t}\n\n\tif ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL ||\n\t ssh_hmac_init(ctx, salt, len) < 0 ||\n\t ssh_hmac_update(ctx, host, strlen(host)) < 0 ||\n\t ssh_hmac_final(ctx, result, sizeof(result)))\n\t\tfatal(\"%s: ssh_hmac failed\", __func__);\n\tssh_hmac_free(ctx);\n\n\tif (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||\n\t __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)\n\t\tfatal(\"%s: __b64_ntop failed\", __func__);\n\n\tsnprintf(encoded, sizeof(encoded), \"%s%s%c%s\", HASH_MAGIC, uu_salt,\n\t HASH_DELIM, uu_result);\n\n\treturn (encoded);\n}\n\n/*\n * Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the\n * pointer over the key. Skips any whitespace at the beginning and at end.\n */\n\nint\nhostfile_read_key(char **cpp, u_int *bitsp, struct sshkey *ret)\n{\n\tchar *cp;\n\tint r;\n\n\t/* Skip leading whitespace. */\n\tfor (cp = *cpp; *cp == ' ' || *cp == '\\t'; cp++)\n\t\t;\n\n\tif ((r = sshkey_read(ret, &cp)) != 0)\n\t\treturn 0;\n\n\t/* Skip trailing whitespace. */\n\tfor (; *cp == ' ' || *cp == '\\t'; cp++)\n\t\t;\n\n\t/* Return results. */\n\t*cpp = cp;\n\tif (bitsp != NULL)\n\t\t*bitsp = sshkey_size(ret);\n\treturn 1;\n}\n\nstatic HostkeyMarker\ncheck_markers(char **cpp)\n{\n\tchar marker[32], *sp, *cp = *cpp;\n\tint ret = MRK_NONE;\n\n\twhile (*cp == '@') {\n\t\t/* Only one marker is allowed */\n\t\tif (ret != MRK_NONE)\n\t\t\treturn MRK_ERROR;\n\t\t/* Markers are terminated by whitespace */\n\t\tif ((sp = strchr(cp, ' ')) == NULL &&\n\t\t (sp = strchr(cp, '\\t')) == NULL)\n\t\t\treturn MRK_ERROR;\n\t\t/* Extract marker for comparison */\n\t\tif (sp <= cp + 1 || sp >= cp + sizeof(marker))\n\t\t\treturn MRK_ERROR;\n\t\tmemcpy(marker, cp, sp - cp);\n\t\tmarker[sp - cp] = '\\0';\n\t\tif (strcmp(marker, CA_MARKER) == 0)\n\t\t\tret = MRK_CA;\n\t\telse if (strcmp(marker, REVOKE_MARKER) == 0)\n\t\t\tret = MRK_REVOKE;\n\t\telse\n\t\t\treturn MRK_ERROR;\n\n\t\t/* Skip past marker and any whitespace that follows it */\n\t\tcp = sp;\n\t\tfor (; *cp == ' ' || *cp == '\\t'; cp++)\n\t\t\t;\n\t}\n\t*cpp = cp;\n\treturn ret;\n}\n\nstruct hostkeys *\ninit_hostkeys(void)\n{\n\tstruct hostkeys *ret = xcalloc(1, sizeof(*ret));\n\n\tret->entries = NULL;\n\treturn ret;\n}\n\nstruct load_callback_ctx {\n\tconst char *host;\n\tu_long num_loaded;\n\tstruct hostkeys *hostkeys;\n};\n\nstatic int\nrecord_hostkey(struct hostkey_foreach_line *l, void *_ctx)\n{\n\tstruct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx;\n\tstruct hostkeys *hostkeys = ctx->hostkeys;\n\tstruct hostkey_entry *tmp;\n\n\tif (l->status == HKF_STATUS_INVALID) {\n\t\t/* XXX make this verbose() in the future */\n\t\tdebug(\"%s:%ld: parse error in hostkeys file\",\n\t\t l->path, l->linenum);\n\t\treturn 0;\n\t}\n\n\tdebug3(\"%s: found %skey type %s in file %s:%lu\", __func__,\n\t l->marker == MRK_NONE ? \"\" :\n\t (l->marker == MRK_CA ? \"ca \" : \"revoked \"),\n\t sshkey_type(l->key), l->path, l->linenum);\n\tif ((tmp = reallocarray(hostkeys->entries,\n\t hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\thostkeys->entries = tmp;\n\thostkeys->entries[hostkeys->num_entries].host = xstrdup(ctx->host);\n\thostkeys->entries[hostkeys->num_entries].file = xstrdup(l->path);\n\thostkeys->entries[hostkeys->num_entries].line = l->linenum;\n\thostkeys->entries[hostkeys->num_entries].key = l->key;\n\tl->key = NULL; /* steal it */\n\thostkeys->entries[hostkeys->num_entries].marker = l->marker;\n\thostkeys->num_entries++;\n\tctx->num_loaded++;\n\n\treturn 0;\n}\n\nvoid\nload_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path)\n{\n\tint r;\n\tstruct load_callback_ctx ctx;\n\n\tctx.host = host;\n\tctx.num_loaded = 0;\n\tctx.hostkeys = hostkeys;\n\n\tif ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, NULL,\n\t HKF_WANT_MATCH|HKF_WANT_PARSE_KEY)) != 0) {\n\t\tif (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT)\n\t\t\tdebug(\"%s: hostkeys_foreach failed for %s: %s\",\n\t\t\t __func__, path, ssh_err(r));\n\t}\n\tif (ctx.num_loaded != 0)\n\t\tdebug3(\"%s: loaded %lu keys from %s\", __func__,\n\t\t ctx.num_loaded, host);\n}\n\nvoid\nfree_hostkeys(struct hostkeys *hostkeys)\n{\n\tu_int i;\n\n\tfor (i = 0; i < hostkeys->num_entries; i++) {\n\t\tfree(hostkeys->entries[i].host);\n\t\tfree(hostkeys->entries[i].file);\n\t\tsshkey_free(hostkeys->entries[i].key);\n\t\texplicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries));\n\t}\n\tfree(hostkeys->entries);\n\texplicit_bzero(hostkeys, sizeof(*hostkeys));\n\tfree(hostkeys);\n}\n\nstatic int\ncheck_key_not_revoked(struct hostkeys *hostkeys, struct sshkey *k)\n{\n\tint is_cert = sshkey_is_cert(k);\n\tu_int i;\n\n\tfor (i = 0; i < hostkeys->num_entries; i++) {\n\t\tif (hostkeys->entries[i].marker != MRK_REVOKE)\n\t\t\tcontinue;\n\t\tif (sshkey_equal_public(k, hostkeys->entries[i].key))\n\t\t\treturn -1;\n\t\tif (is_cert &&\n\t\t sshkey_equal_public(k->cert->signature_key,\n\t\t hostkeys->entries[i].key))\n\t\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n/*\n * Match keys against a specified key, or look one up by key type.\n *\n * If looking for a keytype (key == NULL) and one is found then return\n * HOST_FOUND, otherwise HOST_NEW.\n *\n * If looking for a key (key != NULL):\n * 1. If the key is a cert and a matching CA is found, return HOST_OK\n * 2. If the key is not a cert and a matching key is found, return HOST_OK\n * 3. If no key matches but a key with a different type is found, then\n * return HOST_CHANGED\n * 4. If no matching keys are found, then return HOST_NEW.\n *\n * Finally, check any found key is not revoked.\n */\nstatic HostStatus\ncheck_hostkeys_by_key_or_type(struct hostkeys *hostkeys,\n struct sshkey *k, int keytype, const struct hostkey_entry **found)\n{\n\tu_int i;\n\tHostStatus end_return = HOST_NEW;\n\tint want_cert = sshkey_is_cert(k);\n\tHostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE;\n\tint proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2;\n\n\tif (found != NULL)\n\t\t*found = NULL;\n\n\tfor (i = 0; i < hostkeys->num_entries; i++) {\n\t\tif (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1)\n\t\t\tcontinue;\n\t\tif (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1)\n\t\t\tcontinue;\n\t\tif (hostkeys->entries[i].marker != want_marker)\n\t\t\tcontinue;\n\t\tif (k == NULL) {\n\t\t\tif (hostkeys->entries[i].key->type != keytype)\n\t\t\t\tcontinue;\n\t\t\tend_return = HOST_FOUND;\n\t\t\tif (found != NULL)\n\t\t\t\t*found = hostkeys->entries + i;\n\t\t\tk = hostkeys->entries[i].key;\n\t\t\tbreak;\n\t\t}\n\t\tif (want_cert) {\n\t\t\tif (sshkey_equal_public(k->cert->signature_key,\n\t\t\t hostkeys->entries[i].key)) {\n\t\t\t\t/* A matching CA exists */\n\t\t\t\tend_return = HOST_OK;\n\t\t\t\tif (found != NULL)\n\t\t\t\t\t*found = hostkeys->entries + i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (sshkey_equal(k, hostkeys->entries[i].key)) {\n\t\t\t\tend_return = HOST_OK;\n\t\t\t\tif (found != NULL)\n\t\t\t\t\t*found = hostkeys->entries + i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* A non-maching key exists */\n\t\t\tend_return = HOST_CHANGED;\n\t\t\tif (found != NULL)\n\t\t\t\t*found = hostkeys->entries + i;\n\t\t}\n\t}\n\tif (check_key_not_revoked(hostkeys, k) != 0) {\n\t\tend_return = HOST_REVOKED;\n\t\tif (found != NULL)\n\t\t\t*found = NULL;\n\t}\n\treturn end_return;\n}\n\nHostStatus\ncheck_key_in_hostkeys(struct hostkeys *hostkeys, struct sshkey *key,\n const struct hostkey_entry **found)\n{\n\tif (key == NULL)\n\t\tfatal(\"no key to look up\");\n\treturn check_hostkeys_by_key_or_type(hostkeys, key, 0, found);\n}\n\nint\nlookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype,\n const struct hostkey_entry **found)\n{\n\treturn (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype,\n\t found) == HOST_FOUND);\n}\n\nstatic int\nwrite_host_entry(FILE *f, const char *host, const char *ip,\n const struct sshkey *key, int store_hash)\n{\n\tint r, success = 0;\n\tchar *hashed_host = NULL, *lhost;\n\n\tlhost = xstrdup(host);\n\tlowercase(lhost);\n\n\tif (store_hash) {\n\t\tif ((hashed_host = host_hash(lhost, NULL, 0)) == NULL) {\n\t\t\terror(\"%s: host_hash failed\", __func__);\n\t\t\tfree(lhost);\n\t\t\treturn 0;\n\t\t}\n\t\tfprintf(f, \"%s \", hashed_host);\n\t} else if (ip != NULL)\n\t\tfprintf(f, \"%s,%s \", lhost, ip);\n\telse {\n\t\tfprintf(f, \"%s \", lhost);\n\t}\n\tfree(lhost);\n\tif ((r = sshkey_write(key, f)) == 0)\n\t\tsuccess = 1;\n\telse\n\t\terror(\"%s: sshkey_write failed: %s\", __func__, ssh_err(r));\n\tfputc('\\n', f);\n\treturn success;\n}\n\n/*\n * Appends an entry to the host file. Returns false if the entry could not\n * be appended.\n */\nint\nadd_host_to_hostfile(const char *filename, const char *host,\n const struct sshkey *key, int store_hash)\n{\n\tFILE *f;\n\tint success;\n\n\tif (key == NULL)\n\t\treturn 1;\t/* XXX ? */\n\tf = fopen(filename, \"a\");\n\tif (!f)\n\t\treturn 0;\n\tsuccess = write_host_entry(f, host, NULL, key, store_hash);\n\tfclose(f);\n\treturn success;\n}\n\nstruct host_delete_ctx {\n\tFILE *out;\n\tint quiet;\n\tconst char *host;\n\tint *skip_keys; /* XXX split for host/ip? might want to ensure both */\n\tstruct sshkey * const *keys;\n\tsize_t nkeys;\n\tint modified;\n};\n\nstatic int\nhost_delete(struct hostkey_foreach_line *l, void *_ctx)\n{\n\tstruct host_delete_ctx *ctx = (struct host_delete_ctx *)_ctx;\n\tint loglevel = ctx->quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE;\n\tsize_t i;\n\n\tif (l->status == HKF_STATUS_MATCHED) {\n\t\tif (l->marker != MRK_NONE) {\n\t\t\t/* Don't remove CA and revocation lines */\n\t\t\tfprintf(ctx->out, \"%s\\n\", l->line);\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* XXX might need a knob for this later */\n\t\t/* Don't remove RSA1 keys */\n\t\tif (l->key->type == KEY_RSA1) {\n\t\t\tfprintf(ctx->out, \"%s\\n\", l->line);\n\t\t\treturn 0;\n\t\t}\n\n\t\t/*\n\t\t * If this line contains one of the keys that we will be\n\t\t * adding later, then don't change it and mark the key for\n\t\t * skipping.\n\t\t */\n\t\tfor (i = 0; i < ctx->nkeys; i++) {\n\t\t\tif (sshkey_equal(ctx->keys[i], l->key)) {\n\t\t\t\tctx->skip_keys[i] = 1;\n\t\t\t\tfprintf(ctx->out, \"%s\\n\", l->line);\n\t\t\t\tdebug3(\"%s: %s key already at %s:%ld\", __func__,\n\t\t\t\t sshkey_type(l->key), l->path, l->linenum);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * Hostname matches and has no CA/revoke marker, delete it\n\t\t * by *not* writing the line to ctx->out.\n\t\t */\n\t\tdo_log2(loglevel, \"%s%s%s:%ld: Removed %s key for host %s\",\n\t\t ctx->quiet ? __func__ : \"\", ctx->quiet ? \": \" : \"\",\n\t\t l->path, l->linenum, sshkey_type(l->key), ctx->host);\n\t\tctx->modified = 1;\n\t\treturn 0;\n\t}\n\t/* Retain non-matching hosts and invalid lines when deleting */\n\tif (l->status == HKF_STATUS_INVALID) {\n\t\tdo_log2(loglevel, \"%s%s%s:%ld: invalid known_hosts entry\",\n\t\t ctx->quiet ? __func__ : \"\", ctx->quiet ? \": \" : \"\",\n\t\t l->path, l->linenum);\n\t}\n\tfprintf(ctx->out, \"%s\\n\", l->line);\n\treturn 0;\n}\n\nint\nhostfile_replace_entries(const char *filename, const char *host, const char *ip,\n struct sshkey **keys, size_t nkeys, int store_hash, int quiet, int hash_alg)\n{\n\tint r, fd, oerrno = 0;\n\tint loglevel = quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE;\n\tstruct host_delete_ctx ctx;\n\tchar *fp, *temp = NULL, *back = NULL;\n\tmode_t omask;\n\tsize_t i;\n\n\tomask = umask(077);\n\n\tmemset(&ctx, 0, sizeof(ctx));\n\tctx.host = host;\n\tctx.quiet = quiet;\n\tif ((ctx.skip_keys = calloc(nkeys, sizeof(*ctx.skip_keys))) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tctx.keys = keys;\n\tctx.nkeys = nkeys;\n\tctx.modified = 0;\n\n\t/*\n\t * Prepare temporary file for in-place deletion.\n\t */\n\tif ((r = asprintf(&temp, \"%s.XXXXXXXXXXX\", filename)) < 0 ||\n\t (r = asprintf(&back, \"%s.old\", filename)) < 0) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto fail;\n\t}\n\n\tif ((fd = mkstemp(temp)) == -1) {\n\t\toerrno = errno;\n\t\terror(\"%s: mkstemp: %s\", __func__, strerror(oerrno));\n\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\tgoto fail;\n\t}\n\tif ((ctx.out = fdopen(fd, \"w\")) == NULL) {\n\t\toerrno = errno;\n\t\tclose(fd);\n\t\terror(\"%s: fdopen: %s\", __func__, strerror(oerrno));\n\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\tgoto fail;\n\t}\n\n\t/* Remove all entries for the specified host from the file */\n\tif ((r = hostkeys_foreach(filename, host_delete, &ctx, host, ip,\n\t HKF_WANT_PARSE_KEY)) != 0) {\n\t\terror(\"%s: hostkeys_foreach failed: %s\", __func__, ssh_err(r));\n\t\tgoto fail;\n\t}\n\n\t/* Add the requested keys */\n\tfor (i = 0; i < nkeys; i++) {\n\t\tif (ctx.skip_keys[i])\n\t\t\tcontinue;\n\t\tif ((fp = sshkey_fingerprint(keys[i], hash_alg,\n\t\t SSH_FP_DEFAULT)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto fail;\n\t\t}\n\t\tdo_log2(loglevel, \"%s%sAdding new key for %s to %s: %s %s\",\n\t\t quiet ? __func__ : \"\", quiet ? \": \" : \"\", host, filename,\n\t\t sshkey_ssh_name(keys[i]), fp);\n\t\tfree(fp);\n\t\tif (!write_host_entry(ctx.out, host, ip, keys[i], store_hash)) {\n\t\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\t\tgoto fail;\n\t\t}\n\t\tctx.modified = 1;\n\t}\n\tfclose(ctx.out);\n\tctx.out = NULL;\n\n\tif (ctx.modified) {\n\t\t/* Backup the original file and replace it with the temporary */\n\t\tif (unlink(back) == -1 && errno != ENOENT) {\n\t\t\toerrno = errno;\n\t\t\terror(\"%s: unlink %.100s: %s\", __func__,\n\t\t\t back, strerror(errno));\n\t\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\t\tgoto fail;\n\t\t}\n\t\tif (link(filename, back) == -1) {\n\t\t\toerrno = errno;\n\t\t\terror(\"%s: link %.100s to %.100s: %s\", __func__,\n\t\t\t filename, back, strerror(errno));\n\t\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\t\tgoto fail;\n\t\t}\n\t\tif (rename(temp, filename) == -1) {\n\t\t\toerrno = errno;\n\t\t\terror(\"%s: rename \\\"%s\\\" to \\\"%s\\\": %s\", __func__,\n\t\t\t temp, filename, strerror(errno));\n\t\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\t\tgoto fail;\n\t\t}\n\t} else {\n\t\t/* No changes made; just delete the temporary file */\n\t\tif (unlink(temp) != 0)\n\t\t\terror(\"%s: unlink \\\"%s\\\": %s\", __func__,\n\t\t\t temp, strerror(errno));\n\t}\n\n\t/* success */\n\tr = 0;\n fail:\n\tif (temp != NULL && r != 0)\n\t\tunlink(temp);\n\tfree(temp);\n\tfree(back);\n\tif (ctx.out != NULL)\n\t\tfclose(ctx.out);\n\tfree(ctx.skip_keys);\n\tumask(omask);\n\tif (r == SSH_ERR_SYSTEM_ERROR)\n\t\terrno = oerrno;\n\treturn r;\n}\n\nstatic int\nmatch_maybe_hashed(const char *host, const char *names, int *was_hashed)\n{\n\tint hashed = *names == HASH_DELIM;\n\tconst char *hashed_host;\n\tsize_t nlen = strlen(names);\n\n\tif (was_hashed != NULL)\n\t\t*was_hashed = hashed;\n\tif (hashed) {\n\t\tif ((hashed_host = host_hash(host, names, nlen)) == NULL)\n\t\t\treturn -1;\n\t\treturn nlen == strlen(hashed_host) &&\n\t\t strncmp(hashed_host, names, nlen) == 0;\n\t}\n\treturn match_hostname(host, names) == 1;\n}\n\nint\nhostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,\n const char *host, const char *ip, u_int options)\n{\n\tFILE *f;\n\tchar line[8192], oline[8192], ktype[128];\n\tu_long linenum = 0;\n\tchar *cp, *cp2;\n\tu_int kbits;\n\tint hashed;\n\tint s, r = 0;\n\tstruct hostkey_foreach_line lineinfo;\n\tsize_t l;\n\n\tmemset(&lineinfo, 0, sizeof(lineinfo));\n\tif (host == NULL && (options & HKF_WANT_MATCH) != 0)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif ((f = fopen(path, \"r\")) == NULL)\n\t\treturn SSH_ERR_SYSTEM_ERROR;\n\n\tdebug3(\"%s: reading file \\\"%s\\\"\", __func__, path);\n\twhile (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) {\n\t\tline[strcspn(line, \"\\n\")] = '\\0';\n\t\tstrlcpy(oline, line, sizeof(oline));\n\n\t\tsshkey_free(lineinfo.key);\n\t\tmemset(&lineinfo, 0, sizeof(lineinfo));\n\t\tlineinfo.path = path;\n\t\tlineinfo.linenum = linenum;\n\t\tlineinfo.line = oline;\n\t\tlineinfo.marker = MRK_NONE;\n\t\tlineinfo.status = HKF_STATUS_OK;\n\t\tlineinfo.keytype = KEY_UNSPEC;\n\n\t\t/* Skip any leading whitespace, comments and empty lines. */\n\t\tfor (cp = line; *cp == ' ' || *cp == '\\t'; cp++)\n\t\t\t;\n\t\tif (!*cp || *cp == '#' || *cp == '\\n') {\n\t\t\tif ((options & HKF_WANT_MATCH) == 0) {\n\t\t\t\tlineinfo.status = HKF_STATUS_COMMENT;\n\t\t\t\tif ((r = callback(&lineinfo, ctx)) != 0)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((lineinfo.marker = check_markers(&cp)) == MRK_ERROR) {\n\t\t\tverbose(\"%s: invalid marker at %s:%lu\",\n\t\t\t __func__, path, linenum);\n\t\t\tif ((options & HKF_WANT_MATCH) == 0)\n\t\t\t\tgoto bad;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Find the end of the host name portion. */\n\t\tfor (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\\t'; cp2++)\n\t\t\t;\n\t\tlineinfo.hosts = cp;\n\t\t*cp2++ = '\\0';\n\n\t\t/* Check if the host name matches. */\n\t\tif (host != NULL) {\n\t\t\tif ((s = match_maybe_hashed(host, lineinfo.hosts,\n\t\t\t &hashed)) == -1) {\n\t\t\t\tdebug2(\"%s: %s:%ld: bad host hash \\\"%.32s\\\"\",\n\t\t\t\t __func__, path, linenum, lineinfo.hosts);\n\t\t\t\tgoto bad;\n\t\t\t}\n\t\t\tif (s == 1) {\n\t\t\t\tlineinfo.status = HKF_STATUS_MATCHED;\n\t\t\t\tlineinfo.match |= HKF_MATCH_HOST |\n\t\t\t\t (hashed ? HKF_MATCH_HOST_HASHED : 0);\n\t\t\t}\n\t\t\t/* Try matching IP address if supplied */\n\t\t\tif (ip != NULL) {\n\t\t\t\tif ((s = match_maybe_hashed(ip, lineinfo.hosts,\n\t\t\t\t &hashed)) == -1) {\n\t\t\t\t\tdebug2(\"%s: %s:%ld: bad ip hash \"\n\t\t\t\t\t \"\\\"%.32s\\\"\", __func__, path,\n\t\t\t\t\t linenum, lineinfo.hosts);\n\t\t\t\t\tgoto bad;\n\t\t\t\t}\n\t\t\t\tif (s == 1) {\n\t\t\t\t\tlineinfo.status = HKF_STATUS_MATCHED;\n\t\t\t\t\tlineinfo.match |= HKF_MATCH_IP |\n\t\t\t\t\t (hashed ? HKF_MATCH_IP_HASHED : 0);\n\t\t\t\t}\n\t\t\t}\n\t\t\t/*\n\t\t\t * Skip this line if host matching requested and\n\t\t\t * neither host nor address matched.\n\t\t\t */\n\t\t\tif ((options & HKF_WANT_MATCH) != 0 &&\n\t\t\t lineinfo.status != HKF_STATUS_MATCHED)\n\t\t\t\tcontinue;\n\t\t}\n\n\t\t/* Got a match. Skip host name and any following whitespace */\n\t\tfor (; *cp2 == ' ' || *cp2 == '\\t'; cp2++)\n\t\t\t;\n\t\tif (*cp2 == '\\0' || *cp2 == '#') {\n\t\t\tdebug2(\"%s:%ld: truncated before key type\",\n\t\t\t path, linenum);\n\t\t\tgoto bad;\n\t\t}\n\t\tlineinfo.rawkey = cp = cp2;\n\n\t\tif ((options & HKF_WANT_PARSE_KEY) != 0) {\n\t\t\t/*\n\t\t\t * Extract the key from the line. This will skip\n\t\t\t * any leading whitespace. Ignore badly formatted\n\t\t\t * lines.\n\t\t\t */\n\t\t\tif ((lineinfo.key = sshkey_new(KEY_UNSPEC)) == NULL) {\n\t\t\t\terror(\"%s: sshkey_new failed\", __func__);\n\t\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!hostfile_read_key(&cp, &kbits, lineinfo.key)) {\n#ifdef WITH_SSH1\n\t\t\t\tsshkey_free(lineinfo.key);\n\t\t\t\tlineinfo.key = sshkey_new(KEY_RSA1);\n\t\t\t\tif (lineinfo.key == NULL) {\n\t\t\t\t\terror(\"%s: sshkey_new fail\", __func__);\n\t\t\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!hostfile_read_key(&cp, &kbits,\n\t\t\t\t lineinfo.key))\n\t\t\t\t\tgoto bad;\n#else\n\t\t\t\tgoto bad;\n#endif\n\t\t\t}\n\t\t\tlineinfo.keytype = lineinfo.key->type;\n\t\t\tlineinfo.comment = cp;\n\t\t} else {\n\t\t\t/* Extract and parse key type */\n\t\t\tl = strcspn(lineinfo.rawkey, \" \\t\");\n\t\t\tif (l <= 1 || l >= sizeof(ktype) ||\n\t\t\t lineinfo.rawkey[l] == '\\0')\n\t\t\t\tgoto bad;\n\t\t\tmemcpy(ktype, lineinfo.rawkey, l);\n\t\t\tktype[l] = '\\0';\n\t\t\tlineinfo.keytype = sshkey_type_from_name(ktype);\n\n\t\t\t/*\n\t\t\t * Assume RSA1 if the first component is a short\n\t\t\t * decimal number.\n\t\t\t */\n\t\t\tif (lineinfo.keytype == KEY_UNSPEC && l < 8 &&\n\t\t\t strspn(ktype, \"0123456789\") == l)\n\t\t\t\tlineinfo.keytype = KEY_RSA1;\n\n\t\t\t/*\n\t\t\t * Check that something other than whitespace follows\n\t\t\t * the key type. This won't catch all corruption, but\n\t\t\t * it does catch trivial truncation.\n\t\t\t */\n\t\t\tcp2 += l; /* Skip past key type */\n\t\t\tfor (; *cp2 == ' ' || *cp2 == '\\t'; cp2++)\n\t\t\t\t;\n\t\t\tif (*cp2 == '\\0' || *cp2 == '#') {\n\t\t\t\tdebug2(\"%s:%ld: truncated after key type\",\n\t\t\t\t path, linenum);\n\t\t\t\tlineinfo.keytype = KEY_UNSPEC;\n\t\t\t}\n\t\t\tif (lineinfo.keytype == KEY_UNSPEC) {\n bad:\n\t\t\t\tsshkey_free(lineinfo.key);\n\t\t\t\tlineinfo.key = NULL;\n\t\t\t\tlineinfo.status = HKF_STATUS_INVALID;\n\t\t\t\tif ((r = callback(&lineinfo, ctx)) != 0)\n\t\t\t\t\tbreak;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif ((r = callback(&lineinfo, ctx)) != 0)\n\t\t\tbreak;\n\t}\n\tsshkey_free(lineinfo.key);\n\tfclose(f);\n\treturn r;\n}\n","/* $OpenBSD: log.c,v 1.49 2017/03/10 03:15:58 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n/*\n * Copyright (c) 2000 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)\n# include \n#endif\n\n#include \"log.h\"\n\nstatic LogLevel log_level = SYSLOG_LEVEL_INFO;\nstatic int log_on_stderr = 1;\nstatic int log_stderr_fd = STDERR_FILENO;\nstatic int log_facility = LOG_AUTH;\nstatic char *argv0;\nstatic log_handler_fn *log_handler;\nstatic void *log_handler_ctx;\n\nextern char *__progname;\n\n#define LOG_SYSLOG_VIS\t(VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL)\n#define LOG_STDERR_VIS\t(VIS_SAFE|VIS_OCTAL)\n\n/* textual representation of log-facilities/levels */\n\nstatic struct {\n\tconst char *name;\n\tSyslogFacility val;\n} log_facilities[] = {\n\t{ \"DAEMON\",\tSYSLOG_FACILITY_DAEMON },\n\t{ \"USER\",\tSYSLOG_FACILITY_USER },\n\t{ \"AUTH\",\tSYSLOG_FACILITY_AUTH },\n#ifdef LOG_AUTHPRIV\n\t{ \"AUTHPRIV\",\tSYSLOG_FACILITY_AUTHPRIV },\n#endif\n\t{ \"LOCAL0\",\tSYSLOG_FACILITY_LOCAL0 },\n\t{ \"LOCAL1\",\tSYSLOG_FACILITY_LOCAL1 },\n\t{ \"LOCAL2\",\tSYSLOG_FACILITY_LOCAL2 },\n\t{ \"LOCAL3\",\tSYSLOG_FACILITY_LOCAL3 },\n\t{ \"LOCAL4\",\tSYSLOG_FACILITY_LOCAL4 },\n\t{ \"LOCAL5\",\tSYSLOG_FACILITY_LOCAL5 },\n\t{ \"LOCAL6\",\tSYSLOG_FACILITY_LOCAL6 },\n\t{ \"LOCAL7\",\tSYSLOG_FACILITY_LOCAL7 },\n\t{ NULL,\t\tSYSLOG_FACILITY_NOT_SET }\n};\n\nstatic struct {\n\tconst char *name;\n\tLogLevel val;\n} log_levels[] =\n{\n\t{ \"QUIET\",\tSYSLOG_LEVEL_QUIET },\n\t{ \"FATAL\",\tSYSLOG_LEVEL_FATAL },\n\t{ \"ERROR\",\tSYSLOG_LEVEL_ERROR },\n\t{ \"INFO\",\tSYSLOG_LEVEL_INFO },\n\t{ \"VERBOSE\",\tSYSLOG_LEVEL_VERBOSE },\n\t{ \"DEBUG\",\tSYSLOG_LEVEL_DEBUG1 },\n\t{ \"DEBUG1\",\tSYSLOG_LEVEL_DEBUG1 },\n\t{ \"DEBUG2\",\tSYSLOG_LEVEL_DEBUG2 },\n\t{ \"DEBUG3\",\tSYSLOG_LEVEL_DEBUG3 },\n\t{ NULL,\t\tSYSLOG_LEVEL_NOT_SET }\n};\n\nSyslogFacility\nlog_facility_number(char *name)\n{\n\tint i;\n\n\tif (name != NULL)\n\t\tfor (i = 0; log_facilities[i].name; i++)\n\t\t\tif (strcasecmp(log_facilities[i].name, name) == 0)\n\t\t\t\treturn log_facilities[i].val;\n\treturn SYSLOG_FACILITY_NOT_SET;\n}\n\nconst char *\nlog_facility_name(SyslogFacility facility)\n{\n\tu_int i;\n\n\tfor (i = 0; log_facilities[i].name; i++)\n\t\tif (log_facilities[i].val == facility)\n\t\t\treturn log_facilities[i].name;\n\treturn NULL;\n}\n\nLogLevel\nlog_level_number(char *name)\n{\n\tint i;\n\n\tif (name != NULL)\n\t\tfor (i = 0; log_levels[i].name; i++)\n\t\t\tif (strcasecmp(log_levels[i].name, name) == 0)\n\t\t\t\treturn log_levels[i].val;\n\treturn SYSLOG_LEVEL_NOT_SET;\n}\n\nconst char *\nlog_level_name(LogLevel level)\n{\n\tu_int i;\n\n\tfor (i = 0; log_levels[i].name != NULL; i++)\n\t\tif (log_levels[i].val == level)\n\t\t\treturn log_levels[i].name;\n\treturn NULL;\n}\n\n/* Error messages that should be logged. */\n\nvoid\nerror(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_ERROR, fmt, args);\n\tva_end(args);\n}\n\nvoid\nsigdie(const char *fmt,...)\n{\n#ifdef DO_LOG_SAFE_IN_SIGHAND\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_FATAL, fmt, args);\n\tva_end(args);\n#endif\n\t_exit(1);\n}\n\nvoid\nlogdie(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_INFO, fmt, args);\n\tva_end(args);\n\tcleanup_exit(255);\n}\n\n/* Log this message (information that usually should go to the log). */\n\nvoid\nlogit(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_INFO, fmt, args);\n\tva_end(args);\n}\n\n/* More detailed messages (information that does not need to go to the log). */\n\nvoid\nverbose(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_VERBOSE, fmt, args);\n\tva_end(args);\n}\n\n/* Debugging messages that should not be logged during normal operation. */\n\nvoid\ndebug(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_DEBUG1, fmt, args);\n\tva_end(args);\n}\n\nvoid\ndebug2(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_DEBUG2, fmt, args);\n\tva_end(args);\n}\n\nvoid\ndebug3(const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(SYSLOG_LEVEL_DEBUG3, fmt, args);\n\tva_end(args);\n}\n\n/*\n * Initialize the log.\n */\n\nvoid\nlog_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)\n{\n#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)\n\tstruct syslog_data sdata = SYSLOG_DATA_INIT;\n#endif\n\n\targv0 = av0;\n\n\tswitch (level) {\n\tcase SYSLOG_LEVEL_QUIET:\n\tcase SYSLOG_LEVEL_FATAL:\n\tcase SYSLOG_LEVEL_ERROR:\n\tcase SYSLOG_LEVEL_INFO:\n\tcase SYSLOG_LEVEL_VERBOSE:\n\tcase SYSLOG_LEVEL_DEBUG1:\n\tcase SYSLOG_LEVEL_DEBUG2:\n\tcase SYSLOG_LEVEL_DEBUG3:\n\t\tlog_level = level;\n\t\tbreak;\n\tdefault:\n\t\tfprintf(stderr, \"Unrecognized internal syslog level code %d\\n\",\n\t\t (int) level);\n\t\texit(1);\n\t}\n\n\tlog_handler = NULL;\n\tlog_handler_ctx = NULL;\n\n\tlog_on_stderr = on_stderr;\n\tif (on_stderr)\n\t\treturn;\n\n\tswitch (facility) {\n\tcase SYSLOG_FACILITY_DAEMON:\n\t\tlog_facility = LOG_DAEMON;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_USER:\n\t\tlog_facility = LOG_USER;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_AUTH:\n\t\tlog_facility = LOG_AUTH;\n\t\tbreak;\n#ifdef LOG_AUTHPRIV\n\tcase SYSLOG_FACILITY_AUTHPRIV:\n\t\tlog_facility = LOG_AUTHPRIV;\n\t\tbreak;\n#endif\n\tcase SYSLOG_FACILITY_LOCAL0:\n\t\tlog_facility = LOG_LOCAL0;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_LOCAL1:\n\t\tlog_facility = LOG_LOCAL1;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_LOCAL2:\n\t\tlog_facility = LOG_LOCAL2;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_LOCAL3:\n\t\tlog_facility = LOG_LOCAL3;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_LOCAL4:\n\t\tlog_facility = LOG_LOCAL4;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_LOCAL5:\n\t\tlog_facility = LOG_LOCAL5;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_LOCAL6:\n\t\tlog_facility = LOG_LOCAL6;\n\t\tbreak;\n\tcase SYSLOG_FACILITY_LOCAL7:\n\t\tlog_facility = LOG_LOCAL7;\n\t\tbreak;\n\tdefault:\n\t\tfprintf(stderr,\n\t\t \"Unrecognized internal syslog facility code %d\\n\",\n\t\t (int) facility);\n\t\texit(1);\n\t}\n\n\t/*\n\t * If an external library (eg libwrap) attempts to use syslog\n\t * immediately after reexec, syslog may be pointing to the wrong\n\t * facility, so we force an open/close of syslog here.\n\t */\n#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)\n\topenlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);\n\tcloselog_r(&sdata);\n#else\n\topenlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);\n\tcloselog();\n#endif\n}\n\nvoid\nlog_change_level(LogLevel new_log_level)\n{\n\t/* no-op if log_init has not been called */\n\tif (argv0 == NULL)\n\t\treturn;\n\tlog_init(argv0, new_log_level, log_facility, log_on_stderr);\n}\n\nint\nlog_is_on_stderr(void)\n{\n\treturn log_on_stderr && log_stderr_fd == STDERR_FILENO;\n}\n\n/* redirect what would usually get written to stderr to specified file */\nvoid\nlog_redirect_stderr_to(const char *logfile)\n{\n\tint fd;\n\n\tif ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1) {\n\t\tfprintf(stderr, \"Couldn't open logfile %s: %s\\n\", logfile,\n\t\t strerror(errno));\n\t\texit(1);\n\t}\n\tlog_stderr_fd = fd;\n}\n\n#define MSGBUFSIZ 1024\n\nvoid\nset_log_handler(log_handler_fn *handler, void *ctx)\n{\n\tlog_handler = handler;\n\tlog_handler_ctx = ctx;\n}\n\nvoid\ndo_log2(LogLevel level, const char *fmt,...)\n{\n\tva_list args;\n\n\tva_start(args, fmt);\n\tdo_log(level, fmt, args);\n\tva_end(args);\n}\n\nvoid\ndo_log(LogLevel level, const char *fmt, va_list args)\n{\n#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)\n\tstruct syslog_data sdata = SYSLOG_DATA_INIT;\n#endif\n\tchar msgbuf[MSGBUFSIZ];\n\tchar fmtbuf[MSGBUFSIZ];\n\tchar *txt = NULL;\n\tint pri = LOG_INFO;\n\tint saved_errno = errno;\n\tlog_handler_fn *tmp_handler;\n\n\tif (level > log_level)\n\t\treturn;\n\n\tswitch (level) {\n\tcase SYSLOG_LEVEL_FATAL:\n\t\tif (!log_on_stderr)\n\t\t\ttxt = \"fatal\";\n\t\tpri = LOG_CRIT;\n\t\tbreak;\n\tcase SYSLOG_LEVEL_ERROR:\n\t\tif (!log_on_stderr)\n\t\t\ttxt = \"error\";\n\t\tpri = LOG_ERR;\n\t\tbreak;\n\tcase SYSLOG_LEVEL_INFO:\n\t\tpri = LOG_INFO;\n\t\tbreak;\n\tcase SYSLOG_LEVEL_VERBOSE:\n\t\tpri = LOG_INFO;\n\t\tbreak;\n\tcase SYSLOG_LEVEL_DEBUG1:\n\t\ttxt = \"debug1\";\n\t\tpri = LOG_DEBUG;\n\t\tbreak;\n\tcase SYSLOG_LEVEL_DEBUG2:\n\t\ttxt = \"debug2\";\n\t\tpri = LOG_DEBUG;\n\t\tbreak;\n\tcase SYSLOG_LEVEL_DEBUG3:\n\t\ttxt = \"debug3\";\n\t\tpri = LOG_DEBUG;\n\t\tbreak;\n\tdefault:\n\t\ttxt = \"internal error\";\n\t\tpri = LOG_ERR;\n\t\tbreak;\n\t}\n\tif (txt != NULL && log_handler == NULL) {\n\t\tsnprintf(fmtbuf, sizeof(fmtbuf), \"%s: %s\", txt, fmt);\n\t\tvsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);\n\t} else {\n\t\tvsnprintf(msgbuf, sizeof(msgbuf), fmt, args);\n\t}\n\tstrnvis(fmtbuf, msgbuf, sizeof(fmtbuf),\n\t log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS);\n\tif (log_handler != NULL) {\n\t\t/* Avoid recursion */\n\t\ttmp_handler = log_handler;\n\t\tlog_handler = NULL;\n\t\ttmp_handler(level, fmtbuf, log_handler_ctx);\n\t\tlog_handler = tmp_handler;\n\t} else if (log_on_stderr) {\n\t\tsnprintf(msgbuf, sizeof msgbuf, \"%.*s\\r\\n\",\n\t\t (int)sizeof msgbuf - 3, fmtbuf);\n\t\t(void)write(log_stderr_fd, msgbuf, strlen(msgbuf));\n\t} else {\n#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)\n\t\topenlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);\n\t\tsyslog_r(pri, &sdata, \"%.500s\", fmtbuf);\n\t\tcloselog_r(&sdata);\n#else\n\t\topenlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);\n\t\tsyslog(pri, \"%.500s\", fmtbuf);\n\t\tcloselog();\n#endif\n\t}\n\terrno = saved_errno;\n}\n","/* $OpenBSD: match.c,v 1.37 2017/03/10 04:24:55 djm Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Simple pattern matching, with '*' and '?' as wildcards.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n/*\n * Copyright (c) 2000 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"match.h\"\n#include \"misc.h\"\n\n/*\n * Returns true if the given string matches the pattern (which may contain ?\n * and * as wildcards), and zero if it does not match.\n */\n\nint\nmatch_pattern(const char *s, const char *pattern)\n{\n\tfor (;;) {\n\t\t/* If at end of pattern, accept if also at end of string. */\n\t\tif (!*pattern)\n\t\t\treturn !*s;\n\n\t\tif (*pattern == '*') {\n\t\t\t/* Skip the asterisk. */\n\t\t\tpattern++;\n\n\t\t\t/* If at end of pattern, accept immediately. */\n\t\t\tif (!*pattern)\n\t\t\t\treturn 1;\n\n\t\t\t/* If next character in pattern is known, optimize. */\n\t\t\tif (*pattern != '?' && *pattern != '*') {\n\t\t\t\t/*\n\t\t\t\t * Look instances of the next character in\n\t\t\t\t * pattern, and try to match starting from\n\t\t\t\t * those.\n\t\t\t\t */\n\t\t\t\tfor (; *s; s++)\n\t\t\t\t\tif (*s == *pattern &&\n\t\t\t\t\t match_pattern(s + 1, pattern + 1))\n\t\t\t\t\t\treturn 1;\n\t\t\t\t/* Failed. */\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\t/*\n\t\t\t * Move ahead one character at a time and try to\n\t\t\t * match at each position.\n\t\t\t */\n\t\t\tfor (; *s; s++)\n\t\t\t\tif (match_pattern(s, pattern))\n\t\t\t\t\treturn 1;\n\t\t\t/* Failed. */\n\t\t\treturn 0;\n\t\t}\n\t\t/*\n\t\t * There must be at least one more character in the string.\n\t\t * If we are at the end, fail.\n\t\t */\n\t\tif (!*s)\n\t\t\treturn 0;\n\n\t\t/* Check if the next character of the string is acceptable. */\n\t\tif (*pattern != '?' && *pattern != *s)\n\t\t\treturn 0;\n\n\t\t/* Move to the next character, both in string and in pattern. */\n\t\ts++;\n\t\tpattern++;\n\t}\n\t/* NOTREACHED */\n}\n\n/*\n * Tries to match the string against the\n * comma-separated sequence of subpatterns (each possibly preceded by ! to\n * indicate negation). Returns -1 if negation matches, 1 if there is\n * a positive match, 0 if there is no match at all.\n */\nint\nmatch_pattern_list(const char *string, const char *pattern, int dolower)\n{\n\tchar sub[1024];\n\tint negated;\n\tint got_positive;\n\tu_int i, subi, len = strlen(pattern);\n\n\tgot_positive = 0;\n\tfor (i = 0; i < len;) {\n\t\t/* Check if the subpattern is negated. */\n\t\tif (pattern[i] == '!') {\n\t\t\tnegated = 1;\n\t\t\ti++;\n\t\t} else\n\t\t\tnegated = 0;\n\n\t\t/*\n\t\t * Extract the subpattern up to a comma or end. Convert the\n\t\t * subpattern to lowercase.\n\t\t */\n\t\tfor (subi = 0;\n\t\t i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';\n\t\t subi++, i++)\n\t\t\tsub[subi] = dolower && isupper((u_char)pattern[i]) ?\n\t\t\t tolower((u_char)pattern[i]) : pattern[i];\n\t\t/* If subpattern too long, return failure (no match). */\n\t\tif (subi >= sizeof(sub) - 1)\n\t\t\treturn 0;\n\n\t\t/* If the subpattern was terminated by a comma, then skip it. */\n\t\tif (i < len && pattern[i] == ',')\n\t\t\ti++;\n\n\t\t/* Null-terminate the subpattern. */\n\t\tsub[subi] = '\\0';\n\n\t\t/* Try to match the subpattern against the string. */\n\t\tif (match_pattern(string, sub)) {\n\t\t\tif (negated)\n\t\t\t\treturn -1;\t\t/* Negative */\n\t\t\telse\n\t\t\t\tgot_positive = 1;\t/* Positive */\n\t\t}\n\t}\n\n\t/*\n\t * Return success if got a positive match. If there was a negative\n\t * match, we have already returned -1 and never get here.\n\t */\n\treturn got_positive;\n}\n\n/*\n * Tries to match the host name (which must be in all lowercase) against the\n * comma-separated sequence of subpatterns (each possibly preceded by ! to\n * indicate negation). Returns -1 if negation matches, 1 if there is\n * a positive match, 0 if there is no match at all.\n */\nint\nmatch_hostname(const char *host, const char *pattern)\n{\n\tchar *hostcopy = xstrdup(host);\n\tint r;\n\n\tlowercase(hostcopy);\n\tr = match_pattern_list(hostcopy, pattern, 1);\n\tfree(hostcopy);\n\treturn r;\n}\n\n/*\n * returns 0 if we get a negative match for the hostname or the ip\n * or if we get no match at all. returns -1 on error, or 1 on\n * successful match.\n */\nint\nmatch_host_and_ip(const char *host, const char *ipaddr,\n const char *patterns)\n{\n\tint mhost, mip;\n\n\tif ((mip = addr_match_list(ipaddr, patterns)) == -2)\n\t\treturn -1; /* error in ipaddr match */\n\telse if (host == NULL || ipaddr == NULL || mip == -1)\n\t\treturn 0; /* negative ip address match, or testing pattern */\n\n\t/* negative hostname match */\n\tif ((mhost = match_hostname(host, patterns)) == -1)\n\t\treturn 0;\n\t/* no match at all */\n\tif (mhost == 0 && mip == 0)\n\t\treturn 0;\n\treturn 1;\n}\n\n/*\n * Match user, user@host_or_ip, user@host_or_ip_list against pattern.\n * If user, host and ipaddr are all NULL then validate pattern/\n * Returns -1 on invalid pattern, 0 on no match, 1 on match.\n */\nint\nmatch_user(const char *user, const char *host, const char *ipaddr,\n const char *pattern)\n{\n\tchar *p, *pat;\n\tint ret;\n\n\t/* test mode */\n\tif (user == NULL && host == NULL && ipaddr == NULL) {\n\t\tif ((p = strchr(pattern, '@')) != NULL &&\n\t\t match_host_and_ip(NULL, NULL, p + 1) < 0)\n\t\t\treturn -1;\n\t\treturn 0;\n\t}\n\n\tif ((p = strchr(pattern,'@')) == NULL)\n\t\treturn match_pattern(user, pattern);\n\n\tpat = xstrdup(pattern);\n\tp = strchr(pat, '@');\n\t*p++ = '\\0';\n\n\tif ((ret = match_pattern(user, pat)) == 1)\n\t\tret = match_host_and_ip(host, ipaddr, p);\n\tfree(pat);\n\n\treturn ret;\n}\n\n/*\n * Returns first item from client-list that is also supported by server-list,\n * caller must free the returned string.\n */\n#define\tMAX_PROP\t40\n#define\tSEP\t\",\"\nchar *\nmatch_list(const char *client, const char *server, u_int *next)\n{\n\tchar *sproposals[MAX_PROP];\n\tchar *c, *s, *p, *ret, *cp, *sp;\n\tint i, j, nproposals;\n\n\tc = cp = xstrdup(client);\n\ts = sp = xstrdup(server);\n\n\tfor ((p = strsep(&sp, SEP)), i=0; p && *p != '\\0';\n\t (p = strsep(&sp, SEP)), i++) {\n\t\tif (i < MAX_PROP)\n\t\t\tsproposals[i] = p;\n\t\telse\n\t\t\tbreak;\n\t}\n\tnproposals = i;\n\n\tfor ((p = strsep(&cp, SEP)), i=0; p && *p != '\\0';\n\t (p = strsep(&cp, SEP)), i++) {\n\t\tfor (j = 0; j < nproposals; j++) {\n\t\t\tif (strcmp(p, sproposals[j]) == 0) {\n\t\t\t\tret = xstrdup(p);\n\t\t\t\tif (next != NULL)\n\t\t\t\t\t*next = (cp == NULL) ?\n\t\t\t\t\t strlen(c) : (u_int)(cp - c);\n\t\t\t\tfree(c);\n\t\t\t\tfree(s);\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t}\n\t}\n\tif (next != NULL)\n\t\t*next = strlen(c);\n\tfree(c);\n\tfree(s);\n\treturn NULL;\n}\n\n/*\n * Filters a comma-separated list of strings, excluding any entry matching\n * the 'filter' pattern list. Caller must free returned string.\n */\nchar *\nmatch_filter_list(const char *proposal, const char *filter)\n{\n\tsize_t len = strlen(proposal) + 1;\n\tchar *fix_prop = malloc(len);\n\tchar *orig_prop = strdup(proposal);\n\tchar *cp, *tmp;\n\n\tif (fix_prop == NULL || orig_prop == NULL) {\n\t\tfree(orig_prop);\n\t\tfree(fix_prop);\n\t\treturn NULL;\n\t}\n\n\ttmp = orig_prop;\n\t*fix_prop = '\\0';\n\twhile ((cp = strsep(&tmp, \",\")) != NULL) {\n\t\tif (match_pattern_list(cp, filter, 0) != 1) {\n\t\t\tif (*fix_prop != '\\0')\n\t\t\t\tstrlcat(fix_prop, \",\", len);\n\t\t\tstrlcat(fix_prop, cp, len);\n\t\t}\n\t}\n\tfree(orig_prop);\n\treturn fix_prop;\n}\n\n","/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */\n/*\n * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \n#include \n#include \n\n#include \"openbsd-compat/sys-queue.h\"\n#include \"ssh1.h\"\n#include \"ssh2.h\"\n#include \"buffer.h\"\n#include \"packet.h\"\n#include \"channels.h\"\n#include \"compat.h\"\n#include \"log.h\"\n\n/*\n * SSH Protocol 1.5 aka New Channel Protocol\n * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.\n * Written by Markus Friedl in October 1999\n *\n * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the\n * tear down of channels:\n *\n * 1.3:\tstrict request-ack-protocol:\n *\tCLOSE\t->\n *\t\t<- CLOSE_CONFIRM\n *\n * 1.5:\tuses variations of:\n *\tIEOF\t->\n *\t\t<- OCLOSE\n *\t\t<- IEOF\n *\tOCLOSE\t->\n *\ti.e. both sides have to close the channel\n *\n * 2.0: the EOF messages are optional\n *\n * See the debugging output from 'ssh -v' and 'sshd -d' of\n * ssh-1.2.27 as an example.\n *\n */\n\n/* functions manipulating channel states */\n/*\n * EVENTS update channel input/output states execute ACTIONS\n */\n/*\n * ACTIONS: should never update the channel states\n */\nstatic void\tchan_send_ieof1(Channel *);\nstatic void\tchan_send_oclose1(Channel *);\nstatic void\tchan_send_close2(Channel *);\nstatic void\tchan_send_eof2(Channel *);\nstatic void\tchan_send_eow2(Channel *);\n\n/* helper */\nstatic void\tchan_shutdown_write(Channel *);\nstatic void\tchan_shutdown_read(Channel *);\n\nstatic char *ostates[] = { \"open\", \"drain\", \"wait_ieof\", \"closed\" };\nstatic char *istates[] = { \"open\", \"drain\", \"wait_oclose\", \"closed\" };\n\nstatic void\nchan_set_istate(Channel *c, u_int next)\n{\n\tif (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)\n\t\tfatal(\"chan_set_istate: bad state %d -> %d\", c->istate, next);\n\tdebug2(\"channel %d: input %s -> %s\", c->self, istates[c->istate],\n\t istates[next]);\n\tc->istate = next;\n}\nstatic void\nchan_set_ostate(Channel *c, u_int next)\n{\n\tif (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)\n\t\tfatal(\"chan_set_ostate: bad state %d -> %d\", c->ostate, next);\n\tdebug2(\"channel %d: output %s -> %s\", c->self, ostates[c->ostate],\n\t ostates[next]);\n\tc->ostate = next;\n}\n\n/*\n * SSH1 specific implementation of event functions\n */\n\nstatic void\nchan_rcvd_oclose1(Channel *c)\n{\n\tdebug2(\"channel %d: rcvd oclose\", c->self);\n\tswitch (c->istate) {\n\tcase CHAN_INPUT_WAIT_OCLOSE:\n\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\tbreak;\n\tcase CHAN_INPUT_OPEN:\n\t\tchan_shutdown_read(c);\n\t\tchan_send_ieof1(c);\n\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\tbreak;\n\tcase CHAN_INPUT_WAIT_DRAIN:\n\t\t/* both local read_failed and remote write_failed */\n\t\tchan_send_ieof1(c);\n\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: protocol error: rcvd_oclose for istate %d\",\n\t\t c->self, c->istate);\n\t\treturn;\n\t}\n}\nvoid\nchan_read_failed(Channel *c)\n{\n\tdebug2(\"channel %d: read failed\", c->self);\n\tswitch (c->istate) {\n\tcase CHAN_INPUT_OPEN:\n\t\tchan_shutdown_read(c);\n\t\tchan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: chan_read_failed for istate %d\",\n\t\t c->self, c->istate);\n\t\tbreak;\n\t}\n}\nvoid\nchan_ibuf_empty(Channel *c)\n{\n\tdebug2(\"channel %d: ibuf empty\", c->self);\n\tif (buffer_len(&c->input)) {\n\t\terror(\"channel %d: chan_ibuf_empty for non empty buffer\",\n\t\t c->self);\n\t\treturn;\n\t}\n\tswitch (c->istate) {\n\tcase CHAN_INPUT_WAIT_DRAIN:\n\t\tif (compat20) {\n\t\t\tif (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))\n\t\t\t\tchan_send_eof2(c);\n\t\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\t} else {\n\t\t\tchan_send_ieof1(c);\n\t\t\tchan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: chan_ibuf_empty for istate %d\",\n\t\t c->self, c->istate);\n\t\tbreak;\n\t}\n}\nstatic void\nchan_rcvd_ieof1(Channel *c)\n{\n\tdebug2(\"channel %d: rcvd ieof\", c->self);\n\tswitch (c->ostate) {\n\tcase CHAN_OUTPUT_OPEN:\n\t\tchan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);\n\t\tbreak;\n\tcase CHAN_OUTPUT_WAIT_IEOF:\n\t\tchan_set_ostate(c, CHAN_OUTPUT_CLOSED);\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: protocol error: rcvd_ieof for ostate %d\",\n\t\t c->self, c->ostate);\n\t\tbreak;\n\t}\n}\nstatic void\nchan_write_failed1(Channel *c)\n{\n\tdebug2(\"channel %d: write failed\", c->self);\n\tswitch (c->ostate) {\n\tcase CHAN_OUTPUT_OPEN:\n\t\tchan_shutdown_write(c);\n\t\tchan_send_oclose1(c);\n\t\tchan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);\n\t\tbreak;\n\tcase CHAN_OUTPUT_WAIT_DRAIN:\n\t\tchan_shutdown_write(c);\n\t\tchan_send_oclose1(c);\n\t\tchan_set_ostate(c, CHAN_OUTPUT_CLOSED);\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: chan_write_failed for ostate %d\",\n\t\t c->self, c->ostate);\n\t\tbreak;\n\t}\n}\nvoid\nchan_obuf_empty(Channel *c)\n{\n\tdebug2(\"channel %d: obuf empty\", c->self);\n\tif (buffer_len(&c->output)) {\n\t\terror(\"channel %d: chan_obuf_empty for non empty buffer\",\n\t\t c->self);\n\t\treturn;\n\t}\n\tswitch (c->ostate) {\n\tcase CHAN_OUTPUT_WAIT_DRAIN:\n\t\tchan_shutdown_write(c);\n\t\tif (!compat20)\n\t\t\tchan_send_oclose1(c);\n\t\tchan_set_ostate(c, CHAN_OUTPUT_CLOSED);\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: internal error: obuf_empty for ostate %d\",\n\t\t c->self, c->ostate);\n\t\tbreak;\n\t}\n}\nstatic void\nchan_send_ieof1(Channel *c)\n{\n\tdebug2(\"channel %d: send ieof\", c->self);\n\tswitch (c->istate) {\n\tcase CHAN_INPUT_OPEN:\n\tcase CHAN_INPUT_WAIT_DRAIN:\n\t\tpacket_start(SSH_MSG_CHANNEL_INPUT_EOF);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_send();\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: cannot send ieof for istate %d\",\n\t\t c->self, c->istate);\n\t\tbreak;\n\t}\n}\nstatic void\nchan_send_oclose1(Channel *c)\n{\n\tdebug2(\"channel %d: send oclose\", c->self);\n\tswitch (c->ostate) {\n\tcase CHAN_OUTPUT_OPEN:\n\tcase CHAN_OUTPUT_WAIT_DRAIN:\n\t\tbuffer_clear(&c->output);\n\t\tpacket_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_send();\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: cannot send oclose for ostate %d\",\n\t\t c->self, c->ostate);\n\t\tbreak;\n\t}\n}\n\n/*\n * the same for SSH2\n */\nstatic void\nchan_rcvd_close2(Channel *c)\n{\n\tdebug2(\"channel %d: rcvd close\", c->self);\n\tif (!(c->flags & CHAN_LOCAL)) {\n\t\tif (c->flags & CHAN_CLOSE_RCVD)\n\t\t\terror(\"channel %d: protocol error: close rcvd twice\",\n\t\t\t c->self);\n\t\tc->flags |= CHAN_CLOSE_RCVD;\n\t}\n\tif (c->type == SSH_CHANNEL_LARVAL) {\n\t\t/* tear down larval channels immediately */\n\t\tchan_set_ostate(c, CHAN_OUTPUT_CLOSED);\n\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\treturn;\n\t}\n\tswitch (c->ostate) {\n\tcase CHAN_OUTPUT_OPEN:\n\t\t/*\n\t\t * wait until a data from the channel is consumed if a CLOSE\n\t\t * is received\n\t\t */\n\t\tchan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);\n\t\tbreak;\n\t}\n\tswitch (c->istate) {\n\tcase CHAN_INPUT_OPEN:\n\t\tchan_shutdown_read(c);\n\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\tbreak;\n\tcase CHAN_INPUT_WAIT_DRAIN:\n\t\tif (!(c->flags & CHAN_LOCAL))\n\t\t\tchan_send_eof2(c);\n\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\tbreak;\n\t}\n}\n\nvoid\nchan_rcvd_eow(Channel *c)\n{\n\tdebug2(\"channel %d: rcvd eow\", c->self);\n\tswitch (c->istate) {\n\tcase CHAN_INPUT_OPEN:\n\t\tchan_shutdown_read(c);\n\t\tchan_set_istate(c, CHAN_INPUT_CLOSED);\n\t\tbreak;\n\t}\n}\nstatic void\nchan_rcvd_eof2(Channel *c)\n{\n\tdebug2(\"channel %d: rcvd eof\", c->self);\n\tc->flags |= CHAN_EOF_RCVD;\n\tif (c->ostate == CHAN_OUTPUT_OPEN)\n\t\tchan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);\n}\nstatic void\nchan_write_failed2(Channel *c)\n{\n\tdebug2(\"channel %d: write failed\", c->self);\n\tswitch (c->ostate) {\n\tcase CHAN_OUTPUT_OPEN:\n\tcase CHAN_OUTPUT_WAIT_DRAIN:\n\t\tchan_shutdown_write(c);\n\t\tif (strcmp(c->ctype, \"session\") == 0)\n\t\t\tchan_send_eow2(c);\n\t\tchan_set_ostate(c, CHAN_OUTPUT_CLOSED);\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: chan_write_failed for ostate %d\",\n\t\t c->self, c->ostate);\n\t\tbreak;\n\t}\n}\nstatic void\nchan_send_eof2(Channel *c)\n{\n\tdebug2(\"channel %d: send eof\", c->self);\n\tswitch (c->istate) {\n\tcase CHAN_INPUT_WAIT_DRAIN:\n\t\tpacket_start(SSH2_MSG_CHANNEL_EOF);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_send();\n\t\tc->flags |= CHAN_EOF_SENT;\n\t\tbreak;\n\tdefault:\n\t\terror(\"channel %d: cannot send eof for istate %d\",\n\t\t c->self, c->istate);\n\t\tbreak;\n\t}\n}\nstatic void\nchan_send_close2(Channel *c)\n{\n\tdebug2(\"channel %d: send close\", c->self);\n\tif (c->ostate != CHAN_OUTPUT_CLOSED ||\n\t c->istate != CHAN_INPUT_CLOSED) {\n\t\terror(\"channel %d: cannot send close for istate/ostate %d/%d\",\n\t\t c->self, c->istate, c->ostate);\n\t} else if (c->flags & CHAN_CLOSE_SENT) {\n\t\terror(\"channel %d: already sent close\", c->self);\n\t} else {\n\t\tpacket_start(SSH2_MSG_CHANNEL_CLOSE);\n\t\tpacket_put_int(c->remote_id);\n\t\tpacket_send();\n\t\tc->flags |= CHAN_CLOSE_SENT;\n\t}\n}\nstatic void\nchan_send_eow2(Channel *c)\n{\n\tdebug2(\"channel %d: send eow\", c->self);\n\tif (c->ostate == CHAN_OUTPUT_CLOSED) {\n\t\terror(\"channel %d: must not sent eow on closed output\",\n\t\t c->self);\n\t\treturn;\n\t}\n\tif (!(datafellows & SSH_NEW_OPENSSH))\n\t\treturn;\n\tpacket_start(SSH2_MSG_CHANNEL_REQUEST);\n\tpacket_put_int(c->remote_id);\n\tpacket_put_cstring(\"eow@openssh.com\");\n\tpacket_put_char(0);\n\tpacket_send();\n}\n\n/* shared */\n\nvoid\nchan_rcvd_ieof(Channel *c)\n{\n\tif (compat20)\n\t\tchan_rcvd_eof2(c);\n\telse\n\t\tchan_rcvd_ieof1(c);\n\tif (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&\n\t buffer_len(&c->output) == 0 &&\n\t !CHANNEL_EFD_OUTPUT_ACTIVE(c))\n\t\tchan_obuf_empty(c);\n}\nvoid\nchan_rcvd_oclose(Channel *c)\n{\n\tif (compat20)\n\t\tchan_rcvd_close2(c);\n\telse\n\t\tchan_rcvd_oclose1(c);\n}\nvoid\nchan_write_failed(Channel *c)\n{\n\tif (compat20)\n\t\tchan_write_failed2(c);\n\telse\n\t\tchan_write_failed1(c);\n}\n\nvoid\nchan_mark_dead(Channel *c)\n{\n\tc->type = SSH_CHANNEL_ZOMBIE;\n}\n\nint\nchan_is_dead(Channel *c, int do_send)\n{\n\tif (c->type == SSH_CHANNEL_ZOMBIE) {\n\t\tdebug2(\"channel %d: zombie\", c->self);\n\t\treturn 1;\n\t}\n\tif (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)\n\t\treturn 0;\n\tif (!compat20) {\n\t\tdebug2(\"channel %d: is dead\", c->self);\n\t\treturn 1;\n\t}\n\tif ((datafellows & SSH_BUG_EXTEOF) &&\n\t c->extended_usage == CHAN_EXTENDED_WRITE &&\n\t c->efd != -1 &&\n\t buffer_len(&c->extended) > 0) {\n\t\tdebug2(\"channel %d: active efd: %d len %d\",\n\t\t c->self, c->efd, buffer_len(&c->extended));\n\t\treturn 0;\n\t}\n\tif (c->flags & CHAN_LOCAL) {\n\t\tdebug2(\"channel %d: is dead (local)\", c->self);\n\t\treturn 1;\n\t}\t\t\n\tif (!(c->flags & CHAN_CLOSE_SENT)) {\n\t\tif (do_send) {\n\t\t\tchan_send_close2(c);\n\t\t} else {\n\t\t\t/* channel would be dead if we sent a close */\n\t\t\tif (c->flags & CHAN_CLOSE_RCVD) {\n\t\t\t\tdebug2(\"channel %d: almost dead\",\n\t\t\t\t c->self);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t}\n\tif ((c->flags & CHAN_CLOSE_SENT) &&\n\t (c->flags & CHAN_CLOSE_RCVD)) {\n\t\tdebug2(\"channel %d: is dead\", c->self);\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n/* helper */\nstatic void\nchan_shutdown_write(Channel *c)\n{\n\tbuffer_clear(&c->output);\n\tif (compat20 && c->type == SSH_CHANNEL_LARVAL)\n\t\treturn;\n\t/* shutdown failure is allowed if write failed already */\n\tdebug2(\"channel %d: close_write\", c->self);\n\tif (c->sock != -1) {\n\t\tif (shutdown(c->sock, SHUT_WR) < 0)\n\t\t\tdebug2(\"channel %d: chan_shutdown_write: \"\n\t\t\t \"shutdown() failed for fd %d: %.100s\",\n\t\t\t c->self, c->sock, strerror(errno));\n\t} else {\n\t\tif (channel_close_fd(&c->wfd) < 0)\n\t\t\tlogit(\"channel %d: chan_shutdown_write: \"\n\t\t\t \"close() failed for fd %d: %.100s\",\n\t\t\t c->self, c->wfd, strerror(errno));\n\t}\n}\nstatic void\nchan_shutdown_read(Channel *c)\n{\n\tif (compat20 && c->type == SSH_CHANNEL_LARVAL)\n\t\treturn;\n\tdebug2(\"channel %d: close_read\", c->self);\n\tif (c->sock != -1) {\n\t\t/*\n\t\t * shutdown(sock, SHUT_READ) may return ENOTCONN if the\n\t\t * write side has been closed already. (bug on Linux)\n\t\t * HP-UX may return ENOTCONN also.\n\t\t */\n\t\tif (shutdown(c->sock, SHUT_RD) < 0\n\t\t && errno != ENOTCONN)\n\t\t\terror(\"channel %d: chan_shutdown_read: \"\n\t\t\t \"shutdown() failed for fd %d [i%d o%d]: %.100s\",\n\t\t\t c->self, c->sock, c->istate, c->ostate,\n\t\t\t strerror(errno));\n\t} else {\n\t\tif (channel_close_fd(&c->rfd) < 0)\n\t\t\tlogit(\"channel %d: chan_shutdown_read: \"\n\t\t\t \"close() failed for fd %d: %.100s\",\n\t\t\t c->self, c->rfd, strerror(errno));\n\t}\n}\n","/* $OpenBSD: packet.c,v 1.247 2017/03/11 13:07:35 markus Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * This file contains code implementing the packet protocol and communication\n * with the other side. This same code is used both on client and server side.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n *\n *\n * SSH2 packet format added by Markus Friedl.\n * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \"openbsd-compat/sys-queue.h\"\n#include \n#ifdef HAVE_SYS_TIME_H\n# include \n#endif\n\n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n\n#include \"buffer.h\"\t/* typedefs XXX */\n#include \"key.h\"\t/* typedefs XXX */\n\n#include \"xmalloc.h\"\n#include \"crc32.h\"\n#include \"deattack.h\"\n#include \"compat.h\"\n#include \"ssh1.h\"\n#include \"ssh2.h\"\n#include \"cipher.h\"\n#include \"sshkey.h\"\n#include \"kex.h\"\n#include \"digest.h\"\n#include \"mac.h\"\n#include \"log.h\"\n#include \"canohost.h\"\n#include \"misc.h\"\n#include \"channels.h\"\n#include \"ssh.h\"\n#include \"packet.h\"\n#include \"ssherr.h\"\n#include \"sshbuf.h\"\n\n#ifdef PACKET_DEBUG\n#define DBG(x) x\n#else\n#define DBG(x)\n#endif\n\n#define PACKET_MAX_SIZE (256 * 1024)\n\nstruct packet_state {\n\tu_int32_t seqnr;\n\tu_int32_t packets;\n\tu_int64_t blocks;\n\tu_int64_t bytes;\n};\n\nstruct packet {\n\tTAILQ_ENTRY(packet) next;\n\tu_char type;\n\tstruct sshbuf *payload;\n};\n\nstruct session_state {\n\t/*\n\t * This variable contains the file descriptors used for\n\t * communicating with the other side. connection_in is used for\n\t * reading; connection_out for writing. These can be the same\n\t * descriptor, in which case it is assumed to be a socket.\n\t */\n\tint connection_in;\n\tint connection_out;\n\n\t/* Protocol flags for the remote side. */\n\tu_int remote_protocol_flags;\n\n\t/* Encryption context for receiving data. Only used for decryption. */\n\tstruct sshcipher_ctx *receive_context;\n\n\t/* Encryption context for sending data. Only used for encryption. */\n\tstruct sshcipher_ctx *send_context;\n\n\t/* Buffer for raw input data from the socket. */\n\tstruct sshbuf *input;\n\n\t/* Buffer for raw output data going to the socket. */\n\tstruct sshbuf *output;\n\n\t/* Buffer for the partial outgoing packet being constructed. */\n\tstruct sshbuf *outgoing_packet;\n\n\t/* Buffer for the incoming packet currently being processed. */\n\tstruct sshbuf *incoming_packet;\n\n\t/* Scratch buffer for packet compression/decompression. */\n\tstruct sshbuf *compression_buffer;\n\n\t/* Incoming/outgoing compression dictionaries */\n\tz_stream compression_in_stream;\n\tz_stream compression_out_stream;\n\tint compression_in_started;\n\tint compression_out_started;\n\tint compression_in_failures;\n\tint compression_out_failures;\n\n\t/*\n\t * Flag indicating whether packet compression/decompression is\n\t * enabled.\n\t */\n\tint packet_compression;\n\n\t/* default maximum packet size */\n\tu_int max_packet_size;\n\n\t/* Flag indicating whether this module has been initialized. */\n\tint initialized;\n\n\t/* Set to true if the connection is interactive. */\n\tint interactive_mode;\n\n\t/* Set to true if we are the server side. */\n\tint server_side;\n\n\t/* Set to true if we are authenticated. */\n\tint after_authentication;\n\n\tint keep_alive_timeouts;\n\n\t/* The maximum time that we will wait to send or receive a packet */\n\tint packet_timeout_ms;\n\n\t/* Session key information for Encryption and MAC */\n\tstruct newkeys *newkeys[MODE_MAX];\n\tstruct packet_state p_read, p_send;\n\n\t/* Volume-based rekeying */\n\tu_int64_t max_blocks_in, max_blocks_out, rekey_limit;\n\n\t/* Time-based rekeying */\n\tu_int32_t rekey_interval;\t/* how often in seconds */\n\ttime_t rekey_time;\t/* time of last rekeying */\n\n\t/* Session key for protocol v1 */\n\tu_char ssh1_key[SSH_SESSION_KEY_LENGTH];\n\tu_int ssh1_keylen;\n\n\t/* roundup current message to extra_pad bytes */\n\tu_char extra_pad;\n\n\t/* XXX discard incoming data after MAC error */\n\tu_int packet_discard;\n\tsize_t packet_discard_mac_already;\n\tstruct sshmac *packet_discard_mac;\n\n\t/* Used in packet_read_poll2() */\n\tu_int packlen;\n\n\t/* Used in packet_send2 */\n\tint rekeying;\n\n\t/* Used in ssh_packet_send_mux() */\n\tint mux;\n\n\t/* Used in packet_set_interactive */\n\tint set_interactive_called;\n\n\t/* Used in packet_set_maxsize */\n\tint set_maxsize_called;\n\n\t/* One-off warning about weak ciphers */\n\tint cipher_warning_done;\n\n\t/* SSH1 CRC compensation attack detector */\n\tstruct deattack_ctx deattack;\n\n\t/* Hook for fuzzing inbound packets */\n\tssh_packet_hook_fn *hook_in;\n\tvoid *hook_in_ctx;\n\n\tTAILQ_HEAD(, packet) outgoing;\n};\n\nstruct ssh *\nssh_alloc_session_state(void)\n{\n\tstruct ssh *ssh = NULL;\n\tstruct session_state *state = NULL;\n\n\tif ((ssh = calloc(1, sizeof(*ssh))) == NULL ||\n\t (state = calloc(1, sizeof(*state))) == NULL ||\n\t (state->input = sshbuf_new()) == NULL ||\n\t (state->output = sshbuf_new()) == NULL ||\n\t (state->outgoing_packet = sshbuf_new()) == NULL ||\n\t (state->incoming_packet = sshbuf_new()) == NULL)\n\t\tgoto fail;\n\tTAILQ_INIT(&state->outgoing);\n\tTAILQ_INIT(&ssh->private_keys);\n\tTAILQ_INIT(&ssh->public_keys);\n\tstate->connection_in = -1;\n\tstate->connection_out = -1;\n\tstate->max_packet_size = 32768;\n\tstate->packet_timeout_ms = -1;\n\tstate->p_send.packets = state->p_read.packets = 0;\n\tstate->initialized = 1;\n\t/*\n\t * ssh_packet_send2() needs to queue packets until\n\t * we've done the initial key exchange.\n\t */\n\tstate->rekeying = 1;\n\tssh->state = state;\n\treturn ssh;\n fail:\n\tif (state) {\n\t\tsshbuf_free(state->input);\n\t\tsshbuf_free(state->output);\n\t\tsshbuf_free(state->incoming_packet);\n\t\tsshbuf_free(state->outgoing_packet);\n\t\tfree(state);\n\t}\n\tfree(ssh);\n\treturn NULL;\n}\n\nvoid\nssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx)\n{\n\tssh->state->hook_in = hook;\n\tssh->state->hook_in_ctx = ctx;\n}\n\n/* Returns nonzero if rekeying is in progress */\nint\nssh_packet_is_rekeying(struct ssh *ssh)\n{\n\treturn compat20 &&\n\t (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0));\n}\n\n/*\n * Sets the descriptors used for communication. Disables encryption until\n * packet_set_encryption_key is called.\n */\nstruct ssh *\nssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)\n{\n\tstruct session_state *state;\n\tconst struct sshcipher *none = cipher_by_name(\"none\");\n\tint r;\n\n\tif (none == NULL) {\n\t\terror(\"%s: cannot load cipher 'none'\", __func__);\n\t\treturn NULL;\n\t}\n\tif (ssh == NULL)\n\t\tssh = ssh_alloc_session_state();\n\tif (ssh == NULL) {\n\t\terror(\"%s: cound not allocate state\", __func__);\n\t\treturn NULL;\n\t}\n\tstate = ssh->state;\n\tstate->connection_in = fd_in;\n\tstate->connection_out = fd_out;\n\tif ((r = cipher_init(&state->send_context, none,\n\t (const u_char *)\"\", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 ||\n\t (r = cipher_init(&state->receive_context, none,\n\t (const u_char *)\"\", 0, NULL, 0, CIPHER_DECRYPT)) != 0) {\n\t\terror(\"%s: cipher_init failed: %s\", __func__, ssh_err(r));\n\t\tfree(ssh); /* XXX need ssh_free_session_state? */\n\t\treturn NULL;\n\t}\n\tstate->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL;\n\tdeattack_init(&state->deattack);\n\t/*\n\t * Cache the IP address of the remote connection for use in error\n\t * messages that might be generated after the connection has closed.\n\t */\n\t(void)ssh_remote_ipaddr(ssh);\n\treturn ssh;\n}\n\nvoid\nssh_packet_set_timeout(struct ssh *ssh, int timeout, int count)\n{\n\tstruct session_state *state = ssh->state;\n\n\tif (timeout <= 0 || count <= 0) {\n\t\tstate->packet_timeout_ms = -1;\n\t\treturn;\n\t}\n\tif ((INT_MAX / 1000) / count < timeout)\n\t\tstate->packet_timeout_ms = INT_MAX;\n\telse\n\t\tstate->packet_timeout_ms = timeout * count * 1000;\n}\n\nvoid\nssh_packet_set_mux(struct ssh *ssh)\n{\n\tssh->state->mux = 1;\n\tssh->state->rekeying = 0;\n}\n\nint\nssh_packet_get_mux(struct ssh *ssh)\n{\n\treturn ssh->state->mux;\n}\n\nint\nssh_packet_set_log_preamble(struct ssh *ssh, const char *fmt, ...)\n{\n\tva_list args;\n\tint r;\n\n\tfree(ssh->log_preamble);\n\tif (fmt == NULL)\n\t\tssh->log_preamble = NULL;\n\telse {\n\t\tva_start(args, fmt);\n\t\tr = vasprintf(&ssh->log_preamble, fmt, args);\n\t\tva_end(args);\n\t\tif (r < 0 || ssh->log_preamble == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t}\n\treturn 0;\n}\n\nint\nssh_packet_stop_discard(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tint r;\n\n\tif (state->packet_discard_mac) {\n\t\tchar buf[1024];\n\t\tsize_t dlen = PACKET_MAX_SIZE;\n\n\t\tif (dlen > state->packet_discard_mac_already)\n\t\t\tdlen -= state->packet_discard_mac_already;\n\t\tmemset(buf, 'a', sizeof(buf));\n\t\twhile (sshbuf_len(state->incoming_packet) < dlen)\n\t\t\tif ((r = sshbuf_put(state->incoming_packet, buf,\n\t\t\t sizeof(buf))) != 0)\n\t\t\t\treturn r;\n\t\t(void) mac_compute(state->packet_discard_mac,\n\t\t state->p_read.seqnr,\n\t\t sshbuf_ptr(state->incoming_packet), dlen,\n\t\t NULL, 0);\n\t}\n\tlogit(\"Finished discarding for %.200s port %d\",\n\t ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));\n\treturn SSH_ERR_MAC_INVALID;\n}\n\nstatic int\nssh_packet_start_discard(struct ssh *ssh, struct sshenc *enc,\n struct sshmac *mac, size_t mac_already, u_int discard)\n{\n\tstruct session_state *state = ssh->state;\n\tint r;\n\n\tif (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm)) {\n\t\tif ((r = sshpkt_disconnect(ssh, \"Packet corrupt\")) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_MAC_INVALID;\n\t}\n\t/*\n\t * Record number of bytes over which the mac has already\n\t * been computed in order to minimize timing attacks.\n\t */\n\tif (mac && mac->enabled) {\n\t\tstate->packet_discard_mac = mac;\n\t\tstate->packet_discard_mac_already = mac_already;\n\t}\n\tif (sshbuf_len(state->input) >= discard)\n\t\treturn ssh_packet_stop_discard(ssh);\n\tstate->packet_discard = discard - sshbuf_len(state->input);\n\treturn 0;\n}\n\n/* Returns 1 if remote host is connected via socket, 0 if not. */\n\nint\nssh_packet_connection_is_on_socket(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tstruct sockaddr_storage from, to;\n\tsocklen_t fromlen, tolen;\n\n\tif (state->connection_in == -1 || state->connection_out == -1)\n\t\treturn 0;\n\n\t/* filedescriptors in and out are the same, so it's a socket */\n\tif (state->connection_in == state->connection_out)\n\t\treturn 1;\n\tfromlen = sizeof(from);\n\tmemset(&from, 0, sizeof(from));\n\tif (getpeername(state->connection_in, (struct sockaddr *)&from,\n\t &fromlen) < 0)\n\t\treturn 0;\n\ttolen = sizeof(to);\n\tmemset(&to, 0, sizeof(to));\n\tif (getpeername(state->connection_out, (struct sockaddr *)&to,\n\t &tolen) < 0)\n\t\treturn 0;\n\tif (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)\n\t\treturn 0;\n\tif (from.ss_family != AF_INET && from.ss_family != AF_INET6)\n\t\treturn 0;\n\treturn 1;\n}\n\nvoid\nssh_packet_get_bytes(struct ssh *ssh, u_int64_t *ibytes, u_int64_t *obytes)\n{\n\tif (ibytes)\n\t\t*ibytes = ssh->state->p_read.bytes;\n\tif (obytes)\n\t\t*obytes = ssh->state->p_send.bytes;\n}\n\nint\nssh_packet_connection_af(struct ssh *ssh)\n{\n\tstruct sockaddr_storage to;\n\tsocklen_t tolen = sizeof(to);\n\n\tmemset(&to, 0, sizeof(to));\n\tif (getsockname(ssh->state->connection_out, (struct sockaddr *)&to,\n\t &tolen) < 0)\n\t\treturn 0;\n#ifdef IPV4_IN_IPV6\n\tif (to.ss_family == AF_INET6 &&\n\t IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))\n\t\treturn AF_INET;\n#endif\n\treturn to.ss_family;\n}\n\n/* Sets the connection into non-blocking mode. */\n\nvoid\nssh_packet_set_nonblocking(struct ssh *ssh)\n{\n\t/* Set the socket into non-blocking mode. */\n\tset_nonblock(ssh->state->connection_in);\n\n\tif (ssh->state->connection_out != ssh->state->connection_in)\n\t\tset_nonblock(ssh->state->connection_out);\n}\n\n/* Returns the socket used for reading. */\n\nint\nssh_packet_get_connection_in(struct ssh *ssh)\n{\n\treturn ssh->state->connection_in;\n}\n\n/* Returns the descriptor used for writing. */\n\nint\nssh_packet_get_connection_out(struct ssh *ssh)\n{\n\treturn ssh->state->connection_out;\n}\n\n/*\n * Returns the IP-address of the remote host as a string. The returned\n * string must not be freed.\n */\n\nconst char *\nssh_remote_ipaddr(struct ssh *ssh)\n{\n\tconst int sock = ssh->state->connection_in;\n\n\t/* Check whether we have cached the ipaddr. */\n\tif (ssh->remote_ipaddr == NULL) {\n\t\tif (ssh_packet_connection_is_on_socket(ssh)) {\n\t\t\tssh->remote_ipaddr = get_peer_ipaddr(sock);\n\t\t\tssh->remote_port = get_peer_port(sock);\n\t\t\tssh->local_ipaddr = get_local_ipaddr(sock);\n\t\t\tssh->local_port = get_local_port(sock);\n\t\t} else {\n\t\t\tssh->remote_ipaddr = strdup(\"UNKNOWN\");\n\t\t\tssh->remote_port = 65535;\n\t\t\tssh->local_ipaddr = strdup(\"UNKNOWN\");\n\t\t\tssh->local_port = 65535;\n\t\t}\n\t}\n\treturn ssh->remote_ipaddr;\n}\n\n/* Returns the port number of the remote host. */\n\nint\nssh_remote_port(struct ssh *ssh)\n{\n\t(void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */\n\treturn ssh->remote_port;\n}\n\n/*\n * Returns the IP-address of the local host as a string. The returned\n * string must not be freed.\n */\n\nconst char *\nssh_local_ipaddr(struct ssh *ssh)\n{\n\t(void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */\n\treturn ssh->local_ipaddr;\n}\n\n/* Returns the port number of the local host. */\n\nint\nssh_local_port(struct ssh *ssh)\n{\n\t(void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */\n\treturn ssh->local_port;\n}\n\n/* Closes the connection and clears and frees internal data structures. */\n\nvoid\nssh_packet_close(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tu_int mode;\n\n\tif (!state->initialized)\n\t\treturn;\n\tstate->initialized = 0;\n\tif (state->connection_in == state->connection_out) {\n\t\tshutdown(state->connection_out, SHUT_RDWR);\n\t\tclose(state->connection_out);\n\t} else {\n\t\tclose(state->connection_in);\n\t\tclose(state->connection_out);\n\t}\n\tsshbuf_free(state->input);\n\tsshbuf_free(state->output);\n\tsshbuf_free(state->outgoing_packet);\n\tsshbuf_free(state->incoming_packet);\n\tfor (mode = 0; mode < MODE_MAX; mode++)\n\t\tkex_free_newkeys(state->newkeys[mode]);\n\tif (state->compression_buffer) {\n\t\tsshbuf_free(state->compression_buffer);\n\t\tif (state->compression_out_started) {\n\t\t\tz_streamp stream = &state->compression_out_stream;\n\t\t\tdebug(\"compress outgoing: \"\n\t\t\t \"raw data %llu, compressed %llu, factor %.2f\",\n\t\t\t\t(unsigned long long)stream->total_in,\n\t\t\t\t(unsigned long long)stream->total_out,\n\t\t\t\tstream->total_in == 0 ? 0.0 :\n\t\t\t\t(double) stream->total_out / stream->total_in);\n\t\t\tif (state->compression_out_failures == 0)\n\t\t\t\tdeflateEnd(stream);\n\t\t}\n\t\tif (state->compression_in_started) {\n\t\t\tz_streamp stream = &state->compression_out_stream;\n\t\t\tdebug(\"compress incoming: \"\n\t\t\t \"raw data %llu, compressed %llu, factor %.2f\",\n\t\t\t (unsigned long long)stream->total_out,\n\t\t\t (unsigned long long)stream->total_in,\n\t\t\t stream->total_out == 0 ? 0.0 :\n\t\t\t (double) stream->total_in / stream->total_out);\n\t\t\tif (state->compression_in_failures == 0)\n\t\t\t\tinflateEnd(stream);\n\t\t}\n\t}\n\tcipher_free(state->send_context);\n\tcipher_free(state->receive_context);\n\tstate->send_context = state->receive_context = NULL;\n\tfree(ssh->remote_ipaddr);\n\tssh->remote_ipaddr = NULL;\n\tfree(ssh->state);\n\tssh->state = NULL;\n}\n\n/* Sets remote side protocol flags. */\n\nvoid\nssh_packet_set_protocol_flags(struct ssh *ssh, u_int protocol_flags)\n{\n\tssh->state->remote_protocol_flags = protocol_flags;\n}\n\n/* Returns the remote protocol flags set earlier by the above function. */\n\nu_int\nssh_packet_get_protocol_flags(struct ssh *ssh)\n{\n\treturn ssh->state->remote_protocol_flags;\n}\n\n/*\n * Starts packet compression from the next packet on in both directions.\n * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.\n */\n\nstatic int\nssh_packet_init_compression(struct ssh *ssh)\n{\n\tif (!ssh->state->compression_buffer &&\n\t ((ssh->state->compression_buffer = sshbuf_new()) == NULL))\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\treturn 0;\n}\n\nstatic int\nstart_compression_out(struct ssh *ssh, int level)\n{\n\tif (level < 1 || level > 9)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tdebug(\"Enabling compression at level %d.\", level);\n\tif (ssh->state->compression_out_started == 1)\n\t\tdeflateEnd(&ssh->state->compression_out_stream);\n\tswitch (deflateInit(&ssh->state->compression_out_stream, level)) {\n\tcase Z_OK:\n\t\tssh->state->compression_out_started = 1;\n\t\tbreak;\n\tcase Z_MEM_ERROR:\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tdefault:\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\treturn 0;\n}\n\nstatic int\nstart_compression_in(struct ssh *ssh)\n{\n\tif (ssh->state->compression_in_started == 1)\n\t\tinflateEnd(&ssh->state->compression_in_stream);\n\tswitch (inflateInit(&ssh->state->compression_in_stream)) {\n\tcase Z_OK:\n\t\tssh->state->compression_in_started = 1;\n\t\tbreak;\n\tcase Z_MEM_ERROR:\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tdefault:\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\treturn 0;\n}\n\nint\nssh_packet_start_compression(struct ssh *ssh, int level)\n{\n\tint r;\n\n\tif (ssh->state->packet_compression && !compat20)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tssh->state->packet_compression = 1;\n\tif ((r = ssh_packet_init_compression(ssh)) != 0 ||\n\t (r = start_compression_in(ssh)) != 0 ||\n\t (r = start_compression_out(ssh, level)) != 0)\n\t\treturn r;\n\treturn 0;\n}\n\n/* XXX remove need for separate compression buffer */\nstatic int\ncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)\n{\n\tu_char buf[4096];\n\tint r, status;\n\n\tif (ssh->state->compression_out_started != 1)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\n\t/* This case is not handled below. */\n\tif (sshbuf_len(in) == 0)\n\t\treturn 0;\n\n\t/* Input is the contents of the input buffer. */\n\tif ((ssh->state->compression_out_stream.next_in =\n\t sshbuf_mutable_ptr(in)) == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tssh->state->compression_out_stream.avail_in = sshbuf_len(in);\n\n\t/* Loop compressing until deflate() returns with avail_out != 0. */\n\tdo {\n\t\t/* Set up fixed-size output buffer. */\n\t\tssh->state->compression_out_stream.next_out = buf;\n\t\tssh->state->compression_out_stream.avail_out = sizeof(buf);\n\n\t\t/* Compress as much data into the buffer as possible. */\n\t\tstatus = deflate(&ssh->state->compression_out_stream,\n\t\t Z_PARTIAL_FLUSH);\n\t\tswitch (status) {\n\t\tcase Z_MEM_ERROR:\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tcase Z_OK:\n\t\t\t/* Append compressed data to output_buffer. */\n\t\t\tif ((r = sshbuf_put(out, buf, sizeof(buf) -\n\t\t\t ssh->state->compression_out_stream.avail_out)) != 0)\n\t\t\t\treturn r;\n\t\t\tbreak;\n\t\tcase Z_STREAM_ERROR:\n\t\tdefault:\n\t\t\tssh->state->compression_out_failures++;\n\t\t\treturn SSH_ERR_INVALID_FORMAT;\n\t\t}\n\t} while (ssh->state->compression_out_stream.avail_out == 0);\n\treturn 0;\n}\n\nstatic int\nuncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)\n{\n\tu_char buf[4096];\n\tint r, status;\n\n\tif (ssh->state->compression_in_started != 1)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\n\tif ((ssh->state->compression_in_stream.next_in =\n\t sshbuf_mutable_ptr(in)) == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tssh->state->compression_in_stream.avail_in = sshbuf_len(in);\n\n\tfor (;;) {\n\t\t/* Set up fixed-size output buffer. */\n\t\tssh->state->compression_in_stream.next_out = buf;\n\t\tssh->state->compression_in_stream.avail_out = sizeof(buf);\n\n\t\tstatus = inflate(&ssh->state->compression_in_stream,\n\t\t Z_PARTIAL_FLUSH);\n\t\tswitch (status) {\n\t\tcase Z_OK:\n\t\t\tif ((r = sshbuf_put(out, buf, sizeof(buf) -\n\t\t\t ssh->state->compression_in_stream.avail_out)) != 0)\n\t\t\t\treturn r;\n\t\t\tbreak;\n\t\tcase Z_BUF_ERROR:\n\t\t\t/*\n\t\t\t * Comments in zlib.h say that we should keep calling\n\t\t\t * inflate() until we get an error. This appears to\n\t\t\t * be the error that we get.\n\t\t\t */\n\t\t\treturn 0;\n\t\tcase Z_DATA_ERROR:\n\t\t\treturn SSH_ERR_INVALID_FORMAT;\n\t\tcase Z_MEM_ERROR:\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tcase Z_STREAM_ERROR:\n\t\tdefault:\n\t\t\tssh->state->compression_in_failures++;\n\t\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t\t}\n\t}\n\t/* NOTREACHED */\n}\n\n/*\n * Causes any further packets to be encrypted using the given key. The same\n * key is used for both sending and reception. However, both directions are\n * encrypted independently of each other.\n */\n\nvoid\nssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number)\n{\n#ifndef WITH_SSH1\n\tfatal(\"no SSH protocol 1 support\");\n#else /* WITH_SSH1 */\n\tstruct session_state *state = ssh->state;\n\tconst struct sshcipher *cipher = cipher_by_number(number);\n\tint r;\n\tconst char *wmsg;\n\n\tif (cipher == NULL)\n\t\tfatal(\"%s: unknown cipher number %d\", __func__, number);\n\tif (keylen < 20)\n\t\tfatal(\"%s: keylen too small: %d\", __func__, keylen);\n\tif (keylen > SSH_SESSION_KEY_LENGTH)\n\t\tfatal(\"%s: keylen too big: %d\", __func__, keylen);\n\tmemcpy(state->ssh1_key, key, keylen);\n\tstate->ssh1_keylen = keylen;\n\tif ((r = cipher_init(&state->send_context, cipher, key, keylen,\n\t NULL, 0, CIPHER_ENCRYPT)) != 0 ||\n\t (r = cipher_init(&state->receive_context, cipher, key, keylen,\n\t NULL, 0, CIPHER_DECRYPT) != 0))\n\t\tfatal(\"%s: cipher_init failed: %s\", __func__, ssh_err(r));\n\tif (!state->cipher_warning_done &&\n\t ((wmsg = cipher_warning_message(state->send_context)) != NULL ||\n\t (wmsg = cipher_warning_message(state->send_context)) != NULL)) {\n\t\terror(\"Warning: %s\", wmsg);\n\t\tstate->cipher_warning_done = 1;\n\t}\n#endif /* WITH_SSH1 */\n}\n\n/*\n * Finalizes and sends the packet. If the encryption key has been set,\n * encrypts the packet before sending.\n */\n\nint\nssh_packet_send1(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tu_char buf[8], *cp;\n\tint r, padding, len;\n\tu_int checksum;\n\n\t/*\n\t * If using packet compression, compress the payload of the outgoing\n\t * packet.\n\t */\n\tif (state->packet_compression) {\n\t\tsshbuf_reset(state->compression_buffer);\n\t\t/* Skip padding. */\n\t\tif ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0)\n\t\t\tgoto out;\n\t\t/* padding */\n\t\tif ((r = sshbuf_put(state->compression_buffer,\n\t\t \"\\0\\0\\0\\0\\0\\0\\0\\0\", 8)) != 0)\n\t\t\tgoto out;\n\t\tif ((r = compress_buffer(ssh, state->outgoing_packet,\n\t\t state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t\tsshbuf_reset(state->outgoing_packet);\n if ((r = sshbuf_putb(state->outgoing_packet,\n state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t}\n\t/* Compute packet length without padding (add checksum, remove padding). */\n\tlen = sshbuf_len(state->outgoing_packet) + 4 - 8;\n\n\t/* Insert padding. Initialized to zero in packet_start1() */\n\tpadding = 8 - len % 8;\n\tif (!cipher_ctx_is_plaintext(state->send_context)) {\n\t\tcp = sshbuf_mutable_ptr(state->outgoing_packet);\n\t\tif (cp == NULL) {\n\t\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tarc4random_buf(cp + 8 - padding, padding);\n\t}\n\tif ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0)\n\t\tgoto out;\n\n\t/* Add check bytes. */\n\tchecksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet),\n\t sshbuf_len(state->outgoing_packet));\n\tPOKE_U32(buf, checksum);\n\tif ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0)\n\t\tgoto out;\n\n#ifdef PACKET_DEBUG\n\tfprintf(stderr, \"packet_send plain: \");\n\tsshbuf_dump(state->outgoing_packet, stderr);\n#endif\n\n\t/* Append to output. */\n\tPOKE_U32(buf, len);\n\tif ((r = sshbuf_put(state->output, buf, 4)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_reserve(state->output,\n\t sshbuf_len(state->outgoing_packet), &cp)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(state->send_context, 0, cp,\n\t sshbuf_ptr(state->outgoing_packet),\n\t sshbuf_len(state->outgoing_packet), 0, 0)) != 0)\n\t\tgoto out;\n\n#ifdef PACKET_DEBUG\n\tfprintf(stderr, \"encrypted: \");\n\tsshbuf_dump(state->output, stderr);\n#endif\n\tstate->p_send.packets++;\n\tstate->p_send.bytes += len +\n\t sshbuf_len(state->outgoing_packet);\n\tsshbuf_reset(state->outgoing_packet);\n\n\t/*\n\t * Note that the packet is now only buffered in output. It won't be\n\t * actually sent until ssh_packet_write_wait or ssh_packet_write_poll\n\t * is called.\n\t */\n\tr = 0;\n out:\n\treturn r;\n}\n\nint\nssh_set_newkeys(struct ssh *ssh, int mode)\n{\n\tstruct session_state *state = ssh->state;\n\tstruct sshenc *enc;\n\tstruct sshmac *mac;\n\tstruct sshcomp *comp;\n\tstruct sshcipher_ctx **ccp;\n\tstruct packet_state *ps;\n\tu_int64_t *max_blocks;\n\tconst char *wmsg, *dir;\n\tint r, crypt_type;\n\n\tdebug2(\"set_newkeys: mode %d\", mode);\n\n\tif (mode == MODE_OUT) {\n\t\tdir = \"output\";\n\t\tccp = &state->send_context;\n\t\tcrypt_type = CIPHER_ENCRYPT;\n\t\tps = &state->p_send;\n\t\tmax_blocks = &state->max_blocks_out;\n\t} else {\n\t\tdir = \"input\";\n\t\tccp = &state->receive_context;\n\t\tcrypt_type = CIPHER_DECRYPT;\n\t\tps = &state->p_read;\n\t\tmax_blocks = &state->max_blocks_in;\n\t}\n\tif (state->newkeys[mode] != NULL) {\n\t\tdebug(\"%s: rekeying after %llu %s blocks\"\n\t\t \" (%llu bytes total)\", __func__,\n\t\t (unsigned long long)ps->blocks, dir,\n\t\t (unsigned long long)ps->bytes);\n\t\tcipher_free(*ccp);\n\t\t*ccp = NULL;\n\t\tenc = &state->newkeys[mode]->enc;\n\t\tmac = &state->newkeys[mode]->mac;\n\t\tcomp = &state->newkeys[mode]->comp;\n\t\tmac_clear(mac);\n\t\texplicit_bzero(enc->iv, enc->iv_len);\n\t\texplicit_bzero(enc->key, enc->key_len);\n\t\texplicit_bzero(mac->key, mac->key_len);\n\t\tfree(enc->name);\n\t\tfree(enc->iv);\n\t\tfree(enc->key);\n\t\tfree(mac->name);\n\t\tfree(mac->key);\n\t\tfree(comp->name);\n\t\tfree(state->newkeys[mode]);\n\t}\n\t/* note that both bytes and the seqnr are not reset */\n\tps->packets = ps->blocks = 0;\n\t/* move newkeys from kex to state */\n\tif ((state->newkeys[mode] = ssh->kex->newkeys[mode]) == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tssh->kex->newkeys[mode] = NULL;\n\tenc = &state->newkeys[mode]->enc;\n\tmac = &state->newkeys[mode]->mac;\n\tcomp = &state->newkeys[mode]->comp;\n\tif (cipher_authlen(enc->cipher) == 0) {\n\t\tif ((r = mac_init(mac)) != 0)\n\t\t\treturn r;\n\t}\n\tmac->enabled = 1;\n\tDBG(debug(\"cipher_init_context: %d\", mode));\n\tif ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len,\n\t enc->iv, enc->iv_len, crypt_type)) != 0)\n\t\treturn r;\n\tif (!state->cipher_warning_done &&\n\t (wmsg = cipher_warning_message(*ccp)) != NULL) {\n\t\terror(\"Warning: %s\", wmsg);\n\t\tstate->cipher_warning_done = 1;\n\t}\n\t/* Deleting the keys does not gain extra security */\n\t/* explicit_bzero(enc->iv, enc->block_size);\n\t explicit_bzero(enc->key, enc->key_len);\n\t explicit_bzero(mac->key, mac->key_len); */\n\tif ((comp->type == COMP_ZLIB ||\n\t (comp->type == COMP_DELAYED &&\n\t state->after_authentication)) && comp->enabled == 0) {\n\t\tif ((r = ssh_packet_init_compression(ssh)) < 0)\n\t\t\treturn r;\n\t\tif (mode == MODE_OUT) {\n\t\t\tif ((r = start_compression_out(ssh, 6)) != 0)\n\t\t\t\treturn r;\n\t\t} else {\n\t\t\tif ((r = start_compression_in(ssh)) != 0)\n\t\t\t\treturn r;\n\t\t}\n\t\tcomp->enabled = 1;\n\t}\n\t/*\n\t * The 2^(blocksize*2) limit is too expensive for 3DES,\n\t * blowfish, etc, so enforce a 1GB limit for small blocksizes.\n\t */\n\tif (enc->block_size >= 16)\n\t\t*max_blocks = (u_int64_t)1 << (enc->block_size*2);\n\telse\n\t\t*max_blocks = ((u_int64_t)1 << 30) / enc->block_size;\n\tif (state->rekey_limit)\n\t\t*max_blocks = MINIMUM(*max_blocks,\n\t\t state->rekey_limit / enc->block_size);\n\tdebug(\"rekey after %llu blocks\", (unsigned long long)*max_blocks);\n\treturn 0;\n}\n\n#define MAX_PACKETS\t(1U<<31)\nstatic int\nssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len)\n{\n\tstruct session_state *state = ssh->state;\n\tu_int32_t out_blocks;\n\n\t/* XXX client can't cope with rekeying pre-auth */\n\tif (!state->after_authentication)\n\t\treturn 0;\n\n\t/* Haven't keyed yet or KEX in progress. */\n\tif (ssh->kex == NULL || ssh_packet_is_rekeying(ssh))\n\t\treturn 0;\n\n\t/* Peer can't rekey */\n\tif (ssh->compat & SSH_BUG_NOREKEY)\n\t\treturn 0;\n\n\t/*\n\t * Permit one packet in or out per rekey - this allows us to\n\t * make progress when rekey limits are very small.\n\t */\n\tif (state->p_send.packets == 0 && state->p_read.packets == 0)\n\t\treturn 0;\n\n\t/* Time-based rekeying */\n\tif (state->rekey_interval != 0 &&\n\t (int64_t)state->rekey_time + state->rekey_interval <= monotime())\n\t\treturn 1;\n\n\t/* Always rekey when MAX_PACKETS sent in either direction */\n\tif (state->p_send.packets > MAX_PACKETS ||\n\t state->p_read.packets > MAX_PACKETS)\n\t\treturn 1;\n\n\t/* Rekey after (cipher-specific) maxiumum blocks */\n\tout_blocks = ROUNDUP(outbound_packet_len,\n\t state->newkeys[MODE_OUT]->enc.block_size);\n\treturn (state->max_blocks_out &&\n\t (state->p_send.blocks + out_blocks > state->max_blocks_out)) ||\n\t (state->max_blocks_in &&\n\t (state->p_read.blocks > state->max_blocks_in));\n}\n\n/*\n * Delayed compression for SSH2 is enabled after authentication:\n * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,\n * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.\n */\nstatic int\nssh_packet_enable_delayed_compress(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tstruct sshcomp *comp = NULL;\n\tint r, mode;\n\n\t/*\n\t * Remember that we are past the authentication step, so rekeying\n\t * with COMP_DELAYED will turn on compression immediately.\n\t */\n\tstate->after_authentication = 1;\n\tfor (mode = 0; mode < MODE_MAX; mode++) {\n\t\t/* protocol error: USERAUTH_SUCCESS received before NEWKEYS */\n\t\tif (state->newkeys[mode] == NULL)\n\t\t\tcontinue;\n\t\tcomp = &state->newkeys[mode]->comp;\n\t\tif (comp && !comp->enabled && comp->type == COMP_DELAYED) {\n\t\t\tif ((r = ssh_packet_init_compression(ssh)) != 0)\n\t\t\t\treturn r;\n\t\t\tif (mode == MODE_OUT) {\n\t\t\t\tif ((r = start_compression_out(ssh, 6)) != 0)\n\t\t\t\t\treturn r;\n\t\t\t} else {\n\t\t\t\tif ((r = start_compression_in(ssh)) != 0)\n\t\t\t\t\treturn r;\n\t\t\t}\n\t\t\tcomp->enabled = 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\n/* Used to mute debug logging for noisy packet types */\nint\nssh_packet_log_type(u_char type)\n{\n\tswitch (type) {\n\tcase SSH2_MSG_CHANNEL_DATA:\n\tcase SSH2_MSG_CHANNEL_EXTENDED_DATA:\n\tcase SSH2_MSG_CHANNEL_WINDOW_ADJUST:\n\t\treturn 0;\n\tdefault:\n\t\treturn 1;\n\t}\n}\n\n/*\n * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)\n */\nint\nssh_packet_send2_wrapped(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tu_char type, *cp, macbuf[SSH_DIGEST_MAX_LENGTH];\n\tu_char tmp, padlen, pad = 0;\n\tu_int authlen = 0, aadlen = 0;\n\tu_int len;\n\tstruct sshenc *enc = NULL;\n\tstruct sshmac *mac = NULL;\n\tstruct sshcomp *comp = NULL;\n\tint r, block_size;\n\n\tif (state->newkeys[MODE_OUT] != NULL) {\n\t\tenc = &state->newkeys[MODE_OUT]->enc;\n\t\tmac = &state->newkeys[MODE_OUT]->mac;\n\t\tcomp = &state->newkeys[MODE_OUT]->comp;\n\t\t/* disable mac for authenticated encryption */\n\t\tif ((authlen = cipher_authlen(enc->cipher)) != 0)\n\t\t\tmac = NULL;\n\t}\n\tblock_size = enc ? enc->block_size : 8;\n\taadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;\n\n\ttype = (sshbuf_ptr(state->outgoing_packet))[5];\n\tif (ssh_packet_log_type(type))\n\t\tdebug3(\"send packet: type %u\", type);\n#ifdef PACKET_DEBUG\n\tfprintf(stderr, \"plain: \");\n\tsshbuf_dump(state->outgoing_packet, stderr);\n#endif\n\n\tif (comp && comp->enabled) {\n\t\tlen = sshbuf_len(state->outgoing_packet);\n\t\t/* skip header, compress only payload */\n\t\tif ((r = sshbuf_consume(state->outgoing_packet, 5)) != 0)\n\t\t\tgoto out;\n\t\tsshbuf_reset(state->compression_buffer);\n\t\tif ((r = compress_buffer(ssh, state->outgoing_packet,\n\t\t state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t\tsshbuf_reset(state->outgoing_packet);\n\t\tif ((r = sshbuf_put(state->outgoing_packet,\n\t\t \"\\0\\0\\0\\0\\0\", 5)) != 0 ||\n\t\t (r = sshbuf_putb(state->outgoing_packet,\n\t\t state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t\tDBG(debug(\"compression: raw %d compressed %zd\", len,\n\t\t sshbuf_len(state->outgoing_packet)));\n\t}\n\n\t/* sizeof (packet_len + pad_len + payload) */\n\tlen = sshbuf_len(state->outgoing_packet);\n\n\t/*\n\t * calc size of padding, alloc space, get random data,\n\t * minimum padding is 4 bytes\n\t */\n\tlen -= aadlen; /* packet length is not encrypted for EtM modes */\n\tpadlen = block_size - (len % block_size);\n\tif (padlen < 4)\n\t\tpadlen += block_size;\n\tif (state->extra_pad) {\n\t\ttmp = state->extra_pad;\n\t\tstate->extra_pad =\n\t\t ROUNDUP(state->extra_pad, block_size);\n\t\t/* check if roundup overflowed */\n\t\tif (state->extra_pad < tmp)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\ttmp = (len + padlen) % state->extra_pad;\n\t\t/* Check whether pad calculation below will underflow */\n\t\tif (tmp > state->extra_pad)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\tpad = state->extra_pad - tmp;\n\t\tDBG(debug3(\"%s: adding %d (len %d padlen %d extra_pad %d)\",\n\t\t __func__, pad, len, padlen, state->extra_pad));\n\t\ttmp = padlen;\n\t\tpadlen += pad;\n\t\t/* Check whether padlen calculation overflowed */\n\t\tif (padlen < tmp)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT; /* overflow */\n\t\tstate->extra_pad = 0;\n\t}\n\tif ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0)\n\t\tgoto out;\n\tif (enc && !cipher_ctx_is_plaintext(state->send_context)) {\n\t\t/* random padding */\n\t\tarc4random_buf(cp, padlen);\n\t} else {\n\t\t/* clear padding */\n\t\texplicit_bzero(cp, padlen);\n\t}\n\t/* sizeof (packet_len + pad_len + payload + padding) */\n\tlen = sshbuf_len(state->outgoing_packet);\n\tcp = sshbuf_mutable_ptr(state->outgoing_packet);\n\tif (cp == NULL) {\n\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\tgoto out;\n\t}\n\t/* packet_length includes payload, padding and padding length field */\n\tPOKE_U32(cp, len - 4);\n\tcp[4] = padlen;\n\tDBG(debug(\"send: len %d (includes padlen %d, aadlen %d)\",\n\t len, padlen, aadlen));\n\n\t/* compute MAC over seqnr and packet(length fields, payload, padding) */\n\tif (mac && mac->enabled && !mac->etm) {\n\t\tif ((r = mac_compute(mac, state->p_send.seqnr,\n\t\t sshbuf_ptr(state->outgoing_packet), len,\n\t\t macbuf, sizeof(macbuf))) != 0)\n\t\t\tgoto out;\n\t\tDBG(debug(\"done calc MAC out #%d\", state->p_send.seqnr));\n\t}\n\t/* encrypt packet and append to output buffer. */\n\tif ((r = sshbuf_reserve(state->output,\n\t sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(state->send_context, state->p_send.seqnr, cp,\n\t sshbuf_ptr(state->outgoing_packet),\n\t len - aadlen, aadlen, authlen)) != 0)\n\t\tgoto out;\n\t/* append unencrypted MAC */\n\tif (mac && mac->enabled) {\n\t\tif (mac->etm) {\n\t\t\t/* EtM: compute mac over aadlen + cipher text */\n\t\t\tif ((r = mac_compute(mac, state->p_send.seqnr,\n\t\t\t cp, len, macbuf, sizeof(macbuf))) != 0)\n\t\t\t\tgoto out;\n\t\t\tDBG(debug(\"done calc MAC(EtM) out #%d\",\n\t\t\t state->p_send.seqnr));\n\t\t}\n\t\tif ((r = sshbuf_put(state->output, macbuf, mac->mac_len)) != 0)\n\t\t\tgoto out;\n\t}\n#ifdef PACKET_DEBUG\n\tfprintf(stderr, \"encrypted: \");\n\tsshbuf_dump(state->output, stderr);\n#endif\n\t/* increment sequence number for outgoing packets */\n\tif (++state->p_send.seqnr == 0)\n\t\tlogit(\"outgoing seqnr wraps around\");\n\tif (++state->p_send.packets == 0)\n\t\tif (!(ssh->compat & SSH_BUG_NOREKEY))\n\t\t\treturn SSH_ERR_NEED_REKEY;\n\tstate->p_send.blocks += len / block_size;\n\tstate->p_send.bytes += len;\n\tsshbuf_reset(state->outgoing_packet);\n\n\tif (type == SSH2_MSG_NEWKEYS)\n\t\tr = ssh_set_newkeys(ssh, MODE_OUT);\n\telse if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side)\n\t\tr = ssh_packet_enable_delayed_compress(ssh);\n\telse\n\t\tr = 0;\n out:\n\treturn r;\n}\n\n/* returns non-zero if the specified packet type is usec by KEX */\nstatic int\nssh_packet_type_is_kex(u_char type)\n{\n\treturn\n\t type >= SSH2_MSG_TRANSPORT_MIN &&\n\t type <= SSH2_MSG_TRANSPORT_MAX &&\n\t type != SSH2_MSG_SERVICE_REQUEST &&\n\t type != SSH2_MSG_SERVICE_ACCEPT &&\n\t type != SSH2_MSG_EXT_INFO;\n}\n\nint\nssh_packet_send2(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tstruct packet *p;\n\tu_char type;\n\tint r, need_rekey;\n\n\tif (sshbuf_len(state->outgoing_packet) < 6)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\ttype = sshbuf_ptr(state->outgoing_packet)[5];\n\tneed_rekey = !ssh_packet_type_is_kex(type) &&\n\t ssh_packet_need_rekeying(ssh, sshbuf_len(state->outgoing_packet));\n\n\t/*\n\t * During rekeying we can only send key exchange messages.\n\t * Queue everything else.\n\t */\n\tif ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) {\n\t\tif (need_rekey)\n\t\t\tdebug3(\"%s: rekex triggered\", __func__);\n\t\tdebug(\"enqueue packet: %u\", type);\n\t\tp = calloc(1, sizeof(*p));\n\t\tif (p == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tp->type = type;\n\t\tp->payload = state->outgoing_packet;\n\t\tTAILQ_INSERT_TAIL(&state->outgoing, p, next);\n\t\tstate->outgoing_packet = sshbuf_new();\n\t\tif (state->outgoing_packet == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tif (need_rekey) {\n\t\t\t/*\n\t\t\t * This packet triggered a rekey, so send the\n\t\t\t * KEXINIT now.\n\t\t\t * NB. reenters this function via kex_start_rekex().\n\t\t\t */\n\t\t\treturn kex_start_rekex(ssh);\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/* rekeying starts with sending KEXINIT */\n\tif (type == SSH2_MSG_KEXINIT)\n\t\tstate->rekeying = 1;\n\n\tif ((r = ssh_packet_send2_wrapped(ssh)) != 0)\n\t\treturn r;\n\n\t/* after a NEWKEYS message we can send the complete queue */\n\tif (type == SSH2_MSG_NEWKEYS) {\n\t\tstate->rekeying = 0;\n\t\tstate->rekey_time = monotime();\n\t\twhile ((p = TAILQ_FIRST(&state->outgoing))) {\n\t\t\ttype = p->type;\n\t\t\t/*\n\t\t\t * If this packet triggers a rekex, then skip the\n\t\t\t * remaining packets in the queue for now.\n\t\t\t * NB. re-enters this function via kex_start_rekex.\n\t\t\t */\n\t\t\tif (ssh_packet_need_rekeying(ssh,\n\t\t\t sshbuf_len(p->payload))) {\n\t\t\t\tdebug3(\"%s: queued packet triggered rekex\",\n\t\t\t\t __func__);\n\t\t\t\treturn kex_start_rekex(ssh);\n\t\t\t}\n\t\t\tdebug(\"dequeue packet: %u\", type);\n\t\t\tsshbuf_free(state->outgoing_packet);\n\t\t\tstate->outgoing_packet = p->payload;\n\t\t\tTAILQ_REMOVE(&state->outgoing, p, next);\n\t\t\tmemset(p, 0, sizeof(*p));\n\t\t\tfree(p);\n\t\t\tif ((r = ssh_packet_send2_wrapped(ssh)) != 0)\n\t\t\t\treturn r;\n\t\t}\n\t}\n\treturn 0;\n}\n\n/*\n * Waits until a packet has been received, and returns its type. Note that\n * no other data is processed until this returns, so this function should not\n * be used during the interactive session.\n */\n\nint\nssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)\n{\n\tstruct session_state *state = ssh->state;\n\tint len, r, ms_remain;\n\tfd_set *setp;\n\tchar buf[8192];\n\tstruct timeval timeout, start, *timeoutp = NULL;\n\n\tDBG(debug(\"packet_read()\"));\n\n\tsetp = calloc(howmany(state->connection_in + 1,\n\t NFDBITS), sizeof(fd_mask));\n\tif (setp == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\t/*\n\t * Since we are blocking, ensure that all written packets have\n\t * been sent.\n\t */\n\tif ((r = ssh_packet_write_wait(ssh)) != 0)\n\t\tgoto out;\n\n\t/* Stay in the loop until we have received a complete packet. */\n\tfor (;;) {\n\t\t/* Try to read a packet from the buffer. */\n\t\tr = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);\n\t\tif (r != 0)\n\t\t\tbreak;\n\t\tif (!compat20 && (\n\t\t *typep == SSH_SMSG_SUCCESS\n\t\t || *typep == SSH_SMSG_FAILURE\n\t\t || *typep == SSH_CMSG_EOF\n\t\t || *typep == SSH_CMSG_EXIT_CONFIRMATION))\n\t\t\tif ((r = sshpkt_get_end(ssh)) != 0)\n\t\t\t\tbreak;\n\t\t/* If we got a packet, return it. */\n\t\tif (*typep != SSH_MSG_NONE)\n\t\t\tbreak;\n\t\t/*\n\t\t * Otherwise, wait for some data to arrive, add it to the\n\t\t * buffer, and try again.\n\t\t */\n\t\tmemset(setp, 0, howmany(state->connection_in + 1,\n\t\t NFDBITS) * sizeof(fd_mask));\n\t\tFD_SET(state->connection_in, setp);\n\n\t\tif (state->packet_timeout_ms > 0) {\n\t\t\tms_remain = state->packet_timeout_ms;\n\t\t\ttimeoutp = &timeout;\n\t\t}\n\t\t/* Wait for some data to arrive. */\n\t\tfor (;;) {\n\t\t\tif (state->packet_timeout_ms != -1) {\n\t\t\t\tms_to_timeval(&timeout, ms_remain);\n\t\t\t\tgettimeofday(&start, NULL);\n\t\t\t}\n\t\t\tif ((r = select(state->connection_in + 1, setp,\n\t\t\t NULL, NULL, timeoutp)) >= 0)\n\t\t\t\tbreak;\n\t\t\tif (errno != EAGAIN && errno != EINTR &&\n\t\t\t errno != EWOULDBLOCK)\n\t\t\t\tbreak;\n\t\t\tif (state->packet_timeout_ms == -1)\n\t\t\t\tcontinue;\n\t\t\tms_subtract_diff(&start, &ms_remain);\n\t\t\tif (ms_remain <= 0) {\n\t\t\t\tr = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (r == 0) {\n\t\t\tr = SSH_ERR_CONN_TIMEOUT;\n\t\t\tgoto out;\n\t\t}\n\t\t/* Read data from the socket. */\n\t\tlen = read(state->connection_in, buf, sizeof(buf));\n\t\tif (len == 0) {\n\t\t\tr = SSH_ERR_CONN_CLOSED;\n\t\t\tgoto out;\n\t\t}\n\t\tif (len < 0) {\n\t\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\t\tgoto out;\n\t\t}\n\n\t\t/* Append it to the buffer. */\n\t\tif ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0)\n\t\t\tgoto out;\n\t}\n out:\n\tfree(setp);\n\treturn r;\n}\n\nint\nssh_packet_read(struct ssh *ssh)\n{\n\tu_char type;\n\tint r;\n\n\tif ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\treturn type;\n}\n\n/*\n * Waits until a packet has been received, verifies that its type matches\n * that given, and gives a fatal error and exits if there is a mismatch.\n */\n\nint\nssh_packet_read_expect(struct ssh *ssh, u_int expected_type)\n{\n\tint r;\n\tu_char type;\n\n\tif ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0)\n\t\treturn r;\n\tif (type != expected_type) {\n\t\tif ((r = sshpkt_disconnect(ssh,\n\t\t \"Protocol error: expected packet type %d, got %d\",\n\t\t expected_type, type)) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_PROTOCOL_ERROR;\n\t}\n\treturn 0;\n}\n\n/* Checks if a full packet is available in the data received so far via\n * packet_process_incoming. If so, reads the packet; otherwise returns\n * SSH_MSG_NONE. This does not wait for data from the connection.\n *\n * SSH_MSG_DISCONNECT is handled specially here. Also,\n * SSH_MSG_IGNORE messages are skipped by this function and are never returned\n * to higher levels.\n */\n\nint\nssh_packet_read_poll1(struct ssh *ssh, u_char *typep)\n{\n\tstruct session_state *state = ssh->state;\n\tu_int len, padded_len;\n\tconst char *emsg;\n\tconst u_char *cp;\n\tu_char *p;\n\tu_int checksum, stored_checksum;\n\tint r;\n\n\t*typep = SSH_MSG_NONE;\n\n\t/* Check if input size is less than minimum packet size. */\n\tif (sshbuf_len(state->input) < 4 + 8)\n\t\treturn 0;\n\t/* Get length of incoming packet. */\n\tlen = PEEK_U32(sshbuf_ptr(state->input));\n\tif (len < 1 + 2 + 2 || len > 256 * 1024) {\n\t\tif ((r = sshpkt_disconnect(ssh, \"Bad packet length %u\",\n\t\t len)) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_CONN_CORRUPT;\n\t}\n\tpadded_len = (len + 8) & ~7;\n\n\t/* Check if the packet has been entirely received. */\n\tif (sshbuf_len(state->input) < 4 + padded_len)\n\t\treturn 0;\n\n\t/* The entire packet is in buffer. */\n\n\t/* Consume packet length. */\n\tif ((r = sshbuf_consume(state->input, 4)) != 0)\n\t\tgoto out;\n\n\t/*\n\t * Cryptographic attack detector for ssh\n\t * (C)1998 CORE-SDI, Buenos Aires Argentina\n\t * Ariel Futoransky(futo@core-sdi.com)\n\t */\n\tif (!cipher_ctx_is_plaintext(state->receive_context)) {\n\t\temsg = NULL;\n\t\tswitch (detect_attack(&state->deattack,\n\t\t sshbuf_ptr(state->input), padded_len)) {\n\t\tcase DEATTACK_OK:\n\t\t\tbreak;\n\t\tcase DEATTACK_DETECTED:\n\t\t\temsg = \"crc32 compensation attack detected\";\n\t\t\tbreak;\n\t\tcase DEATTACK_DOS_DETECTED:\n\t\t\temsg = \"deattack denial of service detected\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\temsg = \"deattack error\";\n\t\t\tbreak;\n\t\t}\n\t\tif (emsg != NULL) {\n\t\t\terror(\"%s\", emsg);\n\t\t\tif ((r = sshpkt_disconnect(ssh, \"%s\", emsg)) != 0 ||\n\t\t\t (r = ssh_packet_write_wait(ssh)) != 0)\n\t\t\t\t\treturn r;\n\t\t\treturn SSH_ERR_CONN_CORRUPT;\n\t\t}\n\t}\n\n\t/* Decrypt data to incoming_packet. */\n\tsshbuf_reset(state->incoming_packet);\n\tif ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(state->receive_context, 0, p,\n\t sshbuf_ptr(state->input), padded_len, 0, 0)) != 0)\n\t\tgoto out;\n\n\tif ((r = sshbuf_consume(state->input, padded_len)) != 0)\n\t\tgoto out;\n\n#ifdef PACKET_DEBUG\n\tfprintf(stderr, \"read_poll plain: \");\n\tsshbuf_dump(state->incoming_packet, stderr);\n#endif\n\n\t/* Compute packet checksum. */\n\tchecksum = ssh_crc32(sshbuf_ptr(state->incoming_packet),\n\t sshbuf_len(state->incoming_packet) - 4);\n\n\t/* Skip padding. */\n\tif ((r = sshbuf_consume(state->incoming_packet, 8 - len % 8)) != 0)\n\t\tgoto out;\n\n\t/* Test check bytes. */\n\tif (len != sshbuf_len(state->incoming_packet)) {\n\t\terror(\"%s: len %d != sshbuf_len %zd\", __func__,\n\t\t len, sshbuf_len(state->incoming_packet));\n\t\tif ((r = sshpkt_disconnect(ssh, \"invalid packet length\")) != 0 ||\n\t\t (r = ssh_packet_write_wait(ssh)) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_CONN_CORRUPT;\n\t}\n\n\tcp = sshbuf_ptr(state->incoming_packet) + len - 4;\n\tstored_checksum = PEEK_U32(cp);\n\tif (checksum != stored_checksum) {\n\t\terror(\"Corrupted check bytes on input\");\n\t\tif ((r = sshpkt_disconnect(ssh, \"connection corrupted\")) != 0 ||\n\t\t (r = ssh_packet_write_wait(ssh)) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_CONN_CORRUPT;\n\t}\n\tif ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0)\n\t\tgoto out;\n\n\tif (state->packet_compression) {\n\t\tsshbuf_reset(state->compression_buffer);\n\t\tif ((r = uncompress_buffer(ssh, state->incoming_packet,\n\t\t state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t\tsshbuf_reset(state->incoming_packet);\n\t\tif ((r = sshbuf_putb(state->incoming_packet,\n\t\t state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t}\n\tstate->p_read.packets++;\n\tstate->p_read.bytes += padded_len + 4;\n\tif ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)\n\t\tgoto out;\n\tif (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) {\n\t\terror(\"Invalid ssh1 packet type: %d\", *typep);\n\t\tif ((r = sshpkt_disconnect(ssh, \"invalid packet type\")) != 0 ||\n\t\t (r = ssh_packet_write_wait(ssh)) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_PROTOCOL_ERROR;\n\t}\n\tr = 0;\n out:\n\treturn r;\n}\n\nstatic int\nssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)\n{\n\tstruct session_state *state = ssh->state;\n\tconst u_char *cp;\n\tsize_t need;\n\tint r;\n\n\tif (ssh->kex)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t*typep = SSH_MSG_NONE;\n\tcp = sshbuf_ptr(state->input);\n\tif (state->packlen == 0) {\n\t\tif (sshbuf_len(state->input) < 4 + 1)\n\t\t\treturn 0; /* packet is incomplete */\n\t\tstate->packlen = PEEK_U32(cp);\n\t\tif (state->packlen < 4 + 1 ||\n\t\t state->packlen > PACKET_MAX_SIZE)\n\t\t\treturn SSH_ERR_MESSAGE_INCOMPLETE;\n\t}\n\tneed = state->packlen + 4;\n\tif (sshbuf_len(state->input) < need)\n\t\treturn 0; /* packet is incomplete */\n\tsshbuf_reset(state->incoming_packet);\n\tif ((r = sshbuf_put(state->incoming_packet, cp + 4,\n\t state->packlen)) != 0 ||\n\t (r = sshbuf_consume(state->input, need)) != 0 ||\n\t (r = sshbuf_get_u8(state->incoming_packet, NULL)) != 0 ||\n\t (r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)\n\t\treturn r;\n\tif (ssh_packet_log_type(*typep))\n\t\tdebug3(\"%s: type %u\", __func__, *typep);\n\t/* sshbuf_dump(state->incoming_packet, stderr); */\n\t/* reset for next packet */\n\tstate->packlen = 0;\n\treturn r;\n}\n\nint\nssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)\n{\n\tstruct session_state *state = ssh->state;\n\tu_int padlen, need;\n\tu_char *cp;\n\tu_int maclen, aadlen = 0, authlen = 0, block_size;\n\tstruct sshenc *enc = NULL;\n\tstruct sshmac *mac = NULL;\n\tstruct sshcomp *comp = NULL;\n\tint r;\n\n\tif (state->mux)\n\t\treturn ssh_packet_read_poll2_mux(ssh, typep, seqnr_p);\n\n\t*typep = SSH_MSG_NONE;\n\n\tif (state->packet_discard)\n\t\treturn 0;\n\n\tif (state->newkeys[MODE_IN] != NULL) {\n\t\tenc = &state->newkeys[MODE_IN]->enc;\n\t\tmac = &state->newkeys[MODE_IN]->mac;\n\t\tcomp = &state->newkeys[MODE_IN]->comp;\n\t\t/* disable mac for authenticated encryption */\n\t\tif ((authlen = cipher_authlen(enc->cipher)) != 0)\n\t\t\tmac = NULL;\n\t}\n\tmaclen = mac && mac->enabled ? mac->mac_len : 0;\n\tblock_size = enc ? enc->block_size : 8;\n\taadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;\n\n\tif (aadlen && state->packlen == 0) {\n\t\tif (cipher_get_length(state->receive_context,\n\t\t &state->packlen, state->p_read.seqnr,\n\t\t sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0)\n\t\t\treturn 0;\n\t\tif (state->packlen < 1 + 4 ||\n\t\t state->packlen > PACKET_MAX_SIZE) {\n#ifdef PACKET_DEBUG\n\t\t\tsshbuf_dump(state->input, stderr);\n#endif\n\t\t\tlogit(\"Bad packet length %u.\", state->packlen);\n\t\t\tif ((r = sshpkt_disconnect(ssh, \"Packet corrupt\")) != 0)\n\t\t\t\treturn r;\n\t\t\treturn SSH_ERR_CONN_CORRUPT;\n\t\t}\n\t\tsshbuf_reset(state->incoming_packet);\n\t} else if (state->packlen == 0) {\n\t\t/*\n\t\t * check if input size is less than the cipher block size,\n\t\t * decrypt first block and extract length of incoming packet\n\t\t */\n\t\tif (sshbuf_len(state->input) < block_size)\n\t\t\treturn 0;\n\t\tsshbuf_reset(state->incoming_packet);\n\t\tif ((r = sshbuf_reserve(state->incoming_packet, block_size,\n\t\t &cp)) != 0)\n\t\t\tgoto out;\n\t\tif ((r = cipher_crypt(state->receive_context,\n\t\t state->p_send.seqnr, cp, sshbuf_ptr(state->input),\n\t\t block_size, 0, 0)) != 0)\n\t\t\tgoto out;\n\t\tstate->packlen = PEEK_U32(sshbuf_ptr(state->incoming_packet));\n\t\tif (state->packlen < 1 + 4 ||\n\t\t state->packlen > PACKET_MAX_SIZE) {\n#ifdef PACKET_DEBUG\n\t\t\tfprintf(stderr, \"input: \\n\");\n\t\t\tsshbuf_dump(state->input, stderr);\n\t\t\tfprintf(stderr, \"incoming_packet: \\n\");\n\t\t\tsshbuf_dump(state->incoming_packet, stderr);\n#endif\n\t\t\tlogit(\"Bad packet length %u.\", state->packlen);\n\t\t\treturn ssh_packet_start_discard(ssh, enc, mac, 0,\n\t\t\t PACKET_MAX_SIZE);\n\t\t}\n\t\tif ((r = sshbuf_consume(state->input, block_size)) != 0)\n\t\t\tgoto out;\n\t}\n\tDBG(debug(\"input: packet len %u\", state->packlen+4));\n\n\tif (aadlen) {\n\t\t/* only the payload is encrypted */\n\t\tneed = state->packlen;\n\t} else {\n\t\t/*\n\t\t * the payload size and the payload are encrypted, but we\n\t\t * have a partial packet of block_size bytes\n\t\t */\n\t\tneed = 4 + state->packlen - block_size;\n\t}\n\tDBG(debug(\"partial packet: block %d, need %d, maclen %d, authlen %d,\"\n\t \" aadlen %d\", block_size, need, maclen, authlen, aadlen));\n\tif (need % block_size != 0) {\n\t\tlogit(\"padding error: need %d block %d mod %d\",\n\t\t need, block_size, need % block_size);\n\t\treturn ssh_packet_start_discard(ssh, enc, mac, 0,\n\t\t PACKET_MAX_SIZE - block_size);\n\t}\n\t/*\n\t * check if the entire packet has been received and\n\t * decrypt into incoming_packet:\n\t * 'aadlen' bytes are unencrypted, but authenticated.\n\t * 'need' bytes are encrypted, followed by either\n\t * 'authlen' bytes of authentication tag or\n\t * 'maclen' bytes of message authentication code.\n\t */\n\tif (sshbuf_len(state->input) < aadlen + need + authlen + maclen)\n\t\treturn 0; /* packet is incomplete */\n#ifdef PACKET_DEBUG\n\tfprintf(stderr, \"read_poll enc/full: \");\n\tsshbuf_dump(state->input, stderr);\n#endif\n\t/* EtM: check mac over encrypted input */\n\tif (mac && mac->enabled && mac->etm) {\n\t\tif ((r = mac_check(mac, state->p_read.seqnr,\n\t\t sshbuf_ptr(state->input), aadlen + need,\n\t\t sshbuf_ptr(state->input) + aadlen + need + authlen,\n\t\t maclen)) != 0) {\n\t\t\tif (r == SSH_ERR_MAC_INVALID)\n\t\t\t\tlogit(\"Corrupted MAC on input.\");\n\t\t\tgoto out;\n\t\t}\n\t}\n\tif ((r = sshbuf_reserve(state->incoming_packet, aadlen + need,\n\t &cp)) != 0)\n\t\tgoto out;\n\tif ((r = cipher_crypt(state->receive_context, state->p_read.seqnr, cp,\n\t sshbuf_ptr(state->input), need, aadlen, authlen)) != 0)\n\t\tgoto out;\n\tif ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0)\n\t\tgoto out;\n\tif (mac && mac->enabled) {\n\t\t/* Not EtM: check MAC over cleartext */\n\t\tif (!mac->etm && (r = mac_check(mac, state->p_read.seqnr,\n\t\t sshbuf_ptr(state->incoming_packet),\n\t\t sshbuf_len(state->incoming_packet),\n\t\t sshbuf_ptr(state->input), maclen)) != 0) {\n\t\t\tif (r != SSH_ERR_MAC_INVALID)\n\t\t\t\tgoto out;\n\t\t\tlogit(\"Corrupted MAC on input.\");\n\t\t\tif (need + block_size > PACKET_MAX_SIZE)\n\t\t\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t\t\treturn ssh_packet_start_discard(ssh, enc, mac,\n\t\t\t sshbuf_len(state->incoming_packet),\n\t\t\t PACKET_MAX_SIZE - need - block_size);\n\t\t}\n\t\t/* Remove MAC from input buffer */\n\t\tDBG(debug(\"MAC #%d ok\", state->p_read.seqnr));\n\t\tif ((r = sshbuf_consume(state->input, mac->mac_len)) != 0)\n\t\t\tgoto out;\n\t}\n\tif (seqnr_p != NULL)\n\t\t*seqnr_p = state->p_read.seqnr;\n\tif (++state->p_read.seqnr == 0)\n\t\tlogit(\"incoming seqnr wraps around\");\n\tif (++state->p_read.packets == 0)\n\t\tif (!(ssh->compat & SSH_BUG_NOREKEY))\n\t\t\treturn SSH_ERR_NEED_REKEY;\n\tstate->p_read.blocks += (state->packlen + 4) / block_size;\n\tstate->p_read.bytes += state->packlen + 4;\n\n\t/* get padlen */\n\tpadlen = sshbuf_ptr(state->incoming_packet)[4];\n\tDBG(debug(\"input: padlen %d\", padlen));\n\tif (padlen < 4)\t{\n\t\tif ((r = sshpkt_disconnect(ssh,\n\t\t \"Corrupted padlen %d on input.\", padlen)) != 0 ||\n\t\t (r = ssh_packet_write_wait(ssh)) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_CONN_CORRUPT;\n\t}\n\n\t/* skip packet size + padlen, discard padding */\n\tif ((r = sshbuf_consume(state->incoming_packet, 4 + 1)) != 0 ||\n\t ((r = sshbuf_consume_end(state->incoming_packet, padlen)) != 0))\n\t\tgoto out;\n\n\tDBG(debug(\"input: len before de-compress %zd\",\n\t sshbuf_len(state->incoming_packet)));\n\tif (comp && comp->enabled) {\n\t\tsshbuf_reset(state->compression_buffer);\n\t\tif ((r = uncompress_buffer(ssh, state->incoming_packet,\n\t\t state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t\tsshbuf_reset(state->incoming_packet);\n\t\tif ((r = sshbuf_putb(state->incoming_packet,\n\t\t state->compression_buffer)) != 0)\n\t\t\tgoto out;\n\t\tDBG(debug(\"input: len after de-compress %zd\",\n\t\t sshbuf_len(state->incoming_packet)));\n\t}\n\t/*\n\t * get packet type, implies consume.\n\t * return length of payload (without type field)\n\t */\n\tif ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)\n\t\tgoto out;\n\tif (ssh_packet_log_type(*typep))\n\t\tdebug3(\"receive packet: type %u\", *typep);\n\tif (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) {\n\t\tif ((r = sshpkt_disconnect(ssh,\n\t\t \"Invalid ssh2 packet type: %d\", *typep)) != 0 ||\n\t\t (r = ssh_packet_write_wait(ssh)) != 0)\n\t\t\treturn r;\n\t\treturn SSH_ERR_PROTOCOL_ERROR;\n\t}\n\tif (state->hook_in != NULL &&\n\t (r = state->hook_in(ssh, state->incoming_packet, typep,\n\t state->hook_in_ctx)) != 0)\n\t\treturn r;\n\tif (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side)\n\t\tr = ssh_packet_enable_delayed_compress(ssh);\n\telse\n\t\tr = 0;\n#ifdef PACKET_DEBUG\n\tfprintf(stderr, \"read/plain[%d]:\\r\\n\", *typep);\n\tsshbuf_dump(state->incoming_packet, stderr);\n#endif\n\t/* reset for next packet */\n\tstate->packlen = 0;\n\n\t/* do we need to rekey? */\n\tif (ssh_packet_need_rekeying(ssh, 0)) {\n\t\tdebug3(\"%s: rekex triggered\", __func__);\n\t\tif ((r = kex_start_rekex(ssh)) != 0)\n\t\t\treturn r;\n\t}\n out:\n\treturn r;\n}\n\nint\nssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)\n{\n\tstruct session_state *state = ssh->state;\n\tu_int reason, seqnr;\n\tint r;\n\tu_char *msg;\n\n\tfor (;;) {\n\t\tmsg = NULL;\n\t\tif (compat20) {\n\t\t\tr = ssh_packet_read_poll2(ssh, typep, seqnr_p);\n\t\t\tif (r != 0)\n\t\t\t\treturn r;\n\t\t\tif (*typep) {\n\t\t\t\tstate->keep_alive_timeouts = 0;\n\t\t\t\tDBG(debug(\"received packet type %d\", *typep));\n\t\t\t}\n\t\t\tswitch (*typep) {\n\t\t\tcase SSH2_MSG_IGNORE:\n\t\t\t\tdebug3(\"Received SSH2_MSG_IGNORE\");\n\t\t\t\tbreak;\n\t\t\tcase SSH2_MSG_DEBUG:\n\t\t\t\tif ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||\n\t\t\t\t (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||\n\t\t\t\t (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {\n\t\t\t\t\tfree(msg);\n\t\t\t\t\treturn r;\n\t\t\t\t}\n\t\t\t\tdebug(\"Remote: %.900s\", msg);\n\t\t\t\tfree(msg);\n\t\t\t\tbreak;\n\t\t\tcase SSH2_MSG_DISCONNECT:\n\t\t\t\tif ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||\n\t\t\t\t (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)\n\t\t\t\t\treturn r;\n\t\t\t\t/* Ignore normal client exit notifications */\n\t\t\t\tdo_log2(ssh->state->server_side &&\n\t\t\t\t reason == SSH2_DISCONNECT_BY_APPLICATION ?\n\t\t\t\t SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,\n\t\t\t\t \"Received disconnect from %s port %d:\"\n\t\t\t\t \"%u: %.400s\", ssh_remote_ipaddr(ssh),\n\t\t\t\t ssh_remote_port(ssh), reason, msg);\n\t\t\t\tfree(msg);\n\t\t\t\treturn SSH_ERR_DISCONNECTED;\n\t\t\tcase SSH2_MSG_UNIMPLEMENTED:\n\t\t\t\tif ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)\n\t\t\t\t\treturn r;\n\t\t\t\tdebug(\"Received SSH2_MSG_UNIMPLEMENTED for %u\",\n\t\t\t\t seqnr);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} else {\n\t\t\tr = ssh_packet_read_poll1(ssh, typep);\n\t\t\tswitch (*typep) {\n\t\t\tcase SSH_MSG_NONE:\n\t\t\t\treturn SSH_MSG_NONE;\n\t\t\tcase SSH_MSG_IGNORE:\n\t\t\t\tbreak;\n\t\t\tcase SSH_MSG_DEBUG:\n\t\t\t\tif ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)\n\t\t\t\t\treturn r;\n\t\t\t\tdebug(\"Remote: %.900s\", msg);\n\t\t\t\tfree(msg);\n\t\t\t\tbreak;\n\t\t\tcase SSH_MSG_DISCONNECT:\n\t\t\t\tif ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)\n\t\t\t\t\treturn r;\n\t\t\t\terror(\"Received disconnect from %s port %d: \"\n\t\t\t\t \"%.400s\", ssh_remote_ipaddr(ssh),\n\t\t\t\t ssh_remote_port(ssh), msg);\n\t\t\t\tfree(msg);\n\t\t\t\treturn SSH_ERR_DISCONNECTED;\n\t\t\tdefault:\n\t\t\t\tDBG(debug(\"received packet type %d\", *typep));\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*\n * Buffers the given amount of input characters. This is intended to be used\n * together with packet_read_poll.\n */\n\nint\nssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len)\n{\n\tstruct session_state *state = ssh->state;\n\tint r;\n\n\tif (state->packet_discard) {\n\t\tstate->keep_alive_timeouts = 0; /* ?? */\n\t\tif (len >= state->packet_discard) {\n\t\t\tif ((r = ssh_packet_stop_discard(ssh)) != 0)\n\t\t\t\treturn r;\n\t\t}\n\t\tstate->packet_discard -= len;\n\t\treturn 0;\n\t}\n\tif ((r = sshbuf_put(ssh->state->input, buf, len)) != 0)\n\t\treturn r;\n\n\treturn 0;\n}\n\nint\nssh_packet_remaining(struct ssh *ssh)\n{\n\treturn sshbuf_len(ssh->state->incoming_packet);\n}\n\n/*\n * Sends a diagnostic message from the server to the client. This message\n * can be sent at any time (but not while constructing another message). The\n * message is printed immediately, but only if the client is being executed\n * in verbose mode. These messages are primarily intended to ease debugging\n * authentication problems. The length of the formatted message must not\n * exceed 1024 bytes. This will automatically call ssh_packet_write_wait.\n */\nvoid\nssh_packet_send_debug(struct ssh *ssh, const char *fmt,...)\n{\n\tchar buf[1024];\n\tva_list args;\n\tint r;\n\n\tif (compat20 && (ssh->compat & SSH_BUG_DEBUG))\n\t\treturn;\n\n\tva_start(args, fmt);\n\tvsnprintf(buf, sizeof(buf), fmt, args);\n\tva_end(args);\n\n\tif (compat20) {\n\t\tif ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||\n\t\t (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */\n\t\t (r = sshpkt_put_cstring(ssh, buf)) != 0 ||\n\t\t (r = sshpkt_put_cstring(ssh, \"\")) != 0 ||\n\t\t (r = sshpkt_send(ssh)) != 0)\n\t\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\t} else {\n\t\tif ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 ||\n\t\t (r = sshpkt_put_cstring(ssh, buf)) != 0 ||\n\t\t (r = sshpkt_send(ssh)) != 0)\n\t\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\t}\n\tif ((r = ssh_packet_write_wait(ssh)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nstatic void\nfmt_connection_id(struct ssh *ssh, char *s, size_t l)\n{\n\tsnprintf(s, l, \"%.200s%s%s port %d\",\n\t ssh->log_preamble ? ssh->log_preamble : \"\",\n\t ssh->log_preamble ? \" \" : \"\",\n\t ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));\n}\n\n/*\n * Pretty-print connection-terminating errors and exit.\n */\nvoid\nsshpkt_fatal(struct ssh *ssh, const char *tag, int r)\n{\n\tchar remote_id[512];\n\n\tfmt_connection_id(ssh, remote_id, sizeof(remote_id));\n\n\tswitch (r) {\n\tcase SSH_ERR_CONN_CLOSED:\n\t\tlogdie(\"Connection closed by %s\", remote_id);\n\tcase SSH_ERR_CONN_TIMEOUT:\n\t\tlogdie(\"Connection %s %s timed out\",\n\t\t ssh->state->server_side ? \"from\" : \"to\", remote_id);\n\tcase SSH_ERR_DISCONNECTED:\n\t\tlogdie(\"Disconnected from %s\", remote_id);\n\tcase SSH_ERR_SYSTEM_ERROR:\n\t\tif (errno == ECONNRESET)\n\t\t\tlogdie(\"Connection reset by %s\", remote_id);\n\t\t/* FALLTHROUGH */\n\tcase SSH_ERR_NO_CIPHER_ALG_MATCH:\n\tcase SSH_ERR_NO_MAC_ALG_MATCH:\n\tcase SSH_ERR_NO_COMPRESS_ALG_MATCH:\n\tcase SSH_ERR_NO_KEX_ALG_MATCH:\n\tcase SSH_ERR_NO_HOSTKEY_ALG_MATCH:\n\t\tif (ssh && ssh->kex && ssh->kex->failed_choice) {\n\t\t\tlogdie(\"Unable to negotiate with %s: %s. \"\n\t\t\t \"Their offer: %s\", remote_id, ssh_err(r),\n\t\t\t ssh->kex->failed_choice);\n\t\t}\n\t\t/* FALLTHROUGH */\n\tdefault:\n\t\tlogdie(\"%s%sConnection %s %s: %s\",\n\t\t tag != NULL ? tag : \"\", tag != NULL ? \": \" : \"\",\n\t\t ssh->state->server_side ? \"from\" : \"to\",\n\t\t remote_id, ssh_err(r));\n\t}\n}\n\n/*\n * Logs the error plus constructs and sends a disconnect packet, closes the\n * connection, and exits. This function never returns. The error message\n * should not contain a newline. The length of the formatted message must\n * not exceed 1024 bytes.\n */\nvoid\nssh_packet_disconnect(struct ssh *ssh, const char *fmt,...)\n{\n\tchar buf[1024], remote_id[512];\n\tva_list args;\n\tstatic int disconnecting = 0;\n\tint r;\n\n\tif (disconnecting)\t/* Guard against recursive invocations. */\n\t\tfatal(\"packet_disconnect called recursively.\");\n\tdisconnecting = 1;\n\n\t/*\n\t * Format the message. Note that the caller must make sure the\n\t * message is of limited size.\n\t */\n\tfmt_connection_id(ssh, remote_id, sizeof(remote_id));\n\tva_start(args, fmt);\n\tvsnprintf(buf, sizeof(buf), fmt, args);\n\tva_end(args);\n\n\t/* Display the error locally */\n\tlogit(\"Disconnecting %s: %.100s\", remote_id, buf);\n\n\t/*\n\t * Send the disconnect message to the other side, and wait\n\t * for it to get sent.\n\t */\n\tif ((r = sshpkt_disconnect(ssh, \"%s\", buf)) != 0)\n\t\tsshpkt_fatal(ssh, __func__, r);\n\n\tif ((r = ssh_packet_write_wait(ssh)) != 0)\n\t\tsshpkt_fatal(ssh, __func__, r);\n\n\t/* Close the connection. */\n\tssh_packet_close(ssh);\n\tcleanup_exit(255);\n}\n\n/*\n * Checks if there is any buffered output, and tries to write some of\n * the output.\n */\nint\nssh_packet_write_poll(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tint len = sshbuf_len(state->output);\n\tint r;\n\n\tif (len > 0) {\n\t\tlen = write(state->connection_out,\n\t\t sshbuf_ptr(state->output), len);\n\t\tif (len == -1) {\n\t\t\tif (errno == EINTR || errno == EAGAIN ||\n\t\t\t errno == EWOULDBLOCK)\n\t\t\t\treturn 0;\n\t\t\treturn SSH_ERR_SYSTEM_ERROR;\n\t\t}\n\t\tif (len == 0)\n\t\t\treturn SSH_ERR_CONN_CLOSED;\n\t\tif ((r = sshbuf_consume(state->output, len)) != 0)\n\t\t\treturn r;\n\t}\n\treturn 0;\n}\n\n/*\n * Calls packet_write_poll repeatedly until all pending output data has been\n * written.\n */\nint\nssh_packet_write_wait(struct ssh *ssh)\n{\n\tfd_set *setp;\n\tint ret, r, ms_remain = 0;\n\tstruct timeval start, timeout, *timeoutp = NULL;\n\tstruct session_state *state = ssh->state;\n\n\tsetp = calloc(howmany(state->connection_out + 1,\n\t NFDBITS), sizeof(fd_mask));\n\tif (setp == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = ssh_packet_write_poll(ssh)) != 0) {\n\t\tfree(setp);\n\t\treturn r;\n\t}\n\twhile (ssh_packet_have_data_to_write(ssh)) {\n\t\tmemset(setp, 0, howmany(state->connection_out + 1,\n\t\t NFDBITS) * sizeof(fd_mask));\n\t\tFD_SET(state->connection_out, setp);\n\n\t\tif (state->packet_timeout_ms > 0) {\n\t\t\tms_remain = state->packet_timeout_ms;\n\t\t\ttimeoutp = &timeout;\n\t\t}\n\t\tfor (;;) {\n\t\t\tif (state->packet_timeout_ms != -1) {\n\t\t\t\tms_to_timeval(&timeout, ms_remain);\n\t\t\t\tgettimeofday(&start, NULL);\n\t\t\t}\n\t\t\tif ((ret = select(state->connection_out + 1,\n\t\t\t NULL, setp, NULL, timeoutp)) >= 0)\n\t\t\t\tbreak;\n\t\t\tif (errno != EAGAIN && errno != EINTR &&\n\t\t\t errno != EWOULDBLOCK)\n\t\t\t\tbreak;\n\t\t\tif (state->packet_timeout_ms == -1)\n\t\t\t\tcontinue;\n\t\t\tms_subtract_diff(&start, &ms_remain);\n\t\t\tif (ms_remain <= 0) {\n\t\t\t\tret = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (ret == 0) {\n\t\t\tfree(setp);\n\t\t\treturn SSH_ERR_CONN_TIMEOUT;\n\t\t}\n\t\tif ((r = ssh_packet_write_poll(ssh)) != 0) {\n\t\t\tfree(setp);\n\t\t\treturn r;\n\t\t}\n\t}\n\tfree(setp);\n\treturn 0;\n}\n\n/* Returns true if there is buffered data to write to the connection. */\n\nint\nssh_packet_have_data_to_write(struct ssh *ssh)\n{\n\treturn sshbuf_len(ssh->state->output) != 0;\n}\n\n/* Returns true if there is not too much data to write to the connection. */\n\nint\nssh_packet_not_very_much_data_to_write(struct ssh *ssh)\n{\n\tif (ssh->state->interactive_mode)\n\t\treturn sshbuf_len(ssh->state->output) < 16384;\n\telse\n\t\treturn sshbuf_len(ssh->state->output) < 128 * 1024;\n}\n\nvoid\nssh_packet_set_tos(struct ssh *ssh, int tos)\n{\n#ifndef IP_TOS_IS_BROKEN\n\tif (!ssh_packet_connection_is_on_socket(ssh))\n\t\treturn;\n\tswitch (ssh_packet_connection_af(ssh)) {\n# ifdef IP_TOS\n\tcase AF_INET:\n\t\tdebug3(\"%s: set IP_TOS 0x%02x\", __func__, tos);\n\t\tif (setsockopt(ssh->state->connection_in,\n\t\t IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)\n\t\t\terror(\"setsockopt IP_TOS %d: %.100s:\",\n\t\t\t tos, strerror(errno));\n\t\tbreak;\n# endif /* IP_TOS */\n# ifdef IPV6_TCLASS\n\tcase AF_INET6:\n\t\tdebug3(\"%s: set IPV6_TCLASS 0x%02x\", __func__, tos);\n\t\tif (setsockopt(ssh->state->connection_in,\n\t\t IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0)\n\t\t\terror(\"setsockopt IPV6_TCLASS %d: %.100s:\",\n\t\t\t tos, strerror(errno));\n\t\tbreak;\n# endif /* IPV6_TCLASS */\n\t}\n#endif /* IP_TOS_IS_BROKEN */\n}\n\n/* Informs that the current session is interactive. Sets IP flags for that. */\n\nvoid\nssh_packet_set_interactive(struct ssh *ssh, int interactive, int qos_interactive, int qos_bulk)\n{\n\tstruct session_state *state = ssh->state;\n\n\tif (state->set_interactive_called)\n\t\treturn;\n\tstate->set_interactive_called = 1;\n\n\t/* Record that we are in interactive mode. */\n\tstate->interactive_mode = interactive;\n\n\t/* Only set socket options if using a socket. */\n\tif (!ssh_packet_connection_is_on_socket(ssh))\n\t\treturn;\n\tset_nodelay(state->connection_in);\n\tssh_packet_set_tos(ssh, interactive ? qos_interactive :\n\t qos_bulk);\n}\n\n/* Returns true if the current connection is interactive. */\n\nint\nssh_packet_is_interactive(struct ssh *ssh)\n{\n\treturn ssh->state->interactive_mode;\n}\n\nint\nssh_packet_set_maxsize(struct ssh *ssh, u_int s)\n{\n\tstruct session_state *state = ssh->state;\n\n\tif (state->set_maxsize_called) {\n\t\tlogit(\"packet_set_maxsize: called twice: old %d new %d\",\n\t\t state->max_packet_size, s);\n\t\treturn -1;\n\t}\n\tif (s < 4 * 1024 || s > 1024 * 1024) {\n\t\tlogit(\"packet_set_maxsize: bad size %d\", s);\n\t\treturn -1;\n\t}\n\tstate->set_maxsize_called = 1;\n\tdebug(\"packet_set_maxsize: setting to %d\", s);\n\tstate->max_packet_size = s;\n\treturn s;\n}\n\nint\nssh_packet_inc_alive_timeouts(struct ssh *ssh)\n{\n\treturn ++ssh->state->keep_alive_timeouts;\n}\n\nvoid\nssh_packet_set_alive_timeouts(struct ssh *ssh, int ka)\n{\n\tssh->state->keep_alive_timeouts = ka;\n}\n\nu_int\nssh_packet_get_maxsize(struct ssh *ssh)\n{\n\treturn ssh->state->max_packet_size;\n}\n\n/*\n * 9.2. Ignored Data Message\n *\n * byte SSH_MSG_IGNORE\n * string data\n *\n * All implementations MUST understand (and ignore) this message at any\n * time (after receiving the protocol version). No implementation is\n * required to send them. This message can be used as an additional\n * protection measure against advanced traffic analysis techniques.\n */\nvoid\nssh_packet_send_ignore(struct ssh *ssh, int nbytes)\n{\n\tu_int32_t rnd = 0;\n\tint r, i;\n\n\tif ((r = sshpkt_start(ssh, compat20 ?\n\t SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 ||\n\t (r = sshpkt_put_u32(ssh, nbytes)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\tfor (i = 0; i < nbytes; i++) {\n\t\tif (i % 4 == 0)\n\t\t\trnd = arc4random();\n\t\tif ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0)\n\t\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\t\trnd >>= 8;\n\t}\n}\n\nvoid\nssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds)\n{\n\tdebug3(\"rekey after %llu bytes, %u seconds\", (unsigned long long)bytes,\n\t (unsigned int)seconds);\n\tssh->state->rekey_limit = bytes;\n\tssh->state->rekey_interval = seconds;\n}\n\ntime_t\nssh_packet_get_rekey_timeout(struct ssh *ssh)\n{\n\ttime_t seconds;\n\n\tseconds = ssh->state->rekey_time + ssh->state->rekey_interval -\n\t monotime();\n\treturn (seconds <= 0 ? 1 : seconds);\n}\n\nvoid\nssh_packet_set_server(struct ssh *ssh)\n{\n\tssh->state->server_side = 1;\n}\n\nvoid\nssh_packet_set_authenticated(struct ssh *ssh)\n{\n\tssh->state->after_authentication = 1;\n}\n\nvoid *\nssh_packet_get_input(struct ssh *ssh)\n{\n\treturn (void *)ssh->state->input;\n}\n\nvoid *\nssh_packet_get_output(struct ssh *ssh)\n{\n\treturn (void *)ssh->state->output;\n}\n\n/* Reset after_authentication and reset compression in post-auth privsep */\nstatic int\nssh_packet_set_postauth(struct ssh *ssh)\n{\n\tint r;\n\n\tdebug(\"%s: called\", __func__);\n\t/* This was set in net child, but is not visible in user child */\n\tssh->state->after_authentication = 1;\n\tssh->state->rekeying = 0;\n\tif ((r = ssh_packet_enable_delayed_compress(ssh)) != 0)\n\t\treturn r;\n\treturn 0;\n}\n\n/* Packet state (de-)serialization for privsep */\n\n/* turn kex into a blob for packet state serialization */\nstatic int\nkex_to_blob(struct sshbuf *m, struct kex *kex)\n{\n\tint r;\n\n\tif ((r = sshbuf_put_string(m, kex->session_id,\n\t kex->session_id_len)) != 0 ||\n\t (r = sshbuf_put_u32(m, kex->we_need)) != 0 ||\n\t (r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 ||\n\t (r = sshbuf_put_u32(m, kex->kex_type)) != 0 ||\n\t (r = sshbuf_put_stringb(m, kex->my)) != 0 ||\n\t (r = sshbuf_put_stringb(m, kex->peer)) != 0 ||\n\t (r = sshbuf_put_u32(m, kex->flags)) != 0 ||\n\t (r = sshbuf_put_cstring(m, kex->client_version_string)) != 0 ||\n\t (r = sshbuf_put_cstring(m, kex->server_version_string)) != 0)\n\t\treturn r;\n\treturn 0;\n}\n\n/* turn key exchange results into a blob for packet state serialization */\nstatic int\nnewkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode)\n{\n\tstruct sshbuf *b;\n\tstruct sshcipher_ctx *cc;\n\tstruct sshcomp *comp;\n\tstruct sshenc *enc;\n\tstruct sshmac *mac;\n\tstruct newkeys *newkey;\n\tint r;\n\n\tif ((newkey = ssh->state->newkeys[mode]) == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tenc = &newkey->enc;\n\tmac = &newkey->mac;\n\tcomp = &newkey->comp;\n\tcc = (mode == MODE_OUT) ? ssh->state->send_context :\n\t ssh->state->receive_context;\n\tif ((r = cipher_get_keyiv(cc, enc->iv, enc->iv_len)) != 0)\n\t\treturn r;\n\tif ((b = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\t/* The cipher struct is constant and shared, you export pointer */\n\tif ((r = sshbuf_put_cstring(b, enc->name)) != 0 ||\n\t (r = sshbuf_put(b, &enc->cipher, sizeof(enc->cipher))) != 0 ||\n\t (r = sshbuf_put_u32(b, enc->enabled)) != 0 ||\n\t (r = sshbuf_put_u32(b, enc->block_size)) != 0 ||\n\t (r = sshbuf_put_string(b, enc->key, enc->key_len)) != 0 ||\n\t (r = sshbuf_put_string(b, enc->iv, enc->iv_len)) != 0)\n\t\tgoto out;\n\tif (cipher_authlen(enc->cipher) == 0) {\n\t\tif ((r = sshbuf_put_cstring(b, mac->name)) != 0 ||\n\t\t (r = sshbuf_put_u32(b, mac->enabled)) != 0 ||\n\t\t (r = sshbuf_put_string(b, mac->key, mac->key_len)) != 0)\n\t\t\tgoto out;\n\t}\n\tif ((r = sshbuf_put_u32(b, comp->type)) != 0 ||\n\t (r = sshbuf_put_cstring(b, comp->name)) != 0)\n\t\tgoto out;\n\tr = sshbuf_put_stringb(m, b);\n out:\n\tsshbuf_free(b);\n\treturn r;\n}\n\n/* serialize packet state into a blob */\nint\nssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)\n{\n\tstruct session_state *state = ssh->state;\n\tu_char *p;\n\tsize_t slen, rlen;\n\tint r, ssh1cipher;\n\n\tif (!compat20) {\n\t\tssh1cipher = cipher_ctx_get_number(state->receive_context);\n\t\tslen = cipher_get_keyiv_len(state->send_context);\n\t\trlen = cipher_get_keyiv_len(state->receive_context);\n\t\tif ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, ssh1cipher)) != 0 ||\n\t\t (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, slen)) != 0 ||\n\t\t (r = sshbuf_reserve(m, slen, &p)) != 0 ||\n\t\t (r = cipher_get_keyiv(state->send_context, p, slen)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, rlen)) != 0 ||\n\t\t (r = sshbuf_reserve(m, rlen, &p)) != 0 ||\n\t\t (r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0)\n\t\t\treturn r;\n\t} else {\n\t\tif ((r = kex_to_blob(m, ssh->kex)) != 0 ||\n\t\t (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||\n\t\t (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||\n\t\t (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||\n\t\t (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||\n\t\t (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||\n\t\t (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||\n\t\t (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||\n\t\t (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0)\n\t\t\treturn r;\n\t}\n\n\tslen = cipher_get_keycontext(state->send_context, NULL);\n\trlen = cipher_get_keycontext(state->receive_context, NULL);\n\tif ((r = sshbuf_put_u32(m, slen)) != 0 ||\n\t (r = sshbuf_reserve(m, slen, &p)) != 0)\n\t\treturn r;\n\tif (cipher_get_keycontext(state->send_context, p) != (int)slen)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tif ((r = sshbuf_put_u32(m, rlen)) != 0 ||\n\t (r = sshbuf_reserve(m, rlen, &p)) != 0)\n\t\treturn r;\n\tif (cipher_get_keycontext(state->receive_context, p) != (int)rlen)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tif ((r = sshbuf_put_stringb(m, state->input)) != 0 ||\n\t (r = sshbuf_put_stringb(m, state->output)) != 0)\n\t\treturn r;\n\n\treturn 0;\n}\n\n/* restore key exchange results from blob for packet state de-serialization */\nstatic int\nnewkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode)\n{\n\tstruct sshbuf *b = NULL;\n\tstruct sshcomp *comp;\n\tstruct sshenc *enc;\n\tstruct sshmac *mac;\n\tstruct newkeys *newkey = NULL;\n\tsize_t keylen, ivlen, maclen;\n\tint r;\n\n\tif ((newkey = calloc(1, sizeof(*newkey))) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_froms(m, &b)) != 0)\n\t\tgoto out;\n#ifdef DEBUG_PK\n\tsshbuf_dump(b, stderr);\n#endif\n\tenc = &newkey->enc;\n\tmac = &newkey->mac;\n\tcomp = &newkey->comp;\n\n\tif ((r = sshbuf_get_cstring(b, &enc->name, NULL)) != 0 ||\n\t (r = sshbuf_get(b, &enc->cipher, sizeof(enc->cipher))) != 0 ||\n\t (r = sshbuf_get_u32(b, (u_int *)&enc->enabled)) != 0 ||\n\t (r = sshbuf_get_u32(b, &enc->block_size)) != 0 ||\n\t (r = sshbuf_get_string(b, &enc->key, &keylen)) != 0 ||\n\t (r = sshbuf_get_string(b, &enc->iv, &ivlen)) != 0)\n\t\tgoto out;\n\tif (cipher_authlen(enc->cipher) == 0) {\n\t\tif ((r = sshbuf_get_cstring(b, &mac->name, NULL)) != 0)\n\t\t\tgoto out;\n\t\tif ((r = mac_setup(mac, mac->name)) != 0)\n\t\t\tgoto out;\n\t\tif ((r = sshbuf_get_u32(b, (u_int *)&mac->enabled)) != 0 ||\n\t\t (r = sshbuf_get_string(b, &mac->key, &maclen)) != 0)\n\t\t\tgoto out;\n\t\tif (maclen > mac->key_len) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tmac->key_len = maclen;\n\t}\n\tif ((r = sshbuf_get_u32(b, &comp->type)) != 0 ||\n\t (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0)\n\t\tgoto out;\n\tif (enc->name == NULL ||\n\t cipher_by_name(enc->name) != enc->cipher) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tif (sshbuf_len(b) != 0) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tenc->key_len = keylen;\n\tenc->iv_len = ivlen;\n\tssh->kex->newkeys[mode] = newkey;\n\tnewkey = NULL;\n\tr = 0;\n out:\n\tfree(newkey);\n\tsshbuf_free(b);\n\treturn r;\n}\n\n/* restore kex from blob for packet state de-serialization */\nstatic int\nkex_from_blob(struct sshbuf *m, struct kex **kexp)\n{\n\tstruct kex *kex;\n\tint r;\n\n\tif ((kex = calloc(1, sizeof(struct kex))) == NULL ||\n\t (kex->my = sshbuf_new()) == NULL ||\n\t (kex->peer = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 ||\n\t (r = sshbuf_get_u32(m, &kex->we_need)) != 0 ||\n\t (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 ||\n\t (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 ||\n\t (r = sshbuf_get_stringb(m, kex->my)) != 0 ||\n\t (r = sshbuf_get_stringb(m, kex->peer)) != 0 ||\n\t (r = sshbuf_get_u32(m, &kex->flags)) != 0 ||\n\t (r = sshbuf_get_cstring(m, &kex->client_version_string, NULL)) != 0 ||\n\t (r = sshbuf_get_cstring(m, &kex->server_version_string, NULL)) != 0)\n\t\tgoto out;\n\tkex->server = 1;\n\tkex->done = 1;\n\tr = 0;\n out:\n\tif (r != 0 || kexp == NULL) {\n\t\tif (kex != NULL) {\n\t\t\tsshbuf_free(kex->my);\n\t\t\tsshbuf_free(kex->peer);\n\t\t\tfree(kex);\n\t\t}\n\t\tif (kexp != NULL)\n\t\t\t*kexp = NULL;\n\t} else {\n\t\t*kexp = kex;\n\t}\n\treturn r;\n}\n\n/*\n * Restore packet state from content of blob 'm' (de-serialization).\n * Note that 'm' will be partially consumed on parsing or any other errors.\n */\nint\nssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)\n{\n\tstruct session_state *state = ssh->state;\n\tconst u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output;\n\tsize_t ssh1keylen, rlen, slen, ilen, olen;\n\tint r;\n\tu_int ssh1cipher = 0;\n\n\tif (!compat20) {\n\t\tif ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 ||\n\t\t (r = sshbuf_get_u32(m, &ssh1cipher)) != 0 ||\n\t\t (r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 ||\n\t\t (r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 ||\n\t\t (r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0)\n\t\t\treturn r;\n\t\tif (ssh1cipher > INT_MAX)\n\t\t\treturn SSH_ERR_KEY_UNKNOWN_CIPHER;\n\t\tssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen,\n\t\t (int)ssh1cipher);\n\t\tif (cipher_get_keyiv_len(state->send_context) != (int)slen ||\n\t\t cipher_get_keyiv_len(state->receive_context) != (int)rlen)\n\t\t\treturn SSH_ERR_INVALID_FORMAT;\n\t\tif ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 ||\n\t\t (r = cipher_set_keyiv(state->receive_context, ivin)) != 0)\n\t\t\treturn r;\n\t} else {\n\t\tif ((r = kex_from_blob(m, &ssh->kex)) != 0 ||\n\t\t (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||\n\t\t (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||\n\t\t (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||\n\t\t (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||\n\t\t (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||\n\t\t (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||\n\t\t (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||\n\t\t (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||\n\t\t (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||\n\t\t (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||\n\t\t (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||\n\t\t (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)\n\t\t\treturn r;\n\t\t/*\n\t\t * We set the time here so that in post-auth privsep slave we\n\t\t * count from the completion of the authentication.\n\t\t */\n\t\tstate->rekey_time = monotime();\n\t\t/* XXX ssh_set_newkeys overrides p_read.packets? XXX */\n\t\tif ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||\n\t\t (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)\n\t\t\treturn r;\n\t}\n\tif ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 ||\n\t (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0)\n\t\treturn r;\n\tif (cipher_get_keycontext(state->send_context, NULL) != (int)slen ||\n\t cipher_get_keycontext(state->receive_context, NULL) != (int)rlen)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\tcipher_set_keycontext(state->send_context, keyout);\n\tcipher_set_keycontext(state->receive_context, keyin);\n\n\tif ((r = ssh_packet_set_postauth(ssh)) != 0)\n\t\treturn r;\n\n\tsshbuf_reset(state->input);\n\tsshbuf_reset(state->output);\n\tif ((r = sshbuf_get_string_direct(m, &input, &ilen)) != 0 ||\n\t (r = sshbuf_get_string_direct(m, &output, &olen)) != 0 ||\n\t (r = sshbuf_put(state->input, input, ilen)) != 0 ||\n\t (r = sshbuf_put(state->output, output, olen)) != 0)\n\t\treturn r;\n\n\tif (sshbuf_len(m))\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\tdebug3(\"%s: done\", __func__);\n\treturn 0;\n}\n\n/* NEW API */\n\n/* put data to the outgoing packet */\n\nint\nsshpkt_put(struct ssh *ssh, const void *v, size_t len)\n{\n\treturn sshbuf_put(ssh->state->outgoing_packet, v, len);\n}\n\nint\nsshpkt_putb(struct ssh *ssh, const struct sshbuf *b)\n{\n\treturn sshbuf_putb(ssh->state->outgoing_packet, b);\n}\n\nint\nsshpkt_put_u8(struct ssh *ssh, u_char val)\n{\n\treturn sshbuf_put_u8(ssh->state->outgoing_packet, val);\n}\n\nint\nsshpkt_put_u32(struct ssh *ssh, u_int32_t val)\n{\n\treturn sshbuf_put_u32(ssh->state->outgoing_packet, val);\n}\n\nint\nsshpkt_put_u64(struct ssh *ssh, u_int64_t val)\n{\n\treturn sshbuf_put_u64(ssh->state->outgoing_packet, val);\n}\n\nint\nsshpkt_put_string(struct ssh *ssh, const void *v, size_t len)\n{\n\treturn sshbuf_put_string(ssh->state->outgoing_packet, v, len);\n}\n\nint\nsshpkt_put_cstring(struct ssh *ssh, const void *v)\n{\n\treturn sshbuf_put_cstring(ssh->state->outgoing_packet, v);\n}\n\nint\nsshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v)\n{\n\treturn sshbuf_put_stringb(ssh->state->outgoing_packet, v);\n}\n\n#ifdef WITH_OPENSSL\n#ifdef OPENSSL_HAS_ECC\nint\nsshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g)\n{\n\treturn sshbuf_put_ec(ssh->state->outgoing_packet, v, g);\n}\n#endif /* OPENSSL_HAS_ECC */\n\n#ifdef WITH_SSH1\nint\nsshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v)\n{\n\treturn sshbuf_put_bignum1(ssh->state->outgoing_packet, v);\n}\n#endif /* WITH_SSH1 */\n\nint\nsshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v)\n{\n\treturn sshbuf_put_bignum2(ssh->state->outgoing_packet, v);\n}\n#endif /* WITH_OPENSSL */\n\n/* fetch data from the incoming packet */\n\nint\nsshpkt_get(struct ssh *ssh, void *valp, size_t len)\n{\n\treturn sshbuf_get(ssh->state->incoming_packet, valp, len);\n}\n\nint\nsshpkt_get_u8(struct ssh *ssh, u_char *valp)\n{\n\treturn sshbuf_get_u8(ssh->state->incoming_packet, valp);\n}\n\nint\nsshpkt_get_u32(struct ssh *ssh, u_int32_t *valp)\n{\n\treturn sshbuf_get_u32(ssh->state->incoming_packet, valp);\n}\n\nint\nsshpkt_get_u64(struct ssh *ssh, u_int64_t *valp)\n{\n\treturn sshbuf_get_u64(ssh->state->incoming_packet, valp);\n}\n\nint\nsshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp)\n{\n\treturn sshbuf_get_string(ssh->state->incoming_packet, valp, lenp);\n}\n\nint\nsshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp)\n{\n\treturn sshbuf_get_string_direct(ssh->state->incoming_packet, valp, lenp);\n}\n\nint\nsshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp)\n{\n\treturn sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp);\n}\n\n#ifdef WITH_OPENSSL\n#ifdef OPENSSL_HAS_ECC\nint\nsshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g)\n{\n\treturn sshbuf_get_ec(ssh->state->incoming_packet, v, g);\n}\n#endif /* OPENSSL_HAS_ECC */\n\n#ifdef WITH_SSH1\nint\nsshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v)\n{\n\treturn sshbuf_get_bignum1(ssh->state->incoming_packet, v);\n}\n#endif /* WITH_SSH1 */\n\nint\nsshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v)\n{\n\treturn sshbuf_get_bignum2(ssh->state->incoming_packet, v);\n}\n#endif /* WITH_OPENSSL */\n\nint\nsshpkt_get_end(struct ssh *ssh)\n{\n\tif (sshbuf_len(ssh->state->incoming_packet) > 0)\n\t\treturn SSH_ERR_UNEXPECTED_TRAILING_DATA;\n\treturn 0;\n}\n\nconst u_char *\nsshpkt_ptr(struct ssh *ssh, size_t *lenp)\n{\n\tif (lenp != NULL)\n\t\t*lenp = sshbuf_len(ssh->state->incoming_packet);\n\treturn sshbuf_ptr(ssh->state->incoming_packet);\n}\n\n/* start a new packet */\n\nint\nsshpkt_start(struct ssh *ssh, u_char type)\n{\n\tu_char buf[9];\n\tint len;\n\n\tDBG(debug(\"packet_start[%d]\", type));\n\tlen = compat20 ? 6 : 9;\n\tmemset(buf, 0, len - 1);\n\tbuf[len - 1] = type;\n\tsshbuf_reset(ssh->state->outgoing_packet);\n\treturn sshbuf_put(ssh->state->outgoing_packet, buf, len);\n}\n\nstatic int\nssh_packet_send_mux(struct ssh *ssh)\n{\n\tstruct session_state *state = ssh->state;\n\tu_char type, *cp;\n\tsize_t len;\n\tint r;\n\n\tif (ssh->kex)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tlen = sshbuf_len(state->outgoing_packet);\n\tif (len < 6)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tcp = sshbuf_mutable_ptr(state->outgoing_packet);\n\ttype = cp[5];\n\tif (ssh_packet_log_type(type))\n\t\tdebug3(\"%s: type %u\", __func__, type);\n\t/* drop everything, but the connection protocol */\n\tif (type >= SSH2_MSG_CONNECTION_MIN &&\n\t type <= SSH2_MSG_CONNECTION_MAX) {\n\t\tPOKE_U32(cp, len - 4);\n\t\tif ((r = sshbuf_putb(state->output,\n\t\t state->outgoing_packet)) != 0)\n\t\t\treturn r;\n\t\t/* sshbuf_dump(state->output, stderr); */\n\t}\n\tsshbuf_reset(state->outgoing_packet);\n\treturn 0;\n}\n\n/* send it */\n\nint\nsshpkt_send(struct ssh *ssh)\n{\n\tif (ssh->state && ssh->state->mux)\n\t\treturn ssh_packet_send_mux(ssh);\n\tif (compat20)\n\t\treturn ssh_packet_send2(ssh);\n\telse\n\t\treturn ssh_packet_send1(ssh);\n}\n\nint\nsshpkt_disconnect(struct ssh *ssh, const char *fmt,...)\n{\n\tchar buf[1024];\n\tva_list args;\n\tint r;\n\n\tva_start(args, fmt);\n\tvsnprintf(buf, sizeof(buf), fmt, args);\n\tva_end(args);\n\n\tif (compat20) {\n\t\tif ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||\n\t\t (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||\n\t\t (r = sshpkt_put_cstring(ssh, buf)) != 0 ||\n\t\t (r = sshpkt_put_cstring(ssh, \"\")) != 0 ||\n\t\t (r = sshpkt_send(ssh)) != 0)\n\t\t\treturn r;\n\t} else {\n\t\tif ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 ||\n\t\t (r = sshpkt_put_cstring(ssh, buf)) != 0 ||\n\t\t (r = sshpkt_send(ssh)) != 0)\n\t\t\treturn r;\n\t}\n\treturn 0;\n}\n\n/* roundup current message to pad bytes */\nint\nsshpkt_add_padding(struct ssh *ssh, u_char pad)\n{\n\tssh->state->extra_pad = pad;\n\treturn 0;\n}\n","/* Written by Markus Friedl. Placed in the public domain. */\n\n#include \"includes.h\"\n\n#include \"ssherr.h\"\n#include \"packet.h\"\n#include \"log.h\"\n\nstruct ssh *active_state, *backup_state;\n\n/* Map old to new API */\n\nvoid\nssh_packet_start(struct ssh *ssh, u_char type)\n{\n\tint r;\n\n\tif ((r = sshpkt_start(ssh, type)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nvoid\nssh_packet_put_char(struct ssh *ssh, int value)\n{\n\tu_char ch = value;\n\tint r;\n\n\tif ((r = sshpkt_put_u8(ssh, ch)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nvoid\nssh_packet_put_int(struct ssh *ssh, u_int value)\n{\n\tint r;\n\n\tif ((r = sshpkt_put_u32(ssh, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nvoid\nssh_packet_put_int64(struct ssh *ssh, u_int64_t value)\n{\n\tint r;\n\n\tif ((r = sshpkt_put_u64(ssh, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nvoid\nssh_packet_put_string(struct ssh *ssh, const void *buf, u_int len)\n{\n\tint r;\n\n\tif ((r = sshpkt_put_string(ssh, buf, len)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nvoid\nssh_packet_put_cstring(struct ssh *ssh, const char *str)\n{\n\tint r;\n\n\tif ((r = sshpkt_put_cstring(ssh, str)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nvoid\nssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len)\n{\n\tint r;\n\n\tif ((r = sshpkt_put(ssh, buf, len)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\n#ifdef WITH_SSH1\nvoid\nssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value)\n{\n\tint r;\n\n\tif ((r = sshpkt_put_bignum1(ssh, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n#endif\n\n#ifdef WITH_OPENSSL\nvoid\nssh_packet_put_bignum2(struct ssh *ssh, BIGNUM * value)\n{\n\tint r;\n\n\tif ((r = sshpkt_put_bignum2(ssh, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\n# ifdef OPENSSL_HAS_ECC\nvoid\nssh_packet_put_ecpoint(struct ssh *ssh, const EC_GROUP *curve,\n const EC_POINT *point)\n{\n\tint r;\n\n\tif ((r = sshpkt_put_ec(ssh, point, curve)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n# endif\n#endif /* WITH_OPENSSL */\n\nvoid\nssh_packet_send(struct ssh *ssh)\n{\n\tint r;\n\n\tif ((r = sshpkt_send(ssh)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nu_int\nssh_packet_get_char(struct ssh *ssh)\n{\n\tu_char ch;\n\tint r;\n\n\tif ((r = sshpkt_get_u8(ssh, &ch)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\treturn ch;\n}\n\nu_int\nssh_packet_get_int(struct ssh *ssh)\n{\n\tu_int val;\n\tint r;\n\n\tif ((r = sshpkt_get_u32(ssh, &val)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\treturn val;\n}\n\nu_int64_t\nssh_packet_get_int64(struct ssh *ssh)\n{\n\tu_int64_t val;\n\tint r;\n\n\tif ((r = sshpkt_get_u64(ssh, &val)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\treturn val;\n}\n\n#ifdef WITH_SSH1\nvoid\nssh_packet_get_bignum(struct ssh *ssh, BIGNUM * value)\n{\n\tint r;\n\n\tif ((r = sshpkt_get_bignum1(ssh, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n#endif\n\n#ifdef WITH_OPENSSL\nvoid\nssh_packet_get_bignum2(struct ssh *ssh, BIGNUM * value)\n{\n\tint r;\n\n\tif ((r = sshpkt_get_bignum2(ssh, value)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\n# ifdef OPENSSL_HAS_ECC\nvoid\nssh_packet_get_ecpoint(struct ssh *ssh, const EC_GROUP *curve, EC_POINT *point)\n{\n\tint r;\n\n\tif ((r = sshpkt_get_ec(ssh, point, curve)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n# endif\n#endif /* WITH_OPENSSL */\n\nvoid *\nssh_packet_get_string(struct ssh *ssh, u_int *length_ptr)\n{\n\tint r;\n\tsize_t len;\n\tu_char *val;\n\n\tif ((r = sshpkt_get_string(ssh, &val, &len)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\tif (length_ptr != NULL)\n\t\t*length_ptr = (u_int)len;\n\treturn val;\n}\n\nconst void *\nssh_packet_get_string_ptr(struct ssh *ssh, u_int *length_ptr)\n{\n\tint r;\n\tsize_t len;\n\tconst u_char *val;\n\n\tif ((r = sshpkt_get_string_direct(ssh, &val, &len)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\tif (length_ptr != NULL)\n\t\t*length_ptr = (u_int)len;\n\treturn val;\n}\n\nchar *\nssh_packet_get_cstring(struct ssh *ssh, u_int *length_ptr)\n{\n\tint r;\n\tsize_t len;\n\tchar *val;\n\n\tif ((r = sshpkt_get_cstring(ssh, &val, &len)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\tif (length_ptr != NULL)\n\t\t*length_ptr = (u_int)len;\n\treturn val;\n}\n\n/* Old API, that had to be reimplemented */\n\nvoid\npacket_set_connection(int fd_in, int fd_out)\n{\n\tactive_state = ssh_packet_set_connection(active_state, fd_in, fd_out);\n\tif (active_state == NULL)\n\t\tfatal(\"%s: ssh_packet_set_connection failed\", __func__);\n}\n\nu_int\npacket_get_char(void)\n{\n\treturn (ssh_packet_get_char(active_state));\n}\n\nu_int\npacket_get_int(void)\n{\n\treturn (ssh_packet_get_int(active_state));\n}\n\nint\npacket_read_seqnr(u_int32_t *seqnr)\n{\n\tu_char type;\n\tint r;\n\n\tif ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0)\n\t\tsshpkt_fatal(active_state, __func__, r);\n\treturn type;\n}\n\nint\npacket_read_poll_seqnr(u_int32_t *seqnr)\n{\n\tu_char type;\n\tint r;\n\n\tif ((r = ssh_packet_read_poll_seqnr(active_state, &type, seqnr)))\n\t\tsshpkt_fatal(active_state, __func__, r);\n\treturn type;\n}\n\nvoid\npacket_close(void)\n{\n\tssh_packet_close(active_state);\n\tactive_state = NULL;\n}\n\nvoid\npacket_process_incoming(const char *buf, u_int len)\n{\n\tint r;\n\n\tif ((r = ssh_packet_process_incoming(active_state, buf, len)) != 0)\n\t\tsshpkt_fatal(active_state, __func__, r);\n}\n\nvoid\npacket_write_wait(void)\n{\n\tint r;\n\n\tif ((r = ssh_packet_write_wait(active_state)) != 0)\n\t\tsshpkt_fatal(active_state, __func__, r);\n}\n\nvoid\npacket_write_poll(void)\n{\n\tint r;\n\n\tif ((r = ssh_packet_write_poll(active_state)) != 0)\n\t\tsshpkt_fatal(active_state, __func__, r);\n}\n\nvoid\npacket_read_expect(int expected_type)\n{\n\tint r;\n\n\tif ((r = ssh_packet_read_expect(active_state, expected_type)) != 0)\n\t\tsshpkt_fatal(active_state, __func__, r);\n}\n\nvoid\npacket_disconnect(const char *fmt, ...)\n{\n\tchar buf[1024];\n\tva_list args;\n\n\tva_start(args, fmt);\n\tvsnprintf(buf, sizeof(buf), fmt, args);\n\tva_end(args);\n\tssh_packet_disconnect(active_state, \"%s\", buf);\n}\n\nvoid\npacket_send_debug(const char *fmt, ...)\n{\n\tchar buf[1024];\n\tva_list args;\n\n\tva_start(args, fmt);\n\tvsnprintf(buf, sizeof(buf), fmt, args);\n\tva_end(args);\n\tssh_packet_send_debug(active_state, \"%s\", buf);\n}\n","/* $OpenBSD: readpass.c,v 1.51 2015/12/11 00:20:04 mmcc Exp $ */\n/*\n * Copyright (c) 2001 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \n#include \n#ifdef HAVE_PATHS_H\n# include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"misc.h\"\n#include \"pathnames.h\"\n#include \"log.h\"\n#include \"ssh.h\"\n#include \"uidswap.h\"\n\nstatic char *\nssh_askpass(char *askpass, const char *msg)\n{\n\tpid_t pid, ret;\n\tsize_t len;\n\tchar *pass;\n\tint p[2], status;\n\tchar buf[1024];\n\tvoid (*osigchld)(int);\n\n\tif (fflush(stdout) != 0)\n\t\terror(\"ssh_askpass: fflush: %s\", strerror(errno));\n\tif (askpass == NULL)\n\t\tfatal(\"internal error: askpass undefined\");\n\tif (pipe(p) < 0) {\n\t\terror(\"ssh_askpass: pipe: %s\", strerror(errno));\n\t\treturn NULL;\n\t}\n\tosigchld = signal(SIGCHLD, SIG_DFL);\n\tif ((pid = fork()) < 0) {\n\t\terror(\"ssh_askpass: fork: %s\", strerror(errno));\n\t\tsignal(SIGCHLD, osigchld);\n\t\treturn NULL;\n\t}\n\tif (pid == 0) {\n\t\tpermanently_drop_suid(getuid());\n\t\tclose(p[0]);\n\t\tif (dup2(p[1], STDOUT_FILENO) < 0)\n\t\t\tfatal(\"ssh_askpass: dup2: %s\", strerror(errno));\n\t\texeclp(askpass, askpass, msg, (char *)NULL);\n\t\tfatal(\"ssh_askpass: exec(%s): %s\", askpass, strerror(errno));\n\t}\n\tclose(p[1]);\n\n\tlen = 0;\n\tdo {\n\t\tssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len);\n\n\t\tif (r == -1 && errno == EINTR)\n\t\t\tcontinue;\n\t\tif (r <= 0)\n\t\t\tbreak;\n\t\tlen += r;\n\t} while (sizeof(buf) - 1 - len > 0);\n\tbuf[len] = '\\0';\n\n\tclose(p[0]);\n\twhile ((ret = waitpid(pid, &status, 0)) < 0)\n\t\tif (errno != EINTR)\n\t\t\tbreak;\n\tsignal(SIGCHLD, osigchld);\n\tif (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {\n\t\texplicit_bzero(buf, sizeof(buf));\n\t\treturn NULL;\n\t}\n\n\tbuf[strcspn(buf, \"\\r\\n\")] = '\\0';\n\tpass = xstrdup(buf);\n\texplicit_bzero(buf, sizeof(buf));\n\treturn pass;\n}\n\n/*\n * Reads a passphrase from /dev/tty with echo turned off/on. Returns the\n * passphrase (allocated with xmalloc). Exits if EOF is encountered. If\n * RP_ALLOW_STDIN is set, the passphrase will be read from stdin if no\n * tty is available\n */\nchar *\nread_passphrase(const char *prompt, int flags)\n{\n\tchar *askpass = NULL, *ret, buf[1024];\n\tint rppflags, use_askpass = 0, ttyfd;\n\n\trppflags = (flags & RP_ECHO) ? RPP_ECHO_ON : RPP_ECHO_OFF;\n\tif (flags & RP_USE_ASKPASS)\n\t\tuse_askpass = 1;\n\telse if (flags & RP_ALLOW_STDIN) {\n\t\tif (!isatty(STDIN_FILENO)) {\n\t\t\tdebug(\"read_passphrase: stdin is not a tty\");\n\t\t\tuse_askpass = 1;\n\t\t}\n\t} else {\n\t\trppflags |= RPP_REQUIRE_TTY;\n\t\tttyfd = open(_PATH_TTY, O_RDWR);\n\t\tif (ttyfd >= 0)\n\t\t\tclose(ttyfd);\n\t\telse {\n\t\t\tdebug(\"read_passphrase: can't open %s: %s\", _PATH_TTY,\n\t\t\t strerror(errno));\n\t\t\tuse_askpass = 1;\n\t\t}\n\t}\n\n\tif ((flags & RP_USE_ASKPASS) && getenv(\"DISPLAY\") == NULL)\n\t\treturn (flags & RP_ALLOW_EOF) ? NULL : xstrdup(\"\");\n\n\tif (use_askpass && getenv(\"DISPLAY\")) {\n\t\tif (getenv(SSH_ASKPASS_ENV))\n\t\t\taskpass = getenv(SSH_ASKPASS_ENV);\n\t\telse\n\t\t\taskpass = _PATH_SSH_ASKPASS_DEFAULT;\n\t\tif ((ret = ssh_askpass(askpass, prompt)) == NULL)\n\t\t\tif (!(flags & RP_ALLOW_EOF))\n\t\t\t\treturn xstrdup(\"\");\n\t\treturn ret;\n\t}\n\n\tif (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL) {\n\t\tif (flags & RP_ALLOW_EOF)\n\t\t\treturn NULL;\n\t\treturn xstrdup(\"\");\n\t}\n\n\tret = xstrdup(buf);\n\texplicit_bzero(buf, sizeof(buf));\n\treturn ret;\n}\n\nint\nask_permission(const char *fmt, ...)\n{\n\tva_list args;\n\tchar *p, prompt[1024];\n\tint allowed = 0;\n\n\tva_start(args, fmt);\n\tvsnprintf(prompt, sizeof(prompt), fmt, args);\n\tva_end(args);\n\n\tp = read_passphrase(prompt, RP_USE_ASKPASS|RP_ALLOW_EOF);\n\tif (p != NULL) {\n\t\t/*\n\t\t * Accept empty responses and responses consisting\n\t\t * of the word \"yes\" as affirmative.\n\t\t */\n\t\tif (*p == '\\0' || *p == '\\n' ||\n\t\t strcasecmp(p, \"yes\") == 0)\n\t\t\tallowed = 1;\n\t\tfree(p);\n\t}\n\n\treturn (allowed);\n}\n","/* $OpenBSD: ttymodes.c,v 1.30 2016/05/04 14:22:33 markus Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n\n/*\n * SSH2 tty modes support by Kevin Steves.\n * Copyright (c) 2001 Kevin Steves. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/*\n * Encoding and decoding of terminal modes in a portable way.\n * Much of the format is defined in ttymodes.h; it is included multiple times\n * into this file with the appropriate macro definitions to generate the\n * suitable code.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n#include \n#include \n\n#include \"packet.h\"\n#include \"log.h\"\n#include \"compat.h\"\n#include \"buffer.h\"\n\n#define TTY_OP_END\t\t0\n/*\n * uint32 (u_int) follows speed in SSH1 and SSH2\n */\n#define TTY_OP_ISPEED_PROTO1\t192\n#define TTY_OP_OSPEED_PROTO1\t193\n#define TTY_OP_ISPEED_PROTO2\t128\n#define TTY_OP_OSPEED_PROTO2\t129\n\n/*\n * Converts POSIX speed_t to a baud rate. The values of the\n * constants for speed_t are not themselves portable.\n */\nstatic int\nspeed_to_baud(speed_t speed)\n{\n\tswitch (speed) {\n\tcase B0:\n\t\treturn 0;\n\tcase B50:\n\t\treturn 50;\n\tcase B75:\n\t\treturn 75;\n\tcase B110:\n\t\treturn 110;\n\tcase B134:\n\t\treturn 134;\n\tcase B150:\n\t\treturn 150;\n\tcase B200:\n\t\treturn 200;\n\tcase B300:\n\t\treturn 300;\n\tcase B600:\n\t\treturn 600;\n\tcase B1200:\n\t\treturn 1200;\n\tcase B1800:\n\t\treturn 1800;\n\tcase B2400:\n\t\treturn 2400;\n\tcase B4800:\n\t\treturn 4800;\n\tcase B9600:\n\t\treturn 9600;\n\n#ifdef B19200\n\tcase B19200:\n\t\treturn 19200;\n#else /* B19200 */\n#ifdef EXTA\n\tcase EXTA:\n\t\treturn 19200;\n#endif /* EXTA */\n#endif /* B19200 */\n\n#ifdef B38400\n\tcase B38400:\n\t\treturn 38400;\n#else /* B38400 */\n#ifdef EXTB\n\tcase EXTB:\n\t\treturn 38400;\n#endif /* EXTB */\n#endif /* B38400 */\n\n#ifdef B7200\n\tcase B7200:\n\t\treturn 7200;\n#endif /* B7200 */\n#ifdef B14400\n\tcase B14400:\n\t\treturn 14400;\n#endif /* B14400 */\n#ifdef B28800\n\tcase B28800:\n\t\treturn 28800;\n#endif /* B28800 */\n#ifdef B57600\n\tcase B57600:\n\t\treturn 57600;\n#endif /* B57600 */\n#ifdef B76800\n\tcase B76800:\n\t\treturn 76800;\n#endif /* B76800 */\n#ifdef B115200\n\tcase B115200:\n\t\treturn 115200;\n#endif /* B115200 */\n#ifdef B230400\n\tcase B230400:\n\t\treturn 230400;\n#endif /* B230400 */\n\tdefault:\n\t\treturn 9600;\n\t}\n}\n\n/*\n * Converts a numeric baud rate to a POSIX speed_t.\n */\nstatic speed_t\nbaud_to_speed(int baud)\n{\n\tswitch (baud) {\n\tcase 0:\n\t\treturn B0;\n\tcase 50:\n\t\treturn B50;\n\tcase 75:\n\t\treturn B75;\n\tcase 110:\n\t\treturn B110;\n\tcase 134:\n\t\treturn B134;\n\tcase 150:\n\t\treturn B150;\n\tcase 200:\n\t\treturn B200;\n\tcase 300:\n\t\treturn B300;\n\tcase 600:\n\t\treturn B600;\n\tcase 1200:\n\t\treturn B1200;\n\tcase 1800:\n\t\treturn B1800;\n\tcase 2400:\n\t\treturn B2400;\n\tcase 4800:\n\t\treturn B4800;\n\tcase 9600:\n\t\treturn B9600;\n\n#ifdef B19200\n\tcase 19200:\n\t\treturn B19200;\n#else /* B19200 */\n#ifdef EXTA\n\tcase 19200:\n\t\treturn EXTA;\n#endif /* EXTA */\n#endif /* B19200 */\n\n#ifdef B38400\n\tcase 38400:\n\t\treturn B38400;\n#else /* B38400 */\n#ifdef EXTB\n\tcase 38400:\n\t\treturn EXTB;\n#endif /* EXTB */\n#endif /* B38400 */\n\n#ifdef B7200\n\tcase 7200:\n\t\treturn B7200;\n#endif /* B7200 */\n#ifdef B14400\n\tcase 14400:\n\t\treturn B14400;\n#endif /* B14400 */\n#ifdef B28800\n\tcase 28800:\n\t\treturn B28800;\n#endif /* B28800 */\n#ifdef B57600\n\tcase 57600:\n\t\treturn B57600;\n#endif /* B57600 */\n#ifdef B76800\n\tcase 76800:\n\t\treturn B76800;\n#endif /* B76800 */\n#ifdef B115200\n\tcase 115200:\n\t\treturn B115200;\n#endif /* B115200 */\n#ifdef B230400\n\tcase 230400:\n\t\treturn B230400;\n#endif /* B230400 */\n\tdefault:\n\t\treturn B9600;\n\t}\n}\n\n/*\n * Encode a special character into SSH line format.\n */\nstatic u_int\nspecial_char_encode(cc_t c)\n{\n#ifdef _POSIX_VDISABLE\n\tif (c == _POSIX_VDISABLE)\n\t\treturn 255;\n#endif /* _POSIX_VDISABLE */\n\treturn c;\n}\n\n/*\n * Decode a special character from SSH line format.\n */\nstatic cc_t\nspecial_char_decode(u_int c)\n{\n#ifdef _POSIX_VDISABLE\n\tif (c == 255)\n\t\treturn _POSIX_VDISABLE;\n#endif /* _POSIX_VDISABLE */\n\treturn c;\n}\n\n/*\n * Encodes terminal modes for the terminal referenced by fd\n * or tiop in a portable manner, and appends the modes to a packet\n * being constructed.\n */\nvoid\ntty_make_modes(int fd, struct termios *tiop)\n{\n\tstruct termios tio;\n\tint baud;\n\tBuffer buf;\n\tint tty_op_ospeed, tty_op_ispeed;\n\tvoid (*put_arg)(Buffer *, u_int);\n\n\tbuffer_init(&buf);\n\tif (compat20) {\n\t\ttty_op_ospeed = TTY_OP_OSPEED_PROTO2;\n\t\ttty_op_ispeed = TTY_OP_ISPEED_PROTO2;\n\t\tput_arg = buffer_put_int;\n\t} else {\n\t\ttty_op_ospeed = TTY_OP_OSPEED_PROTO1;\n\t\ttty_op_ispeed = TTY_OP_ISPEED_PROTO1;\n\t\tput_arg = (void (*)(Buffer *, u_int)) buffer_put_char;\n\t}\n\n\tif (tiop == NULL) {\n\t\tif (fd == -1) {\n\t\t\tdebug(\"tty_make_modes: no fd or tio\");\n\t\t\tgoto end;\n\t\t}\n\t\tif (tcgetattr(fd, &tio) == -1) {\n\t\t\tlogit(\"tcgetattr: %.100s\", strerror(errno));\n\t\t\tgoto end;\n\t\t}\n\t} else\n\t\ttio = *tiop;\n\n\t/* Store input and output baud rates. */\n\tbaud = speed_to_baud(cfgetospeed(&tio));\n\tbuffer_put_char(&buf, tty_op_ospeed);\n\tbuffer_put_int(&buf, baud);\n\tbaud = speed_to_baud(cfgetispeed(&tio));\n\tbuffer_put_char(&buf, tty_op_ispeed);\n\tbuffer_put_int(&buf, baud);\n\n\t/* Store values of mode flags. */\n#define TTYCHAR(NAME, OP) \\\n\tbuffer_put_char(&buf, OP); \\\n\tput_arg(&buf, special_char_encode(tio.c_cc[NAME]));\n\n#define TTYMODE(NAME, FIELD, OP) \\\n\tbuffer_put_char(&buf, OP); \\\n\tput_arg(&buf, ((tio.FIELD & NAME) != 0));\n\n#include \"ttymodes.h\"\n\n#undef TTYCHAR\n#undef TTYMODE\n\nend:\n\t/* Mark end of mode data. */\n\tbuffer_put_char(&buf, TTY_OP_END);\n\tif (compat20)\n\t\tpacket_put_string(buffer_ptr(&buf), buffer_len(&buf));\n\telse\n\t\tpacket_put_raw(buffer_ptr(&buf), buffer_len(&buf));\n\tbuffer_free(&buf);\n}\n\n/*\n * Decodes terminal modes for the terminal referenced by fd in a portable\n * manner from a packet being read.\n */\nvoid\ntty_parse_modes(int fd, int *n_bytes_ptr)\n{\n\tstruct termios tio;\n\tint opcode, baud;\n\tint n_bytes = 0;\n\tint failure = 0;\n\tu_int (*get_arg)(void);\n\tint arg_size;\n\n\tif (compat20) {\n\t\t*n_bytes_ptr = packet_get_int();\n\t\tif (*n_bytes_ptr == 0)\n\t\t\treturn;\n\t\tget_arg = packet_get_int;\n\t\targ_size = 4;\n\t} else {\n\t\tget_arg = packet_get_char;\n\t\targ_size = 1;\n\t}\n\n\t/*\n\t * Get old attributes for the terminal. We will modify these\n\t * flags. I am hoping that if there are any machine-specific\n\t * modes, they will initially have reasonable values.\n\t */\n\tif (tcgetattr(fd, &tio) == -1) {\n\t\tlogit(\"tcgetattr: %.100s\", strerror(errno));\n\t\tfailure = -1;\n\t}\n\n\tfor (;;) {\n\t\tn_bytes += 1;\n\t\topcode = packet_get_char();\n\t\tswitch (opcode) {\n\t\tcase TTY_OP_END:\n\t\t\tgoto set;\n\n\t\t/* XXX: future conflict possible */\n\t\tcase TTY_OP_ISPEED_PROTO1:\n\t\tcase TTY_OP_ISPEED_PROTO2:\n\t\t\tn_bytes += 4;\n\t\t\tbaud = packet_get_int();\n\t\t\tif (failure != -1 &&\n\t\t\t cfsetispeed(&tio, baud_to_speed(baud)) == -1)\n\t\t\t\terror(\"cfsetispeed failed for %d\", baud);\n\t\t\tbreak;\n\n\t\t/* XXX: future conflict possible */\n\t\tcase TTY_OP_OSPEED_PROTO1:\n\t\tcase TTY_OP_OSPEED_PROTO2:\n\t\t\tn_bytes += 4;\n\t\t\tbaud = packet_get_int();\n\t\t\tif (failure != -1 &&\n\t\t\t cfsetospeed(&tio, baud_to_speed(baud)) == -1)\n\t\t\t\terror(\"cfsetospeed failed for %d\", baud);\n\t\t\tbreak;\n\n#define TTYCHAR(NAME, OP) \\\n\tcase OP: \\\n\t n_bytes += arg_size; \\\n\t tio.c_cc[NAME] = special_char_decode(get_arg()); \\\n\t break;\n#define TTYMODE(NAME, FIELD, OP) \\\n\tcase OP: \\\n\t n_bytes += arg_size; \\\n\t if (get_arg()) \\\n\t tio.FIELD |= NAME; \\\n\t else \\\n\t tio.FIELD &= ~NAME;\t\\\n\t break;\n\n#include \"ttymodes.h\"\n\n#undef TTYCHAR\n#undef TTYMODE\n\n\t\tdefault:\n\t\t\tdebug(\"Ignoring unsupported tty mode opcode %d (0x%x)\",\n\t\t\t opcode, opcode);\n\t\t\tif (!compat20) {\n\t\t\t\t/*\n\t\t\t\t * SSH1:\n\t\t\t\t * Opcodes 1 to 127 are defined to have\n\t\t\t\t * a one-byte argument.\n\t\t\t\t * Opcodes 128 to 159 are defined to have\n\t\t\t\t * an integer argument.\n\t\t\t\t */\n\t\t\t\tif (opcode > 0 && opcode < 128) {\n\t\t\t\t\tn_bytes += 1;\n\t\t\t\t\t(void) packet_get_char();\n\t\t\t\t\tbreak;\n\t\t\t\t} else if (opcode >= 128 && opcode < 160) {\n\t\t\t\t\tn_bytes += 4;\n\t\t\t\t\t(void) packet_get_int();\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\t/*\n\t\t\t\t\t * It is a truly undefined opcode (160 to 255).\n\t\t\t\t\t * We have no idea about its arguments. So we\n\t\t\t\t\t * must stop parsing. Note that some data\n\t\t\t\t\t * may be left in the packet; hopefully there\n\t\t\t\t\t * is nothing more coming after the mode data.\n\t\t\t\t\t */\n\t\t\t\t\tlogit(\"parse_tty_modes: unknown opcode %d\",\n\t\t\t\t\t opcode);\n\t\t\t\t\tgoto set;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * SSH2:\n\t\t\t\t * Opcodes 1 to 159 are defined to have\n\t\t\t\t * a uint32 argument.\n\t\t\t\t * Opcodes 160 to 255 are undefined and\n\t\t\t\t * cause parsing to stop.\n\t\t\t\t */\n\t\t\t\tif (opcode > 0 && opcode < 160) {\n\t\t\t\t\tn_bytes += 4;\n\t\t\t\t\t(void) packet_get_int();\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tlogit(\"parse_tty_modes: unknown opcode %d\",\n\t\t\t\t\t opcode);\n\t\t\t\t\tgoto set;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\nset:\n\tif (*n_bytes_ptr != n_bytes) {\n\t\t*n_bytes_ptr = n_bytes;\n\t\tlogit(\"parse_tty_modes: n_bytes_ptr != n_bytes: %d %d\",\n\t\t *n_bytes_ptr, n_bytes);\n\t\treturn;\t\t/* Don't process bytes passed */\n\t}\n\tif (failure == -1)\n\t\treturn;\t\t/* Packet parsed ok but tcgetattr() failed */\n\n\t/* Set the new modes for the terminal. */\n\tif (tcsetattr(fd, TCSANOW, &tio) == -1)\n\t\tlogit(\"Setting tty modes failed: %.100s\", strerror(errno));\n}\n","/* $OpenBSD: ttymodes.h,v 1.15 2016/05/03 09:03:49 dtucker Exp $ */\n\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n\n/*\n * SSH2 tty modes support by Kevin Steves.\n * Copyright (c) 2001 Kevin Steves. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/*\n * SSH1:\n * The tty mode description is a stream of bytes. The stream consists of\n * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0).\n * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer\n * arguments. Opcodes 160-255 are not yet defined, and cause parsing to\n * stop (they should only be used after any other data).\n *\n * SSH2:\n * Differences between SSH1 and SSH2 terminal mode encoding include:\n * 1. Encoded terminal modes are represented as a string, and a stream\n * of bytes within that string.\n * 2. Opcode arguments are uint32 (1-159); 160-255 remain undefined.\n * 3. The values for TTY_OP_ISPEED and TTY_OP_OSPEED are different;\n * 128 and 129 vs. 192 and 193 respectively.\n *\n * The client puts in the stream any modes it knows about, and the\n * server ignores any modes it does not know about. This allows some degree\n * of machine-independence, at least between systems that use a posix-like\n * tty interface. The protocol can support other systems as well, but might\n * require reimplementing as mode names would likely be different.\n */\n\n/*\n * Some constants and prototypes are defined in packet.h; this file\n * is only intended for including from ttymodes.c.\n */\n\n/* termios macro */\n/* name, op */\nTTYCHAR(VINTR, 1)\nTTYCHAR(VQUIT, 2)\nTTYCHAR(VERASE, 3)\n#if defined(VKILL)\nTTYCHAR(VKILL, 4)\n#endif /* VKILL */\nTTYCHAR(VEOF, 5)\n#if defined(VEOL)\nTTYCHAR(VEOL, 6)\n#endif /* VEOL */\n#ifdef VEOL2\nTTYCHAR(VEOL2, 7)\n#endif /* VEOL2 */\nTTYCHAR(VSTART, 8)\nTTYCHAR(VSTOP, 9)\n#if defined(VSUSP)\nTTYCHAR(VSUSP, 10)\n#endif /* VSUSP */\n#if defined(VDSUSP)\nTTYCHAR(VDSUSP, 11)\n#endif /* VDSUSP */\n#if defined(VREPRINT)\nTTYCHAR(VREPRINT, 12)\n#endif /* VREPRINT */\n#if defined(VWERASE)\nTTYCHAR(VWERASE, 13)\n#endif /* VWERASE */\n#if defined(VLNEXT)\nTTYCHAR(VLNEXT, 14)\n#endif /* VLNEXT */\n#if defined(VFLUSH)\nTTYCHAR(VFLUSH, 15)\n#endif /* VFLUSH */\n#ifdef VSWTCH\nTTYCHAR(VSWTCH, 16)\n#endif /* VSWTCH */\n#if defined(VSTATUS)\nTTYCHAR(VSTATUS, 17)\n#endif /* VSTATUS */\n#ifdef VDISCARD\nTTYCHAR(VDISCARD, 18)\n#endif /* VDISCARD */\n\n/* name, field, op */\nTTYMODE(IGNPAR,\tc_iflag, 30)\nTTYMODE(PARMRK,\tc_iflag, 31)\nTTYMODE(INPCK,\tc_iflag, 32)\nTTYMODE(ISTRIP,\tc_iflag, 33)\nTTYMODE(INLCR,\tc_iflag, 34)\nTTYMODE(IGNCR,\tc_iflag, 35)\nTTYMODE(ICRNL,\tc_iflag, 36)\n#if defined(IUCLC)\nTTYMODE(IUCLC,\tc_iflag, 37)\n#endif\nTTYMODE(IXON,\tc_iflag, 38)\nTTYMODE(IXANY,\tc_iflag, 39)\nTTYMODE(IXOFF,\tc_iflag, 40)\n#ifdef IMAXBEL\nTTYMODE(IMAXBEL,c_iflag, 41)\n#endif /* IMAXBEL */\n#ifdef IUTF8\nTTYMODE(IUTF8, c_iflag, 42)\n#endif /* IUTF8 */\n\nTTYMODE(ISIG,\tc_lflag, 50)\nTTYMODE(ICANON,\tc_lflag, 51)\n#ifdef XCASE\nTTYMODE(XCASE,\tc_lflag, 52)\n#endif\nTTYMODE(ECHO,\tc_lflag, 53)\nTTYMODE(ECHOE,\tc_lflag, 54)\nTTYMODE(ECHOK,\tc_lflag, 55)\nTTYMODE(ECHONL,\tc_lflag, 56)\nTTYMODE(NOFLSH,\tc_lflag, 57)\nTTYMODE(TOSTOP,\tc_lflag, 58)\n#ifdef IEXTEN\nTTYMODE(IEXTEN, c_lflag, 59)\n#endif /* IEXTEN */\n#if defined(ECHOCTL)\nTTYMODE(ECHOCTL,c_lflag, 60)\n#endif /* ECHOCTL */\n#ifdef ECHOKE\nTTYMODE(ECHOKE,\tc_lflag, 61)\n#endif /* ECHOKE */\n#if defined(PENDIN)\nTTYMODE(PENDIN,\tc_lflag, 62)\n#endif /* PENDIN */\n\nTTYMODE(OPOST,\tc_oflag, 70)\n#if defined(OLCUC)\nTTYMODE(OLCUC,\tc_oflag, 71)\n#endif\n#ifdef ONLCR\nTTYMODE(ONLCR,\tc_oflag, 72)\n#endif\n#ifdef OCRNL\nTTYMODE(OCRNL,\tc_oflag, 73)\n#endif\n#ifdef ONOCR\nTTYMODE(ONOCR,\tc_oflag, 74)\n#endif\n#ifdef ONLRET\nTTYMODE(ONLRET,\tc_oflag, 75)\n#endif\n\nTTYMODE(CS7,\tc_cflag, 90)\nTTYMODE(CS8,\tc_cflag, 91)\nTTYMODE(PARENB,\tc_cflag, 92)\nTTYMODE(PARODD,\tc_cflag, 93)\n","/* $OpenBSD: xmalloc.c,v 1.33 2016/02/15 09:47:49 dtucker Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Versions of malloc and friends that check their results, and never return\n * failure (they call fatal if they encounter an error).\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n\n#include \"includes.h\"\n\n#include \n#ifdef HAVE_STDINT_H\n#include \n#endif\n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"log.h\"\n\nvoid\nssh_malloc_init(void)\n{\n#if defined(__OpenBSD__)\n\textern char *malloc_options;\n\n\tmalloc_options = \"S\";\n#endif /* __OpenBSD__ */\n}\n\nvoid *\nxmalloc(size_t size)\n{\n\tvoid *ptr;\n\n\tif (size == 0)\n\t\tfatal(\"xmalloc: zero size\");\n\tptr = malloc(size);\n\tif (ptr == NULL)\n\t\tfatal(\"xmalloc: out of memory (allocating %zu bytes)\", size);\n\treturn ptr;\n}\n\nvoid *\nxcalloc(size_t nmemb, size_t size)\n{\n\tvoid *ptr;\n\n\tif (size == 0 || nmemb == 0)\n\t\tfatal(\"xcalloc: zero size\");\n\tif (SIZE_MAX / nmemb < size)\n\t\tfatal(\"xcalloc: nmemb * size > SIZE_MAX\");\n\tptr = calloc(nmemb, size);\n\tif (ptr == NULL)\n\t\tfatal(\"xcalloc: out of memory (allocating %zu bytes)\",\n\t\t size * nmemb);\n\treturn ptr;\n}\n\nvoid *\nxreallocarray(void *ptr, size_t nmemb, size_t size)\n{\n\tvoid *new_ptr;\n\n\tnew_ptr = reallocarray(ptr, nmemb, size);\n\tif (new_ptr == NULL)\n\t\tfatal(\"xreallocarray: out of memory (%zu elements of %zu bytes)\",\n\t\t nmemb, size);\n\treturn new_ptr;\n}\n\nchar *\nxstrdup(const char *str)\n{\n\tsize_t len;\n\tchar *cp;\n\n\tlen = strlen(str) + 1;\n\tcp = xmalloc(len);\n\tstrlcpy(cp, str, len);\n\treturn cp;\n}\n\nint\nxasprintf(char **ret, const char *fmt, ...)\n{\n\tva_list ap;\n\tint i;\n\n\tva_start(ap, fmt);\n\ti = vasprintf(ret, fmt, ap);\n\tva_end(ap);\n\n\tif (i < 0 || *ret == NULL)\n\t\tfatal(\"xasprintf: could not allocate memory\");\n\n\treturn (i);\n}\n","/* $OpenBSD: atomicio.c,v 1.28 2016/07/27 23:18:12 djm Exp $ */\n/*\n * Copyright (c) 2006 Damien Miller. All rights reserved.\n * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.\n * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \n#ifdef HAVE_POLL_H\n#include \n#else\n# ifdef HAVE_SYS_POLL_H\n# include \n# endif\n#endif\n#include \n#include \n#include \n\n#include \"atomicio.h\"\n\n/*\n * ensure all of data on socket comes through. f==read || f==vwrite\n */\nsize_t\natomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,\n int (*cb)(void *, size_t), void *cb_arg)\n{\n\tchar *s = _s;\n\tsize_t pos = 0;\n\tssize_t res;\n\tstruct pollfd pfd;\n\n#ifndef BROKEN_READ_COMPARISON\n\tpfd.fd = fd;\n\tpfd.events = f == read ? POLLIN : POLLOUT;\n#endif\n\twhile (n > pos) {\n\t\tres = (f) (fd, s + pos, n - pos);\n\t\tswitch (res) {\n\t\tcase -1:\n\t\t\tif (errno == EINTR)\n\t\t\t\tcontinue;\n\t\t\tif (errno == EAGAIN || errno == EWOULDBLOCK) {\n#ifndef BROKEN_READ_COMPARISON\n\t\t\t\t(void)poll(&pfd, 1, -1);\n#endif\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn 0;\n\t\tcase 0:\n\t\t\terrno = EPIPE;\n\t\t\treturn pos;\n\t\tdefault:\n\t\t\tpos += (size_t)res;\n\t\t\tif (cb != NULL && cb(cb_arg, (size_t)res) == -1) {\n\t\t\t\terrno = EINTR;\n\t\t\t\treturn pos;\n\t\t\t}\n\t\t}\n\t}\n\treturn pos;\n}\n\nsize_t\natomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)\n{\n\treturn atomicio6(f, fd, _s, n, NULL, NULL);\n}\n\n/*\n * ensure all of data on socket comes through. f==readv || f==writev\n */\nsize_t\natomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,\n const struct iovec *_iov, int iovcnt,\n int (*cb)(void *, size_t), void *cb_arg)\n{\n\tsize_t pos = 0, rem;\n\tssize_t res;\n\tstruct iovec iov_array[IOV_MAX], *iov = iov_array;\n\tstruct pollfd pfd;\n\n\tif (iovcnt < 0 || iovcnt > IOV_MAX) {\n\t\terrno = EINVAL;\n\t\treturn 0;\n\t}\n\t/* Make a copy of the iov array because we may modify it below */\n\tmemcpy(iov, _iov, (size_t)iovcnt * sizeof(*_iov));\n\n#ifndef BROKEN_READV_COMPARISON\n\tpfd.fd = fd;\n\tpfd.events = f == readv ? POLLIN : POLLOUT;\n#endif\n\tfor (; iovcnt > 0 && iov[0].iov_len > 0;) {\n\t\tres = (f) (fd, iov, iovcnt);\n\t\tswitch (res) {\n\t\tcase -1:\n\t\t\tif (errno == EINTR)\n\t\t\t\tcontinue;\n\t\t\tif (errno == EAGAIN || errno == EWOULDBLOCK) {\n#ifndef BROKEN_READV_COMPARISON\n\t\t\t\t(void)poll(&pfd, 1, -1);\n#endif\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\treturn 0;\n\t\tcase 0:\n\t\t\terrno = EPIPE;\n\t\t\treturn pos;\n\t\tdefault:\n\t\t\trem = (size_t)res;\n\t\t\tpos += rem;\n\t\t\t/* skip completed iov entries */\n\t\t\twhile (iovcnt > 0 && rem >= iov[0].iov_len) {\n\t\t\t\trem -= iov[0].iov_len;\n\t\t\t\tiov++;\n\t\t\t\tiovcnt--;\n\t\t\t}\n\t\t\t/* This shouldn't happen... */\n\t\t\tif (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) {\n\t\t\t\terrno = EFAULT;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (iovcnt == 0)\n\t\t\t\tbreak;\n\t\t\t/* update pointer in partially complete iov */\n\t\t\tiov[0].iov_base = ((char *)iov[0].iov_base) + rem;\n\t\t\tiov[0].iov_len -= rem;\n\t\t}\n\t\tif (cb != NULL && cb(cb_arg, (size_t)res) == -1) {\n\t\t\terrno = EINTR;\n\t\t\treturn pos;\n\t\t}\n\t}\n\treturn pos;\n}\n\nsize_t\natomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,\n const struct iovec *_iov, int iovcnt)\n{\n\treturn atomiciov6(f, fd, _iov, iovcnt, NULL, NULL);\n}\n","/* $OpenBSD: key.c,v 1.130 2016/05/02 09:36:42 djm Exp $ */\n/*\n * placed in the public domain\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#include \n\n#define SSH_KEY_NO_DEFINE\n#include \"key.h\"\n\n#include \"compat.h\"\n#include \"sshkey.h\"\n#include \"ssherr.h\"\n#include \"log.h\"\n#include \"authfile.h\"\n\nvoid\nkey_add_private(Key *k)\n{\n\tint r;\n\n\tif ((r = sshkey_add_private(k)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nKey *\nkey_new_private(int type)\n{\n\tKey *ret = NULL;\n\n\tif ((ret = sshkey_new_private(type)) == NULL)\n\t\tfatal(\"%s: failed\", __func__);\n\treturn ret;\n}\n\nint\nkey_read(Key *ret, char **cpp)\n{\n\treturn sshkey_read(ret, cpp) == 0 ? 1 : -1;\n}\n\nint\nkey_write(const Key *key, FILE *f)\n{\n\treturn sshkey_write(key, f) == 0 ? 1 : 0;\n}\n\nKey *\nkey_generate(int type, u_int bits)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_generate(type, bits, &ret)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\treturn ret;\n}\n\nvoid\nkey_cert_copy(const Key *from_key, Key *to_key)\n{\n\tint r;\n\n\tif ((r = sshkey_cert_copy(from_key, to_key)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nKey *\nkey_from_private(const Key *k)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_from_private(k, &ret)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\treturn ret;\n}\n\nstatic void\nfatal_on_fatal_errors(int r, const char *func, int extra_fatal)\n{\n\tif (r == SSH_ERR_INTERNAL_ERROR ||\n\t r == SSH_ERR_ALLOC_FAIL ||\n\t (extra_fatal != 0 && r == extra_fatal))\n\t\tfatal(\"%s: %s\", func, ssh_err(r));\n}\n\nKey *\nkey_from_blob(const u_char *blob, u_int blen)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_from_blob(blob, blen, &ret)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nint\nkey_to_blob(const Key *key, u_char **blobp, u_int *lenp)\n{\n\tu_char *blob;\n\tsize_t blen;\n\tint r;\n\n\tif (blobp != NULL)\n\t\t*blobp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn 0;\n\t}\n\tif (blen > INT_MAX)\n\t\tfatal(\"%s: giant len %zu\", __func__, blen);\n\tif (blobp != NULL)\n\t\t*blobp = blob;\n\tif (lenp != NULL)\n\t\t*lenp = blen;\n\treturn blen;\n}\n\nint\nkey_sign(const Key *key, u_char **sigp, u_int *lenp,\n const u_char *data, u_int datalen, const char *alg)\n{\n\tint r;\n\tu_char *sig;\n\tsize_t siglen;\n\n\tif (sigp != NULL)\n\t\t*sigp = NULL;\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif ((r = sshkey_sign(key, &sig, &siglen,\n\t data, datalen, alg, datafellows)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\tif (siglen > INT_MAX)\n\t\tfatal(\"%s: giant len %zu\", __func__, siglen);\n\tif (sigp != NULL)\n\t\t*sigp = sig;\n\tif (lenp != NULL)\n\t\t*lenp = siglen;\n\treturn 0;\n}\n\nint\nkey_verify(const Key *key, const u_char *signature, u_int signaturelen,\n const u_char *data, u_int datalen)\n{\n\tint r;\n\n\tif ((r = sshkey_verify(key, signature, signaturelen,\n\t data, datalen, datafellows)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1;\n\t}\n\treturn 1;\n}\n\nKey *\nkey_demote(const Key *k)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_demote(k, &ret)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n\treturn ret;\n}\n\nint\nkey_to_certified(Key *k)\n{\n\tint r;\n\n\tif ((r = sshkey_to_certified(k)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nint\nkey_drop_cert(Key *k)\n{\n\tint r;\n\n\tif ((r = sshkey_drop_cert(k)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nint\nkey_certify(Key *k, Key *ca)\n{\n\tint r;\n\n\tif ((r = sshkey_certify(k, ca, NULL)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nint\nkey_cert_check_authority(const Key *k, int want_host, int require_principal,\n const char *name, const char **reason)\n{\n\tint r;\n\n\tif ((r = sshkey_cert_check_authority(k, want_host, require_principal,\n\t name, reason)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, 0);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)\nint\nkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)\n{\n\tint r;\n\n\tif ((r = sshkey_ec_validate_public(group, public)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\nint\nkey_ec_validate_private(const EC_KEY *key)\n{\n\tint r;\n\n\tif ((r = sshkey_ec_validate_private(key)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n#endif /* WITH_OPENSSL */\n\nvoid\nkey_private_serialize(const Key *key, struct sshbuf *b)\n{\n\tint r;\n\n\tif ((r = sshkey_private_serialize(key, b)) != 0)\n\t\tfatal(\"%s: %s\", __func__, ssh_err(r));\n}\n\nKey *\nkey_private_deserialize(struct sshbuf *blob)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_private_deserialize(blob, &ret)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\n/* authfile.c */\n\nint\nkey_save_private(Key *key, const char *filename, const char *passphrase,\n const char *comment, int force_new_format, const char *new_format_cipher,\n int new_format_rounds)\n{\n\tint r;\n\n\tif ((r = sshkey_save_private(key, filename, passphrase, comment,\n\t force_new_format, new_format_cipher, new_format_rounds)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nint\nkey_load_file(int fd, const char *filename, struct sshbuf *blob)\n{\n\tint r;\n\n\tif ((r = sshkey_load_file(fd, blob)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nKey *\nkey_load_cert(const char *filename)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_load_cert(filename, &ret)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\t/* Old authfile.c ignored all file errors. */\n\t\tif (r == SSH_ERR_SYSTEM_ERROR)\n\t\t\tdebug(\"%s: %s\", __func__, ssh_err(r));\n\t\telse\n\t\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\treturn ret;\n\n}\n\nKey *\nkey_load_public(const char *filename, char **commentp)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\t/* Old authfile.c ignored all file errors. */\n\t\tif (r == SSH_ERR_SYSTEM_ERROR)\n\t\t\tdebug(\"%s: %s\", __func__, ssh_err(r));\n\t\telse\n\t\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nKey *\nkey_load_private(const char *path, const char *passphrase,\n char **commentp)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\t/* Old authfile.c ignored all file errors. */\n\t\tif (r == SSH_ERR_SYSTEM_ERROR ||\n\t\t r == SSH_ERR_KEY_WRONG_PASSPHRASE)\n\t\t\tdebug(\"%s: %s\", __func__, ssh_err(r));\n\t\telse\n\t\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nKey *\nkey_load_private_cert(int type, const char *filename, const char *passphrase,\n int *perm_ok)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_load_private_cert(type, filename, passphrase,\n\t &ret, perm_ok)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\t/* Old authfile.c ignored all file errors. */\n\t\tif (r == SSH_ERR_SYSTEM_ERROR ||\n\t\t r == SSH_ERR_KEY_WRONG_PASSPHRASE)\n\t\t\tdebug(\"%s: %s\", __func__, ssh_err(r));\n\t\telse\n\t\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nKey *\nkey_load_private_type(int type, const char *filename, const char *passphrase,\n char **commentp, int *perm_ok)\n{\n\tint r;\n\tKey *ret = NULL;\n\n\tif ((r = sshkey_load_private_type(type, filename, passphrase,\n\t &ret, commentp, perm_ok)) != 0) {\n\t\tfatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);\n\t\t/* Old authfile.c ignored all file errors. */\n\t\tif (r == SSH_ERR_SYSTEM_ERROR ||\n\t\t (r == SSH_ERR_KEY_WRONG_PASSPHRASE))\n\t\t\tdebug(\"%s: %s\", __func__, ssh_err(r));\n\t\telse\n\t\t\terror(\"%s: %s\", __func__, ssh_err(r));\n\t\treturn NULL;\n\t}\n\treturn ret;\n}\n\nint\nkey_perm_ok(int fd, const char *filename)\n{\n\treturn sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;\n}\n\n","/* $OpenBSD: dispatch.c,v 1.27 2015/05/01 07:10:01 djm Exp $ */\n/*\n * Copyright (c) 2000 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n\n#include \"ssh1.h\"\n#include \"ssh2.h\"\n#include \"log.h\"\n#include \"dispatch.h\"\n#include \"packet.h\"\n#include \"compat.h\"\n#include \"ssherr.h\"\n\nint\ndispatch_protocol_error(int type, u_int32_t seq, void *ctx)\n{\n\tstruct ssh *ssh = active_state; /* XXX */\n\tint r;\n\n\tlogit(\"dispatch_protocol_error: type %d seq %u\", type, seq);\n\tif (!compat20)\n\t\tfatal(\"protocol error\");\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||\n\t (r = sshpkt_put_u32(ssh, seq)) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0 ||\n\t (r = ssh_packet_write_wait(ssh)) != 0)\n\t\tsshpkt_fatal(ssh, __func__, r);\n\treturn 0;\n}\n\nint\ndispatch_protocol_ignore(int type, u_int32_t seq, void *ssh)\n{\n\tlogit(\"dispatch_protocol_ignore: type %d seq %u\", type, seq);\n\treturn 0;\n}\n\nvoid\nssh_dispatch_init(struct ssh *ssh, dispatch_fn *dflt)\n{\n\tu_int i;\n\tfor (i = 0; i < DISPATCH_MAX; i++)\n\t\tssh->dispatch[i] = dflt;\n}\n\nvoid\nssh_dispatch_range(struct ssh *ssh, u_int from, u_int to, dispatch_fn *fn)\n{\n\tu_int i;\n\n\tfor (i = from; i <= to; i++) {\n\t\tif (i >= DISPATCH_MAX)\n\t\t\tbreak;\n\t\tssh->dispatch[i] = fn;\n\t}\n}\n\nvoid\nssh_dispatch_set(struct ssh *ssh, int type, dispatch_fn *fn)\n{\n\tssh->dispatch[type] = fn;\n}\n\nint\nssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done,\n void *ctxt)\n{\n\tint r;\n\tu_char type;\n\tu_int32_t seqnr;\n\n\tfor (;;) {\n\t\tif (mode == DISPATCH_BLOCK) {\n\t\t\tr = ssh_packet_read_seqnr(ssh, &type, &seqnr);\n\t\t\tif (r != 0)\n\t\t\t\treturn r;\n\t\t} else {\n\t\t\tr = ssh_packet_read_poll_seqnr(ssh, &type, &seqnr);\n\t\t\tif (r != 0)\n\t\t\t\treturn r;\n\t\t\tif (type == SSH_MSG_NONE)\n\t\t\t\treturn 0;\n\t\t}\n\t\tif (type > 0 && type < DISPATCH_MAX &&\n\t\t ssh->dispatch[type] != NULL) {\n\t\t\tif (ssh->dispatch_skip_packets) {\n\t\t\t\tdebug2(\"skipped packet (type %u)\", type);\n\t\t\t\tssh->dispatch_skip_packets--;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t/* XXX 'ssh' will replace 'ctxt' later */\n\t\t\tr = (*ssh->dispatch[type])(type, seqnr, ctxt);\n\t\t\tif (r != 0)\n\t\t\t\treturn r;\n\t\t} else {\n\t\t\tr = sshpkt_disconnect(ssh,\n\t\t\t \"protocol error: rcvd type %d\", type);\n\t\t\tif (r != 0)\n\t\t\t\treturn r;\n\t\t\treturn SSH_ERR_DISCONNECTED;\n\t\t}\n\t\tif (done != NULL && *done)\n\t\t\treturn 0;\n\t}\n}\n\nvoid\nssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done,\n void *ctxt)\n{\n\tint r;\n\n\tif ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0)\n\t\tsshpkt_fatal(ssh, __func__, r);\n}\n","/* $OpenBSD: mac.c,v 1.33 2016/07/08 03:44:42 djm Exp $ */\n/*\n * Copyright (c) 2001 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n\n#include \"digest.h\"\n#include \"hmac.h\"\n#include \"umac.h\"\n#include \"mac.h\"\n#include \"misc.h\"\n#include \"ssherr.h\"\n#include \"sshbuf.h\"\n\n#include \"openbsd-compat/openssl-compat.h\"\n\n#define SSH_DIGEST\t1\t/* SSH_DIGEST_XXX */\n#define SSH_UMAC\t2\t/* UMAC (not integrated with OpenSSL) */\n#define SSH_UMAC128\t3\n\nstruct macalg {\n\tchar\t\t*name;\n\tint\t\ttype;\n\tint\t\talg;\n\tint\t\ttruncatebits;\t/* truncate digest if != 0 */\n\tint\t\tkey_len;\t/* just for UMAC */\n\tint\t\tlen;\t\t/* just for UMAC */\n\tint\t\tetm;\t\t/* Encrypt-then-MAC */\n};\n\nstatic const struct macalg macs[] = {\n\t/* Encrypt-and-MAC (encrypt-and-authenticate) variants */\n\t{ \"hmac-sha1\",\t\t\t\tSSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },\n\t{ \"hmac-sha1-96\",\t\t\tSSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 },\n#ifdef HAVE_EVP_SHA256\n\t{ \"hmac-sha2-256\",\t\t\tSSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },\n\t{ \"hmac-sha2-512\",\t\t\tSSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },\n#endif\n\t{ \"hmac-md5\",\t\t\t\tSSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },\n\t{ \"hmac-md5-96\",\t\t\tSSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },\n#ifdef HAVE_EVP_RIPEMD160\n\t{ \"hmac-ripemd160\",\t\t\tSSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },\n\t{ \"hmac-ripemd160@openssh.com\",\t\tSSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },\n#endif\n\t{ \"umac-64@openssh.com\",\t\tSSH_UMAC, 0, 0, 128, 64, 0 },\n\t{ \"umac-128@openssh.com\",\t\tSSH_UMAC128, 0, 0, 128, 128, 0 },\n\n\t/* Encrypt-then-MAC variants */\n\t{ \"hmac-sha1-etm@openssh.com\",\t\tSSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },\n\t{ \"hmac-sha1-96-etm@openssh.com\",\tSSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 },\n#ifdef HAVE_EVP_SHA256\n\t{ \"hmac-sha2-256-etm@openssh.com\",\tSSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },\n\t{ \"hmac-sha2-512-etm@openssh.com\",\tSSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },\n#endif\n\t{ \"hmac-md5-etm@openssh.com\",\t\tSSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },\n\t{ \"hmac-md5-96-etm@openssh.com\",\tSSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },\n#ifdef HAVE_EVP_RIPEMD160\n\t{ \"hmac-ripemd160-etm@openssh.com\",\tSSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },\n#endif\n\t{ \"umac-64-etm@openssh.com\",\t\tSSH_UMAC, 0, 0, 128, 64, 1 },\n\t{ \"umac-128-etm@openssh.com\",\t\tSSH_UMAC128, 0, 0, 128, 128, 1 },\n\n\t{ NULL,\t\t\t\t\t0, 0, 0, 0, 0, 0 }\n};\n\n/* Returns a list of supported MACs separated by the specified char. */\nchar *\nmac_alg_list(char sep)\n{\n\tchar *ret = NULL, *tmp;\n\tsize_t nlen, rlen = 0;\n\tconst struct macalg *m;\n\n\tfor (m = macs; m->name != NULL; m++) {\n\t\tif (ret != NULL)\n\t\t\tret[rlen++] = sep;\n\t\tnlen = strlen(m->name);\n\t\tif ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {\n\t\t\tfree(ret);\n\t\t\treturn NULL;\n\t\t}\n\t\tret = tmp;\n\t\tmemcpy(ret + rlen, m->name, nlen + 1);\n\t\trlen += nlen;\n\t}\n\treturn ret;\n}\n\nstatic int\nmac_setup_by_alg(struct sshmac *mac, const struct macalg *macalg)\n{\n\tmac->type = macalg->type;\n\tif (mac->type == SSH_DIGEST) {\n\t\tif ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tmac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);\n\t} else {\n\t\tmac->mac_len = macalg->len / 8;\n\t\tmac->key_len = macalg->key_len / 8;\n\t\tmac->umac_ctx = NULL;\n\t}\n\tif (macalg->truncatebits != 0)\n\t\tmac->mac_len = macalg->truncatebits / 8;\n\tmac->etm = macalg->etm;\n\treturn 0;\n}\n\nint\nmac_setup(struct sshmac *mac, char *name)\n{\n\tconst struct macalg *m;\n\n\tfor (m = macs; m->name != NULL; m++) {\n\t\tif (strcmp(name, m->name) != 0)\n\t\t\tcontinue;\n\t\tif (mac != NULL)\n\t\t\treturn mac_setup_by_alg(mac, m);\n\t\treturn 0;\n\t}\n\treturn SSH_ERR_INVALID_ARGUMENT;\n}\n\nint\nmac_init(struct sshmac *mac)\n{\n\tif (mac->key == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tswitch (mac->type) {\n\tcase SSH_DIGEST:\n\t\tif (mac->hmac_ctx == NULL ||\n\t\t ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)\n\t\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t\treturn 0;\n\tcase SSH_UMAC:\n\t\tif ((mac->umac_ctx = umac_new(mac->key)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\treturn 0;\n\tcase SSH_UMAC128:\n\t\tif ((mac->umac_ctx = umac128_new(mac->key)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\treturn 0;\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n}\n\nint\nmac_compute(struct sshmac *mac, u_int32_t seqno,\n const u_char *data, int datalen,\n u_char *digest, size_t dlen)\n{\n\tstatic union {\n\t\tu_char m[SSH_DIGEST_MAX_LENGTH];\n\t\tu_int64_t for_align;\n\t} u;\n\tu_char b[4];\n\tu_char nonce[8];\n\n\tif (mac->mac_len > sizeof(u))\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\n\tswitch (mac->type) {\n\tcase SSH_DIGEST:\n\t\tput_u32(b, seqno);\n\t\t/* reset HMAC context */\n\t\tif (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 ||\n\t\t ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 ||\n\t\t ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 ||\n\t\t ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)\n\t\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t\tbreak;\n\tcase SSH_UMAC:\n\t\tPOKE_U64(nonce, seqno);\n\t\tumac_update(mac->umac_ctx, data, datalen);\n\t\tumac_final(mac->umac_ctx, u.m, nonce);\n\t\tbreak;\n\tcase SSH_UMAC128:\n\t\tput_u64(nonce, seqno);\n\t\tumac128_update(mac->umac_ctx, data, datalen);\n\t\tumac128_final(mac->umac_ctx, u.m, nonce);\n\t\tbreak;\n\tdefault:\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\t}\n\tif (digest != NULL) {\n\t\tif (dlen > mac->mac_len)\n\t\t\tdlen = mac->mac_len;\n\t\tmemcpy(digest, u.m, dlen);\n\t}\n\treturn 0;\n}\n\nint\nmac_check(struct sshmac *mac, u_int32_t seqno,\n const u_char *data, size_t dlen,\n const u_char *theirmac, size_t mlen)\n{\n\tu_char ourmac[SSH_DIGEST_MAX_LENGTH];\n\tint r;\n\n\tif (mac->mac_len > mlen)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif ((r = mac_compute(mac, seqno, data, dlen,\n\t ourmac, sizeof(ourmac))) != 0)\n\t\treturn r;\n\tif (timingsafe_bcmp(ourmac, theirmac, mac->mac_len) != 0)\n\t\treturn SSH_ERR_MAC_INVALID;\n\treturn 0;\n}\n\nvoid\nmac_clear(struct sshmac *mac)\n{\n\tif (mac->type == SSH_UMAC) {\n\t\tif (mac->umac_ctx != NULL)\n\t\t\tumac_delete(mac->umac_ctx);\n\t} else if (mac->type == SSH_UMAC128) {\n\t\tif (mac->umac_ctx != NULL)\n\t\t\tumac128_delete(mac->umac_ctx);\n\t} else if (mac->hmac_ctx != NULL)\n\t\tssh_hmac_free(mac->hmac_ctx);\n\tmac->hmac_ctx = NULL;\n\tmac->umac_ctx = NULL;\n}\n\n/* XXX copied from ciphers_valid */\n#define\tMAC_SEP\t\",\"\nint\nmac_valid(const char *names)\n{\n\tchar *maclist, *cp, *p;\n\n\tif (names == NULL || strcmp(names, \"\") == 0)\n\t\treturn 0;\n\tif ((maclist = cp = strdup(names)) == NULL)\n\t\treturn 0;\n\tfor ((p = strsep(&cp, MAC_SEP)); p && *p != '\\0';\n\t (p = strsep(&cp, MAC_SEP))) {\n\t\tif (mac_setup(NULL, p) < 0) {\n\t\t\tfree(maclist);\n\t\t\treturn 0;\n\t\t}\n\t}\n\tfree(maclist);\n\treturn 1;\n}\n","/* $OpenBSD: uidswap.c,v 1.39 2015/06/24 01:49:19 dtucker Exp $ */\n/*\n * Author: Tatu Ylonen \n * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland\n * All rights reserved\n * Code for uid-swapping.\n *\n * As far as I am concerned, the code I have written for this software\n * can be used freely for any purpose. Any derived versions of this\n * software must be clearly marked as such, and if the derived work is\n * incompatible with the protocol description in the RFC file, it must be\n * called by a name other than \"ssh\" or \"Secure Shell\".\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n\n#include \"log.h\"\n#include \"uidswap.h\"\n#include \"xmalloc.h\"\n\n/*\n * Note: all these functions must work in all of the following cases:\n * 1. euid=0, ruid=0\n * 2. euid=0, ruid!=0\n * 3. euid!=0, ruid!=0\n * Additionally, they must work regardless of whether the system has\n * POSIX saved uids or not.\n */\n\n#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS)\n/* Lets assume that posix saved ids also work with seteuid, even though that\n is not part of the posix specification. */\n#define SAVED_IDS_WORK_WITH_SETEUID\n/* Saved effective uid. */\nstatic uid_t \tsaved_euid = 0;\nstatic gid_t\tsaved_egid = 0;\n#endif\n\n/* Saved effective uid. */\nstatic int\tprivileged = 0;\nstatic int\ttemporarily_use_uid_effective = 0;\nstatic gid_t\t*saved_egroups = NULL, *user_groups = NULL;\nstatic int\tsaved_egroupslen = -1, user_groupslen = -1;\n\n/*\n * Temporarily changes to the given uid. If the effective user\n * id is not root, this does nothing. This call cannot be nested.\n */\nvoid\ntemporarily_use_uid(struct passwd *pw)\n{\n\t/* Save the current euid, and egroups. */\n#ifdef SAVED_IDS_WORK_WITH_SETEUID\n\tsaved_euid = geteuid();\n\tsaved_egid = getegid();\n\tdebug(\"temporarily_use_uid: %u/%u (e=%u/%u)\",\n\t (u_int)pw->pw_uid, (u_int)pw->pw_gid,\n\t (u_int)saved_euid, (u_int)saved_egid);\n#ifndef HAVE_CYGWIN\n\tif (saved_euid != 0) {\n\t\tprivileged = 0;\n\t\treturn;\n\t}\n#endif\n#else\n\tif (geteuid() != 0) {\n\t\tprivileged = 0;\n\t\treturn;\n\t}\n#endif /* SAVED_IDS_WORK_WITH_SETEUID */\n\n\tprivileged = 1;\n\ttemporarily_use_uid_effective = 1;\n\n\tsaved_egroupslen = getgroups(0, NULL);\n\tif (saved_egroupslen < 0)\n\t\tfatal(\"getgroups: %.100s\", strerror(errno));\n\tif (saved_egroupslen > 0) {\n\t\tsaved_egroups = xreallocarray(saved_egroups,\n\t\t saved_egroupslen, sizeof(gid_t));\n\t\tif (getgroups(saved_egroupslen, saved_egroups) < 0)\n\t\t\tfatal(\"getgroups: %.100s\", strerror(errno));\n\t} else { /* saved_egroupslen == 0 */\n\t\tfree(saved_egroups);\n\t}\n\n\t/* set and save the user's groups */\n\tif (user_groupslen == -1) {\n\t\tif (initgroups(pw->pw_name, pw->pw_gid) < 0)\n\t\t\tfatal(\"initgroups: %s: %.100s\", pw->pw_name,\n\t\t\t strerror(errno));\n\n\t\tuser_groupslen = getgroups(0, NULL);\n\t\tif (user_groupslen < 0)\n\t\t\tfatal(\"getgroups: %.100s\", strerror(errno));\n\t\tif (user_groupslen > 0) {\n\t\t\tuser_groups = xreallocarray(user_groups,\n\t\t\t user_groupslen, sizeof(gid_t));\n\t\t\tif (getgroups(user_groupslen, user_groups) < 0)\n\t\t\t\tfatal(\"getgroups: %.100s\", strerror(errno));\n\t\t} else { /* user_groupslen == 0 */\n\t\t\tfree(user_groups);\n\t\t}\n\t}\n\t/* Set the effective uid to the given (unprivileged) uid. */\n\tif (setgroups(user_groupslen, user_groups) < 0)\n\t\tfatal(\"setgroups: %.100s\", strerror(errno));\n#ifndef SAVED_IDS_WORK_WITH_SETEUID\n\t/* Propagate the privileged gid to all of our gids. */\n\tif (setgid(getegid()) < 0)\n\t\tdebug(\"setgid %u: %.100s\", (u_int) getegid(), strerror(errno));\n\t/* Propagate the privileged uid to all of our uids. */\n\tif (setuid(geteuid()) < 0)\n\t\tdebug(\"setuid %u: %.100s\", (u_int) geteuid(), strerror(errno));\n#endif /* SAVED_IDS_WORK_WITH_SETEUID */\n\tif (setegid(pw->pw_gid) < 0)\n\t\tfatal(\"setegid %u: %.100s\", (u_int)pw->pw_gid,\n\t\t strerror(errno));\n\tif (seteuid(pw->pw_uid) == -1)\n\t\tfatal(\"seteuid %u: %.100s\", (u_int)pw->pw_uid,\n\t\t strerror(errno));\n}\n\nvoid\npermanently_drop_suid(uid_t uid)\n{\n#ifndef NO_UID_RESTORATION_TEST\n\tuid_t old_uid = getuid();\n#endif\n\n\tdebug(\"permanently_drop_suid: %u\", (u_int)uid);\n\tif (setresuid(uid, uid, uid) < 0)\n\t\tfatal(\"setresuid %u: %.100s\", (u_int)uid, strerror(errno));\n\n#ifndef NO_UID_RESTORATION_TEST\n\t/*\n\t * Try restoration of UID if changed (test clearing of saved uid).\n\t *\n\t * Note that we don't do this on Cygwin, or on Solaris-based platforms\n\t * where fine-grained privileges are available (the user might be\n\t * deliberately allowed the right to setuid back to root).\n\t */\n\tif (old_uid != uid &&\n\t (setuid(old_uid) != -1 || seteuid(old_uid) != -1))\n\t\tfatal(\"%s: was able to restore old [e]uid\", __func__);\n#endif\n\n\t/* Verify UID drop was successful */\n\tif (getuid() != uid || geteuid() != uid) {\n\t\tfatal(\"%s: euid incorrect uid:%u euid:%u (should be %u)\",\n\t\t __func__, (u_int)getuid(), (u_int)geteuid(), (u_int)uid);\n\t}\n}\n\n/*\n * Restores to the original (privileged) uid.\n */\nvoid\nrestore_uid(void)\n{\n\t/* it's a no-op unless privileged */\n\tif (!privileged) {\n\t\tdebug(\"restore_uid: (unprivileged)\");\n\t\treturn;\n\t}\n\tif (!temporarily_use_uid_effective)\n\t\tfatal(\"restore_uid: temporarily_use_uid not effective\");\n\n#ifdef SAVED_IDS_WORK_WITH_SETEUID\n\tdebug(\"restore_uid: %u/%u\", (u_int)saved_euid, (u_int)saved_egid);\n\t/* Set the effective uid back to the saved privileged uid. */\n\tif (seteuid(saved_euid) < 0)\n\t\tfatal(\"seteuid %u: %.100s\", (u_int)saved_euid, strerror(errno));\n\tif (setegid(saved_egid) < 0)\n\t\tfatal(\"setegid %u: %.100s\", (u_int)saved_egid, strerror(errno));\n#else /* SAVED_IDS_WORK_WITH_SETEUID */\n\t/*\n\t * We are unable to restore the real uid to its unprivileged value.\n\t * Propagate the real uid (usually more privileged) to effective uid\n\t * as well.\n\t */\n\tsetuid(getuid());\n\tsetgid(getgid());\n#endif /* SAVED_IDS_WORK_WITH_SETEUID */\n\n\tif (setgroups(saved_egroupslen, saved_egroups) < 0)\n\t\tfatal(\"setgroups: %.100s\", strerror(errno));\n\ttemporarily_use_uid_effective = 0;\n}\n\n/*\n * Permanently sets all uids to the given uid. This cannot be\n * called while temporarily_use_uid is effective.\n */\nvoid\npermanently_set_uid(struct passwd *pw)\n{\n#ifndef NO_UID_RESTORATION_TEST\n\tuid_t old_uid = getuid();\n\tgid_t old_gid = getgid();\n#endif\n\n\tif (pw == NULL)\n\t\tfatal(\"permanently_set_uid: no user given\");\n\tif (temporarily_use_uid_effective)\n\t\tfatal(\"permanently_set_uid: temporarily_use_uid effective\");\n\tdebug(\"permanently_set_uid: %u/%u\", (u_int)pw->pw_uid,\n\t (u_int)pw->pw_gid);\n\n\tif (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0)\n\t\tfatal(\"setresgid %u: %.100s\", (u_int)pw->pw_gid, strerror(errno));\n\n#ifdef __APPLE__\n\t/*\n\t * OS X requires initgroups after setgid to opt back into\n\t * memberd support for >16 supplemental groups.\n\t */\n\tif (initgroups(pw->pw_name, pw->pw_gid) < 0)\n\t\tfatal(\"initgroups %.100s %u: %.100s\",\n\t\t pw->pw_name, (u_int)pw->pw_gid, strerror(errno));\n#endif\n\n\tif (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0)\n\t\tfatal(\"setresuid %u: %.100s\", (u_int)pw->pw_uid, strerror(errno));\n\n#ifndef NO_UID_RESTORATION_TEST\n\t/* Try restoration of GID if changed (test clearing of saved gid) */\n\tif (old_gid != pw->pw_gid && pw->pw_uid != 0 &&\n\t (setgid(old_gid) != -1 || setegid(old_gid) != -1))\n\t\tfatal(\"%s: was able to restore old [e]gid\", __func__);\n#endif\n\n\t/* Verify GID drop was successful */\n\tif (getgid() != pw->pw_gid || getegid() != pw->pw_gid) {\n\t\tfatal(\"%s: egid incorrect gid:%u egid:%u (should be %u)\",\n\t\t __func__, (u_int)getgid(), (u_int)getegid(),\n\t\t (u_int)pw->pw_gid);\n\t}\n\n#ifndef NO_UID_RESTORATION_TEST\n\t/* Try restoration of UID if changed (test clearing of saved uid) */\n\tif (old_uid != pw->pw_uid &&\n\t (setuid(old_uid) != -1 || seteuid(old_uid) != -1))\n\t\tfatal(\"%s: was able to restore old [e]uid\", __func__);\n#endif\n\n\t/* Verify UID drop was successful */\n\tif (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) {\n\t\tfatal(\"%s: euid incorrect uid:%u euid:%u (should be %u)\",\n\t\t __func__, (u_int)getuid(), (u_int)geteuid(),\n\t\t (u_int)pw->pw_uid);\n\t}\n}\n","/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 dtucker Exp $ */\n/*\n * Copyright (c) 2000 Markus Friedl. All rights reserved.\n * Copyright (c) 2005,2006 Damien Miller. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#ifdef HAVE_PATHS_H\n# include \n#include \n#endif\n#ifdef SSH_TUN_OPENBSD\n#include \n#endif\n\n#include \"xmalloc.h\"\n#include \"misc.h\"\n#include \"log.h\"\n#include \"ssh.h\"\n\n/* remove newline at end of string */\nchar *\nchop(char *s)\n{\n\tchar *t = s;\n\twhile (*t) {\n\t\tif (*t == '\\n' || *t == '\\r') {\n\t\t\t*t = '\\0';\n\t\t\treturn s;\n\t\t}\n\t\tt++;\n\t}\n\treturn s;\n\n}\n\n/* set/unset filedescriptor to non-blocking */\nint\nset_nonblock(int fd)\n{\n\tint val;\n\n\tval = fcntl(fd, F_GETFL);\n\tif (val < 0) {\n\t\terror(\"fcntl(%d, F_GETFL): %s\", fd, strerror(errno));\n\t\treturn (-1);\n\t}\n\tif (val & O_NONBLOCK) {\n\t\tdebug3(\"fd %d is O_NONBLOCK\", fd);\n\t\treturn (0);\n\t}\n\tdebug2(\"fd %d setting O_NONBLOCK\", fd);\n\tval |= O_NONBLOCK;\n\tif (fcntl(fd, F_SETFL, val) == -1) {\n\t\tdebug(\"fcntl(%d, F_SETFL, O_NONBLOCK): %s\", fd,\n\t\t strerror(errno));\n\t\treturn (-1);\n\t}\n\treturn (0);\n}\n\nint\nunset_nonblock(int fd)\n{\n\tint val;\n\n\tval = fcntl(fd, F_GETFL);\n\tif (val < 0) {\n\t\terror(\"fcntl(%d, F_GETFL): %s\", fd, strerror(errno));\n\t\treturn (-1);\n\t}\n\tif (!(val & O_NONBLOCK)) {\n\t\tdebug3(\"fd %d is not O_NONBLOCK\", fd);\n\t\treturn (0);\n\t}\n\tdebug(\"fd %d clearing O_NONBLOCK\", fd);\n\tval &= ~O_NONBLOCK;\n\tif (fcntl(fd, F_SETFL, val) == -1) {\n\t\tdebug(\"fcntl(%d, F_SETFL, ~O_NONBLOCK): %s\",\n\t\t fd, strerror(errno));\n\t\treturn (-1);\n\t}\n\treturn (0);\n}\n\nconst char *\nssh_gai_strerror(int gaierr)\n{\n\tif (gaierr == EAI_SYSTEM && errno != 0)\n\t\treturn strerror(errno);\n\treturn gai_strerror(gaierr);\n}\n\n/* disable nagle on socket */\nvoid\nset_nodelay(int fd)\n{\n\tint opt;\n\tsocklen_t optlen;\n\n\toptlen = sizeof opt;\n\tif (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {\n\t\tdebug(\"getsockopt TCP_NODELAY: %.100s\", strerror(errno));\n\t\treturn;\n\t}\n\tif (opt == 1) {\n\t\tdebug2(\"fd %d is TCP_NODELAY\", fd);\n\t\treturn;\n\t}\n\topt = 1;\n\tdebug2(\"fd %d setting TCP_NODELAY\", fd);\n\tif (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)\n\t\terror(\"setsockopt TCP_NODELAY: %.100s\", strerror(errno));\n}\n\n/* Characters considered whitespace in strsep calls. */\n#define WHITESPACE \" \\t\\r\\n\"\n#define QUOTE\t\"\\\"\"\n\n/* return next token in configuration line */\nchar *\nstrdelim(char **s)\n{\n\tchar *old;\n\tint wspace = 0;\n\n\tif (*s == NULL)\n\t\treturn NULL;\n\n\told = *s;\n\n\t*s = strpbrk(*s, WHITESPACE QUOTE \"=\");\n\tif (*s == NULL)\n\t\treturn (old);\n\n\tif (*s[0] == '\\\"') {\n\t\tmemmove(*s, *s + 1, strlen(*s)); /* move nul too */\n\t\t/* Find matching quote */\n\t\tif ((*s = strpbrk(*s, QUOTE)) == NULL) {\n\t\t\treturn (NULL);\t\t/* no matching quote */\n\t\t} else {\n\t\t\t*s[0] = '\\0';\n\t\t\t*s += strspn(*s + 1, WHITESPACE) + 1;\n\t\t\treturn (old);\n\t\t}\n\t}\n\n\t/* Allow only one '=' to be skipped */\n\tif (*s[0] == '=')\n\t\twspace = 1;\n\t*s[0] = '\\0';\n\n\t/* Skip any extra whitespace after first token */\n\t*s += strspn(*s + 1, WHITESPACE) + 1;\n\tif (*s[0] == '=' && !wspace)\n\t\t*s += strspn(*s + 1, WHITESPACE) + 1;\n\n\treturn (old);\n}\n\nstruct passwd *\npwcopy(struct passwd *pw)\n{\n\tstruct passwd *copy = xcalloc(1, sizeof(*copy));\n\n\tcopy->pw_name = xstrdup(pw->pw_name);\n\tcopy->pw_passwd = xstrdup(pw->pw_passwd);\n#ifdef HAVE_STRUCT_PASSWD_PW_GECOS\n\tcopy->pw_gecos = xstrdup(pw->pw_gecos);\n#endif\n\tcopy->pw_uid = pw->pw_uid;\n\tcopy->pw_gid = pw->pw_gid;\n#ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE\n\tcopy->pw_expire = pw->pw_expire;\n#endif\n#ifdef HAVE_STRUCT_PASSWD_PW_CHANGE\n\tcopy->pw_change = pw->pw_change;\n#endif\n#ifdef HAVE_STRUCT_PASSWD_PW_CLASS\n\tcopy->pw_class = xstrdup(pw->pw_class);\n#endif\n\tcopy->pw_dir = xstrdup(pw->pw_dir);\n\tcopy->pw_shell = xstrdup(pw->pw_shell);\n\treturn copy;\n}\n\n/*\n * Convert ASCII string to TCP/IP port number.\n * Port must be >=0 and <=65535.\n * Return -1 if invalid.\n */\nint\na2port(const char *s)\n{\n\tlong long port;\n\tconst char *errstr;\n\n\tport = strtonum(s, 0, 65535, &errstr);\n\tif (errstr != NULL)\n\t\treturn -1;\n\treturn (int)port;\n}\n\nint\na2tun(const char *s, int *remote)\n{\n\tconst char *errstr = NULL;\n\tchar *sp, *ep;\n\tint tun;\n\n\tif (remote != NULL) {\n\t\t*remote = SSH_TUNID_ANY;\n\t\tsp = xstrdup(s);\n\t\tif ((ep = strchr(sp, ':')) == NULL) {\n\t\t\tfree(sp);\n\t\t\treturn (a2tun(s, NULL));\n\t\t}\n\t\tep[0] = '\\0'; ep++;\n\t\t*remote = a2tun(ep, NULL);\n\t\ttun = a2tun(sp, NULL);\n\t\tfree(sp);\n\t\treturn (*remote == SSH_TUNID_ERR ? *remote : tun);\n\t}\n\n\tif (strcasecmp(s, \"any\") == 0)\n\t\treturn (SSH_TUNID_ANY);\n\n\ttun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);\n\tif (errstr != NULL)\n\t\treturn (SSH_TUNID_ERR);\n\n\treturn (tun);\n}\n\n#define SECONDS\t\t1\n#define MINUTES\t\t(SECONDS * 60)\n#define HOURS\t\t(MINUTES * 60)\n#define DAYS\t\t(HOURS * 24)\n#define WEEKS\t\t(DAYS * 7)\n\n/*\n * Convert a time string into seconds; format is\n * a sequence of:\n * time[qualifier]\n *\n * Valid time qualifiers are:\n * seconds\n * s|S seconds\n * m|M minutes\n * h|H hours\n * d|D days\n * w|W weeks\n *\n * Examples:\n * 90m 90 minutes\n * 1h30m 90 minutes\n * 2d 2 days\n * 1w 1 week\n *\n * Return -1 if time string is invalid.\n */\nlong\nconvtime(const char *s)\n{\n\tlong total, secs, multiplier = 1;\n\tconst char *p;\n\tchar *endp;\n\n\terrno = 0;\n\ttotal = 0;\n\tp = s;\n\n\tif (p == NULL || *p == '\\0')\n\t\treturn -1;\n\n\twhile (*p) {\n\t\tsecs = strtol(p, &endp, 10);\n\t\tif (p == endp ||\n\t\t (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||\n\t\t secs < 0)\n\t\t\treturn -1;\n\n\t\tswitch (*endp++) {\n\t\tcase '\\0':\n\t\t\tendp--;\n\t\t\tbreak;\n\t\tcase 's':\n\t\tcase 'S':\n\t\t\tbreak;\n\t\tcase 'm':\n\t\tcase 'M':\n\t\t\tmultiplier = MINUTES;\n\t\t\tbreak;\n\t\tcase 'h':\n\t\tcase 'H':\n\t\t\tmultiplier = HOURS;\n\t\t\tbreak;\n\t\tcase 'd':\n\t\tcase 'D':\n\t\t\tmultiplier = DAYS;\n\t\t\tbreak;\n\t\tcase 'w':\n\t\tcase 'W':\n\t\t\tmultiplier = WEEKS;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn -1;\n\t\t}\n\t\tif (secs >= LONG_MAX / multiplier)\n\t\t\treturn -1;\n\t\tsecs *= multiplier;\n\t\tif (total >= LONG_MAX - secs)\n\t\t\treturn -1;\n\t\ttotal += secs;\n\t\tif (total < 0)\n\t\t\treturn -1;\n\t\tp = endp;\n\t}\n\n\treturn total;\n}\n\n/*\n * Returns a standardized host+port identifier string.\n * Caller must free returned string.\n */\nchar *\nput_host_port(const char *host, u_short port)\n{\n\tchar *hoststr;\n\n\tif (port == 0 || port == SSH_DEFAULT_PORT)\n\t\treturn(xstrdup(host));\n\tif (asprintf(&hoststr, \"[%s]:%d\", host, (int)port) < 0)\n\t\tfatal(\"put_host_port: asprintf: %s\", strerror(errno));\n\tdebug3(\"put_host_port: %s\", hoststr);\n\treturn hoststr;\n}\n\n/*\n * Search for next delimiter between hostnames/addresses and ports.\n * Argument may be modified (for termination).\n * Returns *cp if parsing succeeds.\n * *cp is set to the start of the next delimiter, if one was found.\n * If this is the last field, *cp is set to NULL.\n */\nchar *\nhpdelim(char **cp)\n{\n\tchar *s, *old;\n\n\tif (cp == NULL || *cp == NULL)\n\t\treturn NULL;\n\n\told = s = *cp;\n\tif (*s == '[') {\n\t\tif ((s = strchr(s, ']')) == NULL)\n\t\t\treturn NULL;\n\t\telse\n\t\t\ts++;\n\t} else if ((s = strpbrk(s, \":/\")) == NULL)\n\t\ts = *cp + strlen(*cp); /* skip to end (see first case below) */\n\n\tswitch (*s) {\n\tcase '\\0':\n\t\t*cp = NULL;\t/* no more fields*/\n\t\tbreak;\n\n\tcase ':':\n\tcase '/':\n\t\t*s = '\\0';\t/* terminate */\n\t\t*cp = s + 1;\n\t\tbreak;\n\n\tdefault:\n\t\treturn NULL;\n\t}\n\n\treturn old;\n}\n\nchar *\ncleanhostname(char *host)\n{\n\tif (*host == '[' && host[strlen(host) - 1] == ']') {\n\t\thost[strlen(host) - 1] = '\\0';\n\t\treturn (host + 1);\n\t} else\n\t\treturn host;\n}\n\nchar *\ncolon(char *cp)\n{\n\tint flag = 0;\n\n\tif (*cp == ':')\t\t/* Leading colon is part of file name. */\n\t\treturn NULL;\n\tif (*cp == '[')\n\t\tflag = 1;\n\n\tfor (; *cp; ++cp) {\n\t\tif (*cp == '@' && *(cp+1) == '[')\n\t\t\tflag = 1;\n\t\tif (*cp == ']' && *(cp+1) == ':' && flag)\n\t\t\treturn (cp+1);\n\t\tif (*cp == ':' && !flag)\n\t\t\treturn (cp);\n\t\tif (*cp == '/')\n\t\t\treturn NULL;\n\t}\n\treturn NULL;\n}\n\n/*\n * Parse a [user@]host[:port] string.\n * Caller must free returned user and host.\n * Any of the pointer return arguments may be NULL (useful for syntax checking).\n * If user was not specified then *userp will be set to NULL.\n * If port was not specified then *portp will be -1.\n * Returns 0 on success, -1 on failure.\n */\nint\nparse_user_host_port(const char *s, char **userp, char **hostp, int *portp)\n{\n\tchar *sdup, *cp, *tmp;\n\tchar *user = NULL, *host = NULL;\n\tint port = -1, ret = -1;\n\n\tif (userp != NULL)\n\t\t*userp = NULL;\n\tif (hostp != NULL)\n\t\t*hostp = NULL;\n\tif (portp != NULL)\n\t\t*portp = -1;\n\n\tif ((sdup = tmp = strdup(s)) == NULL)\n\t\treturn -1;\n\t/* Extract optional username */\n\tif ((cp = strchr(tmp, '@')) != NULL) {\n\t\t*cp = '\\0';\n\t\tif (*tmp == '\\0')\n\t\t\tgoto out;\n\t\tif ((user = strdup(tmp)) == NULL)\n\t\t\tgoto out;\n\t\ttmp = cp + 1;\n\t}\n\t/* Extract mandatory hostname */\n\tif ((cp = hpdelim(&tmp)) == NULL || *cp == '\\0')\n\t\tgoto out;\n\thost = xstrdup(cleanhostname(cp));\n\t/* Convert and verify optional port */\n\tif (tmp != NULL && *tmp != '\\0') {\n\t\tif ((port = a2port(tmp)) <= 0)\n\t\t\tgoto out;\n\t}\n\t/* Success */\n\tif (userp != NULL) {\n\t\t*userp = user;\n\t\tuser = NULL;\n\t}\n\tif (hostp != NULL) {\n\t\t*hostp = host;\n\t\thost = NULL;\n\t}\n\tif (portp != NULL)\n\t\t*portp = port;\n\tret = 0;\n out:\n\tfree(sdup);\n\tfree(user);\n\tfree(host);\n\treturn ret;\n}\n\n/* function to assist building execv() arguments */\nvoid\naddargs(arglist *args, char *fmt, ...)\n{\n\tva_list ap;\n\tchar *cp;\n\tu_int nalloc;\n\tint r;\n\n\tva_start(ap, fmt);\n\tr = vasprintf(&cp, fmt, ap);\n\tva_end(ap);\n\tif (r == -1)\n\t\tfatal(\"addargs: argument too long\");\n\n\tnalloc = args->nalloc;\n\tif (args->list == NULL) {\n\t\tnalloc = 32;\n\t\targs->num = 0;\n\t} else if (args->num+2 >= nalloc)\n\t\tnalloc *= 2;\n\n\targs->list = xreallocarray(args->list, nalloc, sizeof(char *));\n\targs->nalloc = nalloc;\n\targs->list[args->num++] = cp;\n\targs->list[args->num] = NULL;\n}\n\nvoid\nreplacearg(arglist *args, u_int which, char *fmt, ...)\n{\n\tva_list ap;\n\tchar *cp;\n\tint r;\n\n\tva_start(ap, fmt);\n\tr = vasprintf(&cp, fmt, ap);\n\tva_end(ap);\n\tif (r == -1)\n\t\tfatal(\"replacearg: argument too long\");\n\n\tif (which >= args->num)\n\t\tfatal(\"replacearg: tried to replace invalid arg %d >= %d\",\n\t\t which, args->num);\n\tfree(args->list[which]);\n\targs->list[which] = cp;\n}\n\nvoid\nfreeargs(arglist *args)\n{\n\tu_int i;\n\n\tif (args->list != NULL) {\n\t\tfor (i = 0; i < args->num; i++)\n\t\t\tfree(args->list[i]);\n\t\tfree(args->list);\n\t\targs->nalloc = args->num = 0;\n\t\targs->list = NULL;\n\t}\n}\n\n/*\n * Expands tildes in the file name. Returns data allocated by xmalloc.\n * Warning: this calls getpw*.\n */\nchar *\ntilde_expand_filename(const char *filename, uid_t uid)\n{\n\tconst char *path, *sep;\n\tchar user[128], *ret;\n\tstruct passwd *pw;\n\tu_int len, slash;\n\n\tif (*filename != '~')\n\t\treturn (xstrdup(filename));\n\tfilename++;\n\n\tpath = strchr(filename, '/');\n\tif (path != NULL && path > filename) {\t\t/* ~user/path */\n\t\tslash = path - filename;\n\t\tif (slash > sizeof(user) - 1)\n\t\t\tfatal(\"tilde_expand_filename: ~username too long\");\n\t\tmemcpy(user, filename, slash);\n\t\tuser[slash] = '\\0';\n\t\tif ((pw = getpwnam(user)) == NULL)\n\t\t\tfatal(\"tilde_expand_filename: No such user %s\", user);\n\t} else if ((pw = getpwuid(uid)) == NULL)\t/* ~/path */\n\t\tfatal(\"tilde_expand_filename: No such uid %ld\", (long)uid);\n\n\t/* Make sure directory has a trailing '/' */\n\tlen = strlen(pw->pw_dir);\n\tif (len == 0 || pw->pw_dir[len - 1] != '/')\n\t\tsep = \"/\";\n\telse\n\t\tsep = \"\";\n\n\t/* Skip leading '/' from specified path */\n\tif (path != NULL)\n\t\tfilename = path + 1;\n\n\tif (xasprintf(&ret, \"%s%s%s\", pw->pw_dir, sep, filename) >= PATH_MAX)\n\t\tfatal(\"tilde_expand_filename: Path too long\");\n\n\treturn (ret);\n}\n\n/*\n * Expand a string with a set of %[char] escapes. A number of escapes may be\n * specified as (char *escape_chars, char *replacement) pairs. The list must\n * be terminated by a NULL escape_char. Returns replaced string in memory\n * allocated by xmalloc.\n */\nchar *\npercent_expand(const char *string, ...)\n{\n#define EXPAND_MAX_KEYS\t16\n\tu_int num_keys, i, j;\n\tstruct {\n\t\tconst char *key;\n\t\tconst char *repl;\n\t} keys[EXPAND_MAX_KEYS];\n\tchar buf[4096];\n\tva_list ap;\n\n\t/* Gather keys */\n\tva_start(ap, string);\n\tfor (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {\n\t\tkeys[num_keys].key = va_arg(ap, char *);\n\t\tif (keys[num_keys].key == NULL)\n\t\t\tbreak;\n\t\tkeys[num_keys].repl = va_arg(ap, char *);\n\t\tif (keys[num_keys].repl == NULL)\n\t\t\tfatal(\"%s: NULL replacement\", __func__);\n\t}\n\tif (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)\n\t\tfatal(\"%s: too many keys\", __func__);\n\tva_end(ap);\n\n\t/* Expand string */\n\t*buf = '\\0';\n\tfor (i = 0; *string != '\\0'; string++) {\n\t\tif (*string != '%') {\n append:\n\t\t\tbuf[i++] = *string;\n\t\t\tif (i >= sizeof(buf))\n\t\t\t\tfatal(\"%s: string too long\", __func__);\n\t\t\tbuf[i] = '\\0';\n\t\t\tcontinue;\n\t\t}\n\t\tstring++;\n\t\t/* %% case */\n\t\tif (*string == '%')\n\t\t\tgoto append;\n\t\tif (*string == '\\0')\n\t\t\tfatal(\"%s: invalid format\", __func__);\n\t\tfor (j = 0; j < num_keys; j++) {\n\t\t\tif (strchr(keys[j].key, *string) != NULL) {\n\t\t\t\ti = strlcat(buf, keys[j].repl, sizeof(buf));\n\t\t\t\tif (i >= sizeof(buf))\n\t\t\t\t\tfatal(\"%s: string too long\", __func__);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (j >= num_keys)\n\t\t\tfatal(\"%s: unknown key %%%c\", __func__, *string);\n\t}\n\treturn (xstrdup(buf));\n#undef EXPAND_MAX_KEYS\n}\n\n/*\n * Read an entire line from a public key file into a static buffer, discarding\n * lines that exceed the buffer size. Returns 0 on success, -1 on failure.\n */\nint\nread_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,\n u_long *lineno)\n{\n\twhile (fgets(buf, bufsz, f) != NULL) {\n\t\tif (buf[0] == '\\0')\n\t\t\tcontinue;\n\t\t(*lineno)++;\n\t\tif (buf[strlen(buf) - 1] == '\\n' || feof(f)) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\tdebug(\"%s: %s line %lu exceeds size limit\", __func__,\n\t\t\t filename, *lineno);\n\t\t\t/* discard remainder of line */\n\t\t\twhile (fgetc(f) != '\\n' && !feof(f))\n\t\t\t\t;\t/* nothing */\n\t\t}\n\t}\n\treturn -1;\n}\n\nint\ntun_open(int tun, int mode)\n{\n#if defined(CUSTOM_SYS_TUN_OPEN)\n\treturn (sys_tun_open(tun, mode));\n#elif defined(SSH_TUN_OPENBSD)\n\tstruct ifreq ifr;\n\tchar name[100];\n\tint fd = -1, sock;\n\tconst char *tunbase = \"tun\";\n\n\tif (mode == SSH_TUNMODE_ETHERNET)\n\t\ttunbase = \"tap\";\n\n\t/* Open the tunnel device */\n\tif (tun <= SSH_TUNID_MAX) {\n\t\tsnprintf(name, sizeof(name), \"/dev/%s%d\", tunbase, tun);\n\t\tfd = open(name, O_RDWR);\n\t} else if (tun == SSH_TUNID_ANY) {\n\t\tfor (tun = 100; tun >= 0; tun--) {\n\t\t\tsnprintf(name, sizeof(name), \"/dev/%s%d\",\n\t\t\t tunbase, tun);\n\t\t\tif ((fd = open(name, O_RDWR)) >= 0)\n\t\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tdebug(\"%s: invalid tunnel %u\", __func__, tun);\n\t\treturn -1;\n\t}\n\n\tif (fd < 0) {\n\t\tdebug(\"%s: %s open: %s\", __func__, name, strerror(errno));\n\t\treturn -1;\n\t}\n\n\tdebug(\"%s: %s mode %d fd %d\", __func__, name, mode, fd);\n\n\t/* Bring interface up if it is not already */\n\tsnprintf(ifr.ifr_name, sizeof(ifr.ifr_name), \"%s%d\", tunbase, tun);\n\tif ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)\n\t\tgoto failed;\n\n\tif (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {\n\t\tdebug(\"%s: get interface %s flags: %s\", __func__,\n\t\t ifr.ifr_name, strerror(errno));\n\t\tgoto failed;\n\t}\n\n\tif (!(ifr.ifr_flags & IFF_UP)) {\n\t\tifr.ifr_flags |= IFF_UP;\n\t\tif (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {\n\t\t\tdebug(\"%s: activate interface %s: %s\", __func__,\n\t\t\t ifr.ifr_name, strerror(errno));\n\t\t\tgoto failed;\n\t\t}\n\t}\n\n\tclose(sock);\n\treturn fd;\n\n failed:\n\tif (fd >= 0)\n\t\tclose(fd);\n\tif (sock >= 0)\n\t\tclose(sock);\n\treturn -1;\n#else\n\terror(\"Tunnel interfaces are not supported on this platform\");\n\treturn (-1);\n#endif\n}\n\nvoid\nsanitise_stdfd(void)\n{\n\tint nullfd, dupfd;\n\n\tif ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {\n\t\tfprintf(stderr, \"Couldn't open /dev/null: %s\\n\",\n\t\t strerror(errno));\n\t\texit(1);\n\t}\n\twhile (++dupfd <= STDERR_FILENO) {\n\t\t/* Only populate closed fds. */\n\t\tif (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {\n\t\t\tif (dup2(nullfd, dupfd) == -1) {\n\t\t\t\tfprintf(stderr, \"dup2: %s\\n\", strerror(errno));\n\t\t\t\texit(1);\n\t\t\t}\n\t\t}\n\t}\n\tif (nullfd > STDERR_FILENO)\n\t\tclose(nullfd);\n}\n\nchar *\ntohex(const void *vp, size_t l)\n{\n\tconst u_char *p = (const u_char *)vp;\n\tchar b[3], *r;\n\tsize_t i, hl;\n\n\tif (l > 65536)\n\t\treturn xstrdup(\"tohex: length > 65536\");\n\n\thl = l * 2 + 1;\n\tr = xcalloc(1, hl);\n\tfor (i = 0; i < l; i++) {\n\t\tsnprintf(b, sizeof(b), \"%02x\", p[i]);\n\t\tstrlcat(r, b, hl);\n\t}\n\treturn (r);\n}\n\nu_int64_t\nget_u64(const void *vp)\n{\n\tconst u_char *p = (const u_char *)vp;\n\tu_int64_t v;\n\n\tv = (u_int64_t)p[0] << 56;\n\tv |= (u_int64_t)p[1] << 48;\n\tv |= (u_int64_t)p[2] << 40;\n\tv |= (u_int64_t)p[3] << 32;\n\tv |= (u_int64_t)p[4] << 24;\n\tv |= (u_int64_t)p[5] << 16;\n\tv |= (u_int64_t)p[6] << 8;\n\tv |= (u_int64_t)p[7];\n\n\treturn (v);\n}\n\nu_int32_t\nget_u32(const void *vp)\n{\n\tconst u_char *p = (const u_char *)vp;\n\tu_int32_t v;\n\n\tv = (u_int32_t)p[0] << 24;\n\tv |= (u_int32_t)p[1] << 16;\n\tv |= (u_int32_t)p[2] << 8;\n\tv |= (u_int32_t)p[3];\n\n\treturn (v);\n}\n\nu_int32_t\nget_u32_le(const void *vp)\n{\n\tconst u_char *p = (const u_char *)vp;\n\tu_int32_t v;\n\n\tv = (u_int32_t)p[0];\n\tv |= (u_int32_t)p[1] << 8;\n\tv |= (u_int32_t)p[2] << 16;\n\tv |= (u_int32_t)p[3] << 24;\n\n\treturn (v);\n}\n\nu_int16_t\nget_u16(const void *vp)\n{\n\tconst u_char *p = (const u_char *)vp;\n\tu_int16_t v;\n\n\tv = (u_int16_t)p[0] << 8;\n\tv |= (u_int16_t)p[1];\n\n\treturn (v);\n}\n\nvoid\nput_u64(void *vp, u_int64_t v)\n{\n\tu_char *p = (u_char *)vp;\n\n\tp[0] = (u_char)(v >> 56) & 0xff;\n\tp[1] = (u_char)(v >> 48) & 0xff;\n\tp[2] = (u_char)(v >> 40) & 0xff;\n\tp[3] = (u_char)(v >> 32) & 0xff;\n\tp[4] = (u_char)(v >> 24) & 0xff;\n\tp[5] = (u_char)(v >> 16) & 0xff;\n\tp[6] = (u_char)(v >> 8) & 0xff;\n\tp[7] = (u_char)v & 0xff;\n}\n\nvoid\nput_u32(void *vp, u_int32_t v)\n{\n\tu_char *p = (u_char *)vp;\n\n\tp[0] = (u_char)(v >> 24) & 0xff;\n\tp[1] = (u_char)(v >> 16) & 0xff;\n\tp[2] = (u_char)(v >> 8) & 0xff;\n\tp[3] = (u_char)v & 0xff;\n}\n\nvoid\nput_u32_le(void *vp, u_int32_t v)\n{\n\tu_char *p = (u_char *)vp;\n\n\tp[0] = (u_char)v & 0xff;\n\tp[1] = (u_char)(v >> 8) & 0xff;\n\tp[2] = (u_char)(v >> 16) & 0xff;\n\tp[3] = (u_char)(v >> 24) & 0xff;\n}\n\nvoid\nput_u16(void *vp, u_int16_t v)\n{\n\tu_char *p = (u_char *)vp;\n\n\tp[0] = (u_char)(v >> 8) & 0xff;\n\tp[1] = (u_char)v & 0xff;\n}\n\nvoid\nms_subtract_diff(struct timeval *start, int *ms)\n{\n\tstruct timeval diff, finish;\n\n\tgettimeofday(&finish, NULL);\n\ttimersub(&finish, start, &diff);\t\n\t*ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);\n}\n\nvoid\nms_to_timeval(struct timeval *tv, int ms)\n{\n\tif (ms < 0)\n\t\tms = 0;\n\ttv->tv_sec = ms / 1000;\n\ttv->tv_usec = (ms % 1000) * 1000;\n}\n\ntime_t\nmonotime(void)\n{\n#if defined(HAVE_CLOCK_GETTIME) && \\\n (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME))\n\tstruct timespec ts;\n\tstatic int gettime_failed = 0;\n\n\tif (!gettime_failed) {\n#if defined(CLOCK_BOOTTIME)\n\t\tif (clock_gettime(CLOCK_BOOTTIME, &ts) == 0)\n\t\t\treturn (ts.tv_sec);\n#endif\n#if defined(CLOCK_MONOTONIC)\n\t\tif (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)\n\t\t\treturn (ts.tv_sec);\n#endif\n\t\tdebug3(\"clock_gettime: %s\", strerror(errno));\n\t\tgettime_failed = 1;\n\t}\n#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */\n\n\treturn time(NULL);\n}\n\ndouble\nmonotime_double(void)\n{\n#if defined(HAVE_CLOCK_GETTIME) && \\\n (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME))\n\tstruct timespec ts;\n\tstatic int gettime_failed = 0;\n\n\tif (!gettime_failed) {\n#if defined(CLOCK_BOOTTIME)\n\t\tif (clock_gettime(CLOCK_BOOTTIME, &ts) == 0)\n\t\t\treturn (ts.tv_sec + (double)ts.tv_nsec / 1000000000);\n#endif\n#if defined(CLOCK_MONOTONIC)\n\t\tif (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)\n\t\t\treturn (ts.tv_sec + (double)ts.tv_nsec / 1000000000);\n#endif\n\t\tdebug3(\"clock_gettime: %s\", strerror(errno));\n\t\tgettime_failed = 1;\n\t}\n#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */\n\n\treturn (double)time(NULL);\n}\n\nvoid\nbandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)\n{\n\tbw->buflen = buflen;\n\tbw->rate = kbps;\n\tbw->thresh = bw->rate;\n\tbw->lamt = 0;\n\ttimerclear(&bw->bwstart);\n\ttimerclear(&bw->bwend);\n}\t\n\n/* Callback from read/write loop to insert bandwidth-limiting delays */\nvoid\nbandwidth_limit(struct bwlimit *bw, size_t read_len)\n{\n\tu_int64_t waitlen;\n\tstruct timespec ts, rm;\n\n\tif (!timerisset(&bw->bwstart)) {\n\t\tgettimeofday(&bw->bwstart, NULL);\n\t\treturn;\n\t}\n\n\tbw->lamt += read_len;\n\tif (bw->lamt < bw->thresh)\n\t\treturn;\n\n\tgettimeofday(&bw->bwend, NULL);\n\ttimersub(&bw->bwend, &bw->bwstart, &bw->bwend);\n\tif (!timerisset(&bw->bwend))\n\t\treturn;\n\n\tbw->lamt *= 8;\n\twaitlen = (double)1000000L * bw->lamt / bw->rate;\n\n\tbw->bwstart.tv_sec = waitlen / 1000000L;\n\tbw->bwstart.tv_usec = waitlen % 1000000L;\n\n\tif (timercmp(&bw->bwstart, &bw->bwend, >)) {\n\t\ttimersub(&bw->bwstart, &bw->bwend, &bw->bwend);\n\n\t\t/* Adjust the wait time */\n\t\tif (bw->bwend.tv_sec) {\n\t\t\tbw->thresh /= 2;\n\t\t\tif (bw->thresh < bw->buflen / 4)\n\t\t\t\tbw->thresh = bw->buflen / 4;\n\t\t} else if (bw->bwend.tv_usec < 10000) {\n\t\t\tbw->thresh *= 2;\n\t\t\tif (bw->thresh > bw->buflen * 8)\n\t\t\t\tbw->thresh = bw->buflen * 8;\n\t\t}\n\n\t\tTIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);\n\t\twhile (nanosleep(&ts, &rm) == -1) {\n\t\t\tif (errno != EINTR)\n\t\t\t\tbreak;\n\t\t\tts = rm;\n\t\t}\n\t}\n\n\tbw->lamt = 0;\n\tgettimeofday(&bw->bwstart, NULL);\n}\n\n/* Make a template filename for mk[sd]temp() */\nvoid\nmktemp_proto(char *s, size_t len)\n{\n\tconst char *tmpdir;\n\tint r;\n\n\tif ((tmpdir = getenv(\"TMPDIR\")) != NULL) {\n\t\tr = snprintf(s, len, \"%s/ssh-XXXXXXXXXXXX\", tmpdir);\n\t\tif (r > 0 && (size_t)r < len)\n\t\t\treturn;\n\t}\n\tr = snprintf(s, len, \"/tmp/ssh-XXXXXXXXXXXX\");\n\tif (r < 0 || (size_t)r >= len)\n\t\tfatal(\"%s: template string too short\", __func__);\n}\n\nstatic const struct {\n\tconst char *name;\n\tint value;\n} ipqos[] = {\n\t{ \"af11\", IPTOS_DSCP_AF11 },\n\t{ \"af12\", IPTOS_DSCP_AF12 },\n\t{ \"af13\", IPTOS_DSCP_AF13 },\n\t{ \"af21\", IPTOS_DSCP_AF21 },\n\t{ \"af22\", IPTOS_DSCP_AF22 },\n\t{ \"af23\", IPTOS_DSCP_AF23 },\n\t{ \"af31\", IPTOS_DSCP_AF31 },\n\t{ \"af32\", IPTOS_DSCP_AF32 },\n\t{ \"af33\", IPTOS_DSCP_AF33 },\n\t{ \"af41\", IPTOS_DSCP_AF41 },\n\t{ \"af42\", IPTOS_DSCP_AF42 },\n\t{ \"af43\", IPTOS_DSCP_AF43 },\n\t{ \"cs0\", IPTOS_DSCP_CS0 },\n\t{ \"cs1\", IPTOS_DSCP_CS1 },\n\t{ \"cs2\", IPTOS_DSCP_CS2 },\n\t{ \"cs3\", IPTOS_DSCP_CS3 },\n\t{ \"cs4\", IPTOS_DSCP_CS4 },\n\t{ \"cs5\", IPTOS_DSCP_CS5 },\n\t{ \"cs6\", IPTOS_DSCP_CS6 },\n\t{ \"cs7\", IPTOS_DSCP_CS7 },\n\t{ \"ef\", IPTOS_DSCP_EF },\n\t{ \"lowdelay\", IPTOS_LOWDELAY },\n\t{ \"throughput\", IPTOS_THROUGHPUT },\n\t{ \"reliability\", IPTOS_RELIABILITY },\n\t{ NULL, -1 }\n};\n\nint\nparse_ipqos(const char *cp)\n{\n\tu_int i;\n\tchar *ep;\n\tlong val;\n\n\tif (cp == NULL)\n\t\treturn -1;\n\tfor (i = 0; ipqos[i].name != NULL; i++) {\n\t\tif (strcasecmp(cp, ipqos[i].name) == 0)\n\t\t\treturn ipqos[i].value;\n\t}\n\t/* Try parsing as an integer */\n\tval = strtol(cp, &ep, 0);\n\tif (*cp == '\\0' || *ep != '\\0' || val < 0 || val > 255)\n\t\treturn -1;\n\treturn val;\n}\n\nconst char *\niptos2str(int iptos)\n{\n\tint i;\n\tstatic char iptos_str[sizeof \"0xff\"];\n\n\tfor (i = 0; ipqos[i].name != NULL; i++) {\n\t\tif (ipqos[i].value == iptos)\n\t\t\treturn ipqos[i].name;\n\t}\n\tsnprintf(iptos_str, sizeof iptos_str, \"0x%02x\", iptos);\n\treturn iptos_str;\n}\n\nvoid\nlowercase(char *s)\n{\n\tfor (; *s; s++)\n\t\t*s = tolower((u_char)*s);\n}\n\nint\nunix_listener(const char *path, int backlog, int unlink_first)\n{\n\tstruct sockaddr_un sunaddr;\n\tint saved_errno, sock;\n\n\tmemset(&sunaddr, 0, sizeof(sunaddr));\n\tsunaddr.sun_family = AF_UNIX;\n\tif (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {\n\t\terror(\"%s: \\\"%s\\\" too long for Unix domain socket\", __func__,\n\t\t path);\n\t\terrno = ENAMETOOLONG;\n\t\treturn -1;\n\t}\n\n\tsock = socket(PF_UNIX, SOCK_STREAM, 0);\n\tif (sock < 0) {\n\t\tsaved_errno = errno;\n\t\terror(\"socket: %.100s\", strerror(errno));\n\t\terrno = saved_errno;\n\t\treturn -1;\n\t}\n\tif (unlink_first == 1) {\n\t\tif (unlink(path) != 0 && errno != ENOENT)\n\t\t\terror(\"unlink(%s): %.100s\", path, strerror(errno));\n\t}\n\tif (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {\n\t\tsaved_errno = errno;\n\t\terror(\"bind: %.100s\", strerror(errno));\n\t\tclose(sock);\n\t\terror(\"%s: cannot bind to path: %s\", __func__, path);\n\t\terrno = saved_errno;\n\t\treturn -1;\n\t}\n\tif (listen(sock, backlog) < 0) {\n\t\tsaved_errno = errno;\n\t\terror(\"listen: %.100s\", strerror(errno));\n\t\tclose(sock);\n\t\tunlink(path);\n\t\terror(\"%s: cannot listen on path: %s\", __func__, path);\n\t\terrno = saved_errno;\n\t\treturn -1;\n\t}\n\treturn sock;\n}\n\nvoid\nsock_set_v6only(int s)\n{\n#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)\n\tint on = 1;\n\n\tdebug3(\"%s: set socket %d IPV6_V6ONLY\", __func__, s);\n\tif (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)\n\t\terror(\"setsockopt IPV6_V6ONLY: %s\", strerror(errno));\n#endif\n}\n\n/*\n * Compares two strings that maybe be NULL. Returns non-zero if strings\n * are both NULL or are identical, returns zero otherwise.\n */\nstatic int\nstrcmp_maybe_null(const char *a, const char *b)\n{\n\tif ((a == NULL && b != NULL) || (a != NULL && b == NULL))\n\t\treturn 0;\n\tif (a != NULL && strcmp(a, b) != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\n/*\n * Compare two forwards, returning non-zero if they are identical or\n * zero otherwise.\n */\nint\nforward_equals(const struct Forward *a, const struct Forward *b)\n{\n\tif (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)\n\t\treturn 0;\n\tif (a->listen_port != b->listen_port)\n\t\treturn 0;\n\tif (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)\n\t\treturn 0;\n\tif (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)\n\t\treturn 0;\n\tif (a->connect_port != b->connect_port)\n\t\treturn 0;\n\tif (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)\n\t\treturn 0;\n\t/* allocated_port and handle are not checked */\n\treturn 1;\n}\n\n/* returns 1 if bind to specified port by specified user is permitted */\nint\nbind_permitted(int port, uid_t uid)\n{\n\tif (port < IPPORT_RESERVED && uid != 0)\n\t\treturn 0;\n\treturn 1;\n}\n\n/* returns 1 if process is already daemonized, 0 otherwise */\nint\ndaemonized(void)\n{\n\tint fd;\n\n\tif ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {\n\t\tclose(fd);\n\t\treturn 0;\t/* have controlling terminal */\n\t}\n\tif (getppid() != 1)\n\t\treturn 0;\t/* parent is not init */\n\tif (getsid(0) != getpid())\n\t\treturn 0;\t/* not session leader */\n\tdebug3(\"already daemonized\");\n\treturn 1;\n}\n","/* $OpenBSD: utf8.c,v 1.5 2017/02/19 00:10:57 djm Exp $ */\n/*\n * Copyright (c) 2016 Ingo Schwarze \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/*\n * Utility functions for multibyte-character handling,\n * in particular to sanitize untrusted strings for terminal output.\n */\n\n#include \"includes.h\"\n\n#include \n#ifdef HAVE_LANGINFO_H\n# include \n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)\n# include \n#endif\n#ifdef HAVE_WCHAR_H\n# include \n#endif\n\n#include \"utf8.h\"\n\nstatic int\t dangerous_locale(void);\nstatic int\t grow_dst(char **, size_t *, size_t, char **, size_t);\nstatic int\t vasnmprintf(char **, size_t, int *, const char *, va_list);\n\n\n/*\n * For US-ASCII and UTF-8 encodings, we can safely recover from\n * encoding errors and from non-printable characters. For any\n * other encodings, err to the side of caution and abort parsing:\n * For state-dependent encodings, recovery is impossible.\n * For arbitrary encodings, replacement of non-printable\n * characters would be non-trivial and too fragile.\n */\n\nstatic int\ndangerous_locale(void) {\n\tchar\t*loc;\n\n\tloc = nl_langinfo(CODESET);\n\treturn strcmp(loc, \"US-ASCII\") != 0 && strcmp(loc, \"UTF-8\") != 0 &&\n\t strcmp(loc, \"ANSI_X3.4-1968\") != 0 && strcmp(loc, \"646\") != 0;\n}\n\nstatic int\ngrow_dst(char **dst, size_t *sz, size_t maxsz, char **dp, size_t need)\n{\n\tchar\t*tp;\n\tsize_t\t tsz;\n\n\tif (*dp + need < *dst + *sz)\n\t\treturn 0;\n\ttsz = *sz + 128;\n\tif (tsz > maxsz)\n\t\ttsz = maxsz;\n\tif ((tp = realloc(*dst, tsz)) == NULL)\n\t\treturn -1;\n\t*dp = tp + (*dp - *dst);\n\t*dst = tp;\n\t*sz = tsz;\n\treturn 0;\n}\n\n/*\n * The following two functions limit the number of bytes written,\n * including the terminating '\\0', to sz. Unless wp is NULL,\n * they limit the number of display columns occupied to *wp.\n * Whichever is reached first terminates the output string.\n * To stay close to the standard interfaces, they return the number of\n * non-NUL bytes that would have been written if both were unlimited.\n * If wp is NULL, newline, carriage return, and tab are allowed;\n * otherwise, the actual number of columns occupied by what was\n * written is returned in *wp.\n */\n\nstatic int\nvasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap)\n{\n\tchar\t*src;\t/* Source string returned from vasprintf. */\n\tchar\t*sp;\t/* Pointer into src. */\n\tchar\t*dst;\t/* Destination string to be returned. */\n\tchar\t*dp;\t/* Pointer into dst. */\n\tchar\t*tp;\t/* Temporary pointer for dst. */\n\tsize_t\t sz;\t/* Number of bytes allocated for dst. */\n\twchar_t\t wc;\t/* Wide character at sp. */\n\tint\t len;\t/* Number of bytes in the character at sp. */\n\tint\t ret;\t/* Number of bytes needed to format src. */\n\tint\t width;\t/* Display width of the character wc. */\n\tint\t total_width, max_width, print;\n\n\tsrc = NULL;\n\tif ((ret = vasprintf(&src, fmt, ap)) <= 0)\n\t\tgoto fail;\n\n\tsz = strlen(src) + 1;\n\tif ((dst = malloc(sz)) == NULL) {\n\t\tfree(src);\n\t\tret = -1;\n\t\tgoto fail;\n\t}\n\n\tif (maxsz > INT_MAX)\n\t\tmaxsz = INT_MAX;\n\n\tsp = src;\n\tdp = dst;\n\tret = 0;\n\tprint = 1;\n\ttotal_width = 0;\n\tmax_width = wp == NULL ? INT_MAX : *wp;\n\twhile (*sp != '\\0') {\n\t\tif ((len = mbtowc(&wc, sp, MB_CUR_MAX)) == -1) {\n\t\t\t(void)mbtowc(NULL, NULL, MB_CUR_MAX);\n\t\t\tif (dangerous_locale()) {\n\t\t\t\tret = -1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tlen = 1;\n\t\t\twidth = -1;\n\t\t} else if (wp == NULL &&\n\t\t (wc == L'\\n' || wc == L'\\r' || wc == L'\\t')) {\n\t\t\t/*\n\t\t\t * Don't use width uninitialized; the actual\n\t\t\t * value doesn't matter because total_width\n\t\t\t * is only returned for wp != NULL.\n\t\t\t */\n\t\t\twidth = 0;\n\t\t} else if ((width = wcwidth(wc)) == -1 &&\n\t\t dangerous_locale()) {\n\t\t\tret = -1;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Valid, printable character. */\n\n\t\tif (width >= 0) {\n\t\t\tif (print && (dp - dst >= (int)maxsz - len ||\n\t\t\t total_width > max_width - width))\n\t\t\t\tprint = 0;\n\t\t\tif (print) {\n\t\t\t\tif (grow_dst(&dst, &sz, maxsz,\n\t\t\t\t &dp, len) == -1) {\n\t\t\t\t\tret = -1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttotal_width += width;\n\t\t\t\tmemcpy(dp, sp, len);\n\t\t\t\tdp += len;\n\t\t\t}\n\t\t\tsp += len;\n\t\t\tif (ret >= 0)\n\t\t\t\tret += len;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Escaping required. */\n\n\t\twhile (len > 0) {\n\t\t\tif (print && (dp - dst >= (int)maxsz - 4 ||\n\t\t\t total_width > max_width - 4))\n\t\t\t\tprint = 0;\n\t\t\tif (print) {\n\t\t\t\tif (grow_dst(&dst, &sz, maxsz,\n\t\t\t\t &dp, 4) == -1) {\n\t\t\t\t\tret = -1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttp = vis(dp, *sp, VIS_OCTAL | VIS_ALL, 0);\n\t\t\t\twidth = tp - dp;\n\t\t\t\ttotal_width += width;\n\t\t\t\tdp = tp;\n\t\t\t} else\n\t\t\t\twidth = 4;\n\t\t\tlen--;\n\t\t\tsp++;\n\t\t\tif (ret >= 0)\n\t\t\t\tret += width;\n\t\t}\n\t\tif (len > 0)\n\t\t\tbreak;\n\t}\n\tfree(src);\n\t*dp = '\\0';\n\t*str = dst;\n\tif (wp != NULL)\n\t\t*wp = total_width;\n\n\t/*\n\t * If the string was truncated by the width limit but\n\t * would have fit into the size limit, the only sane way\n\t * to report the problem is using the return value, such\n\t * that the usual idiom \"if (ret < 0 || ret >= sz) error\"\n\t * works as expected.\n\t */\n\n\tif (ret < (int)maxsz && !print)\n\t\tret = -1;\n\treturn ret;\n\nfail:\n\tif (wp != NULL)\n\t\t*wp = 0;\n\tif (ret == 0) {\n\t\t*str = src;\n\t\treturn 0;\n\t} else {\n\t\t*str = NULL;\n\t\treturn -1;\n\t}\n}\n\nint\nsnmprintf(char *str, size_t sz, int *wp, const char *fmt, ...)\n{\n\tva_list\t ap;\n\tchar\t*cp;\n\tint\t ret;\n\n\tva_start(ap, fmt);\n\tret = vasnmprintf(&cp, sz, wp, fmt, ap);\n\tva_end(ap);\n\tif (cp != NULL) {\n\t\t(void)strlcpy(str, cp, sz);\n\t\tfree(cp);\n\t} else\n\t\t*str = '\\0';\n\treturn ret;\n}\n\n/*\n * To stay close to the standard interfaces, the following functions\n * return the number of non-NUL bytes written.\n */\n\nint\nvfmprintf(FILE *stream, const char *fmt, va_list ap)\n{\n\tchar\t*str;\n\tint\t ret;\n\n\tif ((ret = vasnmprintf(&str, INT_MAX, NULL, fmt, ap)) < 0)\n\t\treturn -1;\n\tif (fputs(str, stream) == EOF)\n\t\tret = -1;\n\tfree(str);\n\treturn ret;\n}\n\nint\nfmprintf(FILE *stream, const char *fmt, ...)\n{\n\tva_list\t ap;\n\tint\t ret;\n\n\tva_start(ap, fmt);\n\tret = vfmprintf(stream, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\nint\nmprintf(const char *fmt, ...)\n{\n\tva_list\t ap;\n\tint\t ret;\n\n\tva_start(ap, fmt);\n\tret = vfmprintf(stdout, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n/*\n * Set up libc for multibyte output in the user's chosen locale.\n *\n * XXX: we are known to have problems with Turkish (i/I confusion) so we\n * deliberately fall back to the C locale for now. Longer term we should\n * always prefer to select C.[encoding] if possible, but there's no\n * standardisation in locales between systems, so we'll need to survey\n * what's out there first.\n */\nvoid\nmsetlocale(void)\n{\n\tconst char *vars[] = { \"LC_ALL\", \"LC_CTYPE\", \"LANG\", NULL };\n\tchar *cp;\n\tint i;\n\n\t/*\n\t * We can't yet cope with dotless/dotted I in Turkish locales,\n\t * so fall back to the C locale for these.\n\t */\n\tfor (i = 0; vars[i] != NULL; i++) {\n\t\tif ((cp = getenv(vars[i])) == NULL)\n\t\t\tcontinue;\n\t\tif (strncasecmp(cp, \"TR\", 2) != 0)\n\t\t\tbreak;\n\t\t/*\n\t\t * If we're in a UTF-8 locale then prefer to use\n\t\t * the C.UTF-8 locale (or equivalent) if it exists.\n\t\t */\n\t\tif ((strcasestr(cp, \"UTF-8\") != NULL ||\n\t\t strcasestr(cp, \"UTF8\") != NULL) &&\n\t\t (setlocale(LC_CTYPE, \"C.UTF-8\") != NULL ||\n\t\t setlocale(LC_CTYPE, \"POSIX.UTF-8\") != NULL))\n\t\t\treturn;\n\t\tsetlocale(LC_CTYPE, \"C\");\n\t\treturn;\n\t}\n\t/* We can handle this locale */\n\tsetlocale(LC_CTYPE, \"\");\n}\n","/* $OpenBSD: monitor_fdpass.c,v 1.21 2016/02/29 20:22:36 jca Exp $ */\n/*\n * Copyright 2001 Niels Provos \n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n#ifdef HAVE_SYS_UN_H\n#include \n#endif\n\n#include \n#include \n#include \n\n#ifdef HAVE_POLL_H\n# include \n#else\n# ifdef HAVE_SYS_POLL_H\n# include \n# endif\n#endif\n\n#include \"log.h\"\n#include \"monitor_fdpass.h\"\n\nint\nmm_send_fd(int sock, int fd)\n{\n#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))\n\tstruct msghdr msg;\n#ifndef HAVE_ACCRIGHTS_IN_MSGHDR\n\tunion {\n\t\tstruct cmsghdr hdr;\n\t\tchar buf[CMSG_SPACE(sizeof(int))];\n\t} cmsgbuf;\n\tstruct cmsghdr *cmsg;\n#endif\n\tstruct iovec vec;\n\tchar ch = '\\0';\n\tssize_t n;\n\tstruct pollfd pfd;\n\n\tmemset(&msg, 0, sizeof(msg));\n#ifdef HAVE_ACCRIGHTS_IN_MSGHDR\n\tmsg.msg_accrights = (caddr_t)&fd;\n\tmsg.msg_accrightslen = sizeof(fd);\n#else\n\tmemset(&cmsgbuf, 0, sizeof(cmsgbuf));\n\tmsg.msg_control = (caddr_t)&cmsgbuf.buf;\n\tmsg.msg_controllen = sizeof(cmsgbuf.buf);\n\tcmsg = CMSG_FIRSTHDR(&msg);\n\tcmsg->cmsg_len = CMSG_LEN(sizeof(int));\n\tcmsg->cmsg_level = SOL_SOCKET;\n\tcmsg->cmsg_type = SCM_RIGHTS;\n\t*(int *)CMSG_DATA(cmsg) = fd;\n#endif\n\n\tvec.iov_base = &ch;\n\tvec.iov_len = 1;\n\tmsg.msg_iov = &vec;\n\tmsg.msg_iovlen = 1;\n\n\tpfd.fd = sock;\n\tpfd.events = POLLOUT;\n\twhile ((n = sendmsg(sock, &msg, 0)) == -1 &&\n\t (errno == EAGAIN || errno == EINTR)) {\n\t\tdebug3(\"%s: sendmsg(%d): %s\", __func__, fd, strerror(errno));\n\t\t(void)poll(&pfd, 1, -1);\n\t}\n\tif (n == -1) {\n\t\terror(\"%s: sendmsg(%d): %s\", __func__, fd,\n\t\t strerror(errno));\n\t\treturn -1;\n\t}\n\n\tif (n != 1) {\n\t\terror(\"%s: sendmsg: expected sent 1 got %zd\", __func__, n);\n\t\treturn -1;\n\t}\n\treturn 0;\n#else\n\terror(\"%s: file descriptor passing not supported\", __func__);\n\treturn -1;\n#endif\n}\n\nint\nmm_receive_fd(int sock)\n{\n#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))\n\tstruct msghdr msg;\n#ifndef HAVE_ACCRIGHTS_IN_MSGHDR\n\tunion {\n\t\tstruct cmsghdr hdr;\n\t\tchar buf[CMSG_SPACE(sizeof(int))];\n\t} cmsgbuf;\n\tstruct cmsghdr *cmsg;\n#endif\n\tstruct iovec vec;\n\tssize_t n;\n\tchar ch;\n\tint fd;\n\tstruct pollfd pfd;\n\n\tmemset(&msg, 0, sizeof(msg));\n\tvec.iov_base = &ch;\n\tvec.iov_len = 1;\n\tmsg.msg_iov = &vec;\n\tmsg.msg_iovlen = 1;\n#ifdef HAVE_ACCRIGHTS_IN_MSGHDR\n\tmsg.msg_accrights = (caddr_t)&fd;\n\tmsg.msg_accrightslen = sizeof(fd);\n#else\n\tmemset(&cmsgbuf, 0, sizeof(cmsgbuf));\n\tmsg.msg_control = &cmsgbuf.buf;\n\tmsg.msg_controllen = sizeof(cmsgbuf.buf);\n#endif\n\n\tpfd.fd = sock;\n\tpfd.events = POLLIN;\n\twhile ((n = recvmsg(sock, &msg, 0)) == -1 &&\n\t (errno == EAGAIN || errno == EINTR)) {\n\t\tdebug3(\"%s: recvmsg: %s\", __func__, strerror(errno));\n\t\t(void)poll(&pfd, 1, -1);\n\t}\n\tif (n == -1) {\n\t\terror(\"%s: recvmsg: %s\", __func__, strerror(errno));\n\t\treturn -1;\n\t}\n\n\tif (n != 1) {\n\t\terror(\"%s: recvmsg: expected received 1 got %zd\", __func__, n);\n\t\treturn -1;\n\t}\n\n#ifdef HAVE_ACCRIGHTS_IN_MSGHDR\n\tif (msg.msg_accrightslen != sizeof(fd)) {\n\t\terror(\"%s: no fd\", __func__);\n\t\treturn -1;\n\t}\n#else\n\tcmsg = CMSG_FIRSTHDR(&msg);\n\tif (cmsg == NULL) {\n\t\terror(\"%s: no message header\", __func__);\n\t\treturn -1;\n\t}\n\n#ifndef BROKEN_CMSG_TYPE\n\tif (cmsg->cmsg_type != SCM_RIGHTS) {\n\t\terror(\"%s: expected type %d got %d\", __func__,\n\t\t SCM_RIGHTS, cmsg->cmsg_type);\n\t\treturn -1;\n\t}\n#endif\n\tfd = (*(int *)CMSG_DATA(cmsg));\n#endif\n\treturn fd;\n#else\n\terror(\"%s: file descriptor passing not supported\", __func__);\n\treturn -1;\n#endif\n}\n","/*\t$OpenBSD: rijndael.c,v 1.20 2015/03/16 11:09:52 djm Exp $ */\n\n/**\n * rijndael-alg-fst.c\n *\n * @version 3.0 (December 2000)\n *\n * Optimised ANSI C code for the Rijndael cipher (now AES)\n *\n * @author Vincent Rijmen \n * @author Antoon Bosselaers \n * @author Paulo Barreto \n *\n * This code is hereby placed in the public domain.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \"rijndael.h\"\n\n#undef FULL_UNROLL\n\n/*\nTe0[x] = S [x].[02, 01, 01, 03];\nTe1[x] = S [x].[03, 02, 01, 01];\nTe2[x] = S [x].[01, 03, 02, 01];\nTe3[x] = S [x].[01, 01, 03, 02];\n\nTd0[x] = Si[x].[0e, 09, 0d, 0b];\nTd1[x] = Si[x].[0b, 0e, 09, 0d];\nTd2[x] = Si[x].[0d, 0b, 0e, 09];\nTd3[x] = Si[x].[09, 0d, 0b, 0e];\nTd4[x] = Si[x].[01];\n*/\n\nstatic const u32 Te0[256] = {\n 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,\n 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,\n 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,\n 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,\n 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,\n 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,\n 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,\n 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,\n 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,\n 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,\n 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,\n 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,\n 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,\n 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,\n 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,\n 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,\n 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,\n 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,\n 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,\n 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,\n 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,\n 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,\n 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,\n 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,\n 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,\n 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,\n 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,\n 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,\n 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,\n 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,\n 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,\n 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,\n 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,\n 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,\n 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,\n 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,\n 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,\n 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,\n 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,\n 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,\n 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,\n 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,\n 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,\n 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,\n 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,\n 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,\n 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,\n 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,\n 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,\n 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,\n 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,\n 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,\n 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,\n 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,\n 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,\n 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,\n 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,\n 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,\n 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,\n 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,\n 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,\n 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,\n 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,\n 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,\n};\nstatic const u32 Te1[256] = {\n 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,\n 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,\n 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,\n 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,\n 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,\n 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,\n 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,\n 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,\n 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,\n 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,\n 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,\n 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,\n 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,\n 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,\n 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,\n 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,\n 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,\n 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,\n 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,\n 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,\n 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,\n 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,\n 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,\n 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,\n 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,\n 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,\n 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,\n 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,\n 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,\n 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,\n 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,\n 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,\n 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,\n 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,\n 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,\n 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,\n 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,\n 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,\n 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,\n 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,\n 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,\n 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,\n 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,\n 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,\n 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,\n 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,\n 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,\n 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,\n 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,\n 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,\n 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,\n 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,\n 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,\n 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,\n 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,\n 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,\n 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,\n 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,\n 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,\n 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,\n 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,\n 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,\n 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,\n 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,\n};\nstatic const u32 Te2[256] = {\n 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,\n 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,\n 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,\n 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,\n 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,\n 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,\n 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,\n 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,\n 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,\n 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,\n 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,\n 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,\n 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,\n 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,\n 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,\n 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,\n 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,\n 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,\n 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,\n 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,\n 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,\n 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,\n 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,\n 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,\n 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,\n 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,\n 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,\n 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,\n 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,\n 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,\n 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,\n 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,\n 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,\n 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,\n 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,\n 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,\n 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,\n 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,\n 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,\n 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,\n 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,\n 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,\n 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,\n 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,\n 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,\n 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,\n 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,\n 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,\n 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,\n 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,\n 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,\n 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,\n 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,\n 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,\n 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,\n 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,\n 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,\n 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,\n 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,\n 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,\n 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,\n 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,\n 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,\n 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,\n};\nstatic const u32 Te3[256] = {\n 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,\n 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,\n 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,\n 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,\n 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,\n 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,\n 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,\n 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,\n 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,\n 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,\n 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,\n 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,\n 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,\n 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,\n 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,\n 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,\n 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,\n 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,\n 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,\n 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,\n 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,\n 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,\n 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,\n 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,\n 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,\n 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,\n 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,\n 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,\n 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,\n 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,\n 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,\n 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,\n 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,\n 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,\n 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,\n 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,\n 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,\n 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,\n 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,\n 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,\n 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,\n 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,\n 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,\n 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,\n 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,\n 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,\n 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,\n 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,\n 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,\n 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,\n 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,\n 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,\n 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,\n 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,\n 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,\n 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,\n 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,\n 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,\n 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,\n 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,\n 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,\n 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,\n 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,\n 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,\n};\n#if 0\nstatic const u32 Td0[256] = {\n 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,\n 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,\n 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,\n 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,\n 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,\n 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,\n 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,\n 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,\n 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,\n 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,\n 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,\n 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,\n 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,\n 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,\n 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,\n 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,\n 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,\n 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,\n 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,\n 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,\n 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,\n 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,\n 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,\n 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,\n 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,\n 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,\n 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,\n 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,\n 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,\n 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,\n 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,\n 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,\n 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,\n 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,\n 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,\n 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,\n 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,\n 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,\n 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,\n 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,\n 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,\n 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,\n 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,\n 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,\n 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,\n 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,\n 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,\n 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,\n 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,\n 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,\n 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,\n 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,\n 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,\n 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,\n 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,\n 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,\n 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,\n 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,\n 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,\n 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,\n 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,\n 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,\n 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,\n 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,\n};\nstatic const u32 Td1[256] = {\n 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,\n 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,\n 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,\n 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,\n 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,\n 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,\n 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,\n 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,\n 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,\n 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,\n 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,\n 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,\n 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,\n 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,\n 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,\n 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,\n 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,\n 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,\n 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,\n 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,\n 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,\n 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,\n 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,\n 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,\n 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,\n 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,\n 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,\n 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,\n 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,\n 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,\n 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,\n 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,\n 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,\n 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,\n 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,\n 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,\n 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,\n 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,\n 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,\n 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,\n 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,\n 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,\n 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,\n 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,\n 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,\n 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,\n 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,\n 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,\n 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,\n 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,\n 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,\n 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,\n 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,\n 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,\n 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,\n 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,\n 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,\n 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,\n 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,\n 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,\n 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,\n 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,\n 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,\n 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,\n};\nstatic const u32 Td2[256] = {\n 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,\n 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,\n 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,\n 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,\n 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,\n 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,\n 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,\n 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,\n 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,\n 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,\n 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,\n 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,\n 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,\n 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,\n 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,\n 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,\n 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,\n 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,\n 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,\n 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,\n 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,\n 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,\n 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,\n 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,\n 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,\n 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,\n 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,\n 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,\n 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,\n 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,\n 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,\n 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,\n 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,\n 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,\n 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,\n 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,\n 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,\n 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,\n 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,\n 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,\n 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,\n 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,\n 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,\n 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,\n 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,\n 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,\n 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,\n 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,\n 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,\n 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,\n 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,\n 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,\n 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,\n 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,\n 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,\n 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,\n 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,\n 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,\n 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,\n 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,\n 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,\n 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,\n 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,\n 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,\n};\nstatic const u32 Td3[256] = {\n 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,\n 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,\n 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,\n 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,\n 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,\n 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,\n 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,\n 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,\n 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,\n 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,\n 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,\n 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,\n 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,\n 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,\n 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,\n 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,\n 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,\n 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,\n 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,\n 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,\n 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,\n 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,\n 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,\n 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,\n 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,\n 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,\n 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,\n 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,\n 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,\n 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,\n 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,\n 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,\n 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,\n 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,\n 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,\n 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,\n 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,\n 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,\n 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,\n 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,\n 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,\n 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,\n 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,\n 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,\n 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,\n 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,\n 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,\n 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,\n 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,\n 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,\n 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,\n 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,\n 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,\n 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,\n 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,\n 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,\n 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,\n 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,\n 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,\n 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,\n 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,\n 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,\n 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,\n 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,\n};\nstatic const u8 Td4[256] = {\n 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,\n 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,\n 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,\n 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,\n 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,\n 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,\n 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,\n 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,\n 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,\n 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,\n 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,\n 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,\n 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,\n 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,\n 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,\n 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,\n 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,\n 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,\n 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,\n 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,\n 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,\n 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,\n 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,\n 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,\n 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,\n 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,\n 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,\n 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,\n 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,\n 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,\n 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,\n 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,\n};\n#endif\nstatic const u32 rcon[] = {\n\t0x01000000, 0x02000000, 0x04000000, 0x08000000,\n\t0x10000000, 0x20000000, 0x40000000, 0x80000000,\n\t0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */\n};\n\n#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))\n#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }\n\n/**\n * Expand the cipher key into the encryption key schedule.\n *\n * @return\tthe number of rounds for the given cipher key size.\n */\nint\nrijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)\n{\n \tint i = 0;\n\tu32 temp;\n\n\trk[0] = GETU32(cipherKey );\n\trk[1] = GETU32(cipherKey + 4);\n\trk[2] = GETU32(cipherKey + 8);\n\trk[3] = GETU32(cipherKey + 12);\n\tif (keyBits == 128) {\n\t\tfor (;;) {\n\t\t\ttemp = rk[3];\n\t\t\trk[4] = rk[0] ^\n\t\t\t\t(Te2[(temp >> 16) & 0xff] & 0xff000000) ^\n\t\t\t\t(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^\n\t\t\t\t(Te0[(temp ) & 0xff] & 0x0000ff00) ^\n\t\t\t\t(Te1[(temp >> 24) ] & 0x000000ff) ^\n\t\t\t\trcon[i];\n\t\t\trk[5] = rk[1] ^ rk[4];\n\t\t\trk[6] = rk[2] ^ rk[5];\n\t\t\trk[7] = rk[3] ^ rk[6];\n\t\t\tif (++i == 10) {\n\t\t\t\treturn 10;\n\t\t\t}\n\t\t\trk += 4;\n\t\t}\n\t}\n\trk[4] = GETU32(cipherKey + 16);\n\trk[5] = GETU32(cipherKey + 20);\n\tif (keyBits == 192) {\n\t\tfor (;;) {\n\t\t\ttemp = rk[ 5];\n\t\t\trk[ 6] = rk[ 0] ^\n\t\t\t\t(Te2[(temp >> 16) & 0xff] & 0xff000000) ^\n\t\t\t\t(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^\n\t\t\t\t(Te0[(temp ) & 0xff] & 0x0000ff00) ^\n\t\t\t\t(Te1[(temp >> 24) ] & 0x000000ff) ^\n\t\t\t\trcon[i];\n\t\t\trk[ 7] = rk[ 1] ^ rk[ 6];\n\t\t\trk[ 8] = rk[ 2] ^ rk[ 7];\n\t\t\trk[ 9] = rk[ 3] ^ rk[ 8];\n\t\t\tif (++i == 8) {\n\t\t\t\treturn 12;\n\t\t\t}\n\t\t\trk[10] = rk[ 4] ^ rk[ 9];\n\t\t\trk[11] = rk[ 5] ^ rk[10];\n\t\t\trk += 6;\n\t\t}\n\t}\n\trk[6] = GETU32(cipherKey + 24);\n\trk[7] = GETU32(cipherKey + 28);\n\tif (keyBits == 256) {\n\t\tfor (;;) {\n\t\t\ttemp = rk[ 7];\n\t\t\trk[ 8] = rk[ 0] ^\n\t\t\t\t(Te2[(temp >> 16) & 0xff] & 0xff000000) ^\n\t\t\t\t(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^\n\t\t\t\t(Te0[(temp ) & 0xff] & 0x0000ff00) ^\n\t\t\t\t(Te1[(temp >> 24) ] & 0x000000ff) ^\n\t\t\t\trcon[i];\n\t\t\trk[ 9] = rk[ 1] ^ rk[ 8];\n\t\t\trk[10] = rk[ 2] ^ rk[ 9];\n\t\t\trk[11] = rk[ 3] ^ rk[10];\n\t\t\tif (++i == 7) {\n\t\t\t\treturn 14;\n\t\t\t}\n\t\t\ttemp = rk[11];\n\t\t\trk[12] = rk[ 4] ^\n\t\t\t\t(Te2[(temp >> 24) ] & 0xff000000) ^\n\t\t\t\t(Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^\n\t\t\t\t(Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^\n\t\t\t\t(Te1[(temp ) & 0xff] & 0x000000ff);\n\t\t\trk[13] = rk[ 5] ^ rk[12];\n\t\t\trk[14] = rk[ 6] ^ rk[13];\n\t\t \trk[15] = rk[ 7] ^ rk[14];\n\t\t\trk += 8;\n\t\t}\n\t}\n\treturn 0;\n}\n\n#if 0\n/**\n * Expand the cipher key into the decryption key schedule.\n *\n * @return\tthe number of rounds for the given cipher key size.\n */\nint\nrijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)\n{\n\tint Nr, i, j;\n\tu32 temp;\n\n\t/* expand the cipher key: */\n\tNr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);\n\n\t/* invert the order of the round keys: */\n\tfor (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {\n\t\ttemp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;\n\t\ttemp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;\n\t\ttemp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;\n\t\ttemp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;\n\t}\n\t/* apply the inverse MixColumn transform to all round keys but the first and the last: */\n\tfor (i = 1; i < Nr; i++) {\n\t\trk += 4;\n\t\trk[0] =\n\t\t\tTd0[Te1[(rk[0] >> 24) ] & 0xff] ^\n\t\t\tTd1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^\n\t\t\tTd2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^\n\t\t\tTd3[Te1[(rk[0] ) & 0xff] & 0xff];\n\t\trk[1] =\n\t\t\tTd0[Te1[(rk[1] >> 24) ] & 0xff] ^\n\t\t\tTd1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^\n\t\t\tTd2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^\n\t\t\tTd3[Te1[(rk[1] ) & 0xff] & 0xff];\n\t\trk[2] =\n\t\t\tTd0[Te1[(rk[2] >> 24) ] & 0xff] ^\n\t\t\tTd1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^\n\t\t\tTd2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^\n\t\t\tTd3[Te1[(rk[2] ) & 0xff] & 0xff];\n\t\trk[3] =\n\t\t\tTd0[Te1[(rk[3] >> 24) ] & 0xff] ^\n\t\t\tTd1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^\n\t\t\tTd2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^\n\t\t\tTd3[Te1[(rk[3] ) & 0xff] & 0xff];\n\t}\n\treturn Nr;\n}\n#endif\n\nvoid\nrijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16],\n u8 ct[16])\n{\n\tu32 s0, s1, s2, s3, t0, t1, t2, t3;\n#ifndef FULL_UNROLL\n int r;\n#endif /* ?FULL_UNROLL */\n\n /*\n\t * map byte array block to cipher state\n\t * and add initial round key:\n\t */\n\ts0 = GETU32(pt ) ^ rk[0];\n\ts1 = GETU32(pt + 4) ^ rk[1];\n\ts2 = GETU32(pt + 8) ^ rk[2];\n\ts3 = GETU32(pt + 12) ^ rk[3];\n#ifdef FULL_UNROLL\n /* round 1: */\n \tt0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];\n \tt1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];\n \tt2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];\n \tt3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];\n \t/* round 2: */\n \ts0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];\n \ts1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];\n \ts2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];\n \ts3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];\n /* round 3: */\n \tt0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];\n \tt1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];\n \tt2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];\n \tt3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];\n \t/* round 4: */\n \ts0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];\n \ts1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];\n \ts2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];\n \ts3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];\n /* round 5: */\n \tt0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];\n \tt1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];\n \tt2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];\n \tt3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];\n \t/* round 6: */\n \ts0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];\n \ts1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];\n \ts2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];\n \ts3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];\n /* round 7: */\n \tt0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];\n \tt1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];\n \tt2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];\n \tt3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];\n \t/* round 8: */\n \ts0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];\n \ts1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];\n \ts2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];\n \ts3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];\n /* round 9: */\n \tt0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];\n \tt1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];\n \tt2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];\n \tt3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];\n if (Nr > 10) {\n\t/* round 10: */\n\ts0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];\n\ts1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];\n\ts2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];\n\ts3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];\n\t/* round 11: */\n\tt0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];\n\tt1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];\n\tt2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];\n\tt3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];\n\tif (Nr > 12) {\n\t /* round 12: */\n\t s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];\n\t s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];\n\t s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];\n\t s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];\n\t /* round 13: */\n\t t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];\n\t t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];\n\t t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];\n\t t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];\n\t}\n }\n rk += Nr << 2;\n#else /* !FULL_UNROLL */\n /*\n\t * Nr - 1 full rounds:\n\t */\n r = Nr >> 1;\n for (;;) {\n\tt0 =\n\t Te0[(s0 >> 24) ] ^\n\t Te1[(s1 >> 16) & 0xff] ^\n\t Te2[(s2 >> 8) & 0xff] ^\n\t Te3[(s3 ) & 0xff] ^\n\t rk[4];\n\tt1 =\n\t Te0[(s1 >> 24) ] ^\n\t Te1[(s2 >> 16) & 0xff] ^\n\t Te2[(s3 >> 8) & 0xff] ^\n\t Te3[(s0 ) & 0xff] ^\n\t rk[5];\n\tt2 =\n\t Te0[(s2 >> 24) ] ^\n\t Te1[(s3 >> 16) & 0xff] ^\n\t Te2[(s0 >> 8) & 0xff] ^\n\t Te3[(s1 ) & 0xff] ^\n\t rk[6];\n\tt3 =\n\t Te0[(s3 >> 24) ] ^\n\t Te1[(s0 >> 16) & 0xff] ^\n\t Te2[(s1 >> 8) & 0xff] ^\n\t Te3[(s2 ) & 0xff] ^\n\t rk[7];\n\n\trk += 8;\n\tif (--r == 0) {\n\t break;\n\t}\n\n\ts0 =\n\t Te0[(t0 >> 24) ] ^\n\t Te1[(t1 >> 16) & 0xff] ^\n\t Te2[(t2 >> 8) & 0xff] ^\n\t Te3[(t3 ) & 0xff] ^\n\t rk[0];\n\ts1 =\n\t Te0[(t1 >> 24) ] ^\n\t Te1[(t2 >> 16) & 0xff] ^\n\t Te2[(t3 >> 8) & 0xff] ^\n\t Te3[(t0 ) & 0xff] ^\n\t rk[1];\n\ts2 =\n\t Te0[(t2 >> 24) ] ^\n\t Te1[(t3 >> 16) & 0xff] ^\n\t Te2[(t0 >> 8) & 0xff] ^\n\t Te3[(t1 ) & 0xff] ^\n\t rk[2];\n\ts3 =\n\t Te0[(t3 >> 24) ] ^\n\t Te1[(t0 >> 16) & 0xff] ^\n\t Te2[(t1 >> 8) & 0xff] ^\n\t Te3[(t2 ) & 0xff] ^\n\t rk[3];\n }\n#endif /* ?FULL_UNROLL */\n /*\n\t * apply last round and\n\t * map cipher state to byte array block:\n\t */\n\ts0 =\n\t\t(Te2[(t0 >> 24) ] & 0xff000000) ^\n\t\t(Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^\n\t\t(Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^\n\t\t(Te1[(t3 ) & 0xff] & 0x000000ff) ^\n\t\trk[0];\n\tPUTU32(ct , s0);\n\ts1 =\n\t\t(Te2[(t1 >> 24) ] & 0xff000000) ^\n\t\t(Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^\n\t\t(Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^\n\t\t(Te1[(t0 ) & 0xff] & 0x000000ff) ^\n\t\trk[1];\n\tPUTU32(ct + 4, s1);\n\ts2 =\n\t\t(Te2[(t2 >> 24) ] & 0xff000000) ^\n\t\t(Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^\n\t\t(Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^\n\t\t(Te1[(t1 ) & 0xff] & 0x000000ff) ^\n\t\trk[2];\n\tPUTU32(ct + 8, s2);\n\ts3 =\n\t\t(Te2[(t3 >> 24) ] & 0xff000000) ^\n\t\t(Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^\n\t\t(Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^\n\t\t(Te1[(t2 ) & 0xff] & 0x000000ff) ^\n\t\trk[3];\n\tPUTU32(ct + 12, s3);\n}\n\n#if 0\nstatic void\nrijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16],\n u8 pt[16])\n{\n\tu32 s0, s1, s2, s3, t0, t1, t2, t3;\n#ifndef FULL_UNROLL\n int r;\n#endif /* ?FULL_UNROLL */\n\n /*\n\t * map byte array block to cipher state\n\t * and add initial round key:\n\t */\n s0 = GETU32(ct ) ^ rk[0];\n s1 = GETU32(ct + 4) ^ rk[1];\n s2 = GETU32(ct + 8) ^ rk[2];\n s3 = GETU32(ct + 12) ^ rk[3];\n#ifdef FULL_UNROLL\n /* round 1: */\n t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];\n t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];\n t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];\n t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];\n /* round 2: */\n s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];\n s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];\n s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];\n s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];\n /* round 3: */\n t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];\n t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];\n t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];\n t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];\n /* round 4: */\n s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];\n s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];\n s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];\n s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];\n /* round 5: */\n t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];\n t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];\n t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];\n t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];\n /* round 6: */\n s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];\n s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];\n s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];\n s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];\n /* round 7: */\n t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];\n t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];\n t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];\n t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];\n /* round 8: */\n s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];\n s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];\n s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];\n s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];\n /* round 9: */\n t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];\n t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];\n t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];\n t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];\n if (Nr > 10) {\n\t/* round 10: */\n\ts0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];\n\ts1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];\n\ts2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];\n\ts3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];\n\t/* round 11: */\n\tt0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];\n\tt1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];\n\tt2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];\n\tt3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];\n\tif (Nr > 12) {\n\t /* round 12: */\n\t s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];\n\t s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];\n\t s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];\n\t s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];\n\t /* round 13: */\n\t t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];\n\t t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];\n\t t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];\n\t t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];\n\t}\n }\n\trk += Nr << 2;\n#else /* !FULL_UNROLL */\n /*\n * Nr - 1 full rounds:\n */\n r = Nr >> 1;\n for (;;) {\n\tt0 =\n\t Td0[(s0 >> 24) ] ^\n\t Td1[(s3 >> 16) & 0xff] ^\n\t Td2[(s2 >> 8) & 0xff] ^\n\t Td3[(s1 ) & 0xff] ^\n\t rk[4];\n\tt1 =\n\t Td0[(s1 >> 24) ] ^\n\t Td1[(s0 >> 16) & 0xff] ^\n\t Td2[(s3 >> 8) & 0xff] ^\n\t Td3[(s2 ) & 0xff] ^\n\t rk[5];\n\tt2 =\n\t Td0[(s2 >> 24) ] ^\n\t Td1[(s1 >> 16) & 0xff] ^\n\t Td2[(s0 >> 8) & 0xff] ^\n\t Td3[(s3 ) & 0xff] ^\n\t rk[6];\n\tt3 =\n\t Td0[(s3 >> 24) ] ^\n\t Td1[(s2 >> 16) & 0xff] ^\n\t Td2[(s1 >> 8) & 0xff] ^\n\t Td3[(s0 ) & 0xff] ^\n\t rk[7];\n\n\trk += 8;\n\tif (--r == 0) {\n\t break;\n\t}\n\n\ts0 =\n\t Td0[(t0 >> 24) ] ^\n\t Td1[(t3 >> 16) & 0xff] ^\n\t Td2[(t2 >> 8) & 0xff] ^\n\t Td3[(t1 ) & 0xff] ^\n\t rk[0];\n\ts1 =\n\t Td0[(t1 >> 24) ] ^\n\t Td1[(t0 >> 16) & 0xff] ^\n\t Td2[(t3 >> 8) & 0xff] ^\n\t Td3[(t2 ) & 0xff] ^\n\t rk[1];\n\ts2 =\n\t Td0[(t2 >> 24) ] ^\n\t Td1[(t1 >> 16) & 0xff] ^\n\t Td2[(t0 >> 8) & 0xff] ^\n\t Td3[(t3 ) & 0xff] ^\n\t rk[2];\n\ts3 =\n\t Td0[(t3 >> 24) ] ^\n\t Td1[(t2 >> 16) & 0xff] ^\n\t Td2[(t1 >> 8) & 0xff] ^\n\t Td3[(t0 ) & 0xff] ^\n\t rk[3];\n }\n#endif /* ?FULL_UNROLL */\n /*\n\t * apply last round and\n\t * map cipher state to byte array block:\n\t */\n \ts0 =\n \t\t(Td4[(t0 >> 24) ] << 24) ^\n \t\t(Td4[(t3 >> 16) & 0xff] << 16) ^\n \t\t(Td4[(t2 >> 8) & 0xff] << 8) ^\n \t\t(Td4[(t1 ) & 0xff]) ^\n \t\trk[0];\n\tPUTU32(pt , s0);\n \ts1 =\n \t\t(Td4[(t1 >> 24) ] << 24) ^\n \t\t(Td4[(t0 >> 16) & 0xff] << 16) ^\n \t\t(Td4[(t3 >> 8) & 0xff] << 8) ^\n \t\t(Td4[(t2 ) & 0xff]) ^\n \t\trk[1];\n\tPUTU32(pt + 4, s1);\n \ts2 =\n \t\t(Td4[(t2 >> 24) ] << 24) ^\n \t\t(Td4[(t1 >> 16) & 0xff] << 16) ^\n \t\t(Td4[(t0 >> 8) & 0xff] << 8) ^\n \t\t(Td4[(t3 ) & 0xff]) ^\n \t\trk[2];\n\tPUTU32(pt + 8, s2);\n \ts3 =\n \t\t(Td4[(t3 >> 24) ] << 24) ^\n \t\t(Td4[(t2 >> 16) & 0xff] << 16) ^\n \t\t(Td4[(t1 >> 8) & 0xff] << 8) ^\n \t\t(Td4[(t0 ) & 0xff]) ^\n \t\trk[3];\n\tPUTU32(pt + 12, s3);\n}\n#endif\n","/* $OpenBSD: msg.c,v 1.16 2015/01/15 09:40:00 djm Exp $ */\n/*\n * Copyright (c) 2002 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n\n#include \"sshbuf.h\"\n#include \"ssherr.h\"\n#include \"log.h\"\n#include \"atomicio.h\"\n#include \"msg.h\"\n#include \"misc.h\"\n\nint\nssh_msg_send(int fd, u_char type, struct sshbuf *m)\n{\n\tu_char buf[5];\n\tu_int mlen = sshbuf_len(m);\n\n\tdebug3(\"ssh_msg_send: type %u\", (unsigned int)type & 0xff);\n\n\tput_u32(buf, mlen + 1);\n\tbuf[4] = type;\t\t/* 1st byte of payload is mesg-type */\n\tif (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) {\n\t\terror(\"ssh_msg_send: write\");\n\t\treturn (-1);\n\t}\n\tif (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(m), mlen) != mlen) {\n\t\terror(\"ssh_msg_send: write\");\n\t\treturn (-1);\n\t}\n\treturn (0);\n}\n\nint\nssh_msg_recv(int fd, struct sshbuf *m)\n{\n\tu_char buf[4], *p;\n\tu_int msg_len;\n\tint r;\n\n\tdebug3(\"ssh_msg_recv entering\");\n\n\tif (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) {\n\t\tif (errno != EPIPE)\n\t\t\terror(\"ssh_msg_recv: read: header\");\n\t\treturn (-1);\n\t}\n\tmsg_len = get_u32(buf);\n\tif (msg_len > 256 * 1024) {\n\t\terror(\"ssh_msg_recv: read: bad msg_len %u\", msg_len);\n\t\treturn (-1);\n\t}\n\tsshbuf_reset(m);\n\tif ((r = sshbuf_reserve(m, msg_len, &p)) != 0) {\n\t\terror(\"%s: buffer error: %s\", __func__, ssh_err(r));\n\t\treturn -1;\n\t}\n\tif (atomicio(read, fd, p, msg_len) != msg_len) {\n\t\terror(\"ssh_msg_recv: read: %s\", strerror(errno));\n\t\treturn (-1);\n\t}\n\treturn (0);\n}\n","/* $OpenBSD: dns.c,v 1.35 2015/08/20 22:32:42 deraadt Exp $ */\n\n/*\n * Copyright (c) 2003 Wesley Griffin. All rights reserved.\n * Copyright (c) 2003 Jakob Schlyter. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"sshkey.h\"\n#include \"ssherr.h\"\n#include \"dns.h\"\n#include \"log.h\"\n#include \"digest.h\"\n\nstatic const char *errset_text[] = {\n\t\"success\",\t\t/* 0 ERRSET_SUCCESS */\n\t\"out of memory\",\t/* 1 ERRSET_NOMEMORY */\n\t\"general failure\",\t/* 2 ERRSET_FAIL */\n\t\"invalid parameter\",\t/* 3 ERRSET_INVAL */\n\t\"name does not exist\",\t/* 4 ERRSET_NONAME */\n\t\"data does not exist\",\t/* 5 ERRSET_NODATA */\n};\n\nstatic const char *\ndns_result_totext(unsigned int res)\n{\n\tswitch (res) {\n\tcase ERRSET_SUCCESS:\n\t\treturn errset_text[ERRSET_SUCCESS];\n\tcase ERRSET_NOMEMORY:\n\t\treturn errset_text[ERRSET_NOMEMORY];\n\tcase ERRSET_FAIL:\n\t\treturn errset_text[ERRSET_FAIL];\n\tcase ERRSET_INVAL:\n\t\treturn errset_text[ERRSET_INVAL];\n\tcase ERRSET_NONAME:\n\t\treturn errset_text[ERRSET_NONAME];\n\tcase ERRSET_NODATA:\n\t\treturn errset_text[ERRSET_NODATA];\n\tdefault:\n\t\treturn \"unknown error\";\n\t}\n}\n\n/*\n * Read SSHFP parameters from key buffer.\n */\nstatic int\ndns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,\n u_char **digest, size_t *digest_len, struct sshkey *key)\n{\n\tint r, success = 0;\n\tint fp_alg = -1;\n\n\tswitch (key->type) {\n\tcase KEY_RSA:\n\t\t*algorithm = SSHFP_KEY_RSA;\n\t\tif (!*digest_type)\n\t\t\t*digest_type = SSHFP_HASH_SHA1;\n\t\tbreak;\n\tcase KEY_DSA:\n\t\t*algorithm = SSHFP_KEY_DSA;\n\t\tif (!*digest_type)\n\t\t\t*digest_type = SSHFP_HASH_SHA1;\n\t\tbreak;\n\tcase KEY_ECDSA:\n\t\t*algorithm = SSHFP_KEY_ECDSA;\n\t\tif (!*digest_type)\n\t\t\t*digest_type = SSHFP_HASH_SHA256;\n\t\tbreak;\n\tcase KEY_ED25519:\n\t\t*algorithm = SSHFP_KEY_ED25519;\n\t\tif (!*digest_type)\n\t\t\t*digest_type = SSHFP_HASH_SHA256;\n\t\tbreak;\n\tdefault:\n\t\t*algorithm = SSHFP_KEY_RESERVED; /* 0 */\n\t\t*digest_type = SSHFP_HASH_RESERVED; /* 0 */\n\t}\n\n\tswitch (*digest_type) {\n\tcase SSHFP_HASH_SHA1:\n\t\tfp_alg = SSH_DIGEST_SHA1;\n\t\tbreak;\n\tcase SSHFP_HASH_SHA256:\n\t\tfp_alg = SSH_DIGEST_SHA256;\n\t\tbreak;\n\tdefault:\n\t\t*digest_type = SSHFP_HASH_RESERVED; /* 0 */\n\t}\n\n\tif (*algorithm && *digest_type) {\n\t\tif ((r = sshkey_fingerprint_raw(key, fp_alg, digest,\n\t\t digest_len)) != 0)\n\t\t\tfatal(\"%s: sshkey_fingerprint_raw: %s\", __func__,\n\t\t\t ssh_err(r));\n\t\tsuccess = 1;\n\t} else {\n\t\t*digest = NULL;\n\t\t*digest_len = 0;\n\t\tsuccess = 0;\n\t}\n\n\treturn success;\n}\n\n/*\n * Read SSHFP parameters from rdata buffer.\n */\nstatic int\ndns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,\n u_char **digest, size_t *digest_len, u_char *rdata, int rdata_len)\n{\n\tint success = 0;\n\n\t*algorithm = SSHFP_KEY_RESERVED;\n\t*digest_type = SSHFP_HASH_RESERVED;\n\n\tif (rdata_len >= 2) {\n\t\t*algorithm = rdata[0];\n\t\t*digest_type = rdata[1];\n\t\t*digest_len = rdata_len - 2;\n\n\t\tif (*digest_len > 0) {\n\t\t\t*digest = xmalloc(*digest_len);\n\t\t\tmemcpy(*digest, rdata + 2, *digest_len);\n\t\t} else {\n\t\t\t*digest = (u_char *)xstrdup(\"\");\n\t\t}\n\n\t\tsuccess = 1;\n\t}\n\n\treturn success;\n}\n\n/*\n * Check if hostname is numerical.\n * Returns -1 if hostname is numeric, 0 otherwise\n */\nstatic int\nis_numeric_hostname(const char *hostname)\n{\n\tstruct addrinfo hints, *ai;\n\n\t/*\n\t * We shouldn't ever get a null host but if we do then log an error\n\t * and return -1 which stops DNS key fingerprint processing.\n\t */\n\tif (hostname == NULL) {\n\t\terror(\"is_numeric_hostname called with NULL hostname\");\n\t\treturn -1;\n\t}\n\n\tmemset(&hints, 0, sizeof(hints));\n\thints.ai_socktype = SOCK_DGRAM;\n\thints.ai_flags = AI_NUMERICHOST;\n\n\tif (getaddrinfo(hostname, NULL, &hints, &ai) == 0) {\n\t\tfreeaddrinfo(ai);\n\t\treturn -1;\n\t}\n\n\treturn 0;\n}\n\n/*\n * Verify the given hostname, address and host key using DNS.\n * Returns 0 if lookup succeeds, -1 otherwise\n */\nint\nverify_host_key_dns(const char *hostname, struct sockaddr *address,\n struct sshkey *hostkey, int *flags)\n{\n\tu_int counter;\n\tint result;\n\tstruct rrsetinfo *fingerprints = NULL;\n\n\tu_int8_t hostkey_algorithm;\n\tu_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED;\n\tu_char *hostkey_digest;\n\tsize_t hostkey_digest_len;\n\n\tu_int8_t dnskey_algorithm;\n\tu_int8_t dnskey_digest_type;\n\tu_char *dnskey_digest;\n\tsize_t dnskey_digest_len;\n\n\t*flags = 0;\n\n\tdebug3(\"verify_host_key_dns\");\n\tif (hostkey == NULL)\n\t\tfatal(\"No key to look up!\");\n\n\tif (is_numeric_hostname(hostname)) {\n\t\tdebug(\"skipped DNS lookup for numerical hostname\");\n\t\treturn -1;\n\t}\n\n\tresult = getrrsetbyname(hostname, DNS_RDATACLASS_IN,\n\t DNS_RDATATYPE_SSHFP, 0, &fingerprints);\n\tif (result) {\n\t\tverbose(\"DNS lookup error: %s\", dns_result_totext(result));\n\t\treturn -1;\n\t}\n\n\tif (fingerprints->rri_flags & RRSET_VALIDATED) {\n\t\t*flags |= DNS_VERIFY_SECURE;\n\t\tdebug(\"found %d secure fingerprints in DNS\",\n\t\t fingerprints->rri_nrdatas);\n\t} else {\n\t\tdebug(\"found %d insecure fingerprints in DNS\",\n\t\t fingerprints->rri_nrdatas);\n\t}\n\n\t/* Initialize default host key parameters */\n\tif (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,\n\t &hostkey_digest, &hostkey_digest_len, hostkey)) {\n\t\terror(\"Error calculating host key fingerprint.\");\n\t\tfreerrset(fingerprints);\n\t\treturn -1;\n\t}\n\n\tif (fingerprints->rri_nrdatas)\n\t\t*flags |= DNS_VERIFY_FOUND;\n\n\tfor (counter = 0; counter < fingerprints->rri_nrdatas; counter++) {\n\t\t/*\n\t\t * Extract the key from the answer. Ignore any badly\n\t\t * formatted fingerprints.\n\t\t */\n\t\tif (!dns_read_rdata(&dnskey_algorithm, &dnskey_digest_type,\n\t\t &dnskey_digest, &dnskey_digest_len,\n\t\t fingerprints->rri_rdatas[counter].rdi_data,\n\t\t fingerprints->rri_rdatas[counter].rdi_length)) {\n\t\t\tverbose(\"Error parsing fingerprint from DNS.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (hostkey_digest_type != dnskey_digest_type) {\n\t\t\thostkey_digest_type = dnskey_digest_type;\n\t\t\tfree(hostkey_digest);\n\n\t\t\t/* Initialize host key parameters */\n\t\t\tif (!dns_read_key(&hostkey_algorithm,\n\t\t\t &hostkey_digest_type, &hostkey_digest,\n\t\t\t &hostkey_digest_len, hostkey)) {\n\t\t\t\terror(\"Error calculating key fingerprint.\");\n\t\t\t\tfreerrset(fingerprints);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\n\t\t/* Check if the current key is the same as the given key */\n\t\tif (hostkey_algorithm == dnskey_algorithm &&\n\t\t hostkey_digest_type == dnskey_digest_type) {\n\t\t\tif (hostkey_digest_len == dnskey_digest_len &&\n\t\t\t timingsafe_bcmp(hostkey_digest, dnskey_digest,\n\t\t\t hostkey_digest_len) == 0)\n\t\t\t\t*flags |= DNS_VERIFY_MATCH;\n\t\t}\n\t\tfree(dnskey_digest);\n\t}\n\n\tfree(hostkey_digest); /* from sshkey_fingerprint_raw() */\n\tfreerrset(fingerprints);\n\n\tif (*flags & DNS_VERIFY_FOUND)\n\t\tif (*flags & DNS_VERIFY_MATCH)\n\t\t\tdebug(\"matching host key fingerprint found in DNS\");\n\t\telse\n\t\t\tdebug(\"mismatching host key fingerprint found in DNS\");\n\telse\n\t\tdebug(\"no host key fingerprint found in DNS\");\n\n\treturn 0;\n}\n\n/*\n * Export the fingerprint of a key as a DNS resource record\n */\nint\nexport_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic)\n{\n\tu_int8_t rdata_pubkey_algorithm = 0;\n\tu_int8_t rdata_digest_type = SSHFP_HASH_RESERVED;\n\tu_int8_t dtype;\n\tu_char *rdata_digest;\n\tsize_t i, rdata_digest_len;\n\tint success = 0;\n\n\tfor (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) {\n\t\trdata_digest_type = dtype;\n\t\tif (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,\n\t\t &rdata_digest, &rdata_digest_len, key)) {\n\t\t\tif (generic) {\n\t\t\t\tfprintf(f, \"%s IN TYPE%d \\\\# %zu %02x %02x \",\n\t\t\t\t hostname, DNS_RDATATYPE_SSHFP,\n\t\t\t\t 2 + rdata_digest_len,\n\t\t\t\t rdata_pubkey_algorithm, rdata_digest_type);\n\t\t\t} else {\n\t\t\t\tfprintf(f, \"%s IN SSHFP %d %d \", hostname,\n\t\t\t\t rdata_pubkey_algorithm, rdata_digest_type);\n\t\t\t}\n\t\t\tfor (i = 0; i < rdata_digest_len; i++)\n\t\t\t\tfprintf(f, \"%02x\", rdata_digest[i]);\n\t\t\tfprintf(f, \"\\n\");\n\t\t\tfree(rdata_digest); /* from sshkey_fingerprint_raw() */\n\t\t\tsuccess = 1;\n\t\t}\n\t}\n\n\t/* No SSHFP record was generated at all */\n\tif (success == 0) {\n\t\terror(\"%s: unsupported algorithm and/or digest_type\", __func__);\n\t}\n\n\treturn success;\n}\n","/*\n * Copyright (c) 2001 Damien Miller. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#ifdef WITH_OPENSSL\n\n#include \n#include \n#ifdef HAVE_SYS_UN_H\n# include \n#endif\n\n#include \n#include \n\n#include \n#include \n#include \n#include \n#include /* for offsetof */\n\n#include \n#include \n#include \n\n#include \"openbsd-compat/openssl-compat.h\"\n\n#include \"ssh.h\"\n#include \"misc.h\"\n#include \"xmalloc.h\"\n#include \"atomicio.h\"\n#include \"pathnames.h\"\n#include \"log.h\"\n#include \"buffer.h\"\n\n/*\n * Portable OpenSSH PRNG seeding:\n * If OpenSSL has not \"internally seeded\" itself (e.g. pulled data from\n * /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from\n * PRNGd.\n */\n#ifndef OPENSSL_PRNG_ONLY\n\n#define RANDOM_SEED_SIZE 48\n\n/*\n * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon\n * listening either on 'tcp_port', or via Unix domain socket at *\n * 'socket_path'.\n * Either a non-zero tcp_port or a non-null socket_path must be\n * supplied.\n * Returns 0 on success, -1 on error\n */\nint\nget_random_bytes_prngd(unsigned char *buf, int len,\n unsigned short tcp_port, char *socket_path)\n{\n\tint fd, addr_len, rval, errors;\n\tu_char msg[2];\n\tstruct sockaddr_storage addr;\n\tstruct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;\n\tstruct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;\n\tmysig_t old_sigpipe;\n\n\t/* Sanity checks */\n\tif (socket_path == NULL && tcp_port == 0)\n\t\tfatal(\"You must specify a port or a socket\");\n\tif (socket_path != NULL &&\n\t strlen(socket_path) >= sizeof(addr_un->sun_path))\n\t\tfatal(\"Random pool path is too long\");\n\tif (len <= 0 || len > 255)\n\t\tfatal(\"Too many bytes (%d) to read from PRNGD\", len);\n\n\tmemset(&addr, '\\0', sizeof(addr));\n\n\tif (tcp_port != 0) {\n\t\taddr_in->sin_family = AF_INET;\n\t\taddr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n\t\taddr_in->sin_port = htons(tcp_port);\n\t\taddr_len = sizeof(*addr_in);\n\t} else {\n\t\taddr_un->sun_family = AF_UNIX;\n\t\tstrlcpy(addr_un->sun_path, socket_path,\n\t\t sizeof(addr_un->sun_path));\n\t\taddr_len = offsetof(struct sockaddr_un, sun_path) +\n\t\t strlen(socket_path) + 1;\n\t}\n\n\told_sigpipe = mysignal(SIGPIPE, SIG_IGN);\n\n\terrors = 0;\n\trval = -1;\nreopen:\n\tfd = socket(addr.ss_family, SOCK_STREAM, 0);\n\tif (fd == -1) {\n\t\terror(\"Couldn't create socket: %s\", strerror(errno));\n\t\tgoto done;\n\t}\n\n\tif (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {\n\t\tif (tcp_port != 0) {\n\t\t\terror(\"Couldn't connect to PRNGD port %d: %s\",\n\t\t\t tcp_port, strerror(errno));\n\t\t} else {\n\t\t\terror(\"Couldn't connect to PRNGD socket \\\"%s\\\": %s\",\n\t\t\t addr_un->sun_path, strerror(errno));\n\t\t}\n\t\tgoto done;\n\t}\n\n\t/* Send blocking read request to PRNGD */\n\tmsg[0] = 0x02;\n\tmsg[1] = len;\n\n\tif (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) {\n\t\tif (errno == EPIPE && errors < 10) {\n\t\t\tclose(fd);\n\t\t\terrors++;\n\t\t\tgoto reopen;\n\t\t}\n\t\terror(\"Couldn't write to PRNGD socket: %s\",\n\t\t strerror(errno));\n\t\tgoto done;\n\t}\n\n\tif (atomicio(read, fd, buf, len) != (size_t)len) {\n\t\tif (errno == EPIPE && errors < 10) {\n\t\t\tclose(fd);\n\t\t\terrors++;\n\t\t\tgoto reopen;\n\t\t}\n\t\terror(\"Couldn't read from PRNGD socket: %s\",\n\t\t strerror(errno));\n\t\tgoto done;\n\t}\n\n\trval = 0;\ndone:\n\tmysignal(SIGPIPE, old_sigpipe);\n\tif (fd != -1)\n\t\tclose(fd);\n\treturn rval;\n}\n\nstatic int\nseed_from_prngd(unsigned char *buf, size_t bytes)\n{\n#ifdef PRNGD_PORT\n\tdebug(\"trying egd/prngd port %d\", PRNGD_PORT);\n\tif (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == 0)\n\t\treturn 0;\n#endif\n#ifdef PRNGD_SOCKET\n\tdebug(\"trying egd/prngd socket %s\", PRNGD_SOCKET);\n\tif (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == 0)\n\t\treturn 0;\n#endif\n\treturn -1;\n}\n\nvoid\nrexec_send_rng_seed(Buffer *m)\n{\n\tu_char buf[RANDOM_SEED_SIZE];\n\n\tif (RAND_bytes(buf, sizeof(buf)) <= 0) {\n\t\terror(\"Couldn't obtain random bytes (error %ld)\",\n\t\t ERR_get_error());\n\t\tbuffer_put_string(m, \"\", 0);\n\t} else \n\t\tbuffer_put_string(m, buf, sizeof(buf));\n}\n\nvoid\nrexec_recv_rng_seed(Buffer *m)\n{\n\tu_char *buf;\n\tu_int len;\n\n\tbuf = buffer_get_string_ret(m, &len);\n\tif (buf != NULL) {\n\t\tdebug3(\"rexec_recv_rng_seed: seeding rng with %u bytes\", len);\n\t\tRAND_add(buf, len, len);\n\t}\n}\n#endif /* OPENSSL_PRNG_ONLY */\n\nvoid\nseed_rng(void)\n{\n#ifndef OPENSSL_PRNG_ONLY\n\tunsigned char buf[RANDOM_SEED_SIZE];\n#endif\n\tif (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, SSLeay()))\n\t\tfatal(\"OpenSSL version mismatch. Built against %lx, you \"\n\t\t \"have %lx\", (u_long)OPENSSL_VERSION_NUMBER, SSLeay());\n\n#ifndef OPENSSL_PRNG_ONLY\n\tif (RAND_status() == 1) {\n\t\tdebug3(\"RNG is ready, skipping seeding\");\n\t\treturn;\n\t}\n\n\tif (seed_from_prngd(buf, sizeof(buf)) == -1)\n\t\tfatal(\"Could not obtain seed from PRNGd\");\n\tRAND_add(buf, sizeof(buf), sizeof(buf));\n\tmemset(buf, '\\0', sizeof(buf));\n\n#endif /* OPENSSL_PRNG_ONLY */\n\tif (RAND_status() != 1)\n\t\tfatal(\"PRNG is not seeded\");\n}\n\n#else /* WITH_OPENSSL */\n\n/* Handled in arc4random() */\nvoid\nseed_rng(void)\n{\n}\n\n#endif /* WITH_OPENSSL */\n","/* $OpenBSD: umac.c,v 1.11 2014/07/22 07:13:42 guenther Exp $ */\n/* -----------------------------------------------------------------------\n * \n * umac.c -- C Implementation UMAC Message Authentication\n *\n * Version 0.93b of rfc4418.txt -- 2006 July 18\n *\n * For a full description of UMAC message authentication see the UMAC\n * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac\n * Please report bugs and suggestions to the UMAC webpage.\n *\n * Copyright (c) 1999-2006 Ted Krovetz\n * \n * Permission to use, copy, modify, and distribute this software and\n * its documentation for any purpose and with or without fee, is hereby\n * granted provided that the above copyright notice appears in all copies\n * and in supporting documentation, and that the name of the copyright\n * holder not be used in advertising or publicity pertaining to\n * distribution of the software without specific, written prior permission.\n *\n * Comments should be directed to Ted Krovetz (tdk@acm.org) \n * \n * ---------------------------------------------------------------------- */\n \n /* ////////////////////// IMPORTANT NOTES /////////////////////////////////\n *\n * 1) This version does not work properly on messages larger than 16MB\n *\n * 2) If you set the switch to use SSE2, then all data must be 16-byte\n * aligned\n *\n * 3) When calling the function umac(), it is assumed that msg is in\n * a writable buffer of length divisible by 32 bytes. The message itself\n * does not have to fill the entire buffer, but bytes beyond msg may be\n * zeroed.\n *\n * 4) Three free AES implementations are supported by this implementation of\n * UMAC. Paulo Barreto's version is in the public domain and can be found\n * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for\n * \"Barreto\"). The only two files needed are rijndael-alg-fst.c and\n * rijndael-alg-fst.h. Brian Gladman's version is distributed with the GNU\n * Public lisence at http://fp.gladman.plus.com/AES/index.htm. It\n * includes a fast IA-32 assembly version. The OpenSSL crypo library is\n * the third.\n *\n * 5) With FORCE_C_ONLY flags set to 0, incorrect results are sometimes\n * produced under gcc with optimizations set -O3 or higher. Dunno why.\n *\n /////////////////////////////////////////////////////////////////////// */\n \n/* ---------------------------------------------------------------------- */\n/* --- User Switches ---------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n#ifndef UMAC_OUTPUT_LEN\n#define UMAC_OUTPUT_LEN 8 /* Alowable: 4, 8, 12, 16 */\n#endif\n\n#if UMAC_OUTPUT_LEN != 4 && UMAC_OUTPUT_LEN != 8 && \\\n UMAC_OUTPUT_LEN != 12 && UMAC_OUTPUT_LEN != 16\n# error UMAC_OUTPUT_LEN must be defined to 4, 8, 12 or 16\n#endif\n\n/* #define FORCE_C_ONLY 1 ANSI C and 64-bit integers req'd */\n/* #define AES_IMPLEMENTAION 1 1 = OpenSSL, 2 = Barreto, 3 = Gladman */\n/* #define SSE2 0 Is SSE2 is available? */\n/* #define RUN_TESTS 0 Run basic correctness/speed tests */\n/* #define UMAC_AE_SUPPORT 0 Enable auhthenticated encrytion */\n\n/* ---------------------------------------------------------------------- */\n/* -- Global Includes --------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n#include \"includes.h\"\n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"umac.h\"\n#include \"misc.h\"\n\n/* ---------------------------------------------------------------------- */\n/* --- Primitive Data Types --- */\n/* ---------------------------------------------------------------------- */\n\n/* The following assumptions may need change on your system */\ntypedef u_int8_t\tUINT8; /* 1 byte */\ntypedef u_int16_t\tUINT16; /* 2 byte */\ntypedef u_int32_t\tUINT32; /* 4 byte */\ntypedef u_int64_t\tUINT64; /* 8 bytes */\ntypedef unsigned int\tUWORD; /* Register */\n\n/* ---------------------------------------------------------------------- */\n/* --- Constants -------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n#define UMAC_KEY_LEN 16 /* UMAC takes 16 bytes of external key */\n\n/* Message \"words\" are read from memory in an endian-specific manner. */\n/* For this implementation to behave correctly, __LITTLE_ENDIAN__ must */\n/* be set true if the host computer is little-endian. */\n\n#if BYTE_ORDER == LITTLE_ENDIAN\n#define __LITTLE_ENDIAN__ 1\n#else\n#define __LITTLE_ENDIAN__ 0\n#endif\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Architecture Specific ------------------------------------------ */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Primitive Routines --------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n\n/* ---------------------------------------------------------------------- */\n/* --- 32-bit by 32-bit to 64-bit Multiplication ------------------------ */\n/* ---------------------------------------------------------------------- */\n\n#define MUL64(a,b) ((UINT64)((UINT64)(UINT32)(a) * (UINT64)(UINT32)(b)))\n\n/* ---------------------------------------------------------------------- */\n/* --- Endian Conversion --- Forcing assembly on some platforms */\n/* ---------------------------------------------------------------------- */\n\n#if (__LITTLE_ENDIAN__)\n#define LOAD_UINT32_REVERSED(p)\t\tget_u32(p)\n#define STORE_UINT32_REVERSED(p,v)\tput_u32(p,v)\n#else\n#define LOAD_UINT32_REVERSED(p)\t\tget_u32_le(p)\n#define STORE_UINT32_REVERSED(p,v)\tput_u32_le(p,v)\n#endif\n\n#define LOAD_UINT32_LITTLE(p)\t\t(get_u32_le(p))\n#define STORE_UINT32_BIG(p,v)\t\tput_u32(p, v)\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin KDF & PDF Section ---------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* UMAC uses AES with 16 byte block and key lengths */\n#define AES_BLOCK_LEN 16\n\n/* OpenSSL's AES */\n#ifdef WITH_OPENSSL\n#include \"openbsd-compat/openssl-compat.h\"\n#ifndef USE_BUILTIN_RIJNDAEL\n# include \n#endif\ntypedef AES_KEY aes_int_key[1];\n#define aes_encryption(in,out,int_key) \\\n AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key)\n#define aes_key_setup(key,int_key) \\\n AES_set_encrypt_key((const u_char *)(key),UMAC_KEY_LEN*8,int_key)\n#else\n#include \"rijndael.h\"\n#define AES_ROUNDS ((UMAC_KEY_LEN / 4) + 6)\ntypedef UINT8 aes_int_key[AES_ROUNDS+1][4][4];\t/* AES internal */\n#define aes_encryption(in,out,int_key) \\\n rijndaelEncrypt((u32 *)(int_key), AES_ROUNDS, (u8 *)(in), (u8 *)(out))\n#define aes_key_setup(key,int_key) \\\n rijndaelKeySetupEnc((u32 *)(int_key), (const unsigned char *)(key), \\\n UMAC_KEY_LEN*8)\n#endif\n\n/* The user-supplied UMAC key is stretched using AES in a counter\n * mode to supply all random bits needed by UMAC. The kdf function takes\n * an AES internal key representation 'key' and writes a stream of\n * 'nbytes' bytes to the memory pointed at by 'bufp'. Each distinct\n * 'ndx' causes a distinct byte stream.\n */\nstatic void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes)\n{\n UINT8 in_buf[AES_BLOCK_LEN] = {0};\n UINT8 out_buf[AES_BLOCK_LEN];\n UINT8 *dst_buf = (UINT8 *)bufp;\n int i;\n \n /* Setup the initial value */\n in_buf[AES_BLOCK_LEN-9] = ndx;\n in_buf[AES_BLOCK_LEN-1] = i = 1;\n \n while (nbytes >= AES_BLOCK_LEN) {\n aes_encryption(in_buf, out_buf, key);\n memcpy(dst_buf,out_buf,AES_BLOCK_LEN);\n in_buf[AES_BLOCK_LEN-1] = ++i;\n nbytes -= AES_BLOCK_LEN;\n dst_buf += AES_BLOCK_LEN;\n }\n if (nbytes) {\n aes_encryption(in_buf, out_buf, key);\n memcpy(dst_buf,out_buf,nbytes);\n }\n}\n\n/* The final UHASH result is XOR'd with the output of a pseudorandom\n * function. Here, we use AES to generate random output and \n * xor the appropriate bytes depending on the last bits of nonce.\n * This scheme is optimized for sequential, increasing big-endian nonces.\n */\n\ntypedef struct {\n UINT8 cache[AES_BLOCK_LEN]; /* Previous AES output is saved */\n UINT8 nonce[AES_BLOCK_LEN]; /* The AES input making above cache */\n aes_int_key prf_key; /* Expanded AES key for PDF */\n} pdf_ctx;\n\nstatic void pdf_init(pdf_ctx *pc, aes_int_key prf_key)\n{\n UINT8 buf[UMAC_KEY_LEN];\n \n kdf(buf, prf_key, 0, UMAC_KEY_LEN);\n aes_key_setup(buf, pc->prf_key);\n \n /* Initialize pdf and cache */\n memset(pc->nonce, 0, sizeof(pc->nonce));\n aes_encryption(pc->nonce, pc->cache, pc->prf_key);\n}\n\nstatic void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])\n{\n /* 'ndx' indicates that we'll be using the 0th or 1st eight bytes\n * of the AES output. If last time around we returned the ndx-1st\n * element, then we may have the result in the cache already.\n */\n \n#if (UMAC_OUTPUT_LEN == 4)\n#define LOW_BIT_MASK 3\n#elif (UMAC_OUTPUT_LEN == 8)\n#define LOW_BIT_MASK 1\n#elif (UMAC_OUTPUT_LEN > 8)\n#define LOW_BIT_MASK 0\n#endif\n union {\n UINT8 tmp_nonce_lo[4];\n UINT32 align;\n } t;\n#if LOW_BIT_MASK != 0\n int ndx = nonce[7] & LOW_BIT_MASK;\n#endif\n *(UINT32 *)t.tmp_nonce_lo = ((const UINT32 *)nonce)[1];\n t.tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */\n \n if ( (((UINT32 *)t.tmp_nonce_lo)[0] != ((UINT32 *)pc->nonce)[1]) ||\n (((const UINT32 *)nonce)[0] != ((UINT32 *)pc->nonce)[0]) )\n {\n ((UINT32 *)pc->nonce)[0] = ((const UINT32 *)nonce)[0];\n ((UINT32 *)pc->nonce)[1] = ((UINT32 *)t.tmp_nonce_lo)[0];\n aes_encryption(pc->nonce, pc->cache, pc->prf_key);\n }\n \n#if (UMAC_OUTPUT_LEN == 4)\n *((UINT32 *)buf) ^= ((UINT32 *)pc->cache)[ndx];\n#elif (UMAC_OUTPUT_LEN == 8)\n *((UINT64 *)buf) ^= ((UINT64 *)pc->cache)[ndx];\n#elif (UMAC_OUTPUT_LEN == 12)\n ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0];\n ((UINT32 *)buf)[2] ^= ((UINT32 *)pc->cache)[2];\n#elif (UMAC_OUTPUT_LEN == 16)\n ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0];\n ((UINT64 *)buf)[1] ^= ((UINT64 *)pc->cache)[1];\n#endif\n}\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin NH Hash Section ------------------------------------------ */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* The NH-based hash functions used in UMAC are described in the UMAC paper\n * and specification, both of which can be found at the UMAC website. \n * The interface to this implementation has two \n * versions, one expects the entire message being hashed to be passed\n * in a single buffer and returns the hash result immediately. The second\n * allows the message to be passed in a sequence of buffers. In the \n * muliple-buffer interface, the client calls the routine nh_update() as \n * many times as necessary. When there is no more data to be fed to the \n * hash, the client calls nh_final() which calculates the hash output. \n * Before beginning another hash calculation the nh_reset() routine \n * must be called. The single-buffer routine, nh(), is equivalent to \n * the sequence of calls nh_update() and nh_final(); however it is \n * optimized and should be prefered whenever the multiple-buffer interface\n * is not necessary. When using either interface, it is the client's \n * responsability to pass no more than L1_KEY_LEN bytes per hash result. \n * \n * The routine nh_init() initializes the nh_ctx data structure and \n * must be called once, before any other PDF routine. \n */\n \n /* The \"nh_aux\" routines do the actual NH hashing work. They\n * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines\n * produce output for all STREAMS NH iterations in one call, \n * allowing the parallel implementation of the streams.\n */\n\n#define STREAMS (UMAC_OUTPUT_LEN / 4) /* Number of times hash is applied */\n#define L1_KEY_LEN 1024 /* Internal key bytes */\n#define L1_KEY_SHIFT 16 /* Toeplitz key shift between streams */\n#define L1_PAD_BOUNDARY 32 /* pad message to boundary multiple */\n#define ALLOC_BOUNDARY 16 /* Keep buffers aligned to this */\n#define HASH_BUF_BYTES 64 /* nh_aux_hb buffer multiple */\n\ntypedef struct {\n UINT8 nh_key [L1_KEY_LEN + L1_KEY_SHIFT * (STREAMS - 1)]; /* NH Key */\n UINT8 data [HASH_BUF_BYTES]; /* Incoming data buffer */\n int next_data_empty; /* Bookeeping variable for data buffer. */\n int bytes_hashed; /* Bytes (out of L1_KEY_LEN) incorperated. */\n UINT64 state[STREAMS]; /* on-line state */\n} nh_ctx;\n\n\n#if (UMAC_OUTPUT_LEN == 4)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* NH hashing primitive. Previous (partial) hash result is loaded and \n* then stored via hp pointer. The length of the data pointed at by \"dp\",\n* \"dlen\", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key\n* is expected to be endian compensated in memory at key setup. \n*/\n{\n UINT64 h;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7;\n \n h = *((UINT64 *)hp);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n h += MUL64((k0 + d0), (k4 + d4));\n h += MUL64((k1 + d1), (k5 + d5));\n h += MUL64((k2 + d2), (k6 + d6));\n h += MUL64((k3 + d3), (k7 + d7));\n \n d += 8;\n k += 8;\n } while (--c);\n *((UINT64 *)hp) = h;\n}\n\n#elif (UMAC_OUTPUT_LEN == 8)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* Same as previous nh_aux, but two streams are handled in one pass,\n * reading and writing 16 bytes of hash-state per call.\n */\n{\n UINT64 h1,h2;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7,\n k8,k9,k10,k11;\n\n h1 = *((UINT64 *)hp);\n h2 = *((UINT64 *)hp + 1);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);\n\n h1 += MUL64((k0 + d0), (k4 + d4));\n h2 += MUL64((k4 + d0), (k8 + d4));\n\n h1 += MUL64((k1 + d1), (k5 + d5));\n h2 += MUL64((k5 + d1), (k9 + d5));\n\n h1 += MUL64((k2 + d2), (k6 + d6));\n h2 += MUL64((k6 + d2), (k10 + d6));\n\n h1 += MUL64((k3 + d3), (k7 + d7));\n h2 += MUL64((k7 + d3), (k11 + d7));\n\n k0 = k8; k1 = k9; k2 = k10; k3 = k11;\n\n d += 8;\n k += 8;\n } while (--c);\n ((UINT64 *)hp)[0] = h1;\n ((UINT64 *)hp)[1] = h2;\n}\n\n#elif (UMAC_OUTPUT_LEN == 12)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* Same as previous nh_aux, but two streams are handled in one pass,\n * reading and writing 24 bytes of hash-state per call.\n*/\n{\n UINT64 h1,h2,h3;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7,\n k8,k9,k10,k11,k12,k13,k14,k15;\n \n h1 = *((UINT64 *)hp);\n h2 = *((UINT64 *)hp + 1);\n h3 = *((UINT64 *)hp + 2);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);\n k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);\n \n h1 += MUL64((k0 + d0), (k4 + d4));\n h2 += MUL64((k4 + d0), (k8 + d4));\n h3 += MUL64((k8 + d0), (k12 + d4));\n \n h1 += MUL64((k1 + d1), (k5 + d5));\n h2 += MUL64((k5 + d1), (k9 + d5));\n h3 += MUL64((k9 + d1), (k13 + d5));\n \n h1 += MUL64((k2 + d2), (k6 + d6));\n h2 += MUL64((k6 + d2), (k10 + d6));\n h3 += MUL64((k10 + d2), (k14 + d6));\n \n h1 += MUL64((k3 + d3), (k7 + d7));\n h2 += MUL64((k7 + d3), (k11 + d7));\n h3 += MUL64((k11 + d3), (k15 + d7));\n \n k0 = k8; k1 = k9; k2 = k10; k3 = k11;\n k4 = k12; k5 = k13; k6 = k14; k7 = k15;\n \n d += 8;\n k += 8;\n } while (--c);\n ((UINT64 *)hp)[0] = h1;\n ((UINT64 *)hp)[1] = h2;\n ((UINT64 *)hp)[2] = h3;\n}\n\n#elif (UMAC_OUTPUT_LEN == 16)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* Same as previous nh_aux, but two streams are handled in one pass,\n * reading and writing 24 bytes of hash-state per call.\n*/\n{\n UINT64 h1,h2,h3,h4;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7,\n k8,k9,k10,k11,k12,k13,k14,k15,\n k16,k17,k18,k19;\n \n h1 = *((UINT64 *)hp);\n h2 = *((UINT64 *)hp + 1);\n h3 = *((UINT64 *)hp + 2);\n h4 = *((UINT64 *)hp + 3);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);\n k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);\n k16 = *(k+16); k17 = *(k+17); k18 = *(k+18); k19 = *(k+19);\n \n h1 += MUL64((k0 + d0), (k4 + d4));\n h2 += MUL64((k4 + d0), (k8 + d4));\n h3 += MUL64((k8 + d0), (k12 + d4));\n h4 += MUL64((k12 + d0), (k16 + d4));\n \n h1 += MUL64((k1 + d1), (k5 + d5));\n h2 += MUL64((k5 + d1), (k9 + d5));\n h3 += MUL64((k9 + d1), (k13 + d5));\n h4 += MUL64((k13 + d1), (k17 + d5));\n \n h1 += MUL64((k2 + d2), (k6 + d6));\n h2 += MUL64((k6 + d2), (k10 + d6));\n h3 += MUL64((k10 + d2), (k14 + d6));\n h4 += MUL64((k14 + d2), (k18 + d6));\n \n h1 += MUL64((k3 + d3), (k7 + d7));\n h2 += MUL64((k7 + d3), (k11 + d7));\n h3 += MUL64((k11 + d3), (k15 + d7));\n h4 += MUL64((k15 + d3), (k19 + d7));\n \n k0 = k8; k1 = k9; k2 = k10; k3 = k11;\n k4 = k12; k5 = k13; k6 = k14; k7 = k15;\n k8 = k16; k9 = k17; k10 = k18; k11 = k19;\n \n d += 8;\n k += 8;\n } while (--c);\n ((UINT64 *)hp)[0] = h1;\n ((UINT64 *)hp)[1] = h2;\n ((UINT64 *)hp)[2] = h3;\n ((UINT64 *)hp)[3] = h4;\n}\n\n/* ---------------------------------------------------------------------- */\n#endif /* UMAC_OUTPUT_LENGTH */\n/* ---------------------------------------------------------------------- */\n\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_transform(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)\n/* This function is a wrapper for the primitive NH hash functions. It takes\n * as argument \"hc\" the current hash context and a buffer which must be a\n * multiple of L1_PAD_BOUNDARY. The key passed to nh_aux is offset\n * appropriately according to how much message has been hashed already.\n */\n{\n UINT8 *key;\n \n key = hc->nh_key + hc->bytes_hashed;\n nh_aux(key, buf, hc->state, nbytes);\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if (__LITTLE_ENDIAN__)\nstatic void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes)\n/* We endian convert the keys on little-endian computers to */\n/* compensate for the lack of big-endian memory reads during hashing. */\n{\n UWORD iters = num_bytes / bpw;\n if (bpw == 4) {\n UINT32 *p = (UINT32 *)buf;\n do {\n *p = LOAD_UINT32_REVERSED(p);\n p++;\n } while (--iters);\n } else if (bpw == 8) {\n UINT32 *p = (UINT32 *)buf;\n UINT32 t;\n do {\n t = LOAD_UINT32_REVERSED(p+1);\n p[1] = LOAD_UINT32_REVERSED(p);\n p[0] = t;\n p += 2;\n } while (--iters);\n }\n}\n#define endian_convert_if_le(x,y,z) endian_convert((x),(y),(z))\n#else\n#define endian_convert_if_le(x,y,z) do{}while(0) /* Do nothing */\n#endif\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_reset(nh_ctx *hc)\n/* Reset nh_ctx to ready for hashing of new data */\n{\n hc->bytes_hashed = 0;\n hc->next_data_empty = 0;\n hc->state[0] = 0;\n#if (UMAC_OUTPUT_LEN >= 8)\n hc->state[1] = 0;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n hc->state[2] = 0;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n hc->state[3] = 0;\n#endif\n\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_init(nh_ctx *hc, aes_int_key prf_key)\n/* Generate nh_key, endian convert and reset to be ready for hashing. */\n{\n kdf(hc->nh_key, prf_key, 1, sizeof(hc->nh_key));\n endian_convert_if_le(hc->nh_key, 4, sizeof(hc->nh_key));\n nh_reset(hc);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_update(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)\n/* Incorporate nbytes of data into a nh_ctx, buffer whatever is not an */\n/* even multiple of HASH_BUF_BYTES. */\n{\n UINT32 i,j;\n \n j = hc->next_data_empty;\n if ((j + nbytes) >= HASH_BUF_BYTES) {\n if (j) {\n i = HASH_BUF_BYTES - j;\n memcpy(hc->data+j, buf, i);\n nh_transform(hc,hc->data,HASH_BUF_BYTES);\n nbytes -= i;\n buf += i;\n hc->bytes_hashed += HASH_BUF_BYTES;\n }\n if (nbytes >= HASH_BUF_BYTES) {\n i = nbytes & ~(HASH_BUF_BYTES - 1);\n nh_transform(hc, buf, i);\n nbytes -= i;\n buf += i;\n hc->bytes_hashed += i;\n }\n j = 0;\n }\n memcpy(hc->data + j, buf, nbytes);\n hc->next_data_empty = j + nbytes;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void zero_pad(UINT8 *p, int nbytes)\n{\n/* Write \"nbytes\" of zeroes, beginning at \"p\" */\n if (nbytes >= (int)sizeof(UWORD)) {\n while ((ptrdiff_t)p % sizeof(UWORD)) {\n *p = 0;\n nbytes--;\n p++;\n }\n while (nbytes >= (int)sizeof(UWORD)) {\n *(UWORD *)p = 0;\n nbytes -= sizeof(UWORD);\n p += sizeof(UWORD);\n }\n }\n while (nbytes) {\n *p = 0;\n nbytes--;\n p++;\n }\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_final(nh_ctx *hc, UINT8 *result)\n/* After passing some number of data buffers to nh_update() for integration\n * into an NH context, nh_final is called to produce a hash result. If any\n * bytes are in the buffer hc->data, incorporate them into the\n * NH context. Finally, add into the NH accumulation \"state\" the total number\n * of bits hashed. The resulting numbers are written to the buffer \"result\".\n * If nh_update was never called, L1_PAD_BOUNDARY zeroes are incorporated.\n */\n{\n int nh_len, nbits;\n\n if (hc->next_data_empty != 0) {\n nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) &\n ~(L1_PAD_BOUNDARY - 1));\n zero_pad(hc->data + hc->next_data_empty, \n nh_len - hc->next_data_empty);\n nh_transform(hc, hc->data, nh_len);\n hc->bytes_hashed += hc->next_data_empty;\n } else if (hc->bytes_hashed == 0) {\n \tnh_len = L1_PAD_BOUNDARY;\n zero_pad(hc->data, L1_PAD_BOUNDARY);\n nh_transform(hc, hc->data, nh_len);\n }\n\n nbits = (hc->bytes_hashed << 3);\n ((UINT64 *)result)[0] = ((UINT64 *)hc->state)[0] + nbits;\n#if (UMAC_OUTPUT_LEN >= 8)\n ((UINT64 *)result)[1] = ((UINT64 *)hc->state)[1] + nbits;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n ((UINT64 *)result)[2] = ((UINT64 *)hc->state)[2] + nbits;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n ((UINT64 *)result)[3] = ((UINT64 *)hc->state)[3] + nbits;\n#endif\n nh_reset(hc);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh(nh_ctx *hc, const UINT8 *buf, UINT32 padded_len,\n UINT32 unpadded_len, UINT8 *result)\n/* All-in-one nh_update() and nh_final() equivalent.\n * Assumes that padded_len is divisible by L1_PAD_BOUNDARY and result is\n * well aligned\n */\n{\n UINT32 nbits;\n \n /* Initialize the hash state */\n nbits = (unpadded_len << 3);\n \n ((UINT64 *)result)[0] = nbits;\n#if (UMAC_OUTPUT_LEN >= 8)\n ((UINT64 *)result)[1] = nbits;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n ((UINT64 *)result)[2] = nbits;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n ((UINT64 *)result)[3] = nbits;\n#endif\n \n nh_aux(hc->nh_key, buf, result, padded_len);\n}\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin UHASH Section -------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* UHASH is a multi-layered algorithm. Data presented to UHASH is first\n * hashed by NH. The NH output is then hashed by a polynomial-hash layer\n * unless the initial data to be hashed is short. After the polynomial-\n * layer, an inner-product hash is used to produce the final UHASH output.\n *\n * UHASH provides two interfaces, one all-at-once and another where data\n * buffers are presented sequentially. In the sequential interface, the\n * UHASH client calls the routine uhash_update() as many times as necessary.\n * When there is no more data to be fed to UHASH, the client calls\n * uhash_final() which \n * calculates the UHASH output. Before beginning another UHASH calculation \n * the uhash_reset() routine must be called. The all-at-once UHASH routine, \n * uhash(), is equivalent to the sequence of calls uhash_update() and \n * uhash_final(); however it is optimized and should be \n * used whenever the sequential interface is not necessary. \n * \n * The routine uhash_init() initializes the uhash_ctx data structure and \n * must be called once, before any other UHASH routine.\n */ \n\n/* ---------------------------------------------------------------------- */\n/* ----- Constants and uhash_ctx ---------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------- */\n/* ----- Poly hash and Inner-Product hash Constants --------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* Primes and masks */\n#define p36 ((UINT64)0x0000000FFFFFFFFBull) /* 2^36 - 5 */\n#define p64 ((UINT64)0xFFFFFFFFFFFFFFC5ull) /* 2^64 - 59 */\n#define m36 ((UINT64)0x0000000FFFFFFFFFull) /* The low 36 of 64 bits */\n\n\n/* ---------------------------------------------------------------------- */\n\ntypedef struct uhash_ctx {\n nh_ctx hash; /* Hash context for L1 NH hash */\n UINT64 poly_key_8[STREAMS]; /* p64 poly keys */\n UINT64 poly_accum[STREAMS]; /* poly hash result */\n UINT64 ip_keys[STREAMS*4]; /* Inner-product keys */\n UINT32 ip_trans[STREAMS]; /* Inner-product translation */\n UINT32 msg_len; /* Total length of data passed */\n /* to uhash */\n} uhash_ctx;\ntypedef struct uhash_ctx *uhash_ctx_t;\n\n/* ---------------------------------------------------------------------- */\n\n\n/* The polynomial hashes use Horner's rule to evaluate a polynomial one\n * word at a time. As described in the specification, poly32 and poly64\n * require keys from special domains. The following implementations exploit\n * the special domains to avoid overflow. The results are not guaranteed to\n * be within Z_p32 and Z_p64, but the Inner-Product hash implementation\n * patches any errant values.\n */\n\nstatic UINT64 poly64(UINT64 cur, UINT64 key, UINT64 data)\n{\n UINT32 key_hi = (UINT32)(key >> 32),\n key_lo = (UINT32)key,\n cur_hi = (UINT32)(cur >> 32),\n cur_lo = (UINT32)cur,\n x_lo,\n x_hi;\n UINT64 X,T,res;\n \n X = MUL64(key_hi, cur_lo) + MUL64(cur_hi, key_lo);\n x_lo = (UINT32)X;\n x_hi = (UINT32)(X >> 32);\n \n res = (MUL64(key_hi, cur_hi) + x_hi) * 59 + MUL64(key_lo, cur_lo);\n \n T = ((UINT64)x_lo << 32);\n res += T;\n if (res < T)\n res += 59;\n\n res += data;\n if (res < data)\n res += 59;\n\n return res;\n}\n\n\n/* Although UMAC is specified to use a ramped polynomial hash scheme, this\n * implementation does not handle all ramp levels. Because we don't handle\n * the ramp up to p128 modulus in this implementation, we are limited to\n * 2^14 poly_hash() invocations per stream (for a total capacity of 2^24\n * bytes input to UMAC per tag, ie. 16MB).\n */\nstatic void poly_hash(uhash_ctx_t hc, UINT32 data_in[])\n{\n int i;\n UINT64 *data=(UINT64*)data_in;\n \n for (i = 0; i < STREAMS; i++) {\n if ((UINT32)(data[i] >> 32) == 0xfffffffful) {\n hc->poly_accum[i] = poly64(hc->poly_accum[i], \n hc->poly_key_8[i], p64 - 1);\n hc->poly_accum[i] = poly64(hc->poly_accum[i],\n hc->poly_key_8[i], (data[i] - 59));\n } else {\n hc->poly_accum[i] = poly64(hc->poly_accum[i],\n hc->poly_key_8[i], data[i]);\n }\n }\n}\n\n\n/* ---------------------------------------------------------------------- */\n\n\n/* The final step in UHASH is an inner-product hash. The poly hash\n * produces a result not neccesarily WORD_LEN bytes long. The inner-\n * product hash breaks the polyhash output into 16-bit chunks and\n * multiplies each with a 36 bit key.\n */\n\nstatic UINT64 ip_aux(UINT64 t, UINT64 *ipkp, UINT64 data)\n{\n t = t + ipkp[0] * (UINT64)(UINT16)(data >> 48);\n t = t + ipkp[1] * (UINT64)(UINT16)(data >> 32);\n t = t + ipkp[2] * (UINT64)(UINT16)(data >> 16);\n t = t + ipkp[3] * (UINT64)(UINT16)(data);\n \n return t;\n}\n\nstatic UINT32 ip_reduce_p36(UINT64 t)\n{\n/* Divisionless modular reduction */\n UINT64 ret;\n \n ret = (t & m36) + 5 * (t >> 36);\n if (ret >= p36)\n ret -= p36;\n\n /* return least significant 32 bits */\n return (UINT32)(ret);\n}\n\n\n/* If the data being hashed by UHASH is no longer than L1_KEY_LEN, then\n * the polyhash stage is skipped and ip_short is applied directly to the\n * NH output.\n */\nstatic void ip_short(uhash_ctx_t ahc, UINT8 *nh_res, u_char *res)\n{\n UINT64 t;\n UINT64 *nhp = (UINT64 *)nh_res;\n \n t = ip_aux(0,ahc->ip_keys, nhp[0]);\n STORE_UINT32_BIG((UINT32 *)res+0, ip_reduce_p36(t) ^ ahc->ip_trans[0]);\n#if (UMAC_OUTPUT_LEN >= 8)\n t = ip_aux(0,ahc->ip_keys+4, nhp[1]);\n STORE_UINT32_BIG((UINT32 *)res+1, ip_reduce_p36(t) ^ ahc->ip_trans[1]);\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n t = ip_aux(0,ahc->ip_keys+8, nhp[2]);\n STORE_UINT32_BIG((UINT32 *)res+2, ip_reduce_p36(t) ^ ahc->ip_trans[2]);\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n t = ip_aux(0,ahc->ip_keys+12, nhp[3]);\n STORE_UINT32_BIG((UINT32 *)res+3, ip_reduce_p36(t) ^ ahc->ip_trans[3]);\n#endif\n}\n\n/* If the data being hashed by UHASH is longer than L1_KEY_LEN, then\n * the polyhash stage is not skipped and ip_long is applied to the\n * polyhash output.\n */\nstatic void ip_long(uhash_ctx_t ahc, u_char *res)\n{\n int i;\n UINT64 t;\n\n for (i = 0; i < STREAMS; i++) {\n /* fix polyhash output not in Z_p64 */\n if (ahc->poly_accum[i] >= p64)\n ahc->poly_accum[i] -= p64;\n t = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]);\n STORE_UINT32_BIG((UINT32 *)res+i, \n ip_reduce_p36(t) ^ ahc->ip_trans[i]);\n }\n}\n\n\n/* ---------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------- */\n\n/* Reset uhash context for next hash session */\nstatic int uhash_reset(uhash_ctx_t pc)\n{\n nh_reset(&pc->hash);\n pc->msg_len = 0;\n pc->poly_accum[0] = 1;\n#if (UMAC_OUTPUT_LEN >= 8)\n pc->poly_accum[1] = 1;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n pc->poly_accum[2] = 1;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n pc->poly_accum[3] = 1;\n#endif\n return 1;\n}\n\n/* ---------------------------------------------------------------------- */\n\n/* Given a pointer to the internal key needed by kdf() and a uhash context,\n * initialize the NH context and generate keys needed for poly and inner-\n * product hashing. All keys are endian adjusted in memory so that native\n * loads cause correct keys to be in registers during calculation.\n */\nstatic void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)\n{\n int i;\n UINT8 buf[(8*STREAMS+4)*sizeof(UINT64)];\n \n /* Zero the entire uhash context */\n memset(ahc, 0, sizeof(uhash_ctx));\n\n /* Initialize the L1 hash */\n nh_init(&ahc->hash, prf_key);\n \n /* Setup L2 hash variables */\n kdf(buf, prf_key, 2, sizeof(buf)); /* Fill buffer with index 1 key */\n for (i = 0; i < STREAMS; i++) {\n /* Fill keys from the buffer, skipping bytes in the buffer not\n * used by this implementation. Endian reverse the keys if on a\n * little-endian computer.\n */\n memcpy(ahc->poly_key_8+i, buf+24*i, 8);\n endian_convert_if_le(ahc->poly_key_8+i, 8, 8);\n /* Mask the 64-bit keys to their special domain */\n ahc->poly_key_8[i] &= ((UINT64)0x01ffffffu << 32) + 0x01ffffffu;\n ahc->poly_accum[i] = 1; /* Our polyhash prepends a non-zero word */\n }\n \n /* Setup L3-1 hash variables */\n kdf(buf, prf_key, 3, sizeof(buf)); /* Fill buffer with index 2 key */\n for (i = 0; i < STREAMS; i++)\n memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64),\n 4*sizeof(UINT64));\n endian_convert_if_le(ahc->ip_keys, sizeof(UINT64), \n sizeof(ahc->ip_keys));\n for (i = 0; i < STREAMS*4; i++)\n ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */\n \n /* Setup L3-2 hash variables */\n /* Fill buffer with index 4 key */\n kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32));\n endian_convert_if_le(ahc->ip_trans, sizeof(UINT32),\n STREAMS * sizeof(UINT32));\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nstatic uhash_ctx_t uhash_alloc(u_char key[])\n{\n/* Allocate memory and force to a 16-byte boundary. */\n uhash_ctx_t ctx;\n u_char bytes_to_add;\n aes_int_key prf_key;\n \n ctx = (uhash_ctx_t)malloc(sizeof(uhash_ctx)+ALLOC_BOUNDARY);\n if (ctx) {\n if (ALLOC_BOUNDARY) {\n bytes_to_add = ALLOC_BOUNDARY -\n ((ptrdiff_t)ctx & (ALLOC_BOUNDARY -1));\n ctx = (uhash_ctx_t)((u_char *)ctx + bytes_to_add);\n *((u_char *)ctx - 1) = bytes_to_add;\n }\n aes_key_setup(key,prf_key);\n uhash_init(ctx, prf_key);\n }\n return (ctx);\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nstatic int uhash_free(uhash_ctx_t ctx)\n{\n/* Free memory allocated by uhash_alloc */\n u_char bytes_to_sub;\n \n if (ctx) {\n if (ALLOC_BOUNDARY) {\n bytes_to_sub = *((u_char *)ctx - 1);\n ctx = (uhash_ctx_t)((u_char *)ctx - bytes_to_sub);\n }\n free(ctx);\n }\n return (1);\n}\n#endif\n/* ---------------------------------------------------------------------- */\n\nstatic int uhash_update(uhash_ctx_t ctx, const u_char *input, long len)\n/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and\n * hash each one with NH, calling the polyhash on each NH output.\n */\n{\n UWORD bytes_hashed, bytes_remaining;\n UINT64 result_buf[STREAMS];\n UINT8 *nh_result = (UINT8 *)&result_buf;\n \n if (ctx->msg_len + len <= L1_KEY_LEN) {\n nh_update(&ctx->hash, (const UINT8 *)input, len);\n ctx->msg_len += len;\n } else {\n \n bytes_hashed = ctx->msg_len % L1_KEY_LEN;\n if (ctx->msg_len == L1_KEY_LEN)\n bytes_hashed = L1_KEY_LEN;\n\n if (bytes_hashed + len >= L1_KEY_LEN) {\n\n /* If some bytes have been passed to the hash function */\n /* then we want to pass at most (L1_KEY_LEN - bytes_hashed) */\n /* bytes to complete the current nh_block. */\n if (bytes_hashed) {\n bytes_remaining = (L1_KEY_LEN - bytes_hashed);\n nh_update(&ctx->hash, (const UINT8 *)input, bytes_remaining);\n nh_final(&ctx->hash, nh_result);\n ctx->msg_len += bytes_remaining;\n poly_hash(ctx,(UINT32 *)nh_result);\n len -= bytes_remaining;\n input += bytes_remaining;\n }\n\n /* Hash directly from input stream if enough bytes */\n while (len >= L1_KEY_LEN) {\n nh(&ctx->hash, (const UINT8 *)input, L1_KEY_LEN,\n L1_KEY_LEN, nh_result);\n ctx->msg_len += L1_KEY_LEN;\n len -= L1_KEY_LEN;\n input += L1_KEY_LEN;\n poly_hash(ctx,(UINT32 *)nh_result);\n }\n }\n\n /* pass remaining < L1_KEY_LEN bytes of input data to NH */\n if (len) {\n nh_update(&ctx->hash, (const UINT8 *)input, len);\n ctx->msg_len += len;\n }\n }\n\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int uhash_final(uhash_ctx_t ctx, u_char *res)\n/* Incorporate any pending data, pad, and generate tag */\n{\n UINT64 result_buf[STREAMS];\n UINT8 *nh_result = (UINT8 *)&result_buf;\n\n if (ctx->msg_len > L1_KEY_LEN) {\n if (ctx->msg_len % L1_KEY_LEN) {\n nh_final(&ctx->hash, nh_result);\n poly_hash(ctx,(UINT32 *)nh_result);\n }\n ip_long(ctx, res);\n } else {\n nh_final(&ctx->hash, nh_result);\n ip_short(ctx,nh_result, res);\n }\n uhash_reset(ctx);\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nstatic int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res)\n/* assumes that msg is in a writable buffer of length divisible by */\n/* L1_PAD_BOUNDARY. Bytes beyond msg[len] may be zeroed. */\n{\n UINT8 nh_result[STREAMS*sizeof(UINT64)];\n UINT32 nh_len;\n int extra_zeroes_needed;\n \n /* If the message to be hashed is no longer than L1_HASH_LEN, we skip\n * the polyhash.\n */\n if (len <= L1_KEY_LEN) {\n \tif (len == 0) /* If zero length messages will not */\n \t\tnh_len = L1_PAD_BOUNDARY; /* be seen, comment out this case */ \n \telse\n \tnh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1));\n extra_zeroes_needed = nh_len - len;\n zero_pad((UINT8 *)msg + len, extra_zeroes_needed);\n nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result);\n ip_short(ahc,nh_result, res);\n } else {\n /* Otherwise, we hash each L1_KEY_LEN chunk with NH, passing the NH\n * output to poly_hash().\n */\n do {\n nh(&ahc->hash, (UINT8 *)msg, L1_KEY_LEN, L1_KEY_LEN, nh_result);\n poly_hash(ahc,(UINT32 *)nh_result);\n len -= L1_KEY_LEN;\n msg += L1_KEY_LEN;\n } while (len >= L1_KEY_LEN);\n if (len) {\n nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1));\n extra_zeroes_needed = nh_len - len;\n zero_pad((UINT8 *)msg + len, extra_zeroes_needed);\n nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result);\n poly_hash(ahc,(UINT32 *)nh_result);\n }\n\n ip_long(ahc, res);\n }\n \n uhash_reset(ahc);\n return 1;\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin UMAC Section --------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* The UMAC interface has two interfaces, an all-at-once interface where\n * the entire message to be authenticated is passed to UMAC in one buffer,\n * and a sequential interface where the message is presented a little at a \n * time. The all-at-once is more optimaized than the sequential version and\n * should be preferred when the sequential interface is not required. \n */\nstruct umac_ctx {\n uhash_ctx hash; /* Hash function for message compression */\n pdf_ctx pdf; /* PDF for hashed output */\n void *free_ptr; /* Address to free this struct via */\n} umac_ctx;\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nint umac_reset(struct umac_ctx *ctx)\n/* Reset the hash function to begin a new authentication. */\n{\n uhash_reset(&ctx->hash);\n return (1);\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n\nint umac_delete(struct umac_ctx *ctx)\n/* Deallocate the ctx structure */\n{\n if (ctx) {\n if (ALLOC_BOUNDARY)\n ctx = (struct umac_ctx *)ctx->free_ptr;\n free(ctx);\n }\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstruct umac_ctx *umac_new(const u_char key[])\n/* Dynamically allocate a umac_ctx struct, initialize variables, \n * generate subkeys from key. Align to 16-byte boundary.\n */\n{\n struct umac_ctx *ctx, *octx;\n size_t bytes_to_add;\n aes_int_key prf_key;\n \n octx = ctx = xcalloc(1, sizeof(*ctx) + ALLOC_BOUNDARY);\n if (ctx) {\n if (ALLOC_BOUNDARY) {\n bytes_to_add = ALLOC_BOUNDARY -\n ((ptrdiff_t)ctx & (ALLOC_BOUNDARY - 1));\n ctx = (struct umac_ctx *)((u_char *)ctx + bytes_to_add);\n }\n ctx->free_ptr = octx;\n aes_key_setup(key, prf_key);\n pdf_init(&ctx->pdf, prf_key);\n uhash_init(&ctx->hash, prf_key);\n }\n \n return (ctx);\n}\n\n/* ---------------------------------------------------------------------- */\n\nint umac_final(struct umac_ctx *ctx, u_char tag[], const u_char nonce[8])\n/* Incorporate any pending data, pad, and generate tag */\n{\n uhash_final(&ctx->hash, (u_char *)tag);\n pdf_gen_xor(&ctx->pdf, (const UINT8 *)nonce, (UINT8 *)tag);\n \n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\nint umac_update(struct umac_ctx *ctx, const u_char *input, long len)\n/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */\n/* hash each one, calling the PDF on the hashed output whenever the hash- */\n/* output buffer is full. */\n{\n uhash_update(&ctx->hash, input, len);\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nint umac(struct umac_ctx *ctx, u_char *input, \n long len, u_char tag[],\n u_char nonce[8])\n/* All-in-one version simply calls umac_update() and umac_final(). */\n{\n uhash(&ctx->hash, input, len, (u_char *)tag);\n pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag);\n \n return (1);\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- End UMAC Section ----------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n","/* $OpenBSD: umac.c,v 1.11 2014/07/22 07:13:42 guenther Exp $ */\n/* -----------------------------------------------------------------------\n * \n * umac.c -- C Implementation UMAC Message Authentication\n *\n * Version 0.93b of rfc4418.txt -- 2006 July 18\n *\n * For a full description of UMAC message authentication see the UMAC\n * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac\n * Please report bugs and suggestions to the UMAC webpage.\n *\n * Copyright (c) 1999-2006 Ted Krovetz\n * \n * Permission to use, copy, modify, and distribute this software and\n * its documentation for any purpose and with or without fee, is hereby\n * granted provided that the above copyright notice appears in all copies\n * and in supporting documentation, and that the name of the copyright\n * holder not be used in advertising or publicity pertaining to\n * distribution of the software without specific, written prior permission.\n *\n * Comments should be directed to Ted Krovetz (tdk@acm.org) \n * \n * ---------------------------------------------------------------------- */\n \n /* ////////////////////// IMPORTANT NOTES /////////////////////////////////\n *\n * 1) This version does not work properly on messages larger than 16MB\n *\n * 2) If you set the switch to use SSE2, then all data must be 16-byte\n * aligned\n *\n * 3) When calling the function umac(), it is assumed that msg is in\n * a writable buffer of length divisible by 32 bytes. The message itself\n * does not have to fill the entire buffer, but bytes beyond msg may be\n * zeroed.\n *\n * 4) Three free AES implementations are supported by this implementation of\n * UMAC. Paulo Barreto's version is in the public domain and can be found\n * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for\n * \"Barreto\"). The only two files needed are rijndael-alg-fst.c and\n * rijndael-alg-fst.h. Brian Gladman's version is distributed with the GNU\n * Public lisence at http://fp.gladman.plus.com/AES/index.htm. It\n * includes a fast IA-32 assembly version. The OpenSSL crypo library is\n * the third.\n *\n * 5) With FORCE_C_ONLY flags set to 0, incorrect results are sometimes\n * produced under gcc with optimizations set -O3 or higher. Dunno why.\n *\n /////////////////////////////////////////////////////////////////////// */\n \n/* ---------------------------------------------------------------------- */\n/* --- User Switches ---------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n#ifndef UMAC_OUTPUT_LEN\n#define UMAC_OUTPUT_LEN 8 /* Alowable: 4, 8, 12, 16 */\n#endif\n\n#if UMAC_OUTPUT_LEN != 4 && UMAC_OUTPUT_LEN != 8 && \\\n UMAC_OUTPUT_LEN != 12 && UMAC_OUTPUT_LEN != 16\n# error UMAC_OUTPUT_LEN must be defined to 4, 8, 12 or 16\n#endif\n\n/* #define FORCE_C_ONLY 1 ANSI C and 64-bit integers req'd */\n/* #define AES_IMPLEMENTAION 1 1 = OpenSSL, 2 = Barreto, 3 = Gladman */\n/* #define SSE2 0 Is SSE2 is available? */\n/* #define RUN_TESTS 0 Run basic correctness/speed tests */\n/* #define UMAC_AE_SUPPORT 0 Enable auhthenticated encrytion */\n\n/* ---------------------------------------------------------------------- */\n/* -- Global Includes --------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n#include \"includes.h\"\n#include \n#include \n#include \n#include \n#include \n\n#include \"xmalloc.h\"\n#include \"umac.h\"\n#include \"misc.h\"\n\n/* ---------------------------------------------------------------------- */\n/* --- Primitive Data Types --- */\n/* ---------------------------------------------------------------------- */\n\n/* The following assumptions may need change on your system */\ntypedef u_int8_t\tUINT8; /* 1 byte */\ntypedef u_int16_t\tUINT16; /* 2 byte */\ntypedef u_int32_t\tUINT32; /* 4 byte */\ntypedef u_int64_t\tUINT64; /* 8 bytes */\ntypedef unsigned int\tUWORD; /* Register */\n\n/* ---------------------------------------------------------------------- */\n/* --- Constants -------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n#define UMAC_KEY_LEN 16 /* UMAC takes 16 bytes of external key */\n\n/* Message \"words\" are read from memory in an endian-specific manner. */\n/* For this implementation to behave correctly, __LITTLE_ENDIAN__ must */\n/* be set true if the host computer is little-endian. */\n\n#if BYTE_ORDER == LITTLE_ENDIAN\n#define __LITTLE_ENDIAN__ 1\n#else\n#define __LITTLE_ENDIAN__ 0\n#endif\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Architecture Specific ------------------------------------------ */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Primitive Routines --------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n\n/* ---------------------------------------------------------------------- */\n/* --- 32-bit by 32-bit to 64-bit Multiplication ------------------------ */\n/* ---------------------------------------------------------------------- */\n\n#define MUL64(a,b) ((UINT64)((UINT64)(UINT32)(a) * (UINT64)(UINT32)(b)))\n\n/* ---------------------------------------------------------------------- */\n/* --- Endian Conversion --- Forcing assembly on some platforms */\n/* ---------------------------------------------------------------------- */\n\n#if (__LITTLE_ENDIAN__)\n#define LOAD_UINT32_REVERSED(p)\t\tget_u32(p)\n#define STORE_UINT32_REVERSED(p,v)\tput_u32(p,v)\n#else\n#define LOAD_UINT32_REVERSED(p)\t\tget_u32_le(p)\n#define STORE_UINT32_REVERSED(p,v)\tput_u32_le(p,v)\n#endif\n\n#define LOAD_UINT32_LITTLE(p)\t\t(get_u32_le(p))\n#define STORE_UINT32_BIG(p,v)\t\tput_u32(p, v)\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin KDF & PDF Section ---------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* UMAC uses AES with 16 byte block and key lengths */\n#define AES_BLOCK_LEN 16\n\n/* OpenSSL's AES */\n#ifdef WITH_OPENSSL\n#include \"openbsd-compat/openssl-compat.h\"\n#ifndef USE_BUILTIN_RIJNDAEL\n# include \n#endif\ntypedef AES_KEY aes_int_key[1];\n#define aes_encryption(in,out,int_key) \\\n AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key)\n#define aes_key_setup(key,int_key) \\\n AES_set_encrypt_key((const u_char *)(key),UMAC_KEY_LEN*8,int_key)\n#else\n#include \"rijndael.h\"\n#define AES_ROUNDS ((UMAC_KEY_LEN / 4) + 6)\ntypedef UINT8 aes_int_key[AES_ROUNDS+1][4][4];\t/* AES internal */\n#define aes_encryption(in,out,int_key) \\\n rijndaelEncrypt((u32 *)(int_key), AES_ROUNDS, (u8 *)(in), (u8 *)(out))\n#define aes_key_setup(key,int_key) \\\n rijndaelKeySetupEnc((u32 *)(int_key), (const unsigned char *)(key), \\\n UMAC_KEY_LEN*8)\n#endif\n\n/* The user-supplied UMAC key is stretched using AES in a counter\n * mode to supply all random bits needed by UMAC. The kdf function takes\n * an AES internal key representation 'key' and writes a stream of\n * 'nbytes' bytes to the memory pointed at by 'bufp'. Each distinct\n * 'ndx' causes a distinct byte stream.\n */\nstatic void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes)\n{\n UINT8 in_buf[AES_BLOCK_LEN] = {0};\n UINT8 out_buf[AES_BLOCK_LEN];\n UINT8 *dst_buf = (UINT8 *)bufp;\n int i;\n \n /* Setup the initial value */\n in_buf[AES_BLOCK_LEN-9] = ndx;\n in_buf[AES_BLOCK_LEN-1] = i = 1;\n \n while (nbytes >= AES_BLOCK_LEN) {\n aes_encryption(in_buf, out_buf, key);\n memcpy(dst_buf,out_buf,AES_BLOCK_LEN);\n in_buf[AES_BLOCK_LEN-1] = ++i;\n nbytes -= AES_BLOCK_LEN;\n dst_buf += AES_BLOCK_LEN;\n }\n if (nbytes) {\n aes_encryption(in_buf, out_buf, key);\n memcpy(dst_buf,out_buf,nbytes);\n }\n}\n\n/* The final UHASH result is XOR'd with the output of a pseudorandom\n * function. Here, we use AES to generate random output and \n * xor the appropriate bytes depending on the last bits of nonce.\n * This scheme is optimized for sequential, increasing big-endian nonces.\n */\n\ntypedef struct {\n UINT8 cache[AES_BLOCK_LEN]; /* Previous AES output is saved */\n UINT8 nonce[AES_BLOCK_LEN]; /* The AES input making above cache */\n aes_int_key prf_key; /* Expanded AES key for PDF */\n} pdf_ctx;\n\nstatic void pdf_init(pdf_ctx *pc, aes_int_key prf_key)\n{\n UINT8 buf[UMAC_KEY_LEN];\n \n kdf(buf, prf_key, 0, UMAC_KEY_LEN);\n aes_key_setup(buf, pc->prf_key);\n \n /* Initialize pdf and cache */\n memset(pc->nonce, 0, sizeof(pc->nonce));\n aes_encryption(pc->nonce, pc->cache, pc->prf_key);\n}\n\nstatic void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])\n{\n /* 'ndx' indicates that we'll be using the 0th or 1st eight bytes\n * of the AES output. If last time around we returned the ndx-1st\n * element, then we may have the result in the cache already.\n */\n \n#if (UMAC_OUTPUT_LEN == 4)\n#define LOW_BIT_MASK 3\n#elif (UMAC_OUTPUT_LEN == 8)\n#define LOW_BIT_MASK 1\n#elif (UMAC_OUTPUT_LEN > 8)\n#define LOW_BIT_MASK 0\n#endif\n union {\n UINT8 tmp_nonce_lo[4];\n UINT32 align;\n } t;\n#if LOW_BIT_MASK != 0\n int ndx = nonce[7] & LOW_BIT_MASK;\n#endif\n *(UINT32 *)t.tmp_nonce_lo = ((const UINT32 *)nonce)[1];\n t.tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */\n \n if ( (((UINT32 *)t.tmp_nonce_lo)[0] != ((UINT32 *)pc->nonce)[1]) ||\n (((const UINT32 *)nonce)[0] != ((UINT32 *)pc->nonce)[0]) )\n {\n ((UINT32 *)pc->nonce)[0] = ((const UINT32 *)nonce)[0];\n ((UINT32 *)pc->nonce)[1] = ((UINT32 *)t.tmp_nonce_lo)[0];\n aes_encryption(pc->nonce, pc->cache, pc->prf_key);\n }\n \n#if (UMAC_OUTPUT_LEN == 4)\n *((UINT32 *)buf) ^= ((UINT32 *)pc->cache)[ndx];\n#elif (UMAC_OUTPUT_LEN == 8)\n *((UINT64 *)buf) ^= ((UINT64 *)pc->cache)[ndx];\n#elif (UMAC_OUTPUT_LEN == 12)\n ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0];\n ((UINT32 *)buf)[2] ^= ((UINT32 *)pc->cache)[2];\n#elif (UMAC_OUTPUT_LEN == 16)\n ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0];\n ((UINT64 *)buf)[1] ^= ((UINT64 *)pc->cache)[1];\n#endif\n}\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin NH Hash Section ------------------------------------------ */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* The NH-based hash functions used in UMAC are described in the UMAC paper\n * and specification, both of which can be found at the UMAC website. \n * The interface to this implementation has two \n * versions, one expects the entire message being hashed to be passed\n * in a single buffer and returns the hash result immediately. The second\n * allows the message to be passed in a sequence of buffers. In the \n * muliple-buffer interface, the client calls the routine nh_update() as \n * many times as necessary. When there is no more data to be fed to the \n * hash, the client calls nh_final() which calculates the hash output. \n * Before beginning another hash calculation the nh_reset() routine \n * must be called. The single-buffer routine, nh(), is equivalent to \n * the sequence of calls nh_update() and nh_final(); however it is \n * optimized and should be prefered whenever the multiple-buffer interface\n * is not necessary. When using either interface, it is the client's \n * responsability to pass no more than L1_KEY_LEN bytes per hash result. \n * \n * The routine nh_init() initializes the nh_ctx data structure and \n * must be called once, before any other PDF routine. \n */\n \n /* The \"nh_aux\" routines do the actual NH hashing work. They\n * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines\n * produce output for all STREAMS NH iterations in one call, \n * allowing the parallel implementation of the streams.\n */\n\n#define STREAMS (UMAC_OUTPUT_LEN / 4) /* Number of times hash is applied */\n#define L1_KEY_LEN 1024 /* Internal key bytes */\n#define L1_KEY_SHIFT 16 /* Toeplitz key shift between streams */\n#define L1_PAD_BOUNDARY 32 /* pad message to boundary multiple */\n#define ALLOC_BOUNDARY 16 /* Keep buffers aligned to this */\n#define HASH_BUF_BYTES 64 /* nh_aux_hb buffer multiple */\n\ntypedef struct {\n UINT8 nh_key [L1_KEY_LEN + L1_KEY_SHIFT * (STREAMS - 1)]; /* NH Key */\n UINT8 data [HASH_BUF_BYTES]; /* Incoming data buffer */\n int next_data_empty; /* Bookeeping variable for data buffer. */\n int bytes_hashed; /* Bytes (out of L1_KEY_LEN) incorperated. */\n UINT64 state[STREAMS]; /* on-line state */\n} nh_ctx;\n\n\n#if (UMAC_OUTPUT_LEN == 4)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* NH hashing primitive. Previous (partial) hash result is loaded and \n* then stored via hp pointer. The length of the data pointed at by \"dp\",\n* \"dlen\", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key\n* is expected to be endian compensated in memory at key setup. \n*/\n{\n UINT64 h;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7;\n \n h = *((UINT64 *)hp);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n h += MUL64((k0 + d0), (k4 + d4));\n h += MUL64((k1 + d1), (k5 + d5));\n h += MUL64((k2 + d2), (k6 + d6));\n h += MUL64((k3 + d3), (k7 + d7));\n \n d += 8;\n k += 8;\n } while (--c);\n *((UINT64 *)hp) = h;\n}\n\n#elif (UMAC_OUTPUT_LEN == 8)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* Same as previous nh_aux, but two streams are handled in one pass,\n * reading and writing 16 bytes of hash-state per call.\n */\n{\n UINT64 h1,h2;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7,\n k8,k9,k10,k11;\n\n h1 = *((UINT64 *)hp);\n h2 = *((UINT64 *)hp + 1);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);\n\n h1 += MUL64((k0 + d0), (k4 + d4));\n h2 += MUL64((k4 + d0), (k8 + d4));\n\n h1 += MUL64((k1 + d1), (k5 + d5));\n h2 += MUL64((k5 + d1), (k9 + d5));\n\n h1 += MUL64((k2 + d2), (k6 + d6));\n h2 += MUL64((k6 + d2), (k10 + d6));\n\n h1 += MUL64((k3 + d3), (k7 + d7));\n h2 += MUL64((k7 + d3), (k11 + d7));\n\n k0 = k8; k1 = k9; k2 = k10; k3 = k11;\n\n d += 8;\n k += 8;\n } while (--c);\n ((UINT64 *)hp)[0] = h1;\n ((UINT64 *)hp)[1] = h2;\n}\n\n#elif (UMAC_OUTPUT_LEN == 12)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* Same as previous nh_aux, but two streams are handled in one pass,\n * reading and writing 24 bytes of hash-state per call.\n*/\n{\n UINT64 h1,h2,h3;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7,\n k8,k9,k10,k11,k12,k13,k14,k15;\n \n h1 = *((UINT64 *)hp);\n h2 = *((UINT64 *)hp + 1);\n h3 = *((UINT64 *)hp + 2);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);\n k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);\n \n h1 += MUL64((k0 + d0), (k4 + d4));\n h2 += MUL64((k4 + d0), (k8 + d4));\n h3 += MUL64((k8 + d0), (k12 + d4));\n \n h1 += MUL64((k1 + d1), (k5 + d5));\n h2 += MUL64((k5 + d1), (k9 + d5));\n h3 += MUL64((k9 + d1), (k13 + d5));\n \n h1 += MUL64((k2 + d2), (k6 + d6));\n h2 += MUL64((k6 + d2), (k10 + d6));\n h3 += MUL64((k10 + d2), (k14 + d6));\n \n h1 += MUL64((k3 + d3), (k7 + d7));\n h2 += MUL64((k7 + d3), (k11 + d7));\n h3 += MUL64((k11 + d3), (k15 + d7));\n \n k0 = k8; k1 = k9; k2 = k10; k3 = k11;\n k4 = k12; k5 = k13; k6 = k14; k7 = k15;\n \n d += 8;\n k += 8;\n } while (--c);\n ((UINT64 *)hp)[0] = h1;\n ((UINT64 *)hp)[1] = h2;\n ((UINT64 *)hp)[2] = h3;\n}\n\n#elif (UMAC_OUTPUT_LEN == 16)\n\nstatic void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)\n/* Same as previous nh_aux, but two streams are handled in one pass,\n * reading and writing 24 bytes of hash-state per call.\n*/\n{\n UINT64 h1,h2,h3,h4;\n UWORD c = dlen / 32;\n UINT32 *k = (UINT32 *)kp;\n const UINT32 *d = (const UINT32 *)dp;\n UINT32 d0,d1,d2,d3,d4,d5,d6,d7;\n UINT32 k0,k1,k2,k3,k4,k5,k6,k7,\n k8,k9,k10,k11,k12,k13,k14,k15,\n k16,k17,k18,k19;\n \n h1 = *((UINT64 *)hp);\n h2 = *((UINT64 *)hp + 1);\n h3 = *((UINT64 *)hp + 2);\n h4 = *((UINT64 *)hp + 3);\n k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);\n k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);\n do {\n d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);\n d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);\n d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);\n d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);\n k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);\n k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);\n k16 = *(k+16); k17 = *(k+17); k18 = *(k+18); k19 = *(k+19);\n \n h1 += MUL64((k0 + d0), (k4 + d4));\n h2 += MUL64((k4 + d0), (k8 + d4));\n h3 += MUL64((k8 + d0), (k12 + d4));\n h4 += MUL64((k12 + d0), (k16 + d4));\n \n h1 += MUL64((k1 + d1), (k5 + d5));\n h2 += MUL64((k5 + d1), (k9 + d5));\n h3 += MUL64((k9 + d1), (k13 + d5));\n h4 += MUL64((k13 + d1), (k17 + d5));\n \n h1 += MUL64((k2 + d2), (k6 + d6));\n h2 += MUL64((k6 + d2), (k10 + d6));\n h3 += MUL64((k10 + d2), (k14 + d6));\n h4 += MUL64((k14 + d2), (k18 + d6));\n \n h1 += MUL64((k3 + d3), (k7 + d7));\n h2 += MUL64((k7 + d3), (k11 + d7));\n h3 += MUL64((k11 + d3), (k15 + d7));\n h4 += MUL64((k15 + d3), (k19 + d7));\n \n k0 = k8; k1 = k9; k2 = k10; k3 = k11;\n k4 = k12; k5 = k13; k6 = k14; k7 = k15;\n k8 = k16; k9 = k17; k10 = k18; k11 = k19;\n \n d += 8;\n k += 8;\n } while (--c);\n ((UINT64 *)hp)[0] = h1;\n ((UINT64 *)hp)[1] = h2;\n ((UINT64 *)hp)[2] = h3;\n ((UINT64 *)hp)[3] = h4;\n}\n\n/* ---------------------------------------------------------------------- */\n#endif /* UMAC_OUTPUT_LENGTH */\n/* ---------------------------------------------------------------------- */\n\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_transform(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)\n/* This function is a wrapper for the primitive NH hash functions. It takes\n * as argument \"hc\" the current hash context and a buffer which must be a\n * multiple of L1_PAD_BOUNDARY. The key passed to nh_aux is offset\n * appropriately according to how much message has been hashed already.\n */\n{\n UINT8 *key;\n \n key = hc->nh_key + hc->bytes_hashed;\n nh_aux(key, buf, hc->state, nbytes);\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if (__LITTLE_ENDIAN__)\nstatic void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes)\n/* We endian convert the keys on little-endian computers to */\n/* compensate for the lack of big-endian memory reads during hashing. */\n{\n UWORD iters = num_bytes / bpw;\n if (bpw == 4) {\n UINT32 *p = (UINT32 *)buf;\n do {\n *p = LOAD_UINT32_REVERSED(p);\n p++;\n } while (--iters);\n } else if (bpw == 8) {\n UINT32 *p = (UINT32 *)buf;\n UINT32 t;\n do {\n t = LOAD_UINT32_REVERSED(p+1);\n p[1] = LOAD_UINT32_REVERSED(p);\n p[0] = t;\n p += 2;\n } while (--iters);\n }\n}\n#define endian_convert_if_le(x,y,z) endian_convert((x),(y),(z))\n#else\n#define endian_convert_if_le(x,y,z) do{}while(0) /* Do nothing */\n#endif\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_reset(nh_ctx *hc)\n/* Reset nh_ctx to ready for hashing of new data */\n{\n hc->bytes_hashed = 0;\n hc->next_data_empty = 0;\n hc->state[0] = 0;\n#if (UMAC_OUTPUT_LEN >= 8)\n hc->state[1] = 0;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n hc->state[2] = 0;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n hc->state[3] = 0;\n#endif\n\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_init(nh_ctx *hc, aes_int_key prf_key)\n/* Generate nh_key, endian convert and reset to be ready for hashing. */\n{\n kdf(hc->nh_key, prf_key, 1, sizeof(hc->nh_key));\n endian_convert_if_le(hc->nh_key, 4, sizeof(hc->nh_key));\n nh_reset(hc);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_update(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)\n/* Incorporate nbytes of data into a nh_ctx, buffer whatever is not an */\n/* even multiple of HASH_BUF_BYTES. */\n{\n UINT32 i,j;\n \n j = hc->next_data_empty;\n if ((j + nbytes) >= HASH_BUF_BYTES) {\n if (j) {\n i = HASH_BUF_BYTES - j;\n memcpy(hc->data+j, buf, i);\n nh_transform(hc,hc->data,HASH_BUF_BYTES);\n nbytes -= i;\n buf += i;\n hc->bytes_hashed += HASH_BUF_BYTES;\n }\n if (nbytes >= HASH_BUF_BYTES) {\n i = nbytes & ~(HASH_BUF_BYTES - 1);\n nh_transform(hc, buf, i);\n nbytes -= i;\n buf += i;\n hc->bytes_hashed += i;\n }\n j = 0;\n }\n memcpy(hc->data + j, buf, nbytes);\n hc->next_data_empty = j + nbytes;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void zero_pad(UINT8 *p, int nbytes)\n{\n/* Write \"nbytes\" of zeroes, beginning at \"p\" */\n if (nbytes >= (int)sizeof(UWORD)) {\n while ((ptrdiff_t)p % sizeof(UWORD)) {\n *p = 0;\n nbytes--;\n p++;\n }\n while (nbytes >= (int)sizeof(UWORD)) {\n *(UWORD *)p = 0;\n nbytes -= sizeof(UWORD);\n p += sizeof(UWORD);\n }\n }\n while (nbytes) {\n *p = 0;\n nbytes--;\n p++;\n }\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh_final(nh_ctx *hc, UINT8 *result)\n/* After passing some number of data buffers to nh_update() for integration\n * into an NH context, nh_final is called to produce a hash result. If any\n * bytes are in the buffer hc->data, incorporate them into the\n * NH context. Finally, add into the NH accumulation \"state\" the total number\n * of bits hashed. The resulting numbers are written to the buffer \"result\".\n * If nh_update was never called, L1_PAD_BOUNDARY zeroes are incorporated.\n */\n{\n int nh_len, nbits;\n\n if (hc->next_data_empty != 0) {\n nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) &\n ~(L1_PAD_BOUNDARY - 1));\n zero_pad(hc->data + hc->next_data_empty, \n nh_len - hc->next_data_empty);\n nh_transform(hc, hc->data, nh_len);\n hc->bytes_hashed += hc->next_data_empty;\n } else if (hc->bytes_hashed == 0) {\n \tnh_len = L1_PAD_BOUNDARY;\n zero_pad(hc->data, L1_PAD_BOUNDARY);\n nh_transform(hc, hc->data, nh_len);\n }\n\n nbits = (hc->bytes_hashed << 3);\n ((UINT64 *)result)[0] = ((UINT64 *)hc->state)[0] + nbits;\n#if (UMAC_OUTPUT_LEN >= 8)\n ((UINT64 *)result)[1] = ((UINT64 *)hc->state)[1] + nbits;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n ((UINT64 *)result)[2] = ((UINT64 *)hc->state)[2] + nbits;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n ((UINT64 *)result)[3] = ((UINT64 *)hc->state)[3] + nbits;\n#endif\n nh_reset(hc);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic void nh(nh_ctx *hc, const UINT8 *buf, UINT32 padded_len,\n UINT32 unpadded_len, UINT8 *result)\n/* All-in-one nh_update() and nh_final() equivalent.\n * Assumes that padded_len is divisible by L1_PAD_BOUNDARY and result is\n * well aligned\n */\n{\n UINT32 nbits;\n \n /* Initialize the hash state */\n nbits = (unpadded_len << 3);\n \n ((UINT64 *)result)[0] = nbits;\n#if (UMAC_OUTPUT_LEN >= 8)\n ((UINT64 *)result)[1] = nbits;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n ((UINT64 *)result)[2] = nbits;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n ((UINT64 *)result)[3] = nbits;\n#endif\n \n nh_aux(hc->nh_key, buf, result, padded_len);\n}\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin UHASH Section -------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* UHASH is a multi-layered algorithm. Data presented to UHASH is first\n * hashed by NH. The NH output is then hashed by a polynomial-hash layer\n * unless the initial data to be hashed is short. After the polynomial-\n * layer, an inner-product hash is used to produce the final UHASH output.\n *\n * UHASH provides two interfaces, one all-at-once and another where data\n * buffers are presented sequentially. In the sequential interface, the\n * UHASH client calls the routine uhash_update() as many times as necessary.\n * When there is no more data to be fed to UHASH, the client calls\n * uhash_final() which \n * calculates the UHASH output. Before beginning another UHASH calculation \n * the uhash_reset() routine must be called. The all-at-once UHASH routine, \n * uhash(), is equivalent to the sequence of calls uhash_update() and \n * uhash_final(); however it is optimized and should be \n * used whenever the sequential interface is not necessary. \n * \n * The routine uhash_init() initializes the uhash_ctx data structure and \n * must be called once, before any other UHASH routine.\n */ \n\n/* ---------------------------------------------------------------------- */\n/* ----- Constants and uhash_ctx ---------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------- */\n/* ----- Poly hash and Inner-Product hash Constants --------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* Primes and masks */\n#define p36 ((UINT64)0x0000000FFFFFFFFBull) /* 2^36 - 5 */\n#define p64 ((UINT64)0xFFFFFFFFFFFFFFC5ull) /* 2^64 - 59 */\n#define m36 ((UINT64)0x0000000FFFFFFFFFull) /* The low 36 of 64 bits */\n\n\n/* ---------------------------------------------------------------------- */\n\ntypedef struct uhash_ctx {\n nh_ctx hash; /* Hash context for L1 NH hash */\n UINT64 poly_key_8[STREAMS]; /* p64 poly keys */\n UINT64 poly_accum[STREAMS]; /* poly hash result */\n UINT64 ip_keys[STREAMS*4]; /* Inner-product keys */\n UINT32 ip_trans[STREAMS]; /* Inner-product translation */\n UINT32 msg_len; /* Total length of data passed */\n /* to uhash */\n} uhash_ctx;\ntypedef struct uhash_ctx *uhash_ctx_t;\n\n/* ---------------------------------------------------------------------- */\n\n\n/* The polynomial hashes use Horner's rule to evaluate a polynomial one\n * word at a time. As described in the specification, poly32 and poly64\n * require keys from special domains. The following implementations exploit\n * the special domains to avoid overflow. The results are not guaranteed to\n * be within Z_p32 and Z_p64, but the Inner-Product hash implementation\n * patches any errant values.\n */\n\nstatic UINT64 poly64(UINT64 cur, UINT64 key, UINT64 data)\n{\n UINT32 key_hi = (UINT32)(key >> 32),\n key_lo = (UINT32)key,\n cur_hi = (UINT32)(cur >> 32),\n cur_lo = (UINT32)cur,\n x_lo,\n x_hi;\n UINT64 X,T,res;\n \n X = MUL64(key_hi, cur_lo) + MUL64(cur_hi, key_lo);\n x_lo = (UINT32)X;\n x_hi = (UINT32)(X >> 32);\n \n res = (MUL64(key_hi, cur_hi) + x_hi) * 59 + MUL64(key_lo, cur_lo);\n \n T = ((UINT64)x_lo << 32);\n res += T;\n if (res < T)\n res += 59;\n\n res += data;\n if (res < data)\n res += 59;\n\n return res;\n}\n\n\n/* Although UMAC is specified to use a ramped polynomial hash scheme, this\n * implementation does not handle all ramp levels. Because we don't handle\n * the ramp up to p128 modulus in this implementation, we are limited to\n * 2^14 poly_hash() invocations per stream (for a total capacity of 2^24\n * bytes input to UMAC per tag, ie. 16MB).\n */\nstatic void poly_hash(uhash_ctx_t hc, UINT32 data_in[])\n{\n int i;\n UINT64 *data=(UINT64*)data_in;\n \n for (i = 0; i < STREAMS; i++) {\n if ((UINT32)(data[i] >> 32) == 0xfffffffful) {\n hc->poly_accum[i] = poly64(hc->poly_accum[i], \n hc->poly_key_8[i], p64 - 1);\n hc->poly_accum[i] = poly64(hc->poly_accum[i],\n hc->poly_key_8[i], (data[i] - 59));\n } else {\n hc->poly_accum[i] = poly64(hc->poly_accum[i],\n hc->poly_key_8[i], data[i]);\n }\n }\n}\n\n\n/* ---------------------------------------------------------------------- */\n\n\n/* The final step in UHASH is an inner-product hash. The poly hash\n * produces a result not neccesarily WORD_LEN bytes long. The inner-\n * product hash breaks the polyhash output into 16-bit chunks and\n * multiplies each with a 36 bit key.\n */\n\nstatic UINT64 ip_aux(UINT64 t, UINT64 *ipkp, UINT64 data)\n{\n t = t + ipkp[0] * (UINT64)(UINT16)(data >> 48);\n t = t + ipkp[1] * (UINT64)(UINT16)(data >> 32);\n t = t + ipkp[2] * (UINT64)(UINT16)(data >> 16);\n t = t + ipkp[3] * (UINT64)(UINT16)(data);\n \n return t;\n}\n\nstatic UINT32 ip_reduce_p36(UINT64 t)\n{\n/* Divisionless modular reduction */\n UINT64 ret;\n \n ret = (t & m36) + 5 * (t >> 36);\n if (ret >= p36)\n ret -= p36;\n\n /* return least significant 32 bits */\n return (UINT32)(ret);\n}\n\n\n/* If the data being hashed by UHASH is no longer than L1_KEY_LEN, then\n * the polyhash stage is skipped and ip_short is applied directly to the\n * NH output.\n */\nstatic void ip_short(uhash_ctx_t ahc, UINT8 *nh_res, u_char *res)\n{\n UINT64 t;\n UINT64 *nhp = (UINT64 *)nh_res;\n \n t = ip_aux(0,ahc->ip_keys, nhp[0]);\n STORE_UINT32_BIG((UINT32 *)res+0, ip_reduce_p36(t) ^ ahc->ip_trans[0]);\n#if (UMAC_OUTPUT_LEN >= 8)\n t = ip_aux(0,ahc->ip_keys+4, nhp[1]);\n STORE_UINT32_BIG((UINT32 *)res+1, ip_reduce_p36(t) ^ ahc->ip_trans[1]);\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n t = ip_aux(0,ahc->ip_keys+8, nhp[2]);\n STORE_UINT32_BIG((UINT32 *)res+2, ip_reduce_p36(t) ^ ahc->ip_trans[2]);\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n t = ip_aux(0,ahc->ip_keys+12, nhp[3]);\n STORE_UINT32_BIG((UINT32 *)res+3, ip_reduce_p36(t) ^ ahc->ip_trans[3]);\n#endif\n}\n\n/* If the data being hashed by UHASH is longer than L1_KEY_LEN, then\n * the polyhash stage is not skipped and ip_long is applied to the\n * polyhash output.\n */\nstatic void ip_long(uhash_ctx_t ahc, u_char *res)\n{\n int i;\n UINT64 t;\n\n for (i = 0; i < STREAMS; i++) {\n /* fix polyhash output not in Z_p64 */\n if (ahc->poly_accum[i] >= p64)\n ahc->poly_accum[i] -= p64;\n t = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]);\n STORE_UINT32_BIG((UINT32 *)res+i, \n ip_reduce_p36(t) ^ ahc->ip_trans[i]);\n }\n}\n\n\n/* ---------------------------------------------------------------------- */\n\n/* ---------------------------------------------------------------------- */\n\n/* Reset uhash context for next hash session */\nstatic int uhash_reset(uhash_ctx_t pc)\n{\n nh_reset(&pc->hash);\n pc->msg_len = 0;\n pc->poly_accum[0] = 1;\n#if (UMAC_OUTPUT_LEN >= 8)\n pc->poly_accum[1] = 1;\n#endif\n#if (UMAC_OUTPUT_LEN >= 12)\n pc->poly_accum[2] = 1;\n#endif\n#if (UMAC_OUTPUT_LEN == 16)\n pc->poly_accum[3] = 1;\n#endif\n return 1;\n}\n\n/* ---------------------------------------------------------------------- */\n\n/* Given a pointer to the internal key needed by kdf() and a uhash context,\n * initialize the NH context and generate keys needed for poly and inner-\n * product hashing. All keys are endian adjusted in memory so that native\n * loads cause correct keys to be in registers during calculation.\n */\nstatic void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)\n{\n int i;\n UINT8 buf[(8*STREAMS+4)*sizeof(UINT64)];\n \n /* Zero the entire uhash context */\n memset(ahc, 0, sizeof(uhash_ctx));\n\n /* Initialize the L1 hash */\n nh_init(&ahc->hash, prf_key);\n \n /* Setup L2 hash variables */\n kdf(buf, prf_key, 2, sizeof(buf)); /* Fill buffer with index 1 key */\n for (i = 0; i < STREAMS; i++) {\n /* Fill keys from the buffer, skipping bytes in the buffer not\n * used by this implementation. Endian reverse the keys if on a\n * little-endian computer.\n */\n memcpy(ahc->poly_key_8+i, buf+24*i, 8);\n endian_convert_if_le(ahc->poly_key_8+i, 8, 8);\n /* Mask the 64-bit keys to their special domain */\n ahc->poly_key_8[i] &= ((UINT64)0x01ffffffu << 32) + 0x01ffffffu;\n ahc->poly_accum[i] = 1; /* Our polyhash prepends a non-zero word */\n }\n \n /* Setup L3-1 hash variables */\n kdf(buf, prf_key, 3, sizeof(buf)); /* Fill buffer with index 2 key */\n for (i = 0; i < STREAMS; i++)\n memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64),\n 4*sizeof(UINT64));\n endian_convert_if_le(ahc->ip_keys, sizeof(UINT64), \n sizeof(ahc->ip_keys));\n for (i = 0; i < STREAMS*4; i++)\n ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */\n \n /* Setup L3-2 hash variables */\n /* Fill buffer with index 4 key */\n kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32));\n endian_convert_if_le(ahc->ip_trans, sizeof(UINT32),\n STREAMS * sizeof(UINT32));\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nstatic uhash_ctx_t uhash_alloc(u_char key[])\n{\n/* Allocate memory and force to a 16-byte boundary. */\n uhash_ctx_t ctx;\n u_char bytes_to_add;\n aes_int_key prf_key;\n \n ctx = (uhash_ctx_t)malloc(sizeof(uhash_ctx)+ALLOC_BOUNDARY);\n if (ctx) {\n if (ALLOC_BOUNDARY) {\n bytes_to_add = ALLOC_BOUNDARY -\n ((ptrdiff_t)ctx & (ALLOC_BOUNDARY -1));\n ctx = (uhash_ctx_t)((u_char *)ctx + bytes_to_add);\n *((u_char *)ctx - 1) = bytes_to_add;\n }\n aes_key_setup(key,prf_key);\n uhash_init(ctx, prf_key);\n }\n return (ctx);\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nstatic int uhash_free(uhash_ctx_t ctx)\n{\n/* Free memory allocated by uhash_alloc */\n u_char bytes_to_sub;\n \n if (ctx) {\n if (ALLOC_BOUNDARY) {\n bytes_to_sub = *((u_char *)ctx - 1);\n ctx = (uhash_ctx_t)((u_char *)ctx - bytes_to_sub);\n }\n free(ctx);\n }\n return (1);\n}\n#endif\n/* ---------------------------------------------------------------------- */\n\nstatic int uhash_update(uhash_ctx_t ctx, const u_char *input, long len)\n/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and\n * hash each one with NH, calling the polyhash on each NH output.\n */\n{\n UWORD bytes_hashed, bytes_remaining;\n UINT64 result_buf[STREAMS];\n UINT8 *nh_result = (UINT8 *)&result_buf;\n \n if (ctx->msg_len + len <= L1_KEY_LEN) {\n nh_update(&ctx->hash, (const UINT8 *)input, len);\n ctx->msg_len += len;\n } else {\n \n bytes_hashed = ctx->msg_len % L1_KEY_LEN;\n if (ctx->msg_len == L1_KEY_LEN)\n bytes_hashed = L1_KEY_LEN;\n\n if (bytes_hashed + len >= L1_KEY_LEN) {\n\n /* If some bytes have been passed to the hash function */\n /* then we want to pass at most (L1_KEY_LEN - bytes_hashed) */\n /* bytes to complete the current nh_block. */\n if (bytes_hashed) {\n bytes_remaining = (L1_KEY_LEN - bytes_hashed);\n nh_update(&ctx->hash, (const UINT8 *)input, bytes_remaining);\n nh_final(&ctx->hash, nh_result);\n ctx->msg_len += bytes_remaining;\n poly_hash(ctx,(UINT32 *)nh_result);\n len -= bytes_remaining;\n input += bytes_remaining;\n }\n\n /* Hash directly from input stream if enough bytes */\n while (len >= L1_KEY_LEN) {\n nh(&ctx->hash, (const UINT8 *)input, L1_KEY_LEN,\n L1_KEY_LEN, nh_result);\n ctx->msg_len += L1_KEY_LEN;\n len -= L1_KEY_LEN;\n input += L1_KEY_LEN;\n poly_hash(ctx,(UINT32 *)nh_result);\n }\n }\n\n /* pass remaining < L1_KEY_LEN bytes of input data to NH */\n if (len) {\n nh_update(&ctx->hash, (const UINT8 *)input, len);\n ctx->msg_len += len;\n }\n }\n\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int uhash_final(uhash_ctx_t ctx, u_char *res)\n/* Incorporate any pending data, pad, and generate tag */\n{\n UINT64 result_buf[STREAMS];\n UINT8 *nh_result = (UINT8 *)&result_buf;\n\n if (ctx->msg_len > L1_KEY_LEN) {\n if (ctx->msg_len % L1_KEY_LEN) {\n nh_final(&ctx->hash, nh_result);\n poly_hash(ctx,(UINT32 *)nh_result);\n }\n ip_long(ctx, res);\n } else {\n nh_final(&ctx->hash, nh_result);\n ip_short(ctx,nh_result, res);\n }\n uhash_reset(ctx);\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nstatic int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res)\n/* assumes that msg is in a writable buffer of length divisible by */\n/* L1_PAD_BOUNDARY. Bytes beyond msg[len] may be zeroed. */\n{\n UINT8 nh_result[STREAMS*sizeof(UINT64)];\n UINT32 nh_len;\n int extra_zeroes_needed;\n \n /* If the message to be hashed is no longer than L1_HASH_LEN, we skip\n * the polyhash.\n */\n if (len <= L1_KEY_LEN) {\n \tif (len == 0) /* If zero length messages will not */\n \t\tnh_len = L1_PAD_BOUNDARY; /* be seen, comment out this case */ \n \telse\n \tnh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1));\n extra_zeroes_needed = nh_len - len;\n zero_pad((UINT8 *)msg + len, extra_zeroes_needed);\n nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result);\n ip_short(ahc,nh_result, res);\n } else {\n /* Otherwise, we hash each L1_KEY_LEN chunk with NH, passing the NH\n * output to poly_hash().\n */\n do {\n nh(&ahc->hash, (UINT8 *)msg, L1_KEY_LEN, L1_KEY_LEN, nh_result);\n poly_hash(ahc,(UINT32 *)nh_result);\n len -= L1_KEY_LEN;\n msg += L1_KEY_LEN;\n } while (len >= L1_KEY_LEN);\n if (len) {\n nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1));\n extra_zeroes_needed = nh_len - len;\n zero_pad((UINT8 *)msg + len, extra_zeroes_needed);\n nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result);\n poly_hash(ahc,(UINT32 *)nh_result);\n }\n\n ip_long(ahc, res);\n }\n \n uhash_reset(ahc);\n return 1;\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- Begin UMAC Section --------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n\n/* The UMAC interface has two interfaces, an all-at-once interface where\n * the entire message to be authenticated is passed to UMAC in one buffer,\n * and a sequential interface where the message is presented a little at a \n * time. The all-at-once is more optimaized than the sequential version and\n * should be preferred when the sequential interface is not required. \n */\nstruct umac_ctx {\n uhash_ctx hash; /* Hash function for message compression */\n pdf_ctx pdf; /* PDF for hashed output */\n void *free_ptr; /* Address to free this struct via */\n} umac_ctx;\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nint umac_reset(struct umac_ctx *ctx)\n/* Reset the hash function to begin a new authentication. */\n{\n uhash_reset(&ctx->hash);\n return (1);\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n\nint umac_delete(struct umac_ctx *ctx)\n/* Deallocate the ctx structure */\n{\n if (ctx) {\n if (ALLOC_BOUNDARY)\n ctx = (struct umac_ctx *)ctx->free_ptr;\n free(ctx);\n }\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstruct umac_ctx *umac_new(const u_char key[])\n/* Dynamically allocate a umac_ctx struct, initialize variables, \n * generate subkeys from key. Align to 16-byte boundary.\n */\n{\n struct umac_ctx *ctx, *octx;\n size_t bytes_to_add;\n aes_int_key prf_key;\n \n octx = ctx = xcalloc(1, sizeof(*ctx) + ALLOC_BOUNDARY);\n if (ctx) {\n if (ALLOC_BOUNDARY) {\n bytes_to_add = ALLOC_BOUNDARY -\n ((ptrdiff_t)ctx & (ALLOC_BOUNDARY - 1));\n ctx = (struct umac_ctx *)((u_char *)ctx + bytes_to_add);\n }\n ctx->free_ptr = octx;\n aes_key_setup(key, prf_key);\n pdf_init(&ctx->pdf, prf_key);\n uhash_init(&ctx->hash, prf_key);\n }\n \n return (ctx);\n}\n\n/* ---------------------------------------------------------------------- */\n\nint umac_final(struct umac_ctx *ctx, u_char tag[], const u_char nonce[8])\n/* Incorporate any pending data, pad, and generate tag */\n{\n uhash_final(&ctx->hash, (u_char *)tag);\n pdf_gen_xor(&ctx->pdf, (const UINT8 *)nonce, (UINT8 *)tag);\n \n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\nint umac_update(struct umac_ctx *ctx, const u_char *input, long len)\n/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */\n/* hash each one, calling the PDF on the hashed output whenever the hash- */\n/* output buffer is full. */\n{\n uhash_update(&ctx->hash, input, len);\n return (1);\n}\n\n/* ---------------------------------------------------------------------- */\n\n#if 0\nint umac(struct umac_ctx *ctx, u_char *input, \n long len, u_char tag[],\n u_char nonce[8])\n/* All-in-one version simply calls umac_update() and umac_final(). */\n{\n uhash(&ctx->hash, input, len, (u_char *)tag);\n pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag);\n \n return (1);\n}\n#endif\n\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ----- End UMAC Section ----------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n/* ---------------------------------------------------------------------- */\n","/*\n * Copyright (c) 2013 Damien Miller \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/* $OpenBSD: cipher-chachapoly.c,v 1.8 2016/08/03 05:41:57 djm Exp $ */\n\n#include \"includes.h\"\n\n#include \n#include /* needed for log.h */\n#include \n#include /* needed for misc.h */\n\n#include \"log.h\"\n#include \"sshbuf.h\"\n#include \"ssherr.h\"\n#include \"cipher-chachapoly.h\"\n\nint\nchachapoly_init(struct chachapoly_ctx *ctx,\n const u_char *key, u_int keylen)\n{\n\tif (keylen != (32 + 32)) /* 2 x 256 bit keys */\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tchacha_keysetup(&ctx->main_ctx, key, 256);\n\tchacha_keysetup(&ctx->header_ctx, key + 32, 256);\n\treturn 0;\n}\n\n/*\n * chachapoly_crypt() operates as following:\n * En/decrypt with header key 'aadlen' bytes from 'src', storing result\n * to 'dest'. The ciphertext here is treated as additional authenticated\n * data for MAC calculation.\n * En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use\n * POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication\n * tag. This tag is written on encryption and verified on decryption.\n */\nint\nchachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,\n const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt)\n{\n\tu_char seqbuf[8];\n\tconst u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */\n\tu_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\n\t/*\n\t * Run ChaCha20 once to generate the Poly1305 key. The IV is the\n\t * packet sequence number.\n\t */\n\tmemset(poly_key, 0, sizeof(poly_key));\n\tPOKE_U64(seqbuf, seqnr);\n\tchacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);\n\tchacha_encrypt_bytes(&ctx->main_ctx,\n\t poly_key, poly_key, sizeof(poly_key));\n\n\t/* If decrypting, check tag before anything else */\n\tif (!do_encrypt) {\n\t\tconst u_char *tag = src + aadlen + len;\n\n\t\tpoly1305_auth(expected_tag, src, aadlen + len, poly_key);\n\t\tif (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {\n\t\t\tr = SSH_ERR_MAC_INVALID;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\t/* Crypt additional data */\n\tif (aadlen) {\n\t\tchacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);\n\t\tchacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen);\n\t}\n\n\t/* Set Chacha's block counter to 1 */\n\tchacha_ivsetup(&ctx->main_ctx, seqbuf, one);\n\tchacha_encrypt_bytes(&ctx->main_ctx, src + aadlen,\n\t dest + aadlen, len);\n\n\t/* If encrypting, calculate and append tag */\n\tif (do_encrypt) {\n\t\tpoly1305_auth(dest + aadlen + len, dest, aadlen + len,\n\t\t poly_key);\n\t}\n\tr = 0;\n out:\n\texplicit_bzero(expected_tag, sizeof(expected_tag));\n\texplicit_bzero(seqbuf, sizeof(seqbuf));\n\texplicit_bzero(poly_key, sizeof(poly_key));\n\treturn r;\n}\n\n/* Decrypt and extract the encrypted packet length */\nint\nchachapoly_get_length(struct chachapoly_ctx *ctx,\n u_int *plenp, u_int seqnr, const u_char *cp, u_int len)\n{\n\tu_char buf[4], seqbuf[8];\n\n\tif (len < 4)\n\t\treturn SSH_ERR_MESSAGE_INCOMPLETE;\n\tPOKE_U64(seqbuf, seqnr);\n\tchacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);\n\tchacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4);\n\t*plenp = PEEK_U32(buf);\n\treturn 0;\n}\n","/* $OpenBSD: ssh-ed25519.c,v 1.7 2016/04/21 06:08:02 djm Exp $ */\n/*\n * Copyright (c) 2013 Markus Friedl \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \"crypto_api.h\"\n\n#include \n#include \n\n#include \"log.h\"\n#include \"sshbuf.h\"\n#define SSHKEY_INTERNAL\n#include \"sshkey.h\"\n#include \"ssherr.h\"\n#include \"ssh.h\"\n\nint\nssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,\n const u_char *data, size_t datalen, u_int compat)\n{\n\tu_char *sig = NULL;\n\tsize_t slen = 0, len;\n\tunsigned long long smlen;\n\tint r, ret;\n\tstruct sshbuf *b = NULL;\n\n\tif (lenp != NULL)\n\t\t*lenp = 0;\n\tif (sigp != NULL)\n\t\t*sigp = NULL;\n\n\tif (key == NULL ||\n\t sshkey_type_plain(key->type) != KEY_ED25519 ||\n\t key->ed25519_sk == NULL ||\n\t datalen >= INT_MAX - crypto_sign_ed25519_BYTES)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tsmlen = slen = datalen + crypto_sign_ed25519_BYTES;\n\tif ((sig = malloc(slen)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\tif ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,\n\t key->ed25519_sk)) != 0 || smlen <= datalen) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT; /* XXX better error? */\n\t\tgoto out;\n\t}\n\t/* encode signature */\n\tif ((b = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_put_cstring(b, \"ssh-ed25519\")) != 0 ||\n\t (r = sshbuf_put_string(b, sig, smlen - datalen)) != 0)\n\t\tgoto out;\n\tlen = sshbuf_len(b);\n\tif (sigp != NULL) {\n\t\tif ((*sigp = malloc(len)) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tmemcpy(*sigp, sshbuf_ptr(b), len);\n\t}\n\tif (lenp != NULL)\n\t\t*lenp = len;\n\t/* success */\n\tr = 0;\n out:\n\tsshbuf_free(b);\n\tif (sig != NULL) {\n\t\texplicit_bzero(sig, slen);\n\t\tfree(sig);\n\t}\n\n\treturn r;\n}\n\nint\nssh_ed25519_verify(const struct sshkey *key,\n const u_char *signature, size_t signaturelen,\n const u_char *data, size_t datalen, u_int compat)\n{\n\tstruct sshbuf *b = NULL;\n\tchar *ktype = NULL;\n\tconst u_char *sigblob;\n\tu_char *sm = NULL, *m = NULL;\n\tsize_t len;\n\tunsigned long long smlen = 0, mlen = 0;\n\tint r, ret;\n\n\tif (key == NULL ||\n\t sshkey_type_plain(key->type) != KEY_ED25519 ||\n\t key->ed25519_pk == NULL ||\n\t datalen >= INT_MAX - crypto_sign_ed25519_BYTES ||\n\t signature == NULL || signaturelen == 0)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\n\tif ((b = sshbuf_from(signature, signaturelen)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_get_cstring(b, &ktype, NULL)) != 0 ||\n\t (r = sshbuf_get_string_direct(b, &sigblob, &len)) != 0)\n\t\tgoto out;\n\tif (strcmp(\"ssh-ed25519\", ktype) != 0) {\n\t\tr = SSH_ERR_KEY_TYPE_MISMATCH;\n\t\tgoto out;\n\t}\n\tif (sshbuf_len(b) != 0) {\n\t\tr = SSH_ERR_UNEXPECTED_TRAILING_DATA;\n\t\tgoto out;\n\t}\n\tif (len > crypto_sign_ed25519_BYTES) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tif (datalen >= SIZE_MAX - len) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\tsmlen = len + datalen;\n\tmlen = smlen;\n\tif ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tmemcpy(sm, sigblob, len);\n\tmemcpy(sm+len, data, datalen);\n\tif ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,\n\t key->ed25519_pk)) != 0) {\n\t\tdebug2(\"%s: crypto_sign_ed25519_open failed: %d\",\n\t\t __func__, ret);\n\t}\n\tif (ret != 0 || mlen != datalen) {\n\t\tr = SSH_ERR_SIGNATURE_INVALID;\n\t\tgoto out;\n\t}\n\t/* XXX compare 'm' and 'data' ? */\n\t/* success */\n\tr = 0;\n out:\n\tif (sm != NULL) {\n\t\texplicit_bzero(sm, smlen);\n\t\tfree(sm);\n\t}\n\tif (m != NULL) {\n\t\texplicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */\n\t\tfree(m);\n\t}\n\tsshbuf_free(b);\n\tfree(ktype);\n\treturn r;\n}\n","/* $OpenBSD: digest-libc.c,v 1.5 2015/05/05 02:48:17 jsg Exp $ */\n/*\n * Copyright (c) 2013 Damien Miller \n * Copyright (c) 2014 Markus Friedl. All rights reserved.\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"includes.h\"\n\n#ifndef WITH_OPENSSL\n\n#include \n#include \n#include \n#include \n\n#if 0\n#include \n#include \n#include \n#include \n#endif\n\n#include \"ssherr.h\"\n#include \"sshbuf.h\"\n#include \"digest.h\"\n\ntypedef void md_init_fn(void *mdctx);\ntypedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen);\ntypedef void md_final_fn(u_int8_t[], void *mdctx);\n\nstruct ssh_digest_ctx {\n\tint alg;\n\tvoid *mdctx;\n};\n\nstruct ssh_digest {\n\tint id;\n\tconst char *name;\n\tsize_t block_len;\n\tsize_t digest_len;\n\tsize_t ctx_len;\n\tmd_init_fn *md_init;\n\tmd_update_fn *md_update;\n\tmd_final_fn *md_final;\n};\n\n/* NB. Indexed directly by algorithm number */\nconst struct ssh_digest digests[SSH_DIGEST_MAX] = {\n\t{\n\t\tSSH_DIGEST_MD5,\n\t\t\"MD5\",\n\t\tMD5_BLOCK_LENGTH,\n\t\tMD5_DIGEST_LENGTH,\n\t\tsizeof(MD5_CTX),\n\t\t(md_init_fn *) MD5Init,\n\t\t(md_update_fn *) MD5Update,\n\t\t(md_final_fn *) MD5Final\n\t},\n\t{\n\t\tSSH_DIGEST_RIPEMD160,\n\t\t\"RIPEMD160\",\n\t\tRMD160_BLOCK_LENGTH,\n\t\tRMD160_DIGEST_LENGTH,\n\t\tsizeof(RMD160_CTX),\n\t\t(md_init_fn *) RMD160Init,\n\t\t(md_update_fn *) RMD160Update,\n\t\t(md_final_fn *) RMD160Final\n\t},\n\t{\n\t\tSSH_DIGEST_SHA1,\n\t\t\"SHA1\",\n\t\tSHA1_BLOCK_LENGTH,\n\t\tSHA1_DIGEST_LENGTH,\n\t\tsizeof(SHA1_CTX),\n\t\t(md_init_fn *) SHA1Init,\n\t\t(md_update_fn *) SHA1Update,\n\t\t(md_final_fn *) SHA1Final\n\t},\n\t{\n\t\tSSH_DIGEST_SHA256,\n\t\t\"SHA256\",\n\t\tSHA256_BLOCK_LENGTH,\n\t\tSHA256_DIGEST_LENGTH,\n\t\tsizeof(SHA256_CTX),\n\t\t(md_init_fn *) SHA256_Init,\n\t\t(md_update_fn *) SHA256_Update,\n\t\t(md_final_fn *) SHA256_Final\n\t},\n\t{\n\t\tSSH_DIGEST_SHA384,\n\t\t\"SHA384\",\n\t\tSHA384_BLOCK_LENGTH,\n\t\tSHA384_DIGEST_LENGTH,\n\t\tsizeof(SHA384_CTX),\n\t\t(md_init_fn *) SHA384_Init,\n\t\t(md_update_fn *) SHA384_Update,\n\t\t(md_final_fn *) SHA384_Final\n\t},\n\t{\n\t\tSSH_DIGEST_SHA512,\n\t\t\"SHA512\",\n\t\tSHA512_BLOCK_LENGTH,\n\t\tSHA512_DIGEST_LENGTH,\n\t\tsizeof(SHA512_CTX),\n\t\t(md_init_fn *) SHA512_Init,\n\t\t(md_update_fn *) SHA512_Update,\n\t\t(md_final_fn *) SHA512_Final\n\t}\n};\n\nstatic const struct ssh_digest *\nssh_digest_by_alg(int alg)\n{\n\tif (alg < 0 || alg >= SSH_DIGEST_MAX)\n\t\treturn NULL;\n\tif (digests[alg].id != alg) /* sanity */\n\t\treturn NULL;\n\treturn &(digests[alg]);\n}\n\nint\nssh_digest_alg_by_name(const char *name)\n{\n\tint alg;\n\n\tfor (alg = 0; alg < SSH_DIGEST_MAX; alg++) {\n\t\tif (strcasecmp(name, digests[alg].name) == 0)\n\t\t\treturn digests[alg].id;\n\t}\n\treturn -1;\n}\n\nconst char *\nssh_digest_alg_name(int alg)\n{\n\tconst struct ssh_digest *digest = ssh_digest_by_alg(alg);\n\n\treturn digest == NULL ? NULL : digest->name;\n}\n\nsize_t\nssh_digest_bytes(int alg)\n{\n\tconst struct ssh_digest *digest = ssh_digest_by_alg(alg);\n\n\treturn digest == NULL ? 0 : digest->digest_len;\n}\n\nsize_t\nssh_digest_blocksize(struct ssh_digest_ctx *ctx)\n{\n\tconst struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);\n\n\treturn digest == NULL ? 0 : digest->block_len;\n}\n\nstruct ssh_digest_ctx *\nssh_digest_start(int alg)\n{\n\tconst struct ssh_digest *digest = ssh_digest_by_alg(alg);\n\tstruct ssh_digest_ctx *ret;\n\n\tif (digest == NULL || (ret = calloc(1, sizeof(*ret))) == NULL)\n\t\treturn NULL;\n\tif ((ret->mdctx = calloc(1, digest->ctx_len)) == NULL) {\n\t\tfree(ret);\n\t\treturn NULL;\n\t}\n\tret->alg = alg;\n\tdigest->md_init(ret->mdctx);\n\treturn ret;\n}\n\nint\nssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)\n{\n\tconst struct ssh_digest *digest = ssh_digest_by_alg(from->alg);\n\n\tif (digest == NULL || from->alg != to->alg)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tmemcpy(to->mdctx, from->mdctx, digest->ctx_len);\n\treturn 0;\n}\n\nint\nssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)\n{\n\tconst struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);\n\n\tif (digest == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tdigest->md_update(ctx->mdctx, m, mlen);\n\treturn 0;\n}\n\nint\nssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b)\n{\n\treturn ssh_digest_update(ctx, sshbuf_ptr(b), sshbuf_len(b));\n}\n\nint\nssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)\n{\n\tconst struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);\n\n\tif (digest == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif (dlen > UINT_MAX)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif (dlen < digest->digest_len) /* No truncation allowed */\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tdigest->md_final(d, ctx->mdctx);\n\treturn 0;\n}\n\nvoid\nssh_digest_free(struct ssh_digest_ctx *ctx)\n{\n\tconst struct ssh_digest *digest;\n\n\tif (ctx != NULL) {\n\t\tdigest = ssh_digest_by_alg(ctx->alg);\n\t\tif (digest) {\n\t\t\texplicit_bzero(ctx->mdctx, digest->ctx_len);\n\t\t\tfree(ctx->mdctx);\n\t\t\texplicit_bzero(ctx, sizeof(*ctx));\n\t\t\tfree(ctx);\n\t\t}\n\t}\n}\n\nint\nssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)\n{\n\tstruct ssh_digest_ctx *ctx = ssh_digest_start(alg);\n\n\tif (ctx == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif (ssh_digest_update(ctx, m, mlen) != 0 ||\n\t ssh_digest_final(ctx, d, dlen) != 0)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tssh_digest_free(ctx);\n\treturn 0;\n}\n\nint\nssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen)\n{\n\treturn ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen);\n}\n#endif /* !WITH_OPENSSL */\n","/* $OpenBSD: hmac.c,v 1.12 2015/03/24 20:03:44 markus Exp $ */\n/*\n * Copyright (c) 2014 Markus Friedl. All rights reserved.\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n\n#include \"sshbuf.h\"\n#include \"digest.h\"\n#include \"hmac.h\"\n\nstruct ssh_hmac_ctx {\n\tint\t\t\t alg;\n\tstruct ssh_digest_ctx\t*ictx;\n\tstruct ssh_digest_ctx\t*octx;\n\tstruct ssh_digest_ctx\t*digest;\n\tu_char\t\t\t*buf;\n\tsize_t\t\t\t buf_len;\n};\n\nsize_t\nssh_hmac_bytes(int alg)\n{\n\treturn ssh_digest_bytes(alg);\n}\n\nstruct ssh_hmac_ctx *\nssh_hmac_start(int alg)\n{\n\tstruct ssh_hmac_ctx\t*ret;\n\n\tif ((ret = calloc(1, sizeof(*ret))) == NULL)\n\t\treturn NULL;\n\tret->alg = alg;\n\tif ((ret->ictx = ssh_digest_start(alg)) == NULL ||\n\t (ret->octx = ssh_digest_start(alg)) == NULL ||\n\t (ret->digest = ssh_digest_start(alg)) == NULL)\n\t\tgoto fail;\n\tret->buf_len = ssh_digest_blocksize(ret->ictx);\n\tif ((ret->buf = calloc(1, ret->buf_len)) == NULL)\n\t\tgoto fail;\n\treturn ret;\nfail:\n\tssh_hmac_free(ret);\n\treturn NULL;\n}\n\nint\nssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen)\n{\n\tsize_t i;\n\n\t/* reset ictx and octx if no is key given */\n\tif (key != NULL) {\n\t\t/* truncate long keys */\n\t\tif (klen <= ctx->buf_len)\n\t\t\tmemcpy(ctx->buf, key, klen);\n\t\telse if (ssh_digest_memory(ctx->alg, key, klen, ctx->buf,\n\t\t ctx->buf_len) < 0)\n\t\t\treturn -1;\n\t\tfor (i = 0; i < ctx->buf_len; i++)\n\t\t\tctx->buf[i] ^= 0x36;\n\t\tif (ssh_digest_update(ctx->ictx, ctx->buf, ctx->buf_len) < 0)\n\t\t\treturn -1;\n\t\tfor (i = 0; i < ctx->buf_len; i++)\n\t\t\tctx->buf[i] ^= 0x36 ^ 0x5c;\n\t\tif (ssh_digest_update(ctx->octx, ctx->buf, ctx->buf_len) < 0)\n\t\t\treturn -1;\n\t\texplicit_bzero(ctx->buf, ctx->buf_len);\n\t}\n\t/* start with ictx */\n\tif (ssh_digest_copy_state(ctx->ictx, ctx->digest) < 0)\n\t\treturn -1;\n\treturn 0;\n}\n\nint\nssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen)\n{\n\treturn ssh_digest_update(ctx->digest, m, mlen);\n}\n\nint\nssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const struct sshbuf *b)\n{\n\treturn ssh_digest_update_buffer(ctx->digest, b);\n}\n\nint\nssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen)\n{\n\tsize_t len;\n\n\tlen = ssh_digest_bytes(ctx->alg);\n\tif (dlen < len ||\n\t ssh_digest_final(ctx->digest, ctx->buf, len))\n\t\treturn -1;\n\t/* switch to octx */\n\tif (ssh_digest_copy_state(ctx->octx, ctx->digest) < 0 ||\n\t ssh_digest_update(ctx->digest, ctx->buf, len) < 0 ||\n\t ssh_digest_final(ctx->digest, d, dlen) < 0)\n\t\treturn -1;\n\treturn 0;\n}\n\nvoid\nssh_hmac_free(struct ssh_hmac_ctx *ctx)\n{\n\tif (ctx != NULL) {\n\t\tssh_digest_free(ctx->ictx);\n\t\tssh_digest_free(ctx->octx);\n\t\tssh_digest_free(ctx->digest);\n\t\tif (ctx->buf) {\n\t\t\texplicit_bzero(ctx->buf, ctx->buf_len);\n\t\t\tfree(ctx->buf);\n\t\t}\n\t\texplicit_bzero(ctx, sizeof(*ctx));\n\t\tfree(ctx);\n\t}\n}\n\n#ifdef TEST\n\n/* cc -DTEST hmac.c digest.c buffer.c cleanup.c fatal.c log.c xmalloc.c -lcrypto */\nstatic void\nhmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen)\n{\n\tstruct ssh_hmac_ctx\t*ctx;\n\tsize_t\t\t\t i;\n\tu_char\t\t\t digest[16];\n\n\tif ((ctx = ssh_hmac_start(SSH_DIGEST_MD5)) == NULL)\n\t\tprintf(\"ssh_hmac_start failed\");\n\tif (ssh_hmac_init(ctx, key, klen) < 0 ||\n\t ssh_hmac_update(ctx, m, mlen) < 0 ||\n\t ssh_hmac_final(ctx, digest, sizeof(digest)) < 0)\n\t\tprintf(\"ssh_hmac_xxx failed\");\n\tssh_hmac_free(ctx);\n\n\tif (memcmp(e, digest, elen)) {\n\t\tfor (i = 0; i < elen; i++)\n\t\t\tprintf(\"[%zu] %2.2x %2.2x\\n\", i, e[i], digest[i]);\n\t\tprintf(\"mismatch\\n\");\n\t} else\n\t\tprintf(\"ok\\n\");\n}\n\nint\nmain(int argc, char **argv)\n{\n\t/* try test vectors from RFC 2104 */\n\n\tu_char key1[16] = {\n\t 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb,\n\t 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb };\n\tu_char *data1 = \"Hi There\";\n\tu_char dig1[16] = {\n\t 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,\n\t 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d };\n\n\tu_char *key2 = \"Jefe\";\n\tu_char *data2 = \"what do ya want for nothing?\";\n\tu_char dig2[16] = {\n\t 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,\n\t 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 };\n\n\tu_char key3[16];\n\tu_char data3[50];\n\tu_char dig3[16] = {\n\t 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,\n\t 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 };\n\tmemset(key3, 0xaa, sizeof(key3));\n\tmemset(data3, 0xdd, sizeof(data3));\n\n\thmac_test(key1, sizeof(key1), data1, strlen(data1), dig1, sizeof(dig1));\n\thmac_test(key2, strlen(key2), data2, strlen(data2), dig2, sizeof(dig2));\n\thmac_test(key3, sizeof(key3), data3, sizeof(data3), dig3, sizeof(dig3));\n\n\treturn 0;\n}\n\n#endif\n","/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */\n\n/*\n * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,\n * Peter Schwabe, Bo-Yin Yang.\n * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c\n */\n\n#include \"includes.h\"\n#include \"crypto_api.h\"\n\n#include \"ge25519.h\"\n\nstatic void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen)\n{\n unsigned long long i;\n\n for (i = 0;i < 32;++i) playground[i] = sm[i];\n for (i = 32;i < 64;++i) playground[i] = pk[i-32];\n for (i = 64;i < smlen;++i) playground[i] = sm[i];\n\n crypto_hash_sha512(hram,playground,smlen);\n}\n\n\nint crypto_sign_ed25519_keypair(\n unsigned char *pk,\n unsigned char *sk\n )\n{\n sc25519 scsk;\n ge25519 gepk;\n unsigned char extsk[64];\n int i;\n\n randombytes(sk, 32);\n crypto_hash_sha512(extsk, sk, 32);\n extsk[0] &= 248;\n extsk[31] &= 127;\n extsk[31] |= 64;\n\n sc25519_from32bytes(&scsk,extsk);\n \n ge25519_scalarmult_base(&gepk, &scsk);\n ge25519_pack(pk, &gepk);\n for(i=0;i<32;i++)\n sk[32 + i] = pk[i];\n return 0;\n}\n\nint crypto_sign_ed25519(\n unsigned char *sm,unsigned long long *smlen,\n const unsigned char *m,unsigned long long mlen,\n const unsigned char *sk\n )\n{\n sc25519 sck, scs, scsk;\n ge25519 ger;\n unsigned char r[32];\n unsigned char s[32];\n unsigned char extsk[64];\n unsigned long long i;\n unsigned char hmg[crypto_hash_sha512_BYTES];\n unsigned char hram[crypto_hash_sha512_BYTES];\n\n crypto_hash_sha512(extsk, sk, 32);\n extsk[0] &= 248;\n extsk[31] &= 127;\n extsk[31] |= 64;\n\n *smlen = mlen+64;\n for(i=0;i> 8)) - 1;\n}\n","/* $OpenBSD: hash.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */\n\n/* Copied from nacl-20110221/crypto_hash/sha512/ref/hash.c */\n\n/*\n20080913\nD. J. Bernstein\nPublic domain.\n*/\n\n#include \"includes.h\"\n\n#include \"crypto_api.h\"\n\n#define blocks crypto_hashblocks_sha512\n\nstatic const unsigned char iv[64] = {\n 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,\n 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,\n 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,\n 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,\n 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,\n 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,\n 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,\n 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79\n} ;\n\ntypedef unsigned long long uint64;\n\nint crypto_hash_sha512(unsigned char *out,const unsigned char *in,unsigned long long inlen)\n{\n unsigned char h[64];\n unsigned char padded[256];\n unsigned int i;\n unsigned long long bytes = inlen;\n\n for (i = 0;i < 64;++i) h[i] = iv[i];\n\n blocks(h,in,inlen);\n in += inlen;\n inlen &= 127;\n in -= inlen;\n\n for (i = 0;i < inlen;++i) padded[i] = in[i];\n padded[inlen] = 0x80;\n\n if (inlen < 112) {\n for (i = inlen + 1;i < 119;++i) padded[i] = 0;\n padded[119] = bytes >> 61;\n padded[120] = bytes >> 53;\n padded[121] = bytes >> 45;\n padded[122] = bytes >> 37;\n padded[123] = bytes >> 29;\n padded[124] = bytes >> 21;\n padded[125] = bytes >> 13;\n padded[126] = bytes >> 5;\n padded[127] = bytes << 3;\n blocks(h,padded,128);\n } else {\n for (i = inlen + 1;i < 247;++i) padded[i] = 0;\n padded[247] = bytes >> 61;\n padded[248] = bytes >> 53;\n padded[249] = bytes >> 45;\n padded[250] = bytes >> 37;\n padded[251] = bytes >> 29;\n padded[252] = bytes >> 21;\n padded[253] = bytes >> 13;\n padded[254] = bytes >> 5;\n padded[255] = bytes << 3;\n blocks(h,padded,256);\n }\n\n for (i = 0;i < 64;++i) out[i] = h[i];\n\n return 0;\n}\n","/* $OpenBSD: blocks.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */\n\n/*\n * Public Domain, Author: Daniel J. Bernstein\n * Copied from nacl-20110221/crypto_hashblocks/sha512/ref/blocks.c\n */\n\n#include \"includes.h\"\n\n#include \"crypto_api.h\"\n\ntypedef unsigned long long uint64;\n\nstatic uint64 load_bigendian(const unsigned char *x)\n{\n return\n (uint64) (x[7]) \\\n | (((uint64) (x[6])) << 8) \\\n | (((uint64) (x[5])) << 16) \\\n | (((uint64) (x[4])) << 24) \\\n | (((uint64) (x[3])) << 32) \\\n | (((uint64) (x[2])) << 40) \\\n | (((uint64) (x[1])) << 48) \\\n | (((uint64) (x[0])) << 56)\n ;\n}\n\nstatic void store_bigendian(unsigned char *x,uint64 u)\n{\n x[7] = u; u >>= 8;\n x[6] = u; u >>= 8;\n x[5] = u; u >>= 8;\n x[4] = u; u >>= 8;\n x[3] = u; u >>= 8;\n x[2] = u; u >>= 8;\n x[1] = u; u >>= 8;\n x[0] = u;\n}\n\n#define SHR(x,c) ((x) >> (c))\n#define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c))))\n\n#define Ch(x,y,z) ((x & y) ^ (~x & z))\n#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))\n#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))\n#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))\n#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7))\n#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6))\n\n#define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0;\n\n#define EXPAND \\\n M(w0 ,w14,w9 ,w1 ) \\\n M(w1 ,w15,w10,w2 ) \\\n M(w2 ,w0 ,w11,w3 ) \\\n M(w3 ,w1 ,w12,w4 ) \\\n M(w4 ,w2 ,w13,w5 ) \\\n M(w5 ,w3 ,w14,w6 ) \\\n M(w6 ,w4 ,w15,w7 ) \\\n M(w7 ,w5 ,w0 ,w8 ) \\\n M(w8 ,w6 ,w1 ,w9 ) \\\n M(w9 ,w7 ,w2 ,w10) \\\n M(w10,w8 ,w3 ,w11) \\\n M(w11,w9 ,w4 ,w12) \\\n M(w12,w10,w5 ,w13) \\\n M(w13,w11,w6 ,w14) \\\n M(w14,w12,w7 ,w15) \\\n M(w15,w13,w8 ,w0 )\n\n#define F(w,k) \\\n T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \\\n T2 = Sigma0(a) + Maj(a,b,c); \\\n h = g; \\\n g = f; \\\n f = e; \\\n e = d + T1; \\\n d = c; \\\n c = b; \\\n b = a; \\\n a = T1 + T2;\n\nint crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen)\n{\n uint64 state[8];\n uint64 a;\n uint64 b;\n uint64 c;\n uint64 d;\n uint64 e;\n uint64 f;\n uint64 g;\n uint64 h;\n uint64 T1;\n uint64 T2;\n\n a = load_bigendian(statebytes + 0); state[0] = a;\n b = load_bigendian(statebytes + 8); state[1] = b;\n c = load_bigendian(statebytes + 16); state[2] = c;\n d = load_bigendian(statebytes + 24); state[3] = d;\n e = load_bigendian(statebytes + 32); state[4] = e;\n f = load_bigendian(statebytes + 40); state[5] = f;\n g = load_bigendian(statebytes + 48); state[6] = g;\n h = load_bigendian(statebytes + 56); state[7] = h;\n\n while (inlen >= 128) {\n uint64 w0 = load_bigendian(in + 0);\n uint64 w1 = load_bigendian(in + 8);\n uint64 w2 = load_bigendian(in + 16);\n uint64 w3 = load_bigendian(in + 24);\n uint64 w4 = load_bigendian(in + 32);\n uint64 w5 = load_bigendian(in + 40);\n uint64 w6 = load_bigendian(in + 48);\n uint64 w7 = load_bigendian(in + 56);\n uint64 w8 = load_bigendian(in + 64);\n uint64 w9 = load_bigendian(in + 72);\n uint64 w10 = load_bigendian(in + 80);\n uint64 w11 = load_bigendian(in + 88);\n uint64 w12 = load_bigendian(in + 96);\n uint64 w13 = load_bigendian(in + 104);\n uint64 w14 = load_bigendian(in + 112);\n uint64 w15 = load_bigendian(in + 120);\n\n F(w0 ,0x428a2f98d728ae22ULL)\n F(w1 ,0x7137449123ef65cdULL)\n F(w2 ,0xb5c0fbcfec4d3b2fULL)\n F(w3 ,0xe9b5dba58189dbbcULL)\n F(w4 ,0x3956c25bf348b538ULL)\n F(w5 ,0x59f111f1b605d019ULL)\n F(w6 ,0x923f82a4af194f9bULL)\n F(w7 ,0xab1c5ed5da6d8118ULL)\n F(w8 ,0xd807aa98a3030242ULL)\n F(w9 ,0x12835b0145706fbeULL)\n F(w10,0x243185be4ee4b28cULL)\n F(w11,0x550c7dc3d5ffb4e2ULL)\n F(w12,0x72be5d74f27b896fULL)\n F(w13,0x80deb1fe3b1696b1ULL)\n F(w14,0x9bdc06a725c71235ULL)\n F(w15,0xc19bf174cf692694ULL)\n\n EXPAND\n\n F(w0 ,0xe49b69c19ef14ad2ULL)\n F(w1 ,0xefbe4786384f25e3ULL)\n F(w2 ,0x0fc19dc68b8cd5b5ULL)\n F(w3 ,0x240ca1cc77ac9c65ULL)\n F(w4 ,0x2de92c6f592b0275ULL)\n F(w5 ,0x4a7484aa6ea6e483ULL)\n F(w6 ,0x5cb0a9dcbd41fbd4ULL)\n F(w7 ,0x76f988da831153b5ULL)\n F(w8 ,0x983e5152ee66dfabULL)\n F(w9 ,0xa831c66d2db43210ULL)\n F(w10,0xb00327c898fb213fULL)\n F(w11,0xbf597fc7beef0ee4ULL)\n F(w12,0xc6e00bf33da88fc2ULL)\n F(w13,0xd5a79147930aa725ULL)\n F(w14,0x06ca6351e003826fULL)\n F(w15,0x142929670a0e6e70ULL)\n\n EXPAND\n\n F(w0 ,0x27b70a8546d22ffcULL)\n F(w1 ,0x2e1b21385c26c926ULL)\n F(w2 ,0x4d2c6dfc5ac42aedULL)\n F(w3 ,0x53380d139d95b3dfULL)\n F(w4 ,0x650a73548baf63deULL)\n F(w5 ,0x766a0abb3c77b2a8ULL)\n F(w6 ,0x81c2c92e47edaee6ULL)\n F(w7 ,0x92722c851482353bULL)\n F(w8 ,0xa2bfe8a14cf10364ULL)\n F(w9 ,0xa81a664bbc423001ULL)\n F(w10,0xc24b8b70d0f89791ULL)\n F(w11,0xc76c51a30654be30ULL)\n F(w12,0xd192e819d6ef5218ULL)\n F(w13,0xd69906245565a910ULL)\n F(w14,0xf40e35855771202aULL)\n F(w15,0x106aa07032bbd1b8ULL)\n\n EXPAND\n\n F(w0 ,0x19a4c116b8d2d0c8ULL)\n F(w1 ,0x1e376c085141ab53ULL)\n F(w2 ,0x2748774cdf8eeb99ULL)\n F(w3 ,0x34b0bcb5e19b48a8ULL)\n F(w4 ,0x391c0cb3c5c95a63ULL)\n F(w5 ,0x4ed8aa4ae3418acbULL)\n F(w6 ,0x5b9cca4f7763e373ULL)\n F(w7 ,0x682e6ff3d6b2b8a3ULL)\n F(w8 ,0x748f82ee5defb2fcULL)\n F(w9 ,0x78a5636f43172f60ULL)\n F(w10,0x84c87814a1f0ab72ULL)\n F(w11,0x8cc702081a6439ecULL)\n F(w12,0x90befffa23631e28ULL)\n F(w13,0xa4506cebde82bde9ULL)\n F(w14,0xbef9a3f7b2c67915ULL)\n F(w15,0xc67178f2e372532bULL)\n\n EXPAND\n\n F(w0 ,0xca273eceea26619cULL)\n F(w1 ,0xd186b8c721c0c207ULL)\n F(w2 ,0xeada7dd6cde0eb1eULL)\n F(w3 ,0xf57d4f7fee6ed178ULL)\n F(w4 ,0x06f067aa72176fbaULL)\n F(w5 ,0x0a637dc5a2c898a6ULL)\n F(w6 ,0x113f9804bef90daeULL)\n F(w7 ,0x1b710b35131c471bULL)\n F(w8 ,0x28db77f523047d84ULL)\n F(w9 ,0x32caab7b40c72493ULL)\n F(w10,0x3c9ebe0a15c9bebcULL)\n F(w11,0x431d67c49c100d4cULL)\n F(w12,0x4cc5d4becb3e42b6ULL)\n F(w13,0x597f299cfc657e2aULL)\n F(w14,0x5fcb6fab3ad6faecULL)\n F(w15,0x6c44198c4a475817ULL)\n\n a += state[0];\n b += state[1];\n c += state[2];\n d += state[3];\n e += state[4];\n f += state[5];\n g += state[6];\n h += state[7];\n \n state[0] = a;\n state[1] = b;\n state[2] = c;\n state[3] = d;\n state[4] = e;\n state[5] = f;\n state[6] = g;\n state[7] = h;\n\n in += 128;\n inlen -= 128;\n }\n\n store_bigendian(statebytes + 0,state[0]);\n store_bigendian(statebytes + 8,state[1]);\n store_bigendian(statebytes + 16,state[2]);\n store_bigendian(statebytes + 24,state[3]);\n store_bigendian(statebytes + 32,state[4]);\n store_bigendian(statebytes + 40,state[5]);\n store_bigendian(statebytes + 48,state[6]);\n store_bigendian(statebytes + 56,state[7]);\n\n return inlen;\n}\n","/* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 markus Exp $ */\n/*\n * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n\n#include \n#include \n#include \n#include \n#include \n\n#ifdef WITH_OPENSSL\n#include \n#include \n#endif\n\n#include \"ssh2.h\"\n#include \"packet.h\"\n#include \"compat.h\"\n#include \"cipher.h\"\n#include \"sshkey.h\"\n#include \"kex.h\"\n#include \"log.h\"\n#include \"mac.h\"\n#include \"match.h\"\n#include \"misc.h\"\n#include \"dispatch.h\"\n#include \"monitor.h\"\n\n#include \"ssherr.h\"\n#include \"sshbuf.h\"\n#include \"digest.h\"\n\n#if OPENSSL_VERSION_NUMBER >= 0x00907000L\n# if defined(HAVE_EVP_SHA256)\n# define evp_ssh_sha256 EVP_sha256\n# else\nextern const EVP_MD *evp_ssh_sha256(void);\n# endif\n#endif\n\n/* prototype */\nstatic int kex_choose_conf(struct ssh *);\nstatic int kex_input_newkeys(int, u_int32_t, void *);\n\nstatic const char *proposal_names[PROPOSAL_MAX] = {\n\t\"KEX algorithms\",\n\t\"host key algorithms\",\n\t\"ciphers ctos\",\n\t\"ciphers stoc\",\n\t\"MACs ctos\",\n\t\"MACs stoc\",\n\t\"compression ctos\",\n\t\"compression stoc\",\n\t\"languages ctos\",\n\t\"languages stoc\",\n};\n\nstruct kexalg {\n\tchar *name;\n\tu_int type;\n\tint ec_nid;\n\tint hash_alg;\n};\nstatic const struct kexalg kexalgs[] = {\n#ifdef WITH_OPENSSL\n\t{ KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },\n\t{ KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },\n\t{ KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 },\n\t{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },\n\t{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },\n\t{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },\n#ifdef HAVE_EVP_SHA256\n\t{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },\n#endif /* HAVE_EVP_SHA256 */\n#ifdef OPENSSL_HAS_ECC\n\t{ KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,\n\t NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },\n\t{ KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,\n\t SSH_DIGEST_SHA384 },\n# ifdef OPENSSL_HAS_NISTP521\n\t{ KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,\n\t SSH_DIGEST_SHA512 },\n# endif /* OPENSSL_HAS_NISTP521 */\n#endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n#if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)\n\t{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },\n\t{ KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },\n#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */\n\t{ NULL, -1, -1, -1},\n};\n\nchar *\nkex_alg_list(char sep)\n{\n\tchar *ret = NULL, *tmp;\n\tsize_t nlen, rlen = 0;\n\tconst struct kexalg *k;\n\n\tfor (k = kexalgs; k->name != NULL; k++) {\n\t\tif (ret != NULL)\n\t\t\tret[rlen++] = sep;\n\t\tnlen = strlen(k->name);\n\t\tif ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {\n\t\t\tfree(ret);\n\t\t\treturn NULL;\n\t\t}\n\t\tret = tmp;\n\t\tmemcpy(ret + rlen, k->name, nlen + 1);\n\t\trlen += nlen;\n\t}\n\treturn ret;\n}\n\nstatic const struct kexalg *\nkex_alg_by_name(const char *name)\n{\n\tconst struct kexalg *k;\n\n\tfor (k = kexalgs; k->name != NULL; k++) {\n\t\tif (strcmp(k->name, name) == 0)\n\t\t\treturn k;\n\t}\n\treturn NULL;\n}\n\n/* Validate KEX method name list */\nint\nkex_names_valid(const char *names)\n{\n\tchar *s, *cp, *p;\n\n\tif (names == NULL || strcmp(names, \"\") == 0)\n\t\treturn 0;\n\tif ((s = cp = strdup(names)) == NULL)\n\t\treturn 0;\n\tfor ((p = strsep(&cp, \",\")); p && *p != '\\0';\n\t (p = strsep(&cp, \",\"))) {\n\t\tif (kex_alg_by_name(p) == NULL) {\n\t\t\terror(\"Unsupported KEX algorithm \\\"%.100s\\\"\", p);\n\t\t\tfree(s);\n\t\t\treturn 0;\n\t\t}\n\t}\n\tdebug3(\"kex names ok: [%s]\", names);\n\tfree(s);\n\treturn 1;\n}\n\n/*\n * Concatenate algorithm names, avoiding duplicates in the process.\n * Caller must free returned string.\n */\nchar *\nkex_names_cat(const char *a, const char *b)\n{\n\tchar *ret = NULL, *tmp = NULL, *cp, *p, *m;\n\tsize_t len;\n\n\tif (a == NULL || *a == '\\0')\n\t\treturn NULL;\n\tif (b == NULL || *b == '\\0')\n\t\treturn strdup(a);\n\tif (strlen(b) > 1024*1024)\n\t\treturn NULL;\n\tlen = strlen(a) + strlen(b) + 2;\n\tif ((tmp = cp = strdup(b)) == NULL ||\n\t (ret = calloc(1, len)) == NULL) {\n\t\tfree(tmp);\n\t\treturn NULL;\n\t}\n\tstrlcpy(ret, a, len);\n\tfor ((p = strsep(&cp, \",\")); p && *p != '\\0'; (p = strsep(&cp, \",\"))) {\n\t\tif ((m = match_list(ret, p, NULL)) != NULL) {\n\t\t\tfree(m);\n\t\t\tcontinue; /* Algorithm already present */\n\t\t}\n\t\tif (strlcat(ret, \",\", len) >= len ||\n\t\t strlcat(ret, p, len) >= len) {\n\t\t\tfree(tmp);\n\t\t\tfree(ret);\n\t\t\treturn NULL; /* Shouldn't happen */\n\t\t}\n\t}\n\tfree(tmp);\n\treturn ret;\n}\n\n/*\n * Assemble a list of algorithms from a default list and a string from a\n * configuration file. The user-provided string may begin with '+' to\n * indicate that it should be appended to the default or '-' that the\n * specified names should be removed.\n */\nint\nkex_assemble_names(const char *def, char **list)\n{\n\tchar *ret;\n\n\tif (list == NULL || *list == NULL || **list == '\\0') {\n\t\t*list = strdup(def);\n\t\treturn 0;\n\t}\n\tif (**list == '+') {\n\t\tif ((ret = kex_names_cat(def, *list + 1)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tfree(*list);\n\t\t*list = ret;\n\t} else if (**list == '-') {\n\t\tif ((ret = match_filter_list(def, *list + 1)) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tfree(*list);\n\t\t*list = ret;\n\t}\n\n\treturn 0;\n}\n\n/* put algorithm proposal into buffer */\nint\nkex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])\n{\n\tu_int i;\n\tint r;\n\n\tsshbuf_reset(b);\n\n\t/*\n\t * add a dummy cookie, the cookie will be overwritten by\n\t * kex_send_kexinit(), each time a kexinit is set\n\t */\n\tfor (i = 0; i < KEX_COOKIE_LEN; i++) {\n\t\tif ((r = sshbuf_put_u8(b, 0)) != 0)\n\t\t\treturn r;\n\t}\n\tfor (i = 0; i < PROPOSAL_MAX; i++) {\n\t\tif ((r = sshbuf_put_cstring(b, proposal[i])) != 0)\n\t\t\treturn r;\n\t}\n\tif ((r = sshbuf_put_u8(b, 0)) != 0 ||\t/* first_kex_packet_follows */\n\t (r = sshbuf_put_u32(b, 0)) != 0)\t/* uint32 reserved */\n\t\treturn r;\n\treturn 0;\n}\n\n/* parse buffer and return algorithm proposal */\nint\nkex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)\n{\n\tstruct sshbuf *b = NULL;\n\tu_char v;\n\tu_int i;\n\tchar **proposal = NULL;\n\tint r;\n\n\t*propp = NULL;\n\tif ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((b = sshbuf_fromb(raw)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */\n\t\tgoto out;\n\t/* extract kex init proposal strings */\n\tfor (i = 0; i < PROPOSAL_MAX; i++) {\n\t\tif ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)\n\t\t\tgoto out;\n\t\tdebug2(\"%s: %s\", proposal_names[i], proposal[i]);\n\t}\n\t/* first kex follows / reserved */\n\tif ((r = sshbuf_get_u8(b, &v)) != 0 ||\t/* first_kex_follows */\n\t (r = sshbuf_get_u32(b, &i)) != 0)\t/* reserved */\n\t\tgoto out;\n\tif (first_kex_follows != NULL)\n\t\t*first_kex_follows = v;\n\tdebug2(\"first_kex_follows %d \", v);\n\tdebug2(\"reserved %u \", i);\n\tr = 0;\n\t*propp = proposal;\n out:\n\tif (r != 0 && proposal != NULL)\n\t\tkex_prop_free(proposal);\n\tsshbuf_free(b);\n\treturn r;\n}\n\nvoid\nkex_prop_free(char **proposal)\n{\n\tu_int i;\n\n\tif (proposal == NULL)\n\t\treturn;\n\tfor (i = 0; i < PROPOSAL_MAX; i++)\n\t\tfree(proposal[i]);\n\tfree(proposal);\n}\n\n/* ARGSUSED */\nstatic int\nkex_protocol_error(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct ssh *ssh = active_state; /* XXX */\n\tint r;\n\n\terror(\"kex protocol error: type %d seq %u\", type, seq);\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||\n\t (r = sshpkt_put_u32(ssh, seq)) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0)\n\t\treturn r;\n\treturn 0;\n}\n\nstatic void\nkex_reset_dispatch(struct ssh *ssh)\n{\n\tssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,\n\t SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);\n}\n\nstatic int\nkex_send_ext_info(struct ssh *ssh)\n{\n\tint r;\n\tchar *algs;\n\n\tif ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||\n\t (r = sshpkt_put_u32(ssh, 1)) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, \"server-sig-algs\")) != 0 ||\n\t (r = sshpkt_put_cstring(ssh, algs)) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0)\n\t\tgoto out;\n\t/* success */\n\tr = 0;\n out:\n\tfree(algs);\n\treturn r;\n}\n\nint\nkex_send_newkeys(struct ssh *ssh)\n{\n\tint r;\n\n\tkex_reset_dispatch(ssh);\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0)\n\t\treturn r;\n\tdebug(\"SSH2_MSG_NEWKEYS sent\");\n\tdebug(\"expecting SSH2_MSG_NEWKEYS\");\n\tssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);\n\tif (ssh->kex->ext_info_c)\n\t\tif ((r = kex_send_ext_info(ssh)) != 0)\n\t\t\treturn r;\n\treturn 0;\n}\n\nint\nkex_input_ext_info(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct ssh *ssh = ctxt;\n\tstruct kex *kex = ssh->kex;\n\tu_int32_t i, ninfo;\n\tchar *name, *val, *found;\n\tint r;\n\n\tdebug(\"SSH2_MSG_EXT_INFO received\");\n\tssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);\n\tif ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)\n\t\treturn r;\n\tfor (i = 0; i < ninfo; i++) {\n\t\tif ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)\n\t\t\treturn r;\n\t\tif ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) {\n\t\t\tfree(name);\n\t\t\treturn r;\n\t\t}\n\t\tdebug(\"%s: %s=<%s>\", __func__, name, val);\n\t\tif (strcmp(name, \"server-sig-algs\") == 0) {\n\t\t\tfound = match_list(\"rsa-sha2-256\", val, NULL);\n\t\t\tif (found) {\n\t\t\t\tkex->rsa_sha2 = 256;\n\t\t\t\tfree(found);\n\t\t\t}\n\t\t\tfound = match_list(\"rsa-sha2-512\", val, NULL);\n\t\t\tif (found) {\n\t\t\t\tkex->rsa_sha2 = 512;\n\t\t\t\tfree(found);\n\t\t\t}\n\t\t}\n\t\tfree(name);\n\t\tfree(val);\n\t}\n\treturn sshpkt_get_end(ssh);\n}\n\nstatic int\nkex_input_newkeys(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct ssh *ssh = ctxt;\n\tstruct kex *kex = ssh->kex;\n\tint r;\n\n\tdebug(\"SSH2_MSG_NEWKEYS received\");\n\tssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);\n\tssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);\n\tif ((r = sshpkt_get_end(ssh)) != 0)\n\t\treturn r;\n\tif ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0)\n\t\treturn r;\n\tkex->done = 1;\n\tsshbuf_reset(kex->peer);\n\t/* sshbuf_reset(kex->my); */\n\tkex->flags &= ~KEX_INIT_SENT;\n\tfree(kex->name);\n\tkex->name = NULL;\n\treturn 0;\n}\n\nint\nkex_send_kexinit(struct ssh *ssh)\n{\n\tu_char *cookie;\n\tstruct kex *kex = ssh->kex;\n\tint r;\n\n\tif (kex == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tif (kex->flags & KEX_INIT_SENT)\n\t\treturn 0;\n\tkex->done = 0;\n\n\t/* generate a random cookie */\n\tif (sshbuf_len(kex->my) < KEX_COOKIE_LEN)\n\t\treturn SSH_ERR_INVALID_FORMAT;\n\tif ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tarc4random_buf(cookie, KEX_COOKIE_LEN);\n\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||\n\t (r = sshpkt_putb(ssh, kex->my)) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0)\n\t\treturn r;\n\tdebug(\"SSH2_MSG_KEXINIT sent\");\n\tkex->flags |= KEX_INIT_SENT;\n\treturn 0;\n}\n\n/* ARGSUSED */\nint\nkex_input_kexinit(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct ssh *ssh = ctxt;\n\tstruct kex *kex = ssh->kex;\n\tconst u_char *ptr;\n\tu_int i;\n\tsize_t dlen;\n\tint r;\n\n\tdebug(\"SSH2_MSG_KEXINIT received\");\n\tif (kex == NULL)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\n\tssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);\n\tptr = sshpkt_ptr(ssh, &dlen);\n\tif ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)\n\t\treturn r;\n\n\t/* discard packet */\n\tfor (i = 0; i < KEX_COOKIE_LEN; i++)\n\t\tif ((r = sshpkt_get_u8(ssh, NULL)) != 0)\n\t\t\treturn r;\n\tfor (i = 0; i < PROPOSAL_MAX; i++)\n\t\tif ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)\n\t\t\treturn r;\n\t/*\n\t * XXX RFC4253 sec 7: \"each side MAY guess\" - currently no supported\n\t * KEX method has the server move first, but a server might be using\n\t * a custom method or one that we otherwise don't support. We should\n\t * be prepared to remember first_kex_follows here so we can eat a\n\t * packet later.\n\t * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means\n\t * for cases where the server *doesn't* go first. I guess we should\n\t * ignore it when it is set for these cases, which is what we do now.\n\t */\n\tif ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||\t/* first_kex_follows */\n\t (r = sshpkt_get_u32(ssh, NULL)) != 0 ||\t/* reserved */\n\t (r = sshpkt_get_end(ssh)) != 0)\n\t\t\treturn r;\n\n\tif (!(kex->flags & KEX_INIT_SENT))\n\t\tif ((r = kex_send_kexinit(ssh)) != 0)\n\t\t\treturn r;\n\tif ((r = kex_choose_conf(ssh)) != 0)\n\t\treturn r;\n\n\tif (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)\n\t\treturn (kex->kex[kex->kex_type])(ssh);\n\n\treturn SSH_ERR_INTERNAL_ERROR;\n}\n\nint\nkex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp)\n{\n\tstruct kex *kex;\n\tint r;\n\n\t*kexp = NULL;\n\tif ((kex = calloc(1, sizeof(*kex))) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((kex->peer = sshbuf_new()) == NULL ||\n\t (kex->my = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = kex_prop2buf(kex->my, proposal)) != 0)\n\t\tgoto out;\n\tkex->done = 0;\n\tkex_reset_dispatch(ssh);\n\tssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);\n\tr = 0;\n\t*kexp = kex;\n out:\n\tif (r != 0)\n\t\tkex_free(kex);\n\treturn r;\n}\n\nvoid\nkex_free_newkeys(struct newkeys *newkeys)\n{\n\tif (newkeys == NULL)\n\t\treturn;\n\tif (newkeys->enc.key) {\n\t\texplicit_bzero(newkeys->enc.key, newkeys->enc.key_len);\n\t\tfree(newkeys->enc.key);\n\t\tnewkeys->enc.key = NULL;\n\t}\n\tif (newkeys->enc.iv) {\n\t\texplicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len);\n\t\tfree(newkeys->enc.iv);\n\t\tnewkeys->enc.iv = NULL;\n\t}\n\tfree(newkeys->enc.name);\n\texplicit_bzero(&newkeys->enc, sizeof(newkeys->enc));\n\tfree(newkeys->comp.name);\n\texplicit_bzero(&newkeys->comp, sizeof(newkeys->comp));\n\tmac_clear(&newkeys->mac);\n\tif (newkeys->mac.key) {\n\t\texplicit_bzero(newkeys->mac.key, newkeys->mac.key_len);\n\t\tfree(newkeys->mac.key);\n\t\tnewkeys->mac.key = NULL;\n\t}\n\tfree(newkeys->mac.name);\n\texplicit_bzero(&newkeys->mac, sizeof(newkeys->mac));\n\texplicit_bzero(newkeys, sizeof(*newkeys));\n\tfree(newkeys);\n}\n\nvoid\nkex_free(struct kex *kex)\n{\n\tu_int mode;\n\n#ifdef WITH_OPENSSL\n\tif (kex->dh)\n\t\tDH_free(kex->dh);\n#ifdef OPENSSL_HAS_ECC\n\tif (kex->ec_client_key)\n\t\tEC_KEY_free(kex->ec_client_key);\n#endif /* OPENSSL_HAS_ECC */\n#endif /* WITH_OPENSSL */\n\tfor (mode = 0; mode < MODE_MAX; mode++) {\n\t\tkex_free_newkeys(kex->newkeys[mode]);\n\t\tkex->newkeys[mode] = NULL;\n\t}\n\tsshbuf_free(kex->peer);\n\tsshbuf_free(kex->my);\n\tfree(kex->session_id);\n\tfree(kex->client_version_string);\n\tfree(kex->server_version_string);\n\tfree(kex->failed_choice);\n\tfree(kex->hostkey_alg);\n\tfree(kex->name);\n\tfree(kex);\n}\n\nint\nkex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])\n{\n\tint r;\n\n\tif ((r = kex_new(ssh, proposal, &ssh->kex)) != 0)\n\t\treturn r;\n\tif ((r = kex_send_kexinit(ssh)) != 0) {\t\t/* we start */\n\t\tkex_free(ssh->kex);\n\t\tssh->kex = NULL;\n\t\treturn r;\n\t}\n\treturn 0;\n}\n\n/*\n * Request key re-exchange, returns 0 on success or a ssherr.h error\n * code otherwise. Must not be called if KEX is incomplete or in-progress.\n */\nint\nkex_start_rekex(struct ssh *ssh)\n{\n\tif (ssh->kex == NULL) {\n\t\terror(\"%s: no kex\", __func__);\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\tif (ssh->kex->done == 0) {\n\t\terror(\"%s: requested twice\", __func__);\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\tssh->kex->done = 0;\n\treturn kex_send_kexinit(ssh);\n}\n\nstatic int\nchoose_enc(struct sshenc *enc, char *client, char *server)\n{\n\tchar *name = match_list(client, server, NULL);\n\n\tif (name == NULL)\n\t\treturn SSH_ERR_NO_CIPHER_ALG_MATCH;\n\tif ((enc->cipher = cipher_by_name(name)) == NULL) {\n\t\tfree(name);\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\tenc->name = name;\n\tenc->enabled = 0;\n\tenc->iv = NULL;\n\tenc->iv_len = cipher_ivlen(enc->cipher);\n\tenc->key = NULL;\n\tenc->key_len = cipher_keylen(enc->cipher);\n\tenc->block_size = cipher_blocksize(enc->cipher);\n\treturn 0;\n}\n\nstatic int\nchoose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)\n{\n\tchar *name = match_list(client, server, NULL);\n\n\tif (name == NULL)\n\t\treturn SSH_ERR_NO_MAC_ALG_MATCH;\n\tif (mac_setup(mac, name) < 0) {\n\t\tfree(name);\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\t/* truncate the key */\n\tif (ssh->compat & SSH_BUG_HMAC)\n\t\tmac->key_len = 16;\n\tmac->name = name;\n\tmac->key = NULL;\n\tmac->enabled = 0;\n\treturn 0;\n}\n\nstatic int\nchoose_comp(struct sshcomp *comp, char *client, char *server)\n{\n\tchar *name = match_list(client, server, NULL);\n\n\tif (name == NULL)\n\t\treturn SSH_ERR_NO_COMPRESS_ALG_MATCH;\n\tif (strcmp(name, \"zlib@openssh.com\") == 0) {\n\t\tcomp->type = COMP_DELAYED;\n\t} else if (strcmp(name, \"zlib\") == 0) {\n\t\tcomp->type = COMP_ZLIB;\n\t} else if (strcmp(name, \"none\") == 0) {\n\t\tcomp->type = COMP_NONE;\n\t} else {\n\t\tfree(name);\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\tcomp->name = name;\n\treturn 0;\n}\n\nstatic int\nchoose_kex(struct kex *k, char *client, char *server)\n{\n\tconst struct kexalg *kexalg;\n\n\tk->name = match_list(client, server, NULL);\n\n\tdebug(\"kex: algorithm: %s\", k->name ? k->name : \"(no match)\");\n\tif (k->name == NULL)\n\t\treturn SSH_ERR_NO_KEX_ALG_MATCH;\n\tif ((kexalg = kex_alg_by_name(k->name)) == NULL)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tk->kex_type = kexalg->type;\n\tk->hash_alg = kexalg->hash_alg;\n\tk->ec_nid = kexalg->ec_nid;\n\treturn 0;\n}\n\nstatic int\nchoose_hostkeyalg(struct kex *k, char *client, char *server)\n{\n\tk->hostkey_alg = match_list(client, server, NULL);\n\n\tdebug(\"kex: host key algorithm: %s\",\n\t k->hostkey_alg ? k->hostkey_alg : \"(no match)\");\n\tif (k->hostkey_alg == NULL)\n\t\treturn SSH_ERR_NO_HOSTKEY_ALG_MATCH;\n\tk->hostkey_type = sshkey_type_from_name(k->hostkey_alg);\n\tif (k->hostkey_type == KEY_UNSPEC)\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\tk->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);\n\treturn 0;\n}\n\nstatic int\nproposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])\n{\n\tstatic int check[] = {\n\t\tPROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1\n\t};\n\tint *idx;\n\tchar *p;\n\n\tfor (idx = &check[0]; *idx != -1; idx++) {\n\t\tif ((p = strchr(my[*idx], ',')) != NULL)\n\t\t\t*p = '\\0';\n\t\tif ((p = strchr(peer[*idx], ',')) != NULL)\n\t\t\t*p = '\\0';\n\t\tif (strcmp(my[*idx], peer[*idx]) != 0) {\n\t\t\tdebug2(\"proposal mismatch: my %s peer %s\",\n\t\t\t my[*idx], peer[*idx]);\n\t\t\treturn (0);\n\t\t}\n\t}\n\tdebug2(\"proposals match\");\n\treturn (1);\n}\n\nstatic int\nkex_choose_conf(struct ssh *ssh)\n{\n\tstruct kex *kex = ssh->kex;\n\tstruct newkeys *newkeys;\n\tchar **my = NULL, **peer = NULL;\n\tchar **cprop, **sprop;\n\tint nenc, nmac, ncomp;\n\tu_int mode, ctos, need, dh_need, authlen;\n\tint r, first_kex_follows;\n\n\tdebug2(\"local %s KEXINIT proposal\", kex->server ? \"server\" : \"client\");\n\tif ((r = kex_buf2prop(kex->my, NULL, &my)) != 0)\n\t\tgoto out;\n\tdebug2(\"peer %s KEXINIT proposal\", kex->server ? \"client\" : \"server\");\n\tif ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)\n\t\tgoto out;\n\n\tif (kex->server) {\n\t\tcprop=peer;\n\t\tsprop=my;\n\t} else {\n\t\tcprop=my;\n\t\tsprop=peer;\n\t}\n\n\t/* Check whether client supports ext_info_c */\n\tif (kex->server) {\n\t\tchar *ext;\n\n\t\text = match_list(\"ext-info-c\", peer[PROPOSAL_KEX_ALGS], NULL);\n\t\tkex->ext_info_c = (ext != NULL);\n\t\tfree(ext);\n\t}\n\n\t/* Algorithm Negotiation */\n\tif ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],\n\t sprop[PROPOSAL_KEX_ALGS])) != 0) {\n\t\tkex->failed_choice = peer[PROPOSAL_KEX_ALGS];\n\t\tpeer[PROPOSAL_KEX_ALGS] = NULL;\n\t\tgoto out;\n\t}\n\tif ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],\n\t sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) {\n\t\tkex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS];\n\t\tpeer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL;\n\t\tgoto out;\n\t}\n\tfor (mode = 0; mode < MODE_MAX; mode++) {\n\t\tif ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tkex->newkeys[mode] = newkeys;\n\t\tctos = (!kex->server && mode == MODE_OUT) ||\n\t\t (kex->server && mode == MODE_IN);\n\t\tnenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;\n\t\tnmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;\n\t\tncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;\n\t\tif ((r = choose_enc(&newkeys->enc, cprop[nenc],\n\t\t sprop[nenc])) != 0) {\n\t\t\tkex->failed_choice = peer[nenc];\n\t\t\tpeer[nenc] = NULL;\n\t\t\tgoto out;\n\t\t}\n\t\tauthlen = cipher_authlen(newkeys->enc.cipher);\n\t\t/* ignore mac for authenticated encryption */\n\t\tif (authlen == 0 &&\n\t\t (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],\n\t\t sprop[nmac])) != 0) {\n\t\t\tkex->failed_choice = peer[nmac];\n\t\t\tpeer[nmac] = NULL;\n\t\t\tgoto out;\n\t\t}\n\t\tif ((r = choose_comp(&newkeys->comp, cprop[ncomp],\n\t\t sprop[ncomp])) != 0) {\n\t\t\tkex->failed_choice = peer[ncomp];\n\t\t\tpeer[ncomp] = NULL;\n\t\t\tgoto out;\n\t\t}\n\t\tdebug(\"kex: %s cipher: %s MAC: %s compression: %s\",\n\t\t ctos ? \"client->server\" : \"server->client\",\n\t\t newkeys->enc.name,\n\t\t authlen == 0 ? newkeys->mac.name : \"\",\n\t\t newkeys->comp.name);\n\t}\n\tneed = dh_need = 0;\n\tfor (mode = 0; mode < MODE_MAX; mode++) {\n\t\tnewkeys = kex->newkeys[mode];\n\t\tneed = MAXIMUM(need, newkeys->enc.key_len);\n\t\tneed = MAXIMUM(need, newkeys->enc.block_size);\n\t\tneed = MAXIMUM(need, newkeys->enc.iv_len);\n\t\tneed = MAXIMUM(need, newkeys->mac.key_len);\n\t\tdh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher));\n\t\tdh_need = MAXIMUM(dh_need, newkeys->enc.block_size);\n\t\tdh_need = MAXIMUM(dh_need, newkeys->enc.iv_len);\n\t\tdh_need = MAXIMUM(dh_need, newkeys->mac.key_len);\n\t}\n\t/* XXX need runden? */\n\tkex->we_need = need;\n\tkex->dh_need = dh_need;\n\n\t/* ignore the next message if the proposals do not match */\n\tif (first_kex_follows && !proposals_match(my, peer) &&\n\t !(ssh->compat & SSH_BUG_FIRSTKEX))\n\t\tssh->dispatch_skip_packets = 1;\n\tr = 0;\n out:\n\tkex_prop_free(my);\n\tkex_prop_free(peer);\n\treturn r;\n}\n\nstatic int\nderive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,\n const struct sshbuf *shared_secret, u_char **keyp)\n{\n\tstruct kex *kex = ssh->kex;\n\tstruct ssh_digest_ctx *hashctx = NULL;\n\tchar c = id;\n\tu_int have;\n\tsize_t mdsz;\n\tu_char *digest;\n\tint r;\n\n\tif ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif ((digest = calloc(1, ROUNDUP(need, mdsz))) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\n\t/* K1 = HASH(K || H || \"A\" || session_id) */\n\tif ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||\n\t ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||\n\t ssh_digest_update(hashctx, hash, hashlen) != 0 ||\n\t ssh_digest_update(hashctx, &c, 1) != 0 ||\n\t ssh_digest_update(hashctx, kex->session_id,\n\t kex->session_id_len) != 0 ||\n\t ssh_digest_final(hashctx, digest, mdsz) != 0) {\n\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tssh_digest_free(hashctx);\n\thashctx = NULL;\n\n\t/*\n\t * expand key:\n\t * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)\n\t * Key = K1 || K2 || ... || Kn\n\t */\n\tfor (have = mdsz; need > have; have += mdsz) {\n\t\tif ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||\n\t\t ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||\n\t\t ssh_digest_update(hashctx, hash, hashlen) != 0 ||\n\t\t ssh_digest_update(hashctx, digest, have) != 0 ||\n\t\t ssh_digest_final(hashctx, digest + have, mdsz) != 0) {\n\t\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tssh_digest_free(hashctx);\n\t\thashctx = NULL;\n\t}\n#ifdef DEBUG_KEX\n\tfprintf(stderr, \"key '%c'== \", c);\n\tdump_digest(\"key\", digest, need);\n#endif\n\t*keyp = digest;\n\tdigest = NULL;\n\tr = 0;\n out:\n\tfree(digest);\n\tssh_digest_free(hashctx);\n\treturn r;\n}\n\n#define NKEYS\t6\nint\nkex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,\n const struct sshbuf *shared_secret)\n{\n\tstruct kex *kex = ssh->kex;\n\tu_char *keys[NKEYS];\n\tu_int i, j, mode, ctos;\n\tint r;\n\n\tfor (i = 0; i < NKEYS; i++) {\n\t\tif ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,\n\t\t shared_secret, &keys[i])) != 0) {\n\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\tfree(keys[j]);\n\t\t\treturn r;\n\t\t}\n\t}\n\tfor (mode = 0; mode < MODE_MAX; mode++) {\n\t\tctos = (!kex->server && mode == MODE_OUT) ||\n\t\t (kex->server && mode == MODE_IN);\n\t\tkex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1];\n\t\tkex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];\n\t\tkex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];\n\t}\n\treturn 0;\n}\n\n#ifdef WITH_OPENSSL\nint\nkex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,\n const BIGNUM *secret)\n{\n\tstruct sshbuf *shared_secret;\n\tint r;\n\n\tif ((shared_secret = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)\n\t\tr = kex_derive_keys(ssh, hash, hashlen, shared_secret);\n\tsshbuf_free(shared_secret);\n\treturn r;\n}\n#endif\n\n#ifdef WITH_SSH1\nint\nderive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,\n u_int8_t cookie[8], u_int8_t id[16])\n{\n\tu_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];\n\tstruct ssh_digest_ctx *hashctx = NULL;\n\tsize_t hlen, slen;\n\tint r;\n\n\thlen = BN_num_bytes(host_modulus);\n\tslen = BN_num_bytes(server_modulus);\n\tif (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||\n\t slen < (512 / 8) || (u_int)slen > sizeof(sbuf))\n\t\treturn SSH_ERR_KEY_BITS_MISMATCH;\n\tif (BN_bn2bin(host_modulus, hbuf) <= 0 ||\n\t BN_bn2bin(server_modulus, sbuf) <= 0) {\n\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tif ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||\n\t ssh_digest_update(hashctx, sbuf, slen) != 0 ||\n\t ssh_digest_update(hashctx, cookie, 8) != 0 ||\n\t ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {\n\t\tr = SSH_ERR_LIBCRYPTO_ERROR;\n\t\tgoto out;\n\t}\n\tmemcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));\n\tr = 0;\n out:\n\tssh_digest_free(hashctx);\n\texplicit_bzero(hbuf, sizeof(hbuf));\n\texplicit_bzero(sbuf, sizeof(sbuf));\n\texplicit_bzero(obuf, sizeof(obuf));\n\treturn r;\n}\n#endif\n\n#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)\nvoid\ndump_digest(char *msg, u_char *digest, int len)\n{\n\tfprintf(stderr, \"%s\\n\", msg);\n\tsshbuf_dump_data(digest, len, stderr);\n}\n#endif\n","/* $OpenBSD: kexc25519c.c,v 1.7 2015/01/26 06:10:03 djm Exp $ */\n/*\n * Copyright (c) 2001 Markus Friedl. All rights reserved.\n * Copyright (c) 2010 Damien Miller. All rights reserved.\n * Copyright (c) 2013 Aris Adamantiadis. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n#include \n\n#include \"sshkey.h\"\n#include \"cipher.h\"\n#include \"kex.h\"\n#include \"log.h\"\n#include \"packet.h\"\n#include \"ssh2.h\"\n#include \"sshbuf.h\"\n#include \"digest.h\"\n#include \"ssherr.h\"\n\nstatic int\ninput_kex_c25519_reply(int type, u_int32_t seq, void *ctxt);\n\nint\nkexc25519_client(struct ssh *ssh)\n{\n\tstruct kex *kex = ssh->kex;\n\tint r;\n\n\tkexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey);\n#ifdef DEBUG_KEXECDH\n\tdump_digest(\"client private key:\", kex->c25519_client_key,\n\t sizeof(kex->c25519_client_key));\n#endif\n\tif ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 ||\n\t (r = sshpkt_put_string(ssh, kex->c25519_client_pubkey,\n\t sizeof(kex->c25519_client_pubkey))) != 0 ||\n\t (r = sshpkt_send(ssh)) != 0)\n\t\treturn r;\n\n\tdebug(\"expecting SSH2_MSG_KEX_ECDH_REPLY\");\n\tssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_c25519_reply);\n\treturn 0;\n}\n\nstatic int\ninput_kex_c25519_reply(int type, u_int32_t seq, void *ctxt)\n{\n\tstruct ssh *ssh = ctxt;\n\tstruct kex *kex = ssh->kex;\n\tstruct sshkey *server_host_key = NULL;\n\tstruct sshbuf *shared_secret = NULL;\n\tu_char *server_pubkey = NULL;\n\tu_char *server_host_key_blob = NULL, *signature = NULL;\n\tu_char hash[SSH_DIGEST_MAX_LENGTH];\n\tsize_t slen, pklen, sbloblen, hashlen;\n\tint r;\n\n\tif (kex->verify_host_key == NULL) {\n\t\tr = SSH_ERR_INVALID_ARGUMENT;\n\t\tgoto out;\n\t}\n\n\t/* hostkey */\n\tif ((r = sshpkt_get_string(ssh, &server_host_key_blob,\n\t &sbloblen)) != 0 ||\n\t (r = sshkey_from_blob(server_host_key_blob, sbloblen,\n\t &server_host_key)) != 0)\n\t\tgoto out;\n\tif (server_host_key->type != kex->hostkey_type ||\n\t (kex->hostkey_type == KEY_ECDSA &&\n\t server_host_key->ecdsa_nid != kex->hostkey_nid)) {\n\t\tr = SSH_ERR_KEY_TYPE_MISMATCH;\n\t\tgoto out;\n\t}\n\tif (kex->verify_host_key(server_host_key, ssh) == -1) {\n\t\tr = SSH_ERR_SIGNATURE_INVALID;\n\t\tgoto out;\n\t}\n\n\t/* Q_S, server public key */\n\t/* signed H */\n\tif ((r = sshpkt_get_string(ssh, &server_pubkey, &pklen)) != 0 ||\n\t (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 ||\n\t (r = sshpkt_get_end(ssh)) != 0)\n\t\tgoto out;\n\tif (pklen != CURVE25519_SIZE) {\n\t\tr = SSH_ERR_SIGNATURE_INVALID;\n\t\tgoto out;\n\t}\n\n#ifdef DEBUG_KEXECDH\n\tdump_digest(\"server public key:\", server_pubkey, CURVE25519_SIZE);\n#endif\n\n\tif ((shared_secret = sshbuf_new()) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = kexc25519_shared_key(kex->c25519_client_key, server_pubkey,\n\t shared_secret)) < 0)\n\t\tgoto out;\n\n\t/* calc and verify H */\n\thashlen = sizeof(hash);\n\tif ((r = kex_c25519_hash(\n\t kex->hash_alg,\n\t kex->client_version_string,\n\t kex->server_version_string,\n\t sshbuf_ptr(kex->my), sshbuf_len(kex->my),\n\t sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),\n\t server_host_key_blob, sbloblen,\n\t kex->c25519_client_pubkey,\n\t server_pubkey,\n\t sshbuf_ptr(shared_secret), sshbuf_len(shared_secret),\n\t hash, &hashlen)) < 0)\n\t\tgoto out;\n\n\tif ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,\n\t ssh->compat)) != 0)\n\t\tgoto out;\n\n\t/* save session id */\n\tif (kex->session_id == NULL) {\n\t\tkex->session_id_len = hashlen;\n\t\tkex->session_id = malloc(kex->session_id_len);\n\t\tif (kex->session_id == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tmemcpy(kex->session_id, hash, kex->session_id_len);\n\t}\n\n\tif ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)\n\t\tr = kex_send_newkeys(ssh);\nout:\n\texplicit_bzero(hash, sizeof(hash));\n\texplicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));\n\tfree(server_host_key_blob);\n\tfree(server_pubkey);\n\tfree(signature);\n\tsshkey_free(server_host_key);\n\tsshbuf_free(shared_secret);\n\treturn r;\n}\n","/*\n * Copyright (c) 2015 Joyent, Inc\n * Author: Alex Wilson \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n\n#include \"platform.h\"\n\n#include \"openbsd-compat/openbsd-compat.h\"\n\n/*\n * Drop any fine-grained privileges that are not needed for post-startup\n * operation of ssh-agent\n *\n * Should be as close as possible to pledge(\"stdio cpath unix id proc exec\", ...)\n */\nvoid\nplatform_pledge_agent(void)\n{\n#ifdef USE_SOLARIS_PRIVS\n\t/*\n\t * Note: Solaris priv dropping is closer to tame() than pledge(), but\n\t * we will use what we have.\n\t */\n\tsolaris_drop_privs_root_pinfo_net();\n#endif\n}\n\n/*\n * Drop any fine-grained privileges that are not needed for post-startup\n * operation of sftp-server\n */\nvoid\nplatform_pledge_sftp_server(void)\n{\n#ifdef USE_SOLARIS_PRIVS\n\tsolaris_drop_privs_pinfo_net_fork_exec();\n#endif\n}\n\n/*\n * Drop any fine-grained privileges that are not needed for the post-startup\n * operation of the SSH client mux\n *\n * Should be as close as possible to pledge(\"stdio proc tty\", ...)\n */\nvoid\nplatform_pledge_mux(void)\n{\n#ifdef USE_SOLARIS_PRIVS\n\tsolaris_drop_privs_root_pinfo_net_exec();\n#endif\n}\n","/*\n * Copyright (c) 2012 Damien Miller \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/* $OpenBSD: krl.c,v 1.39 2017/03/10 07:18:32 dtucker Exp $ */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n\n#include \n#include \n#include \n#include \n#include \n#include \n\n#include \"sshbuf.h\"\n#include \"ssherr.h\"\n#include \"sshkey.h\"\n#include \"authfile.h\"\n#include \"misc.h\"\n#include \"log.h\"\n#include \"digest.h\"\n#include \"bitmap.h\"\n\n#include \"krl.h\"\n\n/* #define DEBUG_KRL */\n#ifdef DEBUG_KRL\n# define KRL_DBG(x) debug3 x\n#else\n# define KRL_DBG(x)\n#endif\n\n/*\n * Trees of revoked serial numbers, key IDs and keys. This allows\n * quick searching, querying and producing lists in canonical order.\n */\n\n/* Tree of serial numbers. XXX make smarter: really need a real sparse bitmap */\nstruct revoked_serial {\n\tu_int64_t lo, hi;\n\tRB_ENTRY(revoked_serial) tree_entry;\n};\nstatic int serial_cmp(struct revoked_serial *a, struct revoked_serial *b);\nRB_HEAD(revoked_serial_tree, revoked_serial);\nRB_GENERATE_STATIC(revoked_serial_tree, revoked_serial, tree_entry, serial_cmp);\n\n/* Tree of key IDs */\nstruct revoked_key_id {\n\tchar *key_id;\n\tRB_ENTRY(revoked_key_id) tree_entry;\n};\nstatic int key_id_cmp(struct revoked_key_id *a, struct revoked_key_id *b);\nRB_HEAD(revoked_key_id_tree, revoked_key_id);\nRB_GENERATE_STATIC(revoked_key_id_tree, revoked_key_id, tree_entry, key_id_cmp);\n\n/* Tree of blobs (used for keys and fingerprints) */\nstruct revoked_blob {\n\tu_char *blob;\n\tsize_t len;\n\tRB_ENTRY(revoked_blob) tree_entry;\n};\nstatic int blob_cmp(struct revoked_blob *a, struct revoked_blob *b);\nRB_HEAD(revoked_blob_tree, revoked_blob);\nRB_GENERATE_STATIC(revoked_blob_tree, revoked_blob, tree_entry, blob_cmp);\n\n/* Tracks revoked certs for a single CA */\nstruct revoked_certs {\n\tstruct sshkey *ca_key;\n\tstruct revoked_serial_tree revoked_serials;\n\tstruct revoked_key_id_tree revoked_key_ids;\n\tTAILQ_ENTRY(revoked_certs) entry;\n};\nTAILQ_HEAD(revoked_certs_list, revoked_certs);\n\nstruct ssh_krl {\n\tu_int64_t krl_version;\n\tu_int64_t generated_date;\n\tu_int64_t flags;\n\tchar *comment;\n\tstruct revoked_blob_tree revoked_keys;\n\tstruct revoked_blob_tree revoked_sha1s;\n\tstruct revoked_certs_list revoked_certs;\n};\n\n/* Return equal if a and b overlap */\nstatic int\nserial_cmp(struct revoked_serial *a, struct revoked_serial *b)\n{\n\tif (a->hi >= b->lo && a->lo <= b->hi)\n\t\treturn 0;\n\treturn a->lo < b->lo ? -1 : 1;\n}\n\nstatic int\nkey_id_cmp(struct revoked_key_id *a, struct revoked_key_id *b)\n{\n\treturn strcmp(a->key_id, b->key_id);\n}\n\nstatic int\nblob_cmp(struct revoked_blob *a, struct revoked_blob *b)\n{\n\tint r;\n\n\tif (a->len != b->len) {\n\t\tif ((r = memcmp(a->blob, b->blob, MINIMUM(a->len, b->len))) != 0)\n\t\t\treturn r;\n\t\treturn a->len > b->len ? 1 : -1;\n\t} else\n\t\treturn memcmp(a->blob, b->blob, a->len);\n}\n\nstruct ssh_krl *\nssh_krl_init(void)\n{\n\tstruct ssh_krl *krl;\n\n\tif ((krl = calloc(1, sizeof(*krl))) == NULL)\n\t\treturn NULL;\n\tRB_INIT(&krl->revoked_keys);\n\tRB_INIT(&krl->revoked_sha1s);\n\tTAILQ_INIT(&krl->revoked_certs);\n\treturn krl;\n}\n\nstatic void\nrevoked_certs_free(struct revoked_certs *rc)\n{\n\tstruct revoked_serial *rs, *trs;\n\tstruct revoked_key_id *rki, *trki;\n\n\tRB_FOREACH_SAFE(rs, revoked_serial_tree, &rc->revoked_serials, trs) {\n\t\tRB_REMOVE(revoked_serial_tree, &rc->revoked_serials, rs);\n\t\tfree(rs);\n\t}\n\tRB_FOREACH_SAFE(rki, revoked_key_id_tree, &rc->revoked_key_ids, trki) {\n\t\tRB_REMOVE(revoked_key_id_tree, &rc->revoked_key_ids, rki);\n\t\tfree(rki->key_id);\n\t\tfree(rki);\n\t}\n\tsshkey_free(rc->ca_key);\n}\n\nvoid\nssh_krl_free(struct ssh_krl *krl)\n{\n\tstruct revoked_blob *rb, *trb;\n\tstruct revoked_certs *rc, *trc;\n\n\tif (krl == NULL)\n\t\treturn;\n\n\tfree(krl->comment);\n\tRB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_keys, trb) {\n\t\tRB_REMOVE(revoked_blob_tree, &krl->revoked_keys, rb);\n\t\tfree(rb->blob);\n\t\tfree(rb);\n\t}\n\tRB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_sha1s, trb) {\n\t\tRB_REMOVE(revoked_blob_tree, &krl->revoked_sha1s, rb);\n\t\tfree(rb->blob);\n\t\tfree(rb);\n\t}\n\tTAILQ_FOREACH_SAFE(rc, &krl->revoked_certs, entry, trc) {\n\t\tTAILQ_REMOVE(&krl->revoked_certs, rc, entry);\n\t\trevoked_certs_free(rc);\n\t}\n}\n\nvoid\nssh_krl_set_version(struct ssh_krl *krl, u_int64_t version)\n{\n\tkrl->krl_version = version;\n}\n\nint\nssh_krl_set_comment(struct ssh_krl *krl, const char *comment)\n{\n\tfree(krl->comment);\n\tif ((krl->comment = strdup(comment)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\treturn 0;\n}\n\n/*\n * Find the revoked_certs struct for a CA key. If allow_create is set then\n * create a new one in the tree if one did not exist already.\n */\nstatic int\nrevoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key,\n struct revoked_certs **rcp, int allow_create)\n{\n\tstruct revoked_certs *rc;\n\tint r;\n\n\t*rcp = NULL;\n\tTAILQ_FOREACH(rc, &krl->revoked_certs, entry) {\n\t\tif ((ca_key == NULL && rc->ca_key == NULL) ||\n\t\t sshkey_equal(rc->ca_key, ca_key)) {\n\t\t\t*rcp = rc;\n\t\t\treturn 0;\n\t\t}\n\t}\n\tif (!allow_create)\n\t\treturn 0;\n\t/* If this CA doesn't exist in the list then add it now */\n\tif ((rc = calloc(1, sizeof(*rc))) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif (ca_key == NULL)\n\t\trc->ca_key = NULL;\n\telse if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) {\n\t\tfree(rc);\n\t\treturn r;\n\t}\n\tRB_INIT(&rc->revoked_serials);\n\tRB_INIT(&rc->revoked_key_ids);\n\tTAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry);\n\tKRL_DBG((\"%s: new CA %s\", __func__,\n\t ca_key == NULL ? \"*\" : sshkey_type(ca_key)));\n\t*rcp = rc;\n\treturn 0;\n}\n\nstatic int\ninsert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi)\n{\n\tstruct revoked_serial rs, *ers, *crs, *irs;\n\n\tKRL_DBG((\"%s: insert %llu:%llu\", __func__, lo, hi));\n\tmemset(&rs, 0, sizeof(rs));\n\trs.lo = lo;\n\trs.hi = hi;\n\ters = RB_NFIND(revoked_serial_tree, rt, &rs);\n\tif (ers == NULL || serial_cmp(ers, &rs) != 0) {\n\t\t/* No entry matches. Just insert */\n\t\tif ((irs = malloc(sizeof(rs))) == NULL)\n\t\t\treturn SSH_ERR_ALLOC_FAIL;\n\t\tmemcpy(irs, &rs, sizeof(*irs));\n\t\ters = RB_INSERT(revoked_serial_tree, rt, irs);\n\t\tif (ers != NULL) {\n\t\t\tKRL_DBG((\"%s: bad: ers != NULL\", __func__));\n\t\t\t/* Shouldn't happen */\n\t\t\tfree(irs);\n\t\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t\t}\n\t\ters = irs;\n\t} else {\n\t\tKRL_DBG((\"%s: overlap found %llu:%llu\", __func__,\n\t\t ers->lo, ers->hi));\n\t\t/*\n\t\t * The inserted entry overlaps an existing one. Grow the\n\t\t * existing entry.\n\t\t */\n\t\tif (ers->lo > lo)\n\t\t\ters->lo = lo;\n\t\tif (ers->hi < hi)\n\t\t\ters->hi = hi;\n\t}\n\n\t/*\n\t * The inserted or revised range might overlap or abut adjacent ones;\n\t * coalesce as necessary.\n\t */\n\n\t/* Check predecessors */\n\twhile ((crs = RB_PREV(revoked_serial_tree, rt, ers)) != NULL) {\n\t\tKRL_DBG((\"%s: pred %llu:%llu\", __func__, crs->lo, crs->hi));\n\t\tif (ers->lo != 0 && crs->hi < ers->lo - 1)\n\t\t\tbreak;\n\t\t/* This entry overlaps. */\n\t\tif (crs->lo < ers->lo) {\n\t\t\ters->lo = crs->lo;\n\t\t\tKRL_DBG((\"%s: pred extend %llu:%llu\", __func__,\n\t\t\t ers->lo, ers->hi));\n\t\t}\n\t\tRB_REMOVE(revoked_serial_tree, rt, crs);\n\t\tfree(crs);\n\t}\n\t/* Check successors */\n\twhile ((crs = RB_NEXT(revoked_serial_tree, rt, ers)) != NULL) {\n\t\tKRL_DBG((\"%s: succ %llu:%llu\", __func__, crs->lo, crs->hi));\n\t\tif (ers->hi != (u_int64_t)-1 && crs->lo > ers->hi + 1)\n\t\t\tbreak;\n\t\t/* This entry overlaps. */\n\t\tif (crs->hi > ers->hi) {\n\t\t\ters->hi = crs->hi;\n\t\t\tKRL_DBG((\"%s: succ extend %llu:%llu\", __func__,\n\t\t\t ers->lo, ers->hi));\n\t\t}\n\t\tRB_REMOVE(revoked_serial_tree, rt, crs);\n\t\tfree(crs);\n\t}\n\tKRL_DBG((\"%s: done, final %llu:%llu\", __func__, ers->lo, ers->hi));\n\treturn 0;\n}\n\nint\nssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const struct sshkey *ca_key,\n u_int64_t serial)\n{\n\treturn ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial, serial);\n}\n\nint\nssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl,\n const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi)\n{\n\tstruct revoked_certs *rc;\n\tint r;\n\n\tif (lo > hi || lo == 0)\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0)\n\t\treturn r;\n\treturn insert_serial_range(&rc->revoked_serials, lo, hi);\n}\n\nint\nssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const struct sshkey *ca_key,\n const char *key_id)\n{\n\tstruct revoked_key_id *rki, *erki;\n\tstruct revoked_certs *rc;\n\tint r;\n\n\tif ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0)\n\t\treturn r;\n\n\tKRL_DBG((\"%s: revoke %s\", __func__, key_id));\n\tif ((rki = calloc(1, sizeof(*rki))) == NULL ||\n\t (rki->key_id = strdup(key_id)) == NULL) {\n\t\tfree(rki);\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\t}\n\terki = RB_INSERT(revoked_key_id_tree, &rc->revoked_key_ids, rki);\n\tif (erki != NULL) {\n\t\tfree(rki->key_id);\n\t\tfree(rki);\n\t}\n\treturn 0;\n}\n\n/* Convert \"key\" to a public key blob without any certificate information */\nstatic int\nplain_key_blob(const struct sshkey *key, u_char **blob, size_t *blen)\n{\n\tstruct sshkey *kcopy;\n\tint r;\n\n\tif ((r = sshkey_from_private(key, &kcopy)) != 0)\n\t\treturn r;\n\tif (sshkey_is_cert(kcopy)) {\n\t\tif ((r = sshkey_drop_cert(kcopy)) != 0) {\n\t\t\tsshkey_free(kcopy);\n\t\t\treturn r;\n\t\t}\n\t}\n\tr = sshkey_to_blob(kcopy, blob, blen);\n\tsshkey_free(kcopy);\n\treturn r;\n}\n\n/* Revoke a key blob. Ownership of blob is transferred to the tree */\nstatic int\nrevoke_blob(struct revoked_blob_tree *rbt, u_char *blob, size_t len)\n{\n\tstruct revoked_blob *rb, *erb;\n\n\tif ((rb = calloc(1, sizeof(*rb))) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\trb->blob = blob;\n\trb->len = len;\n\terb = RB_INSERT(revoked_blob_tree, rbt, rb);\n\tif (erb != NULL) {\n\t\tfree(rb->blob);\n\t\tfree(rb);\n\t}\n\treturn 0;\n}\n\nint\nssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key)\n{\n\tu_char *blob;\n\tsize_t len;\n\tint r;\n\n\tdebug3(\"%s: revoke type %s\", __func__, sshkey_type(key));\n\tif ((r = plain_key_blob(key, &blob, &len)) != 0)\n\t\treturn r;\n\treturn revoke_blob(&krl->revoked_keys, blob, len);\n}\n\nint\nssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key)\n{\n\tu_char *blob;\n\tsize_t len;\n\tint r;\n\n\tdebug3(\"%s: revoke type %s by sha1\", __func__, sshkey_type(key));\n\tif ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,\n\t &blob, &len)) != 0)\n\t\treturn r;\n\treturn revoke_blob(&krl->revoked_sha1s, blob, len);\n}\n\nint\nssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key)\n{\n\tif (!sshkey_is_cert(key))\n\t\treturn ssh_krl_revoke_key_sha1(krl, key);\n\n\tif (key->cert->serial == 0) {\n\t\treturn ssh_krl_revoke_cert_by_key_id(krl,\n\t\t key->cert->signature_key,\n\t\t key->cert->key_id);\n\t} else {\n\t\treturn ssh_krl_revoke_cert_by_serial(krl,\n\t\t key->cert->signature_key,\n\t\t key->cert->serial);\n\t}\n}\n\n/*\n * Select the most compact section type to emit next in a KRL based on\n * the current section type, the run length of contiguous revoked serial\n * numbers and the gaps from the last and to the next revoked serial.\n * Applies a mostly-accurate bit cost model to select the section type\n * that will minimise the size of the resultant KRL.\n */\nstatic int\nchoose_next_state(int current_state, u_int64_t contig, int final,\n u_int64_t last_gap, u_int64_t next_gap, int *force_new_section)\n{\n\tint new_state;\n\tu_int64_t cost, cost_list, cost_range, cost_bitmap, cost_bitmap_restart;\n\n\t/*\n\t * Avoid unsigned overflows.\n\t * The limits are high enough to avoid confusing the calculations.\n\t */\n\tcontig = MINIMUM(contig, 1ULL<<31);\n\tlast_gap = MINIMUM(last_gap, 1ULL<<31);\n\tnext_gap = MINIMUM(next_gap, 1ULL<<31);\n\n\t/*\n\t * Calculate the cost to switch from the current state to candidates.\n\t * NB. range sections only ever contain a single range, so their\n\t * switching cost is independent of the current_state.\n\t */\n\tcost_list = cost_bitmap = cost_bitmap_restart = 0;\n\tcost_range = 8;\n\tswitch (current_state) {\n\tcase KRL_SECTION_CERT_SERIAL_LIST:\n\t\tcost_bitmap_restart = cost_bitmap = 8 + 64;\n\t\tbreak;\n\tcase KRL_SECTION_CERT_SERIAL_BITMAP:\n\t\tcost_list = 8;\n\t\tcost_bitmap_restart = 8 + 64;\n\t\tbreak;\n\tcase KRL_SECTION_CERT_SERIAL_RANGE:\n\tcase 0:\n\t\tcost_bitmap_restart = cost_bitmap = 8 + 64;\n\t\tcost_list = 8;\n\t}\n\n\t/* Estimate base cost in bits of each section type */\n\tcost_list += 64 * contig + (final ? 0 : 8+64);\n\tcost_range += (2 * 64) + (final ? 0 : 8+64);\n\tcost_bitmap += last_gap + contig + (final ? 0 : MINIMUM(next_gap, 8+64));\n\tcost_bitmap_restart += contig + (final ? 0 : MINIMUM(next_gap, 8+64));\n\n\t/* Convert to byte costs for actual comparison */\n\tcost_list = (cost_list + 7) / 8;\n\tcost_bitmap = (cost_bitmap + 7) / 8;\n\tcost_bitmap_restart = (cost_bitmap_restart + 7) / 8;\n\tcost_range = (cost_range + 7) / 8;\n\n\t/* Now pick the best choice */\n\t*force_new_section = 0;\n\tnew_state = KRL_SECTION_CERT_SERIAL_BITMAP;\n\tcost = cost_bitmap;\n\tif (cost_range < cost) {\n\t\tnew_state = KRL_SECTION_CERT_SERIAL_RANGE;\n\t\tcost = cost_range;\n\t}\n\tif (cost_list < cost) {\n\t\tnew_state = KRL_SECTION_CERT_SERIAL_LIST;\n\t\tcost = cost_list;\n\t}\n\tif (cost_bitmap_restart < cost) {\n\t\tnew_state = KRL_SECTION_CERT_SERIAL_BITMAP;\n\t\t*force_new_section = 1;\n\t\tcost = cost_bitmap_restart;\n\t}\n\tKRL_DBG((\"%s: contig %llu last_gap %llu next_gap %llu final %d, costs:\"\n\t \"list %llu range %llu bitmap %llu new bitmap %llu, \"\n\t \"selected 0x%02x%s\", __func__, (long long unsigned)contig,\n\t (long long unsigned)last_gap, (long long unsigned)next_gap, final,\n\t (long long unsigned)cost_list, (long long unsigned)cost_range,\n\t (long long unsigned)cost_bitmap,\n\t (long long unsigned)cost_bitmap_restart, new_state,\n\t *force_new_section ? \" restart\" : \"\"));\n\treturn new_state;\n}\n\nstatic int\nput_bitmap(struct sshbuf *buf, struct bitmap *bitmap)\n{\n\tsize_t len;\n\tu_char *blob;\n\tint r;\n\n\tlen = bitmap_nbytes(bitmap);\n\tif ((blob = malloc(len)) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif (bitmap_to_string(bitmap, blob, len) != 0) {\n\t\tfree(blob);\n\t\treturn SSH_ERR_INTERNAL_ERROR;\n\t}\n\tr = sshbuf_put_bignum2_bytes(buf, blob, len);\n\tfree(blob);\n\treturn r;\n}\n\n/* Generate a KRL_SECTION_CERTIFICATES KRL section */\nstatic int\nrevoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf)\n{\n\tint final, force_new_sect, r = SSH_ERR_INTERNAL_ERROR;\n\tu_int64_t i, contig, gap, last = 0, bitmap_start = 0;\n\tstruct revoked_serial *rs, *nrs;\n\tstruct revoked_key_id *rki;\n\tint next_state, state = 0;\n\tstruct sshbuf *sect;\n\tstruct bitmap *bitmap = NULL;\n\n\tif ((sect = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\t/* Store the header: optional CA scope key, reserved */\n\tif (rc->ca_key == NULL) {\n\t\tif ((r = sshbuf_put_string(buf, NULL, 0)) != 0)\n\t\t\tgoto out;\n\t} else {\n\t\tif ((r = sshkey_puts(rc->ca_key, buf)) != 0)\n\t\t\tgoto out;\n\t}\n\tif ((r = sshbuf_put_string(buf, NULL, 0)) != 0)\n\t\tgoto out;\n\n\t/* Store the revoked serials. */\n\tfor (rs = RB_MIN(revoked_serial_tree, &rc->revoked_serials);\n\t rs != NULL;\n\t rs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs)) {\n\t\tKRL_DBG((\"%s: serial %llu:%llu state 0x%02x\", __func__,\n\t\t (long long unsigned)rs->lo, (long long unsigned)rs->hi,\n\t\t state));\n\n\t\t/* Check contiguous length and gap to next section (if any) */\n\t\tnrs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs);\n\t\tfinal = nrs == NULL;\n\t\tgap = nrs == NULL ? 0 : nrs->lo - rs->hi;\n\t\tcontig = 1 + (rs->hi - rs->lo);\n\n\t\t/* Choose next state based on these */\n\t\tnext_state = choose_next_state(state, contig, final,\n\t\t state == 0 ? 0 : rs->lo - last, gap, &force_new_sect);\n\n\t\t/*\n\t\t * If the current section is a range section or has a different\n\t\t * type to the next section, then finish it off now.\n\t\t */\n\t\tif (state != 0 && (force_new_sect || next_state != state ||\n\t\t state == KRL_SECTION_CERT_SERIAL_RANGE)) {\n\t\t\tKRL_DBG((\"%s: finish state 0x%02x\", __func__, state));\n\t\t\tswitch (state) {\n\t\t\tcase KRL_SECTION_CERT_SERIAL_LIST:\n\t\t\tcase KRL_SECTION_CERT_SERIAL_RANGE:\n\t\t\t\tbreak;\n\t\t\tcase KRL_SECTION_CERT_SERIAL_BITMAP:\n\t\t\t\tif ((r = put_bitmap(sect, bitmap)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\tbitmap_free(bitmap);\n\t\t\t\tbitmap = NULL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ((r = sshbuf_put_u8(buf, state)) != 0 ||\n\t\t\t (r = sshbuf_put_stringb(buf, sect)) != 0)\n\t\t\t\tgoto out;\n\t\t\tsshbuf_reset(sect);\n\t\t}\n\n\t\t/* If we are starting a new section then prepare it now */\n\t\tif (next_state != state || force_new_sect) {\n\t\t\tKRL_DBG((\"%s: start state 0x%02x\", __func__,\n\t\t\t next_state));\n\t\t\tstate = next_state;\n\t\t\tsshbuf_reset(sect);\n\t\t\tswitch (state) {\n\t\t\tcase KRL_SECTION_CERT_SERIAL_LIST:\n\t\t\tcase KRL_SECTION_CERT_SERIAL_RANGE:\n\t\t\t\tbreak;\n\t\t\tcase KRL_SECTION_CERT_SERIAL_BITMAP:\n\t\t\t\tif ((bitmap = bitmap_new()) == NULL) {\n\t\t\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\t\t\t\tbitmap_start = rs->lo;\n\t\t\t\tif ((r = sshbuf_put_u64(sect,\n\t\t\t\t bitmap_start)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Perform section-specific processing */\n\t\tswitch (state) {\n\t\tcase KRL_SECTION_CERT_SERIAL_LIST:\n\t\t\tfor (i = 0; i < contig; i++) {\n\t\t\t\tif ((r = sshbuf_put_u64(sect, rs->lo + i)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase KRL_SECTION_CERT_SERIAL_RANGE:\n\t\t\tif ((r = sshbuf_put_u64(sect, rs->lo)) != 0 ||\n\t\t\t (r = sshbuf_put_u64(sect, rs->hi)) != 0)\n\t\t\t\tgoto out;\n\t\t\tbreak;\n\t\tcase KRL_SECTION_CERT_SERIAL_BITMAP:\n\t\t\tif (rs->lo - bitmap_start > INT_MAX) {\n\t\t\t\terror(\"%s: insane bitmap gap\", __func__);\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tfor (i = 0; i < contig; i++) {\n\t\t\t\tif (bitmap_set_bit(bitmap,\n\t\t\t\t rs->lo + i - bitmap_start) != 0) {\n\t\t\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tlast = rs->hi;\n\t}\n\t/* Flush the remaining section, if any */\n\tif (state != 0) {\n\t\tKRL_DBG((\"%s: serial final flush for state 0x%02x\",\n\t\t __func__, state));\n\t\tswitch (state) {\n\t\tcase KRL_SECTION_CERT_SERIAL_LIST:\n\t\tcase KRL_SECTION_CERT_SERIAL_RANGE:\n\t\t\tbreak;\n\t\tcase KRL_SECTION_CERT_SERIAL_BITMAP:\n\t\t\tif ((r = put_bitmap(sect, bitmap)) != 0)\n\t\t\t\tgoto out;\n\t\t\tbitmap_free(bitmap);\n\t\t\tbitmap = NULL;\n\t\t\tbreak;\n\t\t}\n\t\tif ((r = sshbuf_put_u8(buf, state)) != 0 ||\n\t\t (r = sshbuf_put_stringb(buf, sect)) != 0)\n\t\t\tgoto out;\n\t}\n\tKRL_DBG((\"%s: serial done \", __func__));\n\n\t/* Now output a section for any revocations by key ID */\n\tsshbuf_reset(sect);\n\tRB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) {\n\t\tKRL_DBG((\"%s: key ID %s\", __func__, rki->key_id));\n\t\tif ((r = sshbuf_put_cstring(sect, rki->key_id)) != 0)\n\t\t\tgoto out;\n\t}\n\tif (sshbuf_len(sect) != 0) {\n\t\tif ((r = sshbuf_put_u8(buf, KRL_SECTION_CERT_KEY_ID)) != 0 ||\n\t\t (r = sshbuf_put_stringb(buf, sect)) != 0)\n\t\t\tgoto out;\n\t}\n\tr = 0;\n out:\n\tbitmap_free(bitmap);\n\tsshbuf_free(sect);\n\treturn r;\n}\n\nint\nssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,\n const struct sshkey **sign_keys, u_int nsign_keys)\n{\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\tstruct revoked_certs *rc;\n\tstruct revoked_blob *rb;\n\tstruct sshbuf *sect;\n\tu_char *sblob = NULL;\n\tsize_t slen, i;\n\n\tif (krl->generated_date == 0)\n\t\tkrl->generated_date = time(NULL);\n\n\tif ((sect = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\t/* Store the header */\n\tif ((r = sshbuf_put(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1)) != 0 ||\n\t (r = sshbuf_put_u32(buf, KRL_FORMAT_VERSION)) != 0 ||\n\t (r = sshbuf_put_u64(buf, krl->krl_version)) != 0 ||\n\t (r = sshbuf_put_u64(buf, krl->generated_date)) != 0 ||\n\t (r = sshbuf_put_u64(buf, krl->flags)) != 0 ||\n\t (r = sshbuf_put_string(buf, NULL, 0)) != 0 ||\n\t (r = sshbuf_put_cstring(buf, krl->comment)) != 0)\n\t\tgoto out;\n\n\t/* Store sections for revoked certificates */\n\tTAILQ_FOREACH(rc, &krl->revoked_certs, entry) {\n\t\tsshbuf_reset(sect);\n\t\tif ((r = revoked_certs_generate(rc, sect)) != 0)\n\t\t\tgoto out;\n\t\tif ((r = sshbuf_put_u8(buf, KRL_SECTION_CERTIFICATES)) != 0 ||\n\t\t (r = sshbuf_put_stringb(buf, sect)) != 0)\n\t\t\tgoto out;\n\t}\n\n\t/* Finally, output sections for revocations by public key/hash */\n\tsshbuf_reset(sect);\n\tRB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) {\n\t\tKRL_DBG((\"%s: key len %zu \", __func__, rb->len));\n\t\tif ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)\n\t\t\tgoto out;\n\t}\n\tif (sshbuf_len(sect) != 0) {\n\t\tif ((r = sshbuf_put_u8(buf, KRL_SECTION_EXPLICIT_KEY)) != 0 ||\n\t\t (r = sshbuf_put_stringb(buf, sect)) != 0)\n\t\t\tgoto out;\n\t}\n\tsshbuf_reset(sect);\n\tRB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) {\n\t\tKRL_DBG((\"%s: hash len %zu \", __func__, rb->len));\n\t\tif ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0)\n\t\t\tgoto out;\n\t}\n\tif (sshbuf_len(sect) != 0) {\n\t\tif ((r = sshbuf_put_u8(buf,\n\t\t KRL_SECTION_FINGERPRINT_SHA1)) != 0 ||\n\t\t (r = sshbuf_put_stringb(buf, sect)) != 0)\n\t\t\tgoto out;\n\t}\n\n\tfor (i = 0; i < nsign_keys; i++) {\n\t\tKRL_DBG((\"%s: signature key %s\", __func__,\n\t\t sshkey_ssh_name(sign_keys[i])));\n\t\tif ((r = sshbuf_put_u8(buf, KRL_SECTION_SIGNATURE)) != 0 ||\n\t\t (r = sshkey_puts(sign_keys[i], buf)) != 0)\n\t\t\tgoto out;\n\n\t\tif ((r = sshkey_sign(sign_keys[i], &sblob, &slen,\n\t\t sshbuf_ptr(buf), sshbuf_len(buf), NULL, 0)) != 0)\n\t\t\tgoto out;\n\t\tKRL_DBG((\"%s: signature sig len %zu\", __func__, slen));\n\t\tif ((r = sshbuf_put_string(buf, sblob, slen)) != 0)\n\t\t\tgoto out;\n\t}\n\n\tr = 0;\n out:\n\tfree(sblob);\n\tsshbuf_free(sect);\n\treturn r;\n}\n\nstatic void\nformat_timestamp(u_int64_t timestamp, char *ts, size_t nts)\n{\n\ttime_t t;\n\tstruct tm *tm;\n\n\tt = timestamp;\n\ttm = localtime(&t);\n\tif (tm == NULL)\n\t\tstrlcpy(ts, \"\", nts);\n\telse {\n\t\t*ts = '\\0';\n\t\tstrftime(ts, nts, \"%Y%m%dT%H%M%S\", tm);\n\t}\n}\n\nstatic int\nparse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl)\n{\n\tint r = SSH_ERR_INTERNAL_ERROR;\n\tu_char type;\n\tconst u_char *blob;\n\tsize_t blen, nbits;\n\tstruct sshbuf *subsect = NULL;\n\tu_int64_t serial, serial_lo, serial_hi;\n\tstruct bitmap *bitmap = NULL;\n\tchar *key_id = NULL;\n\tstruct sshkey *ca_key = NULL;\n\n\tif ((subsect = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\n\t/* Header: key, reserved */\n\tif ((r = sshbuf_get_string_direct(buf, &blob, &blen)) != 0 ||\n\t (r = sshbuf_skip_string(buf)) != 0)\n\t\tgoto out;\n\tif (blen != 0 && (r = sshkey_from_blob(blob, blen, &ca_key)) != 0)\n\t\tgoto out;\n\n\twhile (sshbuf_len(buf) > 0) {\n\t\tsshbuf_free(subsect);\n\t\tsubsect = NULL;\n\t\tif ((r = sshbuf_get_u8(buf, &type)) != 0 ||\n\t\t (r = sshbuf_froms(buf, &subsect)) != 0)\n\t\t\tgoto out;\n\t\tKRL_DBG((\"%s: subsection type 0x%02x\", __func__, type));\n\t\t/* sshbuf_dump(subsect, stderr); */\n\n\t\tswitch (type) {\n\t\tcase KRL_SECTION_CERT_SERIAL_LIST:\n\t\t\twhile (sshbuf_len(subsect) > 0) {\n\t\t\t\tif ((r = sshbuf_get_u64(subsect, &serial)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\tif ((r = ssh_krl_revoke_cert_by_serial(krl,\n\t\t\t\t ca_key, serial)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase KRL_SECTION_CERT_SERIAL_RANGE:\n\t\t\tif ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 ||\n\t\t\t (r = sshbuf_get_u64(subsect, &serial_hi)) != 0)\n\t\t\t\tgoto out;\n\t\t\tif ((r = ssh_krl_revoke_cert_by_serial_range(krl,\n\t\t\t ca_key, serial_lo, serial_hi)) != 0)\n\t\t\t\tgoto out;\n\t\t\tbreak;\n\t\tcase KRL_SECTION_CERT_SERIAL_BITMAP:\n\t\t\tif ((bitmap = bitmap_new()) == NULL) {\n\t\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tif ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 ||\n\t\t\t (r = sshbuf_get_bignum2_bytes_direct(subsect,\n\t\t\t &blob, &blen)) != 0)\n\t\t\t\tgoto out;\n\t\t\tif (bitmap_from_string(bitmap, blob, blen) != 0) {\n\t\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tnbits = bitmap_nbits(bitmap);\n\t\t\tfor (serial = 0; serial < (u_int64_t)nbits; serial++) {\n\t\t\t\tif (serial > 0 && serial_lo + serial == 0) {\n\t\t\t\t\terror(\"%s: bitmap wraps u64\", __func__);\n\t\t\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\t\t\t\tif (!bitmap_test_bit(bitmap, serial))\n\t\t\t\t\tcontinue;\n\t\t\t\tif ((r = ssh_krl_revoke_cert_by_serial(krl,\n\t\t\t\t ca_key, serial_lo + serial)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tbitmap_free(bitmap);\n\t\t\tbitmap = NULL;\n\t\t\tbreak;\n\t\tcase KRL_SECTION_CERT_KEY_ID:\n\t\t\twhile (sshbuf_len(subsect) > 0) {\n\t\t\t\tif ((r = sshbuf_get_cstring(subsect,\n\t\t\t\t &key_id, NULL)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\tif ((r = ssh_krl_revoke_cert_by_key_id(krl,\n\t\t\t\t ca_key, key_id)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\tfree(key_id);\n\t\t\t\tkey_id = NULL;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\terror(\"Unsupported KRL certificate section %u\", type);\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tif (sshbuf_len(subsect) > 0) {\n\t\t\terror(\"KRL certificate section contains unparsed data\");\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tr = 0;\n out:\n\tif (bitmap != NULL)\n\t\tbitmap_free(bitmap);\n\tfree(key_id);\n\tsshkey_free(ca_key);\n\tsshbuf_free(subsect);\n\treturn r;\n}\n\n\n/* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */\nint\nssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,\n const struct sshkey **sign_ca_keys, size_t nsign_ca_keys)\n{\n\tstruct sshbuf *copy = NULL, *sect = NULL;\n\tstruct ssh_krl *krl = NULL;\n\tchar timestamp[64];\n\tint r = SSH_ERR_INTERNAL_ERROR, sig_seen;\n\tstruct sshkey *key = NULL, **ca_used = NULL, **tmp_ca_used;\n\tu_char type, *rdata = NULL;\n\tconst u_char *blob;\n\tsize_t i, j, sig_off, sects_off, rlen, blen, nca_used;\n\tu_int format_version;\n\n\tnca_used = 0;\n\t*krlp = NULL;\n\tif (sshbuf_len(buf) < sizeof(KRL_MAGIC) - 1 ||\n\t memcmp(sshbuf_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) {\n\t\tdebug3(\"%s: not a KRL\", __func__);\n\t\treturn SSH_ERR_KRL_BAD_MAGIC;\n\t}\n\n\t/* Take a copy of the KRL buffer so we can verify its signature later */\n\tif ((copy = sshbuf_fromb(buf)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_consume(copy, sizeof(KRL_MAGIC) - 1)) != 0)\n\t\tgoto out;\n\n\tif ((krl = ssh_krl_init()) == NULL) {\n\t\terror(\"%s: alloc failed\", __func__);\n\t\tgoto out;\n\t}\n\n\tif ((r = sshbuf_get_u32(copy, &format_version)) != 0)\n\t\tgoto out;\n\tif (format_version != KRL_FORMAT_VERSION) {\n\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_get_u64(copy, &krl->krl_version)) != 0 ||\n\t (r = sshbuf_get_u64(copy, &krl->generated_date)) != 0 ||\n\t (r = sshbuf_get_u64(copy, &krl->flags)) != 0 ||\n\t (r = sshbuf_skip_string(copy)) != 0 ||\n\t (r = sshbuf_get_cstring(copy, &krl->comment, NULL)) != 0)\n\t\tgoto out;\n\n\tformat_timestamp(krl->generated_date, timestamp, sizeof(timestamp));\n\tdebug(\"KRL version %llu generated at %s%s%s\",\n\t (long long unsigned)krl->krl_version, timestamp,\n\t *krl->comment ? \": \" : \"\", krl->comment);\n\n\t/*\n\t * 1st pass: verify signatures, if any. This is done to avoid\n\t * detailed parsing of data whose provenance is unverified.\n\t */\n\tsig_seen = 0;\n\tif (sshbuf_len(buf) < sshbuf_len(copy)) {\n\t\t/* Shouldn't happen */\n\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\tgoto out;\n\t}\n\tsects_off = sshbuf_len(buf) - sshbuf_len(copy);\n\twhile (sshbuf_len(copy) > 0) {\n\t\tif ((r = sshbuf_get_u8(copy, &type)) != 0 ||\n\t\t (r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0)\n\t\t\tgoto out;\n\t\tKRL_DBG((\"%s: first pass, section 0x%02x\", __func__, type));\n\t\tif (type != KRL_SECTION_SIGNATURE) {\n\t\t\tif (sig_seen) {\n\t\t\t\terror(\"KRL contains non-signature section \"\n\t\t\t\t \"after signature\");\n\t\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\t/* Not interested for now. */\n\t\t\tcontinue;\n\t\t}\n\t\tsig_seen = 1;\n\t\t/* First string component is the signing key */\n\t\tif ((r = sshkey_from_blob(blob, blen, &key)) != 0) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tif (sshbuf_len(buf) < sshbuf_len(copy)) {\n\t\t\t/* Shouldn't happen */\n\t\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\t\tgoto out;\n\t\t}\n\t\tsig_off = sshbuf_len(buf) - sshbuf_len(copy);\n\t\t/* Second string component is the signature itself */\n\t\tif ((r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0) {\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\t/* Check signature over entire KRL up to this point */\n\t\tif ((r = sshkey_verify(key, blob, blen,\n\t\t sshbuf_ptr(buf), sig_off, 0)) != 0)\n\t\t\tgoto out;\n\t\t/* Check if this key has already signed this KRL */\n\t\tfor (i = 0; i < nca_used; i++) {\n\t\t\tif (sshkey_equal(ca_used[i], key)) {\n\t\t\t\terror(\"KRL signed more than once with \"\n\t\t\t\t \"the same key\");\n\t\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t}\n\t\t/* Record keys used to sign the KRL */\n\t\ttmp_ca_used = reallocarray(ca_used, nca_used + 1,\n\t\t sizeof(*ca_used));\n\t\tif (tmp_ca_used == NULL) {\n\t\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tca_used = tmp_ca_used;\n\t\tca_used[nca_used++] = key;\n\t\tkey = NULL;\n\t}\n\n\tif (sshbuf_len(copy) != 0) {\n\t\t/* Shouldn't happen */\n\t\tr = SSH_ERR_INTERNAL_ERROR;\n\t\tgoto out;\n\t}\n\n\t/*\n\t * 2nd pass: parse and load the KRL, skipping the header to the point\n\t * where the section start.\n\t */\n\tsshbuf_free(copy);\n\tif ((copy = sshbuf_fromb(buf)) == NULL) {\n\t\tr = SSH_ERR_ALLOC_FAIL;\n\t\tgoto out;\n\t}\n\tif ((r = sshbuf_consume(copy, sects_off)) != 0)\n\t\tgoto out;\n\twhile (sshbuf_len(copy) > 0) {\n\t\tsshbuf_free(sect);\n\t\tsect = NULL;\n\t\tif ((r = sshbuf_get_u8(copy, &type)) != 0 ||\n\t\t (r = sshbuf_froms(copy, §)) != 0)\n\t\t\tgoto out;\n\t\tKRL_DBG((\"%s: second pass, section 0x%02x\", __func__, type));\n\n\t\tswitch (type) {\n\t\tcase KRL_SECTION_CERTIFICATES:\n\t\t\tif ((r = parse_revoked_certs(sect, krl)) != 0)\n\t\t\t\tgoto out;\n\t\t\tbreak;\n\t\tcase KRL_SECTION_EXPLICIT_KEY:\n\t\tcase KRL_SECTION_FINGERPRINT_SHA1:\n\t\t\twhile (sshbuf_len(sect) > 0) {\n\t\t\t\tif ((r = sshbuf_get_string(sect,\n\t\t\t\t &rdata, &rlen)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\tif (type == KRL_SECTION_FINGERPRINT_SHA1 &&\n\t\t\t\t rlen != 20) {\n\t\t\t\t\terror(\"%s: bad SHA1 length\", __func__);\n\t\t\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\t\t\tgoto out;\n\t\t\t\t}\n\t\t\t\tif ((r = revoke_blob(\n\t\t\t\t type == KRL_SECTION_EXPLICIT_KEY ?\n\t\t\t\t &krl->revoked_keys : &krl->revoked_sha1s,\n\t\t\t\t rdata, rlen)) != 0)\n\t\t\t\t\tgoto out;\n\t\t\t\trdata = NULL; /* revoke_blob frees rdata */\n\t\t\t}\n\t\t\tbreak;\n\t\tcase KRL_SECTION_SIGNATURE:\n\t\t\t/* Handled above, but still need to stay in synch */\n\t\t\tsshbuf_free(sect);\n\t\t\tsect = NULL;\n\t\t\tif ((r = sshbuf_skip_string(copy)) != 0)\n\t\t\t\tgoto out;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\terror(\"Unsupported KRL section %u\", type);\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t\tif (sect != NULL && sshbuf_len(sect) > 0) {\n\t\t\terror(\"KRL section contains unparsed data\");\n\t\t\tr = SSH_ERR_INVALID_FORMAT;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\t/* Check that the key(s) used to sign the KRL weren't revoked */\n\tsig_seen = 0;\n\tfor (i = 0; i < nca_used; i++) {\n\t\tif (ssh_krl_check_key(krl, ca_used[i]) == 0)\n\t\t\tsig_seen = 1;\n\t\telse {\n\t\t\tsshkey_free(ca_used[i]);\n\t\t\tca_used[i] = NULL;\n\t\t}\n\t}\n\tif (nca_used && !sig_seen) {\n\t\terror(\"All keys used to sign KRL were revoked\");\n\t\tr = SSH_ERR_KEY_REVOKED;\n\t\tgoto out;\n\t}\n\n\t/* If we have CA keys, then verify that one was used to sign the KRL */\n\tif (sig_seen && nsign_ca_keys != 0) {\n\t\tsig_seen = 0;\n\t\tfor (i = 0; !sig_seen && i < nsign_ca_keys; i++) {\n\t\t\tfor (j = 0; j < nca_used; j++) {\n\t\t\t\tif (ca_used[j] == NULL)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (sshkey_equal(ca_used[j], sign_ca_keys[i])) {\n\t\t\t\t\tsig_seen = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!sig_seen) {\n\t\t\tr = SSH_ERR_SIGNATURE_INVALID;\n\t\t\terror(\"KRL not signed with any trusted key\");\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\t*krlp = krl;\n\tr = 0;\n out:\n\tif (r != 0)\n\t\tssh_krl_free(krl);\n\tfor (i = 0; i < nca_used; i++)\n\t\tsshkey_free(ca_used[i]);\n\tfree(ca_used);\n\tfree(rdata);\n\tsshkey_free(key);\n\tsshbuf_free(copy);\n\tsshbuf_free(sect);\n\treturn r;\n}\n\n/* Checks certificate serial number and key ID revocation */\nstatic int\nis_cert_revoked(const struct sshkey *key, struct revoked_certs *rc)\n{\n\tstruct revoked_serial rs, *ers;\n\tstruct revoked_key_id rki, *erki;\n\n\t/* Check revocation by cert key ID */\n\tmemset(&rki, 0, sizeof(rki));\n\trki.key_id = key->cert->key_id;\n\terki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki);\n\tif (erki != NULL) {\n\t\tKRL_DBG((\"%s: revoked by key ID\", __func__));\n\t\treturn SSH_ERR_KEY_REVOKED;\n\t}\n\n\t/*\n\t * Zero serials numbers are ignored (it's the default when the\n\t * CA doesn't specify one).\n\t */\n\tif (key->cert->serial == 0)\n\t\treturn 0;\n\n\tmemset(&rs, 0, sizeof(rs));\n\trs.lo = rs.hi = key->cert->serial;\n\ters = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs);\n\tif (ers != NULL) {\n\t\tKRL_DBG((\"%s: revoked serial %llu matched %llu:%llu\", __func__,\n\t\t key->cert->serial, ers->lo, ers->hi));\n\t\treturn SSH_ERR_KEY_REVOKED;\n\t}\n\treturn 0;\n}\n\n/* Checks whether a given key/cert is revoked. Does not check its CA */\nstatic int\nis_key_revoked(struct ssh_krl *krl, const struct sshkey *key)\n{\n\tstruct revoked_blob rb, *erb;\n\tstruct revoked_certs *rc;\n\tint r;\n\n\t/* Check explicitly revoked hashes first */\n\tmemset(&rb, 0, sizeof(rb));\n\tif ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1,\n\t &rb.blob, &rb.len)) != 0)\n\t\treturn r;\n\terb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb);\n\tfree(rb.blob);\n\tif (erb != NULL) {\n\t\tKRL_DBG((\"%s: revoked by key SHA1\", __func__));\n\t\treturn SSH_ERR_KEY_REVOKED;\n\t}\n\n\t/* Next, explicit keys */\n\tmemset(&rb, 0, sizeof(rb));\n\tif ((r = plain_key_blob(key, &rb.blob, &rb.len)) != 0)\n\t\treturn r;\n\terb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb);\n\tfree(rb.blob);\n\tif (erb != NULL) {\n\t\tKRL_DBG((\"%s: revoked by explicit key\", __func__));\n\t\treturn SSH_ERR_KEY_REVOKED;\n\t}\n\n\tif (!sshkey_is_cert(key))\n\t\treturn 0;\n\n\t/* Check cert revocation for the specified CA */\n\tif ((r = revoked_certs_for_ca_key(krl, key->cert->signature_key,\n\t &rc, 0)) != 0)\n\t\treturn r;\n\tif (rc != NULL) {\n\t\tif ((r = is_cert_revoked(key, rc)) != 0)\n\t\t\treturn r;\n\t}\n\t/* Check cert revocation for the wildcard CA */\n\tif ((r = revoked_certs_for_ca_key(krl, NULL, &rc, 0)) != 0)\n\t\treturn r;\n\tif (rc != NULL) {\n\t\tif ((r = is_cert_revoked(key, rc)) != 0)\n\t\t\treturn r;\n\t}\n\n\tKRL_DBG((\"%s: %llu no match\", __func__, key->cert->serial));\n\treturn 0;\n}\n\nint\nssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key)\n{\n\tint r;\n\n\tKRL_DBG((\"%s: checking key\", __func__));\n\tif ((r = is_key_revoked(krl, key)) != 0)\n\t\treturn r;\n\tif (sshkey_is_cert(key)) {\n\t\tdebug2(\"%s: checking CA key\", __func__);\n\t\tif ((r = is_key_revoked(krl, key->cert->signature_key)) != 0)\n\t\t\treturn r;\n\t}\n\tKRL_DBG((\"%s: key okay\", __func__));\n\treturn 0;\n}\n\nint\nssh_krl_file_contains_key(const char *path, const struct sshkey *key)\n{\n\tstruct sshbuf *krlbuf = NULL;\n\tstruct ssh_krl *krl = NULL;\n\tint oerrno = 0, r, fd;\n\n\tif (path == NULL)\n\t\treturn 0;\n\n\tif ((krlbuf = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((fd = open(path, O_RDONLY)) == -1) {\n\t\tr = SSH_ERR_SYSTEM_ERROR;\n\t\toerrno = errno;\n\t\tgoto out;\n\t}\n\tif ((r = sshkey_load_file(fd, krlbuf)) != 0) {\n\t\toerrno = errno;\n\t\tgoto out;\n\t}\n\tif ((r = ssh_krl_from_blob(krlbuf, &krl, NULL, 0)) != 0)\n\t\tgoto out;\n\tdebug2(\"%s: checking KRL %s\", __func__, path);\n\tr = ssh_krl_check_key(krl, key);\n out:\n\tif (fd != -1)\n\t\tclose(fd);\n\tsshbuf_free(krlbuf);\n\tssh_krl_free(krl);\n\tif (r != 0)\n\t\terrno = oerrno;\n\treturn r;\n}\n","/*\n * Copyright (c) 2015 Damien Miller \n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n\n#include \"bitmap.h\"\n\n#define BITMAP_WTYPE\tu_int\n#define BITMAP_MAX\t(1<<24)\n#define BITMAP_BYTES\t(sizeof(BITMAP_WTYPE))\n#define BITMAP_BITS\t(sizeof(BITMAP_WTYPE) * 8)\n#define BITMAP_WMASK\t((BITMAP_WTYPE)BITMAP_BITS - 1)\nstruct bitmap {\n\tBITMAP_WTYPE *d;\n\tsize_t len; /* number of words allocated */\n\tsize_t top; /* index of top word allocated */\n};\n\nstruct bitmap *\nbitmap_new(void)\n{\n\tstruct bitmap *ret;\n\n\tif ((ret = calloc(1, sizeof(*ret))) == NULL)\n\t\treturn NULL;\n\tif ((ret->d = calloc(1, BITMAP_BYTES)) == NULL) {\n\t\tfree(ret);\n\t\treturn NULL;\n\t}\n\tret->len = 1;\n\tret->top = 0;\n\treturn ret;\n}\n\nvoid\nbitmap_free(struct bitmap *b)\n{\n\tif (b != NULL && b->d != NULL) {\n\t\texplicit_bzero(b->d, b->len);\n\t\tfree(b->d);\n\t}\n\tfree(b);\n}\n\nvoid\nbitmap_zero(struct bitmap *b)\n{\n\tmemset(b->d, 0, b->len * BITMAP_BYTES);\n\tb->top = 0;\n}\n\nint\nbitmap_test_bit(struct bitmap *b, u_int n)\n{\n\tif (b->top >= b->len)\n\t\treturn 0; /* invalid */\n\tif (b->len == 0 || (n / BITMAP_BITS) > b->top)\n\t\treturn 0;\n\treturn (b->d[n / BITMAP_BITS] >> (n & BITMAP_WMASK)) & 1;\n}\n\nstatic int\nreserve(struct bitmap *b, u_int n)\n{\n\tBITMAP_WTYPE *tmp;\n\tsize_t nlen;\n\n\tif (b->top >= b->len || n > BITMAP_MAX)\n\t\treturn -1; /* invalid */\n\tnlen = (n / BITMAP_BITS) + 1;\n\tif (b->len < nlen) {\n\t\tif ((tmp = reallocarray(b->d, nlen, BITMAP_BYTES)) == NULL)\n\t\t\treturn -1;\n\t\tb->d = tmp;\n\t\tmemset(b->d + b->len, 0, (nlen - b->len) * BITMAP_BYTES);\n\t\tb->len = nlen;\n\t}\n\treturn 0;\n}\n\nint\nbitmap_set_bit(struct bitmap *b, u_int n)\n{\n\tint r;\n\tsize_t offset;\n\n\tif ((r = reserve(b, n)) != 0)\n\t\treturn r;\n\toffset = n / BITMAP_BITS;\n\tif (offset > b->top)\n\t\tb->top = offset;\n\tb->d[offset] |= (BITMAP_WTYPE)1 << (n & BITMAP_WMASK);\n\treturn 0;\n}\n\n/* Resets b->top to point to the most significant bit set in b->d */\nstatic void\nretop(struct bitmap *b)\n{\n\tif (b->top >= b->len)\n\t\treturn;\n\twhile (b->top > 0 && b->d[b->top] == 0)\n\t\tb->top--;\n}\n\nvoid\nbitmap_clear_bit(struct bitmap *b, u_int n)\n{\n\tsize_t offset;\n\n\tif (b->top >= b->len || n > BITMAP_MAX)\n\t\treturn; /* invalid */\n\toffset = n / BITMAP_BITS;\n\tif (offset > b->top)\n\t\treturn;\n\tb->d[offset] &= ~((BITMAP_WTYPE)1 << (n & BITMAP_WMASK));\n\t/* The top may have changed as a result of the clear */\n\tretop(b);\n}\n\nsize_t\nbitmap_nbits(struct bitmap *b)\n{\n\tsize_t bits;\n\tBITMAP_WTYPE w;\n\n\tretop(b);\n\tif (b->top >= b->len)\n\t\treturn 0; /* invalid */\n\tif (b->len == 0 || (b->top == 0 && b->d[0] == 0))\n\t\treturn 0;\n\t/* Find MSB set */\n\tw = b->d[b->top];\n\tbits = (b->top + 1) * BITMAP_BITS;\n\twhile (!(w & ((BITMAP_WTYPE)1 << (BITMAP_BITS - 1)))) {\n\t\tw <<= 1;\n\t\tbits--;\n\t}\n\treturn bits;\n}\n\nsize_t\nbitmap_nbytes(struct bitmap *b)\n{\n\treturn (bitmap_nbits(b) + 7) / 8;\n}\n\nint\nbitmap_to_string(struct bitmap *b, void *p, size_t l)\n{\n\tu_char *s = (u_char *)p;\n\tsize_t i, j, k, need = bitmap_nbytes(b);\n\n\tif (l < need || b->top >= b->len)\n\t\treturn -1;\n\tif (l > need)\n\t\tl = need;\n\t/* Put the bytes from LSB backwards */\n\tfor (i = k = 0; i < b->top + 1; i++) {\n\t\tfor (j = 0; j < BITMAP_BYTES; j++) {\n\t\t\tif (k >= l)\n\t\t\t\tbreak;\n\t\t\ts[need - 1 - k++] = (b->d[i] >> (j * 8)) & 0xff;\n\t\t}\n\t}\n\treturn 0;\n}\n\nint\nbitmap_from_string(struct bitmap *b, const void *p, size_t l)\n{\n\tint r;\n\tsize_t i, offset, shift;\n\tu_char *s = (u_char *)p;\n\n\tif (l > BITMAP_MAX / 8)\n\t\treturn -1;\n\tif ((r = reserve(b, l * 8)) != 0)\n\t\treturn r;\n\tbitmap_zero(b);\n\tif (l == 0)\n\t\treturn 0;\n\tb->top = offset = ((l + (BITMAP_BYTES - 1)) / BITMAP_BYTES) - 1;\n\tshift = ((l + (BITMAP_BYTES - 1)) % BITMAP_BYTES) * 8;\n\tfor (i = 0; i < l; i++) {\n\t\tb->d[offset] |= (BITMAP_WTYPE)s[i] << shift;\n\t\tif (shift == 0) {\n\t\t\toffset--;\n\t\t\tshift = BITMAP_BITS - 8;\n\t\t} else\n\t\t\tshift -= 8;\n\t}\n\tretop(b);\n\treturn 0;\n}\n","/* $OpenBSD: crc32.c,v 1.11 2006/04/22 18:29:33 stevesk Exp $ */\n\n/*\n * Copyright (c) 2003 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#include \"includes.h\"\n#include \"crc32.h\"\n\nstatic const u_int32_t crc32tab[] = {\n\t0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,\n\t0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,\n\t0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,\n\t0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,\n\t0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,\n\t0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,\n\t0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,\n\t0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,\n\t0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,\n\t0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,\n\t0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,\n\t0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,\n\t0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,\n\t0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,\n\t0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,\n\t0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,\n\t0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,\n\t0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,\n\t0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,\n\t0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,\n\t0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,\n\t0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,\n\t0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,\n\t0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,\n\t0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,\n\t0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,\n\t0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,\n\t0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,\n\t0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,\n\t0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,\n\t0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,\n\t0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,\n\t0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,\n\t0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,\n\t0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,\n\t0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,\n\t0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,\n\t0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,\n\t0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,\n\t0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,\n\t0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,\n\t0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,\n\t0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,\n\t0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,\n\t0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,\n\t0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,\n\t0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,\n\t0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,\n\t0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,\n\t0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,\n\t0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,\n\t0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,\n\t0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,\n\t0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,\n\t0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,\n\t0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,\n\t0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,\n\t0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,\n\t0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,\n\t0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,\n\t0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,\n\t0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,\n\t0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,\n\t0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL\n};\n\nu_int32_t\nssh_crc32(const u_char *buf, u_int32_t size)\n{\n\tu_int32_t i, crc;\n\n\tcrc = 0;\n\tfor (i = 0; i < size; i++)\n\t\tcrc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);\n\treturn crc;\n}\n","/* $OpenBSD: deattack.c,v 1.32 2015/01/20 23:14:00 deraadt Exp $ */\n/*\n * Cryptographic attack detector for ssh - source code\n *\n * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.\n *\n * All rights reserved. Redistribution and use in source and binary\n * forms, with or without modification, are permitted provided that\n * this copyright notice is retained.\n *\n * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED\n * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR\n * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS\n * SOFTWARE.\n *\n * Ariel Futoransky \n * \n */\n\n#include \"includes.h\"\n\n#include \n#include \n#include \n\n#include \"deattack.h\"\n#include \"crc32.h\"\n#include \"sshbuf.h\"\n#include \"misc.h\"\n\n/*\n * CRC attack detection has a worst-case behaviour that is O(N^3) over\n * the number of identical blocks in a packet. This behaviour can be \n * exploited to create a limited denial of service attack. \n * \n * However, because we are dealing with encrypted data, identical\n * blocks should only occur every 2^35 maximally-sized packets or so. \n * Consequently, we can detect this DoS by looking for identical blocks\n * in a packet.\n *\n * The parameter below determines how many identical blocks we will\n * accept in a single packet, trading off between attack detection and\n * likelihood of terminating a legitimate connection. A value of 32 \n * corresponds to an average of 2^40 messages before an attack is\n * misdetected\n */\n#define MAX_IDENTICAL\t32\n\n/* SSH Constants */\n#define SSH_MAXBLOCKS\t(32 * 1024)\n#define SSH_BLOCKSIZE\t(8)\n\n/* Hashing constants */\n#define HASH_MINSIZE\t(8 * 1024)\n#define HASH_ENTRYSIZE\t(2)\n#define HASH_FACTOR(x)\t((x)*3/2)\n#define HASH_UNUSEDCHAR\t(0xff)\n#define HASH_UNUSED\t(0xffff)\n#define HASH_IV\t\t(0xfffe)\n\n#define HASH_MINBLOCKS\t(7*SSH_BLOCKSIZE)\n\n\n/* Hash function (Input keys are cipher results) */\n#define HASH(x)\t\tPEEK_U32(x)\n\n#define CMP(a, b)\t(memcmp(a, b, SSH_BLOCKSIZE))\n\nstatic void\ncrc_update(u_int32_t *a, u_int32_t b)\n{\n\tb ^= *a;\n\t*a = ssh_crc32((u_char *)&b, sizeof(b));\n}\n\n/* detect if a block is used in a particular pattern */\nstatic int\ncheck_crc(const u_char *S, const u_char *buf, u_int32_t len)\n{\n\tu_int32_t crc;\n\tconst u_char *c;\n\n\tcrc = 0;\n\tfor (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {\n\t\tif (!CMP(S, c)) {\n\t\t\tcrc_update(&crc, 1);\n\t\t\tcrc_update(&crc, 0);\n\t\t} else {\n\t\t\tcrc_update(&crc, 0);\n\t\t\tcrc_update(&crc, 0);\n\t\t}\n\t}\n\treturn crc == 0;\n}\n\nvoid\ndeattack_init(struct deattack_ctx *dctx)\n{\n\tbzero(dctx, sizeof(*dctx));\n\tdctx->n = HASH_MINSIZE / HASH_ENTRYSIZE;\n}\n\n/* Detect a crc32 compensation attack on a packet */\nint\ndetect_attack(struct deattack_ctx *dctx, const u_char *buf, u_int32_t len)\n{\n\tu_int32_t i, j, l, same;\n\tu_int16_t *tmp;\n\tconst u_char *c, *d;\n\n\tif (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||\n\t len % SSH_BLOCKSIZE != 0)\n\t\treturn DEATTACK_ERROR;\n\tfor (l = dctx->n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)\n\t\t;\n\n\tif (dctx->h == NULL) {\n\t\tif ((dctx->h = calloc(l, HASH_ENTRYSIZE)) == NULL)\n\t\t\treturn DEATTACK_ERROR;\n\t\tdctx->n = l;\n\t} else {\n\t\tif (l > dctx->n) {\n\t\t\tif ((tmp = reallocarray(dctx->h, l, HASH_ENTRYSIZE))\n\t\t\t == NULL) {\n\t\t\t\tfree(dctx->h);\n\t\t\t\tdctx->h = NULL;\n\t\t\t\treturn DEATTACK_ERROR;\n\t\t\t}\n\t\t\tdctx->h = tmp;\n\t\t\tdctx->n = l;\n\t\t}\n\t}\n\n\tif (len <= HASH_MINBLOCKS) {\n\t\tfor (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {\n\t\t\tfor (d = buf; d < c; d += SSH_BLOCKSIZE) {\n\t\t\t\tif (!CMP(c, d)) {\n\t\t\t\t\tif ((check_crc(c, buf, len)))\n\t\t\t\t\t\treturn DEATTACK_DETECTED;\n\t\t\t\t\telse\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn DEATTACK_OK;\n\t}\n\tmemset(dctx->h, HASH_UNUSEDCHAR, dctx->n * HASH_ENTRYSIZE);\n\n\tfor (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {\n\t\tfor (i = HASH(c) & (dctx->n - 1); dctx->h[i] != HASH_UNUSED;\n\t\t i = (i + 1) & (dctx->n - 1)) {\n\t\t\tif (!CMP(c, buf + dctx->h[i] * SSH_BLOCKSIZE)) {\n\t\t\t\tif (++same > MAX_IDENTICAL)\n\t\t\t\t\treturn DEATTACK_DOS_DETECTED;\n\t\t\t\tif (check_crc(c, buf, len))\n\t\t\t\t\treturn DEATTACK_DETECTED;\n\t\t\t\telse\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tdctx->h[i] = j;\n\t}\n\treturn DEATTACK_OK;\n}\n","/* \n * Public Domain poly1305 from Andrew Moon\n * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna\n */\n\n/* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */\n\n#include \"includes.h\"\n\n#include \n#ifdef HAVE_STDINT_H\n# include \n#endif\n\n#include \"poly1305.h\"\n\n#define mul32x32_64(a,b) ((uint64_t)(a) * (b))\n\n#define U8TO32_LE(p) \\\n\t(((uint32_t)((p)[0])) | \\\n\t ((uint32_t)((p)[1]) << 8) | \\\n\t ((uint32_t)((p)[2]) << 16) | \\\n\t ((uint32_t)((p)[3]) << 24))\n\n#define U32TO8_LE(p, v) \\\n\tdo { \\\n\t\t(p)[0] = (uint8_t)((v)); \\\n\t\t(p)[1] = (uint8_t)((v) >> 8); \\\n\t\t(p)[2] = (uint8_t)((v) >> 16); \\\n\t\t(p)[3] = (uint8_t)((v) >> 24); \\\n\t} while (0)\n\nvoid\npoly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {\n\tuint32_t t0,t1,t2,t3;\n\tuint32_t h0,h1,h2,h3,h4;\n\tuint32_t r0,r1,r2,r3,r4;\n\tuint32_t s1,s2,s3,s4;\n\tuint32_t b, nb;\n\tsize_t j;\n\tuint64_t t[5];\n\tuint64_t f0,f1,f2,f3;\n\tuint32_t g0,g1,g2,g3,g4;\n\tuint64_t c;\n\tunsigned char mp[16];\n\n\t/* clamp key */\n\tt0 = U8TO32_LE(key+0);\n\tt1 = U8TO32_LE(key+4);\n\tt2 = U8TO32_LE(key+8);\n\tt3 = U8TO32_LE(key+12);\n\n\t/* precompute multipliers */\n\tr0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;\n\tr1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;\n\tr2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;\n\tr3 = t2 & 0x3f03fff; t3 >>= 8;\n\tr4 = t3 & 0x00fffff;\n\n\ts1 = r1 * 5;\n\ts2 = r2 * 5;\n\ts3 = r3 * 5;\n\ts4 = r4 * 5;\n\n\t/* init state */\n\th0 = 0;\n\th1 = 0;\n\th2 = 0;\n\th3 = 0;\n\th4 = 0;\n\n\t/* full blocks */\n\tif (inlen < 16) goto poly1305_donna_atmost15bytes;\npoly1305_donna_16bytes:\n\tm += 16;\n\tinlen -= 16;\n\n\tt0 = U8TO32_LE(m-16);\n\tt1 = U8TO32_LE(m-12);\n\tt2 = U8TO32_LE(m-8);\n\tt3 = U8TO32_LE(m-4);\n\n\th0 += t0 & 0x3ffffff;\n\th1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;\n\th2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;\n\th3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;\n\th4 += (t3 >> 8) | (1 << 24);\n\n\npoly1305_donna_mul:\n\tt[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1);\n\tt[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2);\n\tt[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3);\n\tt[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4);\n\tt[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0);\n\n\t h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26);\n\tt[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);\n\tt[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);\n\tt[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);\n\tt[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);\n\th0 += b * 5;\n\n\tif (inlen >= 16) goto poly1305_donna_16bytes;\n\n\t/* final bytes */\npoly1305_donna_atmost15bytes:\n\tif (!inlen) goto poly1305_donna_finish;\n\n\tfor (j = 0; j < inlen; j++) mp[j] = m[j];\n\tmp[j++] = 1;\n\tfor (; j < 16; j++)\tmp[j] = 0;\n\tinlen = 0;\n\n\tt0 = U8TO32_LE(mp+0);\n\tt1 = U8TO32_LE(mp+4);\n\tt2 = U8TO32_LE(mp+8);\n\tt3 = U8TO32_LE(mp+12);\n\n\th0 += t0 & 0x3ffffff;\n\th1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;\n\th2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;\n\th3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;\n\th4 += (t3 >> 8);\n\n\tgoto poly1305_donna_mul;\n\npoly1305_donna_finish:\n\t b = h0 >> 26; h0 = h0 & 0x3ffffff;\n\th1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;\n\th2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;\n\th3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;\n\th4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;\n\th0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;\n\th1 += b;\n\n\tg0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;\n\tg1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;\n\tg2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;\n\tg3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;\n\tg4 = h4 + b - (1 << 26);\n\n\tb = (g4 >> 31) - 1;\n\tnb = ~b;\n\th0 = (h0 & nb) | (g0 & b);\n\th1 = (h1 & nb) | (g1 & b);\n\th2 = (h2 & nb) | (g2 & b);\n\th3 = (h3 & nb) | (g3 & b);\n\th4 = (h4 & nb) | (g4 & b);\n\n\tf0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);\n\tf1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);\n\tf2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);\n\tf3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]);\n\n\tU32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);\n\tU32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);\n\tU32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);\n\tU32TO8_LE(&out[12], f3);\n}\n","/*\nchacha-merged.c version 20080118\nD. J. Bernstein\nPublic domain.\n*/\n\n#include \"includes.h\"\n\n#include \"chacha.h\"\n\n/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */\n\ntypedef unsigned char u8;\ntypedef unsigned int u32;\n\ntypedef struct chacha_ctx chacha_ctx;\n\n#define U8C(v) (v##U)\n#define U32C(v) (v##U)\n\n#define U8V(v) ((u8)(v) & U8C(0xFF))\n#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))\n\n#define ROTL32(v, n) \\\n (U32V((v) << (n)) | ((v) >> (32 - (n))))\n\n#define U8TO32_LITTLE(p) \\\n (((u32)((p)[0]) ) | \\\n ((u32)((p)[1]) << 8) | \\\n ((u32)((p)[2]) << 16) | \\\n ((u32)((p)[3]) << 24))\n\n#define U32TO8_LITTLE(p, v) \\\n do { \\\n (p)[0] = U8V((v) ); \\\n (p)[1] = U8V((v) >> 8); \\\n (p)[2] = U8V((v) >> 16); \\\n (p)[3] = U8V((v) >> 24); \\\n } while (0)\n\n#define ROTATE(v,c) (ROTL32(v,c))\n#define XOR(v,w) ((v) ^ (w))\n#define PLUS(v,w) (U32V((v) + (w)))\n#define PLUSONE(v) (PLUS((v),1))\n\n#define QUARTERROUND(a,b,c,d) \\\n a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \\\n c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \\\n a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \\\n c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);\n\nstatic const char sigma[16] = \"expand 32-byte k\";\nstatic const char tau[16] = \"expand 16-byte k\";\n\nvoid\nchacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)\n{\n const char *constants;\n\n x->input[4] = U8TO32_LITTLE(k + 0);\n x->input[5] = U8TO32_LITTLE(k + 4);\n x->input[6] = U8TO32_LITTLE(k + 8);\n x->input[7] = U8TO32_LITTLE(k + 12);\n if (kbits == 256) { /* recommended */\n k += 16;\n constants = sigma;\n } else { /* kbits == 128 */\n constants = tau;\n }\n x->input[8] = U8TO32_LITTLE(k + 0);\n x->input[9] = U8TO32_LITTLE(k + 4);\n x->input[10] = U8TO32_LITTLE(k + 8);\n x->input[11] = U8TO32_LITTLE(k + 12);\n x->input[0] = U8TO32_LITTLE(constants + 0);\n x->input[1] = U8TO32_LITTLE(constants + 4);\n x->input[2] = U8TO32_LITTLE(constants + 8);\n x->input[3] = U8TO32_LITTLE(constants + 12);\n}\n\nvoid\nchacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)\n{\n x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);\n x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);\n x->input[14] = U8TO32_LITTLE(iv + 0);\n x->input[15] = U8TO32_LITTLE(iv + 4);\n}\n\nvoid\nchacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)\n{\n u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;\n u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;\n u8 *ctarget = NULL;\n u8 tmp[64];\n u_int i;\n\n if (!bytes) return;\n\n j0 = x->input[0];\n j1 = x->input[1];\n j2 = x->input[2];\n j3 = x->input[3];\n j4 = x->input[4];\n j5 = x->input[5];\n j6 = x->input[6];\n j7 = x->input[7];\n j8 = x->input[8];\n j9 = x->input[9];\n j10 = x->input[10];\n j11 = x->input[11];\n j12 = x->input[12];\n j13 = x->input[13];\n j14 = x->input[14];\n j15 = x->input[15];\n\n for (;;) {\n if (bytes < 64) {\n for (i = 0;i < bytes;++i) tmp[i] = m[i];\n m = tmp;\n ctarget = c;\n c = tmp;\n }\n x0 = j0;\n x1 = j1;\n x2 = j2;\n x3 = j3;\n x4 = j4;\n x5 = j5;\n x6 = j6;\n x7 = j7;\n x8 = j8;\n x9 = j9;\n x10 = j10;\n x11 = j11;\n x12 = j12;\n x13 = j13;\n x14 = j14;\n x15 = j15;\n for (i = 20;i > 0;i -= 2) {\n QUARTERROUND( x0, x4, x8,x12)\n QUARTERROUND( x1, x5, x9,x13)\n QUARTERROUND( x2, x6,x10,x14)\n QUARTERROUND( x3, x7,x11,x15)\n QUARTERROUND( x0, x5,x10,x15)\n QUARTERROUND( x1, x6,x11,x12)\n QUARTERROUND( x2, x7, x8,x13)\n QUARTERROUND( x3, x4, x9,x14)\n }\n x0 = PLUS(x0,j0);\n x1 = PLUS(x1,j1);\n x2 = PLUS(x2,j2);\n x3 = PLUS(x3,j3);\n x4 = PLUS(x4,j4);\n x5 = PLUS(x5,j5);\n x6 = PLUS(x6,j6);\n x7 = PLUS(x7,j7);\n x8 = PLUS(x8,j8);\n x9 = PLUS(x9,j9);\n x10 = PLUS(x10,j10);\n x11 = PLUS(x11,j11);\n x12 = PLUS(x12,j12);\n x13 = PLUS(x13,j13);\n x14 = PLUS(x14,j14);\n x15 = PLUS(x15,j15);\n\n x0 = XOR(x0,U8TO32_LITTLE(m + 0));\n x1 = XOR(x1,U8TO32_LITTLE(m + 4));\n x2 = XOR(x2,U8TO32_LITTLE(m + 8));\n x3 = XOR(x3,U8TO32_LITTLE(m + 12));\n x4 = XOR(x4,U8TO32_LITTLE(m + 16));\n x5 = XOR(x5,U8TO32_LITTLE(m + 20));\n x6 = XOR(x6,U8TO32_LITTLE(m + 24));\n x7 = XOR(x7,U8TO32_LITTLE(m + 28));\n x8 = XOR(x8,U8TO32_LITTLE(m + 32));\n x9 = XOR(x9,U8TO32_LITTLE(m + 36));\n x10 = XOR(x10,U8TO32_LITTLE(m + 40));\n x11 = XOR(x11,U8TO32_LITTLE(m + 44));\n x12 = XOR(x12,U8TO32_LITTLE(m + 48));\n x13 = XOR(x13,U8TO32_LITTLE(m + 52));\n x14 = XOR(x14,U8TO32_LITTLE(m + 56));\n x15 = XOR(x15,U8TO32_LITTLE(m + 60));\n\n j12 = PLUSONE(j12);\n if (!j12) {\n j13 = PLUSONE(j13);\n /* stopping at 2^70 bytes per nonce is user's responsibility */\n }\n\n U32TO8_LITTLE(c + 0,x0);\n U32TO8_LITTLE(c + 4,x1);\n U32TO8_LITTLE(c + 8,x2);\n U32TO8_LITTLE(c + 12,x3);\n U32TO8_LITTLE(c + 16,x4);\n U32TO8_LITTLE(c + 20,x5);\n U32TO8_LITTLE(c + 24,x6);\n U32TO8_LITTLE(c + 28,x7);\n U32TO8_LITTLE(c + 32,x8);\n U32TO8_LITTLE(c + 36,x9);\n U32TO8_LITTLE(c + 40,x10);\n U32TO8_LITTLE(c + 44,x11);\n U32TO8_LITTLE(c + 48,x12);\n U32TO8_LITTLE(c + 52,x13);\n U32TO8_LITTLE(c + 56,x14);\n U32TO8_LITTLE(c + 60,x15);\n\n if (bytes <= 64) {\n if (bytes < 64) {\n for (i = 0;i < bytes;++i) ctarget[i] = c[i];\n }\n x->input[12] = j12;\n x->input[13] = j13;\n return;\n }\n bytes -= 64;\n c += 64;\n m += 64;\n }\n}\n","/* $OpenBSD: sc25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */\n\n/*\n * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,\n * Peter Schwabe, Bo-Yin Yang.\n * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c\n */\n\n#include \"includes.h\"\n\n#include \"sc25519.h\"\n\n/*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */\n\nstatic const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, \n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};\n\nstatic const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, \n 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};\n\nstatic crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */\n{\n unsigned int x = a;\n x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */\n x >>= 31; /* 0: no; 1: yes */\n return x;\n}\n\n/* Reduce coefficients of r before calling reduce_add_sub */\nstatic void reduce_add_sub(sc25519 *r)\n{\n crypto_uint32 pb = 0;\n crypto_uint32 b;\n crypto_uint32 mask;\n int i;\n unsigned char t[32];\n\n for(i=0;i<32;i++) \n {\n pb += m[i];\n b = lt(r->v[i],pb);\n t[i] = r->v[i]-pb+(b<<8);\n pb = b;\n }\n mask = b - 1;\n for(i=0;i<32;i++) \n r->v[i] ^= mask & (r->v[i] ^ t[i]);\n}\n\n/* Reduce coefficients of x before calling barrett_reduce */\nstatic void barrett_reduce(sc25519 *r, const crypto_uint32 x[64])\n{\n /* See HAC, Alg. 14.42 */\n int i,j;\n crypto_uint32 q2[66];\n crypto_uint32 *q3 = q2 + 33;\n crypto_uint32 r1[33];\n crypto_uint32 r2[33];\n crypto_uint32 carry;\n crypto_uint32 pb = 0;\n crypto_uint32 b;\n\n for (i = 0;i < 66;++i) q2[i] = 0;\n for (i = 0;i < 33;++i) r2[i] = 0;\n\n for(i=0;i<33;i++)\n for(j=0;j<33;j++)\n if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];\n carry = q2[31] >> 8;\n q2[32] += carry;\n carry = q2[32] >> 8;\n q2[33] += carry;\n\n for(i=0;i<33;i++)r1[i] = x[i];\n for(i=0;i<32;i++)\n for(j=0;j<33;j++)\n if(i+j < 33) r2[i+j] += m[i]*q3[j];\n\n for(i=0;i<32;i++)\n {\n carry = r2[i] >> 8;\n r2[i+1] += carry;\n r2[i] &= 0xff;\n }\n\n for(i=0;i<32;i++) \n {\n pb += r2[i];\n b = lt(r1[i],pb);\n r->v[i] = r1[i]-pb+(b<<8);\n pb = b;\n }\n\n /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 \n * If so: Handle it here!\n */\n\n reduce_add_sub(r);\n reduce_add_sub(r);\n}\n\nvoid sc25519_from32bytes(sc25519 *r, const unsigned char x[32])\n{\n int i;\n crypto_uint32 t[64];\n for(i=0;i<32;i++) t[i] = x[i];\n for(i=32;i<64;++i) t[i] = 0;\n barrett_reduce(r, t);\n}\n\nvoid shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16])\n{\n int i;\n for(i=0;i<16;i++) r->v[i] = x[i];\n}\n\nvoid sc25519_from64bytes(sc25519 *r, const unsigned char x[64])\n{\n int i;\n crypto_uint32 t[64];\n for(i=0;i<64;i++) t[i] = x[i];\n barrett_reduce(r, t);\n}\n\nvoid sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x)\n{\n int i;\n for(i=0;i<16;i++)\n r->v[i] = x->v[i];\n for(i=0;i<16;i++)\n r->v[16+i] = 0;\n}\n\nvoid sc25519_to32bytes(unsigned char r[32], const sc25519 *x)\n{\n int i;\n for(i=0;i<32;i++) r[i] = x->v[i];\n}\n\nint sc25519_iszero_vartime(const sc25519 *x)\n{\n int i;\n for(i=0;i<32;i++)\n if(x->v[i] != 0) return 0;\n return 1;\n}\n\nint sc25519_isshort_vartime(const sc25519 *x)\n{\n int i;\n for(i=31;i>15;i--)\n if(x->v[i] != 0) return 0;\n return 1;\n}\n\nint sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)\n{\n int i;\n for(i=31;i>=0;i--)\n {\n if(x->v[i] < y->v[i]) return 1;\n if(x->v[i] > y->v[i]) return 0;\n }\n return 0;\n}\n\nvoid sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)\n{\n int i, carry;\n for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];\n for(i=0;i<31;i++)\n {\n carry = r->v[i] >> 8;\n r->v[i+1] += carry;\n r->v[i] &= 0xff;\n }\n reduce_add_sub(r);\n}\n\nvoid sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)\n{\n crypto_uint32 b = 0;\n crypto_uint32 t;\n int i;\n for(i=0;i<32;i++)\n {\n t = x->v[i] - y->v[i] - b;\n r->v[i] = t & 255;\n b = (t >> 8) & 1;\n }\n}\n\nvoid sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)\n{\n int i,j,carry;\n crypto_uint32 t[64];\n for(i=0;i<64;i++)t[i] = 0;\n\n for(i=0;i<32;i++)\n for(j=0;j<32;j++)\n t[i+j] += x->v[i] * y->v[j];\n\n /* Reduce coefficients */\n for(i=0;i<63;i++)\n {\n carry = t[i] >> 8;\n t[i+1] += carry;\n t[i] &= 0xff;\n }\n\n barrett_reduce(r, t);\n}\n\nvoid sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y)\n{\n sc25519 t;\n sc25519_from_shortsc(&t, y);\n sc25519_mul(r, x, &t);\n}\n\nvoid sc25519_window3(signed char r[85], const sc25519 *s)\n{\n char carry;\n int i;\n for(i=0;i<10;i++)\n {\n r[8*i+0] = s->v[3*i+0] & 7;\n r[8*i+1] = (s->v[3*i+0] >> 3) & 7;\n r[8*i+2] = (s->v[3*i+0] >> 6) & 7;\n r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;\n r[8*i+3] = (s->v[3*i+1] >> 1) & 7;\n r[8*i+4] = (s->v[3*i+1] >> 4) & 7;\n r[8*i+5] = (s->v[3*i+1] >> 7) & 7;\n r[8*i+5] ^= (s->v[3*i+2] << 1) & 7;\n r[8*i+6] = (s->v[3*i+2] >> 2) & 7;\n r[8*i+7] = (s->v[3*i+2] >> 5) & 7;\n }\n r[8*i+0] = s->v[3*i+0] & 7;\n r[8*i+1] = (s->v[3*i+0] >> 3) & 7;\n r[8*i+2] = (s->v[3*i+0] >> 6) & 7;\n r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;\n r[8*i+3] = (s->v[3*i+1] >> 1) & 7;\n r[8*i+4] = (s->v[3*i+1] >> 4) & 7;\n\n /* Making it signed */\n carry = 0;\n for(i=0;i<84;i++)\n {\n r[i] += carry;\n r[i+1] += r[i] >> 3;\n r[i] &= 7;\n carry = r[i] >> 2;\n r[i] -= carry<<3;\n }\n r[84] += carry;\n}\n\nvoid sc25519_window5(signed char r[51], const sc25519 *s)\n{\n char carry;\n int i;\n for(i=0;i<6;i++)\n {\n r[8*i+0] = s->v[5*i+0] & 31;\n r[8*i+1] = (s->v[5*i+0] >> 5) & 31;\n r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;\n r[8*i+2] = (s->v[5*i+1] >> 2) & 31;\n r[8*i+3] = (s->v[5*i+1] >> 7) & 31;\n r[8*i+3] ^= (s->v[5*i+2] << 1) & 31;\n r[8*i+4] = (s->v[5*i+2] >> 4) & 31;\n r[8*i+4] ^= (s->v[5*i+3] << 4) & 31;\n r[8*i+5] = (s->v[5*i+3] >> 1) & 31;\n r[8*i+6] = (s->v[5*i+3] >> 6) & 31;\n r[8*i+6] ^= (s->v[5*i+4] << 2) & 31;\n r[8*i+7] = (s->v[5*i+4] >> 3) & 31;\n }\n r[8*i+0] = s->v[5*i+0] & 31;\n r[8*i+1] = (s->v[5*i+0] >> 5) & 31;\n r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;\n r[8*i+2] = (s->v[5*i+1] >> 2) & 31;\n\n /* Making it signed */\n carry = 0;\n for(i=0;i<50;i++)\n {\n r[i] += carry;\n r[i+1] += r[i] >> 5;\n r[i] &= 31;\n carry = r[i] >> 4;\n r[i] -= carry<<5;\n }\n r[50] += carry;\n}\n\nvoid sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)\n{\n int i;\n for(i=0;i<31;i++)\n {\n r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2);\n r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2);\n r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2);\n r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2);\n }\n r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2);\n r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2);\n r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);\n}\n","/* $OpenBSD: ge25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */\n\n/*\n * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,\n * Peter Schwabe, Bo-Yin Yang.\n * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c\n */\n\n#include \"includes.h\"\n\n#include \"fe25519.h\"\n#include \"sc25519.h\"\n#include \"ge25519.h\"\n\n/* \n * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2 \n * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555\n * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);\n */\n\n/* d */\nstatic const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, \n 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}};\n/* 2*d */\nstatic const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, \n 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}};\n/* sqrt(-1) */\nstatic const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, \n 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}};\n\n#define ge25519_p3 ge25519\n\ntypedef struct\n{\n fe25519 x;\n fe25519 z;\n fe25519 y;\n fe25519 t;\n} ge25519_p1p1;\n\ntypedef struct\n{\n fe25519 x;\n fe25519 y;\n fe25519 z;\n} ge25519_p2;\n\ntypedef struct\n{\n fe25519 x;\n fe25519 y;\n} ge25519_aff;\n\n\n/* Packed coordinates of the base point */\nconst ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, \n 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},\n {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, \n 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},\n {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},\n {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, \n 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}};\n\n/* Multiples of the base point in affine representation */\nstatic const ge25519_aff ge25519_base_multiples_affine[425] = {\n#include \"ge25519_base.data\"\n};\n\nstatic void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)\n{\n fe25519_mul(&r->x, &p->x, &p->t);\n fe25519_mul(&r->y, &p->y, &p->z);\n fe25519_mul(&r->z, &p->z, &p->t);\n}\n\nstatic void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)\n{\n p1p1_to_p2((ge25519_p2 *)r, p);\n fe25519_mul(&r->t, &p->x, &p->y);\n}\n\nstatic void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)\n{\n fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;\n fe25519_mul(&qt, &q->x, &q->y);\n fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */\n fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */\n fe25519_sub(&t1, &q->y, &q->x);\n fe25519_add(&t2, &q->y, &q->x);\n fe25519_mul(&a, &a, &t1);\n fe25519_mul(&b, &b, &t2);\n fe25519_sub(&e, &b, &a); /* E = B-A */\n fe25519_add(&h, &b, &a); /* H = B+A */\n fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */\n fe25519_mul(&c, &c, &ge25519_ec2d);\n fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */\n fe25519_sub(&f, &d, &c); /* F = D-C */\n fe25519_add(&g, &d, &c); /* G = D+C */\n fe25519_mul(&r->x, &e, &f);\n fe25519_mul(&r->y, &h, &g);\n fe25519_mul(&r->z, &g, &f);\n fe25519_mul(&r->t, &e, &h);\n}\n\nstatic void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)\n{\n fe25519 a, b, c, d, t;\n \n fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */\n fe25519_sub(&t, &q->y, &q->x);\n fe25519_mul(&a, &a, &t);\n fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */\n fe25519_add(&t, &q->x, &q->y);\n fe25519_mul(&b, &b, &t);\n fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */\n fe25519_mul(&c, &c, &ge25519_ec2d);\n fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */\n fe25519_add(&d, &d, &d);\n fe25519_sub(&r->x, &b, &a); /* E = B-A */\n fe25519_sub(&r->t, &d, &c); /* F = D-C */\n fe25519_add(&r->z, &d, &c); /* G = D+C */\n fe25519_add(&r->y, &b, &a); /* H = B+A */\n}\n\n/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */\nstatic void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)\n{\n fe25519 a,b,c,d;\n fe25519_square(&a, &p->x);\n fe25519_square(&b, &p->y);\n fe25519_square(&c, &p->z);\n fe25519_add(&c, &c, &c);\n fe25519_neg(&d, &a);\n\n fe25519_add(&r->x, &p->x, &p->y);\n fe25519_square(&r->x, &r->x);\n fe25519_sub(&r->x, &r->x, &a);\n fe25519_sub(&r->x, &r->x, &b);\n fe25519_add(&r->z, &d, &b);\n fe25519_sub(&r->t, &r->z, &c);\n fe25519_sub(&r->y, &d, &b);\n}\n\n/* Constant-time version of: if(b) r = p */\nstatic void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)\n{\n fe25519_cmov(&r->x, &p->x, b);\n fe25519_cmov(&r->y, &p->y, b);\n}\n\nstatic unsigned char equal(signed char b,signed char c)\n{\n unsigned char ub = b;\n unsigned char uc = c;\n unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */\n crypto_uint32 y = x; /* 0: yes; 1..255: no */\n y -= 1; /* 4294967295: yes; 0..254: no */\n y >>= 31; /* 1: yes; 0: no */\n return y;\n}\n\nstatic unsigned char negative(signed char b)\n{\n unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */\n x >>= 63; /* 1: yes; 0: no */\n return x;\n}\n\nstatic void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)\n{\n /* constant time */\n fe25519 v;\n *t = ge25519_base_multiples_affine[5*pos+0];\n cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1));\n cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2));\n cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3));\n cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4));\n fe25519_neg(&v, &t->x);\n fe25519_cmov(&t->x, &v, negative(b));\n}\n\nstatic void setneutral(ge25519 *r)\n{\n fe25519_setzero(&r->x);\n fe25519_setone(&r->y);\n fe25519_setone(&r->z);\n fe25519_setzero(&r->t);\n}\n\n/* ********************************************************************\n * EXPORTED FUNCTIONS\n ******************************************************************** */\n\n/* return 0 on success, -1 otherwise */\nint ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])\n{\n unsigned char par;\n fe25519 t, chk, num, den, den2, den4, den6;\n fe25519_setone(&r->z);\n par = p[31] >> 7;\n fe25519_unpack(&r->y, p); \n fe25519_square(&num, &r->y); /* x = y^2 */\n fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */\n fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */\n fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */\n\n /* Computation of sqrt(num/den) */\n /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */\n fe25519_square(&den2, &den);\n fe25519_square(&den4, &den2);\n fe25519_mul(&den6, &den4, &den2);\n fe25519_mul(&t, &den6, &num);\n fe25519_mul(&t, &t, &den);\n\n fe25519_pow2523(&t, &t);\n /* 2. computation of r->x = t * num * den^3 */\n fe25519_mul(&t, &t, &num);\n fe25519_mul(&t, &t, &den);\n fe25519_mul(&t, &t, &den);\n fe25519_mul(&r->x, &t, &den);\n\n /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */\n fe25519_square(&chk, &r->x);\n fe25519_mul(&chk, &chk, &den);\n if (!fe25519_iseq_vartime(&chk, &num))\n fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);\n\n /* 4. Now we have one of the two square roots, except if input was not a square */\n fe25519_square(&chk, &r->x);\n fe25519_mul(&chk, &chk, &den);\n if (!fe25519_iseq_vartime(&chk, &num))\n return -1;\n\n /* 5. Choose the desired square root according to parity: */\n if(fe25519_getparity(&r->x) != (1-par))\n fe25519_neg(&r->x, &r->x);\n\n fe25519_mul(&r->t, &r->x, &r->y);\n return 0;\n}\n\nvoid ge25519_pack(unsigned char r[32], const ge25519_p3 *p)\n{\n fe25519 tx, ty, zi;\n fe25519_invert(&zi, &p->z); \n fe25519_mul(&tx, &p->x, &zi);\n fe25519_mul(&ty, &p->y, &zi);\n fe25519_pack(r, &ty);\n r[31] ^= fe25519_getparity(&tx) << 7;\n}\n\nint ge25519_isneutral_vartime(const ge25519_p3 *p)\n{\n int ret = 1;\n if(!fe25519_iszero(&p->x)) ret = 0;\n if(!fe25519_iseq_vartime(&p->y, &p->z)) ret = 0;\n return ret;\n}\n\n/* computes [s1]p1 + [s2]p2 */\nvoid ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)\n{\n ge25519_p1p1 tp1p1;\n ge25519_p3 pre[16];\n unsigned char b[127];\n int i;\n\n /* precomputation s2 s1 */\n setneutral(pre); /* 00 00 */\n pre[1] = *p1; /* 00 01 */\n dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */\n add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */\n pre[4] = *p2; /* 01 00 */\n add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */\n add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */\n add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */\n dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */\n add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */\n dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */\n add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */\n add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */\n add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */\n add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */\n add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */\n\n sc25519_2interleave2(b,s1,s2);\n\n /* scalar multiplication */\n *r = pre[b[126]];\n for(i=125;i>=0;i--)\n {\n dbl_p1p1(&tp1p1, (ge25519_p2 *)r);\n p1p1_to_p2((ge25519_p2 *) r, &tp1p1);\n dbl_p1p1(&tp1p1, (ge25519_p2 *)r);\n if(b[i]!=0)\n {\n p1p1_to_p3(r, &tp1p1);\n add_p1p1(&tp1p1, r, &pre[b[i]]);\n }\n if(i != 0) p1p1_to_p2((ge25519_p2 *)r, &tp1p1);\n else p1p1_to_p3(r, &tp1p1);\n }\n}\n\nvoid ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)\n{\n signed char b[85];\n int i;\n ge25519_aff t;\n sc25519_window3(b,s);\n\n choose_t((ge25519_aff *)r, 0, b[0]);\n fe25519_setone(&r->z);\n fe25519_mul(&r->t, &r->x, &r->y);\n for(i=1;i<85;i++)\n {\n choose_t(&t, (unsigned long long) i, b[i]);\n ge25519_mixadd2(r, &t);\n }\n}\n","/* $OpenBSD: fe25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */\n\n/*\n * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,\n * Peter Schwabe, Bo-Yin Yang.\n * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c\n */\n\n#include \"includes.h\"\n\n#define WINDOWSIZE 1 /* Should be 1,2, or 4 */\n#define WINDOWMASK ((1<>= 31; /* 1: yes; 0: no */\n return x;\n}\n\nstatic crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */\n{\n unsigned int x = a;\n x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */\n x >>= 31; /* 0: yes; 1: no */\n x ^= 1; /* 1: yes; 0: no */\n return x;\n}\n\nstatic crypto_uint32 times19(crypto_uint32 a)\n{\n return (a << 4) + (a << 1) + a;\n}\n\nstatic crypto_uint32 times38(crypto_uint32 a)\n{\n return (a << 5) + (a << 2) + (a << 1);\n}\n\nstatic void reduce_add_sub(fe25519 *r)\n{\n crypto_uint32 t;\n int i,rep;\n\n for(rep=0;rep<4;rep++)\n {\n t = r->v[31] >> 7;\n r->v[31] &= 127;\n t = times19(t);\n r->v[0] += t;\n for(i=0;i<31;i++)\n {\n t = r->v[i] >> 8;\n r->v[i+1] += t;\n r->v[i] &= 255;\n }\n }\n}\n\nstatic void reduce_mul(fe25519 *r)\n{\n crypto_uint32 t;\n int i,rep;\n\n for(rep=0;rep<2;rep++)\n {\n t = r->v[31] >> 7;\n r->v[31] &= 127;\n t = times19(t);\n r->v[0] += t;\n for(i=0;i<31;i++)\n {\n t = r->v[i] >> 8;\n r->v[i+1] += t;\n r->v[i] &= 255;\n }\n }\n}\n\n/* reduction modulo 2^255-19 */\nvoid fe25519_freeze(fe25519 *r) \n{\n int i;\n crypto_uint32 m = equal(r->v[31],127);\n for(i=30;i>0;i--)\n m &= equal(r->v[i],255);\n m &= ge(r->v[0],237);\n\n m = -m;\n\n r->v[31] -= m&127;\n for(i=30;i>0;i--)\n r->v[i] -= m&255;\n r->v[0] -= m&237;\n}\n\nvoid fe25519_unpack(fe25519 *r, const unsigned char x[32])\n{\n int i;\n for(i=0;i<32;i++) r->v[i] = x[i];\n r->v[31] &= 127;\n}\n\n/* Assumes input x being reduced below 2^255 */\nvoid fe25519_pack(unsigned char r[32], const fe25519 *x)\n{\n int i;\n fe25519 y = *x;\n fe25519_freeze(&y);\n for(i=0;i<32;i++) \n r[i] = y.v[i];\n}\n\nint fe25519_iszero(const fe25519 *x)\n{\n int i;\n int r;\n fe25519 t = *x;\n fe25519_freeze(&t);\n r = equal(t.v[0],0);\n for(i=1;i<32;i++) \n r &= equal(t.v[i],0);\n return r;\n}\n\nint fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)\n{\n int i;\n fe25519 t1 = *x;\n fe25519 t2 = *y;\n fe25519_freeze(&t1);\n fe25519_freeze(&t2);\n for(i=0;i<32;i++)\n if(t1.v[i] != t2.v[i]) return 0;\n return 1;\n}\n\nvoid fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)\n{\n int i;\n crypto_uint32 mask = b;\n mask = -mask;\n for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);\n}\n\nunsigned char fe25519_getparity(const fe25519 *x)\n{\n fe25519 t = *x;\n fe25519_freeze(&t);\n return t.v[0] & 1;\n}\n\nvoid fe25519_setone(fe25519 *r)\n{\n int i;\n r->v[0] = 1;\n for(i=1;i<32;i++) r->v[i]=0;\n}\n\nvoid fe25519_setzero(fe25519 *r)\n{\n int i;\n for(i=0;i<32;i++) r->v[i]=0;\n}\n\nvoid fe25519_neg(fe25519 *r, const fe25519 *x)\n{\n fe25519 t;\n int i;\n for(i=0;i<32;i++) t.v[i]=x->v[i];\n fe25519_setzero(r);\n fe25519_sub(r, r, &t);\n}\n\nvoid fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)\n{\n int i;\n for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];\n reduce_add_sub(r);\n}\n\nvoid fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)\n{\n int i;\n crypto_uint32 t[32];\n t[0] = x->v[0] + 0x1da;\n t[31] = x->v[31] + 0xfe;\n for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe;\n for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i];\n reduce_add_sub(r);\n}\n\nvoid fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)\n{\n int i,j;\n crypto_uint32 t[63];\n for(i=0;i<63;i++)t[i] = 0;\n\n for(i=0;i<32;i++)\n for(j=0;j<32;j++)\n t[i+j] += x->v[i] * y->v[j];\n\n for(i=32;i<63;i++)\n r->v[i-32] = t[i-32] + times38(t[i]); \n r->v[31] = t[31]; /* result now in r[0]...r[31] */\n\n reduce_mul(r);\n}\n\nvoid fe25519_square(fe25519 *r, const fe25519 *x)\n{\n fe25519_mul(r, x, x);\n}\n\nvoid fe25519_invert(fe25519 *r, const fe25519 *x)\n{\n\tfe25519 z2;\n\tfe25519 z9;\n\tfe25519 z11;\n\tfe25519 z2_5_0;\n\tfe25519 z2_10_0;\n\tfe25519 z2_20_0;\n\tfe25519 z2_50_0;\n\tfe25519 z2_100_0;\n\tfe25519 t0;\n\tfe25519 t1;\n\tint i;\n\t\n\t/* 2 */ fe25519_square(&z2,x);\n\t/* 4 */ fe25519_square(&t1,&z2);\n\t/* 8 */ fe25519_square(&t0,&t1);\n\t/* 9 */ fe25519_mul(&z9,&t0,x);\n\t/* 11 */ fe25519_mul(&z11,&z9,&z2);\n\t/* 22 */ fe25519_square(&t0,&z11);\n\t/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9);\n\n\t/* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0);\n\t/* 2^7 - 2^2 */ fe25519_square(&t1,&t0);\n\t/* 2^8 - 2^3 */ fe25519_square(&t0,&t1);\n\t/* 2^9 - 2^4 */ fe25519_square(&t1,&t0);\n\t/* 2^10 - 2^5 */ fe25519_square(&t0,&t1);\n\t/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0);\n\n\t/* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0);\n\t/* 2^12 - 2^2 */ fe25519_square(&t1,&t0);\n\t/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }\n\t/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0);\n\n\t/* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0);\n\t/* 2^22 - 2^2 */ fe25519_square(&t1,&t0);\n\t/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }\n\t/* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0);\n\n\t/* 2^41 - 2^1 */ fe25519_square(&t1,&t0);\n\t/* 2^42 - 2^2 */ fe25519_square(&t0,&t1);\n\t/* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }\n\t/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);\n\n\t/* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0);\n\t/* 2^52 - 2^2 */ fe25519_square(&t1,&t0);\n\t/* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }\n\t/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0);\n\n\t/* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0);\n\t/* 2^102 - 2^2 */ fe25519_square(&t0,&t1);\n\t/* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }\n\t/* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0);\n\n\t/* 2^201 - 2^1 */ fe25519_square(&t0,&t1);\n\t/* 2^202 - 2^2 */ fe25519_square(&t1,&t0);\n\t/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }\n\t/* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0);\n\n\t/* 2^251 - 2^1 */ fe25519_square(&t1,&t0);\n\t/* 2^252 - 2^2 */ fe25519_square(&t0,&t1);\n\t/* 2^253 - 2^3 */ fe25519_square(&t1,&t0);\n\t/* 2^254 - 2^4 */ fe25519_square(&t0,&t1);\n\t/* 2^255 - 2^5 */ fe25519_square(&t1,&t0);\n\t/* 2^255 - 21 */ fe25519_mul(r,&t1,&z11);\n}\n\nvoid fe25519_pow2523(fe25519 *r, const fe25519 *x)\n{\n\tfe25519 z2;\n\tfe25519 z9;\n\tfe25519 z11;\n\tfe25519 z2_5_0;\n\tfe25519 z2_10_0;\n\tfe25519 z2_20_0;\n\tfe25519 z2_50_0;\n\tfe25519 z2_100_0;\n\tfe25519 t;\n\tint i;\n\t\t\n\t/* 2 */ fe25519_square(&z2,x);\n\t/* 4 */ fe25519_square(&t,&z2);\n\t/* 8 */ fe25519_square(&t,&t);\n\t/* 9 */ fe25519_mul(&z9,&t,x);\n\t/* 11 */ fe25519_mul(&z11,&z9,&z2);\n\t/* 22 */ fe25519_square(&t,&z11);\n\t/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9);\n\n\t/* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0);\n\t/* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); }\n\t/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0);\n\n\t/* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0);\n\t/* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }\n\t/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0);\n\n\t/* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0);\n\t/* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); }\n\t/* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0);\n\n\t/* 2^41 - 2^1 */ fe25519_square(&t,&t);\n\t/* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }\n\t/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0);\n\n\t/* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0);\n\t/* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }\n\t/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0);\n\n\t/* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0);\n\t/* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); }\n\t/* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0);\n\n\t/* 2^201 - 2^1 */ fe25519_square(&t,&t);\n\t/* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }\n\t/* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0);\n\n\t/* 2^251 - 2^1 */ fe25519_square(&t,&t);\n\t/* 2^252 - 2^2 */ fe25519_square(&t,&t);\n\t/* 2^252 - 3 */ fe25519_mul(r,&t,x);\n}\n","/* $OpenBSD: kexc25519.c,v 1.10 2016/05/02 08:49:03 djm Exp $ */\n/*\n * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.\n * Copyright (c) 2010 Damien Miller. All rights reserved.\n * Copyright (c) 2013 Aris Adamantiadis. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n#include \"includes.h\"\n\n#include \n\n#include \n#include \n\n#include \n#include \n\n#include \"sshbuf.h\"\n#include \"ssh2.h\"\n#include \"sshkey.h\"\n#include \"cipher.h\"\n#include \"kex.h\"\n#include \"log.h\"\n#include \"digest.h\"\n#include \"ssherr.h\"\n\nextern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE],\n const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE])\n\t__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))\n\t__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)))\n\t__attribute__((__bounded__(__minbytes__, 3, CURVE25519_SIZE)));\n\nvoid\nkexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE])\n{\n\tstatic const u_char basepoint[CURVE25519_SIZE] = {9};\n\n\tarc4random_buf(key, CURVE25519_SIZE);\n\tcrypto_scalarmult_curve25519(pub, key, basepoint);\n}\n\nint\nkexc25519_shared_key(const u_char key[CURVE25519_SIZE],\n const u_char pub[CURVE25519_SIZE], struct sshbuf *out)\n{\n\tu_char shared_key[CURVE25519_SIZE];\n\tint r;\n\n\t/* Check for all-zero public key */\n\texplicit_bzero(shared_key, CURVE25519_SIZE);\n\tif (timingsafe_bcmp(pub, shared_key, CURVE25519_SIZE) == 0)\n\t\treturn SSH_ERR_KEY_INVALID_EC_VALUE;\n\n\tcrypto_scalarmult_curve25519(shared_key, key, pub);\n#ifdef DEBUG_KEXECDH\n\tdump_digest(\"shared secret\", shared_key, CURVE25519_SIZE);\n#endif\n\tsshbuf_reset(out);\n\tr = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE);\n\texplicit_bzero(shared_key, CURVE25519_SIZE);\n\treturn r;\n}\n\nint\nkex_c25519_hash(\n int hash_alg,\n const char *client_version_string,\n const char *server_version_string,\n const u_char *ckexinit, size_t ckexinitlen,\n const u_char *skexinit, size_t skexinitlen,\n const u_char *serverhostkeyblob, size_t sbloblen,\n const u_char client_dh_pub[CURVE25519_SIZE],\n const u_char server_dh_pub[CURVE25519_SIZE],\n const u_char *shared_secret, size_t secretlen,\n u_char *hash, size_t *hashlen)\n{\n\tstruct sshbuf *b;\n\tint r;\n\n\tif (*hashlen < ssh_digest_bytes(hash_alg))\n\t\treturn SSH_ERR_INVALID_ARGUMENT;\n\tif ((b = sshbuf_new()) == NULL)\n\t\treturn SSH_ERR_ALLOC_FAIL;\n\tif ((r = sshbuf_put_cstring(b, client_version_string)) < 0 ||\n\t (r = sshbuf_put_cstring(b, server_version_string)) < 0 ||\n\t /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */\n\t (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 ||\n\t (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||\n\t (r = sshbuf_put(b, ckexinit, ckexinitlen)) < 0 ||\n\t (r = sshbuf_put_u32(b, skexinitlen+1)) < 0 ||\n\t (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||\n\t (r = sshbuf_put(b, skexinit, skexinitlen)) < 0 ||\n\t (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) < 0 ||\n\t (r = sshbuf_put_string(b, client_dh_pub, CURVE25519_SIZE)) < 0 ||\n\t (r = sshbuf_put_string(b, server_dh_pub, CURVE25519_SIZE)) < 0 ||\n\t (r = sshbuf_put(b, shared_secret, secretlen)) < 0) {\n\t\tsshbuf_free(b);\n\t\treturn r;\n\t}\n#ifdef DEBUG_KEX\n\tsshbuf_dump(b, stderr);\n#endif\n\tif (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {\n\t\tsshbuf_free(b);\n\t\treturn SSH_ERR_LIBCRYPTO_ERROR;\n\t}\n\tsshbuf_free(b);\n\t*hashlen = ssh_digest_bytes(hash_alg);\n#ifdef DEBUG_KEX\n\tdump_digest(\"hash\", hash, *hashlen);\n#endif\n\treturn 0;\n}\n","/* $OpenBSD: smult_curve25519_ref.c,v 1.2 2013/11/02 22:02:14 markus Exp $ */\n/*\nversion 20081011\nMatthew Dempsky\nPublic domain.\nDerived from public domain code by D. J. Bernstein.\n*/\n\nint crypto_scalarmult_curve25519(unsigned char *, const unsigned char *, const unsigned char *);\n\nstatic void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])\n{\n unsigned int j;\n unsigned int u;\n u = 0;\n for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; }\n u += a[31] + b[31]; out[31] = u;\n}\n\nstatic void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])\n{\n unsigned int j;\n unsigned int u;\n u = 218;\n for (j = 0;j < 31;++j) {\n u += a[j] + 65280 - b[j];\n out[j] = u & 255;\n u >>= 8;\n }\n u += a[31] - b[31];\n out[31] = u;\n}\n\nstatic void squeeze(unsigned int a[32])\n{\n unsigned int j;\n unsigned int u;\n u = 0;\n for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }\n u += a[31]; a[31] = u & 127;\n u = 19 * (u >> 7);\n for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }\n u += a[31]; a[31] = u;\n}\n\nstatic const unsigned int minusp[32] = {\n 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128\n} ;\n\nstatic void freeze(unsigned int a[32])\n{\n unsigned int aorig[32];\n unsigned int j;\n unsigned int negative;\n\n for (j = 0;j < 32;++j) aorig[j] = a[j];\n add(a,a,minusp);\n negative = -((a[31] >> 7) & 1);\n for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]);\n}\n\nstatic void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])\n{\n unsigned int i;\n unsigned int j;\n unsigned int u;\n\n for (i = 0;i < 32;++i) {\n u = 0;\n for (j = 0;j <= i;++j) u += a[j] * b[i - j];\n for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j];\n out[i] = u;\n }\n squeeze(out);\n}\n\nstatic void mult121665(unsigned int out[32],const unsigned int a[32])\n{\n unsigned int j;\n unsigned int u;\n\n u = 0;\n for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; }\n u += 121665 * a[31]; out[31] = u & 127;\n u = 19 * (u >> 7);\n for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; }\n u += out[j]; out[j] = u;\n}\n\nstatic void square(unsigned int out[32],const unsigned int a[32])\n{\n unsigned int i;\n unsigned int j;\n unsigned int u;\n\n for (i = 0;i < 32;++i) {\n u = 0;\n for (j = 0;j < i - j;++j) u += a[j] * a[i - j];\n for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j];\n u *= 2;\n if ((i & 1) == 0) {\n u += a[i / 2] * a[i / 2];\n u += 38 * a[i / 2 + 16] * a[i / 2 + 16];\n }\n out[i] = u;\n }\n squeeze(out);\n}\n\nstatic void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b)\n{\n unsigned int j;\n unsigned int t;\n unsigned int bminus1;\n\n bminus1 = b - 1;\n for (j = 0;j < 64;++j) {\n t = bminus1 & (r[j] ^ s[j]);\n p[j] = s[j] ^ t;\n q[j] = r[j] ^ t;\n }\n}\n\nstatic void mainloop(unsigned int work[64],const unsigned char e[32])\n{\n unsigned int xzm1[64];\n unsigned int xzm[64];\n unsigned int xzmb[64];\n unsigned int xzm1b[64];\n unsigned int xznb[64];\n unsigned int xzn1b[64];\n unsigned int a0[64];\n unsigned int a1[64];\n unsigned int b0[64];\n unsigned int b1[64];\n unsigned int c1[64];\n unsigned int r[32];\n unsigned int s[32];\n unsigned int t[32];\n unsigned int u[32];\n unsigned int j;\n unsigned int b;\n int pos;\n\n for (j = 0;j < 32;++j) xzm1[j] = work[j];\n xzm1[32] = 1;\n for (j = 33;j < 64;++j) xzm1[j] = 0;\n\n xzm[0] = 1;\n for (j = 1;j < 64;++j) xzm[j] = 0;\n\n for (pos = 254;pos >= 0;--pos) {\n b = e[pos / 8] >> (pos & 7);\n b &= 1;\n select(xzmb,xzm1b,xzm,xzm1,b);\n add(a0,xzmb,xzmb + 32);\n sub(a0 + 32,xzmb,xzmb + 32);\n add(a1,xzm1b,xzm1b + 32);\n sub(a1 + 32,xzm1b,xzm1b + 32);\n square(b0,a0);\n square(b0 + 32,a0 + 32);\n mult(b1,a1,a0 + 32);\n mult(b1 + 32,a1 + 32,a0);\n add(c1,b1,b1 + 32);\n sub(c1 + 32,b1,b1 + 32);\n square(r,c1 + 32);\n sub(s,b0,b0 + 32);\n mult121665(t,s);\n add(u,t,b0);\n mult(xznb,b0,b0 + 32);\n mult(xznb + 32,s,u);\n square(xzn1b,c1);\n mult(xzn1b + 32,r,work);\n select(xzm,xzm1,xznb,xzn1b,b);\n }\n\n for (j = 0;j < 64;++j) work[j] = xzm[j];\n}\n\nstatic void recip(unsigned int out[32],const unsigned int z[32])\n{\n unsigned int z2[32];\n unsigned int z9[32];\n unsigned int z11[32];\n unsigned int z2_5_0[32];\n unsigned int z2_10_0[32];\n unsigned int z2_20_0[32];\n unsigned int z2_50_0[32];\n unsigned int z2_100_0[32];\n unsigned int t0[32];\n unsigned int t1[32];\n int i;\n\n /* 2 */ square(z2,z);\n /* 4 */ square(t1,z2);\n /* 8 */ square(t0,t1);\n /* 9 */ mult(z9,t0,z);\n /* 11 */ mult(z11,z9,z2);\n /* 22 */ square(t0,z11);\n /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9);\n\n /* 2^6 - 2^1 */ square(t0,z2_5_0);\n /* 2^7 - 2^2 */ square(t1,t0);\n /* 2^8 - 2^3 */ square(t0,t1);\n /* 2^9 - 2^4 */ square(t1,t0);\n /* 2^10 - 2^5 */ square(t0,t1);\n /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0);\n\n /* 2^11 - 2^1 */ square(t0,z2_10_0);\n /* 2^12 - 2^2 */ square(t1,t0);\n /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); }\n /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0);\n\n /* 2^21 - 2^1 */ square(t0,z2_20_0);\n /* 2^22 - 2^2 */ square(t1,t0);\n /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); }\n /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0);\n\n /* 2^41 - 2^1 */ square(t1,t0);\n /* 2^42 - 2^2 */ square(t0,t1);\n /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); }\n /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0);\n\n /* 2^51 - 2^1 */ square(t0,z2_50_0);\n /* 2^52 - 2^2 */ square(t1,t0);\n /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }\n /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0);\n\n /* 2^101 - 2^1 */ square(t1,z2_100_0);\n /* 2^102 - 2^2 */ square(t0,t1);\n /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); }\n /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0);\n\n /* 2^201 - 2^1 */ square(t0,t1);\n /* 2^202 - 2^2 */ square(t1,t0);\n /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }\n /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0);\n\n /* 2^251 - 2^1 */ square(t1,t0);\n /* 2^252 - 2^2 */ square(t0,t1);\n /* 2^253 - 2^3 */ square(t1,t0);\n /* 2^254 - 2^4 */ square(t0,t1);\n /* 2^255 - 2^5 */ square(t1,t0);\n /* 2^255 - 21 */ mult(out,t1,z11);\n}\n\nint crypto_scalarmult_curve25519(unsigned char *q,\n const unsigned char *n,\n const unsigned char *p)\n{\n unsigned int work[96];\n unsigned char e[32];\n unsigned int i;\n for (i = 0;i < 32;++i) e[i] = n[i];\n e[0] &= 248;\n e[31] &= 127;\n e[31] |= 64;\n for (i = 0;i < 32;++i) work[i] = p[i];\n mainloop(work,e);\n recip(work + 32,work + 32);\n mult(work + 64,work,work + 32);\n freeze(work + 64);\n for (i = 0;i < 32;++i) q[i] = work[64 + i];\n return 0;\n}\n",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]}