a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
at main 24 kB view raw
1// Copyright 2013 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package ssh 6 7import ( 8 "errors" 9 "fmt" 10 "io" 11 "log" 12 "net" 13 "strings" 14 "sync" 15) 16 17// debugHandshake, if set, prints messages sent and received. Key 18// exchange messages are printed as if DH were used, so the debug 19// messages are wrong when using ECDH. 20const debugHandshake = false 21 22// chanSize sets the amount of buffering SSH connections. This is 23// primarily for testing: setting chanSize=0 uncovers deadlocks more 24// quickly. 25const chanSize = 16 26 27// maxPendingPackets sets the maximum number of packets to queue while waiting 28// for KEX to complete. This limits the total pending data to maxPendingPackets 29// * maxPacket bytes, which is ~16.8MB. 30const maxPendingPackets = 64 31 32// keyingTransport is a packet based transport that supports key 33// changes. It need not be thread-safe. It should pass through 34// msgNewKeys in both directions. 35type keyingTransport interface { 36 packetConn 37 38 // prepareKeyChange sets up a key change. The key change for a 39 // direction will be effected if a msgNewKeys message is sent 40 // or received. 41 prepareKeyChange(*NegotiatedAlgorithms, *kexResult) error 42 43 // setStrictMode sets the strict KEX mode, notably triggering 44 // sequence number resets on sending or receiving msgNewKeys. 45 // If the sequence number is already > 1 when setStrictMode 46 // is called, an error is returned. 47 setStrictMode() error 48 49 // setInitialKEXDone indicates to the transport that the initial key exchange 50 // was completed 51 setInitialKEXDone() 52} 53 54// handshakeTransport implements rekeying on top of a keyingTransport 55// and offers a thread-safe writePacket() interface. 56type handshakeTransport struct { 57 conn keyingTransport 58 config *Config 59 60 serverVersion []byte 61 clientVersion []byte 62 63 // hostKeys is non-empty if we are the server. In that case, 64 // it contains all host keys that can be used to sign the 65 // connection. 66 hostKeys []Signer 67 68 // publicKeyAuthAlgorithms is non-empty if we are the server. In that case, 69 // it contains the supported client public key authentication algorithms. 70 publicKeyAuthAlgorithms []string 71 72 // hostKeyAlgorithms is non-empty if we are the client. In that case, 73 // we accept these key types from the server as host key. 74 hostKeyAlgorithms []string 75 76 // On read error, incoming is closed, and readError is set. 77 incoming chan []byte 78 readError error 79 80 mu sync.Mutex 81 // Condition for the above mutex. It is used to notify a completed key 82 // exchange or a write failure. Writes can wait for this condition while a 83 // key exchange is in progress. 84 writeCond *sync.Cond 85 writeError error 86 sentInitPacket []byte 87 sentInitMsg *kexInitMsg 88 // Used to queue writes when a key exchange is in progress. The length is 89 // limited by pendingPacketsSize. Once full, writes will block until the key 90 // exchange is completed or an error occurs. If not empty, it is emptied 91 // all at once when the key exchange is completed in kexLoop. 92 pendingPackets [][]byte 93 writePacketsLeft uint32 94 writeBytesLeft int64 95 userAuthComplete bool // whether the user authentication phase is complete 96 97 // If the read loop wants to schedule a kex, it pings this 98 // channel, and the write loop will send out a kex 99 // message. 100 requestKex chan struct{} 101 102 // If the other side requests or confirms a kex, its kexInit 103 // packet is sent here for the write loop to find it. 104 startKex chan *pendingKex 105 kexLoopDone chan struct{} // closed (with writeError non-nil) when kexLoop exits 106 107 // data for host key checking 108 hostKeyCallback HostKeyCallback 109 dialAddress string 110 remoteAddr net.Addr 111 112 // bannerCallback is non-empty if we are the client and it has been set in 113 // ClientConfig. In that case it is called during the user authentication 114 // dance to handle a custom server's message. 115 bannerCallback BannerCallback 116 117 // Algorithms agreed in the last key exchange. 118 algorithms *NegotiatedAlgorithms 119 120 // Counters exclusively owned by readLoop. 121 readPacketsLeft uint32 122 readBytesLeft int64 123 124 // The session ID or nil if first kex did not complete yet. 125 sessionID []byte 126 127 // strictMode indicates if the other side of the handshake indicated 128 // that we should be following the strict KEX protocol restrictions. 129 strictMode bool 130} 131 132type pendingKex struct { 133 otherInit []byte 134 done chan error 135} 136 137func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport { 138 t := &handshakeTransport{ 139 conn: conn, 140 serverVersion: serverVersion, 141 clientVersion: clientVersion, 142 incoming: make(chan []byte, chanSize), 143 requestKex: make(chan struct{}, 1), 144 startKex: make(chan *pendingKex), 145 kexLoopDone: make(chan struct{}), 146 147 config: config, 148 } 149 t.writeCond = sync.NewCond(&t.mu) 150 t.resetReadThresholds() 151 t.resetWriteThresholds() 152 153 // We always start with a mandatory key exchange. 154 t.requestKex <- struct{}{} 155 return t 156} 157 158func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport { 159 t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion) 160 t.dialAddress = dialAddr 161 t.remoteAddr = addr 162 t.hostKeyCallback = config.HostKeyCallback 163 t.bannerCallback = config.BannerCallback 164 if config.HostKeyAlgorithms != nil { 165 t.hostKeyAlgorithms = config.HostKeyAlgorithms 166 } else { 167 t.hostKeyAlgorithms = defaultHostKeyAlgos 168 } 169 go t.readLoop() 170 go t.kexLoop() 171 return t 172} 173 174func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport { 175 t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion) 176 t.hostKeys = config.hostKeys 177 t.publicKeyAuthAlgorithms = config.PublicKeyAuthAlgorithms 178 go t.readLoop() 179 go t.kexLoop() 180 return t 181} 182 183func (t *handshakeTransport) getSessionID() []byte { 184 return t.sessionID 185} 186 187func (t *handshakeTransport) getAlgorithms() NegotiatedAlgorithms { 188 return *t.algorithms 189} 190 191// waitSession waits for the session to be established. This should be 192// the first thing to call after instantiating handshakeTransport. 193func (t *handshakeTransport) waitSession() error { 194 p, err := t.readPacket() 195 if err != nil { 196 return err 197 } 198 if p[0] != msgNewKeys { 199 return fmt.Errorf("ssh: first packet should be msgNewKeys") 200 } 201 202 return nil 203} 204 205func (t *handshakeTransport) id() string { 206 if len(t.hostKeys) > 0 { 207 return "server" 208 } 209 return "client" 210} 211 212func (t *handshakeTransport) printPacket(p []byte, write bool) { 213 action := "got" 214 if write { 215 action = "sent" 216 } 217 218 if p[0] == msgChannelData || p[0] == msgChannelExtendedData { 219 log.Printf("%s %s data (packet %d bytes)", t.id(), action, len(p)) 220 } else { 221 msg, err := decode(p) 222 log.Printf("%s %s %T %v (%v)", t.id(), action, msg, msg, err) 223 } 224} 225 226func (t *handshakeTransport) readPacket() ([]byte, error) { 227 p, ok := <-t.incoming 228 if !ok { 229 return nil, t.readError 230 } 231 return p, nil 232} 233 234func (t *handshakeTransport) readLoop() { 235 first := true 236 for { 237 p, err := t.readOnePacket(first) 238 first = false 239 if err != nil { 240 t.readError = err 241 close(t.incoming) 242 break 243 } 244 // If this is the first kex, and strict KEX mode is enabled, 245 // we don't ignore any messages, as they may be used to manipulate 246 // the packet sequence numbers. 247 if !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) { 248 continue 249 } 250 t.incoming <- p 251 } 252 253 // Stop writers too. 254 t.recordWriteError(t.readError) 255 256 // Unblock the writer should it wait for this. 257 close(t.startKex) 258 259 // Don't close t.requestKex; it's also written to from writePacket. 260} 261 262func (t *handshakeTransport) pushPacket(p []byte) error { 263 if debugHandshake { 264 t.printPacket(p, true) 265 } 266 return t.conn.writePacket(p) 267} 268 269func (t *handshakeTransport) getWriteError() error { 270 t.mu.Lock() 271 defer t.mu.Unlock() 272 return t.writeError 273} 274 275func (t *handshakeTransport) recordWriteError(err error) { 276 t.mu.Lock() 277 defer t.mu.Unlock() 278 if t.writeError == nil && err != nil { 279 t.writeError = err 280 t.writeCond.Broadcast() 281 } 282} 283 284func (t *handshakeTransport) requestKeyExchange() { 285 select { 286 case t.requestKex <- struct{}{}: 287 default: 288 // something already requested a kex, so do nothing. 289 } 290} 291 292func (t *handshakeTransport) resetWriteThresholds() { 293 t.writePacketsLeft = packetRekeyThreshold 294 if t.config.RekeyThreshold > 0 { 295 t.writeBytesLeft = int64(t.config.RekeyThreshold) 296 } else if t.algorithms != nil { 297 t.writeBytesLeft = t.algorithms.Write.rekeyBytes() 298 } else { 299 t.writeBytesLeft = 1 << 30 300 } 301} 302 303func (t *handshakeTransport) kexLoop() { 304 305write: 306 for t.getWriteError() == nil { 307 var request *pendingKex 308 var sent bool 309 310 for request == nil || !sent { 311 var ok bool 312 select { 313 case request, ok = <-t.startKex: 314 if !ok { 315 break write 316 } 317 case <-t.requestKex: 318 break 319 } 320 321 if !sent { 322 if err := t.sendKexInit(); err != nil { 323 t.recordWriteError(err) 324 break 325 } 326 sent = true 327 } 328 } 329 330 if err := t.getWriteError(); err != nil { 331 if request != nil { 332 request.done <- err 333 } 334 break 335 } 336 337 // We're not servicing t.requestKex, but that is OK: 338 // we never block on sending to t.requestKex. 339 340 // We're not servicing t.startKex, but the remote end 341 // has just sent us a kexInitMsg, so it can't send 342 // another key change request, until we close the done 343 // channel on the pendingKex request. 344 345 err := t.enterKeyExchange(request.otherInit) 346 347 t.mu.Lock() 348 t.writeError = err 349 t.sentInitPacket = nil 350 t.sentInitMsg = nil 351 352 t.resetWriteThresholds() 353 354 // we have completed the key exchange. Since the 355 // reader is still blocked, it is safe to clear out 356 // the requestKex channel. This avoids the situation 357 // where: 1) we consumed our own request for the 358 // initial kex, and 2) the kex from the remote side 359 // caused another send on the requestKex channel, 360 clear: 361 for { 362 select { 363 case <-t.requestKex: 364 // 365 default: 366 break clear 367 } 368 } 369 370 request.done <- t.writeError 371 372 // kex finished. Push packets that we received while 373 // the kex was in progress. Don't look at t.startKex 374 // and don't increment writtenSinceKex: if we trigger 375 // another kex while we are still busy with the last 376 // one, things will become very confusing. 377 for _, p := range t.pendingPackets { 378 t.writeError = t.pushPacket(p) 379 if t.writeError != nil { 380 break 381 } 382 } 383 t.pendingPackets = t.pendingPackets[:0] 384 // Unblock writePacket if waiting for KEX. 385 t.writeCond.Broadcast() 386 t.mu.Unlock() 387 } 388 389 // Unblock reader. 390 t.conn.Close() 391 392 // drain startKex channel. We don't service t.requestKex 393 // because nobody does blocking sends there. 394 for request := range t.startKex { 395 request.done <- t.getWriteError() 396 } 397 398 // Mark that the loop is done so that Close can return. 399 close(t.kexLoopDone) 400} 401 402// The protocol uses uint32 for packet counters, so we can't let them 403// reach 1<<32. We will actually read and write more packets than 404// this, though: the other side may send more packets, and after we 405// hit this limit on writing we will send a few more packets for the 406// key exchange itself. 407const packetRekeyThreshold = (1 << 31) 408 409func (t *handshakeTransport) resetReadThresholds() { 410 t.readPacketsLeft = packetRekeyThreshold 411 if t.config.RekeyThreshold > 0 { 412 t.readBytesLeft = int64(t.config.RekeyThreshold) 413 } else if t.algorithms != nil { 414 t.readBytesLeft = t.algorithms.Read.rekeyBytes() 415 } else { 416 t.readBytesLeft = 1 << 30 417 } 418} 419 420func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) { 421 p, err := t.conn.readPacket() 422 if err != nil { 423 return nil, err 424 } 425 426 if t.readPacketsLeft > 0 { 427 t.readPacketsLeft-- 428 } else { 429 t.requestKeyExchange() 430 } 431 432 if t.readBytesLeft > 0 { 433 t.readBytesLeft -= int64(len(p)) 434 } else { 435 t.requestKeyExchange() 436 } 437 438 if debugHandshake { 439 t.printPacket(p, false) 440 } 441 442 if first && p[0] != msgKexInit { 443 return nil, fmt.Errorf("ssh: first packet should be msgKexInit") 444 } 445 446 if p[0] != msgKexInit { 447 return p, nil 448 } 449 450 firstKex := t.sessionID == nil 451 452 kex := pendingKex{ 453 done: make(chan error, 1), 454 otherInit: p, 455 } 456 t.startKex <- &kex 457 err = <-kex.done 458 459 if debugHandshake { 460 log.Printf("%s exited key exchange (first %v), err %v", t.id(), firstKex, err) 461 } 462 463 if err != nil { 464 return nil, err 465 } 466 467 t.resetReadThresholds() 468 469 // By default, a key exchange is hidden from higher layers by 470 // translating it into msgIgnore. 471 successPacket := []byte{msgIgnore} 472 if firstKex { 473 // sendKexInit() for the first kex waits for 474 // msgNewKeys so the authentication process is 475 // guaranteed to happen over an encrypted transport. 476 successPacket = []byte{msgNewKeys} 477 } 478 479 return successPacket, nil 480} 481 482const ( 483 kexStrictClient = "kex-strict-c-v00@openssh.com" 484 kexStrictServer = "kex-strict-s-v00@openssh.com" 485) 486 487// sendKexInit sends a key change message. 488func (t *handshakeTransport) sendKexInit() error { 489 t.mu.Lock() 490 defer t.mu.Unlock() 491 if t.sentInitMsg != nil { 492 // kexInits may be sent either in response to the other side, 493 // or because our side wants to initiate a key change, so we 494 // may have already sent a kexInit. In that case, don't send a 495 // second kexInit. 496 return nil 497 } 498 499 msg := &kexInitMsg{ 500 CiphersClientServer: t.config.Ciphers, 501 CiphersServerClient: t.config.Ciphers, 502 MACsClientServer: t.config.MACs, 503 MACsServerClient: t.config.MACs, 504 CompressionClientServer: supportedCompressions, 505 CompressionServerClient: supportedCompressions, 506 } 507 io.ReadFull(t.config.Rand, msg.Cookie[:]) 508 509 // We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm, 510 // and possibly to add the ext-info extension algorithm. Since the slice may be the 511 // user owned KeyExchanges, we create our own slice in order to avoid using user 512 // owned memory by mistake. 513 msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info 514 msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...) 515 516 isServer := len(t.hostKeys) > 0 517 if isServer { 518 for _, k := range t.hostKeys { 519 // If k is a MultiAlgorithmSigner, we restrict the signature 520 // algorithms. If k is a AlgorithmSigner, presume it supports all 521 // signature algorithms associated with the key format. If k is not 522 // an AlgorithmSigner, we can only assume it only supports the 523 // algorithms that matches the key format. (This means that Sign 524 // can't pick a different default). 525 keyFormat := k.PublicKey().Type() 526 527 switch s := k.(type) { 528 case MultiAlgorithmSigner: 529 for _, algo := range algorithmsForKeyFormat(keyFormat) { 530 if contains(s.Algorithms(), underlyingAlgo(algo)) { 531 msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo) 532 } 533 } 534 case AlgorithmSigner: 535 msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...) 536 default: 537 msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat) 538 } 539 } 540 541 if t.sessionID == nil { 542 msg.KexAlgos = append(msg.KexAlgos, kexStrictServer) 543 } 544 } else { 545 msg.ServerHostKeyAlgos = t.hostKeyAlgorithms 546 547 // As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what 548 // algorithms the server supports for public key authentication. See RFC 549 // 8308, Section 2.1. 550 // 551 // We also send the strict KEX mode extension algorithm, in order to opt 552 // into the strict KEX mode. 553 if firstKeyExchange := t.sessionID == nil; firstKeyExchange { 554 msg.KexAlgos = append(msg.KexAlgos, "ext-info-c") 555 msg.KexAlgos = append(msg.KexAlgos, kexStrictClient) 556 } 557 558 } 559 560 packet := Marshal(msg) 561 562 // writePacket destroys the contents, so save a copy. 563 packetCopy := make([]byte, len(packet)) 564 copy(packetCopy, packet) 565 566 if err := t.pushPacket(packetCopy); err != nil { 567 return err 568 } 569 570 t.sentInitMsg = msg 571 t.sentInitPacket = packet 572 573 return nil 574} 575 576var errSendBannerPhase = errors.New("ssh: SendAuthBanner outside of authentication phase") 577 578func (t *handshakeTransport) writePacket(p []byte) error { 579 t.mu.Lock() 580 defer t.mu.Unlock() 581 582 switch p[0] { 583 case msgKexInit: 584 return errors.New("ssh: only handshakeTransport can send kexInit") 585 case msgNewKeys: 586 return errors.New("ssh: only handshakeTransport can send newKeys") 587 case msgUserAuthBanner: 588 if t.userAuthComplete { 589 return errSendBannerPhase 590 } 591 case msgUserAuthSuccess: 592 t.userAuthComplete = true 593 } 594 595 if t.writeError != nil { 596 return t.writeError 597 } 598 599 if t.sentInitMsg != nil { 600 if len(t.pendingPackets) < maxPendingPackets { 601 // Copy the packet so the writer can reuse the buffer. 602 cp := make([]byte, len(p)) 603 copy(cp, p) 604 t.pendingPackets = append(t.pendingPackets, cp) 605 return nil 606 } 607 for t.sentInitMsg != nil { 608 // Block and wait for KEX to complete or an error. 609 t.writeCond.Wait() 610 if t.writeError != nil { 611 return t.writeError 612 } 613 } 614 } 615 616 if t.writeBytesLeft > 0 { 617 t.writeBytesLeft -= int64(len(p)) 618 } else { 619 t.requestKeyExchange() 620 } 621 622 if t.writePacketsLeft > 0 { 623 t.writePacketsLeft-- 624 } else { 625 t.requestKeyExchange() 626 } 627 628 if err := t.pushPacket(p); err != nil { 629 t.writeError = err 630 t.writeCond.Broadcast() 631 } 632 633 return nil 634} 635 636func (t *handshakeTransport) Close() error { 637 // Close the connection. This should cause the readLoop goroutine to wake up 638 // and close t.startKex, which will shut down kexLoop if running. 639 err := t.conn.Close() 640 641 // Wait for the kexLoop goroutine to complete. 642 // At that point we know that the readLoop goroutine is complete too, 643 // because kexLoop itself waits for readLoop to close the startKex channel. 644 <-t.kexLoopDone 645 646 return err 647} 648 649func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { 650 if debugHandshake { 651 log.Printf("%s entered key exchange", t.id()) 652 } 653 654 otherInit := &kexInitMsg{} 655 if err := Unmarshal(otherInitPacket, otherInit); err != nil { 656 return err 657 } 658 659 magics := handshakeMagics{ 660 clientVersion: t.clientVersion, 661 serverVersion: t.serverVersion, 662 clientKexInit: otherInitPacket, 663 serverKexInit: t.sentInitPacket, 664 } 665 666 clientInit := otherInit 667 serverInit := t.sentInitMsg 668 isClient := len(t.hostKeys) == 0 669 if isClient { 670 clientInit, serverInit = serverInit, clientInit 671 672 magics.clientKexInit = t.sentInitPacket 673 magics.serverKexInit = otherInitPacket 674 } 675 676 var err error 677 t.algorithms, err = findAgreedAlgorithms(isClient, clientInit, serverInit) 678 if err != nil { 679 return err 680 } 681 682 if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) { 683 t.strictMode = true 684 if err := t.conn.setStrictMode(); err != nil { 685 return err 686 } 687 } 688 689 // We don't send FirstKexFollows, but we handle receiving it. 690 // 691 // RFC 4253 section 7 defines the kex and the agreement method for 692 // first_kex_packet_follows. It states that the guessed packet 693 // should be ignored if the "kex algorithm and/or the host 694 // key algorithm is guessed wrong (server and client have 695 // different preferred algorithm), or if any of the other 696 // algorithms cannot be agreed upon". The other algorithms have 697 // already been checked above so the kex algorithm and host key 698 // algorithm are checked here. 699 if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) { 700 // other side sent a kex message for the wrong algorithm, 701 // which we have to ignore. 702 if _, err := t.conn.readPacket(); err != nil { 703 return err 704 } 705 } 706 707 kex, ok := kexAlgoMap[t.algorithms.KeyExchange] 708 if !ok { 709 return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.KeyExchange) 710 } 711 712 var result *kexResult 713 if len(t.hostKeys) > 0 { 714 result, err = t.server(kex, &magics) 715 } else { 716 result, err = t.client(kex, &magics) 717 } 718 719 if err != nil { 720 return err 721 } 722 723 firstKeyExchange := t.sessionID == nil 724 if firstKeyExchange { 725 t.sessionID = result.H 726 } 727 result.SessionID = t.sessionID 728 729 if err := t.conn.prepareKeyChange(t.algorithms, result); err != nil { 730 return err 731 } 732 if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil { 733 return err 734 } 735 736 // On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO 737 // message with the server-sig-algs extension if the client supports it. See 738 // RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9. 739 if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") { 740 supportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, ",") 741 extInfo := &extInfoMsg{ 742 NumExtensions: 2, 743 Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1), 744 } 745 extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs")) 746 extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...) 747 extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList)) 748 extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...) 749 extInfo.Payload = appendInt(extInfo.Payload, len("ping@openssh.com")) 750 extInfo.Payload = append(extInfo.Payload, "ping@openssh.com"...) 751 extInfo.Payload = appendInt(extInfo.Payload, 1) 752 extInfo.Payload = append(extInfo.Payload, "0"...) 753 if err := t.conn.writePacket(Marshal(extInfo)); err != nil { 754 return err 755 } 756 } 757 758 if packet, err := t.conn.readPacket(); err != nil { 759 return err 760 } else if packet[0] != msgNewKeys { 761 return unexpectedMessageError(msgNewKeys, packet[0]) 762 } 763 764 if firstKeyExchange { 765 // Indicates to the transport that the first key exchange is completed 766 // after receiving SSH_MSG_NEWKEYS. 767 t.conn.setInitialKEXDone() 768 } 769 770 return nil 771} 772 773// algorithmSignerWrapper is an AlgorithmSigner that only supports the default 774// key format algorithm. 775// 776// This is technically a violation of the AlgorithmSigner interface, but it 777// should be unreachable given where we use this. Anyway, at least it returns an 778// error instead of panicing or producing an incorrect signature. 779type algorithmSignerWrapper struct { 780 Signer 781} 782 783func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) { 784 if algorithm != underlyingAlgo(a.PublicKey().Type()) { 785 return nil, errors.New("ssh: internal error: algorithmSignerWrapper invoked with non-default algorithm") 786 } 787 return a.Sign(rand, data) 788} 789 790func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner { 791 for _, k := range hostKeys { 792 if s, ok := k.(MultiAlgorithmSigner); ok { 793 if !contains(s.Algorithms(), underlyingAlgo(algo)) { 794 continue 795 } 796 } 797 798 if algo == k.PublicKey().Type() { 799 return algorithmSignerWrapper{k} 800 } 801 802 k, ok := k.(AlgorithmSigner) 803 if !ok { 804 continue 805 } 806 for _, a := range algorithmsForKeyFormat(k.PublicKey().Type()) { 807 if algo == a { 808 return k 809 } 810 } 811 } 812 return nil 813} 814 815func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) { 816 hostKey := pickHostKey(t.hostKeys, t.algorithms.HostKey) 817 if hostKey == nil { 818 return nil, errors.New("ssh: internal error: negotiated unsupported signature type") 819 } 820 821 r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.HostKey) 822 return r, err 823} 824 825func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) { 826 result, err := kex.Client(t.conn, t.config.Rand, magics) 827 if err != nil { 828 return nil, err 829 } 830 831 hostKey, err := ParsePublicKey(result.HostKey) 832 if err != nil { 833 return nil, err 834 } 835 836 if err := verifyHostKeySignature(hostKey, t.algorithms.HostKey, result); err != nil { 837 return nil, err 838 } 839 840 err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey) 841 if err != nil { 842 return nil, err 843 } 844 845 return result, nil 846}