2013-10-27 21:59:46 +01:00
# Copyright (C) 2012-2013 Red Hat, Inc.
2012-02-10 07:54:32 -05:00
# Copyright (C) 2012 Cole Robinson <crobinso@redhat.com>
#
2018-04-04 14:35:41 +01:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 15:00:02 -04:00
# See the COPYING file in the top-level directory.
2012-02-10 07:54:32 -05:00
2018-03-15 21:22:14 -04:00
import collections
2012-02-10 07:54:32 -05:00
import logging
import os
2018-03-15 21:22:14 -04:00
import re
2012-02-10 14:07:51 -05:00
import time
2012-02-10 07:54:32 -05:00
2016-06-07 17:33:21 +02:00
from gi . repository import GLib
from gi . repository import Gio
2012-02-10 07:54:32 -05:00
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 :
2013-04-16 13:38:19 -04:00
bus = Gio . bus_get_sync ( Gio . BusType . SYSTEM , None )
2017-07-24 09:26:48 +01:00
except Exception :
2012-02-10 07:54:32 -05:00
logging . exception ( " Error getting system bus handle " )
2012-07-07 10:39:06 -04:00
return
# Check systemd
try :
2013-04-16 13:38:19 -04:00
manager = Gio . DBusProxy . new_sync ( bus , 0 , None ,
" org.freedesktop.login1 " ,
" /org/freedesktop/login1 " ,
" org.freedesktop.login1.Manager " , None )
ret = manager . GetSessionByPID ( " (u) " , pid )
2012-07-07 10:39:06 -04:00
logging . debug ( " Found login1 session= %s " , ret )
return True
2017-07-24 09:26:48 +01:00
except Exception :
2012-07-07 10:39:06 -04:00
logging . exception ( " Couldn ' t connect to logind " )
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
2018-05-02 19:55:07 -04:00
def creds_dialog ( creds , cbdata ) :
2012-02-10 07:54:32 -05:00
"""
Thread safe wrapper for libvirt openAuth user / pass callback
"""
2012-02-10 14:07:51 -05:00
retipc = [ ]
2018-05-02 19:55:07 -04:00
def wrapper ( fn , creds , cbdata ) :
2012-02-10 14:07:51 -05:00
try :
2018-05-02 19:55:07 -04:00
ret = fn ( creds , cbdata )
2017-07-24 09:26:48 +01:00
except Exception :
2012-02-10 14:07:51 -05:00
logging . exception ( " Error from creds dialog " )
ret = - 1
retipc . append ( ret )
2018-05-02 19:55:07 -04:00
GLib . idle_add ( wrapper , _creds_dialog_main , creds , cbdata )
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
2018-05-02 19:55:07 -04:00
def _creds_dialog_main ( creds , cbdata ) :
2012-02-10 07:54:32 -05:00
"""
Libvirt openAuth callback for username / password credentials
"""
2018-05-02 19:55:07 -04:00
_conn = cbdata
2014-04-02 18:39:43 -04:00
from gi . repository import Gtk
2012-02-10 07:54:32 -05:00
2016-02-05 16:18:16 +01:00
dialog = Gtk . Dialog ( _ ( " Authentication required " ) , None , 0 ,
2012-05-14 14:24:56 +01:00
( 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 :
2018-05-02 19:55:07 -04:00
# Libvirt virConnectCredential
credtype , prompt , _challenge , _defresult , _result = cred
noecho = credtype in [
libvirt . VIR_CRED_PASSPHRASE , libvirt . VIR_CRED_NOECHOPROMPT ]
if not prompt :
logging . error ( " No prompt for auth credtype= %s " , credtype )
2012-02-10 07:54:32 -05:00
return - 1
2018-05-02 19:55:07 -04:00
prompt + = " : "
text_label = Gtk . Label ( label = prompt )
text_label . set_alignment ( 0.0 , 0.5 )
label . append ( text_label )
2012-05-14 14:24:56 +01:00
ent = Gtk . Entry ( )
2018-05-02 19:55:07 -04:00
if noecho :
2012-02-10 07:54:32 -05:00
ent . set_visibility ( False )
ent . connect ( " activate " , _on_ent_activate )
entry . append ( ent )
2015-04-11 12:08:57 -04: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 :
2013-04-16 13:38:19 -04:00
bus = Gio . bus_get_sync ( Gio . BusType . SESSION , None )
ka = Gio . DBusProxy . new_sync ( bus , 0 , None ,
" org.gnome.KrbAuthDialog " ,
" /org/gnome/KrbAuthDialog " ,
" org.freedesktop.KrbAuthDialog " , None )
ret = ka . acquireTgt ( " (s) " , " " )
2017-05-05 12:47:21 -04:00
except Exception as e :
2018-03-02 08:01:23 +00:00
logging . info ( " Cannot acquire tgt %s " , str ( e ) )
2012-02-10 07:54:32 -05:00
ret = False
return ret
2018-03-15 21:22:14 -04:00
def connect_error ( conn , errmsg , tb , warnconsole ) :
"""
Format connection error message
"""
errmsg = errmsg . strip ( " \n " )
tb = tb . strip ( " \n " )
hint = " "
show_errmsg = True
config = conn . config
if conn . is_remote ( ) :
logging . debug ( " connect_error: conn transport= %s " ,
conn . get_uri_transport ( ) )
if re . search ( r " nc: .* -- ' U ' " , tb ) :
hint + = _ ( " The remote host requires a version of netcat/nc "
" which supports the -U option. " )
show_errmsg = False
elif ( conn . get_uri_transport ( ) == " ssh " and
re . search ( r " ssh-askpass " , tb ) ) :
askpass = ( config . askpass_package and
config . askpass_package [ 0 ] or
" openssh-askpass " )
hint + = _ ( " You need to install %s or "
" similar to connect to this host. " ) % askpass
show_errmsg = False
else :
hint + = _ ( " Verify that the ' libvirtd ' daemon is running "
" on the remote host. " )
elif conn . is_xen ( ) :
hint + = _ ( " Verify that: \n "
" - A Xen host kernel was booted \n "
" - The Xen service has been started " )
else :
if warnconsole :
hint + = _ ( " Could not detect a local session: if you are "
" running virt-manager over ssh -X or VNC, you "
" may not be able to connect to libvirt as a "
" regular user. Try running as root. " )
show_errmsg = False
elif re . search ( r " libvirt-sock " , tb ) :
hint + = _ ( " Verify that the ' libvirtd ' daemon is running. " )
show_errmsg = False
msg = _ ( " Unable to connect to libvirt %s . " % conn . get_uri ( ) )
if show_errmsg :
msg + = " \n \n %s " % errmsg
if hint :
msg + = " \n \n %s " % hint
msg = msg . strip ( " \n " )
details = msg
details + = " \n \n "
details + = " Libvirt URI is: %s \n \n " % conn . get_uri ( )
details + = tb
title = _ ( " Virtual Machine Manager Connection Failure " )
ConnectError = collections . namedtuple ( " ConnectError " ,
[ " msg " , " details " , " title " ] )
return ConnectError ( msg , details , title )