Encrypt Oracle Database Passwords using Python - python-3.x

So what we've got is some processes that log into databases and we need to have the credentials for that encrypted (at least the password). What we're looking for is the ability to call something that will encrypt and decrypt the password when called so we can use that for the credentials. Something like the below:
Start program
call external decryption program to get credentials
connect to database
do stuff
disconnect
end program
So basically I would like to encrypt the password so that it's not sitting stored as plain text. I have seen a variety of solutions using Wallet's and Python Cyrptography library. Where I am stuck is how to deploy my solution so that only the correct oracle user with permissions is able to decrypt the password file. Is there a way to validate the Oracle user using CX_Oracle?
Below find my current .py file with my connection to CX_Oracle:
import cx_Oracle
def get_ldif_string(row, isFirst):
ldif = ""
if isFirst == False:
ldif += "\r\n"
ldif += "dn: sk-ban=" + \
row[0] + ",ou=XXXXXXXX,ou=XXXXXXXXX,ou=XXXXXX,dc=XXXXXXXXX,dc=com" + "\r\n"
ldif += "objectClass: sk-account\r\n"
ldif += "objectClass: top\r\n"
ldif += "sk-ban: " + row[0] + "\r\n"
if row[1].strip():
ldif += "sk-billingFullName: " + row[1] + "\r\n"
if row[3].strip():
ldif += "sk-billingAddress: " + row[3] + "\r\n"
if row[4].strip():
ldif += "sk-billingCity: " + row[4] + "\r\n"
if row[5].strip():
ldif += "sk-billingProvince: " + row[5] + "\r\n"
if row[6].strip():
ldif += "sk-billingPostalCode: " + row[6] + "\r\n"
if row[7].strip():
ldif += "sk-billingAccountType: " + row[7] + "\r\n"
if row[8].strip():
ldif += "sk-billingServiceNumber: " + row[8] + "\r\n"
if row[9].strip():
ldif += "sk-active: " + row[9] + "\r\n"
if row[10].strip():
ldif += "sk-inactive: " + row[10] + "\r\n"
#print (ldif)
return ldif
def writeToFile(textToWrite, file):
file.write(textToWrite)
dsn_tns = cx_Oracle.makedsn(
'XXXXXXXX', 'XXXX', service_name='XXXXXXXXXXXXXXX')
conn = cx_Oracle.connect(
user=r'XXXXXXX', password=r'XXXXXXX', dsn=dsn_tns)
query = """Select * FROM (
select
COALESCE(ACCT_NO, ' ') as ACCT_NO
, COALESCE(BILLING_FIRST_NAME, '') || ' ' || COALESCE(BRM_LAST_NAME, '')
, COALESCE(BRM_LAST_NAME, ' ')
, COALESCE(BRM_ADDRESS, ' ')
, COALESCE(BRM_CITY, ' ')
, COALESCE(BRM_PROVINCE, ' ')
, COALESCE(BRM_POSTAL_CODE, ' ')
, COALESCE(BRM_ACCOUNT_TYPE, ' ')
, COALESCE(CRB_TN_SN, ' ')
, CASE WHEN BRM_DEAL_STATUS = 'ACTIVE' THEN COALESCE(BRM_DEAL_NAME, ' ') ELSE ' ' END as BRM_ACTIVE
, CASE WHEN BRM_DEAL_STATUS <> 'ACTIVE' THEN COALESCE(BRM_DEAL_NAME, ' ') ELSE ' ' END as
BRM_INACTIVE
from PIN.V_SK_IDM_DATA
ORDER BY ACCT_NO
)
--where ACCT_NO in ('7135942-00002', '7133100', '7206065-00011', '0042006-00003', '0044070-00001')
"""
fileName = "load/loadLDIF.ldif"
open(fileName, 'w').close()
file = open(fileName, "a+")
c = conn.cursor()
c.execute(query)
ban = ""
ldif = ""
isFirst = True
for row in c:
newBan = row[0]
if newBan != ban:
writeToFile(ldif, file)
ldif = get_ldif_string(row, isFirst)
isFirst = False
ban = newBan
else:
if row[9].strip():
ldif += "sk-active: " + row[9] + "\r\n"
else:
ldif += "sk-inactive: " + row[10] + "\r\n"
writeToFile(ldif, file)
conn.close()
file.close()

Related

Any ideas on how to make it so that I dont get Error 429: Too Many Request

Any ideas on how to make it so that I dont get Error 429: Too Many Request
Just a beginner here, I am trying to get ipData from my database which consists of Office365 Audit data..
Am i using the wrong library for such task?
def ipInfo(addr=''):
from urllib.request import urlopen
from json import load
if addr == '':
url = 'https://ipinfo.io/json'
else:
url = 'https://ipinfo.io/' + addr + '/json'
res = urlopen(url)
JSONtext = ''
#response from url(if res==None then check connection)
data = load(res)
#will load the json response into data
for attr in data.keys():
#will print the data line by line
if attr == 'ip':
JSONtext = JSONtext + '{' + '"' + ''.join(attr) + '"' + ':' + '"' + ''.join(data[attr]) + '"'
elif attr == 'readme':
JSONtext = JSONtext + '"'+ ''.join(attr) + '"'+':'+'"' + ''.join(data[attr]) + '"' + '}'
else:
JSONtext = JSONtext + '"'+ ''.join(attr) +'"'+':'+'"'+ ''.join(data[attr]) + '"'
return JSONtext
#get table list
crsr = connection().cursor()
crsr.execute(
"SELECT id,creationdate, userids, operations,auditdata ->> 'ClientIP' AS client_ip,ipdata FROM audits WHERE operations ILIKE '%login%' LIMIT 5;")
tpl = crsr.fetchall()
crsr.close()
#append list to dictionary
dict = {"id":[],"creationdate":[],"userids":[],"operations":[],"clientip":[],"ipdata":[]}
for items in tpl:
#converts item into list
datalist = list(items)
print ('Processing')
for i in datalist:
if i == datalist[0]:
dict["id"].append(i)
elif i == datalist[1]:
dict["creationdate"].append(i)
elif i == datalist[2]:
dict["userids"].append(i)
elif i == datalist[3]:
dict["operations"].append(i)
elif i == datalist[4]:
dict["clientip"].append(i)
ip = i
ip = ''.join(ip)
else:
dict["ipdata"].append(ipInfo(ip))
time.sleep(6)
print('Task Completed')
df = pd.DataFrame.from_dict(dict)

Azure Python Function error --grpcMaxMessageLength 2147483647

I am writing a Azure python function which read emails and write them to a Azure SQL Database. The code runs fine untill it handles a email with a picture in the body. Then the program stop and return the message of :
Starting worker process:py "C:\ProgramData\chocolatey\lib\azure-functions-core-tools-3\tools\workers\python\3.8/WINDOWS/X64/worker.py" --host 127.0.0.1 --port 65101 --workerId 773c7b91-5c39-4d22-8509-2baea30124bb --requestId 0260fedc-f842-4dba-a2e9-6c7630f7228a --grpcMaxMessageLength 2147483647
Than the Azure python function hangs on the type of email and stops working. I try to build Try and Exception with continue to ensures it pickups the next email aswell a check on the length of the email_body. But none of these workarounds is working.
My question is how can i solve / skip this problem so it can also handle / recognize email which has a picture in the email body.
ReadEmail.py
import logging
import email
import imaplib
import pyodbc
from datetime import datetime
from raFunctions import uitvullenDatum
# def readEmail(EMAIL_ADRES,EMAIL_PASSWORD,EMAIL_SERVER,DB_SERVER,DB_DATABASE,DB_USER,DB_PASSWORD):
logging.info('ReadEmail start')
# logging.info('ReadEmail pars:' + EMAIL_ADRES + ' ' + EMAIL_PASSWORD + ' ' + EMAIL_SERVER + ' ' + DB_SERVER + ' ' + DB_DATABASE + ' ' + DB_USER + ' ' + DB_PASSWORD )
#Configurations
EMAIL = 'xxxxxxx'
PASSWORD = 'xxxxxx'
SERVER = 'xxxxxx'
server = 'xxxxxx'
database = 'xxxxx'
username = 'xxxx'
password = 'xxxxx'
driver= '{ODBC Driver 17 for SQL Server}'
# Connection settings to Database and Email Server
mail = imaplib.IMAP4_SSL(SERVER)
mail.login(EMAIL, PASSWORD)
# cnxn = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password +';Authentication=ActiveDirectoryPassword')
cnxn = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password +'; autocommit=True' )
cursor = cnxn.cursor()
cursor_max_mail_date = cnxn.cursor()
max_mail_date = ""
try:
_sql_max_datum = "select format(max(o.ReceivingDate),'dd-MMM-yyyy') from wp_ra.ontvangenmail o "
cursor_max_mail_date.execute(_sql_max_datum)
rows = cursor_max_mail_date.fetchall()
for row in rows:
datum = str(row[0])
max_mail_date = datum
except Exception as e:
print('Max_Mail_Date Error:')
logging.error(str(e))
try:
mail.select('inbox')
# status, data = mail.search(None, 'ALL')
logging.info(max_mail_date)
status, data = mail.search(None, '(SINCE "19-May-2020")')
mail_ids = []
for block in data:
try:
mail_ids += block.split()
except:
print('Error in block in data')
continue
for i in mail_ids:
try:
status, data = mail.fetch(i, '(RFC822)')
for response_part in data:
if isinstance(response_part, tuple):
try:
message = email.message_from_bytes(response_part[1])
mail_from = message['From']
mail_subject = message['Subject']
mail_date = message['Date']
print('mail_date: ' + mail_date + 'mail_subject: ' + mail_subject)
if message.is_multipart():
mail_content = ''
for part in message.get_payload():
if part.get_content_type() == 'text/plain':
mail_content += part.get_payload()
else:
mail_content = part.get_payload()
else:
mail_content = message.get_payload()
maildate = email.utils.parsedate(mail_date)
maildate = uitvullenDatum(str(maildate[0]),str(maildate[1]),str(maildate[2]),str(maildate[3]),str(maildate[4]))
print("Check Mail Content")
if(len(mail_content) >= 1147483647 ):
print("Niet in te lezen email: maildate: " + str(mail_date) + ' mail subject: ' + mail_subject )
else:
values = (maildate, mail_from, mail_subject, mail_content)
sql = "EXEC wp_ra.invoerenmail ?, ?, ?, ?"
cursor.execute(sql, (values))
cursor.commit()
logging.info("Data saved on the database")
except Exception as e:
print('Error reading mail:')
print(str(e))
continue
except:
print('Error i in mail_ids')
continue
except:
print("Fout bij het inlezen van de mail!")
continue
If you stop in some some email, you can try to use continue after output current exception to skip it to deal with other emails:
for i in s :
#Some logic here
try:
#Do something here
except:
print('print something in this place.')
continue

How to print the result of JSON to the output file?

The output of the JSON file has multiple responses like the one seen below
"response_code":1
"scan_date":"2011-07-27 03:44:56"
"permalink":"https://www.virustotal.com/gui/file/1caea01fd9a6c6d12e5ca46007e25a4b1eff640060f45de8213e40aa5b47cd57/detection/f-1caea01fd9a6c6d12e5ca46007e25a4b1eff640060f45de8213e40aa5b47cd57-1311738296"
"verbose_msg":"Scan finished, information embedded"
"total":43
"positives":19
The below code will get the value of "positives" in the JSON output and then print it to the file.
# DOES THE HASH EXISTS IN VT DATABASE?
if response == 0:
print(hash + ": UNKNOWN")
file = open(output,"a")
file.write(hash + " 0")
file.write("\n")
file.close()
# DOES THE HASH EXISTS IN VT DATABASE?
elif response == 1:
positives = int(json_response.get("positives"))
if positives >= 3:
print(hash + ": MALICIOUS")
file = open(output,"a")
file.write(hash + " " + str(positives))
file.write("\n")
file.close()
else:
print(hash + ": NOT MALICIOUS")
file = open(output,"a")
file.write(hash + " 0")
file.write("\n")
file.close()
else: print(hash + ": CAN NOT BE SEARCHED")
So the result of the current code will be something like the below
0136b7453cedf600d6f6aab7900901d3 19
I am trying to get the value of "permalink" in the JSON results and print it in the same output file. So the output must look like the below
0136b7453cedf600d6f6aab7900901d3 19 https://www.virustotal.com/gui/file/1caea01fd9a6c6d12e5ca46007e25a4b1eff640060f45de8213e40aa5b47cd57/detection/f-1caea01fd9a6c6d12e5ca46007e25a4b1eff640060f45de8213e40aa5b47cd57-1311738296
How do I achieve this?
Thanks
You can read it the same way you read the positive values.
elif response == 1:
positives = int(json_response.get("positives"))
permalink = json_response.get("permalink")
if positives >= 3:`enter code here`
print(hash + ": MALICIOUS" + " | URL:" + permalink)
file = open(output,"a")`enter code here`
file.write(hash + " " + str(positives))
file.write("\n")
file.close()

My Graphviz nodes is on top of each other

I want to create a graph with graphviz and python with a lot of nodes. But it renders on top of each other and I cant seem to figure out how to fix the spacing between graphs.
Here is the output:
And here is my code where I generate the nodes:
def build_mind_map(history, site_info):
mind_map = Graph('mind_map', filename='graph', engine='sfdp', strict=True)
mind_map.graph_attr = {'label': heading, 'labelloc': "t", "labelfontsize": '13.0', "labeljust": "l"}
mind_map.graph_attr.update(size="2,2")
sorted_list = sort_list(site_info)
nodes_list_0 = []
nodes_list_1 = []
g = sorted_list[0]
nodes_list_0.append(str(g[0]))
mind_map.attr('node', color='cyan4', style='filled', labelfontsize="20", pad='10')
mind_map.node(str(g[0]), label="<<font point-size='18'><B>" + g[0] + "</B></font><br/><br/>>", nodesep="2")
for j in sorted_list:
date_string = '\n'
for d in j[2]:
date_string = date_string + "\n" + d
if str(j[0]) not in nodes_list_0:
mind_map.attr('node', color='crimson', style='filled', pad='10')
mind_map.node(str(j[0]), label="<<B>" + j[0] + "</B><br/><br/>" + date_string + ">", nodesep="2")
nodes_list_0.append(str(j[0]))
if str(j[1]) not in nodes_list_1:
mind_map.attr('node', color='cyan3', style='filled', pad='10')
mind_map.node(str(j[1]), label="<<B>" + j[1] + "</B><br/><br/>" + date_string + ">")
nodes_list_1.append(str(j[1]))
mind_map.edge(str(j[0]), str(j[1]))
mind_map.edge(str(g[0]), str(g[1]))
if history == "1":
mind_map_second = Graph('mind_map', filename='graph', engine='sfdp')
mind_map_second.attr('node', color='yellow', style='filled', labelfontsize="20")
for i in db.get_history_matches():
m = i[3].split(",")
info_string = ""
try:
if len(m[0]) > 0:
info_string += "<br/>Branch: " + m[0]
except:
pass
try:
if len(m[1]) > 0:
info_string += "<br/>Driver: " + m[1]
except:
pass
try:
if len(m[2]) > 0:
info_string += "<br/>Location" + m[2]
except:
pass
try:
if len(m[3]) > 0:
info_string += "<br/>Date: " + m[3]
except:
pass
try:
if len(m[4]) > 0:
info_string += "<br/>CIS: " + m[4]
except:
pass
try:
if len(m[5]) > 0:
info_string += "<br/>CAS: " + m[5]
except:
pass
if str(i[0]) not in nodes_list_0:
mind_map_second.node(str(i[0]), label="<History Found<br/><br/><B>" + i[0] + "</B><br/>" + info_string + ">")
nodes_list_0.append(str(i[0]))
if str(i[1]) not in nodes_list_1:
mind_map_second.node(str(i[1]), label="<History Found<br/><br/><B>" + i[1] + "</B><br/>" + info_string + ">")
nodes_list_1.append(str(i[1]))
mind_map_second.edge(str(i[0]), str(i[1]))
mind_map.subgraph(mind_map_second)
mind_map.view()
Can someone please help me to figure out how to get the spacing sorted.
Thanks

Correcting logic on a return option on a loop python 3.6

I was taking a online class for Python and one of the tutorials is to create a battle system for a RPG. I finished the tutorial and felt that there was so much missing. One of the missing features was there is no option to go back to a players action which can lead to an infinite loop. I have coded a large section to include a way to go back by typing '0' and it works except for when there is no quantity for an item when selecting items and when there is no more MP for a spell. What happens in that case is when '0' is selected, the last entry on the array is automatically implemented. So lets say I have no MP and 'cura' is my last spell on the list, if I select '0' cura gets cased regardless. Can anyone tak a look at this small section I have included to see where the error is? I will include the entire code if needed.
while running:
print("====================\n")
print("NAME HP MP")
for player in players:
player.get_stats()
print("")
for enemy in enemies:
enemy.get_enemy_stats()
for player in players:
# check if player won
if defeated_enemies == 3:
print("\n" + bcolors.OKGREEN + "You Win!\n♫♫ Fanfare ♫♫" + bcolors.ENDC)
running = False
break
start = True
while start:
start = False
choice = player.choose_action()
index = choice - 1
if index == 0:
dmg = player.generate_damage()
enemy = player.choose_target(enemies)
enemies[enemy].take_damage(dmg)
print("\n" + player.name.replace(" ", "") + " attacked " + enemies[enemy].name.replace(" ", "") + " for", dmg, "points of damage.")
if enemies[enemy].get_hp() == 0:
print(bcolors.BOLD + bcolors.FAIL + enemies[enemy].name.replace(" ", "") + " HAS FALLEN!" + bcolors.ENDC)
del enemies[enemy]
defeated_enemies += 1
elif index == 1:
check_mp = True
while check_mp:
mag_choice = player.choose_magic()
magic_choice = mag_choice - 1
spell = player.magic[magic_choice]
magic_dmg = spell.generate_damage()
current_mp = player.get_mp()
if spell.cost > current_mp:
print(bcolors.FAIL + "\nNot enough MP. Please choose a different spell. Type 0 to go back." + bcolors.ENDC)
continue
else:
check_mp = False
if magic_choice == -1:
start = True
continue
player.reduce_mp(spell.cost)
if spell.type == "white":
player.heal(magic_dmg)
print(bcolors.OKBLUE + "\n" + spell.name + " heals", player.name, "for", str(magic_dmg), "HP." + bcolors.ENDC)
if player.hp > player.maxhp:
player.hp = player.maxhp
elif spell.type == "black":
enemy = player.choose_target(enemies)
enemies[enemy].take_damage(magic_dmg)
print(bcolors.OKBLUE + "\n" + spell.name + " deals", str(magic_dmg), "points of damage to " + enemies[enemy].name.replace(" ", "") + bcolors.ENDC)
if enemies[enemy].get_hp() == 0:
print(bcolors.BOLD + bcolors.FAIL + enemies[enemy].name.replace(" ", "") + " HAS FALLEN!" + bcolors.ENDC)
del enemies[enemy]
defeated_enemies += 1
elif index == 2:
choose_item = True
while choose_item:
itm_choice = player.choose_item()
item_choice = itm_choice -1
item = player.items[item_choice]["item"]
if player.items[item_choice]["quantity"] == 0:
print(bcolors.FAIL + "\nThere are no more " + str(item.name) +"s left. Please choose a different item. Type 0 to go back." + bcolors.ENDC)
continue
else:
break
if item_choice == -1:
start = True
continue
player.items[item_choice]["quantity"] -= 1
if item.type == "potion":
player.heal(item.prop)
print(bcolors.OKGREEN + "\n" + item.name + " heals", player.name, "for", str(item.prop), "HP." + bcolors.ENDC)
if player.hp > player.maxhp:
player.hp = player.maxhp
elif item.type == "elixer":
if item.name == "MegaElixer":
print("\n" + player.name.replace(" ", ""), "uses", item.name)
print(bcolors.OKGREEN + "HP and MP fully restored to all party members!" + bcolors.ENDC)
for i in players:
i.hp = i.maxhp
i.mp = i.maxmp
else:
player.hp = player.maxhp
player.mp = player.maxmp
print(player.name.replace(" ", ""), "uses", item.name)
print(bcolors.OKGREEN + player.name.replace(" ", "") + " HP and MP fully restored!" + bcolors.ENDC)
elif item.type == "attack":
enemy = player.choose_target(enemies)
enemies[enemy].take_damage(item.prop)
print(bcolors.FAIL + "\n" + item.name + " deals", str(item.prop), "points of damage to " + enemies[enemy].name.replace(" ", "") + bcolors.ENDC)
if enemies[enemy].get_hp() == 0:
print(bcolors.BOLD + bcolors.FAIL + enemies[enemy].name.replace(" ", "") + " HAS FALLEN!" + bcolors.ENDC)
del enemies[enemy]
defeated_enemies += 1
else:
continue

Resources