Ocaml how get https url - ssl

How can I get the page to https? Tried that.
open Sys
open Array
open Str
open List
open Printf
open Unix
open Http_client.Convenience
open Nethttp
open Http_client.Convenience
open Netsys_tls;;
let provider = Netsys_tls.current_tls();;
let tls_config =
Netsys_tls.create_x509_config
~system_trust:true
~peer_auth:`Required
provider;;
let getPage _ =
let pipeline = new Http_client.pipeline in
let call = new Http_client.get ("https://vk.com/") in
call#set_redirect_mode Http_client.Do_not_redirect;
pipeline#add call;
pipeline#run ();
let cookies = Header.get_set_cookie call#response_header in
List.iter (fun c -> print_string(c.cookie_name^"="^c.cookie_value^"\n")) cookies;;
getPage();;
But when compiling I've got this error:
Error: Unbound module Netsys_tls
c:\wodi32\opt\wodi32\bin\ocamlfind ocamlopt unix.cmxa bigarray.cmxa str.cmxa -I +labltk labltk.cmxa -I c:\wodi32\opt\wodi32\lib\ocaml\pkg-lib\netsys\ netsys_oothr.cmxa netsys.cmxa -I c:\wodi32\opt\wodi32\lib\ocaml\pkg-lib\netstring\ netstring.cmxa -I c:\wodi32\opt\wodi32\lib\ocaml\pkg-lib\equeue\ equeue.cmxa -I c:\wodi32\opt\wodi32\lib\ocaml\pkg-lib\netclient\ netclient.cmxa vk.ml -I c:\wodi32\opt\wodi32\lib\ocaml\pkg-lib\equeue-ssl\ equeue_ssl.cmxa -I c:\wodi32\opt\wodi32\lib\ocaml\pkg-lib\cryptgps\ cryptgps.cmxa -o vk.exe
where can I get the module Netsys_tls

If you just want to get the url, and have no other reasons to stick with OCamlnet, then you can just use curl library, that will take care of all caveats:
let fetch fname url =
let fd = open_in fname in
let write s = Out_channel.output_string fd s; String.length s in
let conn = Curl.init () in
Curl.set_writefunction conn (write);
Curl.set_failonerror conn true;
Curl.set_followlocation conn true;
Curl.set_url conn url;
Curl.perform conn;
Curl.cleanup conn;
close_out fd
It will fetch any url supported by curl, including https

Related

Need to make a port detector

I am trying to make a service which can detect when a port gets occupied.
So netstat -lntu | grep tcp can list all occupied ports. So a difference between the output from first netstat executioin and one after the a port gets occupied can get me the port value.
And it needs to be fully automated so i made a infinite loop which will continuously check for differences between two consecutive netstat.
Here is my code in js and i am running it using node-daemonize2:
var shell = require("shelljs");
var InfiniteLoop = require("infinite-loop");
var il = new InfiniteLoop();
var diff = require('diff');
var oldStr = '';
var newStr = '';
shell.exec("netstat -lntu | grep tcp",{silent:true}, function (code, output, error) {
oldStr = output;
});
il.add(function () {
shell.exec("netstat -lntu | grep tcp",{silent:true}, function (code, output, error) {
newStr = output;
if(!newStr.replace(oldStr,'')==''){
var dD = diff.diffChars(oldStr, newStr)[1];
if(dD.added){
let value = dD.value.replace(/\n/g,'');
re = /[0-9][0-9][0-9][0-9]/
value = re.exec(value);
console.log(value[0]);
}
}
oldStr = newStr;
});
});
il.run();
Now this thing works perfectly fine, but is resource heavy. So is there a way to make it light or a completely new and more efficient way to approach this problem?

How to make a secure password input field in a command line app?

I am writing a command line application for OS X in Swift. I need to prompt for a username and password (not the user's account on the computer and not credentials saved in the Keychain). I can prompt for the username just fine:
func getInput() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
return NSString(data: inputData, encoding:NSUTF8StringEncoding)!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
let username = getInput()
I would like to prompt for the password as well but it prints the password in the console as the user types it. How can I accept input from STDIN without having it echoed back to the console?
Please note that I need the application to be interactive, the user will never be passing the username and password as command line arguments, so argv is not the correct answer.
For example, when doing this in Ruby, you would enter this:
require 'io/console'
puts "Enter your password"
#password = STDIN.noecho(&:gets).chomp
And then it would display on the screen as this image:
No matter how many letters are entered, it only shows that blue box with the dot in it. It doesn't print the password to the screen and it doesn't show ********* for the password either.
Is it possible to do the same thing with Swift or Objective-C in a command line OS X application?
Just for the sake of completeness: getpass() works great for passwords, but unfortunately this function also has the limitation that it can only read up to 128 characters. If you want to prompt for really long passphrase or private keys, use BSD's readpassphrase() instead.
Swift 2.0 example:
var buf = [Int8](count: 8192, repeatedValue: 0)
let passphrase = readpassphrase("Enter passphrase: ", &buf, buf.count, 0)
if let passphraseStr = String.fromCString(passphrase) {
print(passphraseStr)
}
Swift 3.1 and later:
var buf = [CChar](repeating: 0, count: 8192)
if let passphrase = readpassphrase("Enter passphrase: ", &buf, buf.count, 0),
let passphraseStr = String(validatingUTF8: passphrase) {
print(passphraseStr)
}
inputString = String(validatingUTF8: UnsafePointer<CChar>(getpass("Please enter your password: ")))
This is how you could get the input using swift
Use the C function getpass(3). For example:
char *p = getpass("Please enter your password: ");
NSString *password = [NSString stringWithUTF8String:p];
NSLog(#"%#", password);

How to send a file using scp using python 3.2?

I'm trying to send a group of files to a remote server through no-ack's python byndings for libssh2, but I am totally lost regarding the library usage due to the lack of documentation.
I've tried using the C docs for libssh2 unsuccesfully.
Since I'm using python 3.2, paramiko and pexpect are out of the question.
Anyone can help?
EDIT: I just found some code in no-Ack's blog comments to his post.
import libssh2, socket, os
SERVER = 'someserver'
username = 'someuser'
password = 'secret!'
sourceFilePath = 'source/file/path'
destinationFilePath = 'dest/file/path'
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((SERVER, 22))
session = libssh2.Session()
session.startup(sock)
session.userauth_password(username, password)
sourceFile = open(sourceFilePath, 'rb')
channel = session.scp_send(destinationFilePath, 0o644, os.stat(sourceFilePath).st_size)
while True:
data = sourceFile.read(4096)
if not data:
break
channel.write(data)
exitStatus = channel.exit_status()
channel.close()
Seems to work fine.
And here's how to get files with libssh2 in Python 3.2. Major kudos to no-Ack for showing me this. You'll need the Python3 bindings for libssh2 https://github.com/wallunit/ssh4py
import libssh2, socket, os
SERVER = 'someserver'
username = 'someuser'
password = 'secret!'
sourceFilePath = 'source/file/path'
destinationFilePath = 'dest/file/path'
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((SERVER, 22))
session = libssh2.Session()
session.startup(sock)
session.userauth_password(username, password)
(channel, (st_size, _, _, _)) = session.scp_recv(sourceFilePath, True)
destination = open(destinationFilePath, 'wb')
got = 0
while got < st_size:
data = channel.read(min(st_size - got, 1024))
got += len(data)
destination.write(data)
exitStatus = channel.get_exit_status()
channel.close()
To do this in Python (i.e. not wrapping scp through subprocess.Popen or similar) with the Paramiko library.
Revelent : https://stackoverflow.com/a/69596/1270589
Below is easy but it is not universal means works if you run in linux dosent work if you run in windows. tell me if you know to make below universal i.e across all O.S platforms.
import os
os.system("sshpass -p 'your password' scp /opt/pysftp_server.txt root#172.19.113.87:/home")

Process.Start and "The system cannot find the path specified"

I am trying to run a console application from a mapped drive (T:\ is a mapped drive for a shared network folder) and get the error:
The system cannot find the path specified.
Why do I get this error? The administrator credentials are correct.
var password = new SecureString();
password.AppendChar(Convert.ToChar("P"));
password.AppendChar(Convert.ToChar("a"));
password.AppendChar(Convert.ToChar("a"));
password.AppendChar(Convert.ToChar("s"));
Process.Start(#"t:\ca\test.exe"), "", "Administrator", password, "domain");
Check if the mapped drive T: is also correctly mapped for the Administrator account.
Also, I'm not sure, but the Administrator must probably be logged in for the mapped drive to be available.
You could also try the following, starting cmd.exe, mapping your UNC path and then calling the application:
var password = new SecureString();
password.AppendChar(Convert.ToChar("P"));
password.AppendChar(Convert.ToChar("a"));
password.AppendChar(Convert.ToChar("a"));
password.AppendChar(Convert.ToChar("s"));
var startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UserName = "Administrator";
startInfo.Password = password;
startInfo.Domain = "domain";
var process = Process.Start(startInfo);
process.BeginOutputReadLine();
process.StandardInput.WriteLine(#"pushd \\your_unc_path\ca");
process.StandardInput.WriteLine("test.exe");
process.StandardInput.WriteLine("exit");
process.WaitForExit();

How can you add a Certificate to WebClient in Powershell

I wan't to examine a Webpage which requires Client Side Certificate Authentication.
How can i provide my Cert from the Certstore to the Webrequest:
Is there a way to specify this in Credentials odr within the Proxy?
$webclient = New-Object Net.WebClient
# The next 5 lines are required if your network has a proxy server
$webclient.Credentials = [System.Net.CredentialCache]::DefaultCredentials
if($webclient.Proxy -ne $null) {
$webclient.Proxy.Credentials = `
[System.Net.CredentialCache]::DefaultNetworkCredentials
}
# This is the main call
$output = $webclient.DownloadString("$URL")
PS: Maybe this helps: How can you add a Certificate to WebClient (C#)? But i don't get it.. ;-)
Using the new Add-Type functionality in PowerShell v2, you can craft a custom class that you can then use to make your typical WebRequest. I have included a method on the custom class to allow you to add certificates that can be used for authentication.
PS C:\> $def = #"
public class ClientCertWebClient : System.Net.WebClient
{
System.Net.HttpWebRequest request = null;
System.Security.Cryptography.X509Certificates.X509CertificateCollection certificates = null;
protected override System.Net.WebRequest GetWebRequest(System.Uri address)
{
request = (System.Net.HttpWebRequest)base.GetWebRequest(address);
if (certificates != null)
{
request.ClientCertificates.AddRange(certificates);
}
return request;
}
public void AddCerts(System.Security.Cryptography.X509Certificates.X509Certificate[] certs)
{
if (certificates == null)
{
certificates = new System.Security.Cryptography.X509Certificates.X509CertificateCollection();
}
if (request != null)
{
request.ClientCertificates.AddRange(certs);
}
certificates.AddRange(certs);
}
}
"#
PS C:\> Add-Type -TypeDefinition $def
You would perhaps want to limit the certificates being added to just the one (or ones) you would want to use rather than just use every available certificate in the Current User store, but here is an example that just loads all of them:
PS C:\> $wc = New-Object ClientCertWebClient
PS C:\> $certs = dir cert:\CurrentUser\My
PS C:\> $wc.AddCerts($certs)
PS C:\> $wc.DownloadString("http://stackoverflow.com")