Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
498 changes: 488 additions & 10 deletions Sources/NIOSSH/Connection State Machine/SSHConnectionStateMachine.swift

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions Sources/NIOSSH/Connection State Machine/States/ActiveState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import NIO

extension SSHConnectionStateMachine {
/// The state of a state machine that has completed user auth and key exchange and is
Expand All @@ -24,10 +25,37 @@ extension SSHConnectionStateMachine {

internal var parser: SSHPacketParser

internal var remoteVersion: String

internal var protectionSchemes: [NIOSSHTransportProtection.Type]

internal var sessionIdentifier: ByteBuffer

init(_ previous: UserAuthenticationState) {
self.role = previous.role
self.serializer = previous.serializer
self.parser = previous.parser
self.remoteVersion = previous.remoteVersion
self.protectionSchemes = previous.protectionSchemes
self.sessionIdentifier = previous.sessionIdentifier
}

init(_ previous: RekeyingReceivedNewKeysState) {
self.role = previous.role
self.serializer = previous.serializer
self.parser = previous.parser
self.remoteVersion = previous.remoteVersion
self.protectionSchemes = previous.protectionSchemes
self.sessionIdentifier = previous.sessionIdentifier
}

init(_ previous: RekeyingSentNewKeysState) {
self.role = previous.role
self.serializer = previous.serializer
self.parser = previous.parser
self.remoteVersion = previous.remoteVersion
self.protectionSchemes = previous.protectionSchemes
self.sessionIdentifier = previous.sessionIdentifier
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ extension SSHConnectionStateMachine {
/// The packet serializer used by this state machine.
var serializer: SSHPacketSerializer

var remoteVersion: String

var protectionSchemes: [NIOSSHTransportProtection.Type]

/// The backing state machine.
var keyExchangeStateMachine: SSHKeyExchangeStateMachine

init(sentVersionState state: SentVersionState, allocator: ByteBufferAllocator, remoteVersion: String) {
self.role = state.role
self.parser = state.parser
self.serializer = state.serializer
self.keyExchangeStateMachine = SSHKeyExchangeStateMachine(allocator: allocator, role: state.role, remoteVersion: remoteVersion, protectionSchemes: state.protectionSchemes)
self.remoteVersion = remoteVersion
self.protectionSchemes = state.protectionSchemes
self.keyExchangeStateMachine = SSHKeyExchangeStateMachine(allocator: allocator, role: state.role, remoteVersion: remoteVersion, protectionSchemes: state.protectionSchemes, previousSessionIdentifier: nil)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import NIO

extension SSHConnectionStateMachine {
/// The state of a state machine that has received a KeyExchangeInit message after
/// having been active. In this state, no further channel messages may be sent by the
/// remote peer until key exchange is done. We can send channel messages _and_ key exchange init.
struct ReceivedKexInitWhenActiveState {
/// The role of the connection
let role: SSHConnectionRole

/// The packet serializer used by this state machine.
internal var serializer: SSHPacketSerializer

internal var parser: SSHPacketParser

internal var remoteVersion: String

internal var protectionSchemes: [NIOSSHTransportProtection.Type]

internal var keyExchangeStateMachine: SSHKeyExchangeStateMachine

internal var sessionIdentifier: ByteBuffer

init(_ previous: ActiveState, allocator: ByteBufferAllocator) {
self.role = previous.role
self.serializer = previous.serializer
self.parser = previous.parser
self.remoteVersion = previous.remoteVersion
self.protectionSchemes = previous.protectionSchemes
self.sessionIdentifier = previous.sessionIdentifier
self.keyExchangeStateMachine = SSHKeyExchangeStateMachine(allocator: allocator, role: previous.role, remoteVersion: previous.remoteVersion, protectionSchemes: previous.protectionSchemes, previousSessionIdentifier: self.sessionIdentifier)
}
}
}

extension SSHConnectionStateMachine.ReceivedKexInitWhenActiveState: AcceptsKeyExchangeMessages {}

extension SSHConnectionStateMachine.ReceivedKexInitWhenActiveState: SendsChannelMessages {}

extension SSHConnectionStateMachine.ReceivedKexInitWhenActiveState: SendsKeyExchangeMessages {}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ extension SSHConnectionStateMachine {
/// The packet serializer used by this state machine.
var serializer: SSHPacketSerializer

var remoteVersion: String

var protectionSchemes: [NIOSSHTransportProtection.Type]

var sessionIdentifier: ByteBuffer

/// The backing state machine.
var keyExchangeStateMachine: SSHKeyExchangeStateMachine

Expand All @@ -38,12 +44,15 @@ extension SSHConnectionStateMachine {
self.role = state.role
self.parser = state.parser
self.serializer = state.serializer
self.remoteVersion = state.remoteVersion
self.protectionSchemes = state.protectionSchemes
self.keyExchangeStateMachine = state.keyExchangeStateMachine

// We force unwrap the session ID because it's programmer error to not have it at this time.
self.sessionIdentifier = state.keyExchangeStateMachine.sessionID!
self.userAuthStateMachine = UserAuthenticationStateMachine(role: self.role,
loop: loop,
sessionID: state.keyExchangeStateMachine.sessionID!)
sessionID: self.sessionIdentifier)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIO

extension SSHConnectionStateMachine {
/// The state of a state machine that has received new keys after a key exchange operation from active,
/// but has not yet sent its new keys to the peer.
struct RekeyingReceivedNewKeysState {
/// The role of the connection
let role: SSHConnectionRole

/// The packet parser.
var parser: SSHPacketParser

/// The packet serializer used by this state machine.
var serializer: SSHPacketSerializer

var remoteVersion: String

var protectionSchemes: [NIOSSHTransportProtection.Type]

var sessionIdentifier: ByteBuffer

/// The backing state machine.
var keyExchangeStateMachine: SSHKeyExchangeStateMachine

init(_ previousState: RekeyingState) {
self.role = previousState.role
self.parser = previousState.parser
self.serializer = previousState.serializer
self.remoteVersion = previousState.remoteVersion
self.protectionSchemes = previousState.protectionSchemes
self.sessionIdentifier = previousState.sessionIdentifier
self.keyExchangeStateMachine = previousState.keyExchangeStateMachine
}
}
}

extension SSHConnectionStateMachine.RekeyingReceivedNewKeysState: SendsKeyExchangeMessages {}

extension SSHConnectionStateMachine.RekeyingReceivedNewKeysState: AcceptsChannelMessages {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIO

extension SSHConnectionStateMachine {
/// The state of a state machine that has sent new keys after a key exchange operation from an active channel,
/// but has not yet received the new keys from the peer.
struct RekeyingSentNewKeysState {
/// The role of the connection
let role: SSHConnectionRole

/// The packet parser.
var parser: SSHPacketParser

/// The packet serializer used by this state machine.
var serializer: SSHPacketSerializer

var remoteVersion: String

var protectionSchemes: [NIOSSHTransportProtection.Type]

var sessionIdentifier: ByteBuffer

/// The backing state machine.
var keyExchangeStateMachine: SSHKeyExchangeStateMachine

init(_ previousState: RekeyingState) {
self.role = previousState.role
self.parser = previousState.parser
self.serializer = previousState.serializer
self.remoteVersion = previousState.remoteVersion
self.protectionSchemes = previousState.protectionSchemes
self.sessionIdentifier = previousState.sessionIdentifier
self.keyExchangeStateMachine = previousState.keyExchangeStateMachine
}
}
}

extension SSHConnectionStateMachine.RekeyingSentNewKeysState: AcceptsKeyExchangeMessages {}

extension SSHConnectionStateMachine.RekeyingSentNewKeysState: SendsChannelMessages {}
62 changes: 62 additions & 0 deletions Sources/NIOSSH/Connection State Machine/States/RekeyingState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import NIO

extension SSHConnectionStateMachine {
/// The state of a state machine that is actively engaged in a key exchange operation having been active before.
struct RekeyingState {
/// The role of the connection
let role: SSHConnectionRole

/// The packet parser.
var parser: SSHPacketParser

/// The packet serializer used by this state machine.
var serializer: SSHPacketSerializer

var remoteVersion: String

var protectionSchemes: [NIOSSHTransportProtection.Type]

var sessionIdentifier: ByteBuffer

/// The backing state machine.
var keyExchangeStateMachine: SSHKeyExchangeStateMachine

init(_ previousState: ReceivedKexInitWhenActiveState) {
self.role = previousState.role
self.parser = previousState.parser
self.serializer = previousState.serializer
self.remoteVersion = previousState.remoteVersion
self.protectionSchemes = previousState.protectionSchemes
self.sessionIdentifier = previousState.sessionIdentifier
self.keyExchangeStateMachine = previousState.keyExchangeStateMachine
}

init(_ previousState: SentKexInitWhenActiveState) {
self.role = previousState.role
self.parser = previousState.parser
self.serializer = previousState.serializer
self.remoteVersion = previousState.remoteVersion
self.protectionSchemes = previousState.protectionSchemes
self.sessionIdentifier = previousState.sessionIdentitifier
self.keyExchangeStateMachine = previousState.keyExchangeStateMachine
}
}
}

extension SSHConnectionStateMachine.RekeyingState: AcceptsKeyExchangeMessages {}

extension SSHConnectionStateMachine.RekeyingState: SendsKeyExchangeMessages {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import NIO

extension SSHConnectionStateMachine {
/// The state of a state machine that has sent a KeyExchangeInit message after
/// having been active. In this state, no further channel messages may be sent by the
/// us until key exchange is done. We can receive channel messages _and_ key exchange init.
struct SentKexInitWhenActiveState {
/// The role of the connection
let role: SSHConnectionRole

/// The packet serializer used by this state machine.
internal var serializer: SSHPacketSerializer

internal var parser: SSHPacketParser

internal var remoteVersion: String

internal var protectionSchemes: [NIOSSHTransportProtection.Type]

internal var sessionIdentitifier: ByteBuffer

internal var keyExchangeStateMachine: SSHKeyExchangeStateMachine

init(_ previous: ActiveState, allocator: ByteBufferAllocator) {
self.role = previous.role
self.serializer = previous.serializer
self.parser = previous.parser
self.remoteVersion = previous.remoteVersion
self.protectionSchemes = previous.protectionSchemes
self.sessionIdentitifier = previous.sessionIdentifier
self.keyExchangeStateMachine = SSHKeyExchangeStateMachine(allocator: allocator, role: self.role, remoteVersion: self.remoteVersion, protectionSchemes: self.protectionSchemes, previousSessionIdentifier: previous.sessionIdentifier)
}
}
}

extension SSHConnectionStateMachine.SentKexInitWhenActiveState: AcceptsKeyExchangeMessages {}

extension SSHConnectionStateMachine.SentKexInitWhenActiveState: AcceptsChannelMessages {}

extension SSHConnectionStateMachine.SentKexInitWhenActiveState: SendsKeyExchangeMessages {}
Loading