This script will detect when someone enters the wrong unlock code or swipes the wrong pattern and sends a picture to an E-Mail address in the background, silently.
For some reason it works better with long patterns and even better with long pin codes. I don't know why. If you know it, let me know :)
Let's start, please get:
- Tasker
- Secure Settings (To setup a profile in Tasker which detects wrong unlock codes)
- Python for Android (To run python code)
- SL4A (To run the python script from Tasker)
- The python script "SendEmailA.py" from the Tasker Wiki. (Send an E-Mails silently)
- GoogleMail address
Open the Python for Android application, make sure it is not Python3. Press install button to install the Python runtime environment.
Open SL4A and run the "hello_world.py" script by tapping on it and selecting the leftmost terminal icon. Congratulations, you successfully installed Python and can run Python scripts from Tasker!
Here is my "SendEmailA.py" script. It has a small modification to the original file which is marked in red.
import os
import glob
import mimetypes
from email import encoders
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def attach_files(msg, attachements):
for attachment in attachments:
attachment = attachment.strip()
for path in glob.glob(attachment):
filename = os.path.basename(path)
if not os.path.isfile(path):
continue
# Guess the content type based on the file's extension. Encoding
# will be ignored, although we should check for simple things like
# gzip'd or compressed files.
ctype, encoding = mimetypes.guess_type(path)
if ctype is None or encoding is not None:
# No guess could be made, or the file is encoded (compressed), so
# use a generic bag-of-bits type.
ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
if maintype == 'text':
fp = open(path)
# Note: we should handle calculating the charset
part = MIMEText(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'image':
fp = open(path, 'rb')
part = MIMEImage(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'audio':
fp = open(path, 'rb')
part = MIMEAudio(fp.read(), _subtype=subtype)
fp.close()
else:
fp = open(path, 'rb')
part = MIMEBase(maintype, subtype)
part.set_payload(fp.read())
fp.close()
# Encode the payload using Base64
encoders.encode_base64(part)
# Set the filename parameter
part.add_header('Content-Disposition', 'attachment', filename=filename)
msg.attach(part)
def sendemail(email_name, email_user, email_pswd, mailto, subject, body, attachments):
import smtplib
# DON'T CHANGE THIS!
# ...unless you're rewriting this script for your own SMTP server!
smtp_server = 'smtp.gmail.com'
smtp_port = 587
# Build an SMTP compatible message
msg = MIMEMultipart()
msg['Subject'] = subject
msg['To'] = mailto
msg['From'] = email_name + " <" + email_user + ">"
msg.attach(MIMEText(body, 'plain'))
attach_files(msg, attachments)
# Attempt to connect and send the email
try:
smtpObj = '' # Declare within this block.
# Check for SMTP over SSL by port number and connect accordingly
if( smtp_port == 465):
smtpObj = smtplib.SMTP_SSL(smtp_server,smtp_port)
else:
smtpObj = smtplib.SMTP(smtp_server,smtp_port)
smtpObj.ehlo()
# StartTLS if using the default TLS port number
if(smtp_port == 587):
smtpObj.starttls()
smtpObj.ehlo
# Login, send and close the connection.
smtpObj.login(email_user, email_pswd)
smtpObj.sendmail(email_user, mailto, msg.as_string())
smtpObj.close()
return 1 # Return 1 to denote success!
except Exception, err:
# Print error and return 0 on failure.
print err
return 0
import sys
import android
droid = android.Android()
try:
email_name = droid.getIntent().result[u'extras'][u'%EMAIL_NAME']
except:
email_name = ''
try:
email_user = droid.getIntent().result[u'extras'][u'%EMAIL_USER']
except:
droid.makeToast('EMAIL_USER missing')
sys.exit(1)
try:
email_pswd = droid.getIntent().result[u'extras'][u'%mailp']
except:
droid.makeToast('EMAIL_PSWD missing')
sys.exit(1)
try:
mailto = droid.getIntent().result[u'extras'][u'%EMAIL_TO']
except:
droid.makeToast('EMAIL_TO missing')
sys.exit(1)
try:
subject = droid.getIntent().result[u'extras'][u'%EMAIL_SUBJECT']
except:
subject = ''
try:
body = droid.getIntent().result[u'extras'][u'%EMAIL_BODY']
except:
body = ''
try:
attachments = droid.getIntent().result[u'extras'][u'%EMAIL_ATTACH']
attachments = attachments.split(',')
except:
attachments = ''
# Send email
if (sendemail(email_name, email_user, email_pswd, mailto, subject, body, attachments)):
sys.exit(0)
else:
# Exit with error if email is not sent successfully
droid.makeToast('email failed')
sys.exit(1)
Save this file to your internal SDCard in the SL4A scripts folder (f.e. SDCard\SL4A\Scripts).
The preparation is done, lets go to Tasker. Create a new profile name it "Security Glitch" or something less obvious. Goto State -> Plugin -> Secure Settings. Click on the Edit field near configuration and select the condition "Failed Login Attempts". Type in a low number, like two. Enable "Device Admin". Read and accept the dialog. Click on save in the lower left corner. Hit the back button and create a new Task, name it "Cheeeese" or similar.
Here is my Cheeeese task:
Cheeeeese (45)
Stay Awake
A1: Vibrate [ Time:200 ]
A2: Mobile Data [ Set:On ]
A3: WiFi [ Set:On ]
A4: Variable Add [ Name:%PHOTONUMBER Value:1 Wrap Around:0 ]
A5: Take Photo [ Camera:Front Filename:%PHOTONUMBER Naming Sequence:None Insert In Gallery:Off Discreet:On Resolution:320x240 Scene Mode:Auto White Balance:Auto Flash Mode:Auto ]
A6: Wait [ MS:0 Seconds:3 Minutes:0 Hours:0 Days:0 ]
A7: Load Image [ Source:/sdcard/DCIM/Tasker/%PHOTONUMBER.jpg ]
A8: Rotate Image [ Direction:Right Degrees:90 ]
A9: Save Image [ File:/sdcard/DCIM/Tasker/%PHOTONUMBER.jpg Image Quality:70 Delete From Memory After:On ]
A10: Wait [ MS:0 Seconds:2 Minutes:0 Hours:0 Days:0 ]
A11: Variable Set [ Name:%EMAIL_USER To:mygooglename@gmail.com Do Maths:Off Append:Off ]
A12: Variable Set [ Name:%EMAIL_P To:MyCleartextPassword Do Maths:Off Append:Off ]
A13: Variable Convert [ Name:%EMAIL_P Function:Base64 Encode Store Result In:%EMAIL_P ]
A13: Variable Convert [ Name:%EMAIL_P Function:Base64 Decode Store Result In:%mailp ]
A14: Variable Set [ Name:%EMAIL_TO To:myemailtosendto@domain.com Do Maths:Off Append:Off ]
A15: Variable Set [ Name:%EMAIL_ATTACH To:/sdcard/DCIM/Tasker/%PHOTONUMBER.jpg Do Maths:Off Append:Off ]
A16: Run SL4A Script [ Name:SendEmailA.py Terminal:Off Pass Variables:%EMAIL_USER,%mailp,%EMAIL_TO,%EMAIL_ATTACH Continue Task After Error:On ]
A17: Vibrate [ Time:616 ]
And here you can see the profile as an xml to directly import into Tasker, save it as
SecurityGlitch.prf.xml.
<TaskerData sr="" dvi="1" tv="4.1u3m">
<Profile sr="prof44" ve="2">
<cdate>1353285745747</cdate>
<edate>1376868760042</edate>
<flags>1</flags>
<id>44</id>
<mid0>45</mid0>
<nme>Security Glitch</nme>
<pri>10</pri>
<State sr="con0">
<code>11820</code>
<Bundle sr="arg0">
<Vals sr="val">
<com.intangibleobject.securesettings.plugin.extra.BLURB>Failed Login Attempts - Max: 2</com.intangibleobject.securesettings.plugin.extra.BLURB>
<com.intangibleobject.securesettings.plugin.extra.BLURB-type>java.lang.String</com.intangibleobject.securesettings.plugin.extra.BLURB-type>
<com.intangibleobject.securesettings.plugin.extra.MAX_LOGIN_FAILURES>2</com.intangibleobject.securesettings.plugin.extra.MAX_LOGIN_FAILURES>
<com.intangibleobject.securesettings.plugin.extra.MAX_LOGIN_FAILURES-type>java.lang.Integer</com.intangibleobject.securesettings.plugin.extra.MAX_LOGIN_FAILURES-type>
<com.intangibleobject.securesettings.plugin.extra.SETTING>max_failed_pass_attempts</com.intangibleobject.securesettings.plugin.extra.SETTING>
<com.intangibleobject.securesettings.plugin.extra.SETTING-type>java.lang.String</com.intangibleobject.securesettings.plugin.extra.SETTING-type>
<com.twofortyfouram.locale.intent.extra.BLURB>Failed Login Attempts - Max: 2</com.twofortyfouram.locale.intent.extra.BLURB>
<com.twofortyfouram.locale.intent.extra.BLURB-type>java.lang.String</com.twofortyfouram.locale.intent.extra.BLURB-type>
<net.dinglisch.android.tasker.subbundled>true</net.dinglisch.android.tasker.subbundled>
<net.dinglisch.android.tasker.subbundled-type>java.lang.Boolean</net.dinglisch.android.tasker.subbundled-type>
</Vals>
</Bundle>
<Str sr="arg1" ve="3">com.intangibleobject.securesettings.plugin</Str>
<Str sr="arg2" ve="3">Secure Settings</Str>
</State>
</Profile>
<Task sr="task45">
<cdate>1353285761891</cdate>
<edate>1375520404009</edate>
<id>45</id>
<nme>Cheeeeese</nme>
<pri>10</pri>
<stayawake>true</stayawake>
<Action sr="act0" ve="3">
<code>61</code>
<on>false</on>
<Int sr="arg0" val="200"/>
</Action>
<Action sr="act1" ve="3">
<code>433</code>
<Int sr="arg0" val="1"/>
</Action>
<Action sr="act10" ve="3">
<code>547</code>
<Str sr="arg0" ve="3">%EMAIL_USER</Str>
<Str sr="arg1" ve="3">yourlogin@gmail.com</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act11" ve="3">
<code>596</code>
<Str sr="arg0" ve="3">%EMAIL_P</Str>
<Int sr="arg1" val="25"/>
<Str sr="arg2" ve="3">%email_p</Str>
</Action>
<Action sr="act12" ve="3">
<code>547</code>
<Str sr="arg0" ve="3">%EMAIL_TO</Str>
<Str sr="arg1" ve="3">receivermail@domain.com</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act13" ve="3">
<code>547</code>
<Str sr="arg0" ve="3">%EMAIL_ATTACH</Str>
<Str sr="arg1" ve="3">/sdcard/DCIM/Tasker/%PHOTONUMBER.jpg</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
</Action>
<Action sr="act14" ve="3">
<code>112</code>
<se>false</se>
<Str sr="arg0" ve="3">sendemailA.py</Str>
<Int sr="arg1" val="0"/>
<Str sr="arg2" ve="3">%EMAIL_USER,%email_p,%EMAIL_TO,%EMAIL_ATTACH</Str>
</Action>
<Action sr="act15" ve="3">
<code>61</code>
<on>false</on>
<Int sr="arg0" val="616"/>
</Action>
<Action sr="act2" ve="3">
<code>425</code>
<Int sr="arg0" val="1"/>
</Action>
<Action sr="act3" ve="3">
<code>888</code>
<Str sr="arg0" ve="3">%PHOTONUMBER</Str>
<Int sr="arg1" val="1"/>
<Int sr="arg2" val="0"/>
</Action>
<Action sr="act4" ve="3">
<code>101</code>
<Int sr="arg0" val="1"/>
<Str sr="arg1" ve="3">%PHOTONUMBER</Str>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="1"/>
<Str sr="arg5" ve="3">320x240</Str>
<Int sr="arg6" val="0"/>
<Int sr="arg7" val="0"/>
<Int sr="arg8" val="0"/>
</Action>
<Action sr="act5" ve="3">
<code>30</code>
<Int sr="arg0" val="0"/>
<Int sr="arg1" val="3"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
</Action>
<Action sr="act6" ve="3">
<code>188</code>
<Img sr="arg0" ve="2">
<var>/sdcard/DCIM/Tasker/%PHOTONUMBER.jpg</var>
</Img>
</Action>
<Action sr="act7" ve="3">
<code>191</code>
<Int sr="arg0" val="1"/>
<Int sr="arg1" val="1"/>
</Action>
<Action sr="act8" ve="3">
<code>187</code>
<Str sr="arg0" ve="3">/sdcard/DCIM/Tasker/%PHOTONUMBER.jpg</Str>
<Int sr="arg1" val="70"/>
<Int sr="arg2" val="1"/>
</Action>
<Action sr="act9" ve="3">
<code>30</code>
<Int sr="arg0" val="0"/>
<Int sr="arg1" val="2"/>
<Int sr="arg2" val="0"/>
<Int sr="arg3" val="0"/>
<Int sr="arg4" val="0"/>
</Action>
<Img sr="icn" ve="2">
<nme>yummy_6</nme>
<pkg>net.dinglisch.android.ipack.iconedenthemeshd</pkg>
</Img>
</Task>
</TaskerData>
Please make sure the folder "/sdcard/DCIM/Tasker/" exists and you have the right information filled in in the
purple fields. You can put a file named
.nomedia into the DCIM/Tasker/ folder to make sure, it is not displayed in the gallery.
If you don't know how to setup a specific action, please google it. Line A16 is very important. To create this line goto Script -> RunSL4A Script -> in the name field select the "SendEmailA.py" file. Don't check the Terminal field, but fill in the Pass Variable field with
%EMAIL_USER,%mailp,%EMAIL_TO,%EMAIL_ATTACH. The order is important. Check continue task after error.
You can delete the
bright blue lines after running the Task once successfully. Please note, that your Google Mail password is stored as a global variable in Tasker Base64 encoded - but it is not a safe encryption! If you have suggestions on how to store the password encrypted n Tasker, please tell me!
Run the task a few time to check if your device vibrates twice (short vibrate at the beginning and a long vibrate at the end. Check your myemailtosendto@domain.com mails, don't forget to look into the spam folder. If you received a picture exit Tasker, lock your device, count to ten and check by entering the wrong unlock code/pattern a few time. Maybe you can make the profile run with a higher priority, not necessary. If everything went well and you received the beautiful pictures of yourself delete the
bright blue lines.
Uninformatively there is an android limitation which will show the SL4A icon for a second in the notification bar when the email is send... I tried to make python run without SL4A, but was not successful yet. A workaround could be to make the icon transparent...
I wrote this down pretty fast, please forgive me if something is unclear. I will refresh this post soon.