In principle our downstreams should be able to cope with this. But
maybe they haven't had the fixes, and dumping strange stuff into the
output file seems unfriendly.
So reimplement copyout as a function which reassembles the output line
from pieces, and checks that each Tainted word it is writing out has
been verified by someone to be OK.
As a side effect we normalise the whitespace including indentation.
We rename the input line variable in pline from `i' to `il', since it
contains possibly dangerous content. This makes sure we caught all of
the places it is used.
With these changes, it is necessary to add a couple of explicit calls
to Tainted methods for otherwise-unused parameters, notably the group
name in location() definitions in user-provided site fragments, and
the (optional) email address in an ssh1 rsa key.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
# caller promises to throw if syntax was dangeorus
return self._rtn(True)
# caller promises to throw if syntax was dangeorus
return self._rtn(True)
+ def output(self):
+ if self._ok is False: return ''
+ if self._ok is True: return self._s
+ print('%s:%d: unchecked/unknown additional data "%s"' %
+ (self._file,self._line,self._s),
+ file=sys.stderr)
+ sys.exit(1)
+
bad_name=re.compile(r'^[^a-zA-Z]|[^-_0-9a-zA-Z]')
# secnet accepts _ at start of names, but we reserve that
bad_name_counter=0
bad_name=re.compile(r'^[^a-zA-Z]|[^-_0-9a-zA-Z]')
# secnet accepts _ at start of names, but we reserve that
bad_name_counter=0
self.l=w[1].number(0,max['rsa_bits'],'rsa len')
self.e=w[2].bignum_10('rsa','rsa e')
self.n=w[3].bignum_10('rsa','rsa n')
self.l=w[1].number(0,max['rsa_bits'],'rsa len')
self.e=w[2].bignum_10('rsa','rsa e')
self.n=w[3].bignum_10('rsa','rsa n')
+ if len(w) >= 5: w[4].email()
def __str__(self):
return 'rsa-public("%s","%s")'%(self.e,self.n)
def __str__(self):
return 'rsa-public("%s","%s")'%(self.e,self.n)
else:
obj.properties[prop.raw()]=keywords[prop.raw_mark_ok()][0](w)
else:
obj.properties[prop.raw()]=keywords[prop.raw_mark_ok()][0](w)
-def pline(i,allow_include=False):
+
+def pline(il,allow_include=False):
"Process a configuration file line"
global allow_defs, obstack, root
"Process a configuration file line"
global allow_defs, obstack, root
- w=i.rstrip('\n').split()
- if len(w)==0: return [i]
+ w=il.rstrip('\n').split()
+ if len(w)==0: return ['']
w=list([Tainted(x) for x in w])
keyword=w[0]
current=obstack[len(obstack)-1]
w=list([Tainted(x) for x in w])
keyword=w[0]
current=obstack[len(obstack)-1]
+ copyout=lambda: [' '*len(obstack) +
+ ' '.join([ww.output() for ww in w]) +
+ '\n']
if keyword=='end-definitions':
keyword.raw_mark_ok()
allow_defs=sitelevel.depth
if keyword=='end-definitions':
keyword.raw_mark_ok()
allow_defs=sitelevel.depth
if service and group and current.depth==2:
if group!=current.group:
complain("Incorrect group!")
if service and group and current.depth==2:
if group!=current.group:
complain("Incorrect group!")
else:
# New
# Ignore depth check for now
else:
# New
# Ignore depth check for now