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>
Haskell
Example uses the req and aeson packages:
<lang haskell>{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Data.Aeson (Value) import Data.Default.Class (def) import Network.HTTP.Req
( (/:) , GET(..) , NoReqBody(..) , basicAuth , https , jsonResponse , req , responseBody , runReq )
main :: IO () main = do
response <- runReq def $ req GET (https "httpbin.org" /: "basic-auth" /: "someuser" /: "somepassword") NoReqBody jsonResponse (basicAuth "someuser" "somepassword") print (responseBody response :: Value)</lang>
Julia
An example using HTTP (see the source for HTTP.jl for the code below ) to access and play a song: <lang Julia> using HTTP, HTTP.IOExtras, JSON, MusicProcessing HTTP.open("POST", "http://music.com/play") do io
write(io, JSON.json([ "auth" => "12345XXXX", "song_id" => 7, ])) r = startread(io) @show r.status while !eof(io) bytes = readavailable(io) play(bytes) end
end </lang>
Kotlin
<lang scala>// version 1.2.0
import java.net.Authenticator import java.net.PasswordAuthentication import javax.net.ssl.HttpsURLConnection import java.net.URL import java.io.InputStreamReader import java.io.BufferedReader
object PasswordAuthenticator : Authenticator() {
override fun getPasswordAuthentication() = PasswordAuthentication ("username", "password".toCharArray())
}
fun main(args: Array<String>) {
val url = URL("https://somehost.com") val con = url.openConnection() as HttpsURLConnection Authenticator.setDefault(PasswordAuthenticator) con.allowUserInteraction = true con.connect() val isr = InputStreamReader(con.inputStream) val br = BufferedReader(isr) while (true) { val line = br.readLine() if (line == null) break println(line) }
}</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>
Lua
<lang lua> local requests = require('requests') local auth = requests.HTTPBasicAuth('admin', 'admin') local resp, e = requests.get({
url = 'https://httpbin.org/basic-auth/admin/admin', auth = auth
}) io.write(string.format('Status: %d', resp.status_code)) </lang>
- Output:
Status: 200
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>
Perl 6
Used here to connect to my local wireless router to a page that is password protected. Obviously not going to be generally publicly accessible but should be easily adaptable to other sites / devices.
<lang perl6>use HTTP::UserAgent;
my $username = 'username'; # my username my $password = 'password'; # my password my $address = 'http://192.168.1.1/Status_Router.asp'; # my local wireless router
my $ua = HTTP::UserAgent.new; $ua.auth( $username, $password ); my $response = $ua.get: $address; say $response.is-success ?? $response.content !! $response.status-line;</lang>
Phix
Exactly the same as the HTTP#Phix task. You can of course use curl_easy_setopt(curl,CURLOPT_USERPWD,"user:password") rather than embed that in the url. <lang Phix>include builtins\libcurl.e curl_global_init() atom curl = curl_easy_init() curl_easy_setopt(curl, CURLOPT_URL, "https://user:password@example.com/") object res = curl_easy_perform_ex(curl) curl_easy_cleanup(curl) curl_global_cleanup()
puts(1,res)</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>
<lang python>import requests
username = "user" password = "pass" url = "https://www.example.com"
response = requests.get(url, auth=(username, password)
print(response.text)</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>
Ruby
<lang ruby>require 'uri' require 'net/http'
uri = URI.parse('https://www.example.com') response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new uri request.basic_auth('username', 'password') http.request request
end</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
Scala
<lang Scala>import java.net.{Authenticator, PasswordAuthentication, URL}
import javax.net.ssl.HttpsURLConnection
import scala.io.BufferedSource
object Authenticated extends App {
val con: HttpsURLConnection = new URL("https://somehost.com").openConnection().asInstanceOf[HttpsURLConnection]
object PasswordAuthenticator extends Authenticator { override def getPasswordAuthentication = new PasswordAuthentication("username", "password".toCharArray) }
Authenticator.setDefault(PasswordAuthenticator) con.setAllowUserInteraction(true) con.connect()
new BufferedSource(con.getInputStream).getLines.foreach(println(_))
}</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
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>
Visual Basic
<lang vb>Sub Main()
Dim HttpReq As WinHttp.WinHttpRequest
' in the "references" dialog of the IDE, check ' "Microsoft WinHTTP Services, version 5.1" (winhttp.dll) Const HTTPREQUEST_PROXYSETTING_PROXY As Long = 2
- Const USE_PROXY = 1
Set HttpReq = New WinHttp.WinHttpRequest HttpReq.Open "GET", "https://www.abc.com/xyz/index.html" HttpReq.SetCredentials "<username>", "<password>", 0&
- If USE_PROXY Then
HttpReq.SetProxy HTTPREQUEST_PROXYSETTING_PROXY, "10.167.1.1:80"
- End If
HttpReq.SetTimeouts 1000, 1000, 1000, 1000 HttpReq.Send Debug.Print HttpReq.ResponseText
End Sub</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 ...