mirror of
				https://github.com/jtesta/ssh-audit.git
				synced 2025-11-03 18:52:15 +01:00 
			
		
		
		
	Now prints a more user-friendly error message when installed as a Snap package and permission errors are encountered. Updated the Snap build process as well.
This commit is contained in:
		@@ -21,7 +21,20 @@
 | 
			
		||||
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
   THE SOFTWARE.
 | 
			
		||||
"""
 | 
			
		||||
VERSION = 'v2.6.0-dev'
 | 
			
		||||
SSH_HEADER = 'SSH-{0}-OpenSSH_8.2'  # SSH software to impersonate
 | 
			
		||||
GITHUB_ISSUES_URL = 'https://github.com/jtesta/ssh-audit/issues'  # The URL to the Github issues tracker.
 | 
			
		||||
# The version to display.
 | 
			
		||||
VERSION = 'v2.6.0'
 | 
			
		||||
 | 
			
		||||
# SSH software to impersonate
 | 
			
		||||
SSH_HEADER = 'SSH-{0}-OpenSSH_8.2'
 | 
			
		||||
 | 
			
		||||
# The URL to the Github issues tracker.
 | 
			
		||||
GITHUB_ISSUES_URL = 'https://github.com/jtesta/ssh-audit/issues'
 | 
			
		||||
 | 
			
		||||
# The man page.  Only filled in on Windows systems.
 | 
			
		||||
WINDOWS_MAN_PAGE = ''
 | 
			
		||||
 | 
			
		||||
# True when installed from a Snap package, otherwise False.
 | 
			
		||||
SNAP_PACKAGE = False
 | 
			
		||||
 | 
			
		||||
# Error message when installed as a Snap package and a file access fails.
 | 
			
		||||
SNAP_PERMISSIONS_ERROR = 'Error while accessing file.  It appears that ssh-audit was installed as a Snap package.  In that case, there are two options:  1.) only try to read & write files in the $HOME/snap/ssh-audit/common/ directory, or 2.) grant permissions to read & write files in $HOME using the following command: "sudo snap connect ssh-audit:home :home"'
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@ from datetime import date
 | 
			
		||||
from ssh_audit import exitcodes
 | 
			
		||||
from ssh_audit.ssh2_kex import SSH2_Kex  # pylint: disable=unused-import
 | 
			
		||||
from ssh_audit.banner import Banner  # pylint: disable=unused-import
 | 
			
		||||
from ssh_audit.globals import SNAP_PACKAGE, SNAP_PERMISSIONS_ERROR
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Validates policy files and performs policy testing
 | 
			
		||||
@@ -122,6 +123,13 @@ class Policy:
 | 
			
		||||
            except FileNotFoundError:
 | 
			
		||||
                print("Error: policy file not found: %s" % policy_file)
 | 
			
		||||
                sys.exit(exitcodes.UNKNOWN_ERROR)
 | 
			
		||||
            except PermissionError as e:
 | 
			
		||||
                # If installed as a Snap package, print a more useful message with potential work-arounds.
 | 
			
		||||
                if SNAP_PACKAGE:
 | 
			
		||||
                    print(SNAP_PERMISSIONS_ERROR)
 | 
			
		||||
                else:
 | 
			
		||||
                    print("Error: insufficient permissions: %s" % str(e))
 | 
			
		||||
                sys.exit(exitcodes.UNKNOWN_ERROR)
 | 
			
		||||
 | 
			
		||||
        lines = []
 | 
			
		||||
        if policy_data is not None:
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,8 @@ import traceback
 | 
			
		||||
from typing import Dict, List, Set, Sequence, Tuple, Iterable  # noqa: F401
 | 
			
		||||
from typing import Callable, Optional, Union, Any  # noqa: F401
 | 
			
		||||
 | 
			
		||||
from ssh_audit.globals import SNAP_PACKAGE
 | 
			
		||||
from ssh_audit.globals import SNAP_PERMISSIONS_ERROR
 | 
			
		||||
from ssh_audit.globals import VERSION
 | 
			
		||||
from ssh_audit.globals import WINDOWS_MAN_PAGE
 | 
			
		||||
from ssh_audit.algorithm import Algorithm
 | 
			
		||||
@@ -560,18 +562,27 @@ def make_policy(aconf: AuditConf, banner: Optional['Banner'], kex: Optional['SSH
 | 
			
		||||
    if aconf.policy_file is None:
 | 
			
		||||
        raise RuntimeError('Internal error: cannot write policy file since filename is None!')
 | 
			
		||||
 | 
			
		||||
    # Open with mode 'x' (creates the file, or fails if it already exist).
 | 
			
		||||
    succeeded = True
 | 
			
		||||
    succeeded = False
 | 
			
		||||
    err = ''
 | 
			
		||||
    try:
 | 
			
		||||
        # Open with mode 'x' (creates the file, or fails if it already exist).
 | 
			
		||||
        with open(aconf.policy_file, 'x', encoding='utf-8') as f:
 | 
			
		||||
            f.write(policy_data)
 | 
			
		||||
        succeeded = True
 | 
			
		||||
    except FileExistsError:
 | 
			
		||||
        succeeded = False
 | 
			
		||||
        err = "Error: file already exists: %s" % aconf.policy_file
 | 
			
		||||
    except PermissionError as e:
 | 
			
		||||
        # If installed as a Snap package, print a more useful message with potential work-arounds.
 | 
			
		||||
        if SNAP_PACKAGE:
 | 
			
		||||
            print(SNAP_PERMISSIONS_ERROR)
 | 
			
		||||
            sys.exit(exitcodes.UNKNOWN_ERROR)
 | 
			
		||||
        else:
 | 
			
		||||
            err = "Error: insufficient permissions: %s" % str(e)
 | 
			
		||||
 | 
			
		||||
    if succeeded:
 | 
			
		||||
        print("Wrote policy to %s.  Customize as necessary, then run a policy scan with -P option." % aconf.policy_file)
 | 
			
		||||
    else:
 | 
			
		||||
        print("Error: file already exists: %s" % aconf.policy_file)
 | 
			
		||||
        print(err)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[..., None]) -> 'AuditConf':  # pylint: disable=too-many-statements
 | 
			
		||||
@@ -681,8 +692,16 @@ def process_commandline(out: OutputBuffer, args: List[str], usage_cb: Callable[.
 | 
			
		||||
 | 
			
		||||
    # If a file containing a list of targets was given, read it.
 | 
			
		||||
    if aconf.target_file is not None:
 | 
			
		||||
        with open(aconf.target_file, 'r', encoding='utf-8') as f:
 | 
			
		||||
            aconf.target_list = f.readlines()
 | 
			
		||||
        try:
 | 
			
		||||
            with open(aconf.target_file, 'r', encoding='utf-8') as f:
 | 
			
		||||
                aconf.target_list = f.readlines()
 | 
			
		||||
        except PermissionError as e:
 | 
			
		||||
            # If installed as a Snap package, print a more useful message with potential work-arounds.
 | 
			
		||||
            if SNAP_PACKAGE:
 | 
			
		||||
                print(SNAP_PERMISSIONS_ERROR)
 | 
			
		||||
            else:
 | 
			
		||||
                print("Error: insufficient permissions: %s" % str(e))
 | 
			
		||||
            sys.exit(exitcodes.UNKNOWN_ERROR)
 | 
			
		||||
 | 
			
		||||
        # Strip out whitespace from each line in target file, and skip empty lines.
 | 
			
		||||
        aconf.target_list = [target.strip() for target in aconf.target_list if target not in ("", "\n")]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user