· 8 years ago · Jan 22, 2017, 09:40 PM
1#!/usr/bin/python3
2import requests
3import logging
4import time
5import sys
6import json
7import os
8import signal
9import shutil
10
11
12from urllib.error import HTTPError
13from urllib import parse
14from enum import IntEnum
15from logging.handlers import RotatingFileHandler
16
17import steam
18from steam.guard import SteamAuthenticatorError, SteamAuthenticator
19from steam.webauth import MobileWebAuth
20
21################################################################################
22# Account functions
23def get_sessionid(session):
24 headers = {
25 'X-Requested-With' : 'com.valvesoftware.android.steam.community'
26 }
27 session.session.get('https://steamcommunity.com/login', params={
28 'oauth_client_id' : 'DE45CD61',
29 'oauth_scope' : 'read_profile write_profile read_client write_client'},
30 headers=headers, timeout=15)
31 return session.session.cookies.get_dict()['sessionid']
32
33def get_mafile(secrets, medium, fully_enrolled):
34 cookies = medium.session.cookies.get_dict()
35 data = dict()
36 data.update(secrets)
37
38 #for i in data.items():
39 # data[i[0]] = i[1].replace('/','\\/') if isinstance(i[1],str) else i[1]
40
41 data['device_id'] = steam.guard.generate_device_id(medium.steam_id)
42 data['fully_enrolled'] = fully_enrolled
43 data['Session'] = {
44 'SessionID' : cookies['sessionid'],
45 'SteamLogin' : parse.unquote(cookies['steamLogin']),
46 'SteamLoginSecure': parse.unquote(cookies['steamLoginSecure']),
47 'WebCookie' : None,
48 'OAuthToken' : medium.oauth_token,
49 'SteamID' : medium.steam_id.as_64
50 }
51 return data
52
53def resend_sms(session, sessionid):
54 resp = session.session.get("https://store.steampowered.com/phone/add_ajaxop",
55 params={
56 "op": "resend_sms",
57 "input": "",
58 "sessionID": sessionid,
59 "confirmed": 0
60 },timeout=10).json()
61 if resp['success']:
62 return
63 else:
64 raise SteamAuthenticatorError('Failed sending sms: ', resp)
65
66def check_has_phone(session, sessionid):
67 resp = session.session.post("https://steamcommunity.com/steamguard/phoneajax",
68 data={
69 "op": "has_phone",
70 "arg": "",
71 "sessionid": sessionid,
72 },
73 timeout=10).json()
74 if resp['success']:
75 return resp['has_phone']
76 else:
77 raise SteamAuthenticatorError('Failed phone request: ', resp)
78
79def add_phone(phone_number, session, sessionid):
80 resp = session.session.post('https://steamcommunity.com/steamguard/phoneajax',
81 data = {
82 "op": "add_phone_number",
83 "arg": phone_number,
84 "sessionid": sessionid
85 },
86 timeout=10).json()
87 if not resp['success']:
88 raise SteamAuthenticatorError('Failed adding phone: ', resp)
89 return resp
90
91def verify_sms(code, session, sessionid):
92 resp = session.session.post('https://steamcommunity.com/steamguard/phoneajax',
93 data = {
94 "op": "check_sms_code",
95 "arg": code,
96 "sessionid": sessionid
97 },
98 timeout=10).json()
99 if not resp['success']:
100 raise SteamAuthenticatorError('Failed adding phone: ', resp)
101 return resp
102
103################################################################################
104
105
106
107################################################################################
108# Onlinesim functions
109def get_balance():
110 logger.debug('Getting balance')
111 while not ('resp' in locals() and resp.text):
112 resp = requests.get(url.format('getBalance'),
113 params={
114 'apikey' : apikey
115 },
116 timeout=10)
117 print(resp.text)
118 resp = resp.json()
119 logger.debug(str(resp))
120 if resp['response'] != '1':
121 raise ApiError('Cannot get balance: %s' % resp['response'])
122 return resp['balance']
123
124def get_state(tzid):
125 logger.debug('Getting state')
126 while True:
127 resp = requests.get(url.format('getState'),
128 params={
129 'tzid' : tzid,
130 'apikey' : apikey
131 },
132 timeout=10)
133 if not (resp and resp.text):
134 logger.debug('Has no response')
135 continue
136 print(resp.text)
137 resp = resp.json()
138 if isinstance(resp, list) and resp[0]['response'] == 'TZ_INPOOL':
139 logger.debug('Waiting for number')
140 time.sleep(1)
141 continue
142 break
143 logger.debug(str(resp))
144 if not isinstance(resp, list) and resp['response'] == 'ERROR_NO_OPERATIONS':
145 raise ApiError('Cannot get state: ', resp)
146 return resp[0] # TODO: change to smth else
147
148def set_operation_revise(tzid):
149 logger.debug('Setting operation revise')
150 while not ('resp' in locals() and resp.text):
151 resp = requests.get(url.format('setOperationRevise'),
152 params={
153 'tzid' : tzid,
154 'apikey' : apikey
155 },
156 timeout=10)
157 print(resp.text)
158 print(tzid)
159 try:
160 resp = resp.json()
161 logger.debug(str(resp))
162 if resp['response'] != '1':
163 raise ApiError('Cannot set operation revise: ',
164resp['response'])
165 return resp
166 except:
167 return set_operation_revise(tzid)
168
169
170def set_operation_used(tzid):
171 logger.debug('Setting operation used')
172 while not ('resp' in locals() and resp.text):
173 resp = requests.get(url.format('setOperationUsed'),
174 params={
175 'tzid' : tzid,
176 'apikey' : apikey
177 },
178 timeout=10)
179 resp = resp.json()
180 logger.debug(str(resp))
181 if resp['response'] != '1':
182 raise ApiError('Cannot set operation used: ', resp['response'])
183 return resp
184
185def get_operations():
186 logger.debug('Getting operations')
187 while not ('resp' in locals() and resp.text):
188 resp = requests.get(url.format('getOperations'),
189 params={
190 'apikey' : apikey
191 },
192 timeout=10)
193 resp = resp.json()
194 logger.debug(str(resp))
195 if not isinstance(resp, list) and resp['response'] == 'ERROR_NO_OPERATIONS':
196 raise ApiError('Cannot get operations: ', resp['response'])
197 try:
198 return resp[0]['tzid'] # TODO: change to smth else
199 except:
200 pass
201
202
203def set_operation_ok(tzid):
204 logger.debug('Setting operation ok')
205 while not ('resp' in locals() and resp.text):
206 resp = requests.get(url.format('setOperationOk'),
207 params={
208 'tzid' : tzid,
209 'apikey' : apikey
210 },
211 timeout=10)
212 resp = resp.json()
213 logger.debug(str(resp))
214 if resp['response'] != '1':
215 raise ApiError('Cannot set operation OK: ', resp['response'])
216
217def get_num(form=3):
218 logger.debug('Getting number')
219 while not ('resp' in locals() and resp.text):
220 resp = requests.get(url.format('getNum'),
221 params={
222 'form' : form,
223 'service' : 'Steam',
224 'apikey' : apikey
225 },
226 timeout=10)
227 resp = resp.json()
228 logger.debug(str(resp))
229 if resp['response'] != '1':
230 raise ApiError('Cannot get phone number: ', resp['response'])
231 return resp['tzid']
232
233class ApiError(Exception):
234 pass
235
236def activate_at_phone(tzid):
237 with open('temp_accs.txt','r') as fp:
238 accs = [x.split(';') for x in fp.read().split('\n') if x]
239 i = 0
240 state = None
241 while not state:
242 try:
243 state = get_state(tzid)
244 except ApiError:
245 continue
246
247 phone_number = state['number']
248 msgs = list()
249 wrong_sms = False
250 fatal = 0
251 restart = False
252 while i < 30 and len(msgs) < 31 and accs and int(state['time']) > 40 or wrong_sms:
253 if not wrong_sms and not fatal and not restart:
254 acc = accs[0]
255 accs = accs[1:]
256 # Oh, soome fucking magic numbers?
257 # No, just sometimes service get only 18-19 SMS
258 #if int(state['time']) < 100 and 17 < i < 20:
259 # break
260 session = MobileWebAuth(acc[0], acc[1])
261 logger.info('Logging in {}'.format(acc[0]))
262 try:
263 session.login()
264 except steam.webauth.HTTPError:
265 restart = True
266 logger.exception('Login timed out')
267 continue
268 except steam.webauth.CaptchaRequired:
269 print(session.captcha_url)
270 session.login(captcha=input())
271 except (steam.webauth.LoginIncorrect, TypeError):
272 wrong_sms = False
273 fatal = 0
274 logger.info(('{} has wrong login or something like this'.format(acc[0])))
275 with open('temp_accs.txt','w') as fp:
276 fp.write('\n'.join(';'.join(x) for x in accs))
277 continue
278 except steam.webauth.TwoFactorCodeRequired:
279 logger.info(('{} already has 2fa'.format(acc[0])))
280 with open('temp_accs.txt','w') as fp:
281 fp.write('\n'.join(';'.join(x) for x in accs))
282 continue
283 except KeyError:
284 restart = True
285 logger.exception('Cannot log in')
286 continue
287 if not session.complete:
288 restart = True
289 continue
290 restart = False
291 sessionid = get_sessionid(session)
292 has_phone = check_has_phone(session, sessionid)
293 if has_phone and not wrong_sms:
294 logger.warning(('{} has phone without 2fa, remove it youself').format(acc[0]))
295 continue
296 if not has_phone:
297 logger.info(('Adding 2fa to {}'.format(acc[0])))
298 try:
299 add_phone(phone_number, session, sessionid)
300 except steam.guard.SteamAuthenticatorError as e:
301 logger.exception('Cannot add phone')
302 if e.args[1]['fatal']:
303 if 'Sorry, that phone number has recently been'\
304 ' added to too many accounts.' in e.args[1]['error_text']:
305 fatal += 2
306 break
307 if fatal > 2:
308 break
309 fatal += 1
310 continue
311
312 sa = SteamAuthenticator(medium=session)
313 try:
314 sa.add()
315 except steam.guard.SteamAuthenticatorError as e:
316 logger.exception('Cannot add 2FA')
317 if fatal > 3:
318 break
319 else:
320 fatal += 1
321 continue
322 fatal = 0
323 wrong_sms = False
324 while int(state['time']) > 25:
325 time.sleep(1)
326 while True:
327 if i == 0:
328 state = get_state(tzid)
329 logger.debug('First try to get sms')
330 start_time = time.time()
331 while True:
332 try:
333 if time.time() - start_time > 10:
334 logger.debug('Really long, maybe relogin?')
335 wrong_sms = True
336 break
337 state = get_state(tzid)
338 if 'msg' in state:
339 if state['msg'] in msgs:
340 set_operation_revise(tzid)
341 if msgs[-1] == state['msg']:
342 time.sleep(2)
343 else:
344 break
345 except ApiError:
346 pass
347 time.sleep(1)
348 else:
349 time.sleep(0.2)
350 logger.debug('Trying to get sms')
351 start_time = time.time()
352 set_operation_revise(tzid)
353 state = get_state(tzid)
354 #logger.debug('Got state {}'.format(state))
355 while state['msg'] in msgs:
356 if time.time() - start_time > 20:
357 logger.debug('Really long, maybe relogin?')
358 wrong_sms = True
359 break
360 logger.debug('{} already in array'.format(state['msg']))
361 set_operation_revise(tzid)
362 if state['msg'] == msgs[-1]:
363 time.sleep(2)
364 time.sleep(0.2)
365 state = get_state(tzid)
366 #logger.debug('Got state {}'.format(state))
367 if wrong_sms:
368 break
369 msgs.append(state['msg'])
370 sms_code = state['msg']
371 logger.debug('Using code {}'.format(sms_code))
372 try:
373 verify_sms(sms_code, session, sessionid)
374 break
375 except steam.guard.SteamAuthenticatorError:
376 logger.debug('{} is old code'.format(state['msg']))
377 msgs.append(state['msg'])
378 if len(msgs) == 1:
379 wrong_sms = True
380 if wrong_sms:
381 break
382
383 logger.debug('Sms verified')
384 try:
385 sa.finalize(sms_code)
386 except steam.guard.SteamAuthenticatorError as e:
387 logger.exception('Cannot finalize %s, contact author about this acc')
388 if 'EResult.TwoFactorActivationCodeMismatch' in e.args:
389 print('TwoFactorMismatch')
390 with open('problem_accs.txt','a') as fp:
391 fp.write(';'.join(acc))
392 else:
393 wrong_sms = True
394 with open('maFiles/{}.maFile'.format(session.steam_id),'w') as fp:
395 data = get_mafile(sa.secrets, session, False)
396 json.dump(data, fp, indent=4, separators=(',', ': '), sort_keys=True)
397 break
398 if wrong_sms:
399 continue
400 i += 1
401 fatal = 0
402 logger.info('{} saved'.format(session.username))
403 with open('temp_accs.txt','w') as fp:
404 fp.write('\n'.join(';'.join(x) for x in accs))
405 with open('maFiles/{}.maFile'.format(session.steam_id),'w') as fp:
406 data = get_mafile(sa.secrets, session, True)
407 json.dump(data, fp, indent=4, separators=(',', ': '), sort_keys=True)
408 if is_exit_pressed:
409 break
410 if fatal > 3 and not msgs:
411 set_operation_used(tzid)
412 elif msgs and not is_exit_pressed and accs:
413 set_operation_ok(tzid)
414
415
416################################################################################
417
418
419
420################################################################################
421DEBUGGING = True
422################################################################################
423#logger setup
424try:
425 import colorlog
426 logger = colorlog.getLogger(__name__)
427 sh = colorlog.StreamHandler()
428 formatter2 = colorlog.ColoredFormatter(
429 '%(log_color)s[%(asctime)s.%(msecs)03d] - '
430 '%(levelname)+8s - %(message_log_color)s%(message)s',
431 datefmt='%H:%M:%S',
432 log_colors={
433 'DEBUG': 'cyan',
434 'INFO': 'bold_white',
435 'WARNING': 'yellow',
436 'ERROR': 'red',
437 'CRITICAL': 'red,bg_white',
438 },
439 secondary_log_colors={
440 'message': {
441 'ERROR': 'red',
442 'CRITICAL': 'red,bg_white'
443 }})
444except ImportError:
445 logger = logging.getLogger(__name__)
446 sh = logging.StreamHandler()
447 formatter2 = logging.Formatter('[%(asctime)s.%(msecs)03d] - %(levelname)+8s - %(message)s', '%H:%M:%S')
448################################################################################
449'''
450if os.path.exists('telehandler'):
451 try:
452 import telegram_handler
453 with open('telehandler','r') as fp:
454 handler_args = [x for x in fp.read().split('\n') if x]
455 th = telegram_handler.handlers.TelegramHandler(handler_args[0], handler_args[1])
456 th.setLevel(logging.INFO)
457 ht = telegram_handler.handlers.HtmlFormatter('[%(asctime)s.%(msecs)03d] - %(levelname)+8s - %(message)s', '%H:%M:%S')
458 th.setFormatter(ht)
459 logger.addHandler(th)
460 except ImportError:
461 pass
462'''
463################################################################################
464sh.setFormatter(formatter2)
465logger.addHandler(sh)
466formatter = logging.Formatter('[%(asctime)s][LINE:%(lineno)d]# - %(levelname)s - %(message)s')
467fh = RotatingFileHandler('twofactor.log', maxBytes=1000000, backupCount=5)
468fh.doRollover()
469fh.setFormatter(formatter)
470logger.addHandler(fh)
471
472
473logger.setLevel(logging.DEBUG)
474fh.setLevel(logging.DEBUG)
475sh.setLevel(logging.DEBUG if DEBUGGING else logging.INFO)
476
477################################################################################
478is_exit_pressed = False
479
480def do_exit(signal, frame):
481 global is_exit_pressed
482 print('\b\bPlease wait...')
483 logger.warning('Exit key pressed')
484 if is_exit_pressed:
485 logger.warning('Exiting now')
486 sys.exit(1)
487 is_exit_pressed = True
488def exit_now(signal, frame):
489 logger.error('Emergency quit')
490 sys.exit()
491signal.signal(signal.SIGINT, exit_now)
492
493################################################################################
494try:
495 if not os.path.exists('maFiles/'):
496 os.mkdir('maFiles')
497
498 if not os.path.exists('temp_accs.txt') and os.path.exists('accs.txt'):
499 shutil.copyfile('accs.txt','temp_accs.txt')
500 elif not os.path.exists('temp_accs.txt') and not os.path.exists('accs.txt'):
501 input('Sorry, can\'t find accs file')
502 exit()
503
504 url = 'http://onlinesim.ru/api/{}.php'
505 if os.path.exists('apionlinesim'):
506 with open('apionlinesim','r') as fp:
507 apikey = fp.read().split('\n')[0]
508 else:
509 while True:
510 apikey = input('Enter your api key:\n>')
511 try:
512 get_balance()
513 break
514 except ApiError:
515 continue
516 balance = get_balance()
517 print('Balance: %s' % balance)
518 while True:
519 stop = input('How many accs we will authenticate? \n '
520 'Number will rounded up to a multiple of 30.\n'
521 '(enter 0 to all accounts):\n>')
522 if stop.isdigit():
523 stop = int(stop)
524 break
525 form = None
526 while not (form == 3 or form == 2):
527 form = int(input('Enter price of numbers (2 or 3. 3 is faster)\n>'))
528 #logger.info('Balance: {}'.format(balance))
529 with open('temp_accs.txt','r') as fp:
530 amount = len(fp.readlines())
531 count = 0
532 signal.signal(signal.SIGINT, do_exit)
533 while amount > 1 and count <= stop and not is_exit_pressed:
534 try:
535 try:
536 tzid = get_operations()
537 state = get_state(tzid)
538 if int(state['time']) < 20:
539 set_operation_ok(tzid)
540 raise ApiError
541 except ApiError:
542 if int(balance) < form:
543 logger.info('Low balance, sorry')
544 input()
545 sys.exit()
546 logger.info('Getting new number')
547 try:
548 tzid = get_num(form=1 if form == 3 else 3)
549 except ApiError as e:
550 if e.args[1] == 'TIME_INTERVAL_ERROR':
551 logger.exception('LOOK AT CLOCK! IT\'S {} NOW!'.format(time.strftime('%H:%M')))
552 raise
553
554 activate_at_phone(tzid)
555 except HTTPError as e:
556 logger.warning('HTTPError {}'.format(e))
557 continue
558
559 with open('temp_accs.txt','r') as fp:
560 lenfile = len(fp.readlines())
561 if stop > 0:
562 count += amount - lenfile
563 amount = lenfile
564 balance = get_balance()
565 logger.info('Balance: %s' % balance)
566 if is_exit_pressed:
567 sys.exit(1)
568
569 if int(balance) < form and amount > 1 and count <= stop and not is_exit_pressed:
570 input('Press any key to quit \n'
571 'or refill your balance and press key')
572except:
573 logger.exception('Something gone wrong')
574 raise