Advertisement
Guest User

Untitled

a guest
May 16th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.36 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3. import sys
  4. import getpass
  5. import MySQLdb
  6.  
  7.  
  8.  
  9. NOTE = "\033[34;1m[*]\033[0m"
  10. SUCC = "\033[32;1m[!]\033[0m"
  11. INPUT = "\033[36;1m[>]\033[0m"
  12. ERR = "\033[31;1m[!]\033[0m"
  13.  
  14.  
  15. # colorid: black 0, red 1, green 2, yellow 3, cyan 6
  16. def fmt_color(msg, colorid):
  17. if sys.stdout.isatty():
  18. # running in a real terminal
  19. return '\033[1;' + str(30 + colorid) + 'm' + msg + '\033[0m'
  20. else:
  21. # no color support, e.g. redirection
  22. return msg
  23.  
  24.  
  25. def fmt_bold(msg):
  26. if sys.stdout.isatty():
  27. # running in a real terminal
  28. return '\033[1m' + msg + '\033[0m'
  29. else:
  30. # no color support, e.g. redirection
  31. return msg
  32.  
  33.  
  34. def fmt_red(msg):
  35. return fmt_color(msg, 1)
  36.  
  37.  
  38. def fmt_green(msg):
  39. return fmt_color(msg, 2)
  40.  
  41.  
  42. def fmt_yellow(msg):
  43. return fmt_color(msg, 3)
  44.  
  45.  
  46. def fmt_cyan(msg):
  47. return fmt_color(msg, 6)
  48.  
  49.  
  50. class DB_vdomain:
  51. def __init__(self, identifier, name):
  52. self.identifier = identifier
  53. self.name = name
  54.  
  55.  
  56. class DB_vuser:
  57. def __init__(self, identifier, vdomain_id, name):
  58. self.identifier = identifier
  59. self.vdomain_id = vdomain_id
  60. self.name = name
  61.  
  62.  
  63. class DB_valias:
  64. def __init__(self, identifier, vdomain_id, source, destination):
  65. self.identifier = identifier
  66. self.vdomain_id = vdomain_id
  67. self.source = source
  68. self.destination = destination
  69.  
  70.  
  71. def db_get_vdomains():
  72. vdomains = []
  73. dbcursor.execute('SELECT id, name FROM virtual_domains;')
  74. for row in dbcursor.fetchall():
  75. vdomains.append(DB_vdomain(row[0], row[1]))
  76. return vdomains
  77.  
  78.  
  79. def db_create_vdomain(name):
  80. dbcursor.execute('INSERT INTO virtual_domains (name) VALUES (%s);', (name,))
  81.  
  82.  
  83. def db_delete_vdomain(identifier):
  84. dbcursor.execute('DELETE FROM virtual_domains where id=%s;', (identifier,))
  85.  
  86.  
  87. def db_get_vusers(vdomain_id=None):
  88. vusers = []
  89. if vdomain_id:
  90. dbcursor.execute('SELECT id, domain_id, email FROM virtual_users WHERE domain_id = %s;', (vdomain_id,))
  91. else:
  92. dbcursor.execute('SELECT id, domain_id, email FROM virtual_users;')
  93. for row in dbcursor.fetchall():
  94. vusers.append(DB_vuser(row[0], row[1], row[2]))
  95. return vusers
  96.  
  97.  
  98. def db_create_vuser(vdomain_id, email, password):
  99. dbcursor.execute('INSERT INTO virtual_users (domain_id, email, password) VALUES ( %s, %s,CONCAT("{SHA256-CRYPT}", ENCRYPT (%s, CONCAT("$5$", SUBSTRING(SHA(RAND()), -16)))));', (vdomain_id, email, password,))
  100.  
  101.  
  102. def db_update_vuser(email, password):
  103. dbcursor.execute('UPDATE virtual_users SET password=CONCAT("{SHA256-CRYPT}", ENCRYPT (%s, CONCAT("$5$", SUBSTRING(SHA(RAND()), -16)))) WHERE email=%s;', (password, email,))
  104.  
  105.  
  106. def db_delete_vuser(identifier):
  107. dbcursor.execute('DELETE FROM virtual_users WHERE id=%s;', (identifier,))
  108.  
  109.  
  110. def db_get_valiases(vdomain_id=None):
  111. valiases = []
  112. if vdomain_id:
  113. dbcursor.execute("SELECT id, domain_id, source, destination FROM virtual_aliases WHERE domain_id = %s;", (vdomain_id,))
  114. else:
  115. dbcursor.execute("SELECT id, domain_id, source, destination FROM virtual_aliases;")
  116. for row in dbcursor.fetchall():
  117. valiases.append(DB_valias(row[0], row[1], row[2], row[3]))
  118. return valiases
  119.  
  120.  
  121. def db_create_valias(vdomain_id, srcemail, dstemail):
  122. dbcursor.execute('INSERT INTO virtual_aliases (domain_id, source, destination) VALUES (%s, %s, %s);', (vdomain_id, srcemail, dstemail,))
  123.  
  124.  
  125. def db_delete_valias(srcemail):
  126. dbcursor.execute('DELETE FROM virtual_aliases WHERE source=%s;', (srcemail,))
  127.  
  128.  
  129. def menu_main():
  130. while True:
  131. print()
  132. print(' Options:')
  133. print()
  134. print(' * ' + fmt_bold('q') + 'uit program')
  135. print(' * ' + fmt_bold('a') + 'dd domain')
  136. print(' * ' + fmt_bold('m') + 'anage domain')
  137. print(' * ' + fmt_bold('d') + 'elete domain')
  138. print(' * ' + fmt_bold('l') + 'ist domains')
  139.  
  140. print()
  141. input_str = input(fmt_cyan('Action [q/a/m/d/l]: '))
  142. if input_str in ('quit', 'exit', 'q', 'Q'):
  143. return
  144. elif input_str == 'a':
  145. menu_adddomain()
  146. elif input_str == 'd':
  147. menu_deletedomain()
  148. elif input_str == 'l':
  149. menu_listdomain()
  150. elif input_str == 'm':
  151. menu_managedomain()
  152. else:
  153. print()
  154. print(ERR + ' unknown option \'' + input_str + '\' given.')
  155.  
  156.  
  157. def menu_adddomain():
  158. print()
  159. name = input(fmt_cyan('Name for new domain: '))
  160. print()
  161. print('Create new domain \'' + fmt_bold(name) + '\'?')
  162. print()
  163.  
  164. ack = input(fmt_yellow('y/N: '))
  165. print()
  166. if ack not in ('y', 'Y', 'yes'):
  167. print(NOTE + ' no changes made')
  168. return
  169.  
  170. db_create_vdomain(name)
  171.  
  172. print(SUCC + ' domain \'' + fmt_bold(name) + '\' successfully created')
  173.  
  174.  
  175. def menu_deletedomain():
  176. domains = db_get_vdomains()
  177.  
  178. print()
  179. if not len(domains):
  180. print(NOTE + ' no domain found to delete!')
  181. return
  182.  
  183. print(' Available domains:')
  184. print()
  185. counter = 1
  186. for domain in domains:
  187. print(' ' + fmt_bold(str(counter)) + ' ' + domain.name)
  188. counter += 1
  189. print()
  190. identifier = int(input(fmt_cyan('Domain to delete: ')))
  191. print()
  192. if identifier <= 0 or identifier > len(domains):
  193. print(ERR + ' invalid domain identifier \'' + str(identifier) + '\' given')
  194. return
  195.  
  196. domain = domains[identifier - 1]
  197.  
  198. print('Delete domain \'' + fmt_bold(domain.name) + '\'?')
  199. print()
  200. ack = input(fmt_yellow('y/N: '))
  201. print()
  202. if ack not in ('y', 'Y', 'yes'):
  203. print(NOTE + ' no changes made')
  204. return
  205.  
  206. db_delete_vdomain(domain.identifier)
  207.  
  208. print(SUCC + ' domain \'' + fmt_bold(domain.name) + '\' successfully deleted')
  209. return
  210.  
  211.  
  212. def menu_listdomain():
  213. domains = db_get_vdomains()
  214.  
  215. print()
  216. print(SUCC + ' Found ' + fmt_bold(str(len(domains))) + ' domains')
  217. for domain in domains:
  218. print(' ' + fmt_bold('-') + ' ' + domain.name)
  219.  
  220.  
  221. def menu_adduseralias(domain):
  222. print()
  223. input_str = input(fmt_cyan('Create [u]ser or [a]lias: '))
  224. print()
  225. if input_str == 'u':
  226. return menu_adduser(domain)
  227. elif input_str == 'a':
  228. return menu_addalias(domain)
  229. else:
  230. print(ERR + ' unknown option \'' + input_str + '\' given.')
  231. return
  232.  
  233. def menu_adduser(domain):
  234. print()
  235. name = input(fmt_cyan('Name for new user (@' + domain.name + ' will be appended): '))
  236. name += '@' + domain.name
  237.  
  238. print()
  239. print('Create new email \'' + fmt_bold(name) + '\'?')
  240. print()
  241.  
  242. ack = input(fmt_yellow('y/N: '))
  243. if ack not in ('y', 'Y', 'yes'):
  244. print(NOTE + ' no changes made')
  245. return
  246.  
  247. password = getpass.getpass(fmt_cyan('Password: '))
  248. password2 = getpass.getpass(fmt_cyan('Password (repeat): '))
  249. print()
  250.  
  251. if password != password2:
  252. print(ERR + ' passwords do not match - no changes made')
  253. return
  254.  
  255. db_create_vuser(domain.identifier, name, password)
  256.  
  257. print(SUCC + ' email \'' + fmt_bold(name) + '\' successfully created')
  258.  
  259.  
  260. def menu_addalias(domain):
  261. print()
  262. source = input(fmt_cyan('Source for new alias (@' + domain.name + ' will be appended): '))
  263. source += '@' + domain.name
  264.  
  265. print()
  266. destination = input(fmt_cyan('Destination for new alias (enter full email address): '))
  267.  
  268. print()
  269. print('Create new alias from \'' + fmt_bold(source) + '\' to \'' + fmt_bold(destination) + '\'?')
  270. print()
  271.  
  272. ack = input(fmt_yellow('y/N: '))
  273. if ack not in ('y', 'Y', 'yes'):
  274. print(NOTE + ' no changes made')
  275. return
  276.  
  277. db_create_valias(domain.identifier, source, destination)
  278.  
  279. print(SUCC + ' alias \'' + fmt_bold(source) + '\' to \'' + fmt_bold(destination) + '\' successfully created')
  280.  
  281.  
  282. def menu_pwchangeuser(domain):
  283. users = db_get_vusers(domain.identifier)
  284.  
  285. print()
  286. if not len(users):
  287. print(NOTE + ' no user found!')
  288. return
  289.  
  290. print(' Available users:')
  291. print()
  292. counter = 1
  293. for user in users:
  294. print(' ' + fmt_bold(str(counter)) + ' ' + user.name)
  295. counter += 1
  296. print()
  297. identifier = int(input(fmt_cyan('Change password for user: ')))
  298. print()
  299. if identifier <= 0 or identifier > len(users):
  300. print(ERR + ' invalid user identifier \'' + str(identifier) + '\' given')
  301. return
  302.  
  303. user = users[identifier - 1]
  304.  
  305. print('Changing password for user \'' + fmt_bold(user.name) + '\'..')
  306. print()
  307.  
  308. password = getpass.getpass(fmt_cyan('Password: '))
  309. password2 = getpass.getpass(fmt_cyan('Password (repeat): '))
  310. print()
  311.  
  312. if password != password2:
  313. print(ERR + ' passwords do not match - no changes made')
  314. return
  315.  
  316. db_update_vuser(user.name, password)
  317.  
  318. print(SUCC + ' password for user \'' + fmt_bold(user.name) + '\' successfully changed')
  319.  
  320.  
  321. def menu_deleteuser(domain):
  322. users = db_get_vusers(domain.identifier)
  323. aliases = db_get_valiases(domain.identifier)
  324.  
  325. print()
  326. if not len(users) and not len(aliases):
  327. print(NOTE + ' no user or aliases found to delete!')
  328. return
  329.  
  330. print(' Available users:')
  331. print()
  332. counter = 1
  333. for user in users:
  334. print(' ' + fmt_bold(str(counter)) + ' ' + user.name)
  335. counter += 1
  336. print()
  337. print(' Available aliases:')
  338. print()
  339. for alias in aliases:
  340. print(' ' + fmt_bold(str(counter)) + ' ' + alias.source.ljust(35) + ' ' + fmt_bold('->') + ' ' + alias.destination)
  341. counter += 1
  342. print()
  343. identifier = int(input(fmt_cyan('User/Alias to delete: ')))
  344. print()
  345. if identifier <= 0 or identifier >= counter:
  346. print(ERR + ' invalid user/alias identifier \'' + str(identifier) + '\' given')
  347. return
  348.  
  349. if identifier < len(users):
  350. user = users[identifier - 1]
  351.  
  352. print('Delete user \'' + fmt_bold(user.name) + '\'?')
  353. print()
  354. ack = input(fmt_yellow('y/N: '))
  355. print()
  356. if ack not in ('y', 'Y', 'yes'):
  357. print(NOTE + ' no changes made')
  358. return
  359.  
  360. db_delete_vuser(user.identifier)
  361.  
  362. print(SUCC + ' user \'' + fmt_bold(user.name) + '\' successfully deleted')
  363. return
  364.  
  365. else:
  366. alias = aliases[identifier - len(users) - 1]
  367.  
  368. print('Delete alias \'' + fmt_bold(alias.source) + '\'?')
  369. print()
  370. ack = input(fmt_yellow('y/N: '))
  371. print()
  372. if ack not in ('y', 'Y', 'yes'):
  373. print(NOTE + ' no changes made')
  374. return
  375.  
  376. db_delete_valias(alias.source)
  377.  
  378. print(SUCC + ' alias \'' + fmt_bold(alias.source) + '\' successfully deleted')
  379. return
  380.  
  381.  
  382. def menu_listusers(domain):
  383. users = db_get_vusers(domain.identifier)
  384. aliases = db_get_valiases(domain.identifier)
  385.  
  386. print()
  387. print(SUCC + ' Found ' + fmt_bold(str(len(users))) + ' users')
  388. for user in users:
  389. print(' ' + fmt_bold('-') + ' ' + user.name)
  390.  
  391. print()
  392. print(SUCC + ' Found ' + fmt_bold(str(len(aliases))) + ' aliases')
  393. for alias in aliases:
  394. print(' ' + fmt_bold('-') + ' ' + alias.source.ljust(35) + ' ' + fmt_bold('->') + ' ' + alias.destination)
  395.  
  396.  
  397. def menu_managedomain():
  398. domains = db_get_vdomains()
  399.  
  400. print()
  401. if not len(domains):
  402. print(NOTE + ' no domain found to manage!')
  403. return
  404.  
  405. print(' Available domains:')
  406. print()
  407. counter = 1
  408. for domain in domains:
  409. print(' ' + fmt_bold(str(counter)) + ' ' + domain.name)
  410. counter += 1
  411.  
  412. print()
  413. identifier = int(input(fmt_cyan('Domain to manage: ')))
  414. if identifier <= 0 or identifier > len(domains):
  415. print()
  416. print(ERR + ' invalid domain identifier \'' + str(identifier) + '\' given')
  417. return
  418.  
  419. domain = domains[identifier - 1]
  420.  
  421. while True:
  422. print()
  423. print('Managing domain \'' + fmt_bold(domain.name) + '\'')
  424. print()
  425. print(' Options:')
  426. print()
  427. print(' * ' + fmt_bold('q') + 'uit managing')
  428. print(' * ' + fmt_bold('l') + 'ist users and aliases')
  429. print(' * ' + fmt_bold('a') + 'dd user/alias')
  430. print(' * ' + fmt_bold('d') + 'elete user/alias')
  431. print(' * ' + fmt_bold('c') + 'hange user password')
  432. print()
  433.  
  434. input_str = input(fmt_cyan('Action [q/l/a/d/c]: '))
  435. if input_str in ('quit', 'exit', 'q', 'Q'):
  436. return
  437. elif input_str == 'l':
  438. menu_listusers(domain)
  439. elif input_str == 'a':
  440. menu_adduseralias(domain)
  441. elif input_str == 'd':
  442. menu_deleteuser(domain)
  443. elif input_str == 'c':
  444. menu_pwchangeuser(domain)
  445. else:
  446. print()
  447. print(ERR + ' unknown option \'' + input_str + '\' given.')
  448.  
  449.  
  450. if __name__ == '__main__':
  451. global dbcursor #pylint: disable=global-at-module-level
  452.  
  453. print()
  454. print(fmt_yellow('#'))
  455. print(fmt_yellow('# ISPMail userctl'))
  456. print(fmt_yellow('#'))
  457.  
  458. db = MySQLdb.connect(
  459. host='localhost',
  460. user='root',
  461. #password='password',
  462. db='mailserver')
  463. dbcursor = db.cursor()
  464.  
  465. try:
  466. menu_main()
  467. except KeyboardInterrupt:
  468. db.rollback()
  469. dbcursor.close()
  470. dbcursor = None
  471. db.close()
  472. print()
  473. print()
  474. print(NOTE + ' Bye! ' + fmt_yellow('No changes saved'))
  475. print()
  476. exit(1)
  477.  
  478. db.commit()
  479. dbcursor.close()
  480. dbcursor = None
  481. db.close()
  482. print()
  483. print(SUCC + ' Bye..')
  484. print()
  485. exit(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement