Sample code for 30+ languages & platforms
Lua Requires Chilkat v11.0.0+

IMAP Use Existing SSH Tunnel

Demonstrates how to connect to an IMAP server using an existing SSH tunnel. This creates a new channel within the SSH tunnel, which can be a TCP or TLS connection, and is connected to a remote IMAP server through port forwarding.

Chilkat Lua Downloads

Lua

    -- In the following call to loadlib, change the path (./chilkat.dll) to the relative or absolute directory where the chilkat.dll, chilkat.so, or chilkat.dylib is located.
    chilkat = assert(package.loadlib("./chilkat.dll", "luaopen_chilkat"))()
    print(chilkat._VERSION)

    local success = false

    --  This example assumes the Chilkat API to have been previously unlocked.
    --  See Global Unlock Sample for sample code.

    local tunnel = chilkat.newSocket{}

    local sshHostname = "sftp.example.com"
    local sshPort = 22

    --  Connect to an SSH server and establish the SSH tunnel:
    success = tunnel:SshOpenTunnel(sshHostname,sshPort)
    if success == false then
        print(tunnel:LastErrorText())

    end

    --  Authenticate with the SSH server via a login/password
    --  or with a public key.  
    --  This example demonstrates SSH password authentication.
    --  Note: This is not authenticating with the IMAP server, it is
    --  for authenticating with the SSH server, which is separate.
    success = tunnel:SshAuthenticatePw("mySshLogin","mySshPassword")
    if success == false then
        print(tunnel:LastErrorText())

    end

    --  OK, the SSH tunnel is setup.  Now open a channel within the tunnel.
    --  Once the channel is obtained, the Socket API may
    --  be used exactly the same as usual, except all communications
    --  are sent through the channel in the SSH tunnel.
    --  Any number of channels may be created from the same SSH tunnel.
    --  Multiple channels may coexist at the same time.

    local imap = chilkat.newImap{}

    --  Let the IMAP object also use the SSH tunnel
    success = imap:UseSshTunnel(tunnel)
    if success == false then
        print(imap:LastErrorText())

    end

    --  Connect to an IMAP server via the already established SSH tunnel.
    --  Because the SSH tunnel has been previously setup,
    --  this does not establish a direct connection with the IMAP
    --  server.  It directs the SSH server to establish the connection.

    --  In this example, the IMAP server requires SSL/TLS.  The TLS connection
    --  will be enclosed within the SSH tunnel.
    imap:setSsl(true)
    imap:setPort(993)
    success = imap:Connect("imap.my-imap-server.com")
    if success == false then
        print(imap:LastErrorText())

    end

    --  Authenticate with the IMAP server via the SSH tunnel.
    success = imap:Login("myLogin","myPassword")
    if success == false then
        print(imap:LastErrorText())

    end

    --  Select an IMAP mailbox
    success = imap:SelectMailbox("Inbox")
    if success == false then
        print(imap:LastErrorText())

    end

    --  How many messages in Inbox?
    local msgCount = imap:NumMessages()
    if msgCount == 0 then
        print("No messages found.")

    end

    local upperBound = 10
    if msgCount < upperBound then
        upperBound = msgCount
    end

    --  Download up to the 1st 10 messages.
    local email = chilkat.newEmail{}

    local bUid = false
    for i = 1, upperBound do

        success = imap:FetchEmail(false,i,bUid,email)
        if success == false then
            print(imap:LastErrorText())

        end

        print(email:From())
        print(email:Subject())

    end

    --  Disconnect from the IMAP server.
    --  The SSH tunnel remains open.
    success = imap:Disconnect()
    if success == false then
        print(imap:LastErrorText())

    end

    --  It is possible to re-use the existing SSH tunnel for the next connection:
    success = imap:Connect("imap.my-imap-server2.com")
    if success == false then
        print(imap:LastErrorText())

    end

    --  Review the LastErrorText to see that the connection was made via the SSH tunnel:
    print(imap:LastErrorText())

    --  This closes the SSH channel, which is the connection with the IMAP server.
    --  It does not close the SSH tunnel
    success = imap:Disconnect()
    if success == false then
        print(imap:LastErrorText())

    end

    --  Finally, close the SSH tunnel.

    --  Note: If other objects are using the same SSH tunnel, the tunnel is not 
    --  actually closed.  It is only closed when the last object using the tunnel closes it.

    --  At this point, both the imap and tunnel objects have references to the internal
    --  SSH tunnel.  We need to close each.

    --  This call doesn't actually close the tunnel yet, because the tunnel object still
    --  holds an internal reference.
    success = imap:SshCloseTunnel()
    if success == false then
        print(imap:LastErrorText())

    end

    --  This actually closes the SSH tunnel because it's the last object using it.
    success = tunnel:SshCloseTunnel()
    if success == false then
        print(tunnel:LastErrorText())

    end

    print("IMAP pre-existing SSH tunnel example completed.")