13 Replies Latest reply on Dec 7, 2013 8:29 PM by AlexBlair_1

    Protecting a runtime solution

    JCPython

      Title

      Protecting a runtime solution

      Post

      Looking for effective solutions that others have used to protect their runtime database from piracy,

      Im looking for a type of registration key process, found a few but some of the artcles were from like 15 years ago and i dont know if it would still be stable at this time. i seen code x but i cant affoard to put in any cash, im not looking for cia security but enough to stop the casual user from pirating my runtime and such.

       

      again just looking for what others have used and worked for them.

        • 1. Re: Protecting a runtime solution
          JCPython

          Would anyone recommend this

          http://www.briandunning.com/easy-encryption/

          its the cheapest i found and id hate to have to buy a way to protect my software but if this is my only option im gonna have to go with it.

          • 2. Re: Protecting a runtime solution
            JCPython

            Would it maybe be possible to create a separate filemaker database to be located in the same folder as the runtime and that database is loaded with serial numbers as records, and i have a list of all these serials and when a customer purchases  a copy of the database then they get the serial emailed to them and when the runtime ask for the serial it does a check to see if the serial is a record or not in the other file?

            • 3. Re: Protecting a runtime solution
              philmodjunk

              That would be the same as defining a password in your file that unlocks full capabilites when they open it. EIther way, you are sending them a Key that, if they share it with others, could be used to unlock unauthorized copies of your solution. (Years ago a tech once tried to give me a copy of MS Word along with the unlock code...)

              • 4. Re: Protecting a runtime solution
                JCPython

                oh yes, i didnt think of that, hmmm there has to be a way to secure solutions without paying hundreds or even thousands of dollars

                • 5. Re: Protecting a runtime solution
                  kdefilip

                  Hi

                  I'm working on this very issue right now.  What I have done is created a hidden layout.  Upon first use, the user is required to enter certain information, i.e., organization name, scoring method, etc.  Unbeknownst to them, I use the Get(HostName) and fill a field in this layout called host name with their computer name.  This all happens during the "Open Script".  Subsequent opens detect whether these fields have been filled in.  If they have been, they are not required to fill this information again and are simply sent to the layout that allows their input into the DB.  The last part of the open script additionally checks to see if the field "host name" matches the actual host name of the machine.  If it is filled in and if it does not match, they are given a warning that the software is not licensed and the solution quits.  Keep in mind that the user is not aware of this check and it will probably never occur to them to simply rename another computer and copy the folder to it.

                  Now I don't have this completely working just yet - it's the last step I am stuck on.  But if it pans out, I will pass it along.  If you have any questions, email me and I will try to answer and I will send the details and the open script I am using.

                  • 6. Re: Protecting a runtime solution
                    philmodjunk

                    The main problem that I forsee is if they upgrade their computer and move your solution to it, it will no longer work unless they happen to give it the same name. Be prepared to field tech support calls on this issue from time to time if you use that method. With fileMker 12, you have a better option than the host name, you can use Get ( PersistentID ) to access an ID number that is unique to a specific machine.

                    • 7. Re: Protecting a runtime solution
                      MarkRamsay

                      I've written a script using the exact same idea as kdefilip (independently, thought of it 3 days ago, and wrote it before establishing an account on this Forum).  Here is the script.  I'd like some feedback as a way of an independent evaluation.  I'm soon ready to put my solution to market.  

                      Now this script allow someone with admin access to open the program.  Otherwise, if you write this script with errors, you could be locked out of your own creation.  I will reconsider this based upon the other postings above.  Thanks.

                      The field kdefilip defined has to be set to a global variable on a layout that has one record. The name of the field is "HosterID." Global is set is so the record does not have to be accessed during the startup script sequence.  It's the record that has the "about" info of my software.  The field background and font color is same as background.  User will never see it.  Make the field unselectible in Browse and Find modes (set by the Investigator or similar on older FM versions).

                       

                      • 8. Re: Protecting a runtime solution
                        johnhorner

                        hi mark,

                        i have a couple questions and observations for you:

                        i don't understand what you mean when you say you made HosterID Global so you would not have to access it?  aren't you accessing it in your script when you evaluate it with statements such as "if [IsEmpty (ProgramActivities::HosterID)]?  or do you simply mean that you don't need to create a relationship to it because it is global?  if you are on a layout based on the ProgramActivities table and there is only one record, you would not need a relationship even if it was not global because if you were on any record in that table, it would have to be that one... i am missing something?

                        also, i don't understand what the purpose of your "camouflaged" fields are.  why put them on the layout at all if you don't want to see them and they can't be entered in either mode?

                        it also occurs to me that if this solution is hosted, and the client machine name does not match, resetting the global HosterID field will only persist for that session and will fail the test every time it is opened since global fields are specific to the user... will it not?

                        finally, it seems like it still has the problem that phil mentions whereby if a licensed user gets a new computer and names it differently (which i do every time i get a new computer), they will be locked out of their software (unless you give them an account with full access).  and if you do that, what is to prevent them from giving a copy of your software to someone else along with the full access account info?

                        i'm not positive that this would work, but one idea would be to host an "activation" file which would contain account info (serial numbers, passwords, and client machine id's, etc) and set it up as an external data source for the licensed software.  a startup script could look at the hosted file and if there was a mismatch of information it could inform the user that the software is licensed for one machine and allow them to select which machine they want to "activate".  i did a very quick test of this and it seemed to work but maybe accessing a hosted external data source is not feasible in this type of scenario... does anybody else know?

                        • 9. Re: Protecting a runtime solution
                          MarkRamsay

                          Thanks for comment, JohnHorner.

                          Programs with two files in a Filemaker environment have the problem that the user can double click either to initiate operation.  The startup sequence of the second file has to be called by the startup script of the chosen.  I've had problems writing to fields in other files, so I go global to ensure it happens.

                          I apply fields to layouts to test operation.  Then I hide them when done, revealing again when I want to revise program. But I forgot you can write to a field that is not placed on a record.

                          This method is for a runtime solution.  If the person changes the computer it's a problem.  You can ask them to send their runtime back, their files on it and all, to the author to be reset.  I'm interested in your external variable approach.  I've never used external variables but if you want to try using my computer as the host let me know.  Then I will learn about them.

                          • 10. Re: Protecting a runtime solution
                            johnhorner

                            thanks mark... that answers some of my questions but brings up a couple others.

                            i understand now that you are using a global field because you encountered problems with writing to a non-global.  i am pretty sure that could be resolved and when i have encountered similar problems it has most often been 1 of 2 things: the relationship is not properly defined, or the relationship is not properly referenced when specifying the field... but that is a separate issue which we can leave for now if it is working but keep in mind it could cause problems in a hosted solution... i don't know a lot about runtime solutions including whether they can even host a solution this potential problem may be moot.  there is no reason why you shouldn't be able to write reliably to a field in another file.  inadequate privileges can cause this problem too, but you can call a script in the second file to write to the field and run the script with full access privileges so it will work regardless of the users privilege set.  but this is not causing your problem because it would fail to write whether it was global or not... and since you are able to write to the global, it is not a permission problem.

                            i also understand now why you have the camouflaged fields on your layout but one thing you may want to consider with regard to this is that even though they are invisible, if there are calculation fields or summary fields on the layout, it will take filemaker time to evaluate the fields in order to "display" them, at least this is my understanding of how filemaker works.  i know that many people (including myself) use a completely empty layout for each table to be utilized by scripts as they will run faster, and keep another set of layouts with all the fields on them for development purposes (you can use privileges to keep the user from accessing the "developer" layouts.

                            as for my proposed solution, it is not "external variables", but a completely separate master license file i am proposing of which there would be only one (as opposed to the many runtime solutions being used by your customers) and you would host it on your server (or pay for it to be hosted on by a commercial filemaker hosting provider).  this file would contain all the necessary licensing information.  you would specify this hosted file as an "external data source" under the file>manage>external data sources menu for your runtime solution.  you would specify a "remote" file and enter the ip address and other info in the "favorite hosts" section (you have to "add" a favorite host).  once this is done you can add a table occurrence to your relationship graph in the runtime solution using the hosted file as the data source.  the final step would be to write a script that would look up the license key and computer name and compare that with the master list on the hosted file and then take what ever action you would like to take depending on the results (e.g. quit the application, offer to deactivate it on previous machine and activate on the new one, purchase an additional license if they are trying to install on a second machine, etc).  your runtime users (assuming you don't give them access to scripts or managing the database) would not be able to see or access this hosted file other than via the script which is running unbeknownst to them.  does that make sense?  good luck!

                            • 11. Re: Protecting a runtime solution
                              MarkRamsay

                              Thanks, John.

                              About the script and the fields - during long scripts, I freeze panes to stop the engine that manages the monitor "experience."  My solution has about 20 report layouts and 10 or so field entry ones.  If you are executing a script from another layout, I recall you have to identify the layout in a field reference, e.g.  thatlayout::thatfield.   So if I move scripts, all 50+ of them, I will have to rewrite say 100+ field definitions? Appears I should let well enough alone, and in future solutions, follow your suggestion.

                              Your idea in paragraph 4 makes a lot of sense!  The app stays local to the user, which is the only way FM runs now.  The app does not have to be converted to web-enabled, which I can't do (There is not a web equivalent for "Insert from Index" in FM 11)  I can try this from my heavily networked employer's system accessing the file served by my home Mac.  Will let you know if it works.  It will take a few days for me to set it up.

                              • 12. Re: Protecting a runtime solution
                                johnhorner

                                hey mark... with regard to empty layout/freeze window/scripts issue i have a couple thoughts.

                                for starters, i think you are confusing what the syntax means in the field reference.  it is not "layout::field", it is "tableoccurrence::field".  it is actually independent of layout (with the exception of the fact that for non-global fields, you must have defined a relationship between the table you are currently "sitting on" (the table you have selected in the layout setup under "show records from") and the table where your target field resides and you need to utilize that relationship in specifying the field (that's poorly worded but i think you get the point). perhaps to put in another way, it will perform exactly the same on any layout that is based on the same table.

                                another thing to look into, that i don't have the answer to, is whether or not freeze window actually prevents filemaker from performing the calculations for fields on the layout.  i suspect that it merely stops the screen from displaying what is happening in the background, but i lean towards the notion that it does not actually prevent the action from taking place.  it just hides it from the user.  at least that is how freeze window seems to handle everything else.  for example, if a script step goes to a different layout, just because it appears to the user that you are still on the originla layout, filemaker is actually on the new layout. and if, for example, that new layout has an "onlayoutenter" script trigger, that script will execute.  it's just invisible to the user.  it is still a good idea to use the freeze window step because it is less disconcerting to the user and the script also runs faster in theory because the screen does not need to update, but if you go to a layout in your script that has calculation fields on it, i think filemaker still needs to calculate them.  does anybody else know?

                                finally, if you wanted to make the change to utilising empty layout, you would not actually have to change any of your hundreds of field definitions or scripts.  simply duplicate the layout in question, and delete all the fields from the original layout (and you can even change the name of it to "layout_empty" and all the references to this layout will update automatically in your scripts, field references will not change and do not need to change).  then you can simply use the duplicate layout (which you could rename "layout_developer", for example) and make all the fields permanently visible and enterable so it is easy for you to work with and then set the account privileges so that non-full access users cannot access it.

                                please let me know how it all works out.  happy to try to help if you encounter any issues along the way.

                                • 13. Re: Protecting a runtime solution
                                  AlexBlair_1

                                       Hello all, what gets me is why wouldn't the programmers of filemaker put some inherent module into the scripting options?? 

                                       While i know one shoe won't fit all, it would be nice if they had a simple one that we could adapt... Or are they worried about liability if someones copyright is circumvented and the solution pirated???