2012-02-10 07:54:32 -05:00
#
# Copyright (C) 2012 Red Hat, Inc.
# Copyright (C) 2012 Cole Robinson <crobinso@redhat.com>
#
# This program 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 of the License, or
# (at your option) any later version.
#
# This program 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; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
2013-04-11 17:16:33 -04:00
# pylint: disable=E0611
2013-02-16 14:03:30 -05:00
from gi . repository import GLib
2013-04-11 17:16:33 -04:00
# pylint: enable=E0611
2012-05-14 14:24:56 +01:00
2012-02-10 07:54:32 -05:00
import logging
import os
2012-02-10 14:07:51 -05:00
import time
2012-02-10 07:54:32 -05:00
import dbus
import libvirt
2013-04-13 14:34:52 -04:00
2012-02-10 07:54:32 -05:00
def do_we_have_session ( ) :
pid = os . getpid ( )
try :
bus = dbus . SystemBus ( )
except :
logging . exception ( " Error getting system bus handle " )
2012-07-07 10:39:06 -04:00
return
# Check systemd
try :
manager = dbus . Interface ( bus . get_object (
" org.freedesktop.login1 " ,
" /org/freedesktop/login1 " ) ,
" org.freedesktop.login1.Manager " )
ret = manager . GetSessionByPID ( pid )
logging . debug ( " Found login1 session= %s " , ret )
return True
except :
logging . exception ( " Couldn ' t connect to logind " )
2012-02-10 07:54:32 -05:00
# Check ConsoleKit
try :
manager = dbus . Interface ( bus . get_object (
" org.freedesktop.ConsoleKit " ,
" /org/freedesktop/ConsoleKit/Manager " ) ,
" org.freedesktop.ConsoleKit.Manager " )
ret = manager . GetSessionForUnixProcess ( pid )
logging . debug ( " Found ConsoleKit session= %s " , ret )
2012-07-07 10:39:06 -04:00
return True
2012-02-10 07:54:32 -05:00
except :
2012-07-07 10:39:06 -04:00
logging . exception ( " Couldn ' t connect to ConsoleKit " )
2012-02-10 07:54:32 -05:00
2012-07-07 10:39:06 -04:00
return False
2012-02-10 07:54:32 -05:00
def creds_polkit ( action ) :
"""
Libvirt openAuth callback for PolicyKit < 1.0
"""
if os . getuid ( ) == 0 :
logging . debug ( " Skipping policykit check as root " )
return 0
logging . debug ( " Doing policykit for %s " , action )
try :
# First try to use org.freedesktop.PolicyKit.AuthenticationAgent
# which is introduced with PolicyKit-0.7
bus = dbus . SessionBus ( )
obj = bus . get_object ( " org.freedesktop.PolicyKit.AuthenticationAgent " ,
" / " )
pkit = dbus . Interface ( obj ,
" org.freedesktop.PolicyKit.AuthenticationAgent " )
pkit . ObtainAuthorization ( action , 0 , os . getpid ( ) )
except dbus . exceptions . DBusException , e :
if ( e . get_dbus_name ( ) != " org.freedesktop.DBus.Error.ServiceUnknown " ) :
raise
# If PolicyKit < 0.7, fallback to org.gnome.PolicyKit
logging . debug ( " Falling back to org.gnome.PolicyKit " )
obj = bus . get_object ( " org.gnome.PolicyKit " ,
" /org/gnome/PolicyKit/Manager " )
pkit = dbus . Interface ( obj , " org.gnome.PolicyKit.Manager " )
pkit . ShowDialog ( action , 0 )
return 0
def creds_dialog ( creds ) :
"""
Thread safe wrapper for libvirt openAuth user / pass callback
"""
2012-02-10 14:07:51 -05:00
retipc = [ ]
def wrapper ( fn , creds ) :
try :
ret = fn ( creds )
except :
logging . exception ( " Error from creds dialog " )
ret = - 1
retipc . append ( ret )
2013-02-16 14:03:30 -05:00
GLib . idle_add ( wrapper , creds_dialog_main , creds )
2012-02-10 07:54:32 -05:00
2012-02-10 14:07:51 -05:00
while not retipc :
time . sleep ( .1 )
return retipc [ 0 ]
2012-02-10 07:54:32 -05:00
def creds_dialog_main ( creds ) :
"""
Libvirt openAuth callback for username / password credentials
"""
2013-04-13 14:34:52 -04:00
from gi . repository import Gtk # pylint: disable=E0611
2012-02-10 07:54:32 -05:00
2012-05-14 14:24:56 +01:00
dialog = Gtk . Dialog ( " Authentication required " , None , 0 ,
( Gtk . STOCK_CANCEL , Gtk . ResponseType . CANCEL ,
Gtk . STOCK_OK , Gtk . ResponseType . OK ) )
2012-02-10 07:54:32 -05:00
label = [ ]
entry = [ ]
2012-05-14 14:24:56 +01:00
box = Gtk . Table ( 2 , len ( creds ) )
2012-02-10 07:54:32 -05:00
box . set_border_width ( 6 )
box . set_row_spacings ( 6 )
box . set_col_spacings ( 12 )
def _on_ent_activate ( ent ) :
idx = entry . index ( ent )
if idx < len ( entry ) - 1 :
entry [ idx + 1 ] . grab_focus ( )
else :
2012-05-14 14:24:56 +01:00
dialog . response ( Gtk . ResponseType . OK )
2012-02-10 07:54:32 -05:00
row = 0
for cred in creds :
if ( cred [ 0 ] == libvirt . VIR_CRED_AUTHNAME or
cred [ 0 ] == libvirt . VIR_CRED_PASSPHRASE ) :
prompt = cred [ 1 ]
if not prompt . endswith ( " : " ) :
prompt + = " : "
2012-05-14 14:24:56 +01:00
text_label = Gtk . Label ( label = prompt )
2012-02-10 07:54:32 -05:00
text_label . set_alignment ( 0.0 , 0.5 )
label . append ( text_label )
else :
return - 1
2012-05-14 14:24:56 +01:00
ent = Gtk . Entry ( )
2012-02-10 07:54:32 -05:00
if cred [ 0 ] == libvirt . VIR_CRED_PASSPHRASE :
ent . set_visibility ( False )
ent . connect ( " activate " , _on_ent_activate )
entry . append ( ent )
2012-05-14 14:24:56 +01:00
box . attach ( label [ row ] , 0 , 1 , row , row + 1 , Gtk . AttachOptions . FILL , 0 , 0 , 0 )
box . attach ( entry [ row ] , 1 , 2 , row , row + 1 , Gtk . AttachOptions . FILL , 0 , 0 , 0 )
2012-02-10 07:54:32 -05:00
row = row + 1
vbox = dialog . get_child ( )
vbox . add ( box )
dialog . show_all ( )
res = dialog . run ( )
dialog . hide ( )
2012-05-14 14:24:56 +01:00
if res == Gtk . ResponseType . OK :
2012-02-10 07:54:32 -05:00
row = 0
for cred in creds :
cred [ 4 ] = entry [ row ] . get_text ( )
row = row + 1
2012-02-10 14:07:51 -05:00
ret = 0
2012-02-10 07:54:32 -05:00
else :
2012-02-10 14:07:51 -05:00
ret = - 1
dialog . destroy ( )
return ret
2012-02-10 07:54:32 -05:00
def acquire_tgt ( ) :
"""
Try to get kerberos ticket if openAuth seems to require it
"""
logging . debug ( " In acquire tgt. " )
try :
bus = dbus . SessionBus ( )
ka = bus . get_object ( ' org.gnome.KrbAuthDialog ' ,
' /org/gnome/KrbAuthDialog ' )
ret = ka . acquireTgt ( " " , dbus_interface = ' org.gnome.KrbAuthDialog ' )
except Exception , e :
logging . info ( " Cannot acquire tgt " + str ( e ) )
ret = False
return ret