Announcement

Collapse
No announcement yet.

Protecting Files

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Protecting Files

    I have to deliver 856 files with my program and they must be
    completely protected against overwriting by the customer.

    How can I protect them prior to delivery?

    My program will run under Windows2000.

    Bob

    ------------------

  • #2
    Just a guess, but if you make them read-only, don't they get copied from the distribution media as read-only?

    And if not, you can use the PB SETATTR function to make them read-only as part of your 'install' process.

    MCM

    Comment


    • #3
      Had thought of that!

      Unfortunately can't anyone unset the attribute (or maybe I am
      just used to being Administrator!)

      I was wondering if I could set a security attribute which
      indicates that only my program has write privilege (Not
      that I want to)

      Bob

      ------------------

      Comment


      • #4
        Put 'em in a directory, then make the directory read-only. Then only an adminstrator can change the permissions. This is how Mercator(r) installs.. they even put in the install instructions "On Win NT you must be an administrator to install this product."

        I do not believe you can achieve any better security than that offered by the file/network software.

        As far as protecting against deliberate attempts to overwrite data, that's why pink slips were invented.

        MCM


        Comment


        • #5
          Since you use W2K, does the hard disk use NTFS or the old Fat 16 system?

          NTFS allows you for greater control over the file attributes.

          Just a thought.


          ------------------
          Patrice Terrier
          mailtoterrier@zapsolution.compterrier@zapsolution.com</A>
          http://www.zapsolution.com

          Toolkit: WinLIFT (Skin Engine), GDI+ helper (Graphic package), dvBTree (Index manager)[b]
          Multimedia: ZAP Image Solution, ZAP Media Browser, ZAP Slide Show.
          Freeware: ZAP Audio Player, ZAP Picture Browser.
          Patrice Terrier
          www.zapsolution.com
          www.objreader.com
          Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

          Comment


          • #6
            Michael - Maybe I'm showing my age!! "pink slips"???

            Patrice - Just realised I have no control over which version -
            I always use NTFS

            Thanks,
            Bob

            ------------------

            Comment


            • #7
              bob,

              if you want to have full control on the security attributes, you must use the core file i/o api
              i have written myself several file i/o helper functions that you can found at:
              http://www.powerbasic.com/support/pb...ad.php?t=22634

              see also what msdn says about file and directory security for w2k:

              windows nt/windows 2000 security enables you to control access to file and directory objects stored on a secure file system, such as ntfs. for more information about security, see access-control model.

              you can specify a security descriptor for a file or directory when you call the createfile, createdirectory, or createdirectoryex function. to retrieve the security descriptor of a file or directory object, call the getnamedsecurityinfo or getsecurityinfo function. to change the security descriptor of a file or directory object, call the setnamedsecurityinfo or setsecurityinfo function.

              when a thread calls the createfile function to open a handle to a file or directory object, the thread requests a set of generic access rights to the object. the requested access rights determine the operations that the thread can perform with the returned handle. before returning a handle to the object, createfile checks the thread's access token and the requested access rights against the dacl in the object's security descriptor.

              for file and directory objects, generic_read access maps to the following standard and specific access rights.

              access right description
              file_read_attributes right to read file attributes.
              file_read_data right to read data from the file. for a directory, the right to list the contents of the directory.
              file_read_ea right to read extended attributes.
              standard_rights_read includes read_control, which is the right to read the information in the object's security descriptor, not including the information in the sacl.
              synchronize right to specify a file handle in one of the wait functions. however, for asynchronous file i/o operations, you should wait on the event handle in an overlapped structure rather than using the file handle for synchronization.


              for file and directory objects, generic_write access maps to the following standard and specific access rights.

              access right description
              file_append_data right to append data to the file. for a directory, the right to create a subdirectory.
              file_write_attributes right to write file attributes.
              file_write_data right to write data to the file. for a directory, the right to create a file in the directory.
              file_write_ea right to write extended attributes.
              standard_rights_write includes read_control, which is the right to read the information in the object's security descriptor, not including the information in the sacl.
              synchronize right to specify a file handle in one of the wait functions. however, for asynchronous file i/o operations, you should wait on the event handle in an overlapped structure rather than using the file handle for synchronization.


              you cannot use an access-denied ace to deny only generic_read or only generic_write access to a file. this is because for file objects, the generic mappings for both generic_read or generic_write include the synchronize access right. if an ace denies generic_write access to a trustee, and the trustee requests generic_read access, the request will fail because the request implicitly includes synchronize access which is implicitly denied by the ace. and vice versa, too. instead of using access-denied aces, use access-allowed aces to explicitly allow the permitted access rights.

              you can request the access_system_security access right to a file or directory object if you want to read or write the object's sacl. for more information, see access-control lists (acls) and sacl access right.



              ------------------
              patrice terrier
              mailtoterrier@zapsolution.compterrier@zapsolution.com</a>
              http://www.zapsolution.com

              toolkit: winlift (skin engine), gdi+ helper (graphic package), dvbtree (index manager)[b]
              multimedia: zap image solution, zap media browser, zap slide show.
              freeware: zap audio player, zap picture browser.
              Patrice Terrier
              www.zapsolution.com
              www.objreader.com
              Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

              Comment


              • #8
                Bob,

                Pink Slips ... harks back to when lay-off notices somewhere, sometime were printed or written on pink colord paper. In Michael's usage he means you terminate the hacking fellows ... er somthing like that

                A long time ago in DOSlandia you used to be able to do a keyboard trick when you named the directories, akin to a key combination that added backspaces to the file/dir name ... then it was not always noticed by the less astute and a bear to get rid of unless you knew how ... now you need to use more civilized means.


                ------------------
                Rick Angell



                [This message has been edited by Richard Angell (edited January 31, 2003).]
                Rick Angell

                Comment


                • #9
                  If the data is stored on an NTFS partition, you can use NTFS streams.

                  ------------------
                  -Greg
                  gengle@harringtonsignal.com
                  -Greg
                  gengle@harringtonsignal.com
                  MCP,MCSA,MCSE,MCSD

                  Comment


                  • #10
                    Robert,
                    If these files are generated by your program and will only be
                    used by your program, then enbed a control character in the file
                    name. In *NIX, the quick and dirty was to stick a "BS" character
                    in the file name. You can't see it, but it is a valid file name.
                    Haven't used this for awhile, but it sure "protected" the file
                    against accidental modification, copying, or deletion.
                    Thanks,
                    P.

                    ------------------

                    Comment


                    • #11
                      > and they must be completely protected against overwriting by the customer
                      If the files are on the customers machine the customer will be able to overwrite them regardless of what protective measures you put in place. (and being files on their system, isnt that their right anyway? )
                      One thing you could do is have a file(s) that stores hashes of the files you want to protect - you won't be able to prevent modification, but you can at least detect it...


                      ------------------
                      The PowerBASIC Crypto Archives - My Email - What's mine is yours...
                      -

                      Comment


                      • #12
                        Any idea to create a write-protected file such as INDEX.DAT in the cookies ?

                        Regards


                        ------------------

                        Comment


                        • #13
                          This might be too obvious, but in case your application doesn'
                          t need to alter the files: Leave them on a CD-ROM and require the CD-ROM to be inserted when you application is running...

                          Knuth

                          ------------------
                          http://www.softAware.de

                          Comment


                          • #14
                            Been away for a few days - many thanks for all the tips.

                            The Protected files are for comparison with working files
                            to detect the loss or addition of a text character. I have been
                            bluntly told that the company is at risk if this should happen.


                            I think I will settle for a CD Rom - hadn't thought of that -
                            as the verification only needs to take place once a day.

                            Bob

                            ------------------

                            Comment


                            • #15
                              Originally posted by Robert Wallace:
                              I think I will settle for a CD Rom - hadn't thought of that -
                              as the verification only needs to take place once a day.
                              Bob,

                              For a similar situation I ran a Crc32 sumcheck for each file against
                              a sumcheck reference. I also verified the file version number and it
                              only takes a short time even for a number of files. This has worked
                              well for me and I run at each program start.

                              Regards,

                              ~Bob

                              Comment


                              • #16
                                Bob,

                                This is the routine I use to verify program version numbers and file sumchecks. A similar
                                program may be easily written to generate the reference file list.

                                ~Bob Scott

                                Code:
                                ' The following has been pieced together from routines by Borje Hagsten and Semen Matusovski
                                ' and compares file version numbers and Crc32 sumcheck values against a reference list.
                                '
                                ' The reference is a list ($VersionDocument) of files in the following format:
                                 
                                ' Version Number ,  Hex Crc32 Value,  File Name
                                ' 2003.02.03     ,  12345678       ,  Example Program.exe
                                '                ,  12345678       ,  Example File.txt
                                '                ,  9CD065F0       ,  Check Files.exe
                                 
                                ' Just omit the initial single quote to enable the file check and if no file version is 
                                ' available then replace the version with spaces.
                                 
                                ' Adding any command line argument will append any error values to the $VersionDocument
                                ' to allow ease of editing.  Just delete the appended data when editing is complete. 
                                  
                                #COMPILE EXE "Check Files.exe"
                                #REGISTER NONE
                                #DIM ALL
                                 
                                #INCLUDE "win32api.inc"
                                 
                                DECLARE SUB CheckFiles(Msg$)
                                DECLARE FUNCTION GetVersionStringInfo(BYVAL Fname AS STRING) AS STRING
                                DECLARE SUB Crc32_BuildTable(sCrcTable AS STRING * 1024, BYVAL MagWord AS LONG)
                                DECLARE FUNCTION Crc32_Calculate (BYVAL Address AS DWORD, BYVAL Length AS LONG, _
                                           sCrcTable AS STRING * 1024, BYVAL InitCrc AS LONG, BYVAL Inverse AS LONG) AS LONG
                                 
                                %Attention=&h51030
                                %ErrorFlag=&h51010
                                $VersionDocument="Version Description File.txt"
                                 
                                FUNCTION PBMAIN
                                 
                                  LOCAL ErrorData$, F1 AS LONG
                                 
                                  ' Check Version and Crc32 values
                                  CheckFiles ErrorData$
                                  IF ErrorData$="" THEN
                                    MSGBOX "No Errors Found",%Attention,"Check Files"
                                  ELSE
                                    ErrorData$=Errordata$+$CRLF+$CRLF
                                    MSGBOX Errordata$,%ErrorFlag,"Check Files"
                                    IF COMMAND$ <> "" THEN
                                      F1=FREEFILE
                                      OPEN $VersionDocument FOR APPEND AS F1
                                      PRINT #F1,$CRLF+$CRLF+ErrorData$;
                                      CLOSE #F1             
                                    END IF
                                  END IF
                                 
                                  CLOSE     ' Clean up any open files
                                 
                                END FUNCTION
                                 
                                '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                ' Compare Crc32 sumcheck values and file version numbers..
                                '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                SUB CheckFiles(Msg$)
                                 
                                  DIM Buffer AS STRING, Crc AS LONG, sCrcTable1 AS STRING * 1024, _
                                                            sCrcTable2 AS STRING * 1024
                                 
                                  LOCAL F1 AS LONG, F2 AS LONG, L$, Version$, CrcRef$, Program$, V$
                                 
                                  IF DIR$($VersionDocument)="" THEN EXIT SUB
                                 
                                  F1=FREEFILE
                                  OPEN $VersionDocument FOR INPUT AS #F1
                                  DO WHILE NOT EOF(F1)
                                    LINE INPUT #F1,L$
                                    IF TRIM$(L$) <> "" AND LEFT$(TRIM$(L$),1) <> "'" THEN
                                      Version$=TRIM$(EXTRACT$(L$,","))
                                      CrcRef$=TRIM$(EXTRACT$(REMAIN$(L$,","),","))     ' Crc32 , Program
                                      Program$=TRIM$(REMAIN$(REMAIN$(L$,","),","))     ' Crc32 , Program
                                      IF DIR$(Program$)<>"" THEN
                                        V$=GetVersionStringInfo(Program$)
                                     
                                        F2=FREEFILE
                                        OPEN Program$ FOR BINARY SHARED AS #F2: GET$ #F2, LOF(F2), Buffer: CLOSE #F2
                                     
                                        Crc32_BuildTable sCrcTable1, &HEDB88320
                                        Crc = Crc32_Calculate (STRPTR(Buffer), LEN(Buffer), sCrcTable1, &HFFFFFFFF, 1)
                                      
                                        IF Version$<>V$ THEN
                                          IF COMMAND$="" THEN
                                            Msg$=Msg$+"Version Fail - "+Program$+$CRLF
                                          ELSE
                                            Msg$=Msg$+"Version Fail - "+Program$+"  "+V$+$CRLF
                                          END IF
                                        END IF
                                     
                                        IF HEX$(Crc,8)<>CrcRef$ THEN
                                          IF COMMAND$="" THEN
                                            Msg$=Msg$+"CheckSum Fail - "+Program$+$CRLF
                                          ELSE
                                            Msg$=Msg$+"CheckSum Fail - "+Program$+"   "+HEX$(Crc,8)+$CRLF
                                          END IF
                                        END IF
                                      ELSE
                                        Msg$=Msg$+"Not Found - "+Program$+$CRLF
                                      END IF
                                    END IF
                                  LOOP
                                  CLOSE
                                 
                                END SUB
                                 
                                '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                ' Retrieve a system file's version number..  by Borje Hagsten
                                '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                FUNCTION GetVersionStringInfo(BYVAL Fname AS STRING) AS STRING
                                  LOCAL lRes AS LONG, lZero AS LONG, sBuf AS STRING, tWFD AS WIN32_FIND_DATA
                                  LOCAL zFile AS ASCIIZ * %MAX_PATH, pFI AS VS_FIXEDFILEINFO PTR 
                                 
                                  zFile = zFile + Fname
                                 
                                  lRes = FindFirstFile(zFile, tWFD)                       'see if it exists
                                  IF lRes = %INVALID_HANDLE_VALUE THEN EXIT FUNCTION
                                  FindClose lRes
                                 
                                  lRes = GetFileVersionInfoSize(zFile, lZero)              'can we get any info?
                                  IF lRes = 0 THEN EXIT FUNCTION
                                 
                                  sBuf = SPACE$(lRes)                                      'allocate space
                                  GetFileVersionInfo zFile, lRes, lRes, BYVAL STRPTR(sBuf) 'get version info
                                  VerQueryValue BYVAL STRPTR(sBuf), "\", pFI, lRes         'get VS_FIXEDFILEINFO info
                                 
                                  'build answer
                                  sBuf  = FORMAT$(HIWRD(@pFI.dwFileVersionMS), "0") & "." & _  'Major part
                                          FORMAT$(LOWRD(@pFI.dwFileVersionMS), "00")& "."    'Minor part
                                 
                                  IF @pFI.dwFileVersionLS THEN   'rem out to get version only..
                                    sBuf  = sBuf & FORMAT$(HIWRD(@pFI.dwFileVersionLS), "00") & "." & _  'Major part
                                                   FORMAT$(LOWRD(@pFI.dwFileVersionLS), "0")             'Minor part
                                  END IF
                                 
                                  FUNCTION = sBuf 
                                   
                                END FUNCTION
                                 
                                '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                ' Get a files CRC32 sumcheck value.. by Semen Matusovski
                                '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                                SUB Crc32_BuildTable(sCrcTable AS STRING * 1024, BYVAL MagWord AS LONG)
                                 
                                      ! MOV EDI, sCrcTable
                                      ! MOV EDX, 0
                                 
                                 Crc32_BuildTable_Lb1:
                                      ! MOV EBX, EDX
                                      ! MOV ECX, 8
                                 
                                 Crc32_BuildTable_Lb2:
                                      ! MOV EAX, EBX
                                      ! AND EAX, 1
                                      ! JE Crc32_BuildTable_Lb3
                                      ! SHR EBX, 1
                                      ! MOV EAX, MagWord
                                      ! XOR EBX, EAX
                                      ! JMP Crc32_BuildTable_Lb4
                                 
                                 Crc32_BuildTable_Lb3:
                                      ! SHR EBX, 1
                                 
                                 Crc32_BuildTable_Lb4:
                                      ! DEC ECX
                                      ! JNZ Crc32_BuildTable_Lb2
                                      ! MOV [EDI], EBX
                                      ! ADD EDI, 4
                                      ! INC EDX
                                      ! CMP EDX, 255
                                      ! JLE Crc32_BuildTable_Lb1
                                 
                                   END SUB
                                 
                                FUNCTION Crc32_Calculate (BYVAL Address AS DWORD, BYVAL Length AS LONG, _
                                      sCrcTable AS STRING * 1024, BYVAL InitCrc AS LONG, BYVAL Inverse AS LONG) AS LONG
                                 
                                      ! MOV EBX, InitCrc
                                      ! MOV EDI, Address
                                      ! MOV ESI, EDI
                                      ! ADD ESI, Length
                                 
                                 Crc32_Calculate_Lb1:
                                      ! CMP EDI, ESI
                                      ! JGE  Crc32_Calculate_Lb2
                                 
                                      ! MOV EAX, 0
                                      ! MOV AL, [EDI]
                                      ! XOR EAX, EBX
                                      ! AND EAX, &HFF
                                 
                                      ! SHL EAX, 2
                                      ! add EaX, sCrcTable
                                      ! MOV EAX, [EAX]
                                      ! SHR EBX, 8
                                      ! AND EBX, &H00FFFFFF
                                      ! XOR EBX, EAX
                                      ! INC EDI
                                      ! JMP Crc32_Calculate_Lb1
                                 
                                  Crc32_Calculate_Lb2:
                                      ! CMP Inverse, 0
                                      ! JE  Crc32_Calculate_Lb3
                                      ! XOR EBX, &HFFFFFFFF
                                 
                                 Crc32_Calculate_Lb3:
                                      ! MOV FUNCTION, EBX
                                       
                                END FUNCTION


                                [This message has been edited by Bob Scott (edited February 04, 2003).]

                                Comment


                                • #17
                                  Another easy solution: use PEBundle (www.collakesoftware.com). while I'm not too happy with their support (compression on very large files doens't work, their reply was "use PECompact" another of their products) PECompact works nicely. Use the option to "always unpack" the packed files, then your app can access them and best of all they're always overwritten each time the app starts.

                                  Cheers

                                  ------------------
                                  Balt
                                  bi at inside dot net
                                  "It's not the end, not even the beginning of the end, but, it might be the end of the beginning!"

                                  Comment


                                  • #18
                                    Here's an improved CRC32 algorithm - standalone function, no tables required
                                    Code:
                                    FUNCTION CRC32(BYVAL dwOffset AS DWORD, BYVAL dwLen AS DWORD) AS DWORD
                                    #REGISTER NONE
                                     ! mov esi, dwOffset  ;esi = ptr to buffer
                                     ! mov edi, dwLen     ;edi = length of buffer
                                     ! cmp edi, 0
                                     ! je EndCRC
                                     ! mov ecx, -1        ;ecx = -1
                                     ! mov edx, ecx       ;edx = -1
                                     nextbyte:           ';next byte from butter
                                     ! xor eax, eax       ;eax = 0
                                     ! xor ebx, ebx       ;ebx = 0
                                     ! lodsb              ;get next byte
                                     ! xor al, cl         ;xor al with cl
                                     ! mov cl, ch         ;cl = ch
                                     ! mov ch, dl         ;ch = dl
                                     ! mov dl, dh         ;dl = dh
                                     ! mov dh, 8          ;dh = 8
                                     nextbit:            ';next bit in the byte
                                     ! shr bx, 1          ;shift bits in bx right by 1
                                     ! rcr ax, 1          ;(rotate through carry) bits in ax by 1
                                     ! jnc nocarry        ;jump to nocarry if carry flag not set
                                     ! xor ax, &h08320    ;xor ax with 33568
                                     ! xor bx, &h0EDB8    ;xor bx with 60856
                                     nocarry:            ';if carry flag wasn't set
                                     ! dec dh             ;dh = dh - 1
                                     ! jnz nextbit        ;if dh isnt zero, jump to nextbit
                                     ! xor ecx, eax       ;xor ecx with eax
                                     ! xor edx, ebx       ;xor edx with ebx
                                     ! dec edi            ;finished with that byte, decrement counter
                                     ! jnz nextbyte       ;if edi counter isnt at 0, jump to nextbyte
                                     ! not edx            ;invert edx bits - 1s complement
                                     ! not ecx            ;invert ecx bits - 1s complement
                                     ! mov eax, edx       ;mov edx into eax
                                     ! rol eax, 16        ;rotate bits in eax left by 16 places
                                     ! mov ax, cx         ;mov cx into ax
                                     ! mov FUNCTION, eax  ;crc32 result is in eax
                                    EndCRC:
                                    END FUNCTION
                                    Example usage, get CRC of a file...
                                    Code:
                                    DIM sDat AS STRING, dwCRC32 AS DWORD
                                    OPEN sFile FOR BINARY ACCESS READ LOCK SHARED AS #1
                                      GET$ #1, LOF(1), sDat
                                      dwCRC32 = CRC32(BYVAL STRPTR(sDat), BYVAL LOF(1))
                                    CLOSE #5

                                    ------------------
                                    The PowerBASIC Crypto Archives - My Email - What's mine is yours...
                                    -

                                    Comment


                                    • #19
                                      Originally posted by Wayne Diamond:
                                      Here's an improved CRC32 algorithm - standalone function, no tables required
                                      Wayne,

                                      Your solution is a cleaner approach however, on a test base of 500+ files
                                      Semen's table based solution seemed to be about twice as fast.

                                      Thanks for the input.

                                      ~Bob



                                      ------------------

                                      Comment


                                      • #20
                                        Yup, table-based ones are faster but have more overhead


                                        ------------------
                                        The PowerBASIC Crypto Archives - My Email - What's mine is yours...
                                        -

                                        Comment

                                        Working...
                                        X