Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 85 additions & 2 deletions authprogs/authprogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,93 @@ def find_match_scp(self, rule): # pylint: disable-msg=R0911,R0912
files = rule.get('files')
if not isinstance(files, list):
files = [files]
if filepath not in files:
if rule.get('pcre_match'):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be more clear that this is a pcre against the filename.

Rather than overloading 'files' lets add a new one, path_pcre (this will mirror the path_startswith that came in latest version)

files:
  - foo.txt
  - bar.txt 
paths_pcre: 
  - foo.*txt

Alternatively, if you don't actually need pcre and glob works then use path_glob - there is also now glob support in authprogs.py, which is used by rsync.

for file_pattern in files:
if re.search( file_pattern, filepath ):
# Allow it!
return {'command': self.original_command_list}
self.log(
'scp denied - file "{}" - not in approved '
'list {}\n'.format(filepath, files)
'regex {}\n'.format( filepath, files )
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional needs:

  • unit tests
  • update to doc/authprogs.md (man page)

)
return
else:
if filepath not in files:
self.log(
'scp denied - file "{}" - not in approved '
'list {}\n'.format(filepath, files)
)
return

# Allow it!
return {'command': self.original_command_list}

def find_match_rsync( self, rule ):
"""Handle rsync commands"""

orig_list = []
orig_list.extend(self.original_command_list)
binary = orig_list.pop(0)
allowed_binaries = ['rsync', '/usr/bin/rsync']
if binary not in allowed_binaries:
self.logdebug(
'skipping scp processing - binary "{}" '
'not in approved list.\n'.format(binary)
)
return

filepaths = []
while len( orig_list ) > 0:
path = orig_list.pop()
if path == ".":
break
filepaths.append( path )

arguments = orig_list

if '--server' not in arguments:
self.log(
'rsync denied - not in server mode.\n'
)
return

if '--sender' in arguments:
if not rule.get( 'allow_download' ):
self.log(
'rsync denied - downloading forbidden.\n'
)
return
else:
if not rule.get( 'allow_upload' ):
self.log(
'rsync denied - uploading forbidden.\n'
)
return

if rule.get('files'):
files = rule.get('files')
if not isinstance(files, list):
files = [files]
if rule.get('pcre_match'):
for filepath in filepaths:
cnt = 0
for file_pattern in files:
if re.search( file_pattern, filepath ):
cnt++
if cnt == 0:
self.log(
'rsync denied - file "{}" - not in approved '
'regex {}\n'.format( filepath, files )
)
return
else:
for filepath in filepaths:
if filepath not in files:
self.log(
'rsync denied - file "{}" - not in approved '
'list {}\n'.format(filepath, files)
)
return

# Allow it!
return {'command': self.original_command_list}
Expand Down Expand Up @@ -457,6 +538,8 @@ def find_match(self):
sub = self.find_match_command
elif rule_type == 'scp':
sub = self.find_match_scp
elif rule_type == 'rsync':
sub = self.find_match_rsync
else:
self.log(
'fatal: no such rule_type "{}"\n'.format(rule_type)
Expand Down