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>

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>

Mathematica

<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>

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>