0
# SSH and Terminal Protocols
1
2
SSH version 2 protocol implementation with client, server, SFTP support, and terminal handling capabilities. Twisted Conch provides comprehensive SSH functionality including key management, authentication, channel forwarding, and terminal protocols.
3
4
## Capabilities
5
6
### SSH Transport
7
8
Core SSH transport layer handling encryption, key exchange, and connection establishment.
9
10
```python { .api }
11
class transport.SSHTransportBase:
12
"""
13
Base class for SSH transport implementations.
14
15
Attributes:
16
- supportedCiphers: List of supported encryption ciphers
17
- supportedMACs: List of supported MAC algorithms
18
- supportedKeyExchanges: List of supported key exchange methods
19
"""
20
supportedCiphers = None
21
supportedMACs = None
22
supportedKeyExchanges = None
23
24
class transport.SSHClientTransport(transport.SSHTransportBase):
25
"""
26
SSH client transport protocol.
27
"""
28
def verifyHostKey(self, pubKey, fingerprint):
29
"""
30
Verify the server's host key.
31
32
Args:
33
pubKey (bytes): Server's public key
34
fingerprint (str): Key fingerprint
35
36
Returns:
37
Deferred: Fires when verification complete
38
"""
39
40
def connectionSecure(self):
41
"""Called when SSH connection is secure and ready for authentication."""
42
43
class transport.SSHServerTransport(transport.SSHTransportBase):
44
"""
45
SSH server transport protocol.
46
"""
47
def getPublicKeys(self):
48
"""
49
Get server's public keys.
50
51
Returns:
52
dict: Mapping of key types to public keys
53
"""
54
55
def getPrivateKeys(self):
56
"""
57
Get server's private keys.
58
59
Returns:
60
dict: Mapping of key types to private keys
61
"""
62
```
63
64
### SSH Connection
65
66
SSH connection layer managing channels and requests.
67
68
```python { .api }
69
class connection.SSHConnection:
70
"""
71
SSH connection protocol managing multiple channels.
72
73
Attributes:
74
- transport: Underlying SSH transport
75
- channels: Dict of active channels
76
"""
77
transport = None
78
channels = None
79
80
def openChannel(self, channel, extraData=b''):
81
"""
82
Open a new SSH channel.
83
84
Args:
85
channel: Channel instance
86
extraData (bytes): Extra channel data
87
88
Returns:
89
Deferred: Fires when channel is open
90
"""
91
92
def sendRequest(self, request, data, wantReply=False):
93
"""
94
Send a global request.
95
96
Args:
97
request (bytes): Request type
98
data (bytes): Request data
99
wantReply (bool): Whether to wait for reply
100
101
Returns:
102
Deferred or None: Reply data if wantReply=True
103
"""
104
```
105
106
### SSH Authentication
107
108
Client and server authentication handling.
109
110
```python { .api }
111
class userauth.SSHUserAuthClient:
112
"""
113
SSH client user authentication.
114
"""
115
def getPassword(self, prompt=None):
116
"""
117
Get password for authentication.
118
119
Args:
120
prompt (str): Password prompt
121
122
Returns:
123
Deferred[str]: Password
124
"""
125
126
def getPrivateKey(self):
127
"""
128
Get private key for public key authentication.
129
130
Returns:
131
Deferred[Key]: Private key object
132
"""
133
134
def getPublicKey(self):
135
"""
136
Get public key for authentication.
137
138
Returns:
139
bytes: Public key data
140
"""
141
142
class userauth.SSHUserAuthServer:
143
"""
144
SSH server user authentication.
145
"""
146
def auth_password(self, packet):
147
"""
148
Handle password authentication.
149
150
Args:
151
packet (bytes): Authentication packet
152
153
Returns:
154
Deferred[bool]: Success/failure
155
"""
156
157
def auth_publickey(self, packet):
158
"""
159
Handle public key authentication.
160
161
Args:
162
packet (bytes): Authentication packet
163
164
Returns:
165
Deferred[bool]: Success/failure
166
"""
167
```
168
169
### SSH Channels
170
171
Base classes and implementations for SSH channels.
172
173
```python { .api }
174
class channel.SSHChannel:
175
"""
176
Base class for SSH channels.
177
178
Attributes:
179
- conn: SSH connection object
180
- data: Channel-specific data
181
- localWindowSize: Local window size
182
- remoteWindowSize: Remote window size
183
"""
184
conn = None
185
data = None
186
localWindowSize = None
187
remoteWindowSize = None
188
189
def channelOpen(self, specificData):
190
"""
191
Called when channel is opened.
192
193
Args:
194
specificData (bytes): Channel-specific data
195
"""
196
197
def dataReceived(self, data):
198
"""
199
Called when data is received on channel.
200
201
Args:
202
data (bytes): Received data
203
"""
204
205
def extReceived(self, dataType, data):
206
"""
207
Called when extended data is received.
208
209
Args:
210
dataType (int): Extended data type
211
data (bytes): Extended data
212
"""
213
214
def eofReceived(self):
215
"""Called when EOF is received on channel."""
216
217
def closeReceived(self):
218
"""Called when channel close is received."""
219
220
def write(self, data):
221
"""
222
Write data to channel.
223
224
Args:
225
data (bytes): Data to write
226
227
Returns:
228
int: Number of bytes written
229
"""
230
231
def writeExtended(self, dataType, data):
232
"""
233
Write extended data to channel.
234
235
Args:
236
dataType (int): Extended data type
237
data (bytes): Data to write
238
"""
239
240
def loseConnection(self):
241
"""Close the channel."""
242
```
243
244
### SSH Key Management
245
246
SSH key handling, generation, and format conversion.
247
248
```python { .api }
249
class keys.Key:
250
"""
251
SSH key wrapper supporting multiple key formats.
252
253
Attributes:
254
- keyObject: Underlying cryptographic key object
255
- type: Key type string (e.g., 'rsa', 'ed25519')
256
"""
257
keyObject = None
258
type = None
259
260
@classmethod
261
def fromString(cls, data, type=None, passphrase=None):
262
"""
263
Load key from string data.
264
265
Args:
266
data (bytes): Key data
267
type (str): Key type hint
268
passphrase (bytes): Passphrase for encrypted keys
269
270
Returns:
271
Key: Key object
272
"""
273
274
@classmethod
275
def fromFile(cls, filename, type=None, passphrase=None):
276
"""
277
Load key from file.
278
279
Args:
280
filename (str): Key file path
281
type (str): Key type hint
282
passphrase (bytes): Passphrase for encrypted keys
283
284
Returns:
285
Key: Key object
286
"""
287
288
def toString(self, type, extra=None):
289
"""
290
Export key to string format.
291
292
Args:
293
type (str): Output format ('openssh', 'lsh', 'agentv3')
294
extra: Extra parameters for format
295
296
Returns:
297
bytes: Key data in specified format
298
"""
299
300
def public(self):
301
"""
302
Get public key.
303
304
Returns:
305
Key: Public key object
306
"""
307
308
def isPublic(self):
309
"""
310
Check if this is a public key.
311
312
Returns:
313
bool: True if public key
314
"""
315
316
def fingerprint(self):
317
"""
318
Get key fingerprint.
319
320
Returns:
321
bytes: Key fingerprint
322
"""
323
324
def sign(self, data):
325
"""
326
Sign data with private key.
327
328
Args:
329
data (bytes): Data to sign
330
331
Returns:
332
bytes: Signature
333
"""
334
335
def verify(self, signature, data):
336
"""
337
Verify signature with public key.
338
339
Args:
340
signature (bytes): Signature to verify
341
data (bytes): Original data
342
343
Returns:
344
bool: True if signature is valid
345
"""
346
347
def keys.getPublicKeyString(data, type=None):
348
"""
349
Extract public key string from key data.
350
351
Args:
352
data (bytes): Key data
353
type (str): Key type hint
354
355
Returns:
356
bytes: Public key string
357
"""
358
359
def keys.getPrivateKeyObject(data, passphrase=None):
360
"""
361
Get private key object from key data.
362
363
Args:
364
data (bytes): Private key data
365
passphrase (bytes): Key passphrase
366
367
Returns:
368
Key: Private key object
369
"""
370
371
def keys.encryptKey(keyObject, passphrase):
372
"""
373
Encrypt a private key with passphrase.
374
375
Args:
376
keyObject: Private key object
377
passphrase (bytes): Encryption passphrase
378
379
Returns:
380
bytes: Encrypted key data
381
"""
382
```
383
384
**SSH Key Usage Example**:
385
386
```python
387
from twisted.conch.ssh import keys
388
389
# Load private key from file
390
private_key = keys.Key.fromFile('/path/to/private_key')
391
392
# Get public key
393
public_key = private_key.public()
394
395
# Get fingerprint
396
fingerprint = public_key.fingerprint()
397
print(f"Key fingerprint: {fingerprint}")
398
399
# Sign data
400
data = b"Hello, world!"
401
signature = private_key.sign(data)
402
403
# Verify signature
404
is_valid = public_key.verify(signature, data)
405
print(f"Signature valid: {is_valid}")
406
```
407
408
### SFTP File Transfer
409
410
SSH File Transfer Protocol implementation for file operations over SSH.
411
412
```python { .api }
413
class filetransfer.FileTransferServer:
414
"""
415
SFTP server implementation.
416
417
Attributes:
418
- avatar: User avatar object
419
"""
420
avatar = None
421
422
def packet_OPEN(self, data):
423
"""Handle file open request."""
424
425
def packet_CLOSE(self, data):
426
"""Handle file close request."""
427
428
def packet_READ(self, data):
429
"""Handle file read request."""
430
431
def packet_WRITE(self, data):
432
"""Handle file write request."""
433
434
def packet_STAT(self, data):
435
"""Handle file stat request."""
436
437
class filetransfer.FileTransferClient:
438
"""
439
SFTP client implementation.
440
"""
441
def openFile(self, filename, flags, attrs):
442
"""
443
Open a remote file.
444
445
Args:
446
filename (bytes): File path
447
flags (int): Open flags
448
attrs: File attributes
449
450
Returns:
451
Deferred[SFTPFile]: File object
452
"""
453
454
def removeFile(self, filename):
455
"""
456
Remove a remote file.
457
458
Args:
459
filename (bytes): File path
460
461
Returns:
462
Deferred: Completion indicator
463
"""
464
465
def renameFile(self, oldPath, newPath):
466
"""
467
Rename a remote file.
468
469
Args:
470
oldPath (bytes): Current file path
471
newPath (bytes): New file path
472
473
Returns:
474
Deferred: Completion indicator
475
"""
476
477
def makeDirectory(self, path, attrs):
478
"""
479
Create a remote directory.
480
481
Args:
482
path (bytes): Directory path
483
attrs: Directory attributes
484
485
Returns:
486
Deferred: Completion indicator
487
"""
488
489
def getAttrs(self, path):
490
"""
491
Get file attributes.
492
493
Args:
494
path (bytes): File path
495
496
Returns:
497
Deferred[dict]: File attributes
498
"""
499
500
class filetransfer.SFTPFile:
501
"""
502
SFTP file object for reading/writing remote files.
503
"""
504
def readChunk(self, offset, length):
505
"""
506
Read chunk of file data.
507
508
Args:
509
offset (int): Read offset
510
length (int): Bytes to read
511
512
Returns:
513
Deferred[bytes]: File data
514
"""
515
516
def writeChunk(self, offset, data):
517
"""
518
Write chunk of file data.
519
520
Args:
521
offset (int): Write offset
522
data (bytes): Data to write
523
524
Returns:
525
Deferred: Completion indicator
526
"""
527
528
def getAttrs(self):
529
"""
530
Get file attributes.
531
532
Returns:
533
Deferred[dict]: File attributes
534
"""
535
536
def close(self):
537
"""
538
Close the file.
539
540
Returns:
541
Deferred: Completion indicator
542
"""
543
```
544
545
### SSH Agent
546
547
SSH agent protocol for managing SSH keys.
548
549
```python { .api }
550
class agent.SSHAgentClient:
551
"""
552
SSH agent client for communicating with ssh-agent.
553
"""
554
def requestIdentities(self):
555
"""
556
Request list of identities from agent.
557
558
Returns:
559
Deferred[list]: List of (key_blob, comment) tuples
560
"""
561
562
def signData(self, blob, data):
563
"""
564
Request agent to sign data with key.
565
566
Args:
567
blob (bytes): Key blob
568
data (bytes): Data to sign
569
570
Returns:
571
Deferred[bytes]: Signature
572
"""
573
574
def addIdentity(self, key, comment=b''):
575
"""
576
Add identity to agent.
577
578
Args:
579
key: Private key object
580
comment (bytes): Key comment
581
582
Returns:
583
Deferred: Completion indicator
584
"""
585
586
def removeIdentity(self, blob):
587
"""
588
Remove identity from agent.
589
590
Args:
591
blob (bytes): Key blob to remove
592
593
Returns:
594
Deferred: Completion indicator
595
"""
596
597
class agent.SSHAgentServer:
598
"""
599
SSH agent server implementation.
600
"""
601
def __init__(self):
602
self.keys = {} # Storage for keys
603
604
def getPublicKeys(self):
605
"""
606
Get list of public keys.
607
608
Returns:
609
list: List of public key objects
610
"""
611
612
def getPrivateKey(self, publicKey):
613
"""
614
Get private key for given public key.
615
616
Args:
617
publicKey: Public key object
618
619
Returns:
620
Key or None: Private key if available
621
"""
622
```
623
624
### Terminal Protocols
625
626
Terminal emulation and line-oriented protocols.
627
628
```python { .api }
629
class insults.ServerProtocol:
630
"""
631
Terminal server protocol with VT100 emulation.
632
633
Attributes:
634
- width: Terminal width in characters
635
- height: Terminal height in characters
636
"""
637
width = 80
638
height = 24
639
640
def terminalSize(self, width, height):
641
"""
642
Handle terminal size change.
643
644
Args:
645
width (int): New terminal width
646
height (int): New terminal height
647
"""
648
649
def keystroke(self, keyID, modifier):
650
"""
651
Handle keystroke input.
652
653
Args:
654
keyID: Key identifier
655
modifier: Key modifiers
656
"""
657
658
def write(self, data):
659
"""
660
Write data to terminal.
661
662
Args:
663
data (bytes): Data to write
664
"""
665
666
class manhole.ColoredManhole:
667
"""
668
Interactive Python shell with syntax highlighting.
669
"""
670
def __init__(self, namespace=None):
671
"""
672
Args:
673
namespace (dict): Python namespace for shell
674
"""
675
676
class recvline.HistoricRecvLine:
677
"""
678
Line receiver with command history.
679
680
Attributes:
681
- historyLines: List of command history
682
- historyPosition: Current position in history
683
"""
684
historyLines = None
685
historyPosition = None
686
687
def lineReceived(self, line):
688
"""
689
Handle received line.
690
691
Args:
692
line (str): Received line
693
"""
694
```
695
696
### SSH Factory
697
698
Factory classes for creating SSH protocol instances.
699
700
```python { .api }
701
class factory.SSHFactory:
702
"""
703
Factory for SSH protocol instances.
704
705
Attributes:
706
- publicKeys: Dict of server public keys
707
- privateKeys: Dict of server private keys
708
- services: Dict of available SSH services
709
"""
710
publicKeys = None
711
privateKeys = None
712
services = None
713
714
def getPublicKeys(self):
715
"""
716
Get server's public keys.
717
718
Returns:
719
dict: Public keys by algorithm name
720
"""
721
722
def getPrivateKeys(self):
723
"""
724
Get server's private keys.
725
726
Returns:
727
dict: Private keys by algorithm name
728
"""
729
730
def getPrimes(self):
731
"""
732
Get Diffie-Hellman primes.
733
734
Returns:
735
dict: DH primes by size
736
"""
737
738
def getService(self, transport, name):
739
"""
740
Get SSH service by name.
741
742
Args:
743
transport: SSH transport
744
name (bytes): Service name
745
746
Returns:
747
Service instance or None
748
"""
749
```
750
751
**SSH Server Usage Example**:
752
753
```python
754
from twisted.conch import manhole_ssh
755
from twisted.conch.ssh import factory, keys
756
from twisted.internet import reactor, endpoints
757
from twisted.cred import portal, checkers
758
759
# Create SSH factory
760
ssh_factory = factory.SSHFactory()
761
762
# Load server keys
763
with open('/etc/ssh/ssh_host_rsa_key') as key_file:
764
ssh_factory.privateKeys['ssh-rsa'] = keys.Key.fromString(key_file.read())
765
ssh_factory.publicKeys['ssh-rsa'] = ssh_factory.privateKeys['ssh-rsa'].public()
766
767
# Setup authentication
768
checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
769
checker.addUser(b"admin", b"password")
770
771
realm = manhole_ssh.TerminalRealm()
772
portal_obj = portal.Portal(realm, [checker])
773
774
ssh_factory.portal = portal_obj
775
776
# Start SSH server
777
endpoint = endpoints.TCP4ServerEndpoint(reactor, 2222)
778
endpoint.listen(ssh_factory)
779
780
print("SSH server listening on port 2222")
781
reactor.run()
782
```