We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Can't enter using "oracle" or "tomcat" users
Hello.
I'm using stock userdb.txt file, where "oracle" and "tomcat" users are defined with any password. When using these users, the ssh client gives me an error of "Permission denied (publickey,password)" after entering three times any password.

The ugly thing is that in cowrie.json file appear entries of "cowrie.login.success" type with the message "login attempt [oracle/password] suceeded", which is, obviously, incorrect.

Thanks a lot

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cowrie/shell/pwd.py`
Content:
```
1 # Copyright (c) 2015 Michel Oosterhof <michel@oosterhof.net>
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 #
8 # 1. Redistributions of source code must retain the above copyright
9 #    notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 #    notice, this list of conditions and the following disclaimer in the
12 #    documentation and/or other materials provided with the distribution.
13 # 3. The names of the author(s) may not be used to endorse or promote
14 #    products derived from this software without specific prior written
15 #    permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 # SUCH DAMAGE.
28 
29 from __future__ import absolute_import, division
30 
31 from binascii import crc32
32 from random import randint, seed
33 
34 from cowrie.core.config import CONFIG
35 
36 
37 class Passwd(object):
38     """
39     This class contains code to handle the users and their properties in
40     /etc/passwd. Note that contrary to the name, it does not handle any
41     passwords.
42     """
43 
44     def __init__(self):
45         self.passwd_file = '%s/etc/passwd' % (CONFIG.get('honeypot', 'contents_path'),)
46         self.load()
47 
48     def load(self):
49         """
50         Load /etc/passwd
51         """
52         self.passwd = []
53         with open(self.passwd_file, 'r') as f:
54             while True:
55                 rawline = f.readline()
56                 if not rawline:
57                     break
58 
59                 line = rawline.strip()
60                 if not line:
61                     continue
62 
63                 if line.startswith('#'):
64                     continue
65 
66                 (pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir,
67                  pw_shell) = line.split(':')
68 
69                 e = {}
70                 e["pw_name"] = pw_name
71                 e["pw_passwd"] = pw_passwd
72                 e["pw_gecos"] = pw_gecos
73                 e["pw_dir"] = pw_dir
74                 e["pw_shell"] = pw_shell
75                 try:
76                     e["pw_uid"] = int(pw_uid)
77                 except ValueError:
78                     e["pw_uid"] = 1001
79                 try:
80                     e["pw_gid"] = int(pw_gid)
81                 except ValueError:
82                     e["pw_gid"] = 1001
83 
84                 self.passwd.append(e)
85 
86     def save(self):
87         """
88         Save the user db
89         Note: this is subject to races between cowrie instances, but hey ...
90         """
91         #        with open(self.passwd_file, 'w') as f:
92         #            for (login, uid, passwd) in self.userdb:
93         #                f.write('%s:%d:%s\n' % (login, uid, passwd))
94         raise NotImplementedError
95 
96     def getpwnam(self, name):
97         """
98         Get passwd entry for username
99         """
100         for _ in self.passwd:
101             if name == _["pw_name"]:
102                 return _
103         raise KeyError("getpwnam(): name not found in passwd file: " + name)
104 
105     def getpwuid(self, uid):
106         """
107         Get passwd entry for uid
108         """
109         for _ in self.passwd:
110             if uid == _["pw_uid"]:
111                 return _
112         raise KeyError("getpwuid(): uid not found in passwd file: " + str(uid))
113 
114     def setpwentry(self, name):
115         """
116         If the user is not in /etc/passwd, creates a new user entry for the session
117         """
118 
119         # ensure consistent uid and gid
120         seed_id = crc32(name)
121         seed(seed_id)
122 
123         e = {}
124         e["pw_name"] = name
125         e["pw_passwd"] = "x"
126         e["pw_gecos"] = 0
127         e["pw_dir"] = "/home/" + name
128         e["pw_shell"] = "/bin/bash"
129         e["pw_uid"] = randint(1500, 10000)
130         e["pw_gid"] = e["pw_uid"]
131         self.passwd.append(e)
132         return e
133 
134 
135 class Group(object):
136     """
137     This class contains code to handle the groups and their properties in
138     /etc/group.
139     """
140 
141     def __init__(self):
142         self.group_file = '%s/etc/group' % (CONFIG.get('honeypot', 'contents_path'),)
143         self.load()
144 
145     def load(self):
146         """
147         Load /etc/group
148         """
149         self.group = []
150         with open(self.group_file, 'r') as f:
151             while True:
152                 rawline = f.readline()
153                 if not rawline:
154                     break
155 
156                 line = rawline.strip()
157                 if not line:
158                     continue
159 
160                 if line.startswith('#'):
161                     continue
162 
163                 (gr_name, gr_passwd, gr_gid, gr_mem) = line.split(':')
164 
165                 e = {}
166                 e["gr_name"] = gr_name
167                 try:
168                     e["gr_gid"] = int(gr_gid)
169                 except ValueError:
170                     e["gr_gid"] = 1001
171                 e["gr_mem"] = gr_mem
172 
173                 self.group.append(e)
174 
175     def save(self):
176         """
177         Save the group db
178         Note: this is subject to races between cowrie instances, but hey ...
179         """
180         #        with open(self.group_file, 'w') as f:
181         #            for (login, uid, passwd) in self.userdb:
182         #                f.write('%s:%d:%s\n' % (login, uid, passwd))
183         raise NotImplementedError
184 
185     def getgrnam(self, name):
186         """
187         Get group entry for groupname
188         """
189         for _ in self.group:
190             if name == _["gr_name"]:
191                 return _
192         raise KeyError("getgrnam(): name not found in group file: " + name)
193 
194     def getgrgid(self, uid):
195         """
196         Get group entry for gid
197         """
198         for _ in self.group:
199             if uid == _["gr_gid"]:
200                 return _
201         raise KeyError("getgruid(): uid not found in group file: " + str(uid))
202
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cowrie/shell/pwd.py b/src/cowrie/shell/pwd.py
--- a/src/cowrie/shell/pwd.py
+++ b/src/cowrie/shell/pwd.py
@@ -117,7 +117,7 @@
         """
 
         # ensure consistent uid and gid
-        seed_id = crc32(name)
+        seed_id = crc32(name.encode("utf-8"))
         seed(seed_id)
 
         e = {}

{"golden_diff": "diff --git a/src/cowrie/shell/pwd.py b/src/cowrie/shell/pwd.py\n--- a/src/cowrie/shell/pwd.py\n+++ b/src/cowrie/shell/pwd.py\n@@ -117,7 +117,7 @@\n         \"\"\"\n \n         # ensure consistent uid and gid\n-        seed_id = crc32(name)\n+        seed_id = crc32(name.encode(\"utf-8\"))\n         seed(seed_id)\n \n         e = {}\n", "issue": "Can't enter using \"oracle\" or \"tomcat\" users\nHello.\r\nI'm using stock userdb.txt file, where \"oracle\" and \"tomcat\" users are defined with any password. When using these users, the ssh client gives me an error of \"Permission denied (publickey,password)\" after entering three times any password.\r\n\r\nThe ugly thing is that in cowrie.json file appear entries of \"cowrie.login.success\" type with the message \"login attempt [oracle/password] suceeded\", which is, obviously, incorrect.\r\n\r\nThanks a lot\n", "before_files": [{"content": "# Copyright (c) 2015 Michel Oosterhof <michel@oosterhof.net>\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n# 1. Redistributions of source code must retain the above copyright\n#    notice, this list of conditions and the following disclaimer.\n# 2. Redistributions in binary form must reproduce the above copyright\n#    notice, this list of conditions and the following disclaimer in the\n#    documentation and/or other materials provided with the distribution.\n# 3. The names of the author(s) may not be used to endorse or promote\n#    products derived from this software without specific prior written\n#    permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n# SUCH DAMAGE.\n\nfrom __future__ import absolute_import, division\n\nfrom binascii import crc32\nfrom random import randint, seed\n\nfrom cowrie.core.config import CONFIG\n\n\nclass Passwd(object):\n    \"\"\"\n    This class contains code to handle the users and their properties in\n    /etc/passwd. Note that contrary to the name, it does not handle any\n    passwords.\n    \"\"\"\n\n    def __init__(self):\n        self.passwd_file = '%s/etc/passwd' % (CONFIG.get('honeypot', 'contents_path'),)\n        self.load()\n\n    def load(self):\n        \"\"\"\n        Load /etc/passwd\n        \"\"\"\n        self.passwd = []\n        with open(self.passwd_file, 'r') as f:\n            while True:\n                rawline = f.readline()\n                if not rawline:\n                    break\n\n                line = rawline.strip()\n                if not line:\n                    continue\n\n                if line.startswith('#'):\n                    continue\n\n                (pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir,\n                 pw_shell) = line.split(':')\n\n                e = {}\n                e[\"pw_name\"] = pw_name\n                e[\"pw_passwd\"] = pw_passwd\n                e[\"pw_gecos\"] = pw_gecos\n                e[\"pw_dir\"] = pw_dir\n                e[\"pw_shell\"] = pw_shell\n                try:\n                    e[\"pw_uid\"] = int(pw_uid)\n                except ValueError:\n                    e[\"pw_uid\"] = 1001\n                try:\n                    e[\"pw_gid\"] = int(pw_gid)\n                except ValueError:\n                    e[\"pw_gid\"] = 1001\n\n                self.passwd.append(e)\n\n    def save(self):\n        \"\"\"\n        Save the user db\n        Note: this is subject to races between cowrie instances, but hey ...\n        \"\"\"\n        #        with open(self.passwd_file, 'w') as f:\n        #            for (login, uid, passwd) in self.userdb:\n        #                f.write('%s:%d:%s\\n' % (login, uid, passwd))\n        raise NotImplementedError\n\n    def getpwnam(self, name):\n        \"\"\"\n        Get passwd entry for username\n        \"\"\"\n        for _ in self.passwd:\n            if name == _[\"pw_name\"]:\n                return _\n        raise KeyError(\"getpwnam(): name not found in passwd file: \" + name)\n\n    def getpwuid(self, uid):\n        \"\"\"\n        Get passwd entry for uid\n        \"\"\"\n        for _ in self.passwd:\n            if uid == _[\"pw_uid\"]:\n                return _\n        raise KeyError(\"getpwuid(): uid not found in passwd file: \" + str(uid))\n\n    def setpwentry(self, name):\n        \"\"\"\n        If the user is not in /etc/passwd, creates a new user entry for the session\n        \"\"\"\n\n        # ensure consistent uid and gid\n        seed_id = crc32(name)\n        seed(seed_id)\n\n        e = {}\n        e[\"pw_name\"] = name\n        e[\"pw_passwd\"] = \"x\"\n        e[\"pw_gecos\"] = 0\n        e[\"pw_dir\"] = \"/home/\" + name\n        e[\"pw_shell\"] = \"/bin/bash\"\n        e[\"pw_uid\"] = randint(1500, 10000)\n        e[\"pw_gid\"] = e[\"pw_uid\"]\n        self.passwd.append(e)\n        return e\n\n\nclass Group(object):\n    \"\"\"\n    This class contains code to handle the groups and their properties in\n    /etc/group.\n    \"\"\"\n\n    def __init__(self):\n        self.group_file = '%s/etc/group' % (CONFIG.get('honeypot', 'contents_path'),)\n        self.load()\n\n    def load(self):\n        \"\"\"\n        Load /etc/group\n        \"\"\"\n        self.group = []\n        with open(self.group_file, 'r') as f:\n            while True:\n                rawline = f.readline()\n                if not rawline:\n                    break\n\n                line = rawline.strip()\n                if not line:\n                    continue\n\n                if line.startswith('#'):\n                    continue\n\n                (gr_name, gr_passwd, gr_gid, gr_mem) = line.split(':')\n\n                e = {}\n                e[\"gr_name\"] = gr_name\n                try:\n                    e[\"gr_gid\"] = int(gr_gid)\n                except ValueError:\n                    e[\"gr_gid\"] = 1001\n                e[\"gr_mem\"] = gr_mem\n\n                self.group.append(e)\n\n    def save(self):\n        \"\"\"\n        Save the group db\n        Note: this is subject to races between cowrie instances, but hey ...\n        \"\"\"\n        #        with open(self.group_file, 'w') as f:\n        #            for (login, uid, passwd) in self.userdb:\n        #                f.write('%s:%d:%s\\n' % (login, uid, passwd))\n        raise NotImplementedError\n\n    def getgrnam(self, name):\n        \"\"\"\n        Get group entry for groupname\n        \"\"\"\n        for _ in self.group:\n            if name == _[\"gr_name\"]:\n                return _\n        raise KeyError(\"getgrnam(): name not found in group file: \" + name)\n\n    def getgrgid(self, uid):\n        \"\"\"\n        Get group entry for gid\n        \"\"\"\n        for _ in self.group:\n            if uid == _[\"gr_gid\"]:\n                return _\n        raise KeyError(\"getgruid(): uid not found in group file: \" + str(uid))\n", "path": "src/cowrie/shell/pwd.py"}], "after_files": [{"content": "# Copyright (c) 2015 Michel Oosterhof <michel@oosterhof.net>\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n# 1. Redistributions of source code must retain the above copyright\n#    notice, this list of conditions and the following disclaimer.\n# 2. Redistributions in binary form must reproduce the above copyright\n#    notice, this list of conditions and the following disclaimer in the\n#    documentation and/or other materials provided with the distribution.\n# 3. The names of the author(s) may not be used to endorse or promote\n#    products derived from this software without specific prior written\n#    permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR\n# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n# SUCH DAMAGE.\n\nfrom __future__ import absolute_import, division\n\nfrom binascii import crc32\nfrom random import randint, seed\n\nfrom cowrie.core.config import CONFIG\n\n\nclass Passwd(object):\n    \"\"\"\n    This class contains code to handle the users and their properties in\n    /etc/passwd. Note that contrary to the name, it does not handle any\n    passwords.\n    \"\"\"\n\n    def __init__(self):\n        self.passwd_file = '%s/etc/passwd' % (CONFIG.get('honeypot', 'contents_path'),)\n        self.load()\n\n    def load(self):\n        \"\"\"\n        Load /etc/passwd\n        \"\"\"\n        self.passwd = []\n        with open(self.passwd_file, 'r') as f:\n            while True:\n                rawline = f.readline()\n                if not rawline:\n                    break\n\n                line = rawline.strip()\n                if not line:\n                    continue\n\n                if line.startswith('#'):\n                    continue\n\n                (pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir,\n                 pw_shell) = line.split(':')\n\n                e = {}\n                e[\"pw_name\"] = pw_name\n                e[\"pw_passwd\"] = pw_passwd\n                e[\"pw_gecos\"] = pw_gecos\n                e[\"pw_dir\"] = pw_dir\n                e[\"pw_shell\"] = pw_shell\n                try:\n                    e[\"pw_uid\"] = int(pw_uid)\n                except ValueError:\n                    e[\"pw_uid\"] = 1001\n                try:\n                    e[\"pw_gid\"] = int(pw_gid)\n                except ValueError:\n                    e[\"pw_gid\"] = 1001\n\n                self.passwd.append(e)\n\n    def save(self):\n        \"\"\"\n        Save the user db\n        Note: this is subject to races between cowrie instances, but hey ...\n        \"\"\"\n        #        with open(self.passwd_file, 'w') as f:\n        #            for (login, uid, passwd) in self.userdb:\n        #                f.write('%s:%d:%s\\n' % (login, uid, passwd))\n        raise NotImplementedError\n\n    def getpwnam(self, name):\n        \"\"\"\n        Get passwd entry for username\n        \"\"\"\n        for _ in self.passwd:\n            if name == _[\"pw_name\"]:\n                return _\n        raise KeyError(\"getpwnam(): name not found in passwd file: \" + name)\n\n    def getpwuid(self, uid):\n        \"\"\"\n        Get passwd entry for uid\n        \"\"\"\n        for _ in self.passwd:\n            if uid == _[\"pw_uid\"]:\n                return _\n        raise KeyError(\"getpwuid(): uid not found in passwd file: \" + str(uid))\n\n    def setpwentry(self, name):\n        \"\"\"\n        If the user is not in /etc/passwd, creates a new user entry for the session\n        \"\"\"\n\n        # ensure consistent uid and gid\n        seed_id = crc32(name.encode(\"utf-8\"))\n        seed(seed_id)\n\n        e = {}\n        e[\"pw_name\"] = name\n        e[\"pw_passwd\"] = \"x\"\n        e[\"pw_gecos\"] = 0\n        e[\"pw_dir\"] = \"/home/\" + name\n        e[\"pw_shell\"] = \"/bin/bash\"\n        e[\"pw_uid\"] = randint(1500, 10000)\n        e[\"pw_gid\"] = e[\"pw_uid\"]\n        self.passwd.append(e)\n        return e\n\n\nclass Group(object):\n    \"\"\"\n    This class contains code to handle the groups and their properties in\n    /etc/group.\n    \"\"\"\n\n    def __init__(self):\n        self.group_file = '%s/etc/group' % (CONFIG.get('honeypot', 'contents_path'),)\n        self.load()\n\n    def load(self):\n        \"\"\"\n        Load /etc/group\n        \"\"\"\n        self.group = []\n        with open(self.group_file, 'r') as f:\n            while True:\n                rawline = f.readline()\n                if not rawline:\n                    break\n\n                line = rawline.strip()\n                if not line:\n                    continue\n\n                if line.startswith('#'):\n                    continue\n\n                (gr_name, gr_passwd, gr_gid, gr_mem) = line.split(':')\n\n                e = {}\n                e[\"gr_name\"] = gr_name\n                try:\n                    e[\"gr_gid\"] = int(gr_gid)\n                except ValueError:\n                    e[\"gr_gid\"] = 1001\n                e[\"gr_mem\"] = gr_mem\n\n                self.group.append(e)\n\n    def save(self):\n        \"\"\"\n        Save the group db\n        Note: this is subject to races between cowrie instances, but hey ...\n        \"\"\"\n        #        with open(self.group_file, 'w') as f:\n        #            for (login, uid, passwd) in self.userdb:\n        #                f.write('%s:%d:%s\\n' % (login, uid, passwd))\n        raise NotImplementedError\n\n    def getgrnam(self, name):\n        \"\"\"\n        Get group entry for groupname\n        \"\"\"\n        for _ in self.group:\n            if name == _[\"gr_name\"]:\n                return _\n        raise KeyError(\"getgrnam(): name not found in group file: \" + name)\n\n    def getgrgid(self, uid):\n        \"\"\"\n        Get group entry for gid\n        \"\"\"\n        for _ in self.group:\n            if uid == _[\"gr_gid\"]:\n                return _\n        raise KeyError(\"getgruid(): uid not found in group file: \" + str(uid))\n", "path": "src/cowrie/shell/pwd.py"}]}