]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - contrib/encodelib.py
Remove references to "Win32" and "32-bit Windows".
[PuTTY.git] / contrib / encodelib.py
1 # Python module to make it easy to manually encode SSH packets, by
2 # supporting the various uint32, string, mpint primitives.
3 #
4 # The idea of this is that you can use it to manually construct key
5 # exchange sequences of interesting kinds, for testing purposes.
6
7 import struct, random
8
9 def boolean(b):
10     return "\1" if b else "\0"
11
12 def byte(b):
13     assert 0 <= b < 0x100
14     return chr(b)
15
16 def uint32(u):
17     assert 0 <= u < 0x100000000
18     return struct.pack(">I", u)
19
20 def uint64(u):
21     assert 0 <= u < 0x10000000000000000
22     return struct.pack(">L", u)
23
24 def string(s):
25     return uint32(len(s)) + s
26
27 def mpint(m):
28     s = ""
29     lastbyte = 0
30     while m > 0:
31         lastbyte = m & 0xFF
32         s = chr(lastbyte) + s
33         m >>= 8
34     if lastbyte & 0x80:
35         s = "\0" + s
36     return string(s)
37
38 def name_list(ns):
39     s = ""
40     for n in ns:
41         assert "," not in n
42         if s != "":
43             s += ","
44         s += n
45     return string(s)
46
47 def ssh_rsa_key_blob(modulus, exponent):
48     return string(string("ssh-rsa") + mpint(modulus) + mpint(exponent))
49
50 def ssh_rsa_signature_blob(signature):
51     return string(string("ssh-rsa") + mpint(signature))
52
53 def greeting(string):
54     # Greeting at the start of an SSH connection.
55     return string + "\r\n"
56
57 # Packet types.
58 SSH2_MSG_DISCONNECT = 1
59 SSH2_MSG_IGNORE = 2
60 SSH2_MSG_UNIMPLEMENTED = 3
61 SSH2_MSG_DEBUG = 4
62 SSH2_MSG_SERVICE_REQUEST = 5
63 SSH2_MSG_SERVICE_ACCEPT = 6
64 SSH2_MSG_KEXINIT = 20
65 SSH2_MSG_NEWKEYS = 21
66 SSH2_MSG_KEXDH_INIT = 30
67 SSH2_MSG_KEXDH_REPLY = 31
68 SSH2_MSG_KEX_DH_GEX_REQUEST_OLD = 30
69 SSH2_MSG_KEX_DH_GEX_GROUP = 31
70 SSH2_MSG_KEX_DH_GEX_INIT = 32
71 SSH2_MSG_KEX_DH_GEX_REPLY = 33
72 SSH2_MSG_KEX_DH_GEX_REQUEST = 34
73 SSH2_MSG_KEXRSA_PUBKEY = 30
74 SSH2_MSG_KEXRSA_SECRET = 31
75 SSH2_MSG_KEXRSA_DONE = 32
76 SSH2_MSG_USERAUTH_REQUEST = 50
77 SSH2_MSG_USERAUTH_FAILURE = 51
78 SSH2_MSG_USERAUTH_SUCCESS = 52
79 SSH2_MSG_USERAUTH_BANNER = 53
80 SSH2_MSG_USERAUTH_PK_OK = 60
81 SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ = 60
82 SSH2_MSG_USERAUTH_INFO_REQUEST = 60
83 SSH2_MSG_USERAUTH_INFO_RESPONSE = 61
84 SSH2_MSG_GLOBAL_REQUEST = 80
85 SSH2_MSG_REQUEST_SUCCESS = 81
86 SSH2_MSG_REQUEST_FAILURE = 82
87 SSH2_MSG_CHANNEL_OPEN = 90
88 SSH2_MSG_CHANNEL_OPEN_CONFIRMATION = 91
89 SSH2_MSG_CHANNEL_OPEN_FAILURE = 92
90 SSH2_MSG_CHANNEL_WINDOW_ADJUST = 93
91 SSH2_MSG_CHANNEL_DATA = 94
92 SSH2_MSG_CHANNEL_EXTENDED_DATA = 95
93 SSH2_MSG_CHANNEL_EOF = 96
94 SSH2_MSG_CHANNEL_CLOSE = 97
95 SSH2_MSG_CHANNEL_REQUEST = 98
96 SSH2_MSG_CHANNEL_SUCCESS = 99
97 SSH2_MSG_CHANNEL_FAILURE = 100
98 SSH2_MSG_USERAUTH_GSSAPI_RESPONSE = 60
99 SSH2_MSG_USERAUTH_GSSAPI_TOKEN = 61
100 SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE = 63
101 SSH2_MSG_USERAUTH_GSSAPI_ERROR = 64
102 SSH2_MSG_USERAUTH_GSSAPI_ERRTOK = 65
103 SSH2_MSG_USERAUTH_GSSAPI_MIC = 66
104
105 def clearpkt(msgtype, *stuff):
106     # SSH-2 binary packet, in the cleartext format used for initial
107     # setup and kex.
108     s = byte(msgtype)
109     for thing in stuff:
110         s += thing
111     padlen = 0
112     while padlen < 4 or len(s) % 8 != 3:
113         padlen += 1
114         s += byte(random.randint(0,255))
115     s = byte(padlen) + s
116     return string(s)
117
118 def decode_uint32(s):
119     assert len(s) == 4
120     return struct.unpack(">I", s)[0]
121
122 def read_clearpkt(fh):
123     length_field = fh.read(4)
124     s = fh.read(decode_uint32(length_field))
125     import sys
126     padlen = ord(s[0])
127     s = s[1:-padlen]
128     msgtype = ord(s[0])
129     return msgtype, s[1:]