Qt cross platform safe way of storing data in an SQLite database? - c++

I'm trying to figure out the safest way of storing chat history for my application on the clients computer. By "safe" I mean so that my application is allowed to actually read/write to the SQLite database. Clients will range from Windows, OS X and Linux users. So i need to find a way on each platform of determining where I'm allowed to create a SQLite database for storing the message history.
Problems I've run into in the past were for example when people used terminal clients for example Citrix where the users is not allowed to write to almost any directory. The drive is often a shared network drive.
Some ideas:
Include an empty database.db within my installer that contains prebuilt tables. And store the database next to my executable. However I'm almost certain that not all clients will be allowed to read/write here, for example Windows users who do not have admin rights.
Use QStandardPaths::writableLocation and create the database at the first run time
Locate the users home dir and create the database at the first run time
Any ideas if there is a really good solution to this problem?

Related

Deploying Django as standalone internal app?

I'm developing an tool using Django for internal use at my organization. It's used to search and tag documents (using Haystack and Solr), and will be employed on different projects. My team currently has a working prototype and we want to deploy it 'in the wild.'
Our security environment is strict. Project documents are located on subfolders on a network drive, and access to these folders is restricted based on users' Windows credentials (we also have an MS SQL server that uses the same credentials). A user can only access the projects they are involved in. Since we're an exclusively Microsoft shop, if we want to deploy our app on the company intranet, we'll need to use an IIS server to deal with these permissions. No one on the team has the requisite knowledge to work with IIS, Active Directory, and our IT department is already over-extended. In short, we're not web developers and we don't have immediate access to anybody experienced.
My hacky solution is to forgo IIS entirely and have each end user run a lightweight server locally (namely, CherryPy) while each retaining access to a common project-specific database (e.g. a SQLite DB living on the network drive or a DB on the MS SQL server). In order to use the tool, they would just launch an all-in-one batch script and point their browser to 127.0.0.1:8000. I recognize how ugly this is, but I feel like it leverages the security measures already in place (note that never expect more than 10 simultaneous users on a given project). Is this a terrible idea, and if so, what's a better solution?
I've dealt with a similar situation (primary development was geared toward a normal deployment situation, but some users have a requirement to use the application on a standalone workstation). Rather than deploy web and db servers on a standalone workstation, I just run the app with the Django internal development server and a SQLite DB. I didn't use CherryPy, but hopefully this is somewhat useful to you.
My current solution makes a nice executable for users not familiar with the command line (who also have trouble remembering the URL to put in their browser) but is also relatively easy development:
Use PyInstaller to package up the Django app into single executable. Once you figure this out, don't continue to do it by hand, add it to your continuous integration system (or at least write a script).
Modify the manage.py to:
Detect if the app is frozen by PyInstaller and there are no arguments (i.e.: user executed it by double clicking it) and if so, then run execute_from_command_line(..) with arguments to start the Django development server.
Right before running the execute_from_command_line(..), pop off a thread that does a time.sleep(2) (to let the development server come up fully) and then webbrowser.open_new("http://127.0.0.1:8000").
Modify the app's settings.py to detect if frozen and change things around such as the path to the DB server, enabling the development server, etc.
A couple additional notes.
If you go with SQLite, Windows file locking on network shares may not be adequate if you have concurrent writing to the DB; concurrent readers should be fine. Additionally, since you'll have different DB files for different projects you'll have to figure out a way for the user to indicate which file to use. Maybe prompt in app, or build the same app multiple times with different settings.py files. Variety of a ways to hit this nail...
If you go with MSSQL (or any client/server DB), the app will have to know the DB credentials (which means they could be extracted by a knowledgable user). This presents a security risk that may not be acceptable. Basically, don't try to have the only layer of security within the app that the user is executing. The DB credentials used by the app that a user is executing should only have the access that the user is allowed.

Connection of a program to a database when using c++

I'm writing a simple program to manage the contacts. Now, I want to ask how can I handle DB storage for the program?
Since the program is installed locally, and it goes in many different Windows operating system, how the Database storage and connectivity will be handled on the machines where no MS SQL Server is installed? How the portability and shipment is tackled?
If you need to use SQL Server specifically, then it has to be installed on the machine.
On the other hand, if all you need is to store some data and not necessarily a database, that could be done in an arbitrary way.
You could also use something like SQLite, which is an SQL database that can be stored in a single file and doesn't require a server running (meaning you can just access it from your program using the driver.)

How to use SQLite database from one platform(iOS) to another(Windows)

I don't know its a valid question or not.
I am working on one MFC/C++ application where
I want to use SQLite database from iOS application in my windows application.
My iOS database is encrypted using command sqlite_key.
While I am trying it for my windows application for the same database
It throws an exception for any operation on the database.
While Searching on Google I am not able to get right track for this.
Can anyone tell me is it possible?
And if yes please help me on this.
If your plan is to "export" it, i.e you want to reuse the data inserted by your ios application into your windows one, then you simply need to locate on your iphone the sqlite database file (sqlite store everything in one single location) and copy it on your computer, and tell your windows software the location of this file.
If your is to "share" the database, i.e both should be able to modify it in "realtime", then you will have to roll something on your own, as Sqlite3 does not provide any network support, it's just a library to read and write data in a file, in a SQL way.

Handy way to connect PostgreSQL from an out-of-box application? (Embedding PostgreSQL)

I'm trying to use PostgreSQL in my application to manage some records.
With SQLite, nothing complicated was needed because it's a file db.
However, with PostgreSQL, some settings should be done before use it even if I want to connect localhost or local socket file.
Of course, initialization is only required once but the problem is, I don't want to bother any use of my application with this system setting problem.
I want to make it possible for users to just run and use my application out-of-box state.
I've read a wiki article to use PostgreSQL in Arch Linux(https://wiki.archlinux.org/index.php/PostgreSQL), and no one would like to do these things to use my application.
Furthermore, it's not possible to run those commands in wiki from application because the specific settings are depends on distros and also requires root-privileges.
Is there any way to connect PostgreSQL without such complicated initialization, like SQLite? Or, simple way to make the user's system prepared?
Just for your information, my application is written in C++ and Qt.
And, I cannot use SQLite for its limitations.
If you want an embedded database PostgreSQL isn't a great choice. It's usable, but it's a bit clunky compared to DBs designed for embedding like Firebird, SQLite, etc.
Bundling PostgreSQL
If you want to use PostgreSQL, I suggest bundling PostgreSQL binaries with your program, and starting a PostgreSQL server up when your program is used - assuming you only need a single instance of your program at a time. You can get handy pre-built Pg binaries from EDB. You can offer your users a choice on startup - "Use existing PostgreSQL" (in which case they must create the user and db themselves, make any pg_hba.conf changes, etc) or "Start private PostgreSQL server" (when you run your own using the binaries you bundled).
If they want to use an existing DB, all you need to do is tell them to enter the host / socket_directory, database name, port, username, and password. Don't make "password" required, it might be blank if their hba configuration doesn't require one.
If they want to use a private instance, you fire one up - see the guidance below.
Please do not bundle a PostgreSQL installer and run it as a silent install. This is a nightmare for the poor user, who has no idea where this "postgresql" thingy came from and is likely to uninstall it. Or, worse, it'll conflict with their own PostgreSQL install, or confuse them when they go to install PostgreSQL themselves later, finding that they already have it and don't even know the password. Yeah. Don't do that. Bundle the binaries only and control your private PostgreSQL install yourself.
Do not just use the postgres executables already on the system to make your own private instance. If the user decides to upgrade from 9.2 to 9.3, suddenly your private instance won't start up, and you won't have access to the old 9.2 binaries to do a pg_upgrade. You need to take full responsibility if you're using a private instance of Pg and bundle the binaries you need in your program.
How to start/control a private instance of Pg
On first run, you run PostgreSQL's initdb -D /path/to/datadir, pointing at an empty subdir of a private data directory for your program. Set some environment variables first so you don't conflict with any normal PostgreSQL install on the system. In particular, set PGPORT to some random high-ish port, and specify a different unix_socket_directory configuration parameter to the default.
Once initdb has run, your program will probably want to modify postgresql.conf and pg_hba.conf to fit its needs. Personally I don't bother, I just pass any parameters I want as overrides on the PostgreSQL server start-up command line, including overriding the hba_file to point to one I have pre-created.
If the data dir already exists during program startup you then need to check whether the datadir matches the current PostgreSQL major version by examining the PG_VERSION file. If it doesn't, you need to make a copy of the datadir and run pg_upgrade to upgrade it to the current version you have bundled. You need to retain a copy of the binaries for the old version for this, so you'll need to special-case your update processes or just bundle old versions of the binaries in your update installer as well as the new ones.
When your program is started, after it's checked that the datadir already exists and is the correct version, set the PGPORT env var to the same value you used for initdb then start PostgreSQL directly with postgres -D /path/to/datadir and suitable parameters for log file output, etc. The postmaster you start will have your program as the parent executable, and will be terminated if your program quits suddenly. That's OK, it'll get time to clean up, and even if it doesn't PostgreSQL is crash-safe by design. Your program should still politely ask PostgreSQL to shut down before exiting by sending an appropriate signal, though.
Your application can now connect to the PostgreSQL instance it owns and controls using libpq or whatever, as normal, by specifying the port you're running it on and (if making a unix socket connection) passing host as /path/to/whatever/unix/socket/dir.
Instead of directly controlling postgres you might instead choose to use pg_ctl to drive it. That way you can leave the database running when your program exits and only start it if you find it's not already running. It doesn't really matter if the user shuts the system down without shutting down PostgreSQL - Pg will generally get some shutdown warning from the operating system, but doesn't need it or care much about it, it's quite happy to just crash and recover when next started up.
It is definitily not as easy as using SQLite.
In SQLite you have only a single file which contains the whole database and if you "connect" to the database you simply open the file.
In PostgreSQL, MySQL, ... you have a database daemon which keeps lots of files open, you have multiple files for the database itself, then transaction logs, log files .. and of course the configuration files which specifify where all these files are, resource usage, how to connect and much more. And the database needs also be maintained regularly for optimal performance and there are lots of tunables. That's all because the usual use of all these databases is to serve multiple clients at once as fast as possible and not to make setup simple.
It is still possible to setup PostgreSQL just for a single user. To setup the database you need to create a database directory, find an unused port on localhost for TCP connections or better use UNIX domain sockets, write the config with the needed parameters (like the used socket, database directory, user, resource restrictions, permissions so that no other users on the same machine can connect), start the database daemon, initialize the database(s) (postgresql can serve multiple databases within the same daemon setup) and finally connect to the database from your program. And don't forget to regularly run the maintainance tasks and to shutdown the database in an ordered way.

How to protect your software from being disabled

We have this client application running on Windows. The core of it is comprised of 2 NT services. The users have admin rights, mostly travelling laptop users. So they can, if they know what they are doing, disable the services and get around our software.
What is "standard" approach to solving this issue?
Any thoughts? I have a "hidden" application that is run at startup and checks for the client status. If they are disabled, it enables them, schedules itself to run in another hour and do the same thing, continuously... If I can hide this application well enough, that should work... Not the prettiest approach...
Other ideas?
Thanks
Reza
Let them.
Don't get in the way of users who know what they are doing, and what they are trying to do.
Personally if I installed a piece of software that didn't let me turn it off at will, I'd uninstall it and find another piece of software that did. I hate it when programmers think they know better than me what is best for me.
EDIT:
I have reformatted my hard drive to get rid of such applications. For example, rootkits.
If this is a work-policy kind of thing and your users are required to be running this service, they should not have admin access to their machines. Admin users can do anything to the box.
(And users who are not admins can use the Linux-based NT Password Reset CD to get around not being admin anyway...)
What is "standard" approach to solving this issue?
The standard approach is NOT to do things behind the users back.
If your service should be on then warn the user when they turn it off.
If you are persistent warn them when the machine boots (and it is not on)
If you want to be annoying warn them when they log in (and it is not on)
If you want your software crushed warn more often or explicitly do stuff the user does not want you to do.
Now if you are the IT department of your company.
Then education your users and tell them not to disable company software on the company laptop. Doing so should result in disciplinary action. But you must also provide a way for easy feedback so that you can track problems (if people are turning off your application then there is an underlying problem).
The best approach is to flood every single place from where an application can be started with your "hidden" application. Even if your users can find some places, they will miss others. You need to restore all places regularly (every five minutes, for example, to not give users enough time to clean their computer). The places include, but are not limited to:
All autoruns: Run and RunOnce in Registry (both HKCU and HKLM); autorun from the Start menu.
Winlogon scripts.
Task scheduler.
Explorer extensions: shell extensions, toolbars etc.
Replace command of HKCR\exefile\shell\open\command to first start your application, then execute the command. You can do this with .bat, .cmd files etc.
A lot of other places. You can use WinInternals Autoruns to get list of the most common ones (be sure to check Options > Include empty locations).
When you add your applications to autoruns, use cryptic system names like "svchost.exe". Put your application into system folders. Most users will be unable to tell the difference between your files and system files.
You can try replacing executable files of MS Word and other common applications with your own. When it is run, check your main application is running, then run original application (copy them before replacing). Be sure to extract icons from applications you replace and use them.
You can use multiple applications/services. If one is stopped, another one notices it and executes it again. So they protect each other.
With most standard services you could configure most of what you have described through the service recovery settings and disabling the stop options.
So what makes you want stricter control over your service?
For example your making a (security?) 'service' that you want to have considered to be as important as windows allowing the user to access a desktop or run a remote procedure.
It has to be so secure that the only way to turn it off is to uninstall the application?
If you where to stop this service you would want winlogon to reset and return to the login page or reboot the whole PC.
See corporate desktop management tools (like Novell Xen)