SQLCipher: verify key against open database - c

Is it possible to check if a given key is a correct decryption for already open and unlocked database?
#define SQLITE_HAS_CODEC
#include <sqlcipher/sqlite3.h>
#include <assert.h>
sqlite3 *open_db(void)
{
sqlite3 *dbh;
sqlite3_open_v2("test.db", &dbh, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
sqlite3_key(dbh, "xxxx", 4);
return dbh;
}
int key_is_valid(sqlite3 *dbh, const char *key)
{
/* ??? */
return 1;
}
int main(int argc, char *argv[])
{
sqlite3 *dbh = open_db();
assert(key_is_valid(dbh, "test"));
assert(!key_is_valid(dbh, "foobar"));
return 0;
}
I know I could store decryption key passed to sqlite3_key for later verification, but I'd like to avoid it.
The reason I need to do this is that I want to allow users to change password, and before that I want them to provide old one.

You can verify the password provided is valid following the keying of the database by attempting to read from the sqlite_master table:
SELECT count(*) FROM sqlite_master;
The library requires the correct password is provided before changing the password. Once you have properly keyed the database, you can change the password using the following API:
int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey);

Related

How to set sub table name while using tdengine's schemaless insert

I know that tdengine support schemaless insert. And there are three line protocols that tdengine supports. The follow is the sample code from taosdata's website schemaless chapeter.
#include <stdlib.h>
#include <stdio.h>
#include <taos.h>
int main() {
const char* host = "127.0.0.1";
const char* user = "root";
const char* passwd = "taosdata";
// connect to server
TAOS* taos = taos_connect(host, user, passwd, "test", 0);
// prepare the line string
char* lines1[] = {
"stg,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000",
"stg,t1=4i64,t3=\"t4\",t2=5f64,t4=5f64 c1=3i64,c3=L\"passitagin\",c2=true,c4=5f64,c5=5f64 1626006833641000000"
};
// schema-less insert
TAOS_RES* res = taos_schemaless_insert(taos, lines1, 2, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANO_SECONDS);
if (taos_errno(res) != 0) {
printf("failed to insert schema-less data, reason: %s\n", taos_errstr(res));
}
taos_free_result(res);
// close the connection
taos_close(taos);
return (code);
}
I know this will create the stable "stg" and create substable for the incoming data record. I want to ask can I control the subtable's name and how to configure the name?
No, you cannot configure subtable name in TDengine database
Please refer this link for how subtable name is generated: https://docs.tdengine.com/reference/schemaless/#main-processing-logic-for-schemaless-writing

Using SSH authentification with libgit2

I am trying to authenticate against a git server with libgit2 using SSH keys.
So far, this is working for URLs like ssh://myuser#host.domain:1234/dirs/repo.git, where my application accepts the URL as an argument.
However, if I remove the username from the URL (i.e. ssh://host.domain:1234/dirs/repo.git) the connection fails, even if I set the user name programmatically (see below).
Consider the following MCVE for a program that checks whether a certain repository is reachable (no error checks except for the necessary):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <git2.h>
#include <git2/sys/repository.h>
int my_cred_cb(git_cred **out, const char *url,
const char *username_from_url, unsigned int allowed_types, void *payload)
{
uid_t uid = geteuid(); // Get effective user ID
struct passwd* pw = getpwuid(uid); // Get password file entry
char privkeypath[strlen(pw->pw_dir) + 13];
strcpy(privkeypath, pw->pw_dir);
strcat(privkeypath, "/.ssh/id_rsa"); // "~user/.ssh/id_rsa"
char publkeypath[strlen(privkeypath) + 5];
strcpy(publkeypath, privkeypath);
strcat(publkeypath, ".pub"); // "~user/.ssh/id_rsa.pub"
const char* username = (username_from_url != NULL ? username_from_url : pw->pw_name);
printf("Using username: %s, priv key %s and publ key %s\n", username, privkeypath, publkeypath);
return git_cred_ssh_key_new(out, username, publkeypath, privkeypath, ""); // No passphrase for keys
}
int main(int argc, char** argv)
{
git_remote* remote = NULL;
git_repository* repo = NULL;
git_remote_callbacks cbs;
const git_error* err;
if (argc != 2) return EXIT_FAILURE;
git_libgit2_init();
git_repository_new(&repo);
git_remote_create_anonymous(&remote, repo, argv[1]);
git_remote_init_callbacks(&cbs, GIT_REMOTE_CALLBACKS_VERSION);
cbs.credentials = my_cred_cb;
if (git_remote_connect(remote, GIT_DIRECTION_FETCH, &cbs, NULL, NULL)) {
err = giterr_last();
printf ("Error %d: %s\n", err->klass, err->message);
return EXIT_FAILURE;
}
git_libgit2_shutdown();
printf("git repo exists and is reachable.\n");
}
This can be compiled with gcc -Wall -pedantic -std=c99 -o myapp main.c -lssh2 -lgit2, assuming the include and library paths are set properly.
Now consider the output for different URLs:
$ ./myapp ssh://myuser#host.domain:1234/dirs/repo.git
Using username: myuser, priv key /home/myuser/.ssh/id_rsa and publ key /home/myuser/.ssh/id_rsa.pub
git repo exists and is reachable.
And now the failing case:
$ ./myapp ssh://host.domain:1234/dirs/repo.git # Note the missing user name
Using username: myuser, priv key /home/myuser/.ssh/id_rsa and publ key /home/myuser/.ssh/id_rsa.pub
Error 23: callback returned unsupported credentials type
I do not understand why I receive this error, since I pass the exact same information to the library (why is it "unsupported credentials type" in the first place?).
Even worse, I usually use Host entries in my ~/.ssh/config, such that instead of putting host.domain:1234 I can simply use myhost (e.g. git clone ssh://myhost/dirs/repo.git works just fine). For my application, this is the output:
$ ./myapp ssh://myhost/dirs/repo.git
Error 12: failed to resolve address for myhost: Name or service not known
It looks like libgit2 does not configure libssh2 to read in the ssh-config. That's a related, yet probably a different problem. Still I feel these two problems belong together.
Summarizing my questions:
How do I pass the username to the git credentials programmatically (vs. in the URL)?
How do I tell libgit2 to retrieve information from my ssh-config before attempting to connect?
These really are two separate unrelated questions.
You should be checking the allowed_types parameter in your callback and only return a git_cred_ssh_key_new credential if it contains GIT_CREDTYPE_SSH_KEY. The backend is probably requesting a credential of type GIT_CREDTYPE_USERNAME because the URL doesn't have one. In that case you should be returning a credential created by git_cred_username_new. Your callback will be called twice, once to get the username, and a second time to create the ssh credential.
Reading config settings from your OpenSSH config file at ~/.ssh/config isn't supported by libgit2 because it isn't support by libssh2. If you want to read settings from there, you have to do it yourself.

GetAppliedGPOList and pGuidExtension value

I'm trying to use the GetAppliedGPOList function, but cannot find/understand what the pGuidExtension should be.
Here's the simple code so far:
#include <Windows.h>
#include <UserEnv.h>
int wmain(int argc, WCHAR *argv[])
{
//GetAppliedGPOList
DWORD flags = GPO_LIST_FLAG_MACHINE;
LPCWSTR machineName = NULL; //Local computer is used
PSID sidUser = NULL;
GUID *pGuidExtension; //What is the GUID of the extension?
PGROUP_POLICY_OBJECT *ppGPOList;
return 0;
}
Cannot run the function because I need to send that value.
Any example about the pGuidExtension value?
I did search here but found nothing about it.
Thank you.
The guids is listed at
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions
For example - Group Policy Client Side Extension List. The GetAppliedGPOList is looked under
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\{GuidExtension}
key

Getting the KVM VM domain name in a C program using libvirt API

I'm writing a C program and I'd like to get the KVM VM's domain name. Is there an easy way to do that? I have the VM id of the machine and can get a pointer to the virDomainInfo struct. I know I can do it with the command, virsh domname <id>, but I can't seem to find a libvirt API so I can do it programmatically. After some digging I found the struct info for the virDomain. Would it be an option to grab it from there?
struct _virDomain {
virObject object;
virConnectPtr conn; /* pointer back to the connection */
char *name; /* the domain external name */
int id; /* the domain ID */
unsigned char uuid[VIR_UUID_BUFLEN]; /* the domain unique identifier */
};
below is the code I'm using.
virConnectPtr conn = virConnectOpen(connString);
virDomainPtr domainPtr = virDomainLookupByID(conn, vmid);
Not sure where to go from here. Thanks in advance for any help.
Just browsing through the libvirt API I found virDomainGetName, which seems like it may be exactly what you want:
virDomainGetName
const char * virDomainGetName (virDomainPtr domain)
Get the public name for that domain
domain
a domain object Returns
a pointer to the name or NULL, the string need not be deallocated its lifetime will be the same as the domain object.
I through together some sample code:
int main(int argc, char **argv) {
virConnectPtr c;
virDomainPtr d;
char *name;
c = virConnectOpen(NULL);
d = virDomainLookupByID(c, 2);
name = virDomainGetName(d);
printf("name of domain %d is %s\n", 2, name);
return 0;
}

SQLite3: the database was created empty?

I'm trying to create a database with a table using sqlite3 on my C program, however the database is always created as empty, though it was created non-empty using the sqlite shell,
here is my code below:
int main(void)
{
printf("hello\n");
sqlite3 *sqdb;
sqlite3_initialize();
const char* db = "test";
sqlite3_open(db, &sqdb);
const char* stmt = "CREATE TABLE IF NOT EXISTS testtable(creationdate DATE, data VARCHAR);";
sqlite3_stmt *ppstmt;
if (sqlite3_prepare_v2(sqdb, stmt, -1, &ppstmt, 0)!=SQLITE_OK)printf("error!\n");
sqlite3_finalize(ppstmt);
getch();
return 0;
}
please help me to solve the problem.
sqlite3_prepare_v2() alone just compiles the SQL but does not run it. Call sqlite3_step() on the compiled statement to run it, or use sqlite3_exec() that combines prepare+step+finalize into one function call.
Try this:
int main(void)
{
printf("hello\n");
sqlite3 *sqdb;
int ret;
sqlite3_initialize();
const char* db = "test.sqlite3";
sqlite3_open(db, &sqdb);
const char* stmt = "CREATE TABLE IF NOT EXISTS testtable(creationdate DATE, data VARCHAR);";
sqlite3_stmt *ppstmt=NULL;
ret=sqlite3_exec(sqdb,stmt,0,0,0);
if(ret!=SQLITE_OK)printf("error!\n");
else printf("Table added\n");
sqlite3_finalize(ppstmt);
sqlite3_close(sqdb);
return 0;
}
Please do remember to close the DB after operation.

Resources