Add the cas-proxy-validate script with a setuid wrapper

This commit is contained in:
Daniel Berteaud 2013-09-17 13:56:10 +02:00
parent c8eb7a0e88
commit ac381110ec
4 changed files with 123 additions and 1 deletions

10
cas-proxy-validate.c Normal file
View File

@ -0,0 +1,10 @@
#include <unistd.h>
#ifndef REAL_PATH
#define REAL_PATH "/usr/share/SOGo/cgi-bin/cas-proxy-validate.py"
#endif
int main(ac, av)
char **av;
{
execv(REAL_PATH, av);
return 0;
}

View File

@ -1,5 +1,5 @@
%define version 0.2.12
%define release 1.beta1
%define release 1.beta2
%define name ipasserelle-groupware
Name: %{name}
@ -10,11 +10,13 @@ Group: Networking/Daemons
License: GPLv3+
URL: http://www.ipasserelle.com
Source0: %{name}-%{version}.tar.gz
Source1: cas-proxy-validate.c
BuildArch: noarch
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
BuildRequires: e-smith-devtools
BuildRequires: gcc
Requires: smeserver-release >= 8
Requires: e-smith-ldap >= 5.2.0-19
Requires: sogo >= 2.0.4b
@ -160,7 +162,9 @@ Based on smeserver-sogo from nethesis
%build
%{__mkdir_p} root/var/log/memcached-sogo
%{__mkdir_p} root/usr/share/SOGo/cgi-bin
perl ./createlinks
gcc -o root/usr/share/SOGo/cgi-bin/cas-proxy-validate %{SOURCE1}
%install
rm -rf $RPM_BUILD_ROOT
@ -179,6 +183,8 @@ rm -f %{name}-%{version}-filelist
--file /var/service/memcached-sogo/log/run 'attr(0755, root, root)' \
--dir /var/log/memcached-sogo 'attr(0700, sogo, sogo)' \
--file /etc/cron.hourly/sogo-sessions 'attr(0755, root, root)' \
--file /usr/share/SOGo/cgi-bin/cas-proxy-validate 'attr(4750, sogo, www)' \
--file /usr/share/SOGo/cgi-bin/cas-proxy-validate.py 'attr(0755, root, root)' \
$RPM_BUILD_ROOT > %{name}-%{version}-%{release}-filelist
%files -f %{name}-%{version}-%{release}-filelist

View File

@ -10,6 +10,19 @@
$OUT = "";
}
ScriptAlias /SOGo/cgi-bin /usr/share/SOGo/cgi-bin
<Directory /usr/share/SOGo/cgi-bin>
AllowOverride None
Options +ExecCGI
</Directory>
ProxyPass /SOGo/casProxy http://localhost/SOGo/cgi-bin/cas-proxy-validate
<Proxy http://localhost/SOGo/cgi-bin/cas-proxy-validate>
Order deny,allow
Allow from 127.0.0.1 192.168.7.1
</Proxy>
ProxyPass /SOGo http://127.0.0.1:{$sogod{'TCPPort'}}/SOGo
ProxyPassReverse /SOGo http://127.0.0.1:{$sogod{'TCPPort'}}/SOGo
SetEnvIf Host (.*) REQUEST_HOST=$1

View File

@ -0,0 +1,93 @@
#!/usr/bin/python
# cas-proxy-validate.py - this file is part of SOGo
#
# Copyright (C) 2010 Inverse inc.
#
# Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# This script provides a CGI to avoid reentrancy issues when using SOGo in CAS
# mode
# debian dep: python-memcache
import cgi
import memcache
import os
import sys
config = { "cas-addr": "127.0.0.1",
"memcached-addrs": ["unix:/var/run/sogo/memcached.sock"] }
class CASProxyValidator:
def run(self):
if os.environ.has_key("GATEWAY_INTERFACE"):
self._runAsCGI()
else:
self._runAsCmd()
def _runAsCGI(self):
if self._cgiChecks():
form = cgi.FieldStorage()
if form.list == []:
message = "Empty parameters : assuming cert. validation"
self._printCGIError(message, 200)
return
if form.has_key("pgtId") and form.has_key("pgtIou"):
pgtIou = form.getfirst("pgtIou")
pgtId = form.getfirst("pgtId")
self._registerPGTIdAndIou(pgtIou, pgtId)
message = "'%s' set to '%s'" \
% ("cas-pgtiou:%s" % pgtIou, pgtId)
self._printCGIError(message, 200)
else:
self._printCGIError("Missing parameter.")
def _cgiChecks(self):
rc = False
if os.environ["REQUEST_METHOD"] == "GET":
if os.environ["REMOTE_ADDR"] == config["cas-addr"]:
rc = True
else:
self._printCGIError("Who are you? (%s)" % os.environ["REMOTE_ADDR"])
else:
self._printCGIError("Only 'GET' is accepted.")
return rc
def _printCGIError(self, message, code = 403):
print("Status: %d\n"
"Content-Type: text/plain; charset=utf-8\n\n%s"
% (code, message))
def _runAsCmd(self):
if len(sys.argv) == 3:
self._registerPGTIdAndIou(sys.argv[1], sys.argv[2])
print "set '%s' to '%s'" \
% ("cas-pgtiou:%s" % sys.argv[1], sys.argv[2])
else:
raise Exception, "Missing or too many parameters."
def _registerPGTIdAndIou(self, pgtIou, pgtId):
mc = memcache.Client(config["memcached-addrs"])
mc.set("cas-pgtiou:%s" % pgtIou, pgtId)
if __name__ == "__main__":
process = CASProxyValidator()
process.run()