EXC_BAD_ACCESS While trying to access OS X Keychain - c

I wrote a sample code (with help received earlier) to add and retrieve a password from OS X keychain. I am able to successfully add the password but when I try to retrieve it I get a EXC_BAD_ACCESS (code=EXC_I386_GPFLT). I tried doing this two ways:
Using the SecItemCopyMatching API that uses a query based approach to access the keychain.
Using the SecKeychainFindGenericPassword.
The BAD ACCESS error happens only withe first approach, the second one succeeds. I am trying to use the first approach so that I can ensure that I am using the SecKeychainItemFreeContent to clean up once I am done.
Note - this is a sample code and hence I haven't put any checks for return values. Though I have been keeping an eye on them in the debugger and see no errors there.
#include <stdio.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
int main(int argc, const char * argv[])
{
char acc_name[20];
char password[20];
CFStringRef keys[3];
printf("Enter account name - ");
scanf("%s", acc_name);
printf("\nEnter password - ");
scanf("%s", password);
keys[0] = kSecClass;
keys[1] = kSecAttrAccount;
keys[2] = kSecValueData;
CFTypeRef values[3];
values[0] = kSecClassGenericPassword;
values[1] = CFStringCreateWithCString(kCFAllocatorDefault, acc_name, kCFStringEncodingUTF8);
values[2] = CFStringCreateWithCString(kCFAllocatorDefault, password, kCFStringEncodingUTF8);
CFDictionaryRef query;
query = CFDictionaryCreate(kCFAllocatorDefault, (const void**) keys, (const void**) values, 3, NULL, NULL);
OSStatus result = SecItemAdd(query, NULL);
printf("%d\n", result);
printf("Retrieve\n");
SecKeychainItemRef pitem = NULL;
SecKeychainItemRef kch_ref = NULL;
CFStringRef qkeys[6];
qkeys[0] = kSecClass;
qkeys[1] = kSecAttrAccount;
qkeys[2] = kSecMatchLimit;
qkeys[3] = kSecReturnAttributes;
qkeys[4] = kSecReturnData;
qkeys[5] = kSecReturnRef;
CFTypeRef qvalues[6];
qvalues[0] = kSecClassGenericPassword;
qvalues[1] = CFStringCreateWithCString(kCFAllocatorDefault, acc_name, kCFStringEncodingUTF8);
qvalues[2] = kSecMatchLimitOne;
qvalues[3] = kCFBooleanTrue;
qvalues[4] = kCFBooleanTrue;
qvalues[5] = kCFBooleanTrue;
unsigned int plength = 0;
char *pdata = NULL;
unsigned int plength2 = 0;
void *pdata2 = NULL;
CFDictionaryRef extract_query = CFDictionaryCreate(kCFAllocatorDefault, (const void **)qkeys, (const void **)qvalues, 6, NULL, NULL);
result = SecItemCopyMatching(extract_query, (CFTypeRef *)&kch_ref);
SecKeychainItemCopyAttributesAndData(kch_ref, NULL, NULL, NULL, &plength2, &pdata2); // <-- EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
//result = SecKeychainFindGenericPassword(NULL, 0, NULL, (uint32)strlen(acc_name), acc_name, &plength, (void **)&pdata, &pitem);
if (result)
{
//return error;
}
printf("password - %s\n", pdata);
return 0;
}

You seem to be passing a bad parameter to SecKeychainItemCopyAttributesAndData.
In your query dictionary, you specify three different return types: kSecReturnAttributes, kSecReturnData, and kSecReturnRef. The documentation for SecItemCopyMatching has this to say:
Use the keys found in Item Return Result Keys to indicate whether you seek the item’s attributes, the item’s data, a reference to the data, a persistent reference to the data, or a combination of these. When you specify more than one return type, the search returns a dictionary containing each of the types you request. When your search allows multiple results, they’re all returned together in an array of items.
So, the type returned by SecItemCopyMatching (since you limit to one result) will be a CFDictionary containing the item data, item attributes and a reference to the item.
You then pass it to SecKeychainItemCopyAttributesAndData, but the documentation for the first parameter says:
itemRef
A reference to the keychain item from which you wish to retrieve data or attributes.
If you modify your query dictionary to only include the kSecReturnRef return type (removing kSecReturnAttributes and kSecReturnData), your code will work.
(Or, extract the reference from the dictionary that SecItemCopyMatching is returning and pass that to SecKeychainItemCopyAttributesAndData)

Related

why simple Vulkan fails at vkCreateInstance()?

I'm trying to vulkanize my life. so I can use Vulkan compute. But creating a simple instance fails every way I tried.
Here is the code :
#include <vulkan/vulkan.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
VkApplicationInfo vkAppInfo;
vkAppInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
vkAppInfo.apiVersion = VK_API_VERSION_1_0;
VkInstanceCreateInfo vkCreateInfo;
vkCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
vkCreateInfo.pApplicationInfo = &vkAppInfo;
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(&vkCreateInfo, NULL, &instance);
return -1;
if (result != VK_SUCCESS) {
return -2;
} else {
return -3;
}
return 0;
}
I tried Vulkan Tutorial (without the graphics function GLFW)
The problem here is that you assume the rest of the fields you do not fill out will be filled out somehow automatically with some valid data, but that is not the case. It will be filled with garbage. Don't forget this is a very general thing in C and C++: Every memory that is not explicitely initialized is just garbage.
I propose you write some wrapper functions for filling your Vulkan structs such as VkApplicationInfo. It could look like this:
VkApplicationInfo fill_app_info(const char* app_name, const char* app_version,
const char* engine_name, uint32_t engine_version,
uint32_t vk_api_version) {
VkApplicationInfo info;
info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
info.pNext = NULL;
info.pApplicationName = app_name;
info.applicationVersion = app_version;
info.pEngineName = engine_name;
info.engineVersion = engine_version;
info.apiVersion = vk_api_version;
return info;
}
This might seem not worth it for VkApplicationInfo, but there are Vulkan structures you will need more often.
Once you wrote the most verbose version of fill_app_info, you can use two powerful tools to make it even more easy for you: default parameters and overloading:
// This is even better: it has default parameters
VkApplicationInfo fill_app_info(const char* app_name, const char* app_version,
const char* engine_name = "MyEngine",
uint32_t engine_version = VK_MAKE_VERSION(1,0,0),
uint32_t vk_api_version = VK_API_VERSION_1_2) {
VkApplicationInfo info;
info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
info.pNext = NULL;
info.pApplicationName = app_name;
info.applicationVersion = app_version;
info.pEngineName = engine_name;
info.engineVersion = engine_version;
info.apiVersion = vk_api_version;
return info;
}
VkApplicationInfo fill_app_info(const char* app_name) {
// Call the other function
return fill_app_info(app_name, VK_MAKE_VERSION(1,0,0));
}
// Call function 1 with all parameters specified
VkApplicationInfo example1 = fill_app_info("MyApp", VK_MAKE_VERSION(1,0,0),
"MyCustomEngine1000", VK_MAKE_VERSION(1,0,6),
VK_API_VERSION_1_1);
// Call function 1 and use default parameters
VkApplicationInfo example2 = fill_app_info("MyApp", VK_MAKE_VERSION(1,0,0));
// Call function 2 and let it fill out everything but the app name
VkApplicationInfo example3 = fill_app_info("MyApp");
As you can see, example3 is created with only one argument specified. This makes your overall code much shorter if you create functions like this for all Vulkan structs. In Vulkan we often have the that we do need to fill out all members of the struct, even if some of the members are not really used. I would also suggest to enable validation layers to check if you use the API ccorrectly. Also, read the Vulkan docs. They tell you how to fill out every struct correctly: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkApplicationInfo.html

GCC C and passing integer to PostgreSQL

I know that there probably was plenty on that but after several days of searching I am unable to find how to do one simple passing of integer and char in one go to PostgreSQL from C under Linux.
In PHP it is easy, like 123, and in C using libpq it seem to be like something out of ordinary.
I had a look at PQexecParams but is seem to be not helping. Examples on the net are not helping as well and it seems to be an impossible mission.
Would someone be kind enough to translate this simple PHP statement to C and show me how to pass multiple vars of different types in one INSERT query.
col1 is INT
col2 is CHAR
$int1 = 1;
$char1 = 'text';
$query = "INSERT INTO table (col1, col2) values ('$int1',$char1)";
$result = ibase_query($query);
This would show what I am trying to do (please mind the code is very wrong):
void insert_CommsDb(PGconn *conn, PGresult *pgres, int csrv0) { const char * params[1];
params[0] = csrv0;
pgres = PQexecParams(conn, "INSERT INTO comms_db (srv0::int) values ($1)",
1,
NULL,
params,
1,
NULL,
0);
if (PQresultStatus(pgres) != PGRES_COMMAND_OK)
{
fprintf(stderr, "INSERT failed: %s", PQerrorMessage(conn));
exit_nicely(conn,pgres);
}
PQclear(pgres);
}
https://www.postgresql.org/docs/current/static/libpq-exec.html
As #joop commented above:
If the paramTypes argument is NULL, all the params are assumed to be strings.
So, you should transform your int argument to a string.
void insert_CommsDb(PGconn *conn, int csrv0)
{
PGresult *pgres;
char * params[1];
char buff[12];
sprintf(buff, "%d", csrv0);
params[0] = buff;
pgres = PQexecParams(conn
, "INSERT INTO comms_db (srv0::int) values ($1)" // The query (we dont need the cast here)
, 1 // number of params
, NULL // array with types, or NULL
, params // array with parameter values
, NULL // ARRAY with parameter lenghts
, NULL // array with per-param flags indicating binary/non binary
, 0 // set to 1 if we want BINARY results, 0 for txt
);
if (PQrresultStatus(pgres) != PGRES_COMMAND_OK)
{
fprintf(stderr, "INSERT failed: %s", PQerrorMessage(conn));
exit_nicely(conn,pgres);
}
PQclear(pgres);
}
wildplasser's answer shows the way in general.
Since you explicitly asked about several parameters, I'll add an example for that.
If you are not happy to convert integers to strings, the alternative would be to use the external binary format of the data type in question. That requires inside knowledge and probably reading the PostgreSQL source. For some data types, it can also depend on the hardware.
PGresult *res;
PGconn *conn;
Oid types[2];
char * values[2];
int lengths[2], formats[2];
int arg0;
/* connect to the database */
/*
* The first argument is in binary format.
* Apart from having to use the "external binary
* format" for the data, we have to specify
* type and length.
*/
arg0 = htonl(42); /* external binary format: network byte order */
types[0] = 23; /* OID of "int4" */
values[0] = (char *) &arg0;
lengths[0] = sizeof(int);
formats[0] = 1;
/* second argument is in text format */
types[1] = 0;
values[1] = "something";
lengths[1] = 0;
formats[1] = 0;
res = PQexecParams(
conn,
"INSERT INTO mytab (col1, col2) values ($1, $2)",
2,
types,
(const char * const *)values,
lengths,
formats,
0 /* results in text format */
);
I'd recommend that you use the text format for most data types.
The notable exception is bytea, where it usually is an advantage to use the binary format, as it saves space and CPU power. In this case, the external binary format is simply the bytes.
VS C++ not liking htonl(42):
arg0 = htonl(42); /* external binary format: network byte order */

Parse to integer with argp.h

I would like to be able to receive program arguments and options in my C program. The options should be treated as floats or ints. For some reason, I couldn't find good articles, tutorials, docs about argp.h. I started my implementation with the examples on the GNU Libc Manual, though unfortunately, it didn't get me to the solution.
Here is how I tried to solve the problem (example can be compiled, included every necessary line):
#include <stdlib.h>
#include <argp.h>
static char doc[] = "Doc";
static char args_doc[] = "ARG1";
static struct argp_option options[] = {
{"bool", 'b', 0, 0, "Simple boolean flag, works as I expected."},
{"int", 'i', 0, 0, "Would like to be able to parse options as --int=4 or -i 4."}, // but I can't
{0}
};
struct arguments {char *args[1]; int xbool, xint;};
static error_t
parse_opt (int key, char *arg, struct argp_state *state) {
struct arguments *arguments = state->input;
printf("key = %c, arg = %s\n", key, arg); // My attempt to understand the problem
//if (arg == NULL) return 0; // Prevents segfaults, in order to see how the args and keys change
switch (key) {
case 'b': arguments->xbool = 1; break;
case 'i': arguments->xint = (int) strtol(arg, NULL, 10); break;
case ARGP_KEY_ARG: if (state->arg_num >= 1) {argp_usage(state);} arguments->args[state->arg_num] = arg; break;
case ARGP_KEY_END: if (state->arg_num < 1) {argp_usage(state);} break;
default: return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = { options, parse_opt, args_doc, doc };
int main (int argc, char **argv) {
struct arguments arguments;
arguments.xbool = 0;
arguments.xint = 0;
argp_parse (&argp, argc, argv, 0, 0, &arguments);
printf("ARG1 = %s\nbool option = %s\nparsed int option = %d",
arguments.args[0], arguments.xbool ? "true" : "false", arguments.xint);
exit (0);
}
The simple boolean flag works, as expected, so ./myprogram.out myarg --bool and ./myprogram.out myarg -b changes the flag's value.
However, I can't seem to find a way to parse the arguments as integers or floating point numbers.
This it the output I get for ./a.out -b --int=2 myarg:
key = , arg = (null)
key = b, arg = (null)
./a.out: option '--int' doesn't allow an argument
Try `a.out --help' or `a.out --usage' for more information.
and for ./a.out -b --int 2 myarg I get a segmentation fault, as I try to parse a NULL: key = i, arg = (null). I added a NULL check, and this way I could see, that the option I would like to parse comes with a , key (expected to come with i).
key = i, arg = (null)
key = , arg = 2
I thought about using a library because the program needs to handle various float and int options, falling back to default values, and I've seen often that it's not recommended to roll your own argument and options parser. Based on the examples, argp.h looked promising, however I couldn't get it to work yet.
ps. I know that parsing directly to ints and floats are not part of argp, this is why I was (naively, it seems) trying to add it to the structures and parse_opt function.
As it turned out, there was an error with options[]. The third, const char *arg parameter in the argp_option struct must be provided, if the option has argument associated with it [source: GNU C: Argp Option Vectors].
static struct argp_option options[] = {
{"bool", 'b', 0, 0, "Simple boolean flag, works as I expected."},
{"int", 'i', "Numbah", 0, "Now everything works as expected, I get the correct key-value (key-arg) pair in the parse_opt function"},
{0}
};

Redland RDF libraries: why does parsing model from Turtle without base URI cause error?

Why does the following test produce an error? Does Redland's turtle parser insist on a base URI even if all actual URIs are absolute? (Apache Jena apparently does not.) And how could I find out more about what actually went wrong (i.e. what API call would return an error description, or similar)?
librdf_world *world = librdf_new_world();
librdf_world_open(world);
librdf_storage *storage = librdf_new_storage(world, "memory", NULL, NULL);
librdf_model *model = librdf_new_model(world, storage, NULL);
librdf_parser* parser = librdf_new_parser(world, NULL, "text/turtle", NULL);
librdf_uri *baseUri = NULL;
const char *turtle = "<http://example.com/SomeSubject> <http://example.com/SomePredicate> <http://example.com/SomeObject> .";
int error = librdf_parser_parse_string_into_model(parser, (const unsigned char *)turtle, baseUri, model);
A base URI is required because the parser says so using RAPTOR_SYNTAX_NEED_BASE_URI flag. It produces the error before even looking at the content in raptor_parser_parse_start().
If you know a real base URI is not needed, you can supply a dummy URI such as . instead:
librdf_uri *baseUri = librdf_new_uri(world, (const unsigned char *)".");
To enable better error reports, you should register a logger with librdf_world_set_logger() - the default logger just spits to stderr. Return non-0 from the logger function to signal you handler the message yourself. Example:
#include <librdf.h>
int customlogger(void *user_data, librdf_log_message *message) {
fputs("mad custom logger: ", stderr);
fputs(message->message, stderr);
fputs("\n", stderr);
return 1;
}
int main() {
librdf_world *world = librdf_new_world();
librdf_world_set_logger(world, /*user_data=*/ 0, customlogger);
librdf_world_open(world);
librdf_storage *storage = librdf_new_storage(world, "memory", NULL, NULL);
librdf_model *model = librdf_new_model(world, storage, NULL);
librdf_parser* parser = librdf_new_parser(world, NULL, "text/turtle", NULL);
librdf_uri *baseUri = NULL;
const char *turtle = "<http://example.com/SomeSubject> <http://example.com/SomePredicate> <http://example.com/SomeObject> .";
int error = librdf_parser_parse_string_into_model(parser, (const unsigned char *)turtle, baseUri, model);
}
Running this will result in
mad custom logger: Missing base URI for turtle parser
(For a real program, add some cleanup etc.)

Is my method of passing a struct as both value and reference correct?

I have looked at the examples of passing a struct by both value and reference. My code compiles but is not working as it should. I am using C to program a micro-controller so it is hard to check if it is working properly, but I am not getting the desired output.
So, as per instructions, I first define my structure:
struct package //define a structure type called package.
{
unsigned char
wavType,startFreq1,startFreq2,startFreq3,startFreq4,
stopFreq1,stopFreq2,
stopFreq3,stopFreq4,step,dura,amp,sett; //define bytes to use
};
In the main method I create an instance of it:
struct package p; //create a new instance of Package
Now I pass it by reference (pointer - because I'm using C) to a function:
getPackage(&p);
Within the function getpackage() I update the values of the respective elements of p:
getPackage(struct package *p) //Get data package
{
p->wavType = receive();
p->startFreq1 = receive();
p->startFreq2 = receive();
p->startFreq3 = receive();
p->startFreq4 = receive();
p->stopFreq1 = receive();
p->stopFreq2 = receive();
p->stopFreq3 = receive();
p->stopFreq4 = receive();
p->step = receive();
p->dura = receive();
p->amp = receive();
p->sett = receive();
}
This is the receive function:
unsigned char receive(void)
{
unsigned char dataR = 0x00;
for(signed char i = 0; i <=7 ;i++)
{
dataR |= PORTBbits.RB1 << i; //move the value on the data pin to a bit in dataR
}
return dataR;
}
QUESTION: Will this correctly update the bytes in the package p? Also, does package p need to be returned if I want to use it elsewhere? I ask this because....
I now pass the package p, by value, into another function using:
sendSine(p);
This function makes use of the value of the bytes in the package p:
void sendSine(struct package p)
{
dataL = p.startFreq1;
dataH = p.startFreq2;
send(dataL,dataH);
dataL = p.startFreq3;
dataH = p.startFreq4;
send(dataL,dataH);
}
I know the function send(dataL,dataH) is working because I have tested it by setting dataL and dataH by hand and I get the required result, so there must be an error along the way with the struct - I just cant figure out where... Can anyone help me with were it might be?
The receive function seems to be the procedure in question. Try writing a stub-replacement for receive, such as:
unsigned char receive(void)
{
unsigned char X = 'a';
// or whatever value you want to simulate as being received
return X;
}
and then try running your complete application, tf it works then go back and re-think your original receive per some of the comments that have already been made.

Resources