Code Metaphor

Programming, Writing, Reading, Thoughts…

KT 메가패스의 인증 자동화 ⑵

전에 KT 메가패스의 인증을 자동화하는 스크립트를 만들었는데, 결국 그것을 iMac이 잠자기에서 깼을 때 실행되게 만들지는 못했다. 그래서 고민을 더 하다가, 아예 HTTP 프록시로 구현해볼 수도 있지 않을까 싶었다. 그래서 전에 만들었던 Perl 스크립트를 좀더 확장하여 HTTP 프록시 데몬을 구현했다. 내가 사용한 모듈은 원본 스크립트에서도 썼던 WWW::Mechanize와 HTTP 프록시를 정말 쉽게 구현하게 해주는 HTTP::Proxy, 몇줄의 코드로 데몬을 만들 수 있게 해주는 Daemon::Generic, 이렇게 셋이다. 당연히 CPAN으로 쉽게 설치할 수 있다.

내 기본적인 아이디어는, 어떠한 HTTP 요청이 일어났을 때 그 요청이 직접 원격지로 전달되는 대신 프록시로 전달되게 하고, 프록시에서 그 요청을 원격지로 했을 때 “Please wait while you are redirected” 어쩌고 하며 KT 메가패스 인증 페이지로 리다이렉션시키는 응답이 오면 프록시가 자동으로 인증을 하고—이 부분은 기존 스크립트를 그대로 썼다—하려던 요청을 다시 하는 것이다. 당연히 한번 인증이 된 이후로는 KT 메가패스 인증을 가지고 뭐라하지 않기 때문에 프록시는 투명하게 동작하게 된다.

HTTP::Proxy에는 필터를 크게 HTTP::Proxy::HeaderFilterHTTP::Proxy::BodyFilter 두 종류 지원하는데, 나는 헤더를 가지고 할 작업은 없으므로 후자를 구현했다. 사실 실제로 어떤 여과를 하지 않고 투명한 결과를 내는 필터지만, 중간에 아무말 없이 인증을 시도하게 된다. 그러니까 HTTP::Proxy 저자가 모듈을 디자인할 때 의도한대로 사용하는 것이 아니라, 부수 효과(side effect)를 이용하는 셈이다.

아래 코드는 KTAuthFilter.pm 파일의 내용이다.

package KTAuthFilter;
use base qw( HTTP::Proxy::BodyFilter );

use warnings;
use strict;
use WWW::Mechanize;
require LWP::UserAgent;

sub filter {
    my ($self, $dataref, $message, $protocol, $buffer) = @_;
    return unless $message->isa('HTTP::Response');
    return unless 1024 > length $$dataref;
    return unless $$dataref =~ /Please wait while you are redirected/i;

    my $mech = new WWW::Mechanize;
    $$dataref =~ /d+;s*url=(https?://[^"]+)/i;
    $mech->get($1);

    $mech->submit_form(
        form_number => 2,
        fields => {
            userID => '<YOUR ID GOES HERE>',
            userPW => '<YOUR PASSWORD GOES HERE>'
        }
    );

    my $ua = LWP::UserAgent->new;
    my $response = $ua->request($message->request);
    $message->headers->clear();

    foreach my $field ($response->headers->header_field_names) {
        $message->headers->header(
            $field => $response->headers->header($field)
        );
    }

    $$dataref = $response->content;
}   

1;

이렇게 필터를 구현했으니 이제 가져다 쓰기만 하면 된다. Daemon::Generic은 gc_preconfiggc_run만 정의하면 아주 잘 돌아간다. 아래 코드는 ktauth-htproxyd 파일이다. 나는 이 파일에 실행 권한을 주었다.

#!/usr/bin/env perl
use warnings;
use strict;
use HTTP::Proxy;
use KTAuthFilter;
use Daemon::Generic;

newdaemon(
    progname => "ktauth-htproxyd",
    pidfile  => "/var/run/ktauth-htproxyd.pid"
);

sub gd_preconfig {
    return ();
}

sub gd_run {
    my $proxy = HTTP::Proxy->new(port => 8888);
    $proxy->push_filter(response => KTAuthFilter->new());
    $proxy->start;
}

이리하고 직접 데몬을 시동시켜봤다.

$ sudo ./ktauth-htproxyd start
Starting ktauth-htproxyd server

잘 된다. 하핳. 그 이후에는 Mac OS X의 System Preferences에 가서 Network, Advanced…, Proxies의 “Web Proxy (HTTP)” 항목을 켜고 localhost:8888을 프록시로 연결시키면 된다.

System Preferences에서 HTTP Proxy 설정하기

This entry was posted on January 28, 2009 at 11:39 PM. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

2 Responses to “KT 메가패스의 인증 자동화 ⑵”

  1. appler's me2DAY Says:

    appler의 생각…

    KT 메가패스의 인증 자동화 ⑵ — Code Metaphor 프록시 활용법! KT는 또 막으려나?…

  2. znmean Says:

    멋지네요. 저는 ISP에 전화하는 방법으로 해결했습니다만, 그게 여의치 않으면 이런 방법도 있군요.

Powered by WordPress. Styled by Hong, MinHee. XML Feed, Comments XML Feed.