Skip to content

Commit 58db5df

Browse files
committed
feat:first commit
0 parents  commit 58db5df

File tree

16 files changed

+4867
-0
lines changed

16 files changed

+4867
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.db
2+
.idea/
3+
__pycache__/
4+
metadata.txt
5+
db_path.txt

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Secure Remote Desktop Connection (Secure RDC)
2+
3+
This Python program provides a robust solution for managing Remote Desktop Connection (RDC) credentials and traces on Windows operating systems, enhancing your privacy and security. It empowers users to control and sanitize their remote desktop connections efficiently.
4+
5+
6+
### Features
7+
8+
- **Credential Management:** Easily store and manage RDP login information using Windows generic credentials.
9+
- **Connection Establishment:** Initiate remote desktop connections effortlessly with the provided credentials.
10+
- **Trace Removal:** Clear all traces of the remote desktop connection for enhanced security and privacy.
11+
12+
### How it works?
13+
14+
- Sets up credentials for the specified IP address with the provided username and password.
15+
- Launches a Remote Desktop Connection to the specified IP address.
16+
- After the connection is finished, deletes stored credentials for the specified IP address.
17+
- Removes terminal credentials associated with the specified IP address.
18+
- Clears Terminal Server Client settings for a clean slate.
19+
- Deletes the hidden Default.rdp file from the user's Documents directory.
20+
- Deletes the non-hidden Default.rdp file from the user's Documents directory.
21+
22+
### Usage Guidelines
23+
24+
- Save your credentials using the provided script.
25+
- Connect to the remote computer using the Windows Remote Desktop Connection program.
26+
- For enhanced security, delete traces of the connection as needed.
27+
28+
**Note:** Ensure you have the necessary permissions before executing these commands.
29+
30+
Feel free to contribute, report issues, or suggest improvements!

VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1.0.0

generateMetadata.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from src.info import (CompanyName,
2+
AppName,
3+
AppVersion,
4+
OriginalFilename,
5+
FileDescription,
6+
LegalCopyright)
7+
8+
9+
def generate_md(output_path):
10+
version_content = f"""
11+
VSVersionInfo(
12+
ffi=FixedFileInfo(
13+
filevers=({AppVersion.replace('.', ',')}),
14+
mask=0x3f,
15+
flags=0x0,
16+
OS=0x4,
17+
fileType=0x1,
18+
subtype=0x0,
19+
date=(0, 0)
20+
),
21+
kids=[
22+
StringFileInfo(
23+
[
24+
StringTable(
25+
u'040904b0',
26+
[StringStruct(u'CompanyName', u'{CompanyName}'),
27+
StringStruct(u'ProductName', u'{AppName}'),
28+
StringStruct(u'ProductVersion', u'{AppVersion}'),
29+
StringStruct(u'OriginalFilename', u'{OriginalFilename}'),
30+
StringStruct(u'FileDescription', u'{FileDescription}'),
31+
StringStruct(u'LegalCopyright', u'{LegalCopyright}'),])
32+
]),
33+
VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
34+
]
35+
)
36+
"""
37+
with open(output_path, 'w', encoding='utf-8') as output_file:
38+
output_file.write(version_content.strip())
39+
40+
41+
if __name__ == "__main__":
42+
generate_md('metadata.txt')

icons/connect.ico

30.2 KB
Binary file not shown.

icons/favicon.ico

27.2 KB
Binary file not shown.

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
PyQt5
2+
SQLAlchemy

src/app.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import os, sys, subprocess, time
2+
from ui_pycode.main import Ui_Main
3+
from info import *
4+
from db_connect import *
5+
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
6+
7+
8+
class Main(QMainWindow, Ui_Main):
9+
def __init__(self):
10+
super().__init__()
11+
self.setupUi(self)
12+
self.setWindowTitle(AppName)
13+
self.switch_general()
14+
self.set_username()
15+
16+
self.btn_general.clicked.connect(self.switch_general)
17+
self.btn_username.clicked.connect(self.switch_username)
18+
self.btn_connect.clicked.connect(self.connect)
19+
20+
def connect_db(self):
21+
with Session() as session:
22+
user = session.query(Connection).first()
23+
try:
24+
return user
25+
except Exception as e:
26+
self.get_error(f"\n{e}")
27+
28+
def switch_general(self):
29+
self.stackedWidget.setCurrentIndex(0)
30+
user = self.connect_db()
31+
self.input_port.setText(user.port_number)
32+
33+
def switch_username(self):
34+
self.stackedWidget.setCurrentIndex(1)
35+
self.input_username.setFocus()
36+
37+
def set_username(self):
38+
self.input_username.clear()
39+
40+
user = self.connect_db()
41+
if user.log_username is None:
42+
username = user.default_username
43+
else:
44+
username = user.log_username
45+
46+
self.input_username.setText(username)
47+
48+
# Update username
49+
def UpdateUserAndPort(self):
50+
username = self.input_username.text().strip().upper()
51+
port_number = self.input_port.text()
52+
53+
if username:
54+
with Session() as session:
55+
user = session.query(Connection).first()
56+
if self.checkbox_save_me.isChecked():
57+
user.default_username = username
58+
59+
user.log_username = username
60+
user.port_number = port_number
61+
session.commit()
62+
else:
63+
self.get_error(f"\nEnter Username!")
64+
65+
66+
# Control ip and password and connect remote desktop
67+
def connect(self):
68+
self.UpdateUserAndPort()
69+
70+
user = self.connect_db()
71+
if user.log_username is None:
72+
username = user.default_username
73+
else:
74+
username = user.log_username
75+
76+
ip_address = self.input_ip_address.text()
77+
port_number = self.input_port.text()
78+
password = self.input_password.text()
79+
80+
if not ip_address:
81+
self.get_error(f"\nEnter IP address!")
82+
elif not password:
83+
self.get_error(f"\nEnter password!")
84+
else:
85+
self.input_ip_address.clear()
86+
self.input_password.clear()
87+
if port_number:
88+
complete_address = ip_address+':'+port_number
89+
else:
90+
complete_address = ip_address
91+
92+
self.remote_desktop_connection(ip_address, username, password, complete_address)
93+
94+
95+
def remote_desktop_connection(self, ip_address, username, password, complete_address):
96+
# Create the RDP file path
97+
rdp_file_path = os.path.join(os.environ['HOMEPATH'], 'Documents', 'local.rdp')
98+
99+
# Create the RDP file with local resource settings
100+
with open(rdp_file_path, 'w') as rdp_file:
101+
rdp_file.write(f"full address:s:{complete_address}\n")
102+
rdp_file.write("redirectprinters:i:1\n") # Enable printer redirection
103+
rdp_file.write("redirectclipboard:i:1\n") # Enable clipboard redirection
104+
rdp_file.write("redirectcomports:i:1\n") # Enable COM port redirection
105+
106+
credentials = f'cmdkey /generic:{ip_address} /user:{username} /pass:{password}'
107+
connect = f'mstsc "{rdp_file_path}"'
108+
109+
# Commands to clean up after connection
110+
delete_connection = f'cmdkey /delete:{ip_address}'
111+
delete_connection_term = f'cmdkey /delete:TERMSRV/{ip_address}'
112+
delete_TSC = r'reg delete "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client" /f'
113+
delete_hidden_default_rdp = f'del /ah "{os.path.join(os.environ["HOMEPATH"], "Documents", "Default.rdp")}"'
114+
delete_default_rdp = f'del "{os.path.join(os.environ["HOMEPATH"], "Documents", "Default.rdp")}"'
115+
delete_default_rdp = f'del "{os.path.join(os.environ["HOMEPATH"], "Documents", "local.rdp")}"'
116+
117+
# List of commands to execute
118+
commands = [credentials, connect, delete_connection, delete_connection_term, delete_TSC,
119+
delete_hidden_default_rdp, delete_default_rdp]
120+
121+
self.close()
122+
123+
for command in commands:
124+
try:
125+
proc = subprocess.Popen(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
126+
proc.communicate()
127+
time.sleep(0.08)
128+
except Exception as e:
129+
self.get_error(f"\n{e}")
130+
131+
132+
# Show Error
133+
def get_error(self, error):
134+
QMessageBox.critical(self, AppName, f"{error}")
135+
136+
137+
if __name__ == "__main__":
138+
app = QApplication(sys.argv)
139+
main_window = Main()
140+
main_window.show()
141+
sys.exit(app.exec_())

src/db_connect.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import os
2+
from sqlalchemy import create_engine, Column, Integer, String, Boolean
3+
from sqlalchemy.ext.declarative import declarative_base
4+
from sqlalchemy.orm import sessionmaker
5+
6+
Base = declarative_base()
7+
8+
class Connection(Base):
9+
__tablename__ = 'connection'
10+
11+
id = Column(Integer, primary_key=True)
12+
default_username = Column(String(100), default=None)
13+
log_username = Column(String(100), default=None)
14+
ip_address = Column(String(100), default=None)
15+
port_number = Column(String(100), default=None)
16+
17+
18+
def get_db_path(file_path):
19+
if not os.path.exists(file_path):
20+
# If the file does not exist, create it
21+
with open(file_path, 'w') as file:
22+
file.write('')
23+
return ''
24+
25+
with open(file_path, 'r') as file:
26+
return file.readline().strip()
27+
28+
db_path = get_db_path('db_path.txt')
29+
DB_NAME = 'secure.db'
30+
31+
# Create a SQLite database using the path from the text file and the static database name
32+
engine = create_engine(f'sqlite:///{os.path.join(db_path, DB_NAME)}')
33+
Base.metadata.create_all(engine)
34+
Session = sessionmaker(bind=engine)
35+
36+
37+
# Create a new connection with the current user's login name
38+
with Session() as session:
39+
user = session.query(Connection).first()
40+
if user:
41+
user.log_username = None
42+
else:
43+
current_user = str(os.getlogin()).upper()
44+
user = Connection(default_username=current_user)
45+
session.add(user)
46+
session.commit()

src/info.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
AppName = 'Secure RDC'
2+
AppVersion = '1.0.0.0'
3+
OriginalFilename = 'Secure RDC.exe'
4+
FileDescription = 'Secure Remote Desktop Connection'
5+
CompanyName = 'Texno Region'
6+
LegalCopyright = 'Texno Region. All Rights Reserved © 2025.'

0 commit comments

Comments
 (0)