Python How to create a password protected zip file - python

This is my current code:
rc = subprocess.Popen(['C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\7-Zip', 'a', 'test', '-y', 'myarchive.zip'] +
['./device teams.txt'])
It is giving me an error of Access is Denied. This is the same for any file I point to.
Because of my companies security, I'm not able to install pyminizip and need a way for this line of code, or another equal to, to work.
Anyone know why it is denying me access?

Related

prompt user to login to protected directory in python

I have a script that searches through a protected directory and opens file explorer to a selected location. The problem is that it only works after the user has already logged into the directory.
Example of what sort of thing the code is doing below:
subfolder = input("give a subfolder")
if os.path.isdir("\\\\directory\\path\\"):
#run some stuff
os.startfile("\\\\directory\\path\\" + subfolder)
else:
print('error message- unable to connect to drive. Please log in')
If the user has opened "\\directory\path" on their own and entered their username/password into the windows security prompt, then my code works. If they haven't, I can't find the directory path.
Is there a way to open to the windows security prompt from Python? Ideally user puts in username and password and then can continue to the directory.
If you install win32, you can connect to network resources with a prompted username and password. It's not a simple solution (like an os call), but you can use the wnet_connect method from this example to pass a username/password in your except call.
It boils down to:
win32wnet.WNetAddConnection2(0, None, full_path, None, username, password)

How can I add Windows Credentials using Python?

I am trying to create a program that automatically installs a network shortcut onto my desktop and downloads a driver (it is a print server for my work), but in order to access the shortcut after it is installed I need to enter my work credentials under the printer network's domain. I tried using the keyring library for Python but that was unsuccessful, I also tried to use win32wnet.WNETADDCONNECTION2() which I have seen posted on several forums but it was also unsuccessful for me.
Here is the code currently
import os, winshell, keyring, win32wnet
from win32com.client import Dispatch
#Add Windows Credentials
#**************************
url = r'\\LINKTOTHENETWORK'
win32wnet.WNetAddConnection2(0, None, url, None, USERNAME, PASSWORD)
keyring.set_password(url, USERNAME, PASSWORD)
keyring.get_password(url, USERNAME)
#**************************
# This is where I am having troubles.
# Create the shortcut
desktop = winshell.desktop()
path = os.path.join(desktop, "MYLINK.lnk")
target = url
# Set path and save
shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(path)
shortcut.Targetpath = target
shortcut.save()
# Open the shortcut
os.startfile(target)
In my full program I have an interface using Kivy that asks for my Username and Password and then I hit an "Install" button and it adds the domain to my Username (domain\username). Using keyring it was properly showing up, just in the wrong area so that should no be an issue, I just can't find a method to add a Windows Credentials instead of General Credentials.
I am using python2.7 on a Windows 10 computer.
If anyone knows of a library I could use or another method that would be great. Thanks!
I'm pretty sure you can achieve this by creating a .bat file and executing it in your program.
For Ex.
def bat_create_with_creds(id, pwd):
"""create Batch file to init printer domain creds with variables"""
auth_print= open("auth_print.bat", "w")
auth_print.write("NET USE \\printserverip /USER:%"+id+"% %"+pwd+"%")
auth_print.close()
I haven't done this for your particular use case, but it works perfectly well for init. rdp sessions using windows mstsc for example.

Umbraco 7.2.8 - how do remove existing user/node permissions from code

I am trying to manage user permissions
I know that if I want to grant a particular user Publish and Browse (PermissionIds U,F) I would do this:
contentService.AssignContentPermission(node, 'U', userId);
contentService.AssignContentPermission(node, 'F', userId);
but if the user already had those permissions and I want to remove Publish and grant 'Send to Publish' (H) how do I remove the existing Publish permission for that user/node combo?
I tried:
contentService.AssignContentPermission(node, '-', userId);
but this didn't seem to work.
looks like it's best to assign the permissions using the ApplicationContext.Current.Services.UserService
get all applicatble nodes (a single one in my case) and permissions and call
userService.ReplaceUserPermissions(user.Id, permissions, nodes);

What is the Windows equivalent of pwd.getpwnam(username).pw_dir?

The Python pwd module provides access to getpwnam(3) POSIX API, which can be used to get the home directory for a particular user by username, as well determining if the username is valid at all. pwd.getpwnam will raise an exception if called with a non-existent username.
At first it seems like the same result can be achieved in a cross-platform manner via os.path.expanduser('~username'). However, it appears that with Python 2.6 on Windows XP this won't actually produce a failure for a non-existent username. Furthermore, on Python 2.5 on Windows XP, it seems to fail even for valid users.
Can this information be obtained reliably on Windows? How?
Reading the 2.6 documentation shows that os.path.expanduser() is broken on Windows:
On Windows, HOME and USERPROFILE will
be used if set, otherwise a
combination of HOMEPATH and HOMEDRIVE
will be used. An initial ~user is
handled by stripping the last
directory component from the created
user path derived above.
Say whaat? This assumes all user homes have to be under the same parent directory. Nuh-ugh!
It was a bit hard to dig but here is a solution that will look up a local user by given name:
from win32security import LookupAccountName, ConvertSidToStringSid
from _winreg import OpenKey, QueryValueEx, HKEY_LOCAL_MACHINE
def getUserDir(userName):
ssid = ConvertSidToStringSid(LookupAccountName(None, userName)[0])
key = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\\' + ssid)
return QueryValueEx(key, 'ProfileImagePath')[0]
I am new to Windows security... but reading MSDN and some blogs it seems to me that the way MS want us to handle other users specific data is by getting a user token.
There used to be a nice wiki of Keith Brown .Net Developers Guide to Windows Security... you can still find it in Google cache for "pluralsight keith.guidebook"
Case 1: If you don't have the user password:
For local accounts you can try reading the Windows registry as Nas Banov already suggested and there are some other recipes on SO or the Internet.
I am not sure how various Windows versions behaves for freshly create users ... those which have never performed an interactive session login ... does it automatically creates their registry, home folder and profile data?
I have done some tests on Windows XP and those registry keys were not present after creating an local account ... but in this case you can try to guess it based in All Users registry values ... or just fail :)
For desktop applications, when the application is running as a logged in user, I am using something like this to get the home folder.... and to get the equivalent of ~/.local I am using CSIDL_APPDATA, for roaming profiles, or just CSIDL_LOCAL_APPDATA.
from win32com.shell import shell, shellcon
# See microsoft references for further CSIDL constants
# http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, 0, 0)
Reading Keith Brown article "How To Get A Token For A User" .. you can look for some other ways of getting an user token without a password...
Case 2: If you have the user password:
Reading the MSDN I got the impressing that if I have an user token, I can get its folders by calling something like the code below... but it did not worked for me. (not sure why)
token = win32security.LogonUser(
username,
None, # we uses UPN format for username
password,
win32security.LOGON32_LOGON_NETWORK,
win32security.LOGON32_PROVIDER_DEFAULT,
)
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, token, 0)
This is why I ended up with this code...which is far from being perfect due to the fact that it requires username and password.
token = win32security.LogonUser(
username,
None, # Here should be the domain ... or just go with default values
password,
win32security.LOGON32_LOGON_NETWORK,
win32security.LOGON32_PROVIDER_DEFAULT,
)
win32security.ImpersonateLoggedOnUser(token)
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, 0, 0)
win32security.RevertToSelf()
This question is somehow related: How to find the real user home directory using python?
you could go the win32api.GetUserName() (current user only) or win32net.NetUserGetInfo() (any user on any server, localhost included) route. the latter could be a bit slow since it can take some time to get this information back from the OS.
import win32net
def userDir(username):
return win32net.NetUserGetInfo(None, username, 1).get("home_dir")
alternatively you could expand the environment variable USERPROFILE on windows or HOME on unix to get the information about the currently logged in user:
def userDir():
if os.platform.system() == 'Windows':
return os.environ['USERPROFILE']
elif os.platform.system() == 'Linux':
return os.environ['HOME']
else:
return None
This seems to be only applicable to the current user, but on my (winxp) machine, os.path.expanduser('~') returns my home directory.

Email and Password Authentication Without Showing the Password

I find myself needing to log into google to use the remote api, however it requires an email and password to authenticate the process. Is there anyway I could hide both of them and require other contributors to the project to add their own (securely)?
from google.appengine.ext.remote_api import remote_api_stub
import database
import getpass
email = "gmail#gmail.com" #can't show this line
password = "password" #can't show this line
def auth_func():
return (email, password)
remote_api_stub.ConfigureRemoteApi(None, '/_ah/remote_api', auth_func,
'app.appspot.com')
You can keep the sensitive information in environment variables, and include instructions to set the environment variables in your application documentation prior to running the application.
To retrieve the variables from within Python (from here):
import os
email = os.environ.get("GOOGLE_EMAIL")
password = os.environ.get("GOOGLE_PASSWORD")
if email and password:
# ... process...
If you're using virtualenv (which you should!) you may also want to use a tool like autoenv (or others mentioned on this question) which can set the relevant environment variables for your single command line/console session when you cd into the project directory.
You may also put the commands in a shell script/batch file and just make sure not to commit it.
I would put it in a different file (config.xml for example) and not committing it. You could them verify if it exists before building your app.

Resources