win.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. """"
  2. # ============================================================================
  3. # This file is part of Pwman3.
  4. #
  5. # Pwman3 is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License, version 2
  7. # as published by the Free Software Foundation;
  8. #
  9. # Pwman3 is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with Pwman3; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. # ============================================================================
  18. # Copyright (C) 2012 Oz Nahum <nahumoz@gmail.com>
  19. # ============================================================================
  20. # Copyright (C) 2006 Ivan Kelly <ivan@ivankelly.net>
  21. # ============================================================================
  22. """
  23. from __future__ import print_function
  24. import time
  25. import ctypes
  26. import ast
  27. import os
  28. try:
  29. import msvcrt
  30. except ImportError:
  31. pass
  32. from colorama import Fore
  33. import pwman.util.config as config
  34. from pwman.ui.cli import PwmanCliNew
  35. from pwman.data.nodes import NewNode
  36. from pwman.ui import tools
  37. from pwman.util.crypto import zerome
  38. def winGetClipboard():
  39. ctypes.windll.user32.OpenClipboard(0)
  40. pcontents = ctypes.windll.user32.GetClipboardData(1) # 1 is CF_TEXT
  41. data = ctypes.c_char_p(pcontents).value
  42. #ctypes.windll.kernel32.GlobalUnlock(pcontents)
  43. ctypes.windll.user32.CloseClipboard()
  44. return data
  45. def winSetClipboard(text):
  46. text = str(text)
  47. GMEM_DDESHARE = 0x2000
  48. ctypes.windll.user32.OpenClipboard(0)
  49. ctypes.windll.user32.EmptyClipboard()
  50. try:
  51. # works on Python 2 (bytes() only takes one argument)
  52. hCd = ctypes.windll.kernel32.GlobalAlloc(GMEM_DDESHARE, len(bytes(text))+1)
  53. except TypeError:
  54. # works on Python 3 (bytes() requires an encoding)
  55. hCd = ctypes.windll.kernel32.GlobalAlloc(GMEM_DDESHARE, len(bytes(text, 'ascii'))+1)
  56. pchData = ctypes.windll.kernel32.GlobalLock(hCd)
  57. try:
  58. # works on Python 2 (bytes() only takes one argument)
  59. ctypes.cdll.msvcrt.strcpy(ctypes.c_char_p(pchData), bytes(text))
  60. except TypeError:
  61. # works on Python 3 (bytes() requires an encoding)
  62. ctypes.cdll.msvcrt.strcpy(ctypes.c_char_p(pchData), bytes(text, 'ascii'))
  63. ctypes.windll.kernel32.GlobalUnlock(hCd)
  64. ctypes.windll.user32.SetClipboardData(1, hCd)
  65. ctypes.windll.user32.CloseClipboard()
  66. class PwmanCliWinNew(PwmanCliNew):
  67. """
  68. windows ui class
  69. """
  70. def do_new(self, args):
  71. """
  72. can override default config settings the following way:
  73. Pwman3 0.2.1 (c) visit: http://github.com/pwman3/pwman3
  74. pwman> n {'leetify':False, 'numerics':True, 'special_chars':True}
  75. Password (Blank to generate):
  76. """
  77. errmsg = """could not parse config override, please input some"""\
  78. + """ kind of dictionary, e.g.: n {'leetify':False, """\
  79. + """'numerics':True, 'special_chars':True}"""
  80. try:
  81. username = self.get_username()
  82. if args:
  83. try:
  84. args = ast.literal_eval(args)
  85. except Exception:
  86. raise Exception(errmsg)
  87. if not isinstance(args, dict):
  88. raise Exception(errmsg)
  89. password = self.get_password(1, **args)
  90. else:
  91. numerics = config.get_value(
  92. "Generator", "numerics").lower() == 'true'
  93. # TODO: allow custom leetifying through the config
  94. leetify = config.get_value(
  95. "Generator", "leetify").lower() == 'true'
  96. special_chars = config.get_value(
  97. "Generator", "special_chars").lower() == 'true'
  98. password = self.get_password(0,
  99. numerics=numerics,
  100. symbols=leetify,
  101. special_signs=special_chars)
  102. url = self.get_url()
  103. notes = self.get_notes()
  104. node = NewNode()
  105. node.username = username
  106. node.password = password
  107. node.url = url
  108. node.notes = notes
  109. tags = self.get_tags()
  110. node.tags = tags
  111. self._db.addnodes([node])
  112. print("Password ID: %d" % (node._id))
  113. # when done with node erase it
  114. zerome(password)
  115. except Exception as e:
  116. self.error(e)
  117. def print_node(self, node):
  118. width = tools._defaultwidth
  119. print("Node {}.".format(node._id))
  120. print("{} {}".format(tools.typeset("Username:", Fore.RED).ljust(width),
  121. node.username))
  122. print ("{} {}".format(tools.typeset("Password:", Fore.RED).ljust(width),
  123. node.password))
  124. print("{} {}".format(tools.typeset("Url:", Fore.RED).ljust(width), node.url))
  125. print("{} {}".format(tools.typeset("Notes:", Fore.RED).ljust(width), node.notes))
  126. print("{}".format(tools.typeset("Tags: ", Fore.RED)), end=" ")
  127. for t in node.tags:
  128. print(t.name)
  129. def heardEnterWin():
  130. c = msvcrt.kbhit()
  131. if c == 1:
  132. ret = msvcrt.getch()
  133. if ret is not None:
  134. return True
  135. return False
  136. def waituntil_enter(somepredicate, timeout, period=0.25):
  137. mustend = time.time() + timeout
  138. while time.time() < mustend:
  139. cond = somepredicate()
  140. if cond:
  141. break
  142. time.sleep(period)
  143. self.do_cls('')
  144. flushtimeout = int(config.get_value("Global", "cls_timeout"))
  145. if flushtimeout > 0:
  146. print("Press any key to flush screen (autoflash "
  147. "in %d sec.)" % flushtimeout)
  148. waituntil_enter(heardEnterWin, flushtimeout)
  149. def do_copy(self, args):
  150. ids = self.get_ids(args)
  151. if len(ids) > 1:
  152. print ("Can copy only 1 password at a time...")
  153. return None
  154. try:
  155. node = self._db.getnodes(ids)
  156. winSetClipboard(node[0].password)
  157. print("copied password for {}@{} clipboard".format(
  158. node[0].username, node[0].url))
  159. print("erasing in 10 sec...")
  160. time.sleep(10)
  161. winSetClipboard("")
  162. except Exception as e:
  163. self.error(e)
  164. def do_open(self, args):
  165. ids = self.get_ids(args)
  166. if not args:
  167. self.help_open()
  168. return
  169. if len(ids) > 1:
  170. print ("Can open only 1 link at a time ...")
  171. return None
  172. try:
  173. node = self._db.getnodes(ids)
  174. url = node[0].url
  175. if not url.startswith(("http://", "https://")):
  176. url = "https://" + url
  177. os.system("start "+url)
  178. except Exception as e:
  179. self.error(e)