Reputation: 1344
I have a link on my website to the standard publish page generated by Visual Studio. My concern is that if anybody finds out the URL to that page, they can download my software. Sure, I could password protect the page with the link, but it still would not be protecting the download URL. Are there any ways to secure the click once upload? I have looked around, and it seems like I am stuck in this sense.
Upvotes: 6
Views: 1787
Reputation: 78
Public URL is a security issue in ClickOnce Deployment. However, there is a solution for your problem if your web server has windows and .NET installed. Tell me if you have one ? I will have to come up with another workaround for Linux web server in case you have that.
Firstly, a bit of information about ClickOnce deployment. When you deploy the application, the GET requests on the server made are (assuming WebDir is the publish directory on the server)
G-1. GET /WebDir/setup.exe
(Initial download)
G-2. GET /WebDir/MyApp.Application
(setup.exe -url request)
G-3. GET /WebDir/MyApp.Application
(.application deployment provider URL request)
G-4. GET /WebDir/Application Files/MyApp_1_0_0_0/MyApp.exe.manifest
(Application manifest request)
G-5. GET /WebDir/Application Files/MyApp_1_0_0_0/MyApp.exe.deploy
and other .deploy files ... (Application file requests)
Now, the solution is to intercept these file requests on the server. On IIS, you can attach a custom HTTPHandler and handle the request. On Apache, you can redirect requests to a PHP code using .htaccess files. Apart from this, you will have to generate unique identifier uid
for client instances downloaded from the server (can be your license key) and put that in the deployment provider URL query parameters.
Create an "Application"
folder inside your WebDir
and restrict access to /WebDir/Application/
. Rest everything can be there inside /WebDir/
So here's what you do on a Apache web server hosted on a windows machine:
/WebDir/Download.php
Download.php
, you have to send setup.exe
from your code (can do it with readfile()
in PHP) to the user. However, the catch is bootstrapper (setup.exe
) after installing will do a GET request [G-2]. Don't forget now, that you have to validate this file request. So basically you change the "setup.exe -url"
property to include uid
before returning the file. For eg: change it to /WebDir/uid/MyApp.Application
[G-2]. You can use MsiStuff.exe to change the URL property for the bootstrapper..htaccess
file, rewrite [G-2] to /WebDir/Handler.php?user=uid
. From Handler.php
, you can check if it is a valid uid
. If it is valid, you will have to include the uid
in the deployment provider URL and "Dependent Assemblies Path" in deployment manifest so that if an upgrade request comes (It essentially requests the deployment manifest), you can validate the user there too. Add uid
to query string parameters. For eg: change it to /WebDir/MyApp.application?user=uid
[G-3]. Don't forget that you will have to resign the manifests once you modify them. Use Mage or write your own code to do that.So finally, the GET requests on the server will be (assuming uid
=1f3rd)
G-1. GET /WebDir/Download.php
Action: return setup.exe
with the -url changed
G-2. GET /WebDir/Application/setup.exe/1f3rd/MyApp.Application
Action: redirect, validate user, change URL, re-sign and return file
G-3. GET /WebDir/Application/setup.exe/MyApp.Application?user=1f3rd
Action: redirect, validate user and return file
G-4. GET /WebDir/Application/1f3rd/Application Files/MyApp_1_0_0_0/MyApp.exe.manifest
Action: redirect, validate user and return file
G-5. GET /WebDir/Application/1f3rd/Application Files/MyApp_1_0_0_0/MyApp.exe.deploy
and other .deploy files ...
Action: redirect, validate user and return file
uid
in the URL present.If you want me to make something clear or explain in detail, feel free to ask. In case you have suggestions for modification to the above, post that too.
I will write a detailed CodeProject article if I have spare time someday.
Upvotes: 4