webui patch to switch to Apache digest (or basic or whatever) auth

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch removes the pass-through authentication and related forms
in favor of using Apache's digest auth (by default).    This makes it
trivial for people to replace the default in their Apache
configuration with mod_auth_ldap, mod_auth_pam, or whatever.  It is
generated against the latest git, but may apply to 0.6.2 with a little
manual fudging.

The default username/password in .htaccess is "cobbler/ILoveCobbler".
Obviously, you will want to change this.   A default was deemed safe
to include because the webui is disabled by default.

New users can be added using the htdigest command.
htdigest /var/www/cgi-bin/cobbler/.htaccess "Cobbler WebUI
Authentication" $username

Switching to other auth modules is left as an exercise to the user for
now, but submissions to the wiki for various modules will be welcomed
after 0.6.3 is released.

-Al
From 455e9f335df543fc7fd63e01e9e80545c637d921 Mon Sep 17 00:00:00 2001
From: Al Tobey <tobert@xxxxxxxxx>
Date: Fri, 26 Oct 2007 13:27:09 -0700
Subject: [PATCH] Switch auth from pass-through to Apache digest auth.

---
 MANIFEST.in                 |    1 +
 cobbler.spec                |    1 +
 cobbler/webui/CobblerWeb.py |  106 +++++++++--------------------------
 cobbler/webui/master.py     |  131 +++++++++++++++++++------------------------
 config/.htaccess            |    1 +
 config/cobbler.conf         |   12 ++++
 scripts/webui.cgi           |   26 ++++-----
 setup.py                    |    2 +-
 webui_templates/index.tmpl  |    5 --
 webui_templates/login.tmpl  |   28 ---------
 webui_templates/master.tmpl |   43 ++++++--------
 11 files changed, 130 insertions(+), 226 deletions(-)
 create mode 100644 config/.htaccess
 delete mode 100644 webui_templates/login.tmpl

diff --git a/MANIFEST.in b/MANIFEST.in
index c4103ec..85ba1ef 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -10,6 +10,7 @@ include config/modules.conf
 include config/auth.conf
 include config/webui-cherrypy.cfg
 include config/settings
+include config/.htaccess
 recursive-include templates *.template
 recursive-include kickstarts *.ks
 include docs/cobbler.1.gz
diff --git a/cobbler.spec b/cobbler.spec
index 326b586..8d7462e 100644
--- a/cobbler.spec
+++ b/cobbler.spec
@@ -142,6 +142,7 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man1/cobbler.1.gz
 /etc/init.d/cobblerd
 %config(noreplace) /etc/httpd/conf.d/cobbler.conf
+%config(noreplace) /var/www/cgi-bin/cobbler/.htaccess
 %dir /var/log/cobbler/syslog
 
 %defattr(755,root,root)
diff --git a/cobbler/webui/CobblerWeb.py b/cobbler/webui/CobblerWeb.py
index 93b47da..8e34eef 100644
--- a/cobbler/webui/CobblerWeb.py
+++ b/cobbler/webui/CobblerWeb.py
@@ -19,15 +19,9 @@ import string
 from cobbler.utils import *
 import logging
 import sys
-import Cookie
-import time
 
 LOGGING_ENABLED = True
 
-## FIXME: move to htaccess and eliminate browser cookies?
-
-COOKIE_TIMEOUT=29*60
-
 if LOGGING_ENABLED:
     # set up logging
     logger = logging.getLogger("cobbler.webui")
@@ -40,8 +34,6 @@ if LOGGING_ENABLED:
 else:
     logger = None
 
-INVALID_CREDS="Login Required"
-
 def log_exc():
     """
     Log active traceback to logfile.
@@ -68,9 +60,8 @@ class CobblerWeb(object):
         self.username = username
         self.password = password
         self.logout = None
-        self.__cookies = Cookie.SimpleCookie(Cookie.SimpleCookie(os.environ.get("HTTP_COOKIE","")))
 
-    def __xmlrpc_setup(self,is_login=False):
+    def __xmlrpc_setup(self):
         """
         Sets up the connection to the Cobbler XMLRPC server.  Right now, the
         r/w server is required.   In the future, it may be possible to instantiate
@@ -80,10 +71,6 @@ class CobblerWeb(object):
         # changed to always create a new connection object
         self.remote = xmlrpclib.Server(self.server, allow_none=True)
 
-        # if we do not have a token in memory, is it in a cookie?
-        if self.token is None:
-            self.token = self.__get_cookie_token()
-
         # else if we do have a token, try to use it...
         if self.token is not None:
             # validate that our token is still good
@@ -96,13 +83,11 @@ class CobblerWeb(object):
                         logger.info("token timeout for: %s" % self.username)
                         log_exc()
                     self.token = None
-                    # this should put us back to the login screen
-                    self.__cookie_logout()
                 else:
                     raise e
         
         # if we (still) don't have a token, login for the first time
-        if self.token is None and is_login:
+        elif self.password and self.username:
             try:
                 self.token = self.remote.login( self.username, self.password )
             except Exception, e:
@@ -110,14 +95,12 @@ class CobblerWeb(object):
                     logger.info("login failed for: %s" % self.username)
                 log_exc()
                 return False
-            self.__cookie_login(self.token) # save what we've got
             self.password = None # don't need it anymore, get rid of it
             return True
         
         # login failed
         return False
 
-
     def __render(self, template, data):
         """
         Call the templating engine (Cheetah), wrapping up the location
@@ -126,16 +109,6 @@ class CobblerWeb(object):
 
         data['base_url'] = self.base_url
 
-        # used by master.tmpl to determine whether or not to show login/logout links
-        if data.has_key("hide_links"):
-            data['logged_in'] = None
-        elif self.token is not None:
-            data['logged_in'] = 1
-        elif self.username and self.password:
-            data['logged_in'] = 'configured'
-        else:
-            data['logged_in'] = None
-
         filepath = os.path.join("/usr/share/cobbler/webui_templates/",template)
         tmpl = Template( file=filepath, searchList=[data] )
         return str(tmpl)
@@ -232,38 +205,11 @@ class CobblerWeb(object):
     # ------------------------------------------------------------------------ #
 
     def index(self):
-        return self.__render( 'index.tmpl', { "hide_links" : True } )
+        return self.__render( 'index.tmpl', { } )
 
     def menu(self):
         return self.__render( 'blank.tmpl', { } )
    
-
-    # ------------------------------------------------------------------------ #
-    # Authentication
-    # ------------------------------------------------------------------------ #
-
-    def login(self, message=None):
-        return self.__render( 'login.tmpl', {'message': message, "hide_links" : True } )
-
-    def login_submit(self, username=None, password=None, submit=None):
-        if username is None:
-            return self.error_page( "No username supplied." )
-        if password is None:
-            return self.error_page( "No password supplied." )
-
-        self.username = username
-        self.password = password
-
-        if not self.__xmlrpc_setup(is_login=True):
-            return self.login(message="Login Failed.")
-
-        return self.menu()
-
-    def logout_submit(self):
-        self.token = None
-        self.__cookie_logout()
-        return self.login()
-
     # ------------------------------------------------------------------------ #
     # Settings
     # ------------------------------------------------------------------------ #
@@ -274,7 +220,7 @@ class CobblerWeb(object):
 
     def settings_view(self):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         return self.__render( 'item.tmpl', {
             'item_data': self.remote.get_settings(),
@@ -287,7 +233,7 @@ class CobblerWeb(object):
 
     def distro_list(self):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
         distros = self.remote.get_distros()
         if len(distros) > 0:
             return self.__render( 'distro_list.tmpl', {
@@ -299,7 +245,7 @@ class CobblerWeb(object):
     def distro_edit(self, name=None):
 
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
          
         input_distro = None
         if name is not None:
@@ -316,7 +262,7 @@ class CobblerWeb(object):
                     delete1=None,delete2=None,**args):
 
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         # handle deletes as a special case
         if new_or_edit == 'edit' and delete1 and delete2:
@@ -383,7 +329,7 @@ class CobblerWeb(object):
     def system_list(self):
 
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         systems = self.remote.get_systems()
         if len(systems) > 0:
@@ -400,7 +346,7 @@ class CobblerWeb(object):
                     delete1=None, delete2=None, **args):
 
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         # parameter checking
         if name is None and editmode=='edit' and oldname is not None:
@@ -508,7 +454,7 @@ class CobblerWeb(object):
     def system_edit(self, name=None):
 
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         input_system = None
         if name is not None:
@@ -526,7 +472,7 @@ class CobblerWeb(object):
     # ------------------------------------------------------------------------ #
     def profile_list(self):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
         profiles = self.remote.get_profiles()
         if len(profiles) > 0:
             return self.__render( 'profile_list.tmpl', {
@@ -541,7 +487,7 @@ class CobblerWeb(object):
     def profile_edit(self, name=None, subprofile=0):
 
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         input_profile = None
         if name is not None:
@@ -564,7 +510,7 @@ class CobblerWeb(object):
                      parent=None,virtcpus=None,virtbridge=None,subprofile=None,**args):
 
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         # pre-command parameter checking 
         if name is None and editmode=='edit' and oldname is not None:
@@ -655,7 +601,7 @@ class CobblerWeb(object):
 
     def repo_list(self):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
         repos = self.remote.get_repos()
         if len(repos) > 0:
             return self.__render( 'repo_list.tmpl', {
@@ -666,7 +612,7 @@ class CobblerWeb(object):
 
     def repo_edit(self, name=None):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         input_repo = None
         if name is not None:
@@ -681,7 +627,7 @@ class CobblerWeb(object):
                   mirror=None,keep_updated=None,local_filename=None,
                   rpm_list=None,createrepo_flags=None,delete1=None,delete2=None,**args):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         # pre-command parameter checking
         if name is None and editmode=='edit' and oldname is not None:
@@ -744,14 +690,14 @@ class CobblerWeb(object):
 
     def ksfile_list(self):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
         return self.__render( 'ksfile_list.tmpl', {
             'ksfiles': self.remote.get_kickstart_templates(self.token)
         } )
 
     def ksfile_edit(self, name=None):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
         return self.__render( 'ksfile_edit.tmpl', {
             'name': name,
             'ksdata': self.remote.read_or_write_kickstart_template(name,True,"",self.token)
@@ -759,7 +705,7 @@ class CobblerWeb(object):
 
     def ksfile_save(self, name=None, ksdata=None, **args):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
         try:
             self.remote.read_or_write_kickstart_template(name,False,ksdata,self.token)
         except Exception, e:
@@ -772,7 +718,7 @@ class CobblerWeb(object):
  
     def sync(self):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
 
         try:
             rc = self.remote.sync(self.token)
@@ -789,7 +735,7 @@ class CobblerWeb(object):
 
     def random_mac(self):
         if not self.__xmlrpc_setup():
-            return self.login(message=INVALID_CREDS)
+            return self.xmlrpc_auth_failure()
         mac = self.remote.get_random_mac()
         return mac
 
@@ -805,6 +751,11 @@ class CobblerWeb(object):
             'message': message
         } )
 
+    def xmlrpc_auth_failure(self):
+        return self.__render( 'error_page.tmpl', {
+            'message': "XMLRPC Authentication Error.   See Apache logs for details."
+        } )
+
     # make CherryPy and related frameworks able to use this module easily
     # by borrowing the 'exposed' function attritbute standard and using
     # it for the modes() method
@@ -814,11 +765,6 @@ class CobblerWeb(object):
     index.exposed = True
     menu.exposed = True
 
-    login.exposed = True
-    login_submit.exposed = True
-    logout_submit.exposed = True
-    cookies.exposed = False
-
     distro_edit.exposed = True
     distro_list.exposed = True
     distro_save.exposed = True
diff --git a/cobbler/webui/master.py b/cobbler/webui/master.py
index 17d93b0..ee20ed7 100644
--- a/cobbler/webui/master.py
+++ b/cobbler/webui/master.py
@@ -33,10 +33,10 @@ VFN=valueForName
 currentTime=time.time
 __CHEETAH_version__ = '2.0rc8'
 __CHEETAH_versionTuple__ = (2, 0, 0, 'candidate', 8)
-__CHEETAH_genTime__ = 1192826261.8448961
-__CHEETAH_genTimestamp__ = 'Fri Oct 19 16:37:41 2007'
+__CHEETAH_genTime__ = 1193430296.732923
+__CHEETAH_genTimestamp__ = 'Fri Oct 26 13:24:56 2007'
 __CHEETAH_src__ = 'webui_templates/master.tmpl'
-__CHEETAH_srcLastModified__ = 'Fri Oct 12 11:53:14 2007'
+__CHEETAH_srcLastModified__ = 'Fri Oct 26 11:41:47 2007'
 __CHEETAH_docstring__ = 'Autogenerated by CHEETAH: The Python-Powered Template Engine'
 
 if __CHEETAH_versionTuple__ < RequiredCheetahVersionTuple:
@@ -69,7 +69,7 @@ class master(Template):
 
 
 
-        ## CHEETAH: generated from #block body at line 60, col 1.
+        ## CHEETAH: generated from #block body at line 53, col 1.
         trans = KWS.get("trans")
         if (not trans and not self._CHEETAH__isBuffering and not callable(self.transaction)):
             trans = self.transaction # is None unless self.awake() was called
@@ -148,75 +148,60 @@ class master(Template):
 
 <div id="sidebar">
     <ul id="nav">
-''')
-        if not VFFSL(SL,"logged_in",True): # generated from line 31, col 9
-            write('''            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 32, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 32, col 26.
-            write('''/login" class="menu">Log In</a></li>
-''')
-        else: # generated from line 33, col 9
-            write('''            <li><a href="/cobbler/webui/wui.html" class="menu">Docs</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 35, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 35, col 26.
-            write('''/settings_view" class="menu">Settings</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 36, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 36, col 26.
-            write('''/logout_submit" class="menu">Log Out</a></li>
-            <li><hr/></li>
-            <li>LIST</li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 39, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 39, col 26.
-            write('''/distro_list" class="menu">Distros</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 40, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 40, col 26.
-            write('''/profile_list" class="menu">Profiles</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 41, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 41, col 26.
-            write('''/system_list" class="menu">Systems</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 42, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 42, col 26.
-            write('''/ksfile_list" class="menu">Kickstarts</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 43, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 43, col 26.
-            write('''/repo_list" class="menu">Repos</a></li>
-            <li><hr/></li>
-            <li>ADD</li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 46, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 46, col 26.
-            write('''/distro_edit" class="menu">Distro</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 47, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 47, col 26.
-            write('''/profile_edit" class="menu">Profile</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 48, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 48, col 26.
-            write('''/subprofile_edit" class="menu">Subprofile</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 49, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 49, col 26.
-            write('''/system_edit" class="menu">System</a></li>
-            <li><a href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 50, col 26
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 50, col 26.
-            write('''/repo_edit" class="menu">Repo</a></li>
-            <li><hr/><br/></li>
-            <li><a class="button sync" href="''')
-            _v = VFFSL(SL,"base_url",True) # '$base_url' on line 52, col 46
-            if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 52, col 46.
-            write('''/sync">Sync</a></li>
-''')
-        write('''
-
+        <li><a href="/cobbler/webui/wui.html" class="menu">Docs</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 32, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 32, col 22.
+        write('''/settings_view" class="menu">Settings</a></li>
+        <li><hr/></li>
+        <li>LIST</li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 35, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 35, col 22.
+        write('''/distro_list" class="menu">Distros</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 36, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 36, col 22.
+        write('''/profile_list" class="menu">Profiles</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 37, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 37, col 22.
+        write('''/system_list" class="menu">Systems</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 38, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 38, col 22.
+        write('''/ksfile_list" class="menu">Kickstarts</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 39, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 39, col 22.
+        write('''/repo_list" class="menu">Repos</a></li>
+        <li><hr/></li>
+        <li>ADD</li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 42, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 42, col 22.
+        write('''/distro_edit" class="menu">Distro</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 43, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 43, col 22.
+        write('''/profile_edit" class="menu">Profile</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 44, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 44, col 22.
+        write('''/subprofile_edit" class="menu">Subprofile</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 45, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 45, col 22.
+        write('''/system_edit" class="menu">System</a></li>
+        <li><a href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 46, col 22
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 46, col 22.
+        write('''/repo_edit" class="menu">Repo</a></li>
+        <li><hr/><br/></li>
+        <li><a class="button sync" href="''')
+        _v = VFFSL(SL,"base_url",True) # '$base_url' on line 48, col 42
+        if _v is not None: write(_filter(_v, rawExpr='$base_url')) # from line 48, col 42.
+        write('''/sync">Sync</a></li>
     </ul>
 </div>
 
diff --git a/config/.htaccess b/config/.htaccess
new file mode 100644
index 0000000..310327a
--- /dev/null
+++ b/config/.htaccess
@@ -0,0 +1 @@
+cobbler:Cobbler WebUI Authentication:4551d917d1d3698954a91686ceb14f3a
diff --git a/config/cobbler.conf b/config/cobbler.conf
index 187e63e..1b0244f 100644
--- a/config/cobbler.conf
+++ b/config/cobbler.conf
@@ -22,4 +22,16 @@ ProxyPassReverse /cobbler_api http://localhost:25151/
 ProxyPass /cobbler_api_rw http://localhost:25152/
 ProxyPassReverse /cobbler_api_rw http://localhost:25152/
 
+# See: http://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie
+BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On
+
+# set up digest authentication for the webui
+# to add users: htdigest /var/www/cgi-bin/cobbler/.htaccess "Cobbler WebUI Authentication" $username
+<Location "/var/www/cgi-bin/cobbler/webui.cgi">
+    AuthType Digest
+    AuthName "Cobbler WebUI Authentication"
+    AuthDigestProvider file
+    AuthUserFile /var/www/cgi-bin/cobbler/.htaccess
+    Require valid-user
+</Location>
 
diff --git a/scripts/webui.cgi b/scripts/webui.cgi
index ed0690f..1a7257d 100755
--- a/scripts/webui.cgi
+++ b/scripts/webui.cgi
@@ -16,6 +16,7 @@ import cgitb
 import Cookie
 import os
 import sys
+import ConfigParser
 from cobbler.webui.CobblerWeb import CobblerWeb
 
 def map_modes():
@@ -44,8 +45,6 @@ def configure():
         'password':          None,
         'cgitb_enabled':     1     
     }
-    #config.username = 'testuser',
-    #config.password = 'llamas2007'
 
     # defaults
     if config['server'] is None:
@@ -54,6 +53,17 @@ def configure():
     if config['base_url'] is None:
         config['base_url'] = base_url()
 
+    if ( os.access('/etc/cobbler/auth.conf', os.R_OK) ):
+        config_parser = ConfigParser.ConfigParser()
+        auth_conf = open("/etc/cobbler/auth.conf")
+        config_parser.readfp(auth_conf)
+        auth_conf.close()
+        for auth in config_parser.items("xmlrpc_service_users"):
+            sys.stderr.write( str(auth) )
+            if auth[1].lower() != "disabled":
+                config['username'] = auth[0]
+                config['password'] = auth[1]
+
     return config
 
 def main():
@@ -61,7 +71,6 @@ def main():
     cw_conf = configure()
     path    = map_modes()
     form    = cgi.parse()
-    cookies = Cookie.SimpleCookie(os.environ.get("HTTP_COOKIE",""))
 
     # make cgitb enablement configurable
     if cw_conf['cgitb_enabled'] == 1:
@@ -80,12 +89,6 @@ def main():
     # instantiate a CobblerWeb object
     cw = CobblerWeb( **cw_conf )
 
-    # FIXME: allow for direct URL access and pages will redirect appropriately.
-
-    #if not path.startswith('login') and (cw_conf['token'] is None and (cw_conf['username'] is None or cw_conf['password'] is None)):
-    #    func = getattr( cw, 'login' )
-    #    content = func( message="Authentication Required." )
-
     # check for a valid path/mode
     if path in cw.modes():
         func = getattr( cw, path )
@@ -96,11 +99,6 @@ def main():
         func = getattr( cw, 'error_page' )
         content = func( "Invalid Mode: \"%s\"" % path )
 
-    # finally, get any cookies generated by the CobblerWeb object
-    cookie_header = cw.cookies().output()
-    if cookie_header:
-        print cookie_header
-
     # deliver content
     print "Content-type: text/html"
     print
diff --git a/setup.py b/setup.py
index f094d8b..93cb058 100644
--- a/setup.py
+++ b/setup.py
@@ -64,6 +64,7 @@ if __name__ == "__main__":
                                 (cgipath,  ['scripts/webui.cgi']),
  
                                 # miscellaneous config files
+                                (cgipath,  ['config/.htaccess']),
                                 (rotpath,  ['config/cobblerd_rotate']),
                                 (wwwconf,  ['config/cobbler.conf']),
                                 (cobpath,  ['config/cobbler_hosts']),
@@ -148,7 +149,6 @@ if __name__ == "__main__":
                                 (wwwtmpl,           ['webui_templates/master.tmpl']),
                                 (wwwtmpl,           ['webui_templates/item.tmpl']),
                                 (wwwtmpl,           ['webui_templates/index.tmpl']),
-                                (wwwtmpl,           ['webui_templates/login.tmpl']),
 
                                 # Web UI kickstart file editing
                                 (wwwtmpl,           ['webui_templates/ksfile_edit.tmpl']),
diff --git a/webui_templates/index.tmpl b/webui_templates/index.tmpl
index 8141734..5bbb0d7 100644
--- a/webui_templates/index.tmpl
+++ b/webui_templates/index.tmpl
@@ -4,10 +4,5 @@
 
 Welcome to <A HREF="http://cobbler.et.redhat.com";>Cobbler</A>.
 
-<br/>
-<br/>
-
-Please log in.
-
 #end block body
 
diff --git a/webui_templates/login.tmpl b/webui_templates/login.tmpl
deleted file mode 100644
index 891dc4c..0000000
--- a/webui_templates/login.tmpl
+++ /dev/null
@@ -1,28 +0,0 @@
-#extends cobbler.webui.master
-
-#block body
-<form method="post" action="$base_url/login_submit">
-
-#if $message
-    <h1>$message</h1>
-#end if
-
-<fieldset id="cform">
-    <legend>Log In</legend>
-
-    <label for="username">Username:</label>
-    <input type="text" id="username" name="username" style="width: 150px;" value="" size="16"/>
-
-    <br/>
-
-    <label for="password">Password:</label>
-    <input type="password" id="password" name="password" style="width: 150px;" value="" size="16"/>
-
-    <br/>
-
-    <input type="submit" name="submit" value="Login"/>
-
-</fieldset>
-</form>
-#end block body
-
diff --git a/webui_templates/master.tmpl b/webui_templates/master.tmpl
index 58ecdfa..abd09af 100644
--- a/webui_templates/master.tmpl
+++ b/webui_templates/master.tmpl
@@ -28,31 +28,24 @@
 
 <div id="sidebar">
     <ul id="nav">
-        #if not $logged_in 
-            <li><a href="$base_url/login" class="menu">Log In</a></li>
-        #else
-            <li><a href="/cobbler/webui/wui.html" class="menu">Docs</a></li>
-            <li><a href="$base_url/settings_view" class="menu">Settings</a></li>
-            <li><a href="$base_url/logout_submit" class="menu">Log Out</a></li>
-            <li><hr/></li>
-            <li>LIST</li>
-            <li><a href="$base_url/distro_list" class="menu">Distros</a></li>
-            <li><a href="$base_url/profile_list" class="menu">Profiles</a></li>
-            <li><a href="$base_url/system_list" class="menu">Systems</a></li>
-            <li><a href="$base_url/ksfile_list" class="menu">Kickstarts</a></li>
-            <li><a href="$base_url/repo_list" class="menu">Repos</a></li>
-            <li><hr/></li>
-            <li>ADD</li>
-            <li><a href="$base_url/distro_edit" class="menu">Distro</a></li>
-            <li><a href="$base_url/profile_edit" class="menu">Profile</a></li>
-            <li><a href="$base_url/subprofile_edit" class="menu">Subprofile</a></li>
-            <li><a href="$base_url/system_edit" class="menu">System</a></li>
-            <li><a href="$base_url/repo_edit" class="menu">Repo</a></li>
-            <li><hr/><br/></li>
-            <li><a class="button sync" href="$base_url/sync">Sync</a></li>
-        #end if
-
-
+        <li><a href="/cobbler/webui/wui.html" class="menu">Docs</a></li>
+        <li><a href="$base_url/settings_view" class="menu">Settings</a></li>
+        <li><hr/></li>
+        <li>LIST</li>
+        <li><a href="$base_url/distro_list" class="menu">Distros</a></li>
+        <li><a href="$base_url/profile_list" class="menu">Profiles</a></li>
+        <li><a href="$base_url/system_list" class="menu">Systems</a></li>
+        <li><a href="$base_url/ksfile_list" class="menu">Kickstarts</a></li>
+        <li><a href="$base_url/repo_list" class="menu">Repos</a></li>
+        <li><hr/></li>
+        <li>ADD</li>
+        <li><a href="$base_url/distro_edit" class="menu">Distro</a></li>
+        <li><a href="$base_url/profile_edit" class="menu">Profile</a></li>
+        <li><a href="$base_url/subprofile_edit" class="menu">Subprofile</a></li>
+        <li><a href="$base_url/system_edit" class="menu">System</a></li>
+        <li><a href="$base_url/repo_edit" class="menu">Repo</a></li>
+        <li><hr/><br/></li>
+        <li><a class="button sync" href="$base_url/sync">Sync</a></li>
     </ul>
 </div>
 
-- 
1.5.2.4

_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/et-mgmt-tools

[Index of Archives]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux