Commit ae94e9f3 authored by Leo Pound Singer's avatar Leo Pound Singer
Browse files

Check permissions on netrc file

The netrc.netrc class from the Python standard library applies access
safety checks (requiring that the netrc file is readable only by the
current user, and not by group members or other users) only if using the
netrc file in the default location (~/.netrc). This subclass applies the
same access safety checks regardless of the path to the netrc file.
parent 726d0fe5
......@@ -17,11 +17,8 @@
# along with lvalert. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import netrc
import sys
import os
import time
import select
import logging
import libxml2
import getpass
......@@ -32,6 +29,7 @@ from M2Crypto.SSL import Context
# pubsub import must come first because it overloads part of the
# StanzaProcessor class
from ligo.lvalert import pubsub
from ligo.lvalert.utils import safe_netrc
from pyxmpp.all import JID,Iq,Presence,Message,StreamError,TLSSettings
from pyxmpp.jabber.all import Client
......@@ -150,8 +148,8 @@ if (opts.add_publisher or opts.create or opts.delete or opts.subscribe or opts.u
parser.error("--node must be provided")
try:
default_username, _, default_password = netrc.netrc(os.path.expanduser(opts.netrc)).authenticators(opts.server)
except:
default_username, _, default_password = safe_netrc(os.path.expanduser(opts.netrc)).authenticators(opts.server)
except IOError:
default_username, default_password = None, None
myusername = opts.username or default_username
......
......@@ -18,12 +18,9 @@
# along with lvalert. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import netrc
import sys
import os
import datetime
import time
import select
import logging
import libxml2
import getpass
......@@ -36,6 +33,7 @@ from M2Crypto.SSL import Context
# pubsub import must come first because it overloads part of the
# StanzaProcessor class
from ligo.lvalert import pubsub
from ligo.lvalert.utils import safe_netrc
from pyxmpp.all import JID,Iq,Presence,Message,StreamError,TLSSettings
from pyxmpp.jabber.all import Client
......@@ -163,8 +161,8 @@ if opts.version:
exit(0)
try:
default_username, _, default_password = netrc.netrc(os.path.expanduser(opts.netrc)).authenticators(opts.server)
except:
default_username, _, default_password = safe_netrc(os.path.expanduser(opts.netrc)).authenticators(opts.server)
except IOError:
default_username, default_password = None, None
myusername = opts.username or default_username
......
......@@ -17,7 +17,6 @@
# along with lvalert. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
import netrc
import sys
import os
import datetime
......@@ -31,6 +30,7 @@ from M2Crypto.SSL import Context
# pubsub import must come first because it overloads part of the
# StanzaProcessor class
from ligo.lvalert import pubsub
from ligo.lvalert.utils import safe_netrc
from pyxmpp.all import JID,TLSSettings
from pyxmpp.jabber.all import Client
......@@ -126,8 +126,8 @@ if opts.version:
exit(0)
try:
default_username, _, default_password = netrc.netrc(os.path.expanduser(opts.netrc)).authenticators(opts.server)
except:
default_username, _, default_password = safe_netrc(os.path.expanduser(opts.netrc)).authenticators(opts.server)
except IOError:
default_username, default_password = None, None
myusername = opts.username or default_username
......
......@@ -16,8 +16,12 @@
# You should have received a copy of the GNU General Public License
# along with lvalert. If not, see <http://www.gnu.org/licenses/>.
from netrc import netrc, NetrcParseError
import stat
import sys
import os
if os.name == 'posix':
import pwd
from six.moves.urllib.parse import urlparse
from six import StringIO
from optparse import *
......@@ -230,3 +234,33 @@ def submit_condor_job(subfile):
return p
class safe_netrc(netrc):
"""The netrc.netrc class from the Python standard library applies access
safety checks (requiring that the netrc file is readable only by the
current user, and not by group members or other users) only if using the
netrc file in the default location (~/.netrc). This subclass applies the
same access safety checks regardless of the path to the netrc file."""
def _parse(self, file, fp, default_netrc):
# Copied and adapted from netrc.py from Python 2.7
if os.name == 'posix':
prop = os.fstat(fp.fileno())
if prop.st_uid != os.getuid():
try:
fowner = pwd.getpwuid(prop.st_uid)[0]
except KeyError:
fowner = 'uid %s' % prop.st_uid
try:
user = pwd.getpwuid(os.getuid())[0]
except KeyError:
user = 'uid %s' % os.getuid()
raise NetrcParseError(
("~/.netrc file owner (%s) does not match"
" current user (%s)") % (fowner, user),
file)
if (prop.st_mode & (stat.S_IRWXG | stat.S_IRWXO)):
raise NetrcParseError(
"~/.netrc access too permissive: access"
" permissions must restrict access to only"
" the owner", file)
return netrc._parse(self, file, fp, default_netrc)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment