X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/chopwood/blobdiff_plain/ea3f041b2d50610848bfd7eabc81588ca7d9e223..e3295bed428adbf5e1863f2d9395adac33dbb071:/chpwd diff --git a/chpwd b/chpwd index 65ae873..07fe830 100755 --- a/chpwd +++ b/chpwd @@ -30,6 +30,7 @@ import optparse as OP import os as OS; ENV = OS.environ import shlex as SL import sys as SYS +import syslog as L from auto import HOME, VERSION import cgi as CGI @@ -83,6 +84,19 @@ for short, long, props in [ 'help': "impersonate USER, and default context to `userv'." })]: OPTPARSE.add_option(short, long, **props) +def parse_options(): + """ + Parse the main command-line options, returning the positional arguments. + """ + global OPTS + OPTS, args = OPTPARSE.parse_args() + OPTPARSE.show_global_opts = False + ## It's tempting to load the configuration here. Don't do that. Some + ## contexts will want to check that the command line was handled properly + ## upstream before believing it for anything, such as executing arbitrary + ## Python code. + return args + ###-------------------------------------------------------------------------- ### CGI dispatch. @@ -95,10 +109,9 @@ CGI.SPECIAL['%user'] = None ## issuing redirects in the early setup phase fails because we don't know ## the script name. So package the setup here. def cgi_setup(ctx = 'cgi-noauth'): - global OPTS if OPTS: return OPTPARSE.context = ctx - OPTS, args = OPTPARSE.parse_args() + args = parse_options() if args: raise U.ExpectedError, (500, 'Unexpected arguments to CGI') CONF.loadconfig(OPTS.config) D.opendb() @@ -200,24 +213,30 @@ def cli_errors(): if __name__ == '__main__': + L.openlog(OS.path.basename(SYS.argv[0]), 0, L.LOG_AUTH) + if 'REQUEST_METHOD' in ENV: ## This looks like a CGI request. The heavy lifting for authentication ## over HTTP is done in `dispatch_cgi'. with OUT.redirect_to(CGI.HTTPOutput()): - with CGI.cgi_errors(cgi_setup): dispatch_cgi() + with U.Escape() as CGI.HEADER_DONE: + with CGI.cgi_errors(cgi_setup): + dispatch_cgi() elif 'USERV_SERVICE' in ENV: ## This is a Userv request. The caller's user name is helpfully in the ## `USERV_USER' environment variable. with cli_errors(): - OPTS, args = OPTPARSE.parse_args() + args = parse_options() + if not args or args[0] != 'userv': + raise U.ExpectedError, (500, 'missing userv token') CONF.loadconfig(OPTS.config) try: CU.set_user(ENV['USERV_USER']) except KeyError: raise ExpectedError, (500, 'USERV_USER unset') with OUT.redirect_to(O.FileOutput()): - OPTPARSE.dispatch('userv', [ENV['USERV_SERVICE']] + args) + OPTPARSE.dispatch('userv', [ENV['USERV_SERVICE']] + args[1:]) elif 'SSH_ORIGINAL_COMMAND' in ENV: ## This looks like an SSH request; but we present two different @@ -226,8 +245,7 @@ if __name__ == '__main__': def ssh_setup(): """Extract and parse the client's request from where SSH left it.""" - global OPTS - OPTS, args = OPTPARSE.parse_args() + args = parse_options() CONF.loadconfig(OPTS.config) cmd = SL.split(ENV['SSH_ORIGINAL_COMMAND']) if args: raise U.ExpectedError, (500, 'Unexpected arguments via SSH') @@ -240,7 +258,6 @@ if __name__ == '__main__': with cli_errors(): cmd = ssh_setup() CU.set_user(ENV['CHPWD_SSH_USER']) - S.SERVICES['master'].find(CU.USER) with OUT.redirect_to(O.FileOutput()): OPTPARSE.dispatch('userv', cmd) @@ -273,7 +290,7 @@ if __name__ == '__main__': ## as we are. with cli_errors(): - OPTS, args = OPTPARSE.parse_args() + args = parse_options() CONF.loadconfig(OPTS.config) CGI.SSLP = OPTS.sslp ctx = OPTS.context @@ -283,7 +300,9 @@ if __name__ == '__main__': if ctx is None: ctx = 'userv' else: D.opendb() - if ctx is None: ctx = 'admin' + if ctx is None: + ctx = 'admin' + OPTPARSE.show_global_opts = True with OUT.redirect_to(O.FileOutput()): OPTPARSE.dispatch(ctx, args)