Store data in GridFS(MongoDB) using stream in PHP. - encryption

I need to store encrypted files into GridFS using PHP.
So far I've found the following way:
Open the file (fopen)
Apply a encryption filter (stream_filter_append)
Write the encrypted data in a new temporary file (fwrite)
Use MongoGridFS::put() to store the encrypted file into GridFS.
Remove the temporary file
This approach as the inconvenient to go with a temporary file which can lead to a big lack of performance when dealing with huge files.
Is there any way to get a “writeable” stream in gridFS in order to merge step 3 and 4 of my above scenario and avoid the temporary file?
In another words, is there any equivalent to MongoGridFSFile::getResource but for “write” purpose?

Related

Prevent easy downloading of mp3s that play on mp3 players?

I have mp3 players set up on my site to play mp3s. At the moment, users can easily look through the source, run a search for "mp3" and download all of the music on my site. I know it's virtually impossible to completely prevent a determined user from downloading the music but I want to make it harder for the average user. Is there any way I can obfuscate the links to the mp3s?
Relevant site: http://boyceavenue.com/music
You did not specify the language you are using. To expand upon what Marc B wrote, I would recommend using the PHP http_send_file command along with the checksum of the file.
To send the file, use the following:
$filename = "/absolute/or/relative/path/to/file.ext";
$mime_type = "audio/mpeg"; // See note below
http_send_content_disposition($filename, true);
http_send_content_type($mime_type);
http_throttle(0.1, 2048);
http_send_file($filename);
If you are serving up multiple types of files using PHP 5.3.0 or later, you could determine the mimetype this way:
$filename = "/absolute/or/relative/path/to/file.ext";
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $filename);
finfo_close($finfo);
Calculating the checksum is simple enough. Just use md5_file.
So, what can you do with the checksum?
Well, you could create an array of checksums and filenames that cross-reference each other. That is, you include the checksum in the links to the file, but have a little routine that looks up the checksum and delivers the mp3 file. You also could do this in a database. You also could do like some apps that store files in a directory structure based on their checksums (music/3/3a/song.mp3 with a checksum of 3a62f6 or whatever).
If you don't care about the filenames being mangled, you could save the files with a checksum for the filename. That could be done at upload time (if your files are being uploaded) or through a batch script (using the CLI).
Another thing you should do is to put a default document (index.php or whatever) that tells people to look elsewhere. Also disable browsing the directory. If only a very small number of people will need access, you could also throw a password on the directory, thus requiring a login to access the files.

what is the best way to upload a csv file into a MS SQL table?

Several approaches:
Use SQL Bulk Import Stored Proc and call the stored proc with the file path
Use SqlBulkCopy in System.Data.SqlClient dll
Read the file line by line and then insert into a table row by row
Any other ways?
Which one is best? I just want the user to select a file from asp.net webpage. And then click on Upload button to store the file in DB.
Secondly, do I need to move the file in server's memory before the file is copied into db table?
The DB won't know of the file because everything should be decoupled and layered. Saving the file to some shared location adds overhead and tidy ups etc
Yes
Surely you want this to be an atomic operation. 10k rows would be 10 round trips with a client side transaction running. If not atomic, then you'd need staging tables and tidy ups
Parse in c#, send to the DB with a table valued parameter. Otherwise, probably nothing same and/or realistic...

Replacing SQLite database while accessing it

I am completely new to SQLite and I intend to use it in a M2M / client-server environment where a database is generated on the server, sent to the client as a file and used on the client for data lookup.
The question is: can I replace the whole database file while the client is using it at the same time?
The question may sound silly but the client is a Linux thin client and to replace the database file a temporary file would be renamed to the final file name. In Linux, a program which has still open the older version of the file will still access the older data since the old file is preserved by the OS until all file handles have been closed. Only new open()s will access the new version of the file.
So, in short:
client randomly accesses the SQLite database
a new version of the database is received from the server and written to a temporary file
the temporary file is renamed to the SQLite database file
I know it is a very specific question, but maybe someone can tell me if this would be a problem for SQLite or if there are similar methods to replace a database while the client is running. I do not want to send a bunch of SQL statements from the server to the client to update the database.
No, you cannot just replace an open SQLite3 DB file. SQLite will keep using the same file descriptor (or handle in Windows-speak), unless you close and re-open your database. More specifically:
Deleting and replacing an open file is either useless (Linux) or impossible (Windows). SQLite will never get to see the contents of the new file at all.
Overwriting an SQLite3 DB file is a recipe for data corruption. From the SQLite3 documentation:
Likewise, if a rogue process opens a
database file or journal and writes
malformed data into the middle of it,
then the database will become corrupt.
Arbitrarily overwriting the contents of the DB file can cause a whole pile of issues:
If you are very lucky it will just cause DB errors, forcing you to reopen the database anyway.
Depending on how you use the data, your application might just crash and burn.
Your application may try to apply an existing journal on the new file. Sounds painful? It is!
If you are really unlucky, the user will just get back invalid results from any queries.
The best way to deal with this would be a proper client-server implementation where the client DB file is updated from data coming from the server. In the long run that would allow for far more flexibility, while also reducing the bandwidth requirements by sending updates, rather than the whole file.
If that is not possible, you should update the client DB file in three discrete steps:
Send a message to the client application to close the DB. This allows the application to commit any changes, remove any journal files and clean-up its internal state.
Replace/Overwrite the file.
Send a message to the client application to re-open the DB. You would have to setup all prepared statements again, though.
If you do not want to close the DB file for some reason, then you should have your application - or even a separate process - update the original DB file using the new file as input. The SQLite3 backup API might be of interest to you in that case.

Extend file upload class to use encryption

Is there an easy/straightforward way to extend the file upload class to encrypt files that are being uploaded? Not just encrypting the filename, but rather the data in the file itself.
I'm using mcrypt for db encryption, and would prefer to use the same for file encryption.
Looking through the Upload.php library, I don't see an obvious place where the uploaded file is read which is where I assume I'd shim in the encryption.
Any help/advice would be appreciated.
edit:
What I'm thinking is that somewhere in do_upload() (I'm thinking file_temp) the file gets encrypted before being moved (not copied!) into its final destination. However, I don't see anywhere in Upload.php where the code is working with any of the files' data outside of filename, size, type, etc. Does this approach make sense?
Rather than encrypting just the upload, use HTTPS/SSL to encrypt the entire connection between the client and server.
I decided to forgo modifying the upload class. What I did was after the file was uploaded, open the file, encrypt it, and write it out again.
$f=file_get_contents(BASE_PATH.$fileFullPath) or die ('<script>window.parent.transUpdateFail(\'no gfc'.$fileFullPath.'\');</script>');
$encf=$this->encrypt->encode($f,$this->e_key) or die ('<script>window.parent.transUpdateFail(\'no encrypt\');</script>');
$nf=fopen(BASE_PATH.$fileFullPath,"r+") or die ('<script>window.parent.transUpdateFail(\'no open '.$fileFullPath.'\');</script>');
$fw=fwrite($nf,$encf) or die ('<script>window.parent.transUpdateFail(\'no fwrite\');</script>');
fclose($nf);

Using an encrypted file securely

I'm writing an application with a dBASE database file in Borland Delphi 7.
Note: I think this question is file-security related and you can forget the dBASE thing (consider it as a TXT file) in this question.
The database must be accessed just by the application. Then it must be encrypted. Unfortunately dBASE doesn't support any password mechanism and i had to encrypt the file by myself (and i also HAVE to use dBASE)
What approach do you suggest to secure the database file?
The simple one is:
Encrypting the database file and placing it near beside the application EXE file.
When the application runs, it should decrypt the file (with a hard-coded password) and copy the result to a temporary file that has DeleteOnClose and NoSharingPermission flags.
When Closing, application should encrypt the temp dBASE file and replaces the old encrypted file with the new one.
I think this is a fair secure approach. But it have two big problems:
With an undelete tool the user can restore and access to the deleted temp file.
Worse: When application is running, if the system rebooted suddenly the DeleteOnClose flag fails and the temp file remains on hard disk and user can access it.
Is there any solution for, at least, the second part?
Is there any other solution?
You could also try to create a TrueCrypt file-based containter, mount it, and then put the dBase file inside the mounted encrypted volume. TrueCrypt is free (in both senses) and it's accessible via command line parameters from your application (mount before start, unmount before quit).
Depending on what you're doing with the database, you may be able to get away with just decrypting the records you actually need. For example, you could build indexes based on hash codes (rather than real data); this would reduce seeks into the database to a smaller set of data. Each record in the subset would have to be decrypted, but this could be a lot better than decrypting the entire database.

Resources