prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  [ssh] Can ssh plugin check the permissions set for /home/*/.ssh files?
  Hello!
  
  When users set wrong permissions to files in their ~/.ssh/ folder, i.e. they set write permission for `~/.ssh/authenticated_keys` for `other`, the SSH server will refuse to accept connections for this user.
  
  I think it would be nice for the [ssh] plugin to check, if the permissions set for files in the `.ssh` folders of system users are correct, or if they are corrupted in some way. 
  
  A very simple solution for that would be to just run `ls -l .ssh/` in every home directory. Would it be OK to extend the ssh plugin to do this? Would it be better to have a separate plugin do this?
  
  Let me know what you think, and I'll give it a try if that's ok :)
  
  </issue>
  <code>
  [start of sos/report/plugins/ssh.py]
  1 # Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
  2 
  3 # This file is part of the sos project: https://github.com/sosreport/sos
  4 #
  5 # This copyrighted material is made available to anyone wishing to use,
  6 # modify, copy, or redistribute it subject to the terms and conditions of
  7 # version 2 of the GNU General Public License.
  8 #
  9 # See the LICENSE file in the source distribution for further information.
  10 
  11 from sos.report.plugins import Plugin, IndependentPlugin
  12 
  13 
  14 class Ssh(Plugin, IndependentPlugin):
  15 
  16     short_desc = 'Secure shell service'
  17 
  18     plugin_name = 'ssh'
  19     profiles = ('services', 'security', 'system', 'identity')
  20 
  21     def setup(self):
  22 
  23         self.add_file_tags({
  24             '/etc/ssh/sshd_config': 'sshd_config',
  25             '/etc/ssh/ssh_config': 'ssh_config'
  26         })
  27 
  28         sshcfgs = [
  29             "/etc/ssh/ssh_config",
  30             "/etc/ssh/sshd_config"
  31             ]
  32 
  33         # Include main config files
  34         self.add_copy_spec(sshcfgs)
  35 
  36         # Read configs for any includes and copy those
  37         try:
  38             for sshcfg in sshcfgs:
  39                 tag = sshcfg.split('/')[-1]
  40                 with open(sshcfg, 'r') as cfgfile:
  41                     for line in cfgfile:
  42                         # skip empty lines and comments
  43                         if len(line.split()) == 0 or line.startswith('#'):
  44                             continue
  45                         # ssh_config keywords are allowed as case-insensitive
  46                         if line.lower().startswith('include'):
  47                             confarg = line.split()
  48                             self.add_copy_spec(confarg[1], tags=tag)
  49         except Exception:
  50             pass
  51 
  52 
  53 # vim: set et ts=4 sw=4 :
  54
  [end of sos/report/plugins/ssh.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/sos/report/plugins/ssh.py b/sos/report/plugins/ssh.py
  --- a/sos/report/plugins/ssh.py
  +++ b/sos/report/plugins/ssh.py
  @@ -9,6 +9,7 @@
   # See the LICENSE file in the source distribution for further information.
   
   from sos.report.plugins import Plugin, IndependentPlugin
  +import os.path
   
   
   class Ssh(Plugin, IndependentPlugin):
  @@ -33,6 +34,10 @@
           # Include main config files
           self.add_copy_spec(sshcfgs)
   
  +        self.included_configs(sshcfgs)
  +        self.user_ssh_files_permissions()
  +
  +    def included_configs(self, sshcfgs):
           # Read configs for any includes and copy those
           try:
               for sshcfg in sshcfgs:
  @@ -49,5 +54,33 @@
           except Exception:
               pass
   
  +    def user_ssh_files_permissions(self):
  +        """
  +        Iterate over .ssh folders in user homes to see their permissions.
  +
  +        Bad permissions can prevent SSH from allowing access to given user.
  +        """
  +        users_data = self.exec_cmd('getent passwd')
  +
  +        if users_data['status']:
  +            # If getent fails, fallback to just reading /etc/passwd
  +            try:
  +                with open('/etc/passwd') as passwd_file:
  +                    users_data_lines = passwd_file.readlines()
  +            except Exception:
  +                # If we can't read /etc/passwd, then there's something wrong.
  +                self._log_error("Couldn't read /etc/passwd")
  +                return
  +        else:
  +            users_data_lines = users_data['output'].splitlines()
  +
  +        # Read the home paths of users in the system and check the ~/.ssh dirs
  +        for usr_line in users_data_lines:
  +            try:
  +                home_dir = os.path.join(usr_line.split(':')[5], '.ssh')
  +                if self.path_isdir(home_dir):
  +                    self.add_cmd_output('ls -laZ {}'.format(home_dir))
  +            except IndexError:
  +                pass
   
   # vim: set et ts=4 sw=4 :
  
verification_info: {"golden_diff": "diff --git a/sos/report/plugins/ssh.py b/sos/report/plugins/ssh.py\n--- a/sos/report/plugins/ssh.py\n+++ b/sos/report/plugins/ssh.py\n@@ -9,6 +9,7 @@\n # See the LICENSE file in the source distribution for further information.\n \n from sos.report.plugins import Plugin, IndependentPlugin\n+import os.path\n \n \n class Ssh(Plugin, IndependentPlugin):\n@@ -33,6 +34,10 @@\n         # Include main config files\n         self.add_copy_spec(sshcfgs)\n \n+        self.included_configs(sshcfgs)\n+        self.user_ssh_files_permissions()\n+\n+    def included_configs(self, sshcfgs):\n         # Read configs for any includes and copy those\n         try:\n             for sshcfg in sshcfgs:\n@@ -49,5 +54,33 @@\n         except Exception:\n             pass\n \n+    def user_ssh_files_permissions(self):\n+        \"\"\"\n+        Iterate over .ssh folders in user homes to see their permissions.\n+\n+        Bad permissions can prevent SSH from allowing access to given user.\n+        \"\"\"\n+        users_data = self.exec_cmd('getent passwd')\n+\n+        if users_data['status']:\n+            # If getent fails, fallback to just reading /etc/passwd\n+            try:\n+                with open('/etc/passwd') as passwd_file:\n+                    users_data_lines = passwd_file.readlines()\n+            except Exception:\n+                # If we can't read /etc/passwd, then there's something wrong.\n+                self._log_error(\"Couldn't read /etc/passwd\")\n+                return\n+        else:\n+            users_data_lines = users_data['output'].splitlines()\n+\n+        # Read the home paths of users in the system and check the ~/.ssh dirs\n+        for usr_line in users_data_lines:\n+            try:\n+                home_dir = os.path.join(usr_line.split(':')[5], '.ssh')\n+                if self.path_isdir(home_dir):\n+                    self.add_cmd_output('ls -laZ {}'.format(home_dir))\n+            except IndexError:\n+                pass\n \n # vim: set et ts=4 sw=4 :\n", "issue": "[ssh] Can ssh plugin check the permissions set for /home/*/.ssh files?\nHello!\r\n\r\nWhen users set wrong permissions to files in their ~/.ssh/ folder, i.e. they set write permission for `~/.ssh/authenticated_keys` for `other`, the SSH server will refuse to accept connections for this user.\r\n\r\nI think it would be nice for the [ssh] plugin to check, if the permissions set for files in the `.ssh` folders of system users are correct, or if they are corrupted in some way. \r\n\r\nA very simple solution for that would be to just run `ls -l .ssh/` in every home directory. Would it be OK to extend the ssh plugin to do this? Would it be better to have a separate plugin do this?\r\n\r\nLet me know what you think, and I'll give it a try if that's ok :)\n", "before_files": [{"content": "# Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com>\n\n# This file is part of the sos project: https://github.com/sosreport/sos\n#\n# This copyrighted material is made available to anyone wishing to use,\n# modify, copy, or redistribute it subject to the terms and conditions of\n# version 2 of the GNU General Public License.\n#\n# See the LICENSE file in the source distribution for further information.\n\nfrom sos.report.plugins import Plugin, IndependentPlugin\n\n\nclass Ssh(Plugin, IndependentPlugin):\n\n    short_desc = 'Secure shell service'\n\n    plugin_name = 'ssh'\n    profiles = ('services', 'security', 'system', 'identity')\n\n    def setup(self):\n\n        self.add_file_tags({\n            '/etc/ssh/sshd_config': 'sshd_config',\n            '/etc/ssh/ssh_config': 'ssh_config'\n        })\n\n        sshcfgs = [\n            \"/etc/ssh/ssh_config\",\n            \"/etc/ssh/sshd_config\"\n            ]\n\n        # Include main config files\n        self.add_copy_spec(sshcfgs)\n\n        # Read configs for any includes and copy those\n        try:\n            for sshcfg in sshcfgs:\n                tag = sshcfg.split('/')[-1]\n                with open(sshcfg, 'r') as cfgfile:\n                    for line in cfgfile:\n                        # skip empty lines and comments\n                        if len(line.split()) == 0 or line.startswith('#'):\n                            continue\n                        # ssh_config keywords are allowed as case-insensitive\n                        if line.lower().startswith('include'):\n                            confarg = line.split()\n                            self.add_copy_spec(confarg[1], tags=tag)\n        except Exception:\n            pass\n\n\n# vim: set et ts=4 sw=4 :\n", "path": "sos/report/plugins/ssh.py"}]}