def get(self, request, uid): from tacticalrmm.utils import generate_winagent_exe try: _ = uuid.UUID(uid, version=4) except ValueError: return notify_error("invalid") d = get_object_or_404(Deployment, uid=uid) client = d.client.name.replace(" ", "").lower() site = d.site.name.replace(" ", "").lower() client = re.sub(r"([^a-zA-Z0-9]+)", "", client) site = re.sub(r"([^a-zA-Z0-9]+)", "", site) ext = ".exe" if d.arch == "64" else "-x86.exe" file_name = f"rmm-{client}-{site}-{d.mon_type}{ext}" return generate_winagent_exe( client=d.client.pk, site=d.site.pk, agent_type=d.mon_type, rdp=d.install_flags["rdp"], ping=d.install_flags["ping"], power=d.install_flags["power"], arch=d.arch, token=d.token_key, api=f"https://{request.get_host()}", file_name=file_name, )
def install_agent(request): from knox.models import AuthToken from agents.utils import get_winagent_url client_id = request.data["client"] site_id = request.data["site"] version = settings.LATEST_AGENT_VER arch = request.data["arch"] # response type is blob so we have to use # status codes and render error message on the frontend if arch == "64" and not os.path.exists( os.path.join(settings.EXE_DIR, "meshagent.exe")): return Response(status=status.HTTP_406_NOT_ACCEPTABLE) if arch == "32" and not os.path.exists( os.path.join(settings.EXE_DIR, "meshagent-x86.exe")): return Response(status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE) inno = (f"winagent-v{version}.exe" if arch == "64" else f"winagent-v{version}-x86.exe") download_url = get_winagent_url(arch) _, token = AuthToken.objects.create( user=request.user, expiry=dt.timedelta(hours=request.data["expires"])) if request.data["installMethod"] == "exe": from tacticalrmm.utils import generate_winagent_exe return generate_winagent_exe( client=client_id, site=site_id, agent_type=request.data["agenttype"], rdp=request.data["rdp"], ping=request.data["ping"], power=request.data["power"], arch=arch, token=token, api=request.data["api"], file_name=request.data["fileName"], ) elif request.data["installMethod"] == "manual": cmd = [ inno, "/VERYSILENT", "/SUPPRESSMSGBOXES", "&&", "ping", "127.0.0.1", "-n", "5", "&&", r'"C:\Program Files\TacticalAgent\tacticalrmm.exe"', "-m", "install", "--api", request.data["api"], "--client-id", client_id, "--site-id", site_id, "--agent-type", request.data["agenttype"], "--auth", token, ] if int(request.data["rdp"]): cmd.append("--rdp") if int(request.data["ping"]): cmd.append("--ping") if int(request.data["power"]): cmd.append("--power") resp = { "cmd": " ".join(str(i) for i in cmd), "url": download_url, } return Response(resp) elif request.data["installMethod"] == "powershell": ps = os.path.join(settings.BASE_DIR, "core/installer.ps1") with open(ps, "r") as f: text = f.read() replace_dict = { "innosetupchange": inno, "clientchange": str(client_id), "sitechange": str(site_id), "apichange": request.data["api"], "atypechange": request.data["agenttype"], "powerchange": str(request.data["power"]), "rdpchange": str(request.data["rdp"]), "pingchange": str(request.data["ping"]), "downloadchange": download_url, "tokenchange": token, } for i, j in replace_dict.items(): text = text.replace(i, j) file_name = "rmm-installer.ps1" ps1 = os.path.join(settings.EXE_DIR, file_name) if os.path.exists(ps1): try: os.remove(ps1) except Exception as e: logger.error(str(e)) with open(ps1, "w") as f: f.write(text) if settings.DEBUG: with open(ps1, "r") as f: response = HttpResponse(f.read(), content_type="text/plain") response[ "Content-Disposition"] = f"inline; filename={file_name}" return response else: response = HttpResponse() response[ "Content-Disposition"] = f"attachment; filename={file_name}" response["X-Accel-Redirect"] = f"/private/exe/{file_name}" return response