Help with gpgme_passphrase_cb_t - gnupg

I'm working with GPGME...I need an example on use of gpgme_passphrase_cb_t and gpgme_set_passphrase_cb function because I don't understand how to create a gpgme_passphrase_cb_t.

This is the code from gpgme++ that wraps the callback-based interface into a C++ interface:
The interface:
class PassphraseProvider {
public:
virtual ~PassphraseProvider() {}
virtual char * getPassphrase( const char * useridHint,
const char * description,
bool previousWasBad,
bool & canceled ) = 0;
};
The function is supposed to display description as a prompt, and return the passphrase entered (the buffer must be malloc()ed). It may also set canceled to true to indicate that the user aborted. The parameters useridHint and previousWasBad are just additional information.
And this this the generic callback:
// Code taken from gpgme++, license: LGPLv2+
static
gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, const char * desc,
int prev_was_bad, int fd ) {
PassphraseProvider * provider = static_cast<PassphraseProvider*>( opaque );
bool canceled = false;
gpgme_error_t err = GPG_ERR_NO_ERROR;
char * passphrase = provider ? provider->getPassphrase( uid_hint, desc, prev_was_bad, canceled ) : 0 ;
if ( canceled )
err = make_error( GPG_ERR_CANCELED );
else
if ( passphrase && *passphrase ) {
size_t passphrase_length = std::strlen( passphrase );
size_t written = 0;
do {
#ifdef HAVE_GPGME_IO_READWRITE
ssize_t now_written = gpgme_io_write( fd, passphrase + written, passphrase_length - written );
#else
ssize_t now_written = write( fd, passphrase + written, passphrase_length - written );
#endif
if ( now_written < 0 ) {
err = make_err_from_syserror();
break;
}
written += now_written;
} while ( written < passphrase_length );
}
free( passphrase );
#ifdef HAVE_GPGME_IO_READWRITE
gpgme_io_write( fd, "\n", 1 );
#else
write( fd, "\n", 1 );
#endif
return err;
}
Given an implementation pp of the PassphraseProvider interface, you'd tie everything together like this:
gpgme_set_passphrase_cb( ctx, &passphrase_callback, pp );

Related

Electric UI example ESP32 websockets example code issue

This is the example code given for Electric UI's ESP32 websockets intergration.
// This example was written with the ESP8266 and ESP32 as the target hardware.
// Connects to a wifi access point and runs a websockets server as a transport for eUI.
// The ws path is hinted to the UI over the serial connection which ruggedises connection discovery.
// Base wifi libraries from the ESP library pack
#include "WiFi.h"
#include "WiFiMulti.h"
#include "WiFiClientSecure.h"
// Websockets library https://github.com/Links2004/arduinoWebSockets
#include "WebSocketsServer.h"
#include "electricui.h"
#define LED_PIN LED_BUILTIN
// Define default network credentials
char * wifi_ssid = "ssid";
char * wifi_pass = "password";
uint8_t ws_connected = 0; //state indication
uint8_t ws_port = 80;
char ws_path[] = "ws(s)://255.255.255.255:81";
// Simple variables to modify the LED behaviour
uint8_t blink_enable = 1; //if the blinker should be running
uint8_t led_state = 0; //track if the LED is illuminated
uint16_t glow_time = 200; //in milliseconds
// Keep track of when the light turns on or off
uint32_t led_timer = 0;
//example variables
uint8_t example_uint8 = 21;
uint16_t example_uint16 = 321;
uint32_t example_uint32 = 654321;
float example_float = 3.141592;
char demo_string[] = "ESP32 Test Board";
eui_message_t dev_msg_store[] = {
EUI_UINT8( "wsc", ws_connected),
EUI_CHAR_ARRAY( "ws", ws_path ),
EUI_UINT8( "led_blink", blink_enable ),
EUI_UINT8( "led_state", led_state ),
EUI_UINT16( "lit_time", glow_time ),
EUI_UINT8( "ui8", example_uint8 ),
EUI_UINT16( "i16", example_uint16 ),
EUI_UINT32( "i32", example_uint32 ),
EUI_FLOAT( "fPI", example_float ),
EUI_CHAR_ARRAY_RO( "name", demo_string ),
};
WiFiMulti WiFiMulti;
WebSocketsServer webSocket = WebSocketsServer(ws_port);
void tx_putc(uint8_t *data, uint16_t len);
void ws_tx_putc(uint8_t *data, uint16_t len);
eui_interface_t comm_links[] = {
EUI_INTERFACE(&tx_putc),
EUI_INTERFACE(&ws_tx_putc),
};
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
uint8_t * iter = payload;
uint8_t * end = payload + length;
switch(type)
{
case WStype_DISCONNECTED:
ws_connected = 2;
break;
case WStype_CONNECTED:
ws_connected = 3;
break;
case WStype_TEXT:
// send data to all connected clients
// webSocket.broadcastTXT("message here");
break;
case WStype_BIN:
while( iter < end )
{
eui_parse(*iter++, &comm_links[1]);
}
break;
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
ws_connected = 4;
break;
}
}
void wifi_handle()
{
if( WiFiMulti.run() == WL_CONNECTED )
{
//we have a wifi connection
if(!ws_connected)
{
webSocket.begin();
webSocket.onEvent(webSocketEvent);
ws_connected = 1;
// The hint is formatted like ws://255.255.255.255:81
memset( ws_path, 0, sizeof(ws_path) ); //clear the string first
snprintf(ws_path, sizeof(ws_path), "ws://%s:%d", WiFi.localIP().toString().c_str(), ws_port);
glow_time = 200;
// Using Arduino Strings
// String ws_path_string = "ws://" + WiFi.localIP().toString().c_str() + ":" + String(ws_port);
// ws_path_string.toCharArray(ws_path, sizeof(ws_path));
}
else
{
webSocket.loop();
}
}
else
{
//no connection, try again later
ws_connected = 0;
}
}
void eui_callback( uint8_t message )
{
switch(message)
{
case EUI_CB_TRACKED:
// UI recieved a tracked message ID and has completed processing
break;
case EUI_CB_UNTRACKED:
{
// UI passed in an untracked message ID
// Grab parts of the inbound packet which are are useful
eui_header_t header = comm_links[0].packet.header;
uint8_t *name_rx = comm_links[0].packet.id_in;
void *payload = comm_links[0].packet.data_in;
// See if the inbound packet name matches our intended variable
if( strcmp( (char *)name_rx, "talk" ) == 0 )
{
webSocket.broadcastTXT("hello over websockets");
glow_time = 50;
}
}
break;
case EUI_CB_PARSE_FAIL:
break;
}
}
void setup()
{
Serial.begin(115200);
pinMode( LED_BUILTIN, OUTPUT );
//eUI setup
comm_links[0].interface_cb = &eui_callback;
eui_setup_interfaces(comm_links, 2);
EUI_TRACK(dev_msg_store);
eui_setup_identifier("esp32", 5);
WiFiMulti.addAP(wifi_ssid, wifi_pass);
led_timer = millis();
}
void loop()
{
wifi_handle();
while(Serial.available() > 0)
{
eui_parse(Serial.read(), &comm_links[0]);
}
if( blink_enable )
{
// Check if the LED has been on for the configured duration
if( millis() - led_timer >= glow_time )
{
led_state = !led_state; //invert led state
led_timer = millis();
}
}
digitalWrite( LED_PIN, led_state ); //update the LED to match the intended state
}
void tx_putc( uint8_t *data, uint16_t len )
{
Serial.write( data, len );
}
void ws_tx_putc( uint8_t *data, uint16_t len )
{
webSocket.broadcastBIN( data, len);
}
When I enter my SSID and Password the serial monitor just displays:
E (2462) wifi:Association refused temporarily, comeback time 200 mSec
However the LED is blinking as it should.... The Electric UI shows no devices found....

Browse LDAP servers in the domain

I am following this guide.
I used the following code to display LDAP servers in the domain:
#include <dns_sd.h>
#include <stdio.h>
#include <pthread.h>
void ResolveCallBack(DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
const char *fullname,
const char *hosttarget,
uint16_t port, /* In network byte order */
uint16_t txtLen,
const unsigned char *txtRecord,
void *context) {
}
void BrowserCallBack(DNSServiceRef inServiceRef,
DNSServiceFlags inFlags,
uint32_t inIFI,
DNSServiceErrorType inError,
const char* inName,
const char* inType,
const char* inDomain,
void* inContext) {
DNSServiceErrorType err = DNSServiceResolve(&inServiceRef,
0, // Indicate it's a shared connection.
inIFI,
inName,
inType,
inDomain,
ResolveCallBack,
NULL);
printf("DNSServiceResolve err = %x, name = %s, type=%s, domain=%s\n",
err, inName, inType, inDomain);
}
int main() {
DNSServiceRef ServiceRef;
DNSServiceErrorType err = DNSServiceBrowse(&ServiceRef, // Receives reference to Bonjour browser object.
kDNSServiceFlagsDefault, // Indicate it's a shared connection.
kDNSServiceInterfaceIndexAny, // Browse on all network interfaces.
"_ldap._tcp", // Browse for service types.
NULL, // Browse on the default domain (e.g. local.).
BrowserCallBack, // Callback function when Bonjour events occur.
NULL); // Callback context.
printf("err = 0x%x\n", err);
int sockfd = DNSServiceRefSockFD(ServiceRef);
printf("sockfd = %d\n", sockfd);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
fd_set descriptors;
FD_ZERO(&descriptors);
FD_SET(sockfd, &descriptors);
int r = select(sockfd + 1, &descriptors, NULL, NULL, &timeout);
printf("r = %d\n", r);
fflush(stdout);
if (r > 0) {
if (FD_ISSET(sockfd, &descriptors)) {
// This function will call the appropiate callback to process the
// event, in this case the BrowseReply static method.
err = DNSServiceProcessResult(ServiceRef);
if (err != kDNSServiceErr_NoError) {
printf("Error on process an event in event loop, e = 0x%x\n", err);
}
}
} else if (r == -1) {
printf("The select() call failed");
}
return 0;
}
However, this didn't give me any LDAP server.
Any Help on this?
Thanks in advance
N.B:
This command returns results:
$nslookup -type=any _ldap._tcp
So there is LDAP servers in the domain.
When I tried "_http._tcp" as the registration type this returns
results.
Operating system is Mac OS X 10.9.

Cast a (void const *x) to a (unsigned char const *y)

I'm going through a source code analyzing its implementations where I have a method defined :
unsigned int rs_calc_weak_sum(void const *p, int len) {
unsigned char const *buf = (unsigned char const *) p;
}
What type of parameter should be passed into this method??
please help me.
thanks.
Any pointer can be passed to a void * parameter. What 'should' be passed, depends on what the code does with that parameter.
char array[12] = "Hello World";
unsigned in res = 0;
res = rs_calc_weak_sum(array, 12);
#include <stdio.h>
int main ( void )
{
char filename[] = "file.txt";
FILE *file = fopen ( filename, "r" );
if (file != NULL) {
char line [1000];
while(fgets(line,sizeof line,file)!= NULL) /* read a line from a file */ {
res = rs_calc_weak_sum(line, 1000);
}
fclose(file);
}
else {
perror(filename); //print the error message on stderr.
}
return 0;
}

Find out if UNC path is pointing to local machine

Is there any simple way to tell if UNC path points to a local machine.
I found the following question SO
Is there any WIN32 API that will do the same?
#include <windows.h>
#include <WinSock.h>
#include <string>
#include <algorithm>
#pragma comment(lib, "wsock32.lib")
using namespace std;
std::wstring ExtractHostName( const std::wstring &share )
{
if (share.size() < 3 )
return L"";
size_t pos = share.find( L"\\", 2 );
wstring server = ( pos != string::npos ) ? share.substr( 2, pos - 2 ) : share.substr( 2 );
transform( server.begin(),server.end(), server.begin(), tolower);
return server;
}
bool IsIP( const std::wstring &server )
{
size_t invalid = server.find_first_not_of( L"0123456789." );
bool fIsIP = ( invalid == string::npos );
return fIsIP;
}
bool IsLocalIP( const std::wstring &ipToCheck )
{
if ( ipToCheck == L"127.0.0.1" )
return true;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 1, 1 );
if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )
return false;
bool fIsLocal = false;
char hostName[255];
if( gethostname ( hostName, sizeof(hostName)) == 0 )
{
PHOSTENT hostinfo;
if(( hostinfo = gethostbyname(hostName)) != NULL )
{
for (int i = 0; hostinfo->h_addr_list[i]; i++)
{
char *ip = inet_ntoa(*( struct in_addr *)hostinfo->h_addr_list[i]);
wchar_t wcIP[100]={0};
::MultiByteToWideChar(CP_ACP, 0, ip, -1, wcIP, _countof(wcIP));
if (ipToCheck == wcIP)
{
fIsLocal = true;
break;
}
}
}
}
WSACleanup();
return fIsLocal;
}
bool IsLocalHost( const std::wstring &server )
{
if (server == L"localhost")
return true;
bool fIsLocalHost = false;
wchar_t buffer[MAX_PATH]={0};
DWORD dwSize = _countof(buffer);
BOOL fRet = GetComputerName( buffer, &dwSize );
transform( buffer, buffer + dwSize, buffer, tolower);
fIsLocalHost = ( server == buffer );
return fIsLocalHost;
}
bool ShareIsLocal( const std::wstring &share )
{
wstring server = ExtractHostName( share );
bool fIsIp = IsIP( server );
if ( fIsIp )
return IsLocalIP( server );
else
return IsLocalHost( server );
}

How do I correctly call LsaLogonUser for an interactive logon?

I'm trying to use LsaLogonUser to create an interactive logon session, but it always returns STATUS_INVALID_INFO_CLASS (0xc0000003). From what I have found in searching online, the memory layout of the KERB_INTERACTIVE_LOGON structure is tricky, but I'm pretty sure I've done that right.
I've also tried using MSV1.0 instead of Kerberos, with MSV1_0_INTERACTIVE_LOGON for the authentication structure and MSV1_0_PACKAGE_NAME as the package name, but that fails with STATUS_BAD_VALIDATION_CLASS (0xc00000a7).
Can anyone tell what I'm doing wrong here? Here's the code, with most of the error handling stripped. Clearly this isn't production-quality; I'm just trying to get a working sample.
// see below for definitions of these
size_t wcsByteLen( const wchar_t* str );
void InitUnicodeString( UNICODE_STRING& str, const wchar_t* value, BYTE* buffer, size_t& offset );
int main( int argc, char * argv[] )
{
// connect to the LSA
HANDLE lsa;
LsaConnectUntrusted( &lsa );
const wchar_t* domain = L"mydomain";
const wchar_t* user = L"someuser";
const wchar_t* password = L"scaryplaintextpassword";
// prepare the authentication info
ULONG authInfoSize = sizeof(KERB_INTERACTIVE_LOGON) +
wcsByteLen( domain ) + wcsByteLen( user ) + wcsByteLen( password );
BYTE* authInfoBuf = new BYTE[authInfoSize];
KERB_INTERACTIVE_LOGON* authInfo = (KERB_INTERACTIVE_LOGON*)authInfoBuf;
authInfo->MessageType = KerbInteractiveLogon;
size_t offset = sizeof(KERB_INTERACTIVE_LOGON);
InitUnicodeString( authInfo->LogonDomainName, domain, authInfoBuf, offset );
InitUnicodeString( authInfo->UserName, user, authInfoBuf, offset );
InitUnicodeString( authInfo->Password, password, authInfoBuf, offset );
// find the Kerberos security package
char packageNameRaw[] = MICROSOFT_KERBEROS_NAME_A;
LSA_STRING packageName;
packageName.Buffer = packageNameRaw;
packageName.Length = packageName.MaximumLength = (USHORT)strlen( packageName.Buffer );
ULONG packageId;
LsaLookupAuthenticationPackage( lsa, &packageName, &packageId );
// create a dummy origin and token source
LSA_STRING origin = {};
origin.Buffer = _strdup( "TestAppFoo" );
origin.Length = (USHORT)strlen( origin.Buffer );
origin.MaximumLength = origin.Length;
TOKEN_SOURCE source = {};
strcpy( source.SourceName, "foobar" );
AllocateLocallyUniqueId( &source.SourceIdentifier );
void* profileBuffer;
DWORD profileBufLen;
LUID luid;
HANDLE token;
QUOTA_LIMITS qlimits;
NTSTATUS subStatus;
NTSTATUS status = LsaLogonUser( lsa, &origin, Interactive, packageId,
&authInfo, authInfoSize, 0, &source, &profileBuffer, &profileBufLen,
&luid, &token, &qlimits, &subStatus );
if( status != ERROR_SUCCESS )
{
ULONG err = LsaNtStatusToWinError( status );
printf( "LsaLogonUser failed: %x\n", status );
return 1;
}
}
size_t wcsByteLen( const wchar_t* str )
{
return wcslen( str ) * sizeof(wchar_t);
}
void InitUnicodeString( UNICODE_STRING& str, const wchar_t* value,
BYTE* buffer, size_t& offset )
{
size_t size = wcsByteLen( value );
str.Length = str.MaximumLength = (USHORT)size;
str.Buffer = (PWSTR)(buffer + offset);
memcpy( str.Buffer, value, size );
offset += size;
}
You goofed up on one of the parameters to LsaLogonUser(); instead of &authInfo you should pass just authInfo. Happens to everyone :)

Resources