SHOW:
|
|
- or go back to the newest paste.
1 | #!/usr/bin/python | |
2 | ||
3 | import sys, posix, time, md5, binascii, socket, select | |
4 | ||
5 | class ApiRos: | |
6 | "Routeros api" | |
7 | def __init__(self, sk): | |
8 | self.sk = sk | |
9 | self.currenttag = 0 | |
10 | ||
11 | def login(self, username, pwd): | |
12 | for repl, attrs in self.talk(["/login"]): | |
13 | chal = binascii.unhexlify(attrs['=ret']) | |
14 | md = md5.new() | |
15 | md.update('\x00') | |
16 | md.update(pwd) | |
17 | md.update(chal) | |
18 | self.talk(["/login", "=name=" + username, | |
19 | "=response=00" + binascii.hexlify(md.digest())]) | |
20 | ||
21 | def talk(self, words): | |
22 | if self.writeSentence(words) == 0: return | |
23 | r = [] | |
24 | while 1: | |
25 | i = self.readSentence(); | |
26 | if len(i) == 0: continue | |
27 | reply = i[0] | |
28 | attrs = {} | |
29 | for w in i[1:]: | |
30 | j = w.find('=', 1) | |
31 | if (j == -1): | |
32 | attrs[w] = '' | |
33 | else: | |
34 | attrs[w[:j]] = w[j+1:] | |
35 | r.append((reply, attrs)) | |
36 | if reply == '!done': return r | |
37 | ||
38 | def writeSentence(self, words): | |
39 | ret = 0 | |
40 | for w in words: | |
41 | self.writeWord(w) | |
42 | ret += 1 | |
43 | self.writeWord('') | |
44 | return ret | |
45 | ||
46 | def readSentence(self): | |
47 | r = [] | |
48 | while 1: | |
49 | w = self.readWord() | |
50 | if w == '': return r | |
51 | r.append(w) | |
52 | ||
53 | def writeWord(self, w): | |
54 | print "<<< " + w | |
55 | self.writeLen(len(w)) | |
56 | self.writeStr(w) | |
57 | ||
58 | def readWord(self): | |
59 | ret = self.readStr(self.readLen()) | |
60 | print ">>> " + ret | |
61 | return ret | |
62 | ||
63 | def writeLen(self, l): | |
64 | if l < 0x80: | |
65 | self.writeStr(chr(l)) | |
66 | elif l < 0x4000: | |
67 | l |= 0x8000 | |
68 | self.writeStr(chr((l >> 8) & 0xFF)) | |
69 | self.writeStr(chr(l & 0xFF)) | |
70 | elif l < 0x200000: | |
71 | l |= 0xC00000 | |
72 | self.writeStr(chr((l >> 16) & 0xFF)) | |
73 | self.writeStr(chr((l >> 8) & 0xFF)) | |
74 | self.writeStr(chr(l & 0xFF)) | |
75 | elif l < 0x10000000: | |
76 | l |= 0xE0000000 | |
77 | self.writeStr(chr((l >> 24) & 0xFF)) | |
78 | self.writeStr(chr((l >> 16) & 0xFF)) | |
79 | self.writeStr(chr((l >> 8) & 0xFF)) | |
80 | self.writeStr(chr(l & 0xFF)) | |
81 | else: | |
82 | self.writeStr(chr(0xF0)) | |
83 | self.writeStr(chr((l >> 24) & 0xFF)) | |
84 | self.writeStr(chr((l >> 16) & 0xFF)) | |
85 | self.writeStr(chr((l >> 8) & 0xFF)) | |
86 | self.writeStr(chr(l & 0xFF)) | |
87 | ||
88 | def readLen(self): | |
89 | c = ord(self.readStr(1)) | |
90 | if (c & 0x80) == 0x00: | |
91 | pass | |
92 | elif (c & 0xC0) == 0x80: | |
93 | c &= ~0xC0 | |
94 | c <<= 8 | |
95 | c += ord(self.readStr(1)) | |
96 | elif (c & 0xE0) == 0xC0: | |
97 | c &= ~0xE0 | |
98 | c <<= 8 | |
99 | c += ord(self.readStr(1)) | |
100 | c <<= 8 | |
101 | c += ord(self.readStr(1)) | |
102 | elif (c & 0xF0) == 0xE0: | |
103 | c &= ~0xF0 | |
104 | c <<= 8 | |
105 | c += ord(self.readStr(1)) | |
106 | c <<= 8 | |
107 | c += ord(self.readStr(1)) | |
108 | c <<= 8 | |
109 | c += ord(self.readStr(1)) | |
110 | elif (c & 0xF8) == 0xF0: | |
111 | c = ord(self.readStr(1)) | |
112 | c <<= 8 | |
113 | c += ord(self.readStr(1)) | |
114 | c <<= 8 | |
115 | c += ord(self.readStr(1)) | |
116 | c <<= 8 | |
117 | c += ord(self.readStr(1)) | |
118 | return c | |
119 | ||
120 | def writeStr(self, str): | |
121 | n = 0; | |
122 | while n < len(str): | |
123 | r = self.sk.send(str[n:]) | |
124 | if r == 0: raise RuntimeError, "connection closed by remote end" | |
125 | n += r | |
126 | ||
127 | def readStr(self, length): | |
128 | ret = '' | |
129 | while len(ret) < length: | |
130 | s = self.sk.recv(length - len(ret)) | |
131 | if s == '': raise RuntimeError, "connection closed by remote end" | |
132 | ret += s | |
133 | return ret | |
134 | ||
135 | def main(): | |
136 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
137 | - | s.connect((sys.argv[1], 8728)) |
137 | + | s.connect((192.168.0.10, 8728)) |
138 | apiros = ApiRos(s); | |
139 | - | apiros.login(sys.argv[2], sys.argv[3]); |
139 | + | apiros.login(admin, ''); |
140 | ||
141 | inputsentence = [] | |
142 | ||
143 | while 1: | |
144 | r = select.select([s, sys.stdin], [], [], None) | |
145 | if s in r[0]: | |
146 | # something to read in socket, read sentence | |
147 | x = apiros.readSentence() | |
148 | ||
149 | if sys.stdin in r[0]: | |
150 | # read line from input and strip off newline | |
151 | l = sys.stdin.readline() | |
152 | l = l[:-1] | |
153 | ||
154 | # if empty line, send sentence and start with new | |
155 | # otherwise append to input sentence | |
156 | if l == '': | |
157 | apiros.writeSentence(inputsentence) | |
158 | inputsentence = [] | |
159 | else: | |
160 | inputsentence.append(l) | |
161 | ||
162 | if __name__ == '__main__': | |
163 | main() |