WMQ Security Exit UserID/PWD passing issue - c

We are currently implementing a security exit for our SVRCONN channels. This exit will authenticate to our LDAP(AD or UNIX). Our current implementation of the exit is working for only connections coming from MQ EXPLORER.
When we write a code to connect and pass the userID/PWD, the security exit is picking up the user account login on the client machine.
Here is a snippet on how we connect to MQ
Code:
MQCNO ConnectOptions = {MQCNO_DEFAULT};
MQCD ClientConn = {MQCD_CLIENT_CONN_DEFAULT};
MQCSP mqCSP = {MQCSP_DEFAULT};
MQHCONN HConn;
MQLONG CompCode;
MQLONG Reason;
char QMName[MQ_Q_MGR_NAME_LENGTH+1]="QMGRNAME";
char channelName[MQ_CHANNEL_NAME_LENGTH+1]="MY_CHANNEL";
char hostname[1024]="MQSERVER(PORT)";
char UserId[32+1]="MyID";
char Password[32+1]="MyPWD";
strncpy(ClientConn.ConnectionName, hostname, MQ_CONN_NAME_LENGTH);
strncpy(ClientConn.ChannelName, channelName, MQ_CHANNEL_NAME_LENGTH);
mqCSP.AuthenticationType = MQCSP_AUTH_USER_ID_AND_PWD;
mqCSP.Version = MQCSP_VERSION_1;
mqCSP.CSPUserIdPtr = &UserId;
mqCSP.CSPUserIdOffset = 0;
mqCSP.CSPUserIdLength = strlen(UserId);
mqCSP.CSPPasswordPtr = &Password;
mqCSP.CSPPasswordOffset = 0;
mqCSP.CSPPasswordLength = strlen(Password);
ConnectOptions.SecurityParmsPtr = &mqCSP;
ConnectOptions.SecurityParmsOffset = 0;
ConnectOptions.ClientConnPtr = &ClientConn;
ConnectOptions.Version = MQCNO_VERSION_5;
MQCONNX (QMName, &ConnectOptions, &HConn, &CompCode, &Reason);
Then we use this code to retrieve the userID/PWD on the security exit.
Code:
memset (User, 0, pChDef->LongRemoteUserIdLength);
memset (Pass, 0, MQ_PASSWORD_LENGTH);
MakeCString(User,pChDef->LongRemoteUserIdPtr,pChDef->LongRemoteUserIdLength);
MakeCString(Pass,pChDef->RemotePassword,MQ_PASSWORD_LENGTH);
MQ Server->7.1.0.2

Why in the world would you re-invent the wheel when there is a cheap product that does authentication against an LDAP server? If you spent more than a day programming this, you instead could have purchased a license for MQ Authenticate Security Exit and done something else.
MQ only flows the password in plain text. Very easy to grab that password if you are familiar with MQ or just use WireShark since it knows/understands MQ protocol.
MQ uses 2 different styles of flowing the UserID and Password between a client and server: "old" and "new" style. Different platforms support different styles. Some support both directly and some support both indirectly and some platforms do a conversion and flow both at the same time (very weird!).
It is fine if all of your applications can be rebuilt to use MQCONNX by what if the application cannot be rebuilt? Or the application team does not want to do it or the source code is lost. What about 3rd party applications that do not support MQCONNX? What are you going to do?
What about MQ JNDI or CCDT (Client Channel Table Definitions) or the new "MQClient.ini" file? Have you thought about how you are going to handle these implementations?
You are going to easily spend 6 months (i.e. 1000 hours) building a working prototype that covers some of the issues I have highlighted. You are in for a world of hurt. I know, I've been there done that.

Related

LwIP Clilent can't establish a connection

I want to connect two F746ZG boards so that they can communicate via TCP. I am using the STM implementation of LwIP with the netconn API. The IP address is supplied via DHCP, but it is always the same address. Also, the address matches the expected value. The problem I am facing is that the client seemingly can't establish a connection. I am binding the connection to port 8880. Since I ran into this issue, I have written a debug client that should just periodically send a predefined message to a server. Here is the code for the client:
static void tcpecho_client_thread(void const *arg)
{
struct netconn *xNetConn = NULL;
err_t bind_err, connect_err;
char* b_data = "OK"; // Data to be sent
uint16_t b_len = sizeof ( b_data );
IP4_ADDR(&local_ip, IP_ADDR0_CLIENT, IP_ADDR1_CLIENT, IP_ADDR2_CLIENT, IP_ADDR3_CLIENT);
IP4_ADDR(&pc_ip, IP_ADDR0_PC, IP_ADDR0_PC, IP_ADDR2_PC, IP_ADDR3_PC);
xNetConn = netconn_new ( NETCONN_TCP );
if (xNetConn != NULL){
bind_err = netconn_bind ( xNetConn, &local_ip, TCP_PORT_NETCONN );
if(bind_err == ERR_OK){
// Try to connect to server
for(;;){
connect_err = netconn_connect ( xNetConn, &pc_ip, TCP_PORT_NETCONN);
if (connect_err == ERR_OK){
// We are connected
while(1){
BSP_LED_On(LED1);
netconn_write(xNetConn, b_data, b_len, NETCONN_COPY);
vTaskDelay(1000); // To see the result easily in Comm Operator
}
}
}
}else{
// Failed to bind the connection
BSP_LED_On(LED3);
}
}else{
// Failed to allocate a new connection
BSP_LED_On(LED3);
}
}
When I debug this, netconn_connect never manages to actually connect to something. Since I am able to ping the board and get a response, I am confused, what is going wrong here. I have tried to use Hercules to set up a TCP server on my PC so that the board can connect to that, but that also doesn't work. Using Wireshark, I can see the responses to my ping command coming in, but I don't see anything that would indicate the board trying to connect to my PC.
I have tested the corresponding server on the second board, but that runs fine. I can connect to it with Hercules and send data, so I doubt there is anything fundamentally wrong with the LwIP stack.
What I could guess is that I messed up the netconn_bind, I am not 100% sure what IP you are supposed to bind the connection to. The way it currently is, is how I read the documentation. For the server, I have bound it to IP_ADDR_ANY. Besides that, my implementation mostly matches with the examples you can find online (e.g. LwIP Wiki).
I have figured out the problem. After I delete the netconn_bind call, everything works fine for me.

How to register a SIP account with a specify network interface

I am using Pjsip library to register a Sip account to Sip server
/* Register to SIP server by creating SIP account. */
{
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
cfg.id = pj_str("sip:" SIP_USER "#" SIP_DOMAIN);
cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
cfg.cred_count = 1;
cfg.cred_info[0].realm = pj_str(SIP_DOMAIN);
cfg.cred_info[0].scheme = pj_str("digest");
cfg.cred_info[0].username = pj_str(SIP_USER);
cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
cfg.cred_info[0].data = pj_str(SIP_PASSWD);
status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
if (status != PJ_SUCCESS) error_exit("Error adding account", status);
}
This working fine when my board only has one network interface, but when i run it on a new board which has many network interface, it always register to Server via interface have smalless IP address value. I read in this link: https://trac.pjsip.org/repos/wiki/FAQ#multihomed And realize that Pjsip always chooses a network interface to register by its algorithm. And i tried to bind my application to a newtork interface too like this: https://unix.stackexchange.com/questions/210982/bind-unix-program-to-specific-network-interface but it not work too. I need to choose network interface manually in the code, how can i do it ?
Search for parameters named bound_addr in pjsip configuration - there should be (unless something changed with updates) one in transport configuration and one in rtp configuration. This is binding by interface address, not interface name, but it might be a starting point for modifications if necessary.

BlueNRG Bluetooth: read central device name

I'm using the STM BlueNRG-MS chip on my peripheral device and after connection I'd like to read the name of the connected central device (android phone).
I thought I can do this directly in my user_notify routine which is registered as hci callback
/* Initialize the Host-Controller Interface */
hci_init(user_notify, NULL);
So on the EVT_LE_CONN_COMPLETE event, I take the provided handle for the central device and I use aci_gatt_read_using_charac_uuid() to read what I thought is the characteristic with the device name (uuid 0x2a00).
case EVT_LE_META_EVENT:
{
evt_le_meta_event *evt = (void *)event_pckt->data;
switch(evt->subevent){
case EVT_LE_CONN_COMPLETE:
{
evt_le_connection_complete *cc = (void *)evt->data;
GAP_ConnectionComplete_CB(cc->peer_bdaddr, cc->handle);
uint16_t uuid = 0x2a00;
resp = aci_gatt_read_using_charac_uuid(cc->handle, 0, 1, UUID_TYPE_16, (uint8_t*)&uuid);
LOG("GATT read status: %d", resp);
enqueEvent(EVENT_BLE_CONNECTED);
}
break;
}
}
Long story short, it doesn't work. First thing I'm not sure about is, what is the start_handle and end_handle parameter of aci_gatt_read_using_charac_uuid(), it returns ERR_INVALID_HCI_CMD_PARAMS.
Can someone shed some light here?
update
What also puzzles me is that the function aci_gatt_read_using_charac_uuid() is nowehere referenced in the BlueNRG-MS Programming Guidelines.
update2
I changed the function call to aci_gatt_read_using_charac_uuid(cc->handle, 0x0001, 0xffff, UUID_TYPE_16, (uint8_t*)&uuid); but I still get the ERR_INVALID_HCI_CMD_PARAMS. What which paramter could even be invalid? The uuid exists, I can read the device name if I use the BlueNRG GUI with a bluetooth dongle.
update3
Has anyone ever used this function or somehow managed to read a characteristic from a central device? I'd highly appreciate any help or hint.
Here you go, The BlueNRG-MS Bluetooth® LE stack application command interface (ACI) - User manual
page 75 - 4.6.25 Aci_Gatt_Read_Charac_Using_UUID()
and make sure you have called Aci_Gatt_Init()
The user manual is last revised July 2019, the document you link to is from 2018, don't know if this is why ?
The start_handle and end_handle is the range of handles in your service as pictured here -
Here is a discussion to the closest thing I could find to match your question.
As it turned out there are two bugs in the BlueNRG API.
In bluenrg_aci_const.h file the OCF code OCF_GATT_READ_USING_CHARAC_UUID shall be 0x119 instead of 0x109.
And in the implementation of the aci_gatt_read_using_charac_uuid() function, there is a missing setting on event:
rq.event = EVT_CMD_STATUS;
Patching them fixed the issue.

MQTT TLS session resumption in C

I'm using the Eclipse Paho MQTT C client to connect to a mosquitto broker with TLS using openssl. This is part of my code:
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_SSLOptions sslOptions = MQTTClient_SSLOptions_initializer;
MQTTClient_deliveryToken token;
int rc;
MQTTClient_create(&client, ADDRESS, CLIENTID,
MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
/* TLS */
sslOptions.enableServerCertAuth = 0;
sslOptions.trustStore = "ca_rsp.crt";
conn_opts.ssl = &sslOptions;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
Actually every time I reconnect to the broker, the client make a full handshake. I would like to use the TLS session resumption to reduce the overhead. I've search around the web but I haven't found any example of how o implement that in a simple way.
Any suggestion?
Thanks
This came up recently on the mosquitto dev mailing list here https://dev.eclipse.org/mhonarc/lists/mosquitto-dev/msg01606.html
The following excerpt seams to imply it may not be possible just yet with the code as it is.
How can I use Mosquitto / OpenSSL C API to leverage session tickets in an
MQTT C client ?
Not at the moment, this needs code changes that are a bit more
involved - it looks like we need to use SSL_set_session() to apply a
saved session to your client and SSL_CTX_sess_set_new_cb() to save the
session out.
Is there any way I could persist session tickets on the clients, so they
would remain valid across reboot ?
With the above changes, yes.
Make conn_opts.cleansession = 0;
Disabling the cleansession flag in PAHO-client programs enables session resumption.
I have already verified it with wireshark.
With session Resumption, 1st packet transmission
We can see 4 times communication between server and client in 1 image and even certificates are transferred.
With session Resumption ,screenshot taken for 2nd packet transmission
Observe both images carefully , there is only 3 times communication between server and client in2 image, hence the server negotiates not to perform full handshake.
Session resumption time limit is 7200 seconds.
But setting the cleansession flag to 1 will always perform full handshake which means no session resumption.
I feel it was a good decision taken by PAHO people who made clean session flag linked with session resumption because mosquitto client provided in github lacks this inbuilt feature of session resumption.
Go through the specification of MQTT v3.1.1
Or refer MQTT specification in their website

C HTTP Server & OpenSSL - Works fine for HTTP - Multiple/rapid/concurrent connections being dropped using HTTPS

I'm writing an HTTP server in C using sockets. It can listen on multiple ports and works on a 1-thread-per-port basis to run listening loops and each loop spawns another thread to deliver a response
The code works perfectly when delivering standard HTTP responses. I have it set up to respond with an HTML page with JavaScript code that just refreshes the browser repeatedly in order to stress test the server. I've tested this with my computer running as the server and 4 other devices spamming it with requests at the same time.
No crashes, no dropped connections and no memory leaks. CPU usage never jumps beyond 5% running on a 2.0 GHz Intel Core 2 Duo in HTTP mode with 4 devices spamming requests.
I just added OpenSSL yesterday so it can deliver secure responses over HTTPS. That went fairly smoothly as it seems that all I had to do with replace some standard socket calls with their OSSL counterparts for secure mode (based on the solution to this question: Turn a simple socket into an SSL socket).
There is one SSL context and SSL struct per connection. It does work but not very reliably. Again, each response happens on its own thread but multiple/rapid/concurrent requests in secure mode are getting dropped seemingly at random, though there are still no crashes or memory leaks in my code.
When a connection is dropped the browser will either say its waiting for a response that never happens (Chrome) or just says the connection was reset (Firefox).
For reference, here is the updated connection creation and closing code.
Connection creation code (main part of the listening loop):
// Note: sslCtx and sslConnection exist
// elsewhere in memory allocated specifically
// for each connection.
struct sockaddr_in clientAddr; // memset-ed to 0 before accept
int clientAddrLength = sizeof(clientAddr);
...
int clientSocketHandle = accept(serverSocketHandle, (struct sockaddr *)&clientAddr, &clientAddrLength);
...
if (useSSL)
{
int use_cert, use_privateKey, accept_result;
sslCtx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_set_options(sslCtx, SSL_OP_SINGLE_DH_USE);
use_cert = SSL_CTX_use_certificate_file(sslCtx, sslCertificatePath , SSL_FILETYPE_PEM);
use_privateKey = SSL_CTX_use_PrivateKey_file(sslCtx, sslCertificatePath , SSL_FILETYPE_PEM);
sslConnection = SSL_new(sslCtx);
SSL_set_fd(sslConnection, clientSocketHandle);
accept_result = SSL_accept(sslConnection);
}
... // Do other things and spawn request handling thread
Connection closing code:
int recvResult = 0;
if (!useSSL)
{
shutdown(clientSocketHandle, SHUT_WR);
while (TRUE)
{
recvResult = recv(clientSocketHandle, NULL, 0, 0);
if (recvResult <= 0) break;
}
}
else
{
SSL_shutdown(sslConnection);
while (TRUE)
{
recvResult = SSL_read(sslConnection, NULL, 0);
if (recvResult <= 0) break;
}
SSL_free(sslConnection);
SSL_CTX_free(sslCtx);
}
closesocket(clientSocketHandle);
Again, this works 100% perfect for HTTP responses. What could be going wrong for HTTPS responses?
Update
I've updated the code with OpenSSL callbacks for mutli-threaded environments and the server is slightly more reliable using code from an answer to this question: OpenSSL and multi-threads.
I wrote a small command line program to spam the server with HTTPS requests and it is not dropping any connections with 5 multiple instances of it running at the same time. Multiple instances of Firefox also appear not to be dropping any connections.
What is interesting however is that connections are still being dropped with modern WebKit-based browsers. Chrome starts to drop connections at under 30 seconds of spamming, Safari on an iPhone 4 (iOS 5.1) rarely makes it past 3 refreshes before saying the connection was lost, but Safari on an iPad 2 (iOS 5.0) seems to cope the longest but ultimately ends up dropping connections as well.
You should call SSL_accept() in your request handling thread. This will allow your listening thread to process the TCP accept/listen queue more quickly, and reduce the chance of new connections getting a RESET from the TCP stack because of a full accept/listen queue.
SSL handshake is compute intensive. I would guess that your spammer is probably not using SSL session cache, so this causes your server to use the maximum amount of CPU. This will cause it to be CPU starved in regards to servicing the other connections, or new incoming connections.

Resources