Browse Source

Finish custom password policy, add documentation

oz123 12 years ago
parent
commit
7cfd4101c4
3 changed files with 99 additions and 23 deletions
  1. 27 4
      README.md
  2. 33 16
      pwman/ui/cli.py
  3. 39 3
      pwman/util/generator.py

+ 27 - 4
README → README.md

@@ -13,11 +13,11 @@ 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
 
 
@@ -73,7 +73,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 +88,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` 
       

+ 33 - 16
pwman/ui/cli.py

@@ -121,30 +121,32 @@ class PwmanCli(cmd.Cmd):
     def get_username(self, default=""):
         return getinput("Username: ", default)
 
-    def get_password(self, numerics=False,leetify=False):
+    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
         """
-        # TODO: add key word for specialsigns = False
+        if argsgiven > 0:
+            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'
-            # TODO: allow custom leetifying through the config
-            leetify = config.get_value("Generator", "leetify") == 'true'
-                                 generate_password(minlen, maxlen, capitals = True, symbols = False, numerics = False)
             (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
-
+        
     def get_url(self, default=""):
         return getinput("Url: ", default)
 
@@ -376,16 +378,31 @@ class PwmanCli(cmd.Cmd):
         """
         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}
+        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()
             if args:
-                args = ast.literal_eval(args)
-                password = self.get_password(**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:
-                password = self.get_password()
+                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)

+ 39 - 3
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):
@@ -83,13 +86,46 @@ def random_special_sign(password):
     ;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: