Foros Python

Versión completa: Validación de contraseña para acceso a unidad de red
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Hola a todos,

Soy Rafa y estoy empezado poco a poco con esto de Python. Estoy intentando hacer mi primer script para controlar una unidad de red en entorno Windows y quiero ponerle algo de seguridad.
Lo que pretendo es que al ejecutar el script se mapee una unidad de red y que se elimine cuando el script termine.

Al principio usé este código:

Código:
os.system("net use \\\\miservidor\c$ /user:Usuario1 12345678" ) 

Pero no quiero que la contraseña se vea. Aunque el script sólo lo voy a usar yo, no me gusta dejar contraseñas a la vista. 
Así que de momento, lo que estoy probando es a solicitar la contraseña de acceso y que sea Windows quien controle si la contraseña es correcta o no.
Al final acabaré codificando la contraseña para poder automatizar el script pero aún no tengo claro como codificarla.

Había pensado en usar try - except para recoger el error de contraseña incorrecta. Por desgracia, en ningún caso llego a acceder al except:
No se ejecuta el exit() y el script falla porque no puede listar los archivos del directorio.

Si la contraseña es correcta, el script hace su trabajo.

Este es el código. ¿Me podéis decir como debo configurar el except?

Código:
import os
import ctypes
from getpass import getpass

try:

    password = getpass("Escribe la contraseña de acceso: ")
    os.system("net use \\\\miservidor\c$ /user:Usuario1 " + password ) 

except:

    ctypes.windll.user32.MessageBoxW(0, "Contraseña incorrecta", "Error!!", 0x00010000)
    exit()

servidor = os.listdir ('//miservidor/c$')

Este es el error que recoge la consola: 

Cita:Traceback (most recent call last):
  File "C:\Scripts\prueba.py", line 35, in <module>
    servidor= os.listdir ('//miservidor/c$')
OSError: [WinError 1326] El nombre de usuario o la contraseña no son correctos: '//miservidor/c$'


Muchas gracias de antemano
Hola, Rafa, bienvenido.

El error aparentemente lo está tirando la función listdir(), así que debería ser:

Código:
try:
    servidor = os.listdir ('//miservidor/c$')
except OSError:
    ctypes.windll.user32.MessageBoxW(0, "Contraseña incorrecta", "Error!!", 0x00010000)
    exit()

No es conveniente usar "except:" a secas, porque en ese caso Python captura cualquier excepción, dando como resultado que eventualmente nuestro programa tome un error por otro. Por ejemplo, listdir() podría tirar otras excepciones distintas de OSError que no queremos capturar.

En cuanto a la contraseña, por lo general eso se soluciona usando una variable de entorno para guardar el dato sensible, que luego podés obtener desde Python vía os.getenv().

Por último, en Python conviene usar el módulo subprocess en lugar de la vieja os.system() para ejecutar comandos u otros programas. Te dejo un pequeño tutorial: subprocess – Creación y comunicación con procesos.

Saludos
Hola Francisco, 

Muchas gracias por tu solución. Es cierto que el fallo saltaba al hacer la llamada al listdir. Aplicando tu código el error se soluciona.
El problema es que, como bien dices, tanto si es un problema de contraseña o de comunicación con el servidor o cualquier otra cosa siempre salta el mismo mensaje.

A falta de revisar lo que me propones del módulo subprocess, he modificado así el código:

Código:
try:
    password = getpass("Escribe la contraseña de acceso: ")
   os.system("net use \\\\miservidor\c$ /user:Usuario1 " + password )
   directorio = os.listdir ('//miservidor/c$')
except WindowsError as e:
     if e.winerror == 1326:
          ctypes.windll.user32.MessageBoxW(0, "Contraseña incorrecta", "Error!!", 0x00010000)
          exit()
except OSError:
     ctypes.windll.user32.MessageBoxW(0, "No se conecta con la unidad de red", "Error!!", 0x00010000)
     exit()

De esta forma parece que puedo identificar si es un problema de contraseña u otra cosa.

Cita:En cuanto a la contraseña, por lo general eso se soluciona usando una variable de entorno para guardar el dato sensible, que luego podés obtener desde Python vía os.getenv().

La idea que tengo es codificarla en un documento externo y descodificarla al traerla al script. Hice algo similar con Powershell. Ahora falta aplicarlo a Python.

De nuevo, muchas gracias.
¡Excelente! Smile