Use the --port option also for SSL, drop the --ssl-port options
[crackpop.git] / crackpop.py
index 3c7d0f7..d44ed28 100755 (executable)
@@ -26,25 +26,36 @@ __version = "0.1"
 __author_info = "Antonio Ospite"
 
 
 __author_info = "Antonio Ospite"
 
 
+# returns a tuple: (num_passwords, passwords)
+# where passwords is an iterable type
 def generate_passwords(password_pattern, dry_run=False):
 def generate_passwords(password_pattern, dry_run=False):
-    passwords = list(exrex.generate(password_pattern))
+    num_passwords = exrex.count(password_pattern)
+    passwords = exrex.generate(password_pattern)
 
     if dry_run:
 
     if dry_run:
-        print "Generated %d passwords." % len(passwords)
+        print "Generated %d passwords." % num_passwords
         for p in passwords:
             print p
         for p in passwords:
             print p
-        return []
+        return (0, iter([]))
 
 
-    return passwords
+    return (num_passwords, passwords)
 
 
 
 
-def crackpop(host, port, user, passwords):
-    print "Testing %d passwords." % len(passwords)
-    for p in passwords:
+# the passwords parameter is a tuple: (n, L)
+# where L is an iterable type and n is the number of elements in L
+def crackpop(host, port, ssl, user, passwords):
+    if ssl:
+        pop3_connect = poplib.POP3_SSL
+    else:
+        pop3_connect = poplib.POP3
+
+    print "Testing %d passwords." % passwords[0]
+    for p in passwords[1]:
         # TODO maybe the same connection can be reused for more than one try,
         # but some logic needs to be added to detect the maximum allowed
         # authentication attempts or a disconnection from the server.
         # TODO maybe the same connection can be reused for more than one try,
         # but some logic needs to be added to detect the maximum allowed
         # authentication attempts or a disconnection from the server.
-        pop3 = poplib.POP3(host, port)
+        pop3 = pop3_connect(host, port)
+
         try:
             pop3.user(user)
             pop3.pass_(p)
         try:
             pop3.user(user)
             pop3.pass_(p)
@@ -73,7 +84,7 @@ def option_parser():
 
     parser.add_argument(
         '-P', '--port', metavar="<port>",
 
     parser.add_argument(
         '-P', '--port', metavar="<port>",
-        dest='port', default=110,
+        dest='port', default=None,
         help='the port the pop3 server is listening on')
 
     parser.add_argument(
         help='the port the pop3 server is listening on')
 
     parser.add_argument(
@@ -91,6 +102,11 @@ def option_parser():
         dest='dry_run', action='store_const', const=True,
         help='only print out the passwords, do not connect to the pop3 server')
 
         dest='dry_run', action='store_const', const=True,
         help='only print out the passwords, do not connect to the pop3 server')
 
+    parser.add_argument(
+        '-s', '--ssl',
+        dest='ssl', action='store_const', const=True,
+        help='use SSL to connect to the pop3 server')
+
     return parser
 
 
     return parser
 
 
@@ -98,5 +114,13 @@ if __name__ == "__main__":
     parser = option_parser()
     args = parser.parse_args()
 
     parser = option_parser()
     args = parser.parse_args()
 
+    if args.port is None:
+        if args.ssl:
+            port = poplib.POP3_SSL_PORT
+        else:
+            port = poplib.POP3_PORT
+    else:
+        port = args.port
+
     passwords = generate_passwords(args.password_pattern, args.dry_run)
     passwords = generate_passwords(args.password_pattern, args.dry_run)
-    crackpop(args.host, args.port, args.user, passwords)
+    crackpop(args.host, port, args.ssl, args.user, passwords)