Differenze tra le versioni di "Inserire le password per lanciare comandi"

Da Gambas-it.org - Wikipedia.
Riga 168: Riga 168:
  
  
==Uso di ''gksu''==
+
==Dare una volta sola la password di root per aprire un file protetto==
Si potrà utilizzare semplicemente il comando ''gksu'' lanciato con ''Shell''. Nel primo spazio presente nella finestra, che sarà mostrata, si dovrà inserire l'intera riga di comando che si intende lanciare come ''root''.
+
Per far immettere la propria password di root, con Shell si utilizza il comando "sudo", ad esempio per ottenere libero accesso ai file-device.
'''Public''' Sub Button1_Click()
 
 
  Shell "gksu"
 
 
'''End'''
 
 
 
 
 
===Dare una volta sola la password di root per aprire un file protetto===
 
Per far immettere la propria password di root, con Shell si utilizza il comando gksu (o gksudo):
 
 
 
Shell "gksu ''file_ad_accesso_protetto''"
 
 
 
che fa aprire un'apposita finestra. Si dovrà, però, inserire ogni volta la password, se dobbiamo utilizzare il nostro applicativo più volte nella medesima sessione di sistema.
 
 
 
Si può ovviare a questo fastidio, utilizzando il comando ''chmod'' una volta sola per impostare il ''setUID''. Tale comando consentirà con effetto temporaneo, limitato alla sola attuale sessione di sistema, che tutti possano eseguire tranquillamente un programma o accedere ad un file che richiede i permessi di root.
 
In sostanza, la password verrà sì inserita, ma 1 volta soltanto:
 
Shell "gksu <FONT color=#B22222>chmod 4777</font> ''file_ad_accesso_protetto''"
 
 
 
Se il comando che dobbiamo lanciare prevede delle opzioni indicate con il segno – (come ad esempio: ''wmctrl -l -p'') il comando da eseguire dovrà inserito tra degli apici semplici es:
 
gksu 'wmctrl -l -p'
 
 
 
 
 
Vediamo di seguito un paio di esempi con l'intento di ottenere libero accedesso ai file-device.
 
 
 
  
====Uso di ''Process''====
+
===Lanciando "sudo" da un Terminale appositamente aperto
Private flPro As Process
+
Il comando ''sudo'' potrà essere utilizzato all'interno di un terminale, per sbloccare così sino alla chiusura della sessione un file protetto:
 
 
'''Public''' Sub Form_Open()
 
 
<FONT color=#006400>' ''Riconosce se il programma è stato già lanciato nell'attuale sessione di sistema operativo.''
 
' ''<Span style="text-decoration:underline">Se non</span> è stato lanciato almeno una volta, fa inserire la password di root per impostare il setUID e consentire l'apertura del file protetto:''</font>
 
  If Stat("''/percorso/del/file-device/protetto''").Auth <> "rwsrwxrwx" Then
 
    Exec ["gksu", "chmod 4777", "''/percorso/del/file-device/protetto''"] Wait
 
  Endif
 
 
<FONT color=#006400>' ''Va a gestire il file-device:''</font>
 
  flPro = Exec ["cat", "''/percorso/del/file-device''"] For Read As "flPro"
 
 
'''End'''
 
 
 
'''Public''' Sub flPro_Read()
 
 
 
  Dim b As Byte
 
 
<FONT color=#006400>' ''legge i dati provenienti dal file-device del mouse...''</font>
 
  Read #flPro, b
 
 
<FONT color=#006400>' ''...e li mostra in console:''</font>
 
  Print b
 
 
 
'''End'''
 
 
 
 
 
====Uso di ''Open.... For Read Watch''====
 
Private fl As File
 
 
 
'''Public''' Sub Form_Open()
 
 
<FONT color=#006400>' ''Riconosce se il programma è stato già lanciato nell'attuale sessione di sistema operativo.''
 
' ''<Span style="text-decoration:underline">Se non</span> è stato lanciato almeno una volta, fa inserire la password di root per impostare il setUID e consentire l'apertura del file protetto:''</font>
 
  If Stat("''/percorso/del/file-device/protetto''").Auth <> "rwsrwxrwx" Then
 
    Exec ["gksu", "chmod 4777", "''/percorso/del/file-device/protetto''"] Wait
 
  Endif
 
 
<FONT color=#006400>' ''va a gestire il file-device:''</font>
 
  fl = Open "''/percorso/del/file-device''" For Read Watch
 
 
'''End'''
 
 
 
'''Public''' Sub File_Read()
 
 
 
  Dim b As Byte
 
 
<FONT color=#006400>' ''legge i dati provenienti dal file-device della porta...''</font>
 
  Read #fl, b
 
 
<FONT color=#006400>' ''...e li mostra in console:''</font>
 
  Print b
 
 
'''End'''
 
 
 
 
 
==Uso di ''sudo''==
 
Si potrà utilizzare anche il comando ''sudo'', da far lanciare però all'interno di un terminale, per sbloccare sino alla chiusura della sessione un file protetto:
 
 
  Shell "xterm -e sudo chmod 4777 ''file_protetto_da_sbloccare''"
 
  Shell "xterm -e sudo chmod 4777 ''file_protetto_da_sbloccare''"
 
oppure se si vuole lanciare un comando che necessita dell'inserimento della parola-chiave:
 
oppure se si vuole lanciare un comando che necessita dell'inserimento della parola-chiave:
 
  Shell "xterm -e sudo ''comando_da_lanciare''"
 
  Shell "xterm -e sudo ''comando_da_lanciare''"
 
Si aprirà la finestra del terminale, nella quale inserire la propria parola-chiave. Anche in questo i dati saranno mostrati all'interno della finestra del terminale.
 
Si aprirà la finestra del terminale, nella quale inserire la propria parola-chiave. Anche in questo i dati saranno mostrati all'interno della finestra del terminale.
 
  
 
===Senza far aprire la finestra del Terminale per l'inserimento della password===
 
===Senza far aprire la finestra del Terminale per l'inserimento della password===
Se non si vuole far aprire la finestra del terminale per l'inserimento della password, allora si potrà utilizzare la seguente modalità.
+
Se non si vuole far aprire la finestra del terminale per l'inserimento della password, allora si potrà utilizzare la seguente modalità che prevede anche l'uso del comando "echo":
 
 
Per sbloccare un file protetto:
 
 
  Shell "echo <FONT Color=gray>''password''</font> | sudo -S chmod 4777 <FONT Color=gray>''file_protetto_da_sbloccare''</font>"
 
  Shell "echo <FONT Color=gray>''password''</font> | sudo -S chmod 4777 <FONT Color=gray>''file_protetto_da_sbloccare''</font>"
 
Esempio:
 
Esempio:
Riga 301: Riga 212:
 
  '''End'''
 
  '''End'''
  
 
+
===Se è necessario usare la propria password di sistema===
 
+
Per lanciare, invece, un comando che necessita dell'inserimento della proprie parola-chiave di sistema, si inserirà la propria password di sistema dopo il comando "echo":
Per lanciare, invece, un comando che necessita dell'inserimento della parola-chiave:
+
  Shell "echo ''mia-password'' | sudo -S ''comando_da_lanciare''"
  Shell "echo ''password'' | sudo -S ''comando_da_lanciare''"
 
  
  
Riga 317: Riga 227:
 
    
 
    
 
  '''End'''
 
  '''End'''
 
  
  

Versione delle 05:38, 9 ago 2021

A volte può capitare che per poter utilizzare alcuni comandi o per eliminare la protezione ad alcuni file, sia necessario inserire la propria parola-chiave di root.

A seconda delle circostanze vi sono alcune modilità.


Utilizzo della funzione Gambas: Desktop.RunAsRoot

Innanzitutto possiamo lanciare un comando bash attraverso la funzione propria di Gambas: Desktop.RunAsRoot. Essa presuppone innanzitutto che sia stato impostato il componente gb.desktop, e che sia presente nel sistema il programma xterm.
Nelle parentesi va scritta fra virgolette l'intera linea di comando da lanciare, e non il solo comando:

Public Sub Button1_Click()

 Desktop.RunAsRoot("Intera_linea_di_comando")

End

Esempio:

Desktop.RunAsRoot("cat /dev/input/mouse0")


Se il codice prevede l'intercettazione di dati, questi potrebbero essere raccolti servendosi, laddove possibile, di una variabile d'appoggio.
Prendendo in considerazione l'esempio precedente:

Private fl As File
Private sFile As String


Public Sub Form_Open()

' Temp$() rappresenta il file temporaneo d'appoggio:
 sFile = Temp$()

 Desktop.RunAsRoot("cat /dev/input/mouse0 > " & sFile)

' Restiamo in attesa sino a quando il file non sarà creato:
 Repeat
   Wait 0.01
 Until Exist(sFile)

 fl = Open sFile For Read Watch

End


Public Sub File_Read()

 Dim s As String

 s = File.Load(sFile)

 TextEdit1.Text = s

End


Attendere sino a quando non è stata immessa la password

Nel precedente esempio abbiamo visto una modalità per far attendere al programma l'immissione della password necessaria per l'esecuzione del comando inserito nella funzione Desktop.RunAsRoot. In quel caso il codice attendeva la creazione di un file:

' Restiamo in attesa sino a quando il file non sarà creato:
 Repeat
   Wait 0.1
 Until Exist(sFile)

Ora vediamo una possibile soluzione nel caso in cui, invece, si debba attendere la chiusura della finestra di xterm, nella quale viene immessa la password, ossia la chiusura del processo di quel programma:

Public Sub Form_Open()  
 
 Dim s As String  
 
' Intendo avviare il comando come "root":
 Desktop.RunAsRoot("linea_di_comando")  
  
' Per ciascun processo in questo momento attivo... 
 For Each s In Dir("/proc", "", gb.Directory)  
    
' ...vado a vedere il file "comm":
   If Exist("/proc" &/ s &/ "comm") Then  
   
' Se in quel file c'è una stringa simile a "xterm",...
     If File.Load("/proc" &/ s &/ "comm") Like "*xterm*" Then  
     
' ...allora avvio il ciclo,
       Repeat  
         Wait 0.01  
' ...che gira in attesa fino a quando il processo di "xterm" non è stato terminato:
       Until Exist("/proc" &/ s) = False  
     Endif  
 
   Endif  
 Next  
  
' Allora sono sicuro che ho passato *innanzitutto* la password, e il comando bash dovrebbe così poter partire tranquillamente.

End


Dare una volta sola la password di root per aprire un file protetto

Per dare una volta sola la password di root per aprire un file protetto si utilizza il comando chmod |1| e il codice 4777 |2| (corrispondente a: rwsrwxrwx) per impostare il setUID. Tale comando consentirà con effetto temporaneo, ossia limitato alla sola attuale sessione di sistema, di modificare i permessi del file, in modo tale ad esempio che tutti possano eseguire tranquillamente un programma o accedere ad un file che di norma richiede i permessi di root.
In sostanza, la password verrà sì inserita, ma 1 volta soltanto.

Esempio:

Private pr as Process


Public Sub Form_Open()

' Se il file non possiede i più ampi permessi...
 If Stat("/dev/input/mouse0").Auth <> "rwsrwxrwx" Then
' ...allora modificheremo in quel senso i permessi del file:
   Desktop.RunAsRoot("chmod 4777 /dev/input/mouse0")
 ' Restiamo in attesa fino a che i permessi non vengono modificati, come desiderato:
   Repeat
     Wait 0.01
   Until Stat("/dev/input/mouse0").Auth = "rwsrwxrwx"
 Endif

' Modificati i permessi, passiamo, dunque, avanti per gestire il file:
  pr = Shell "cat /dev/input/mouse0" For Read As "pro"

End


Public Sub pro_Read()
 
 Dim b As Byte
 
 Read #pr, b
 
 Print b
 
End


Uso diretto di comandi bash lanciati mediante Shell

Far aprire un terminale per inserire la propria password con su

La seguente riga di comando farà aprire una finestra di Terminale, nella quale si potrà inserire la propria parola-chiave:

Public Sub Button1_Click()

 Shell "xterm -e su -c \"comando_da_lanciare > percorso_file_d'appoggio\" \"$user\""
 
' oppure anche con "x-terminal-emulator":
 Shell "/usr/bin/x-terminal-emulator -e su -c \"comando_da_lanciare\" \"$user\"" 

End

Il risultato del comando però si svolgerà tutto all'interno della finestra del terminale. Altrimenti potremo deviare il flusso di dati verso un qualsiasi file d'appoggio:

Shell "xterm -e su -c \"comando_da_lanciare > percorso_file_d'appoggio\" \"$user\""

e raccogliere successivamente i dati salvati nel file d'appoggio:

Private c As File


Public Sub Form_Open()

 c = Open "/tmp/c" For Read Watch
 
 Shell "xterm -e su -c \"comando_da_lanciare > percorso_file_d'appoggio\" \"$user\""
 
' oppure anche con "x-terminal-emulator":
 Shell "/usr/bin/x-terminal-emulator -e su -c \"comando_da_lanciare > percorso_file_d'appoggio\" \"$user\"" 
 
End


Public Sub File_Read()

 Dim s As String
 
 s = File.Load("percorso_file_d'appoggio")
 
 Print s
 
End


Dare una volta sola la password di root per aprire un file protetto

Per far immettere la propria password di root, con Shell si utilizza il comando "sudo", ad esempio per ottenere libero accesso ai file-device.

===Lanciando "sudo" da un Terminale appositamente aperto Il comando sudo potrà essere utilizzato all'interno di un terminale, per sbloccare così sino alla chiusura della sessione un file protetto:

Shell "xterm -e sudo chmod 4777 file_protetto_da_sbloccare"

oppure se si vuole lanciare un comando che necessita dell'inserimento della parola-chiave:

Shell "xterm -e sudo comando_da_lanciare"

Si aprirà la finestra del terminale, nella quale inserire la propria parola-chiave. Anche in questo i dati saranno mostrati all'interno della finestra del terminale.

Senza far aprire la finestra del Terminale per l'inserimento della password

Se non si vuole far aprire la finestra del terminale per l'inserimento della password, allora si potrà utilizzare la seguente modalità che prevede anche l'uso del comando "echo":

Shell "echo password | sudo -S chmod 4777 file_protetto_da_sbloccare"

Esempio:

Public Sub Main()

 Dim fl As File
 
 Shell "echo mia_password | sudo -S chmod 4777 '/dev/tty0'"
 
 Repeat
   Wait 0.01
 Loop Until Stat("/dev/tty0").Auth = "rwsrwxrwx"

 fl = Open "/dev/tty0" For Write
 If IsNull(fl) Then Error.Raise("Impossibile aprire il dispositivo '/dev/tty0' !")

  ......

End

o anche più semplicemente ponendo Wait a destra dell'istruzione con Shell:

Public Sub Main()

 Dim fl As File
 
 Shell "echo mia_password | sudo -S chmod 4777 '/dev/tty0'" Wait
 
 fl = Open "/dev/tty0" For Write
 If IsNull(fl) Then Error.Raise("Impossibile aprire il dispositivo '/dev/tty0' !")

  ......

End

Se è necessario usare la propria password di sistema

Per lanciare, invece, un comando che necessita dell'inserimento della proprie parola-chiave di sistema, si inserirà la propria password di sistema dopo il comando "echo":

Shell "echo mia-password | sudo -S comando_da_lanciare"


Vediamo un semplice esempio pratico, nel quale si porrà il comando Input seguito da una semplice variabile di tipo Stringa, che dovrà contenere la pasword immessa nello spazio sottostante la console del progetto, oppure nel Terminale. La funzione Input bloccherà lo scorrimento del programma sino a quando non sarà stata immessa ed inviata la nostra password per sbloccare un file-device, assegnando così i permessi di lettura e scrittura ai tre gruppi:

Public Sub Main()
 
 Dim s As String
 
 Input s
   
 Shell "echo " & s & " | sudo -S chmod 666 /dev/tty2" Wait
  
End


Lanciare i comandi bash senza uso di Shell

E' possibile lanciare i comandi bash senza l'uso della funzione Shell di Gambas, ma utilizzando la funzione esterna system( ), dichiarata nel file header di sistema /usr/include/stdlib.h, oppure alcune funzioni esterne dal API di libgksu2 .


Uso della funzione esterna system( )

La funzione esterna system( ) è dichiarata nel file header di sistema /usr/include/stdlib.h e passa il nome del comando o del programma specificato per eseguito.

Di seguito mostriamo un esempio con sudo:

Library "libc:6"

' int system (const char *__command)
' Execute the given line as a shell command.
Private Extern system_C(__command As String) As Integer Exec "system"


Public Sub Main()
 
 Dim i As Integer
  
 i = system_C("echo 'MIA_PASSWORD' | sudo -S chmod 666 /dev/tty0")
 If i < 0 Then Error.Raise("Impossibile lanciare il comando !")
  
End


Uso delle risorse del API di libgksu2

La libreria libgksu2 fornisce le funzionalità di "su" e di "sudo" all'utente. [ Nota 3 ]

Le risorse ; pertanto sarà necessario richiamare le seguenti librerie dinamiche condivise:

  • "libgtk-x11-2.0.so.0.2400.23"
  • "libgksu2.so.0.0.2"


Possiamo utilizzare due codici che mostriamo di seguito.

1a modalità

Questa modalità richiederà di inserire la propria password ll'interno della console/Terminale:

Library "libgtk-x11-2.0:0.2400.23"

' void gtk_init (int *argc, char ***argv)
' Initialize everything needed to operate the toolkit.
Private Extern gtk_init(argc As Pointer, argv As Pointer)

Library "libgksu2:0.0.2"

Public Struct GksuContext
  xauth As Pointer
  dirp As Pointer
  display As Pointer
  sudo_mode As Boolean
  gconf_client As Pointer
  userp As Pointer
  command As Pointer
  login_shell As Boolean
  keep_env As Boolean
  description As Pointer
  message As Pointer
  alert As Pointer
  grab As Boolean
  always_ask_password As Boolean
  sn_context As Pointer
  sn_id As Pointer
  ref_count As Integer
  debugb As Boolean
End Struct

' GksuContext* gksu_context_new (void)
Private Extern gksu_context_new() As Pointer

' gboolean gksu_sudo_full (GksuContext *context, GksuAskPassFunc ask_pass, gpointer ask_pass_data, GksuPassNotNeededFunc pass_not_needed, gpointer pass_not_needed_data, GError **error)
Private Extern gksu_su_full(context As GksuContext, ask_pass As Pointer, ask_pass_data As Pointer, pass_not_needed As Pointer, pass_not_needed_data As Pointer, GError As Pointer) As Boolean


Library "libc:6"

' char *getpass (const char *__prompt)
' Prompt with PROMPT and read a string from the terminal without echoing.
Private Extern getpass(__prompt As String) As String


Public Sub Main()
 
 Dim cntxt As GksuContext
  
 gtk_init(0, 0)
  
 cntxt = gksu_context_new()
   
 With cntxt
   .debugb = False
   .command = Alloc("chmod 666 /dev/tty9")
 End With
   
 gksu_su_full(cntxt, su_ask_pass, 0, 0, 0, 0)
    
 Free(Object.Address(cntxt))
  
End


Private Function su_ask_pass(ct As Pointer, prompt As String, data As Pointer, GError As Pointer) As String
 
 Return getpass("Inserire la propria password: ")
 
End


2a modalità

Quest'altra modalità determinerà l'apertura di un'apposita finestra, nella quale si dovrà inserire la propria password:

Library "libgtk-x11-2.0:0.2400.23"

' void gtk_init (int *argc, char ***argv)
' Initialize everything needed to operate the toolkit.
Private Extern gtk_init(argc As Pointer, argv As Pointer)


Library "libgksu2:0.0.2"

' gboolean gksu_sudo (gchar *command_line, GError **error)
Private Extern gksu_su(command_line As String, GError As Pointer) As Boolean


Public Sub Main()
 
 Dim bo As Boolean
 
 gtk_init(0, 0)
  
 bo = gksu_su("chmod 666 /dev/tty1", 0)
 If bo = False Then Error.Raise("Errore alla funzione 'gksu_sudo()' !")
  
End


Note

[1] Va sottolineato che il comando chmod andrà scritto tutto in minuscolo !

[2] Come impostare il valore per cambiare i permessi dei file con chmod: chmod può prendere argomenti del tipo alfabetico, ad esempio, g + wr, u + x, a-w, laddove:

a = all (ossia per tutte e tre le classi: proprietario del file, gruppo, altri);
o = "others" (altri);
g = "group" (gruppo)
u = "user" (proprietario)

r = lettura
w = scrittura
x = esecuzione

È possibile utilizzare l'operatore - per rimuovere un privilegio, per esempio, a-w rimuove il permesso di scrittura per tutti;
È possibile utilizzare l'operatore + per aggiungere un privilegio, ad esempio, g+w aggiunge permessi di scrittura per il gruppo;
È possibile utilizzare l'operatore = per impostare il privilegio in modo identico per , ad esempio, a=rw imposterà il permesso di [rw-rw-rw-]


chmod può anche assumere argomenti numerici di "modalità" (mode), che così rappresentiamo: nnn
laddove:
- il primo numero è la modalità per il proprietario del file;
- il secondo numero è la modalità per il gruppo;
- il terzo numero è la modalità per ogni altro utente.

Per specificare i permessi attribuiti a ciascuna delle predette tre modalità, viene assegnato dato dalla eventuale somma dei seguenti numeri:

4 = lettura
2 = scrittura
1 = esecuzione


Così, ad esempio 765 significa:
alla classe "proprietario" sono modificati i permessi attribuendo: 4 (lettura) + 2 (scrittura) + 1 (esecuzione) = 7 (sono, dunque, modificati tutti e tre i permessi)
alla classe "gruppo" sono sono modificati i permessi attribuendo: 4 (lettura) + 2 (scrittura) + 0 (esecuzione) = 6 (assegnando 0 al permesso per l'esecuzione, esso viene negato)
alla classe "altri" sono sono modificati i permessi attribuendo: 4 (lettura) + 0 (scrittura) + 1 (esecuzione) = 5 (assegnando 0 al permesso per la scrittura, esso viene negato)

Assegnando ad una classe utente del file il valore 0 (zero) per i tre permessi, viene negata alla classe ovviamente ogni tipo di permesso.
Esempi:
000 nega ogni permesso a tutte e tre le classi di utenti;
604 nega ogni permesso alla sola classe "gruppo";
700 nega ogni permesso alle classi "gruppo" ed "altri".


[3] Per vedere le risorse della libreria libgksu2: https://people.debian.org/~kov/gksu/reference/index.html