Bladeren bron

Merge branch 'custom_generators'

oz123 12 jaren geleden
bovenliggende
commit
b67d8cbfaa
6 gewijzigde bestanden met toevoegingen van 203 en 49 verwijderingen
  1. 33 21
      ChangeLog
  2. 30 8
      README.md
  3. 4 0
      documentation/general_notes.txt
  4. 1 1
      pwman/__init__.py
  5. 65 17
      pwman/ui/cli.py
  6. 70 2
      pwman/util/generator.py

+ 33 - 21
ChangeLog

@@ -1,41 +1,53 @@
 2012-12-14 Oz Nahum <nahumoz@gmail.com>
-	* Version 0.2.1 
-	* implement open uri function
-	* better MacOSX logic
-	* implement test mode, so code can run locally
-	* use ArgParse 
-	* some improvements on documentation
+    * Version 0.3.0
+    * add custom generator for passwords, support of Alphanumerics + special
+          signs.
+    * Individual password policy.
+    * Fix bug with Random number generation (thank you Rian).
+    * fix bug that prevented not working on other system than MacOSX 
+         (thank you Rian).
+    * fix autoflashing of passwords, a timeout before flashing can specified
+          or completly disables with -1.
+    * Improvements documentation
+        
+2012-12-14 Oz Nahum <nahumoz@gmail.com>
+    * Version 0.2.1 
+    * implement open uri function
+    * better MacOSX logic
+    * implement test mode, so code can run locally
+    * use ArgParse 
+    * some improvements on documentation
 
 2012-10-06 Oz Nahum <nahumoz@gmail.com>
-	* added Debian patches.
+    * added Debian patches.
     * Merge pull request from David North.
-	* Add copy to clipboard on Mac OSX
+    * Add copy to clipboard on Mac OSX
 
 2012-10-06 Oz Nahum <nahumoz@gmail.com>
-	* pwman/__init__.py: Version 0.1.0
-	* pwman/ui/cli.py: Added copy of password to clipboard.
+    * pwman/__init__.py: Version 0.1.0
+    * pwman/ui/cli.py: Added copy of password to clipboard.
     * pwman/ui/cli.py: Added autoflushing of printed output.
 
 2009-09-06 Ivan Kelly <ivan@ivankelly.net>
-	* pwman/__init__.py: Version 0.0.8
-	
+    * pwman/__init__.py: Version 0.0.8
+        
 2010-09-06 Emmanuel Bouthenot <kolter@openics.org>
-	* pwman/ui/cli.py: Improved list output (patch from Emmanuel Bouthenot)
+    * pwman/ui/cli.py: Improved list output (patch from Emmanuel Bouthenot)
 
 2009-09-05 Tero Tilus <tero@tilus.net>
-	* pwman/ui/cli.py: list accepts tag parameters and resets filter
-	* pwman/ui/cli.py: self.get_ids(arg) (print, edit, ... commands) now accepts tag params
+    * pwman/ui/cli.py: list accepts tag parameters and resets filter
+    * pwman/ui/cli.py: self.get_ids(arg) (print, edit, ... commands) now accepts tag params
 
 2009-03-06 Ivan Kelly <ivan@ivankelly.net>
-	* pwman/ui/cli.py: Made leetify configurable
+    * pwman/ui/cli.py: Made leetify configurable
 
 2009-03-05 IKEGAMI Hiroyuki <ikegam@mixallow.net>
-	* pwman/util/generator.py, pwman/ui/cli.py: Added numerous password generation options.
+    * pwman/util/generator.py, pwman/ui/cli.py: Added numerous password generation options.
     
 2009-02-16 Ivan Kelly <ivan@ivankelly.net>
-	* pwman/__init__.py: Version 0.0.7
-	
+    * pwman/__init__.py: Version 0.0.7
+        
 2009-02-16 Ivan Kelly <ivan@ivankelly.net>
-	* pwman/ui/cli.py: Added short commands
-	* pwman/exchange/exporter.py, pwman/exchange/importer.py, pwman/ui/cli.py, scripts/pwman3: Added patches that usually go in debian package. Removed echo on password input
+    * pwman/ui/cli.py: Added short commands
+    * pwman/exchange/exporter.py, pwman/exchange/importer.py, pwman/ui/cli.py, scripts/pwman3: Added patches that usually go in debian package. Removed echo on password input
 

+ 30 - 8
README.md

@@ -13,18 +13,17 @@ Besides managing and storing passwords, Pwman3 can also generate passwords using
 ## Installing 
 
 Pwman3 requires the following debian packages:
-	
+ 
 when using python 2.4:    
     
     python-pysqlite2
-	python-celementtree
+    python-celementtree
     python-crypto
 
-
-
 when using python >= 2.5 
     
-    python-crypto
+    python-crypto (>=2.6) from upstream (currently broken with 
+    pycrypto from Debian).
 
 for nicer functionality:
     
@@ -73,7 +72,7 @@ To install:
 
  * making a password from the numeric character and the alphabet character ([A-Za-z0-9]).
 
-   You can add a parametor for making the password to the config(~/.pwman/config).
+   You can add a parameter for making the password to the config(~/.pwman/config).
 
    For Example:
      
@@ -88,8 +87,31 @@ To install:
      [Generator]
      leetify = true
      ```
+ * Passwords can contain one of the following special signs:
+    
+    ```
+    specialsigns = ["@", "#", "?", "!", '\\', "|", "$",
+                     "%", "^", "&", "*", "(", ")", ":", ";",
+                     "{", "}", "+","-"]
+    ```
+The config file  must have the following option:
+    
+    ```
+    [Generator]
+    special_signs = true
+    ```
 
- * Copying password to X11 or Mac clipbord:
+ * Individual password policy can be chosen with:
+ 
+     ```
+     Pwman3 0.2.1 (c) visit: http://github.com/pwman3/pwman3
+     pwman> n {'leetify':False, 'numerics':True, 'special_signs':True}
+     Username: username
+     Password length (default 7): 7
+     New password: Q1dab@7
+     ``` 
+   
+ * Copying password to X11 or Mac clip board:
   - On Mac OSX systems copying utilizes `pbcopy`  
   - On X11 Systems  Specify the path to `xsel` if you already have `~/.pwman/config` 
       
@@ -97,7 +119,7 @@ To install:
      [Global]
      xsel = yes
       xselpath = /usr/bin/xsel
-      ```
+     ```
  
      When launching `pwman` for the first time, it will try and look for 
      `xsel` and write the configuration properly. 

+ 4 - 0
documentation/general_notes.txt

@@ -58,3 +58,7 @@ finally you should step into:
   1. Password expiry date - register password date,  remind when password is about to expire.
   2. Make new passwords according to user defined rules. 
 
+# build the package with 
+  python setup.py sdist
+# upload  
+  python setup.py sdist upload

+ 1 - 1
pwman/__init__.py

@@ -20,7 +20,7 @@
 #============================================================================
 
 appname = "Pwman3"
-version = "0.2.1"
+version = "0.3.0"
 website = "http://github.com/pwman3/pwman3"
 author = "Oz Nahum"
 authoremail = "nahumoz@gmail.com"

+ 65 - 17
pwman/ui/cli.py

@@ -43,6 +43,7 @@ import cmd
 import time
 import select as uselect
 import subprocess as sp
+import ast
 
 if sys.platform != 'win32':
     import tty
@@ -120,33 +121,44 @@ class PwmanCli(cmd.Cmd):
     def get_username(self, default=""):
         return getinput("Username: ", default)
 
-    def get_password(self, default=""):
+    def get_password(self, argsgiven, numerics=False,leetify=False, symbols=False,
+                     special_signs=False):
+        """
+        in the config file:
+        numerics -> numerics
+        leetify -> symbols
+        special_chars -> special_signs
+        """        
+        if argsgiven == 1:
+            length = getinput("Password length (default 7): ", "7")
+            length = int(length)
+            (password, dumpme) = generator.generate_password(length, length, \
+                True, leetify, numerics, special_signs)
+            print "New password: %s" % (password)
+            return password
+        # no args given
         password = getpassword("Password (Blank to generate): ", _defaultwidth, \
             False)
         if len(password) == 0:
             length = getinput("Password length (default 7): ", "7")
             length = int(length)
-
-            numerics = config.get_value("Generator", "numerics") == 'true'
-            leetify = config.get_value("Generator", "leetify") == 'true'
+        
             (password, dumpme) = generator.generate_password(length, length, \
-                True, leetify, numerics)
-
+                True, leetify, numerics, special_signs)
             print "New password: %s" % (password)
-            return password
-        else:
-            return password
-
+        
+        return password
+        
     def get_url(self, default=""):
         return getinput("Url: ", default)
 
     def get_notes(self, default=""):
         return getinput("Notes: ", default)
 
-    def get_tags(self, default="tag"):
+    def get_tags(self, default=None):
         defaultstr = ''
 
-        if len(default) > 0:
+        if default:
             for t in default:
                 defaultstr += "%s " % (t.get_name())
         else:
@@ -364,10 +376,35 @@ class PwmanCli(cmd.Cmd):
     def do_n(self, arg):
         self.do_new(arg)
 
-    def do_new(self, arg):
+    def do_new(self, args):
+        """
+        can override default config settings the following way:
+        Pwman3 0.2.1 (c) visit: http://github.com/pwman3/pwman3
+        pwman> n {'leetify':False, 'numerics':True, 'special_chars':True}
+        Password (Blank to generate):
+        """
+        errmsg = """could not parse config override, please input some"""\
+                 +""" kind of dictionary, e.g.: n {'leetify':False, """\
+                 +"""'numerics':True, 'special_chars':True}"""
         try:
             username = self.get_username()
-            password = self.get_password()
+            if args:
+                try:
+                    args = ast.literal_eval(args)
+                except Exception:
+                    raise Exception(errmsg)
+                if not isinstance(args, dict):
+                    raise Exception(errmsg)
+                password = self.get_password(1, **args)
+            else:
+                numerics = config.get_value("Generator", "numerics").lower() == 'true'
+                # TODO: allow custom leetifying through the config
+                leetify = config.get_value("Generator", "leetify").lower() == 'true' 
+                special_chars = config.get_value("Generator", "special_chars").lower() == 'true' 
+                password = self.get_password(0,
+                                             numerics=numerics,
+                                             symbols=leetify,
+                                             special_signs=special_chars)
             url = self.get_url()
             notes = self.get_notes()
             node = Node(username, password, url, notes)
@@ -621,7 +658,9 @@ the url must contain http:// or https://."
 
     def help_new(self):
         self.usage("new")
-        print "Creates a new node."
+        print """Creates a new node., 
+You can override default config settings the following way:      
+pwman> n {'leetify':False, 'numerics':True}"""
 
     def help_rm(self):
         self.help_delete()
@@ -926,9 +965,18 @@ class CliMenu(object):
             print "%c - Finish editing" % ('X')
             option = getonechar("Enter your choice:")
             try:
-                # substract 1 because array subscripts start at 1
+                # substract 1 because array subscripts start at 0
                 selection = int(option) - 1
-                value = self.items[selection].editor(self.items[selection].getter())
+                print "selection, ", selection
+                # new value is created by calling the editor with the 
+                # previous value as a parameter 
+                # TODO: enable overriding password policy as if new node
+                # is created.
+                if selection == 1: # for password
+                    value = self.items[selection].editor(0)
+                else:
+                    value = self.items[selection].editor(self.items[selection].getter())
+                
                 self.items[selection].setter(value)
             except (ValueError, IndexError):
                 if (option.upper() == 'X'):

+ 70 - 2
pwman/util/generator.py

@@ -40,14 +40,17 @@ class PasswordGenerationException(Exception):
     def __str__(self):
         return self.message
 
-def generate_password(minlen, maxlen, capitals = True, symbols = False, numerics = False):
+def generate_password(minlen, maxlen, capitals = True, symbols = False, \
+    numerics = False, special_chars = False):
     (password, hyphenated) = generate_password_shazel(minlen, maxlen)
     if (capitals):
         password = randomly_capitalize(password)
     if (symbols):
         password = leetify(password)
-    elif (numerics):
+    if (numerics):
         password = change_numerics(password)
+    if (special_chars):
+        password = random_special_sign(password)
     return (password, hyphenated)
 
 def randomly_capitalize(password):
@@ -66,6 +69,71 @@ def leetify(password):
         newpassword = newpassword + l
     return newpassword
 
+def random_special_sign(password):
+    """
+    replace one letter with a special sign,
+    this will do the following:
+    In [203]: for i in range(10):
+    print random_special_sign("secret")
+    .....:     
+    secre%
+    sec\et
+    secre?
+    s;cret
+    se$ret
+    secr}t
+    secr*t
+    ;ecret
+    s%cret
+    secre(
+    note: numbers are not replaced:
+    In [5]: for i in range(10):
+    print random_special_sign(password)
+   ...:     
+    s3cr?t
+    s3cr$t
+    s3cre#
+    $3cret
+    s3c\et
+    s3cr-t
+    }3cret
+    s3*ret
+    s3cre:
+    s3cr@t
+    
+    In [6]: password = "v3r71mp0rt4nt"
+    
+    In [7]: for i in range(10):
+        print random_special_sign(password)
+   ...:     
+    v3r71mp0rt4)t
+    v3r71m&0rt4nt
+    v3r71mp0rt4-t
+    v3r71mp0rt4&t
+    v3^71mp0rt4nt
+    v3r71@p0rt4nt
+    v3}71mp0rt4nt
+    v3r71m}0rt4nt
+    v3r71mp0r*4nt
+    v3^71mp0rt4nt
+    """
+    newpass = str()
+    specialsigns = ["@", "#", "?", "!", '\\', "|", "$",
+                     "%", "^", "&", "*", "(", ")", ":", ";",
+                     "{", "}", "+","-"]
+     
+    place = int(random.randint(0, len(password)-1))
+    while password[place].isdigit():
+        place = int(random.randint(0, len(password)-1))
+    
+    randomsign = specialsigns[int(random.randint(0, len(specialsigns)-1))]
+    for idx, letter in enumerate(password):
+        if not idx == place:
+            newpass = newpass + letter
+        if idx == place:
+            newpass = newpass + randomsign
+    return newpass
+    
 def change_numerics(password):
     newpassword = str()
     for l in password: