HTTPS/Authenticated
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.
You are encouraged to solve this task according to the task description, using any language you may know.
AutoHotkey
<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
- Include iweb.ahk
- Include COM.ahk
- Include COMinvokeDeep.ahk</lang>
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- 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#
<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
<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'))
- x->set(CURLOPT_USERPWD, #username + ':' + #password)
local(y = #x->result)
- 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
<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
Note: You should install mechanize to run code below. Visit: http://wwwsearch.sourceforge.net/mechanize/
<lang python>#!/usr/bin/python
- -*- 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)]
- remove comment if you get debug output
- br.set_debug_redirects(True)
- br.set_debug_responses(True)
- 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>
- 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
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
for thebinary encode
subcommand, otherwise uses
Uses the Tls package. <lang Tcl>package require http package require tls http::register https 443 ::tls::socket
- Generate the authentication
set user theUser set pass thePassword dict set auth Authenticate "Basic [binary encode base64 ${user}:${pass}]"
- Make a secure authenticated connection
set token [http::geturl https://secure.example.com/ -headers $auth]
- 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 ...