I'm trying to familiarise myself with the OpenSSL Diffie Hellman features and, in doing so, I've tried to create a simple programme which will generate two sets of Diffie Hellman private and public keys and then derive the shared secret. I have followed the Diffie Hellman tutorial on the OpenSSL wiki and I am able to generate the keys, however I am unable to derive the shared secret. My C++ (Linux) code is as follows:
#include <iostream>
#include <openssl/dh.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
int main(int argc, char** argv)
{
EVP_PKEY* params;
EVP_PKEY_CTX *kctx1, *kctx2, *dctx1, *dctx2;
unsigned char *skey1, *skey2;
size_t skeylen1, skeylen2;
EVP_PKEY *dh_1, *dh_2;
BIO* bio_out = NULL;
int result = 0;
ENGINE* eng;
BIO* fp = BIO_new_fp(stdout, BIO_NOCLOSE);
// Initalise Diffie Hellman PKEY for client 1
if(NULL == (dh_1 = EVP_PKEY_new())) {
std::cout << "error 1" << std::endl;
}
// Initalise Diffie Hellman PKEY for client 2
if(NULL == (dh_2 = EVP_PKEY_new())) {
std::cout << "error 2" << std::endl;
}
// Initalise Diffie Hellman parameter PKEY
if(NULL == (params = EVP_PKEY_new())) {
std::cout << "error 3" << std::endl;
}
// Set Diffie Hellman paramerers
if(1 != EVP_PKEY_set1_DH(params, DH_get_2048_256())) {
std::cout << "error 4" << std::endl;
}
// Initalise client 1 PKEY Context
if(!(kctx1 = EVP_PKEY_CTX_new(params, NULL))) {
std::cout << "error 5" << std::endl;
}
// Initalise client 2 PKEY Context
if(!(kctx2 = EVP_PKEY_CTX_new(params, NULL))) {
std::cout << "error 6" << std::endl;
}
if(!kctx1) {
std::cout << "error 7" << std::endl;
}
if(!kctx2) {
std::cout << "error 8" << std::endl;
}
// Initalise both contexts key generators
if(1 != EVP_PKEY_keygen_init(kctx1)) {
std::cout << "error 9" << std::endl;
}
if(1 != EVP_PKEY_keygen_init(kctx2)) {
std::cout << "error 10" << std::endl;
}
// Generate DH public and private keys for client 1
if(1 != EVP_PKEY_keygen(kctx1, &dh_1)) {
std::cout << "error 11" << std::endl;
}
// Generate DH public and private keys for client 2
if(1 != EVP_PKEY_keygen(kctx2, &dh_2)) {
std::cout << "error 12" << std::endl;
}
// EVP_PKEY_print_public(fp, dh_1, 3, NULL);
// EVP_PKEY_print_public(fp, dh_2, 3, NULL);
// Create key derivation context
if(NULL == (dctx1 = EVP_PKEY_CTX_new(dh_1, NULL))) {
std::cout << "error 13" << std::endl;
}
if(!dctx1) {
std::cout << "error 14" << std::endl;
}
// Initalise first key derivation context
if(1 != EVP_PKEY_derive_init(dctx1)) {
std::cout << "error 15" << std::endl;
}
if(1 != EVP_PKEY_check(dctx1)) {
std::cout << "error 16" << std::endl;
}
if(1 != EVP_PKEY_param_check(dctx1)) {
std::cout << "error 17" << std::endl;
}
// Set first key derivation context peer key to the second DH PKEY
if(1 != EVP_PKEY_derive_set_peer(dctx1, dh_2)) {
std::cout << "error 18" << std::endl;
}
if(1 != EVP_PKEY_public_check(dctx1)) {
std::cout << "error 19" << std::endl;
}
/* Determine buffer length */
if(EVP_PKEY_derive(dctx1, NULL, &skeylen1) <= 0) {
}
// Assign memory for shared key variable
skey1 = (unsigned char*)OPENSSL_malloc(skeylen1);
if(result = EVP_PKEY_derive(dctx1, skey1, &skeylen1) <= 0) {
std::cout << "Key: " << skey1 << std::endl;
for(int i = 0; i < skeylen1; i++) {
std::cout << std::hex << (unsigned int)skey1[i];
}
}
ERR_print_errors_fp(stdout);
std::cout << result << std::endl;
}
My main concerns are:
What do I need to do to derive the shared secret?
Do I need a new context for each key pair and key derivation?
Thanks!
EDIT:
I get the following errors and no shared key:
140690271102784:error:05079079:Diffie-Hellman routines:DH_check_ex:unable to check generator:../crypto/dh/dh_check.c:92:
140690271102784:error:05079076:Diffie-Hellman routines:DH_check_ex:check p not safe prime:../crypto/dh/dh_check.c:96:
140690271102784:error:0507B07B:Diffie-Hellman routines:DH_check_pub_key_ex:check pubkey too large:../crypto/dh/dh_check.c:190:
140690271102784:error:0507B07A:Diffie-Hellman routines:DH_check_pub_key_ex:check pubkey invalid:../crypto/dh/dh_check.c:192:
when I use
if(NULL == (dctx1 = EVP_PKEY_CTX_new(dh_1, NULL))) {
std::cout << "error 13" << std::endl;
}
and I get the following errors
error 16
error 19
Key: �ȭ��U
c0c8add7c4550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
139939742943040:error:060BA096:digital envelope routines:EVP_PKEY_check:operation not supported for this keytype:../crypto/evp/pmeth_gn.c:188:
139939742943040:error:0507C07D:Diffie-Hellman routines:dh_pkey_public_check:missing pubkey:../crypto/dh/dh_ameth.c:517:
139939742943040:error:05066064:Diffie-Hellman routines:compute_key:no private value:../crypto/dh/dh_key.c:183:
1
when I change "EVP_PKEY_CTX_new(dh_1, NULL)" to "EVP_PKEY_CTX_new(params, NULL)", like so:
if(NULL == (dctx1 = EVP_PKEY_CTX_new(params, NULL))) {
std::cout << "error 13" << std::endl;
}
The difference between these two variables is that "dh_1" stores a DH keypair, whereas "params" contains the DH parameters. It appears that the derivation context initalises to some extent with the latter, though it does not have a private and public key associated with it.
With the version of the code that you posted I got slightly different errors to you. I get the following output from your code (linked against OpenSSL 1.1.1):
error 16
error 17
140673674348352:error:060BA096:digital envelope routines:EVP_PKEY_check:operation not supported for this keytype:crypto/evp/pmeth_gn.c:187:
140673674348352:error:05079076:Diffie-Hellman routines:DH_check_ex:check p not safe prime:crypto/dh/dh_check.c:93:
0
The first "error 16" output is simply because OpenSSL does not currently support the EVP_PKEY_check() call for Diffie-Hellman keys. So this can be safely ignored.
The second "error 17" output (which is associated with the "check p not safe prime" error in the error queue) is more of an issue. This is because Diffie-Hellman keys come in two different varieties. By default OpenSSL uses PKCS#3 Diffie-Hellman keys. However it also supports X9.42 Diffie-Hellman keys. The function DH_get_2048_256() gives you a built-in set of parameters for X9.42 keys. However the function EVP_PKEY_set1_DH() expects the provided DH object to be a PKCS#3 key.
This actually looks like a bug in OpenSSL to me (EVP_PKEY_set1_DH() should really detect what type of key it is and do the right thing), so I have raised the following OpenSSL issue for this:
https://github.com/openssl/openssl/issues/10592
You can work around this by replacing the EVP_PKEY_set1_DH() call with one to EVP_PKEY_assign() instead and specify the type as EVP_PKEY_DHX as follows:
if(1 != EVP_PKEY_assign(params, EVP_PKEY_DHX, DH_get_2048_256())) {
std::cout << "error 4" << std::endl;
}
Alternatively you might just use PKCS#3 parameters instead.
Finally, the reason you get no shared secret derived is because you are only printing it if the EVP_PKEY_derive() call fails! It is actually succeeding!
I made the following changes to your code and it works for me:
--- derive.cpp 2019-12-09 11:11:15.493349734 +0000
+++ derive-new.cpp 2019-12-09 11:14:59.348715074 +0000
## -37,7 +37,7 ##
}
// Set Diffie Hellman paramerers
- if(1 != EVP_PKEY_set1_DH(params, DH_get_2048_256())) {
+ if(1 != EVP_PKEY_assign(params, EVP_PKEY_DHX, DH_get_2048_256())) {
std::cout << "error 4" << std::endl;
}
## -96,9 +96,11 ##
std::cout << "error 15" << std::endl;
}
+#if 0
if(1 != EVP_PKEY_check(dctx1)) {
std::cout << "error 16" << std::endl;
}
+#endif
if(1 != EVP_PKEY_param_check(dctx1)) {
std::cout << "error 17" << std::endl;
## -120,7 +122,7 ##
// Assign memory for shared key variable
skey1 = (unsigned char*)OPENSSL_malloc(skeylen1);
- if(result = EVP_PKEY_derive(dctx1, skey1, &skeylen1) <= 0) {
+ if((result = EVP_PKEY_derive(dctx1, skey1, &skeylen1)) > 0) {
std::cout << "Key: " << skey1 << std::endl;
for(int i = 0; i < skeylen1; i++) {
Above is Eliptic Curve Diffie and Hellman. A working example with OpenSSL 3 (none eliptic curve)
https://gist.github.com/digitalhuman/2a2b85d61672e4bf83596d41351723ba
Related
i'm trying to make a little program to my university that can change values in the memory of another process. With the exact address value that the Cheat Engine give me i can do this, but not ever the value is the same then my problem is with the memory pointers. In the following image i has the every offset that i found in the pointer scan map:
I already make a program but it not work and ever gives me 299 error code, i Run it as administrator. The code is the following:
#include <iostream>
#include <Windows.h>
#include <Psapi.h>
#include <TlHelp32.h>
#include <queue>
using namespace std;
int main() {
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(PROCESSENTRY32);
// Snapshot to list all process
HANDLE pHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (pHandlers == NULL) {
cout << "Error 1";
return 1;
}
// Listing process
if (Process32First(pHandlers, &pEntry)) {
while (Process32Next(pHandlers, &pEntry)) {
// Convert value to string
wstring wstr(pEntry.szExeFile);
string str(wstr.begin(), wstr.end());
// Check if is the process that i wan't
if (str == "Playgroundd.exe") {
MODULEENTRY32 mEntry;
mEntry.dwSize = sizeof(MODULEENTRY32);
// Snapshot to list all modules inside process
HANDLE mHandlers = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pEntry.th32ProcessID);
if (mHandlers == NULL) {
cout << "Error 2";
return 1;
}
// Usually the first process is the main module
if (Module32First(mHandlers, &mEntry)) {
// Convert the name to string
wstring wstrr(mEntry.szExePath);
string strr(wstrr.begin(), wstrr.end());
if (strr.find("Playgroundd.exe")) {
// Get the base address of module
DWORD moduleBaseAddress = (DWORD)mEntry.modBaseAddr;
// Append initial value
moduleBaseAddress += (DWORD)0x000000E8;
// Offsets defined
DWORD offsets[] = {0x88,0x98,0x90,0x20,0x10,0x48,0x904};
// Open process with the right process id
cout << "process id: " << pEntry.th32ProcessID << endl << endl;
HANDLE processHandler = OpenProcess(PROCESS_ALL_ACCESS, 0, pEntry.th32ProcessID);
if (processHandler == NULL) {
cout << "Can't open the process";
return 1;
}
// Sum offsets
for (int i = 0; i < 7;i++) {
moduleBaseAddress += offsets[i];
}
int receive = 0;
size_t bytesRead = 0;
bool resultStatus = ReadProcessMemory(processHandler,
(LPCVOID)moduleBaseAddress, &receive, sizeof(receive), &bytesRead);
cout << "result status :" << resultStatus << endl;
cout << "Received : " << receive << endl;
cout << "Bytes read : " << bytesRead << endl;
cout << "Possible error code : " << GetLastError() << endl;
}
else {
cout << "Can't find module";
return 1;
}
}
}
}
}
};
This is the output of the above program, the error code can be ignored if the result status be non-zero
result status :0
Received : 0
Bytes read : 0
Possible error code : 299
What i am doing wrong?
As pointed by the comment above, your calculation of the target address is questionable.
Your use of GetLastError is unsafe - you should call it immediately after FAILED call to ReadProcessMemory. However, in this case, cout << ... doesn't change that code, so you are OK.
According to docs
ERROR_PARTIAL_COPY
299 (0x12B)
Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
And this post states
ReadProcessMemory would return FALSE and GetLastError would return ERROR_PARTIAL_COPY when the copy hits a page fault.
I'm trying to use the following code to change the wall paper on a Windows 7 machine. I'm compiling with Multi Byte Character Set.
if(SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, L"c:\\temp\\extracted.png", SPIF_SENDCHANGE) != 0)
{
std::cout << "Success !" << std::endl;
}
else
{
std::cout << "Failure :(" << std::endl;
std::cout << "Error: " << GetLastError() << std::endl;
system("title :(");
}
I have no idea of why this is not working since it doesn't return an error code (GetLastError gives 0). No need to say that the wall paper remains unchanged.
EDIT: tried to change to this and to put a bmp file instead.
int error(0);
if(SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, L"c:\\temp\\extracted.bmp", SPIF_SENDCHANGE) != 0)
{
std::cout << "Success !" << std::endl;
}
else
{
error = GetLastError();
std::cout << "Failure :(" << std::endl;
std::cout << "Error: " << error << std::endl;
system("title :(");
}
system("pause");
Output in console is Failure :( followed by Error: 0
From the advice on the comments I abandoned ChangeParametersInfo and implemented this quick function I found. Worked instantly.
void SetWallpaper(LPCWSTR file)
{
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
IActiveDesktop* desktop;
HRESULT status = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&desktop);
WALLPAPEROPT wOption;
ZeroMemory(&wOption, sizeof(WALLPAPEROPT));
wOption.dwSize = sizeof(WALLPAPEROPT);
wOption.dwStyle = WPSTYLE_CENTER;
status = desktop->SetWallpaper(file, 0);
status = desktop->SetWallpaperOptions(&wOption, 0);
status = desktop->ApplyChanges(AD_APPLY_ALL);
desktop->Release();
CoUninitialize();
}
Usage
SetWallpaper(L"c:\\temp\\extracted.png");
This is so much easier than bothering with the old one. Still wondering why it wasn't giving an error. Hope this will help someone else.
Thanks for the advices everyone.
I was trying to apply an iteration to my leveldb file, but unfortunately I couldn't get the result. The problem that I'm facing is a segmentation fault in using the pointer of the iterator. I used gdb And I got that the problem is in the line
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
(I added before some values to this file /tem/userDb , and the add is working good .)
#include <assert.h>
#include <leveldb/db.h>
#include <iostream>
#include <sstream>
using namespace std;
void iteration(leveldb::DB* db)
{
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next())
{
cout << "key :" << it->key().ToString() << " : "
<< "value:" << it - > value().ToString() << endl;
}
if (false == it->status().ok())
{
cerr << "An error was found during the scan" << endl;
cerr << it->status().ToString() << endl;
}
delete it;
}
int main(int argc, char *argv[])
{
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
// erase error if the database exists
options.error_if_exists = true;
leveldb::Status s = leveldb::DB::Open(options, "/tmp/userDb", &db);
if (!s.ok())
cerr << s.ToString() << endl;
iteration(db);
delete db;
}
Not familiar with the leveldb API, but you're using db regardless of whether s.ok() is true or false. I'd assume that if s.ok() is false, db is either NULL, or in a state such that iteration or other operations won't work.
You should change the code to:
if (!s.ok()) {
cerr << s.ToString() << endl;
return -1;
}
This is the first time I am implementing ssh programmatically and I am baffled about why my code does not work -- to be more specific, ssh_channel_read() keeps returning 0 bytes read. I don't know what I am doing wrong! I have been following the API instructions step by step but I am obviously omitting something inadvertently.
I am trying to connect to my Pi with a user name + password. Here is the complete code, you can just copy paste this and compile it with:
g++ main.cpp -lssh -o myapp
After the code, you can see the output I am getting. Please don't be harsh, like I said, this is the first time I am dealing with SSH:
#include <iostream>
#include <string>
#include <libssh/libsshpp.hpp>
int main(int argc, const char **argv)
{
int vbs = SSH_LOG_RARE;
int timeout_ms = 1000;
ssh_session session = ssh_new();
ssh_channel channel;
char buffer[256];
int bytes_red;
if (session == NULL)
{
std::cout << "Failed to create ssh session." << std::endl;
exit(-1);
}
ssh_set_blocking(session, 1);
std::cout << "Created SSH session..." << std::endl;
ssh_options_set(session, SSH_OPTIONS_HOST, "192.168.1.5");
ssh_options_set(session, SSH_OPTIONS_PORT_STR, "22");
ssh_options_set(session, SSH_OPTIONS_USER, "pi#192.168.1.5");
ssh_options_set(session,SSH_OPTIONS_LOG_VERBOSITY, &vbs);
int con_result = ssh_connect(session);
int auth_result = ssh_userauth_password(session, "pi", "1234");
std::cout << "Connecton Result is: " << con_result << std::endl;
std::cout << "Auth Result is: " << auth_result << std::endl;
///////////////////////////////////////////
// Did we create the session successfully?
///////////////////////////////////////////
if (con_result != SSH_OK)
{
std::cout << "SSH connection failed. Error code is: " << con_result << std::endl;
ssh_free(session);
return con_result;
}
///////////////////////////////////////////
// Did we authenticate?
///////////////////////////////////////////
if (auth_result != SSH_AUTH_SUCCESS)
{
std::cout << "SSH authentication failed. Error code is: " << auth_result << std::endl;
ssh_free(session);
return auth_result;
}
///////////////////////////////////////////
// Create a new ssh_channel
///////////////////////////////////////////
channel = ssh_channel_new(session);
if (channel == NULL)
{
std::cout << "Failed to create SSH channel." << std::endl;
ssh_free(session);
return SSH_ERROR;
}
if (ssh_channel_is_open(channel))
std::cout << "Channel is open" << std::endl;
else
std::cout << "Channel is closed" << std::endl;
while(!ssh_channel_is_eof(channel))
{
bytes_red = ssh_channel_read_timeout(channel, buffer, sizeof(buffer), 0, timeout_ms);
// if (bytes_red)
std::cout << "Bytes read: " << bytes_red << std::endl;
}
std::cout << "Exiting ..." << std::endl;
ssh_channel_close(channel);
ssh_channel_free(channel);
ssh_free(session);
return 0;
}
and here is the output I am getting when running it:
$./myapp
Created SSH session...
[2018/05/19 14:57:14.246759, 1] socket_callback_connected: Socket connection callback: 1 (0)
[2018/05/19 14:57:14.301270, 1] ssh_client_connection_callback: SSH server banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 14:57:14.301321, 1] ssh_analyze_banner: Analyzing banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 14:57:14.301337, 1] ssh_analyze_banner: We are talking to an OpenSSH client version: 7.4 (70400)
Connecton Result is: 0
Auth Result is: 0
Channel is closed
[2018/05/19 14:57:14.669298, 1] ssh_packet_process: Couldn't do anything with packet type 80
Bytes read: 0
Bytes read: 0
Bytes read: 0
Bytes read: 0
Bytes read: 0
^C
$
I can see the error, "Channel is closed" but why? What am I doing wrong?
After this, I also want to send data to the server and obviously get the feedback. From what I have read, ssh_channel_write() is the function to use.
I haven't dealt with SSH programmatically before and I am learning this as I write this.
All your help is very much appreciated.
Update
Thank to Jarra, I have solved this! Here is the final code that works!
#include <iostream>
#include <string>
#include <libssh/libsshpp.hpp>
int main(int argc, const char **argv)
{
int vbs = SSH_LOG_RARE;
int timeout_ms = 1000;
ssh_session session = ssh_new();
ssh_channel channel;
char buffer[256];
int bytes_red;
if (session == NULL)
{
std::cout << "Failed to create ssh session." << std::endl;
exit(-1);
}
ssh_set_blocking(session, 1);
std::cout << "Created SSH session..." << std::endl;
ssh_options_set(session, SSH_OPTIONS_HOST, "192.168.1.5");
ssh_options_set(session, SSH_OPTIONS_PORT_STR, "22");
ssh_options_set(session, SSH_OPTIONS_USER, "pi#192.168.1.5");
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &vbs);
int con_result = ssh_connect(session);
int auth_result = ssh_userauth_password(session, "pi", "1234");
std::cout << "Connecton Result is: " << con_result << std::endl;
std::cout << "Auth Result is: " << auth_result << std::endl;
///////////////////////////////////////////
// Did we create the session successfully?
///////////////////////////////////////////
if (con_result != SSH_OK)
{
std::cout << "SSH connection failed. Error code is: " << con_result << std::endl;
ssh_free(session);
return con_result;
}
///////////////////////////////////////////
// Did we authenticate?
///////////////////////////////////////////
if (auth_result != SSH_AUTH_SUCCESS)
{
std::cout << "SSH authentication failed. Error code is: " << auth_result << std::endl;
ssh_free(session);
return auth_result;
}
///////////////////////////////////////////
// Create a new ssh_channel
///////////////////////////////////////////
channel = ssh_channel_new(session);
if (channel == NULL)
{
std::cout << "Failed to create SSH channel." << std::endl;
ssh_free(session);
return SSH_ERROR;
}
ssh_channel_open_session(channel);
if (ssh_channel_is_open(channel))
std::cout << "Channel is open" << std::endl;
else
std::cout << "Channel is closed" << std::endl;
int rc = ssh_channel_request_exec(channel, "ls");
while(!ssh_channel_is_eof(channel))
{
bytes_red = ssh_channel_read_timeout(channel, buffer, sizeof(buffer), 0, timeout_ms);
// if (bytes_red)
// std::cout << "Bytes read: " << bytes_red << std::endl;
std::cout << buffer << std::endl;
}
std::cout << "Exiting ..." << std::endl;
ssh_channel_close(channel);
ssh_channel_free(channel);
ssh_free(session);
return 0;
}
To compile: g++ main.cpp -lssh -o myapp and here is what you get when I run it:
./myapp
Created SSH session...
[2018/05/19 16:01:41.830861, 1] socket_callback_connected: Socket connection callback: 1 (0)
[2018/05/19 16:01:41.884875, 1] ssh_client_connection_callback: SSH server banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 16:01:41.884929, 1] ssh_analyze_banner: Analyzing banner: SSH-2.0-OpenSSH_7.4p1 Raspbian-10+deb9u1
[2018/05/19 16:01:41.884945, 1] ssh_analyze_banner: We are talking to an OpenSSH client version: 7.4 (70400)
Connecton Result is: 0
Auth Result is: 0
[2018/05/19 16:01:42.258668, 1] ssh_packet_process: Couldn't do anything with packet type 80
Channel is open
Desktop
Documents
Downloads
Music
Pictures
Public
python_games
Templates
Videos
����s
Exiting ...
I just need to work on that last bit with the funny chars. This is straight out of my source code editor when I just got it to work, so the code isn't perfect.
ssh_channel_new allocated the resources for a new channel. It does not open it.
Depending on what you are trying to achieve you should then call an appropriate ssh_channel_open_XXXX function on that channel.
A simple example can be found here: https://github.com/substack/libssh/blob/c073979235eb0d0587ac9cb3c192e91e32d34b06/examples/exec.c
First ssh_channel_open_session is called to open a session (shell) channel, and then ssh_channel_request_exec is called to execute the lsof command.
How/when you will write to the channel depends on the type of channel you have opened. An example of writing to a session channel (after calling cat > /dev/null on the host to pipe written data to /dev/null) can be seen here: https://github.com/substack/libssh/blob/c073979235eb0d0587ac9cb3c192e91e32d34b06/examples/senddata.c
I am having a really hard time with some API calls to the Wininet dll. I am trying to read cookies client side set by IE 9. Here's the code.
#include "stdafx.h"
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
LPTSTR lpData = NULL;
DWORD dwSz = 500;
std::cout << "Hello Chris" << std::endl;
lpData = new TCHAR[dwSz];
std::wcout << "Arg 0: " << argv[1] << std::endl;
bool val = InternetGetCookieEx(argv[1], argv[2], lpData, &dwSz, INTERNET_COOKIE_THIRD_PARTY | INTERNET_FLAG_RESTRICTED_ZONE, NULL);
if (!val)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::cout << "Insufficent Buffer size" << std::endl;
lpData = new TCHAR[dwSz];
val = InternetGetCookieEx(argv[1], argv[2], lpData, &dwSz, INTERNET_COOKIE_THIRD_PARTY | INTERNET_FLAG_RESTRICTED_ZONE, NULL);
if (val)
{
std::cout << "Cookie Data: " << lpData << std::endl;
}
else
{
std::cout << "ERROR Code: " << GetLastError() << std::endl;
}
}
else
{
int err = GetLastError();
std::cout << "ERROR Code: " << err << std::endl;
}
}
else
{
std::cout << "Cookie Data: " << lpData << std::endl;
}
//}
return 0;
}
The problem that I am having is that when I call InternetGetCookeEx I always return false and get an error code of 259, which means no more data available. When you consult the API essentially what that means is that it couldn't find my cookie.
Because I am using IE 9 the names for files that the cookie is being stored in are obviously mangled , which is why I am trying to read my cookie data that way.
I have removed the company name to protect the company. Essentially what I am trying to do is. Find the lUsrCtxPersist cookie value. Therefore I am calling the code as such CookieReader.ext http://[CompanyDomain].com lUsrCtxPersist.
However I always get a false and an error code of 259. Any light you might be able to shed on this would be greatly appreciated.
http://msdn.microsoft.com/en-us/library/ms537312%28v=vs.85%29.aspx
Try to use IEGetProtectedModeCookie
Assuming the cookie name is correct, then try removing the INTERNET_COOKIE_THIRD_PARTY and/or INTERNET_FLAG_RESTRICTED_ZONE flags and see what happens. Or try calling InternetGetCookie() instead, which has no such flags available.
On a separate note, when InternetGetCookieEx() returns ERROR_INSUFFICIENT_BUFFER, you are leaking memory. You need to delete[] your existing buffer before then calling new[] to allocate a new buffer.