HTTPS/Authenticated

From Rosetta Code
Task
HTTPS/Authenticated
You are encouraged to solve this task according to the task description, using any language you may know.

The goal of this task is to demonstrate HTTPS requests with authentication. Implementations of this task should not use client certificates for this: that is the subject of another task.

AutoHotkey

Library: iweb
Library: COM

<lang AutoHotkey>iWeb_Init() pwb := iWeb_newGui(0, 0, 1000, 800) iWeb_nav(pwb, "http://www.facebook.com/login.php?ref=pf") iWeb_Term() iWeb_complete(pwb) inputbox, email, email inputbox, pass, password iWeb_setDomObj(pwb,"Email",email) iWeb_setDomObj(pwb,"pass",pass) iWeb_clickDomObj(pwb, "login") return

  1. Include iweb.ahk
  2. Include COM.ahk
  3. Include COMinvokeDeep.ahk</lang>

C

Library: libcurl

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include "curl/curl.h"

int main(void) {

       CURL *curl;
       char buffer[CURL_ERROR_SIZE];
       if ((curl = curl_easy_init()) != NULL) {
               curl_easy_setopt(curl, CURLOPT_URL, "https://user:password@secure.example.com/");
               curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
               curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer);
               if (curl_easy_perform(curl) != CURLE_OK) {
                       fprintf(stderr, "%s\n", buffer);
                       return EXIT_FAILURE;
               }
               curl_easy_cleanup(curl);
       }
       return EXIT_SUCCESS;

}</lang>

C#

Works with: C sharp version 3.0

<lang csharp> using System; using System.Net;

class Program {

   static void Main(string[] args)
   {
       var client = new WebClient();
       // credentials of current user:
       client.Credentials = CredentialCache.DefaultCredentials;
       // or specify credentials manually:
       client.Credentials = new NetworkCredential("User", "Password");
       var data = client.DownloadString("https://example.com");
       Console.WriteLine(data);
   }

} </lang>

Clojure

Library: clj-http

<lang clojure>(clj-http.client/get "https://somedomain.com"

                    {:basic-auth ["user" "pass"]})</lang>

Delphi

<lang Delphi>program ShowHTTPSAuthenticated;

{$APPTYPE CONSOLE}

uses IdHttp, IdSSLOpenSSL;

var

 s: string;
 lHTTP: TIdHTTP;
 lIOHandler: TIdSSLIOHandlerSocketOpenSSL;

begin

 ReportMemoryLeaksOnShutdown := True;
 lHTTP := TIdHTTP.Create(nil);
 lIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
 try
   lHTTP.Request.Username := 'USERNAME';
   lHTTP.Request.Password := 'PASSWD';
   lHTTP.IOHandler := lIOHandler;
   lHTTP.HandleRedirects := True;
   s := lHTTP.Get('https://SomeSecureSite.net/');
   Writeln(s);
 finally
   lHTTP.Free;
   lIOHandler.Free;
 end;

end.</lang>

Go

The task solution is really the client program, but to test it I wrote a server and created a custom certificate. I won't describe the certificate, but this is the server: <lang go>package main

import (

   "encoding/base64"
   "io"
   "log"
   "net/http"
   "strings"

)

const userPass = "rosetta:code" const unauth = http.StatusUnauthorized

func hw(w http.ResponseWriter, req *http.Request) {

   auth := req.Header.Get("Authorization")
   if !strings.HasPrefix(auth, "Basic ") {
       log.Print("Invalid authorization:", auth)
       http.Error(w, http.StatusText(unauth), unauth)
       return
   }
   up, err := base64.StdEncoding.DecodeString(auth[6:])
   if err != nil {
       log.Print("authorization decode error:", err)
       http.Error(w, http.StatusText(unauth), unauth)
       return
   }
   if string(up) != userPass {
       log.Print("invalid username:password:", string(up))
       http.Error(w, http.StatusText(unauth), unauth)
       return
   }
   io.WriteString(w, "Goodbye, World!")

}

func main() {

   http.HandleFunc("/", hw)
   log.Fatal(http.ListenAndServeTLS(":8080", "cert.pem", "key.pem", nil))

}</lang> It is a "Hello world" server, but over TLS and with basic authentication required on the Get. Errors are logged to aid client debugging.

The client: <lang go>package main

import (

   "crypto/tls"
   "crypto/x509"
   "fmt"
   "io/ioutil"
   "log"
   "net/http"

)

const (

   userid   = "rosetta"
   password = "code"

)

func main() {

   // Use custom certificate for testing.  Not exactly required by task.
   b, err := ioutil.ReadFile("cert.pem")
   if err != nil {
       log.Fatal(err)
   }
   pool := x509.NewCertPool()
   if ok := pool.AppendCertsFromPEM(b); !ok {
       log.Fatal("Failed to append cert")
   }
   tc := &tls.Config{RootCAs: pool}
   tr := &http.Transport{TLSClientConfig: tc}
   client := &http.Client{Transport: tr}
   req, err := http.NewRequest("GET", "https://127.0.0.1:8080", nil)
   if err != nil {
       log.Fatal(err)
   }
   // This one line implements the authentication required for the task.
   req.SetBasicAuth(userid, password)
   // Make request and show output.
   resp, err := client.Do(req)
   if err != nil {
       log.Fatal(err)
   }
   b, err = ioutil.ReadAll(resp.Body)
   resp.Body.Close()
   if err != nil {
       log.Fatal(err)
   }
   fmt.Println(string(b))

}</lang>

Lasso

<lang Lasso>local(username = 'hello',password = 'world') local(x = curl('https://sourceforge.net'))

  1. x->set(CURLOPT_USERPWD, #username + ':' + #password)

local(y = #x->result)

  1. y->asString</lang>

LiveCode

HTTP Basic Auth as part of url <lang LiveCode>command getAuthWebResource

   libURLFollowHttpRedirects true
   libURLSetSSLVerification true
   put URL "https://user:passwd@example.basicauth.com/" into response
   put response

end getAuthWebResource</lang>

You can also set the headers for the basic auth requests <lang LiveCode>command getAuthWebResource

   libURLFollowHttpRedirects true
   libURLSetSSLVerification true
   set the httpHeaders to "Authorization: Basic " && base64Encode("user:passwd")
   put URL "https://example.basicauth.com" into response
   put response

end getAuthWebResource</lang>

Mathematica / Wolfram Language

<lang Mathematica>a = RunThrough["curl -u JohnDoe:Password https://www.example.com", 1] For[ i=0, i < Length[a] , i++, SomeFunction[a]]</lang>

Perl

Library: LWP

<lang perl>use LWP::UserAgent qw(); my $ua = LWP::UserAgent->new; my $netloc = 'http://www.buddhism-dict.net/cgi-bin/xpr-dealt.pl:80'; $ua->credentials(

  $netloc,
  'CJK-E and Buddhist Dictionaries', # basic realm
  'guest',  # user
  ,       # empty pw

); my $response = $ua->get($netloc);

use WWW::Mechanize qw(); my $mech = WWW::Mechanize->new; $mech->get('https://login.yahoo.com/'); $mech->submit_form(with_fields => {

   login         => 'XXXXXX',
   passwd        => 'YYYYYY',
   '.persistent' => 'y',  # tick checkbox

});</lang>

PicoLisp

<lang PicoLisp>(let (User "Bill" Pass "T0p5ecRet" Url "https://www.example.com")

  (in (list 'curl "-u" (pack User ': Pass) Url)
     (while (line)
        (doSomeProcessingWithLine @) ) ) )</lang>

Python

Works with: Python version 2.4 and 2.6

Note: You should install mechanize to run code below. Visit: http://wwwsearch.sourceforge.net/mechanize/

<lang python>#!/usr/bin/python

  1. -*- coding: utf-8 -*-

from mechanize import Browser

USER_AGENT = "Mozilla/5.0 (X11; U; Linux i686; tr-TR; rv:1.8.1.9) Gecko/20071102 Pardus/2007 Firefox/2.0.0.9"

br = Browser() br.addheaders = [("User-agent", USER_AGENT)]

  1. remove comment if you get debug output
  2. br.set_debug_redirects(True)
  3. br.set_debug_responses(True)
  4. br.set_debug_http(True)

br.open("https://www.facebook.com")

br.select_form("loginform") br['email'] = "xxxxxxx@xxxxx.com" br['pass'] = "xxxxxxxxx" br['persistent'] = ["1"]

response = br.submit() print response.read()</lang>

Racket

<lang racket>

  1. lang racket

(require net/url net/url-connect openssl)

(module+ main

 (parameterize ([current-https-protocol (ssl-make-client-context)])
   (ssl-set-verify! (current-https-protocol) #t)
   ;; When this is #f, we correctly get an exception:
   ;; error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
   (when #t
     (ssl-load-verify-source! (current-https-protocol)
                              '(directory
                                ;; This location works on Debian 6;
                                ;; adjust as needed for your platform.
                                "/etc/ssl/certs"
                                )))
   (for ([l (in-port read-line (get-pure-port (string->url "https://www.google.com/")))])
     (displayln  l))))

</lang>

Run BASIC

<lang runbasic>html "

LOGIN
UserName"
TEXTBOX #userName, "" 
html "
Password:"

PasswordBox #passWord, ""

html "
"

button #si, "Signin", [doSignin] html " " button #ex, "Exit", [exit]

html "
"

WAIT

[doSignin] loginUserName$ = trim$(#userName contents$()) loginPassWord$ = trim$(#passWord contents$()) if (loginUserName$ = "admin" and loginPassWord$ = "admin" then

  print "Login ok"
 else
  print "invalid User or Pass"
  cls
  goto [loop]

end if

print Platform$ ' OS where Run BASIC is being hosted print UserInfo$ ' Information about the user's web browser print UserAddress$ ' IP address of the user

[exit] end</lang>

Sidef

<lang ruby>require('WWW::Mechanize')

var mech = %s'WWW::Mechanize'.new(

   cookie_jar => Hash.new,
   agent => 'Mozilla/5.0',

)

mech.get('https://login.yahoo.com/') mech.submit_form(

   form_id => 'mbr-login-form',   # form id
   fields => Hash.new(
       'login'  => 'XXXXXX',
       'passwd' => 'YYYYYY',

))</lang>

Tcl

Works with: Tcl version 8.6
for the binary encode subcommand, otherwise uses
Library: Tcllib (Package: base64)

Uses the Tls package. <lang Tcl>package require http package require tls http::register https 443 ::tls::socket

  1. Generate the authentication

set user theUser set pass thePassword dict set auth Authenticate "Basic [binary encode base64 ${user}:${pass}]"

  1. Make a secure authenticated connection

set token [http::geturl https://secure.example.com/ -headers $auth]

  1. Now as for conventional use of the “http” package

set data [http::data $token] http::cleanup $token</lang>

zkl

Using cURL to do the heavy lifting, get a XML list of computers connected to my router. <lang zkl>zkl: var ZC=Import("zklCurl") zkl: var data=ZC().get("http://usr:pw@192.168.1.1/computer_list.xml") L(Data(1,049),121,0) zkl: data[0][121,*].text</lang>

Output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<computers>
<ip_address0>192.168.1.100</ip_address0><host_name0>core-shot
...