Authen-Captcha-1.023/0002755000175000017500000000000007770230760012756 5ustar emhnemhnAuthen-Captcha-1.023/Captcha/0002755000175000017500000000000007770230760014321 5ustar emhnemhnAuthen-Captcha-1.023/Captcha/images/0002755000175000017500000000000010344146004015552 5ustar emhnemhnAuthen-Captcha-1.023/Captcha/images/w.png0000644000175000017500000000035107762723166016547 0ustar emhnemhnPNG  IHDR#&PLTEfff̙3334gIDATxՏ 0D/vyGbӃd {Vx&D-SHE lTd6(tyAi4+gjofs9MnRZ]oO /Gb D%DAzl`@ \.+xowe|{n W鑼!^ SֽIrN QZ`p2[PDTlQ:ׇ@>r/.̕A&ۏYS~ac̨+H-Y1O$a8P" o%hd d܌s9ebE08S`ED+ Uj_b?7ɺH;}VTJ-PԗGdRAi/AgN'8=5IV:("O~̎Zɖd _ رei Nrb'+`[!+*nvO DilB[rQ0lu)Fґ,_)ZSulWYxW]7}+?o3jHZ%,wF bE$/u aii -p&{" Cxl*b1vղ~WƄfWa~Nso!X[Ωb q sQV!$$޲*P*2^PPz`nʛ^q?4vk"'6Aģ&COeASn1!.\\0AHi L0KfUZ@^8 pA)_Ŵ?"N482P"X Ղ#SbXhRBPXw<D l{M[21A0!0 @Q ARZhb+/jl)ݮm;356# !&rkVzm|yyҘ/+p2^nu;YjgP1x<0)c$0 DTw& /W|˨呮u)5tbröű 5²AapֵCT0! M5]SlsEredbӾ7}·.˗9lڞXr5?4I> TX3>`\V(4iH[\*. 4fsEdR|V4?Ԡ|;"^+4܌3ه9إ_Ԫd@~[|KD I(23$w->Id3aՆLkp\n9@m Pclo$4֋Gr3 ?n "PR/~7KlV`S[2Z}$g]kе9bۥ-gdFUZyo3LN"{ R#SX$RVOmbk- q AxYhiQB4c/>&FD ¶:zdvR8 YS> h'S&/Qivޑ"_*΄sUe0&5?{`0ޯIo5Qyrݺz؁14SX=3yT O( >Zܪ*`T1-Î +&? ;axN6_Ӛ| \S lAM_xo RIMjw^ K1 34>x1?Kzs*/ W>̔kB$۬Sxr?QqO/jaJ;h-6]0VH]stK0zb54$7̧^O-APMg-DKlhbYIl~v4Tc.iArϩ"<˧mho@CF4Gd(ΐ|E/.;"sĔS&͚}hgZ B%{4Rl+岂0 DimR,q#/j$=GÌOX*SDOVa߬ SY;`"wꃖ#1{ОhZ k7jvPn3j"fIv1_=E Jlf  ;'!U̺thދ&l/ãbq AEKkR_?Q.TN|_P-);7@]LG)(8IE)1H2R`9@B]MXx#y]m?2/~+@?,56fh3spG0v}6^:v#/jM(yր%!eH< ΐm`MrQ11/7W6$'sqJd@)>%VzSOӳO]A fМ(0I{`i4Ɖ5 i_!d7ڣ [xzױCy4pe9vuʜeS/N!fn4=d8pץ'NbABi, W[uaЎu8_ev\ Z(9tjy,w"hCxDMy(f ¼d #e貔c!s7R 9> rp8(QsA .Z5l1k-j9<SzoD+af( Zv ë%hx2FZ zB`ff?2>ݠ;hI-}bpΨ hԶTE_ԙú:# JHΙOFڨ'- 85r2QŢHI0]-J@R`@ ;vIENDB`Authen-Captcha-1.023/Captcha/images/8.png0000644000175000017500000000031507762723167016451 0ustar emhnemhnPNG  IHDR#&PLTE̙fff333ŜvIDATxc`2q1q\ S\ FGBGT)tqccS py0(HUEL'$3v>FOf=3Jmb [IENDB`Authen-Captcha-1.023/Captcha/images/k.png0000644000175000017500000000026407762723166016536 0ustar emhnemhnPNG  IHDR#&PLTEfff333 A]IDATxc` IP(h¥@@g(d (Q'(CV)S@!dW;  ] T*[ERܒYQIENDB`Authen-Captcha-1.023/Captcha/images/x.png0000644000175000017500000000030107762723166016543 0ustar emhnemhnPNG  IHDR#&PLTEfff̙333jIDATxc`@PH( By ,Pe(W* (h( W$PT'/h*S ME(hwY#C#Pp*eWJ1PfIENDB`Authen-Captcha-1.023/Captcha/images/background5.png0000644000175000017500000001622207762723166020511 0ustar emhnemhnPNG  IHDR#gAMA|Q cHRMz%u0`:oIDATx 1k@.wIb'.8%_XnEl;Epr{ntfF%ggYe@|gQDY媲S^':l_DZkm%P ?i'AZuA=}k$+1`}Jz!mIrޚ Ogӛ MKA(1"Tdؖw?btb"2֏(6q$ʚ_1*J|[B"l L^sޭ/C?.j4ػn1gp}r8S|vm?a0Eaˌy#&=7{1-+%Q[JG*$ )C%Y, A >Քõ [\HJ$q,AYʸG%h7&e@p Ҁ^z".޼IA~{8.Ktn,ʙLk7oӦ=qY/ o.6h  !+."%/;/)463A 89 "P0Lo-CwnhA>'_AI6f}i))% *LbѰ闌PD0LdHJذ0xӪb"ѕ2gLϼ}5;e~CZ&w-X,X glԙ3YGC„z'GIs6޻pdw=]6h    ('+*(,.9F "  =%IR6f    !%,-%79!5!%9/!CI '2EVPP6Da{R :aeѵxmM5EF`tL_#^EAY^-#PɄDN f9 8KaF`^2Ұ.X2S8ßÈ; zs?Gc+sW;- N(W6$RcϏ3I:[_y~\go5A5t6i          ,-2#$-4 C$E)(1CD+ (&% G0TJC}K^kf[HQ44Z@D0I,f[9!ϧ$ ؝0k@Fs80aPyXE28*YB4LQ,j.v֜ kut[^5kmֶhu9?| $gyAj7MH\4mßv6       && *&-  $22H#'L+N*<$E!HE!P6n       ! #('+ (# 1+=C#N+NG*KE#FF*9G #L6^     # !,+*C"C'I'> #%58 EL-6R     %   + +336BNEPL9FH'(G6>     +# %02*-5!$C$ $$@ 2$Q6C)L(6C      %#  #)74G'Q+B%L&!?"CB1#6?      $ , !,-$0, &&L ',O E:HD"%)K6B     !!   $&#.6-,NLN$ ?8IDF OM6Q       "( $"(+- #1&?P A$=B8%,-"+6h            *!  &" ' EQ )# @;?!!SHQ)"6h         ( $.% 9 ) < =H$;A!H2V!'6^         "%6"G BB8$I( "!&"K0\6 aܘMJB*Jo} _/`[hh4{j] H07r\^J ҊˉNUQy*81;igׁR]:g45:{S?FI?B#󯂉!eվ6!n07}]m.Tw"W~p8u6C      %-.& ,8#> 2 C31!KJ%*$(" :-X,% O6+        ) !"8! # *(!BEKL6;      #(2 " +3 *0 ) 5 >; $5 < N媷!|0O2L*Xi!Hi0˩`ߣpg yR&$6d    #  2)(( '"$'7E>D 7:'?9#: %D=6e   #$  " / .3 G3@EG?!2%4"#6Z   #  +)  &8:! 7+5)";,6d     !  6*:'((L/30 )%7PXw+Cq{c.$J ^W 1a%9=O 0u%YIENDB`Authen-Captcha-1.023/Captcha/images/9.png0000644000175000017500000000032707762723167016455 0ustar emhnemhnPNG  IHDR#&PLTEfff333̈JeIDATxK0 P6{R.@2 @*z8{S>c]OΨDArB*4k@y\ f~AdѫxXNQ`Ejrnmx7NnuGD_aDBIENDB`Authen-Captcha-1.023/Captcha/images/l.png0000644000175000017500000000013307762723166016532 0ustar emhnemhnPNG  IHDR#[3PLTEU~IDATxc` П*e^IENDB`Authen-Captcha-1.023/Captcha/images/y.png0000644000175000017500000000032007762723166016545 0ustar emhnemhnPNG  IHDR#&PLTEfff333*yIDATx P@ 8-ϒ8Mhr=A?FQӆ:\MR|].rjA.w4z$ PoIaɨ$dn& A*HiZR^&E0ĂPkGg킜IENDB`Authen-Captcha-1.023/Captcha/images/m.png0000644000175000017500000000023407762723166016535 0ustar emhnemhnPNG  IHDR#&PLTEfff333b8uEIDATxc`@PAYЈU c4p ^ ! ĂB 3 (' A &Uy /IENDB`Authen-Captcha-1.023/Captcha/images/z.png0000644000175000017500000000023507762723167016554 0ustar emhnemhnPNG  IHDR#&PLTE̙fff333oYFIDATxc`@ 0OQ(a@ * 8hf !a @9!$qaX_ IENDB`Authen-Captcha-1.023/Captcha/images/a.png0000644000175000017500000000030407762723166016517 0ustar emhnemhnPNG  IHDR#&PLTEfff333 =cmIDATxM af`tÔ☴ i P-8~/@_eGL.M։%diѭo T7'ڗ> GD "FIENDB`Authen-Captcha-1.023/Captcha/images/n.png0000644000175000017500000000022407762723166016535 0ustar emhnemhnPNG  IHDR#&PLTE̙333fffv2=IDATxc`@PAYYc[i3 ޟIENDB`Authen-Captcha-1.023/Captcha/images/c.png0000644000175000017500000000026007762723166016522 0ustar emhnemhnPNG  IHDR#&PLTE̙fff333ŜYIDATxc`ԀQYSq(qqK20@t8 <&G 5|y`S`LFW$P݂NT?ҩIENDB`Authen-Captcha-1.023/Captcha/images/p.png0000644000175000017500000000027507762723166016545 0ustar emhnemhnPNG  IHDR#&PLTEfff3330LfIDATxc`ĀQPPXs D@4eIG((PPf 4@ E'b&>C}(nCAj(P8C;xHx +ǵ IENDB`Authen-Captcha-1.023/Captcha/images/d.png0000644000175000017500000000026507762723166016530 0ustar emhnemhnPNG  IHDR#&PLTEfff333Wl^IDATxc`&`*Pc   4apXEBX9 a0CՇj&} @N?w 7VIENDB`Authen-Captcha-1.023/Captcha/images/q.png0000644000175000017500000000027607762723166016547 0ustar emhnemhnPNG  IHDR#&PLTEfff333xQ) gIDATxc`@Xq566XcSԁEs6```!L!ҡ^CYD:@n35YJ=mT\)̍ 43IENDB`Authen-Captcha-1.023/Captcha/images/f.png0000644000175000017500000000021007762723166016520 0ustar emhnemhnPNG  IHDR#&PLTE333fff*%R1IDATxc`2vDpM  %* !"#$&:'()+6,-./0123457>89;M<=?F@ABCDEGOHIJKLN`PWQRSTUVX_YZ[\]^abRoot Entry -61{Catalog2 Y !"#$%&'()*+,-./123456789:;<=>?@BCDEFGHIJKLMNOPQSTUVWXYZ[\]^_`abcefghijklmnopqrstvwxyz{|}~ o_##RGBARGBA?>ږ[/P8ѤbTWWVԴoiz݌ƍ%8%H8ºxK.gmN4i-fh)*A@8u~3>[Cqw[2Usr,5o6ֱm ޝl|˕WJIWXx3ZŴ7zu/.U^g1)',rOEuPAd޺C(e 2]@!2Aw;IaXTw?±kh'cRM үAwetApт?iW Qwpa8WhS|z灴Gw}D;80Pyh`({;$%[irm UR_-{Jzj-^N7< qv\BT|KWӼMO\]Ŷ,п%U%$ǩ>+h'cR׏O4 iEKEP~.|StP-(-+@~CA^M@rۢnc(<AU xGz.xoU7KenabyE^-Y5MwZ푳c NX+Rvү|Ƭ-v1'Mv);psW xcVMS]dly ;`(((((((('``|4p.png|4a sc##RGBARGBA?Bf 2I^HU,I=߉ '|Y־ oX.c8xbGu>AȬ_hoiii1<1\BVu4[뷴4QOPr(-5/PԬn:A NATΗ^\jVw7VVxa] Pr }*KMgK/.l+;f+<0ήpC(9SG>UW;m]5EIiKםew=$s]Y.;^vj󿍖[TϚvd[yO!6Vͪ ;_Xs=ܐ&B.OY6odX랴VODu}GQBH?̓ r:l^MWui$ah1X<#ODu}GQBH?̓ r:QEQEQEQEQEQEQEQEW z##RGBARGBA?MGUӴ{as@X eK,@tu];G: nfXԱ2 *MGUӴ{as@X eK,@+ס*; z a+3405A6RIס*5[u['g.]3g 3]7'Uq}%ٜ;Ipz5[u['g.]3g+B(>%ivH*~\/|%}K'Ө1KNT29&x^JDO)Pb"dsMG<˟ x]KI)XdRY^88O.|-u-'TXaId=zg8?4xS>,ԴP>yb5OE%ꭜヌ?~hs}7ۼ3n=sھ/Ínow}ѱv1W{Wq?Mnϵ66n6|j+» *{8۫8+T77VqyWAqW ?3nnn"<|~gEr=6JDCFG#F<{m'77B/7OG xOo +#n^n} 9(//n,u \,0n=>V7:{.Eche7a@+GKBs="14L2sϠWWWQ\'o_ ] x>\rb= ֹNƾn%0pL|N;zӭs7𝿍|)wJ`2 r)ʜw'Z+ &?hlifQ(;xߤB39 %t#o¿;cBZbY#DdtW|-|< XԮIu$cTS2z'zW߇ mJėRF>QE8'rzW|-|< XԮIu$cTS2z'Wu]QEQEQEQE  ##RGBARGBA?h5$fլ#q{^NOC۵gKjIͫXG~+l(%njΗ_ѠԓMVVPJz)9=nVh֍QExn|2s/\p1xn|2s/\p1xn|2s/\p1Wi߳dž]GT_젡)<N<0::e 1HFvwgqᄗQ/a{((aB3稢gZoFI:d'9gҧf?R׼3j2M9$Ey9n=={0:;QiΙ",3cppﴩـTsO ~dgsO ~dgsO ~dg^ON/:Yƿ#bI,ne7vqxφ5?H!ev.ϻ ǿSN|1؄A /w}ݸl=,?- x"Jn##pG[?^\\rb= ֊aGqbh|q97vc8|' h&Sq_7n81jaGqbh|q97vc8>GQGQGQp;]cP#J+b+b(((( =-##RGBARGBA?n"|[o X&^b=Hvߝհ0xˎy$W|#ᣩk#pۤL1b͸738~kn2ƥ68r@z?j:7 jDc,ۈs1WWWQTu6-gD&wo$ FR?QtصLݼ6}HGYbtK2` wv@e#_}6Ng8=+[ >u' x`ʳndW{>x2Z7d-8u9r01 5veVO)p ,'p=+=G׼i_k U2'lgg~ ֯@zݙUFu 633J+kx }CKYce[';cpvpOm~!|/iwK,zly$ln`:` 7 .IeM1o$=•0bXF$k)zg$ 4W|. ,څ̞uԉAROC>6s̳j2yR' w=I>zg`2ͨ\]Ht`*$Wo]vQEQEQEQEW ##RGBARGBA?t[?BywwNc>_hO;yӚ??l }s;=:sEhVhQEQEQ^'YG i;d ]B 471<|}VWo!b(N9g1 ·|BTE7;wh:00`zb+mg -R9ݠ|=-,HSsGvs v"맮?'I~l;>׏Z?'I~l;>׏Z?'I~l;>׏Z+YJ5~ЬX??hVR`/_E𗌃:howP0V(ʈ `t/"KA4Z跻(+eDn0}:K|% -t[D 27v> ((((+ fV##RGBARGBA?6 \R@q9k*Oh u5.ۤ wsƲ6 \R@q9h@C(e 2ZPAd޵ #WoufKiF6qp^sYt_/G-8_ygQ~\]dTl`wTW= ~iwpK-rbg\(;>Rq=9{?<P.R$J8䓓Iqflltt@HX+0SNN9'隯%!,e!bDÉNI9;H䟻RRRyxRGA Mw"?NH85—<d,%mrA8&x>C!a,mȽӒ94WiMv4CtJ9Oעhѥ"HȻP0\dݞ5}ƽFݥ-0yFE%@~y/<=$ڕۉ.| qO^oI6vK#(¢d׹=+[xA<ͩ]H00 dOJ+껪((((+ ##RGBARGBA?i'aլ$AK2NGQ۽gEOëXI~-l(e^Tz΋_ѧԟMVZ.Pʽ:9GnVh֍QE|@WךB~kPy{8Ms4UucP++~lĎ?\ ?_|yjX. 漅 ǟ#^Um:wo`Hb%|xdf{>snfM'$]^̚Owm$<ܜdhLLLo~.o'`wlfLVx:<7ſ]x7X0KVB3KcBc1 3›eH-fnd>1 3›eH-fnd>1 3›eH-ZZZ+kKSgˑNTG=:= —z-Ħ.)ϗ"q؏Bzu{.[L\6+MRҖ3$DWW[Cnb!M)c1-OTO@|x忄>6+MRҖ3$DWQ^/x0H&}$=O`+|oxZ& 2Od =zmo C b[̐?Az맢(((( ##RGBARGBA?{=2K--cFIw,伿ppx֩tص'հ] ppZ+B ẅf9bqx11*21 3141 2B[8ʼlOЊЂxnYXe^6 E%IRQ^InQy$:Du\?Ÿe;mrPr_{O^O|GJe6tKxF(R9/x积vj#2i\%k#)&7ikz&Lg}h2U#kq^cxᶝjriwֈ+\6}V}#WW=OIahV&\30Fy IG}ysh ^w71~Fލ>U{,$$UMJyMrHnrNOSѴ{ 'K4q#;9?SN\$|Ϸgޜwl$|Ϸgޝ#wǩ<2vh2Hr<=W=:9Y57 2Hr<=W=:9Y57L݌R$9ZySY@ݴVBGA僜'*{cZ>,9?1SczP47my`!֊2Y+: ^|K4x̥a_1l,2~g1:%̸ozbI2XXI2P$ŕ?xX&,=;RQC GDw7NWmsi͛< #^.[]_j'd{=3ft?ן˽qvWڷ&Lٹc.9EQҮR77HF-݀'׺U][|<y%BJKo#|/$vҊt4 8gpC'=}$l4aĒC'=}$l4`q$O_z)4Ⱥ lIc~i%u@.$y&7eI>i["뇀\HbLn}ɢjwms*5ڢ;qc8n6ڥٹQVS8z7mRʏov)qc8KgH[we6ĀÞ9fKgGv.xg/.Qwn 0F~{"d6`YKʣ$s]Eı4p[F 0)~YTdjn%6`YKʣ$dQXDk e3ң/ ]j}:AjgAFqG_pAEGKghK5{Rt$0vkSYrFr^4Fc! tM t#We/Ft$0Qm x@+f\ ߐpi -72DZ]2`s84ie&H[e s84T7ӛۡdKlLw72G^~5 Y %%;ۀ#?s}v,̞ hxVx\+}ŠȵSwZocZǽAj)xCcA?Y|AEIZSԞ=v? IoZc[_ x5w [ן |Uk_׹uZAUe{Ef{6f|;n?3Y?ͿOZX?ӿ?hǬ?5|w v\enָ?Q 8g7bIV!^Մ7׬?ɫoXXQ_ ``RGBARGBA?lqۀT69M ;p =)nP|Z[cHKli/im"B?֢쮔۔,}1Xk])(XcаײSnP9?a4V睵<>ҵ鼑#?HYG73gVu팞a`sy_PSY׶2y!ϡ}AMg^>u4UmXo\-vn v mXo-9'Sʘ+ci=T[s?kNIr0s=38=38=38F$p[421#٧4e&*L=?U<{/_?#W{"_(3~GDQ|g8VV!]g~ײԔJ+l/ԓZZXv-yh_C3g_C3g_C3gxX)bǡ?GUf,POcПX#^ X'OSPeFhdlT%YQ6[< VTfAV_on)o՘~on)o՘~on)o՘~TlIH=qӎ9yq;)Rvatzy'NTw83qTD2#F;pTD2#F;pTD2#F;pgQU0b 3ӷVuE^c 6*=;~ugQU0b 3ӷEp7.^^ܹ{'{WruEDzDzDz4?4?4?V!!?ΰ/ uH}OA3Zk u5c] yЅt6i\Bǝp_QQ'݋TIbw(Kb,?԰(EտPEտPEտPT O}S@4W={"]A^7ܓUI$\J~W?sҊ ``RGBARGBA?-jbdX *cfq볻Եuy`PvR֡&MB      !"#$%&()*+,-./0123456789:;<=?@ABCDEFGHIJKMNOPQRSTUVWXZ[\]^_`abzdefghijlmnopqrstuvwxy|}~1lgξ5, @G!@=fI<9`gt< =2Mii;.Q8PAE:Yt[thQqR29epY.kqj.7\ FG,49e-n!ѣ[EH9抏VM 3n$oqQQiA>~-č9=Z; 6('#;A#?,:M%C';z,:M%C';z,:M%C';zTz__/\hK4iR%=03'&.dӬѥKX$XDNKF-b\S5=^) 7o2sf!#QFN}Lxb2$j2]H϶({WԵheD1=sھ D- &=-xZ%h d)0 AEo]j:70(g <{C/}OKGWheIuiu\ќt ?Ί΂+F+F0OQ-"^kmz΂+F+F0OQ+m+CXaӐq:kAbҴ1stX8u*kK[V]yY]m/mmYvIR0>iev?¦e' H *]iiohfT *߰^--㺍 ʁ@U~uwQP3@ ~V/N"Lwdwba-a ^k(QWvGLV/N"Lwdw7)I\oRWȥ'rOU;i*c?_E?Z)k<pSES??ҩyT?`?QRhf4OQV.¬\XT? *v|_Sx:Y/q72Y/qU{o 5^BWp3EҿQw!+ҿQ[gl?f|V[7W"zW"zW"z+ ``RGBARGBA5161'71>f81L ?<)IñĞxSYK A-Q[ȓc=𦲖Z'{{Z=ݠ̌*>{Z=ݠ̌*>{Z=ݠ̌*>WZ\ͨ7ڄ\+.fBI vw֗3j $Wzp;{ +g0zWQI!`9“CsaEz/b`GPa"_((1"5DQPbE@#h3h[3,n^2=z62#ފ[̬N3\ԋv2BknHW28om,6s8$6@G_Zl3Lciuom,6s8$6@G_Eq{au<kU- cs\fno>^cO)x:֝apg]\*/ix:֊҅c?^MjiB1U?Ư&wo*Ev^5- ǃ]KCCe3R`x4W\b&q'K=hM/1 \N${q^b@9ǯҊx6),{vk.ۀKGȸ#nǷoƊY S,+gNs_Ş;rŠ㢜MaU[rOj㢜MaU[rOj㢜MaU[rOj+ӵ׎${BF#}+ӵ׎${BF#}+ӵ׎${BF#}(ɮ2@$劓eZ$NX+άs{SECī9<*%YldOPq*ncc$2?J*Hdϙ!;[>f3ҤKl{J+R'҅(³zz֤O$ Q[fHHJ E,@͜zRl0 O,@͜zQY[l) 0]ş=-\.V|. Fqgb}(ؼS;J x,p3oŸbL+\)= }39p8(FI 2DzWmee?& $$8M<;0F08Rjx'va`.p=>Oq\z}IQ|4ǻ EӲSk/E#N=O@4 * 3HL/@4 (;xᰋxkNl"9?ZӷO֊IMR] jK$63s|I' ^Oe6pC׎讂ؼf=e  -mmP Oؼf=e  )dX&qۯNا;GmcgySn;b@U BnaO=*#!+ D%sᨏ4Uh뙪3Ufп{ƅ޶4/VnwVK!\5K!EU~#Uu'u]GI]G4Tv /?'t_Q&Oʊݶ}O5mdkv?Ud%|!Ud%|!Ud%|!ENЪtTS**!p1Q}QOS'p_id >L ZJ##RGBARGBA?nEX]iy26ԆkGcI<ͻaw泧\RL'$+6Z%vΟms#mHfDv=0ȢDWF VSGuу#U+AdEt`e9z)u|aMׄ]Xam!g(XH# />)L7R2 It!U{W7^quc)UA`I *c+W j ӵ-n{KQ[nE 7 l99W3௃~<jZݤږlR=̊An 8rsg_)x/NԵI-Fn{ 0p'Et  5 9u϶rZs'F2y  5 9u϶rZs'F2y  5 9u϶rZs'F2y{]|O4=֙kߌ?.OLW=\wOi> ms%s5|O4=֙kߌ?.OLW=Ep8xz+i `ڸ,}Fk>1Xx{Ğ`,a[H8Wlf3\?z$޳c F»f6 0=Q+gp_j^$Iء12M?t H~3ڗ,aC(LLc'O2z{zGKll$$@R뿢(((((((( ##RGBARGBA?ZkEvzC2C ;AȪy%equ̐pPr*_IggY\]D3$0#}T+ǿgwX$oykyvg7t߳ƻkkjOټ<3p:z ]5I?['_]s8=W~*м+gK+&CP lP}FGy ¶z]d1ܠedzב~*м+gK+&CP lP}FGi>xjBUӾ aìd6դ- WNT1SKs`wVg%];Pk M.\:Cmnq߽~̿4֮ۧKe?r_/?+  g-)bE˼l0}S}k8x.ŞK7tE.ÅN;/xR}._ҙ$\߅8֊Ҿ5^k6KxWT%f!$pĂp;+UdMuI)x=OPt1u ?] oRzt>)x=OPt1u ?]91(c02k12 {22! oRzt>)x=OPt1u ?] oRzM}2]Bm0f:Q_@O[K[-F УT~0=+6[iu ehpGjU((((((((+ {##RGBARGBA?m:k/$*IxӬ8-BK!ªm:k/$*I̤[aowy[+l< 2B_ uҒ#m?Wh:m*=OH7/H Z-_MGZUc^_=";W8ܼ#<}h*ҭ*+ņxF'qN8{)qĢiHFG9WM-<976q΅1-"9%7┩>x5RYо#T9$~q^?R4ï\ƾJK:`$(uhGʞDek']g&򧾑mAAw8'Z> Yf>|F[A qPy81 V+t)e0YV eV<9%RaqN;8?xr/xKQХ.d;X2wqEy|bχzV-RIc\N1xgË=+O $|[ر.rNFGGh3𞕧 fԒa-X9'a##ӂs6ޛ[cQ-4@=` y5 Si dSɯ\n:u0 M0PE zM[EQEQEQEQEQEQEQEQE.png|4t.png|4u.p td##RGBARGBA?VׂuHtLu"[DRN v< jc[^ !u3w-Ԋmo-I8f$2}o x'TMܷR*%A$ᘒc+[0&dP22=kK8.c hE 0@###ֻ+[0&dP22=hj(8Ao:8A󢾀+ ((+o5%y?펾f?_(h. lu1*CG?c woO{c7Q_Q2_MX˪CQFr)QG'OzLh2QJToQ6GS5%51=mug*rx MrU(+Fs[$&Z԰y#N6;:W7uƶ,HL:`GLmw ׌tn5ύlufYG5;c{^Vρ~#>m}|3h=qڶ| Gk~kD\݌mfճ_?d_C/Z"~ck7\v +XڤnUfIˑ?y<|9HܪͩĒ/#cP ?*ybsjUS$_.FW]MW@\ ,M*AI'>x7Fo>:|P=ƗKF <`{Iϭu Ѵυz=kqт,sEyo3Ojٗft忳/?+ ~|]; wQ 3'rr?:~|]; wQ 3'rr?:~|]; wQ 3'rr?:+ƙ?.OdX0һ i /#txfMuC =+ƙ?.OdX0Ҋ~ Ov3wcn^/oocWG&fܽ}k'^?M|q1z^^^EQEQEQEQEQEQEQEQEng|4v.pngh94w.png ##RGBARGBA?|SM#S[Et"RAr1О3W~^ijkv(nJX.Y:xJ|]O m4MnM"K0BxEvPAd޻P32"42#52$62%C(e 2]!2Aw(}GKHm6Ax*GUz~0xu~+?ңZ#;U~FA³pyc#GU_p#X+*;9#UWd+7]Mu5^/Uſ'RX>xA} -?ļrDWUdoĿ 6O%sB#B.x $SEfHܺ~mDQ\ד+#!-:q%XW7 jDtƝ8tެx+ЃGOktKmcNIg:oV< A#ڊ𷏴Zo{$ 5H荻'נ3oi^1Ե]H,c4j vOAg#>Ҽcj6=X6ǾhA#g6^]Mu5M8u*!)G9%6ZsϨx4]^t=ef3ONY}rJm>W>𵇃9mi,9?v|#kxrF17I#Ys@_DG嶍cnF4ڊܭܢkw:w>`o3{m2Xy9ΡgϥXzw< :zp*sYsV#?gި% +t^ծ|]1>)$sj8^?5:GI >.ypX9a ` `#ׅukLOuI<,ڰW00 |2V>]'v&+"ΎAq$9#oS>G .́AsG ~ w UI]\E?uq@k֊(((((((( ##RGBARGBA?%Ǎ>k:Ny˿isH9*ʒAR+_IqOΓ^xEnR1J2T 1\xꗞ,w9[c팩$ u+ߣ&%#ea9hX2:Vkߣ&%#eau:EQEx  \Ӿ8"fMdL q'/?)/Ѵ|pD̛O_,.~#|R_ X0+isN7 0)L෈OV`ge(lοs෈OV`ge(lοs෈OV`ge(lοs +˙p[pTd  +˙p[pTd  +˙p[pTd +>CqƗ5nvq8yn5pS1ƭ>r>uQ?/  Ƴw^nw8չ@=Ϊ8gT$> J[_ p3¨v;Gy!ƯJW"ݠcGs?~5xRn ;<"(((((((( ##RGBARGBA72& 82'*9203?=[RFѯKEQK2@sյ(tmTY +y.$X,U$ z=[RFѯKEQK2@᣼@sCk᣼@sCk᣼@sCh_tk3iz] [5hT2c]',> hObӎ=G+.'-_jgBfQOAE[D4['FV9ݻ\vkwඉhOM.`4rwF88=m>oڛ{H]Zh#v1rpp{>>>((((((((h94z.png|4d.png ##RGBARGBA?u݂Yk]4gv fc}wXѝ*(%hq\mGj0/.A@o-+m>hUF?(ҳE]s-\z /ڽ_x%/8QW<]w:/5]CBK?QO˱gz8'e8s|3#U4$+JܻFwq]À:qW<]w:/5]CBK?QO˱gz8'e8R?O5 jEEK8U|eX˝"EiDQĈp9*O^/N>Eɲ/fD&L?{n>O^/N>Eɲ/fD&L?{n>O^/N>Eɲ/fD&L?{n>UIaY?TU{qyVO^jEEE{{{QEO兜~e֟q ) ѰQ#cSnaguuC nsld2HX,XY]]i›< :\O k>m冹gK5SI289BGU?q<-G.eO5$ TUXkdPy<ԓ(c$uSQ^^^EQEQEQEQE  ##RGBARGBA?6 \R@q9k*Oh u5.ۤ wsƲ6 \R@q9h@C(e 2ZPAd޵ #W~ek=2vmVGW #K(>Ċ?,<-gXNM!!teؑ^Gŗ Y^D$7,(BWB0$dVf$P~uXZⷻF,䀪sӏι _v\Vw]YBzq^_Wzo.]^q70$ o> w*y!|@^_Wzo.]^q70$ o>Wy]wWh-<1b,#KGcŸ}5[xb 4Y5>F83*0Dž>q^k4ij:|,qfT`(= }#͇R~kUۿzn8#͇R~kUۿzn8#͇R~kUۿzn8+1xFQƱ7yF0Lh #>۱]x32N5QΒ1c@T'1݊ x&jqzt=Q^^^EQEQEQEQEQEQEQEQE ##RGBARGBA?M; ";_&O}~=}? /SC'<Ͽo篷Z6%h}|?矙EtWAEQEQE|7y¾?_?𢾀+ ((+L5^%}@\_~?0?{Mrw{ywOξP     M !"#$%&')*+,-./123456789:<=>?@ABCDEFGHIJKLNPQRSTUWXYZ[\]^_`abcefghijklmnopqstuvwxyz{|}~X 7"W=w?:+=&mGF{xLA(r'No&tkۋI,縷Y-Y qt+=&mGF{xLA(r'NW*QE4]x$C v8,灯C+"'xfH9f8<NNN,+Rmt.{Hg.JuڬskKǞ!+ԸfvU*j\vς/xVK紆xRTG\ 9q֊<5ͣxWH6y2JD H ih4F2GZl7t.i쬡$d@q(JԭJ(((((+ ##RGBARGBA?M; ";_&O}~=}? /SC'<Ͽo篷Z6%h}|?矙EtWAEQEQE|7y¾?_?𢾀+ ((+j_;?o^+j_;?o^+j_;?o^(ppp((o͏"?yqϛ,l#>|Oʸo͏"?yqϛ» (((((( ##RGBARGBA?3ooo`M5ԘX|Aϋ#ž_/kkՁ4Rbf a+>,|_oV]I Q,UxFSXN5*(=atmE5ORymƒ:νFSXN5*(=azQEQ^?G<+yV?-x$O*Z+< $_ K^O'UZ<R]tQEQ^?G<+yV?-x$O*Z+< $_ K^O'UZ<R]tQEQ\ߍo|WcC/MCP7 EtTE. :/K[]TՇz>/K[]TՇz>/K[]TՇzxN[|#**3+ *?xN'%mʒ>n"2lIңxN[|#**3+ (~ ֟k.PO+Ϻen.ESg[]]ivZVy^}h+u!p53;E63O73VO83dRĜ @*ɏZ+ x~ѬA-c۸ Vc^lk|X ՘$ƾׇ--"=uf8I'񢵫Z?$](ow:Huw҈@~Ɵ=sa!״q-6H- @~+}{ SŚGu8p"iNhj,>éÄiX.F;OzuxCTfN#Hp?1}GӮ]-t\1 /}^_3nFs{?o c cW+۶E^B@g6_g;q׽x'xB@g>~n׵ !>ϲۤg8uG|1w,t}g/vN1{Q]tQEQEQEQEQEQ_4i.png"|4j.png#|4k.png$|4l.png%|4m. z##RGBARGBA?X?,A}=v'wby?|޻}>_θX?,A}=v'w» (((?Ww|+>W}EQEQE|7y¾?_?𢾀+ ((+Y_~NO/^ .'owo}ozV_w=ӿ {^^^EQEQEQEQEQE C3##RGBARGBA?G }&~g;cYzz~#>m}|3h=qڽ?oɶ>_Eo_? G?ٯwn}޿XOzO'Ov G?ٯwn}޿x>}Ȉٷ9=}?wns{㯈?k[_M3"#cfs/L +iO_?̿4ۧ֯f_kQG ??Q7yŠ?ihM̭oFkeo{4W}E|?<Ӭhw,/I YNdwJπ~&x5u[+[ [XlY#_7ʲ>ßLjVNȲGt9$4oe;q}(5_]QuXKm86PrMO4Ο[h8Y 3j}?MWŗ~7nt']VAĪ@T(1EYռ /4񅞕airm̌A}'jvcxJ496efF ͓G;qVuoB1agXili2#_jfڣֽֽ֊(((((((( F6##RGBARGBA?>/K[]TՇz>/K[]TՇz>/K[]TՇz x,#;[ud9Oz<-K?xr\xnI]GU=,]Mr9㵺߱'PmvC T?ex^/7ΒdAyri Id+@ZM|&D ĞH@?ex^/7ΒdAyri Id(» (?$](ow:Huw҈ ?J> !пJ$ ?J+߿+߿+߿(+ )hjNo.-꛶̌ybɮ?▉ƭ6hީlǖ <)hjNo.-꛶̌ybɢ ⿂<mo[lM6̶b|n[Hpx.H.˴m/l\#0ܷx#O{|7i`,TאOJ5q/%;d\xє?5q/%;d\xє?5q/%;d\xє?+fkfΟX턀^]Gm+!9 @|s2;a QJq0sBP/o0\ 93rHvҲmL3Д ~>|6]Ys;*$s: V OҾhgJ.㹝FdE ŏs9+{ᆏ_ D%Vqʣ2I"bǹWxeW_ީ1ıG&ag1Ҽ*MIfx%>380(^U7hL{4q,QDAGLn_]F$QFX}QޱW?xjD%bQ|Ѹ9VBdwoj/XbE4nUЁ.4^ ]iѹX.|Pˡ8c$+˴/lmktnV 'rp2N0 #K(?hƝw  6:@|9^G{=@*$/Lz?_ob5^yĤCan !vo٭Q.ImCUFXڶ]y΁U0fٽ~^ŧgcBq:f-ȫD:m"/m_,)eQr^,JAjBѴeuS|?`#Mk%"!yr;w` 0ae,shh[{*rKDBTElld&[-ʹ:q̖5g%iy (lCpPFM0|# (FWhZ ))S1 %,y=` 5~; fų#l~yylrki@vp7:_.ҕѮk3']k%m.WeUw| aKR\p\8芻^mY7P\_1yzEtE0 PNV$I`d0M&(ή 4iY/6( FQ"u?5tﶛeҴ lum=O '/b姺8}iZeQݶϰl)}Xu4̋LZ~ AfĻ:Tb5쎧4e%':ߐJf$F޲l =b\7i*O8  ve ~2e< 4. Y90_EYU$ DA&*ExNh"U.@ʋ~ۍF}l;̙_E}^al(i"mNt QFHb]:`U C:JHAwh JX\[EZ{53Kb#Wyj톫/9+g~~ܹ oθBN&t}^'@{بl-iX)5}yhӅZNwZ\#3%*-;`޺.U ç! U8=~f뇌v߿l{JtTPxUATD88-Iͭ*)|p]Q%I%9?y8͎2Ųg3\Rj^!2PAOEOv (,G:PMhtֽV?>x0 ' "t]C3$g+i1wm>{m7htՏ{DBL|2/5=7_؅pzX$x_W78?jb0-T.5Fڑ0nmM z 'FJ̈́?0Զ+聡mqeUAi%,KVznCT0E 6De&[;fe8cUTǢ ]J`~- C1 @t2~w&-g8LoitcndhȖ?elEZ=h̪0DU?VhU"I ]pr‹ĚRm+EДQ27ZEA_:O!Zu?h&W"-(PDBW;0pmzP2>Ž̯GHʓQq*Y5U;6ߪiRvBp.Z[1'$R%L¯@\aD;"UsgiDw7:<lj u#P篆O\P3s~_M@?$Yi p.h V.(WH;[(G`ZhBJV{Ϝ JCxޮ!M?x4K>&uvbodkRFO9×>\A"t_MO ˰!ݏzkIchys̋$epRj9 B2iQPǢX@nEԆ'82d]7sh<'YW̠a()bMC=F{҂?,R MăQ__)3[jFF#9A(99%6yЉT9,4t[>OU6>)\4ZSIUQc㿥I5 UTʢm'PJ:k[b䎪 RUkm^{7qb*6*}a5m+']<'ߙ} O{=ތI6 VS<`G-v FV!?XPР^o^Y;_7;_Jhjm?TvAC6L$Kx4#B"4,-u\AOPD=H1ޔĐ^#?࿕  $ċMzay>\7; 3l46P|^[B5==OFwJΐn'eU3U)/Dzδv@sZlje N}oFq l!DTӱ%UCybQ)"hJRH&.v:\fp;[<F[[UHq1 ΚcaamZ,OOmݦ0 )ge,9)<9IΏN]Nݹʹyeߧs]Tǽ!A~FX.tQ̠a »ThJ4z LRBR Bofvޛ7%vaZ\.NJuSi<ء$rJsbIwW >Uu./޶x#͊(Y {ߕC/u[[f%rU+q Fx͑BN!7t<z|C&-GA4+G; A9mZ™7:~cgPͶ,ע;_\.ӓn$d/ {똆u:V%ZۡCfI4Y\]hb,XȩuImߝ﹋ť6!f?4 A݊Պcs̓ {bPiԯxgմz$ݝ}?f]kKjL= i(߁(fws%mT$Uuyqm~râ{ڏG8ŻXD^dK:%|䫪f>:'RbJ nf{>W ĀwkMp #EoGJOuR7w-^x=o>Z!MbK)ǘKodJwʻV6 Aģ*CL! $ELaY-Uu-h;EQ7W _.?MT,͔ VRdYlfo}P ~ Z(AҋiR[AbYEzQ q&XH(bOn7|z(EצN)?'RX[#= $㫩Ua{>Ҥ UaEO v4 >'&}|Ɵ)PB/e۶N~#zPu;D%IADd{6 WnOXNVupVD$Qn6Mő/n;1{g  rX5QovÁ<+_W&ͧ'a(mb6/ECQh1z55zj8G ?=owl}3 "O6ɚ2/r񹘌ʹ ?8*p7T>-Eg!0JbrElNf),Yy:E#K>bɷ!Udޭݝ U'  ko jgfքI](I]_dx0j͋{HQQWȧUUV!&x+MTp 5&N=M>MYKfT+$]/Խ>,n\i$2|#3_6_aw{UF鉧O.'a Kx0)1Ƌ!GL걍!%\oAriY{3oVz!{#P.|7#,XTfU۸&Mm8w]5W zuj\n zb5^Ȏ~GsCsby6 հC!I+ʒ| Y9!Y.-4"E`czȰrڎnҁW` "˦>`Ʋ5HC>=үY.ͦgA  ~yfuz{ 9X [nIr{ztEҺe[ i )߽WݯTNADgVzTc$+'@ʁhqOj]"YTwWW׉l}|X҃<(v^.{mHF7 *e)ƨytpy!=)k}ׂ$X,X,!X|y.Y[$d\IQkIj/Cd>Om6*^sv /",l0a?C3W ]/[kŤ`&Pp:6$y+%⠕VFA*IS.ݏKNmO! @? G6DLY>=rs۽r`̯LKqDsO ]L.%1#c+]/[+"{˺gkͽ}7)ėVgZ:ZhOwLX|A2C6"b"v&sR3x8B~4O7܀`ywXFKv2yz|a=zJȭ (UIJ%ڊ =rʄY~#祅U`Vk3^&[^ ceܾx#g}7'.pH:FSUGB^4(;3{ nd0]&)W24苜lW4ڣyc2kɃU|ܑCBqrբ<mNmЎWͥ ³ [x`?BNFA$d6Yoa2355'1 b/)^Jѳija pߛ"J[ݵ`ky?C$aб0waJ./ӝbt]|ˇGuqWق|/n,jq r$YG&H$R3#bZ7 ]$!W7F#֡৯o0T(*y煃m[qp4^tO58˄ţ ~;tʼnEa$B L( hɇr :U^Dݞ?x b[GJ{CA/MFz0J%m} F2afcfeY֨Hp᳇um1VaZ /b4IQED$i`)%UUJӴ 2 Qz13 2:ǩr2c 9*aiHGf<2MC" ,s [gY'0|lH>%ԛ/LkBKj4bXd0|ءq2ԤbC^TZ Þ5p$+e=MAlC0MrWAP%Itݶ8:cu]JQ?_Q(ʲLКbۣ#sy & jdY =g]cQ-]Á=Olst80hZbɷl>= @.DX$$/?1^P5At] :M-N;m߼ Ieh` $TkZi?\joE6pA̕=d[p,I#6K6ȅLx0EМȸ$}PHu}?dnvϔ3y&j#Vs0kv0hv;̣Z9@BZ' Ѓ'%*JE&”B>`Q0pFҤ🮘Hxhf s8}f='IVaLZkDBL swlL&ΑLl%= `r؂-E8兽Kno|Uo4ՌW‘ЩU+x¶}{o™Lr ŖHB3Z鵫lIž 4 Qx kAH~EҀ'"TLҋ~&B]vw潙ysVuPi]$rc=^+\+H R( x+Z!tx5xo_%wg,qh̦keCkSз:ŗbX(vh@,ryڦ&asxŏ sշ "|dedM;@?LTBVTZr=~[L0U ;GqX1V&`ڈ3N(ٶͯ8KEIqeus [oIC9; ElDPEK(3G  a.Oghs.'1?ք(AVO1CE7׋ Tizh^ڙ7/o73fBU-Ss!\`#`N{+ɮjGlD-jF=0^Z'ţ֤iWrl^Tv=DݧO/|`Tn*,>K_Ytav+}c\JXF\^'vƂ-5$!J_҆h0}'eud SQDrՁ? &znU]ˀ~Iis:zZ.:lt3jh=r*q5znyzg='T:ϯ#M5p"w T[Mk@[E{* o^gCT/{tA$;3;>XQ?n#pkq$+;DqjPm-O>UUwrdR+m5(J+ > fl!1 nEsz:,'|8DyR7 _!< }xc *!yEZ5MQ}S};1kc@Z@]dQIyZsQz40ʖ¢#)2C*U%DfzPPfpDr`孚wGE4`9y ʿŌ#2V˪< @$ Cq8@ p#C 2(Be-LE@ 0DdCC)Kӌ=k{^W uff =OH/@.hS,C9r)n:av>psAU{99 kF||V2Hb1i !HZ0٪Q.8-RW1^WTtlo:J)Pf<˂2K(Mۣ I!VbYV4X?aW(TYGa&EzB-H|^BHD<O1lI!6iDLˊ ,r0<>FN[ %7JE7Ъۛˊ+pFlKyU.;uGp_8q= 3c7NPI2!piYkl!)߰X ŕ$D"c '!b8 1!/XUoCNfuU撧{ߜXoW+D4^3xXMW2X"5B+.IkԬHId'KA/F o|>6&lspn<Ɣ!JV33Q8 67 kؚ'-ֆi}S|BcI@PA=aR܏,-gj*үL855U7h9 R2=vMFIi򌸅p4n/{5Zj~HQPdɄ,K@AP VrF \hYR. ]KDR4N@B( P H|}DwD ]9;sfn.BdJ'5vN,CٖQh\7#wKbuݔŭM3!Ƕ td{Tl_.(ƒkQ%,Ą4G݊+y)\/AL+^#OF^I γX]+e/vLk0x6,5oa, ,/)tu^تWX-{_x8 SV( E`W^(_ӄH 1 =v7^P3?ulhNXFQ3sIJKXM֠ХXR; '}×k;L~OvrK3m+IXD1ζ:LPunoIaؐmQy4nNg(rV6λ^)3PuW`(M7g`D,?+{[q4jEb ;^uSMab3 `f$s1 -*ViG+I/>&LTN7g& B07yi2͂PtB6M!1 9T͞Е"/c!"8]]s%{־'Ϛ035*Fj3T$V"~"Vک?'{C4̫՗.k ެ ,ҶEȆ#o>g G33!v;W]k:B١qDs΀u(ULJL(k\on/]$p,1a4U/_{.|6޿Jp*aYB`r\wXUg?wpjPXL[%쯉DW.`(AčDI8D/~h9$A3;[5h߾ynMc-91#j(^-VvQR+8sO nC)N]_X3TQz۽n7&E۠F EEJ 9elrwx[ VN2@<"BRkoGZo{-ӑs묪%79F `)fbs(}ldx8A^Mp}O@nYV)05ϒd\ר՞Y|(H >$:xd=FzFݤ-U)KIENDB`Authen-Captcha-1.023/Captcha/images/5.png0000644000175000017500000000031507762723167016446 0ustar emhnemhnPNG  IHDR#&PLTE̙fff333oYvIDATxc`( njcA1 (h3T@9  fZb:eAQLB`ai D<H0Amj . 8 <4tF"  %IENDB`Authen-Captcha-1.023/Captcha/images/h.png0000644000175000017500000000022507762723166016530 0ustar emhnemhnPNG  IHDR#&PLTE̙fff333oY>IDATxc` `P3TA!OЈAUPa``H Gu?[IENDB`Authen-Captcha-1.023/Captcha/images/u.png0000644000175000017500000000022407762723166016544 0ustar emhnemhnPNG  IHDR#&PLTEfff333b8u=IDATxc`QPH R,(*0x@E0"1 :ͤ=- IENDB`Authen-Captcha-1.023/Captcha/images/background2.png0000644000175000017500000001540707762723166020512 0ustar emhnemhnPNG  IHDR#gAMA|Q cHRMz%u0`:oIDATx6 & =A$ $.$ 6)0C^ *#!3%Z&**   p@>?ڭB"Hw D`̶vݪ;ۗVPc%RH;(X*i82CJlP^Be[wld7AݯuQ$xZެQ 6N$g6;|>^Mg&,WyaZDjgA wS+-E.%Ek--܆P`/*" z׼-s%a lb(rSaHKwn먃p[S"*OZ"gMF 6qMRT@ 9{Ȭ{0:Xo2e+; '}4 s!Y=emAޜ`#7§/¯L @EgߏlE0",?h -#(( RLqHj4R^u!Fr|.2p>ռFB Vqἱ@B:8گe#_Lu`~r8,My=kTdqnJfJa}MqL"#:!t e(+X+ks@3 `[Y6lلqCHĭF"#jkYV%<8&4Q"rQ,afiܣF{MK,3vSddܔ0^r)&"_]"- K_ؗmgOq s NC_^@HFr!\*HX6 45-E;os%`6 1C)pId`Qnykpt\F$ ugcMA.ѽ`*e;!) 4ρ1Jn]QZz6 `8tv.~gvj5}WoL9Up9'n ^pP.;aF*邰 bc$S`ςHvT_YAvr4fdE cj4V=E$></Y Nrd1_ e FqAHf1H4gE}UI@T2]ut3Xpz77:|, |/qew' PtFQtN-ZDP"ボZ \qSri$ AQE9e{d6PJշL#pp _Uzu^2zFDb&Cyqh g.I$zIJ _XvrLNb;&7=bh̃}--X"f.ؿbfeoB~=a|J\X?xL$⒢/~e`x_<ϢdP/ W_2*rf`E>Z6G],"ÍZ'H}n{Zg*xɯl2J2<PBbR @tW5tmS,CPտ#;EjQnj~fqKuI/ !$\mZ7mڽ= c{Sru!Vr4?Wٵmt)S؝эO\|NG*@ݽƢ~6DgDwPz}~6 R a۪)FKڰp+,$""!NuPeơPK'+\) Q bE})cFC+p3̓B 8uP-ޑ\6]5{Z:"W`4^N;Egqd3LO/)I ͅ[iI%DW Q^W1LMɋ??+=oOOD } X12<V|߁AW50a12c$+d0%0lc*b7?Uaӵgڴ?,bn.ԟYk+ribx~ Ϸb? 06p?f_,"ܠfX@T DMDQEVAK|09a!#V:Ht TrVZAlbi'HJB qU5DWti $Қ`*ef!)ds|,OZۥXM绝 &| קk'I{o蠬Yi_AeTP)F~T8EQFppD 4ʊXH#.%/x89U,QOW1&1$Yfh$*;䳯 !*nMu[| y B#HhXBz3RB%:Ie%fv'ǃ ME;3h9D nhX7է꿔ٿX QD[lps |.}vNMt1hA+|WN NΑ&RU 5 qV,]PH@&2hd JPV2@n$}Rj@+Liu׀5ANIâDi+Ӱ"ǂd0F/_TGȼ[$xghܯN7&[#H!Tې@,~F毿 6F6N1F_s|eDAaaa`;SHG@ݝ? ld_cAO׿<=_>&'|E].? ppр۞G_lo1XT0}`h2|~_x5>} #z UC0_S i%'%bE``v4HV;R^O&ErNgoRg-%\X @T({Rv1(͉3,e/w7zJ_Pi(ϏVA55 (3y{3/Q+3߾?a `} 8ܹyΫ_.<[ZȚʟωEKxg癿Z@nw0dXXCA@ ~5%~SY 1\fuk@0*;?>;ŏcb lY=~?oƗ?=f ]ax jZzGw:~SuYX+{S/ ?30[V!:/L y39=0VlL%1O.op<,Zr5vk,ɽbOs|AZm#?{u{kO_e0p1?W`,~w]#gOO:IK}9g}?ןR2yYn(0]pΟkL?f翠ssಕ xxߟ/Y4JD۟=~a0>L[Ç=|[N[3'"bo 9~) =0L>sToi_'soe^|W|M{g>k / e|ßo~`+/Bd ?3 r?QW~FWY)?c0`ph1&~3=sOw6nz<8a!.%% jlϼE"I-ۃJܠ\.#Ԟ< xY19jӶ>>xB8ië_F8/||SoF濟>32}m[G<_ & "X~6Jfu~Kr Eވ 0&7vm\>u^k)导{ ymK~_O; =y)+/ϸ8:?T|&?Gg’3v x =O_\=-qtƎE[$!bHRN{RI#6^C`KD=xsh\ΓV-٢2AuW gU8ԚKg$ՒC62Y  Hr_,g{pM>`xA*_2B <:)x/%3C?zSF }a~.(9ϗŁ^xXylџY^1|I^jC/_#7fUbqظcA\M;ǧ~Tgfo$X I0|'`[`C+_ ."@ 8yGxxn}~Xo^|;)Rv6grevE<|ML_ ܔPb/8DN}| /w:_/)+} {ѓ?<ڬ/Csf);_{m? קd9Ŵ7z+;<<_>},3BڼH ǐS+##+w|"2Inc68%A ۀ21+#A\sVGb╘o䟋}fyߒ߮HȰ~zpGO⫓ x8+wV4\_^K]}횃1p0ًy/7Ԥof7P "a|fO |/_Oz1<~W=;3~aRՓ g&ֻ<,n3|'!􆉟g> ~y[wMM'VV}󳉧>-K<'.JWWOgRYn1g12R#4%π3Uj|yO_?fA&>Y$HtbgQE_?_qJ] ’o_[W?laܿ)K_^1H3b-*O&Y6=\Ӹ7ӗO(@ٵ ayf3 kl@3%i^]1i1_@Gw]lLSh1DߔhBI[SV(C3أJW}`=G 3M\؆7/WO eL7DьZyI4u6ikuWZhP*s =);k:xn2>o ~-f ѵRB(-(a EO DN 3?3#kŇ1Z9Qg=ص܄!lE9X-LE/8xIhT+B%2xeh Hpe|9.N1]i3E/H+Iܡ})k-XE|cԧͅbIENDB`Authen-Captcha-1.023/Captcha/images/6.png0000644000175000017500000000032307762723167016446 0ustar emhnemhnPNG  IHDR#&PLTE̙333fff8z|IDATxc`2vsD`FcI yP#P1L H)L!4RZ0yA^(C8v(3@ b1-6?(*C)SqWj=G^@Iy.@Sn'2ʛ FWRڧ2ٮ&m]Y]n yeIENDB`Authen-Captcha-1.023/Captcha/images/background3.png0000644000175000017500000001546507762723166020517 0ustar emhnemhnPNG  IHDR#gAMA|Q cHRMz%u0`:oIDATxN0+hP!  H8qgiOl1Ӭ $˵!`KӘ$L%[]OS@fR'~M43ZV J6\szDf@Ewq]on9 gxa/6i)c#:AŶ }c<9GsQi/I 0@e[J6qig:g."-I|d[=dAբ2;]9q<2x:8NMeřcSjrNy׋<.&FeS^ڏxSrMű< U؇C(k.VC}IS/s LB˸2ݹqqa+:l(! _ ?:Ps?O*pZܢ-60wb^uXi 1ƞ(ǼĜ^+.FTǏSl֓VS 7E.#Kp=5dU7qoghlYF%8^_`v[JQC4Kb{~nF[J{AZ nSlX{k?V)L//Z sO>"swO)y!y31nQ!k#j l+vLw>ǐ1`y, ,jSW!t xղuD/{f%hinΩsZ>?;) }BH&qm݆ #k#?8w Zq zEN_/I]qRLazO󬕮SwfBZls 2%D @|^jIe?;;8Uar!eBow"4!Avl0f*[yMt]rrcf[Ȟ5 \#bU4{薥!,18xcxӒ/ȏW}Mq[v[ubɬrd )e7BMh-kPQX\BNDm@3 @&CP fnz]osYbQ1un4Ŗ2͗b,}JGq&bkS8ae]ރ*.~.?D\-C4"*3 VgFo[pCɪ$L֛usqۇf&cY<FI<*fPS;C4ak9\N8u?j,ERWr;"UnTY2 )c6 #pK`^V hVt-ezZi"ZD( jZ8N>9ˏ_|t[+gAk4,RZ堂-5{ulJ,wL2ᨗ MC@M;g&flM>}'5ٗ:`1Ul ObqQD3 Jwvy"$.[Vv\$@HW<\[ӿ K @1 -B+^gAE+MLFnA4euS B(5@BaO`/]Ue(%i#۽~s3( Uȳh 6L~CXs$MgjhSUq}tM<"ǼLEC04^PܶAZg ֻn0P;cߘ!IDs7J?#;(B 0Uˎ] 'l?bB,{%R`qʯ6ӱ޺Q./ir D]/قaQA5UuDT$GIxrҜ/2GE8 7*EF&OM$hԝtyhKO&t[SՌCJ#t#Olri 2k_ 'MQ%$ ..8sn E5{l4[ דՒ/Ŗ=nݶ Ce` p:3FTE؈F"EWںM(mG )ϓSN%CYR3( f!F)+$)Fn_3(.5,XUҤAqeMZN]D\yGo+'^>d-%BTgi.~;ri#MwmXZ r&$:&SC%?pL"] dAV"뽱U(MhK4Z) (R|?! gJ6c|ԺOLgi(9v+kkqY0eeGSVϽe:Mc7 BDA=BW܊ an@PX!qmϚ׵نaѨ#RgF/"zQsx>Ւ(#L'܋"G~?A@8'^ov}Ej;]~ M56j~rշJk{F1cId;#ꭌ+y0\7 a@3DQ4m]0ިƤ 4@!9Lyx{b'KdO9 fĘ}^R p.LpG67CPt Iek2z78y{#@ٱGOΝCve"EX2w@ǚ0Շ1Za}IY`U\Njr6u  $& ) /& $ )> #  "H,0   3-'( $ 0\ `)YÀW%=x5n2M) H>W^تj04nFS(6sb6 Ko;}fztFc8˹k )vWdIA1{HcrTw `!{ab 7P^nE?Eqb@+,a{(Va /Kj~ p tsNgJI@]轟{.DDAܬsZ~q _K;EEsl㓎.]#d? J_*_`-Zj&ҹs n>n\u)^2V_6]Hz*zsoFs*c-谍zbQj6XL*ATq" IXh݁ p٭ `4C\b=fA7EE s975lO]8X8"n~>n\I[QҴ%fR@K:BGdȝxm4%lZ.淢@}ĕjZܗLkbm -A&C@9Ifۺゔ)^z>+ c|EeJu硖. `~VԕSWA.EءzʠKnQХB'Js[G}ڜ4fNL+x[l7vTְ^:?Z8Ў%܋%#N<-vnHn?F>HHORЃŨ\ s,=$w=5넞Ā̰0+M )qG _g޻_=cIz[Aܜiz _s{% Xd:_qďő;X@lz/HnUfqy1ྞRA(Oi HINJ sKkF_$ߑ<Ŗ$ 1䅏ȷx$t3R`&k%_5=>a`^r>"#8F% ;;wKFRx v{SЇЯf p.(>Syat%SʜAlbw' euzPqo"dsC5waF/%sDݺ7Bш)PhoF=%: P>R?A=)2h`DJ%Qr5诨R1S{&g$-2!\gk{Y["Hh :{X(idH4C%Zs'[uS n0b~q㒽eoi춓`&cȰK/&Y+Exm6 cY]!l.Оޖ'WoVYe?̌;ܝ\;0X79 @=g&VlhTAUZU)v+ŧoiv-9ޚ#Ky̖lƾˠFWA)|C.J ,;G+*Ҵ~2 7jX_vjB{bhHI!"\l2%C|M Uaχf/岛0 DьmJPĢUU?Կ%lV4`'{zm.RcZF }K2ka';3ud_m^cP+*7T\ab@i}+fm7OW#md~*ޛ9Y3Eh)D2J:#Md"bsplitdir( $this_dir ); $default_images_folder = File::Spec->catdir(@this_dirs,'Captcha','images'); } my $num_of_soundfile_versions = 10; # Preloaded methods go here. sub new { my ($this) = shift; my $class = ref($this) || $this; my $self = {}; bless( $self, $class ); my %opts = @_; # default character source images my $type = defined($opts{type}) ? $opts{type} : 'image'; $self->type($type); my $src_images = (defined($opts{images_folder}) && (-d $opts{images_folder})) ? $opts{images_folder} : $default_images_folder; $self->images_folder($src_images); my $debug = (defined($opts{debug}) && ($opts{debug} =~ /^\d+$/)) ? $opts{debug} : 0; $self->debug($debug); $self->data_folder($opts{data_folder}) if($opts{data_folder}); $self->output_folder($opts{output_folder}) if($opts{output_folder}); my $expire = (defined($opts{expire}) && ($opts{expire} =~ /^\d+$/)) ? $opts{expire} : 300; $self->expire($expire); my $width = (defined($opts{width}) && ($opts{width} =~ /^\d+$/)) ? $opts{width} : 25; $self->width($width); my $height = (defined($opts{height}) && ($opts{height} =~ /^\d+$/)) ? $opts{height} : 35; $self->height($height); my $keep_failures = (defined($opts{keep_failures}) && $opts{keep_failures}) ? 1 : 0; $self->keep_failures($keep_failures); # create a random seed if perl version less than 5.004 if ($] < 5.005) { # have to seed rand. using a fairly good seed srand( time() ^ ($$ + ($$ << 15)) ); } # else, we're just going to let perl do it's thing return $self; } sub type { ref(my $self = shift) or croak "instance variable needed"; if (@_) { if ($_[0] =~ /^(jpg|png|gif|image|picture)$/i) { $self->{_type} = 'image'; } elsif ($_[0] =~ /^(sound|snd|wav|mp3)$/i) { $self->{_type} = 'sound'; } return $self->{_type}; } else { return $self->{_type}; } } sub debug { ref(my $self = shift) or croak "instance variable needed"; if (@_) { $self->{_debug} = $_[0]; return $self->{_debug}; } else { return $self->{_debug}; } } sub keep_failures { ref(my $self = shift) or croak "instance variable needed"; if (@_) { croak "keep_failures must be a zero or one" unless ($_[0] =~ /^[01]$/); $self->{_keep_failures} = $_[0]; return $self->{_keep_failures}; } else { return $self->{_keep_failures}; } } sub expire { ref(my $self = shift) or croak "instance variable needed"; if (@_) { croak "expire must be a possitive integer" unless ($_[0] =~ /^\d+$/); $self->{_expire} = $_[0]; return $self->{_expire}; } else { return $self->{_expire}; } } sub width { ref(my $self = shift) or croak "instance variable needed"; if (@_) { croak "width must be a possitive integer" unless ($_[0] =~ /^\d+$/); $self->{_width} = $_[0]; return $self->{_width}; } else { return $self->{_width}; } } sub height { ref(my $self = shift) or croak "instance variable needed"; if (@_) { croak "height must be a possitive integer" unless ($_[0] =~ /^\d+$/); $self->{_height} = $_[0]; return $self->{_height}; } else { return $self->{_height}; } } sub output_folder { ref(my $self = shift) or croak "instance variable needed"; if (@_) { # it's a setter $self->{_output_folder} = $_[0]; return $self->{_output_folder}; } else { return $self->{_output_folder}; } } sub images_folder { ref(my $self = shift) or croak "instance variable needed"; if (@_) { # it's a setter $self->{_images_folder} = $_[0]; return $self->{_images_folder}; } else { return $self->{_images_folder}; } } sub data_folder { ref(my $self = shift) or croak "instance variable needed"; if (@_) { # it's a setter $self->{_data_folder} = $_[0]; return $self->{_data_folder}; } else { return $self->{_data_folder}; } } sub check_code { ref(my $self = shift) or croak "instance variable needed"; my ($code, $crypt) = @_; $code = lc($code); warn "$code $crypt\n" if($self->debug() >= 2); my $current_time = time; my $return_value = 0; my $database_file = File::Spec->catfile($self->data_folder(),"codes.txt"); # create database file if it doesn't already exist $self->_touch_file($database_file); # zeros (0) and ones (1) are not part of the code # they could be confused with (o) and (l), so we swap them in $code =~ tr/01/ol/; my $md5 = md5_hex($code); # pull in current database warn "Open File: $database_file\n" if($self->debug() >= 2); open (DATA, "<$database_file") or die "Can't open File: $database_file\n"; flock DATA, 1; # read lock my @data=; close(DATA); warn "Close File: $database_file\n" if($self->debug() >= 2); my $passed=0; # $new_data will hold the part of the database we want to keep and # write back out my $new_data = ""; my $found; foreach my $line (@data) { $line =~ s/\n//; my ($data_time,$data_code) = split(/::/,$line); my $png_file = File::Spec->catfile($self->output_folder(),$data_code . ".png"); if ($data_code eq $crypt) { # the crypt was found in the database if (($current_time - $data_time) > $self->expire()) { warn "Crypt Found But Expired\n" if($self->debug() >= 2); # the crypt was found but has expired $return_value = -1; } else { warn "Match Crypt in File Crypt: $crypt\n" if($self->debug() >= 2); $found = 1; } if ( ($md5 ne $crypt) && ($return_value != -1) && $self->keep_failures()) { # solution was wrong, not expired, and we're keeping failures $new_data .= $line."\n"; } else { # remove the found crypt so it can't be used again warn "Unlink File: " . $png_file . "\n" if($self->debug() >= 2); unlink($png_file) or carp("Can't remove png file [$png_file]\n"); } } elsif (($current_time - $data_time) > $self->expire()) { # removed expired crypt warn "Removing Expired Crypt File: " . $png_file ."\n" if($self->debug() >= 2); unlink($png_file) or carp("Can't remove png file [$png_file]\n"); } else { # crypt not found or expired, keep it $new_data .= $line."\n"; } } if ($md5 eq $crypt) { warn "Match: " . $md5 . " And " . $crypt . "\n" if($self->debug() >= 2); # solution was correct if ($found) { # solution was correct and was found in database - passed $return_value = 1; } elsif (!$return_value) { # solution was not found in database $return_value = -2; } } else { warn "No Match: " . $md5 . " And " . $crypt . "\n" if($self->debug() >= 2); # incorrect solution $return_value = -3; } # update database open(DATA,">$database_file") or die "Can't open File: $database_file\n"; flock DATA, 2; # write lock print DATA $new_data; close(DATA); return $return_value; } sub _touch_file { ref(my $self = shift) or croak "instance variable needed"; my $file = shift; # create database file if it doesn't already exist if (! -e $file) { open (DATA, ">>$file") or die "Can't create File: $file\n"; close(DATA); } } sub generate_random_string { ref(my $self = shift) or croak "instance variable needed"; my $length = shift; # generate a new code my $code = ""; for(my $i=0; $i < $length; $i++) { my $char; my $list = int(rand 4) +1; if ($list == 1) { # choose a number 1/4 of the time $char = int(rand 7)+50; } else { # choose a letter 3/4 of the time $char = int(rand 25)+97; } $char = chr($char); $code .= $char; } return $code; } sub _save_code { ref(my $self = shift) or croak "instance variable needed"; my $code = shift; my $md5 = shift; my $database_file = File::Spec->catfile($self->data_folder(),'codes.txt'); # set a variable with the current time my $current_time = time; # create database file if it doesn't already exist $self->_touch_file($database_file); # clean expired codes and images open (DATA, "<$database_file") or die "Can't open File: $database_file\n"; flock DATA, 1; # read lock my @data=; close(DATA); my $new_data = ""; foreach my $line (@data) { $line =~ s/\n//; my ($data_time,$data_code) = split(/::/,$line); if ( (($current_time - $data_time) > ($self->expire())) || ($data_code eq $md5) ) { # remove expired captcha, or a dup my $png_file = File::Spec->catfile($self->output_folder(),$data_code . ".png"); unlink($png_file) or carp("Can't remove png file [$png_file]\n"); } else { $new_data .= $line."\n"; } } # save the code to database warn "open File: $database_file\n" if($self->debug() >= 2); open(DATA,">$database_file") or die "Can't open File: $database_file\n"; flock DATA, 2; # write lock warn "-->>" . $new_data . "\n" if($self->debug() >= 2); warn "-->>" . $current_time . "::" . $md5."\n" if($self->debug() >= 2); print DATA $new_data; print DATA $current_time."::".$md5."\n"; close(DATA); warn "Close File: $database_file\n" if($self->debug() >= 2); } sub create_image_file { ref(my $self = shift) or croak "instance variable needed"; my $code = shift; my $md5 = shift; my $length = length($code); my $im_width = $self->width(); # create a new image and color my $im = new GD::Image(($im_width * $length),$self->height()); my $black = $im->colorAllocate(0,0,0); # copy the character images into the code graphic for(my $i=0; $i < $length; $i++) { my $letter = substr($code,$i,1); my $letter_png = File::Spec->catfile($self->images_folder(),$letter . ".png"); my $source = new GD::Image($letter_png); $im->copy($source,($i*($self->width()),0,0,0,$self->width(),$self->height())); my $a = int(rand (int(($self->width())/14)))+0; my $b = int(rand (int(($self->height())/12)))+0; my $c = int(rand (int(($self->width())/3)))-(int(($self->width())/5)); my $d = int(rand (int(($self->height())/3)))-(int(($self->height())/5)); $im->copyResized($source,($i*($self->width()))+$a,$b,0,0,($self->width())+$c,($self->height())+$d,$self->width(),$self->height()); } # distort the code graphic for(my $i=0; $i<($length*($self->width())*($self->height())/14+200); $i++) { my $a = (int(rand ($length*($self->width())))+0); my $b = (int(rand $self->height())+0); my $c = (int(rand ($length*($self->width())))+0); my $d = (int(rand $self->height())+0); my $index = $im->getPixel($a,$b); if ($i < (($length*($self->width())*($self->height())/14+200)/100)) { $im->line($a,$b,$c,$d,$index); } elsif ($i < (($length*($self->width())*($self->height())/14+200)/2)) { $im->setPixel($c,$d,$index); } else { $im->setPixel($c,$d,$black); } } # generate a background my $a = int(rand 5)+1; my $background_img = File::Spec->catfile($self->images_folder(),"background" . $a . ".png"); my $source = new GD::Image($background_img); my ($background_width,$background_height) = $source->getBounds(); my $b = int(rand (int($background_width/13)))+0; my $c = int(rand (int($background_height/7)))+0; my $d = int(rand (int($background_width/13)))+0; my $e = int(rand (int($background_height/7)))+0; my $source2 = new GD::Image(($length*($self->width())),$self->height()); $source2->copyResized($source,0,0,$b,$c,($length*($self->width())),$self->height(),$background_width-$b-$d,$background_height-$c-$e); # merge the background onto the image $im->copyMerge($source2,0,0,0,0,($length*($self->width())),$self->height(),40); # add a border $im->rectangle(0,0,((($length)*($self->width()))-1),(($self->height())-1),$black); # save the image to file my $png_data = $im->png; return \$png_data; } sub create_sound_file { ref(my $self = shift) or croak "instance variable needed"; my $code = shift; my $md5 = shift; my $length = length($code); my @chars = split('',$code); my $snd_file; local $/; # input record separator. So we can slurp the data. # get a random voice speaking the code foreach my $char (@chars) { my $voice = int(rand $num_of_soundfile_versions) + 1; my $src_name = File::Spec->catfile($self->images_folder(),$voice, $char . ".wav"); warn "Open File: $src_name\n" if($self->debug() >= 2); open (FILE,"< $src_name") or die "Can't open File: $src_name\n"; flock FILE, 1; # read lock binmode FILE; $snd_file .= ; close FILE; warn "Close File: $src_name\n" if($self->debug() >= 2); } return \$snd_file; } sub _save_file { ref(my $self = shift) or croak "instance variable needed"; my $file_ref = shift; my $file_name = shift; warn "Open File: $file_name\n" if($self->debug() >= 2); open (FILE,">$file_name") or die "Can't open File: $file_name \n"; flock FILE, 2; # write lock binmode FILE; print FILE $$file_ref; close FILE; warn "Close File: $file_name\n" if($self->debug() >= 2); } sub generate_code { ref(my $self = shift) or croak "instance variable needed"; my $length = shift; my $code = $self->generate_random_string($length); my $md5 = md5_hex($code); my ($captcha_data_ref,$output_filename); if ($self->type() eq 'image') { $captcha_data_ref = $self->create_image_file($code,$md5); $output_filename = File::Spec->catfile($self->output_folder(),$md5 . ".png"); } elsif ($self->type() eq 'sound') { $captcha_data_ref = $self->create_sound_file($code,$md5); $output_filename = File::Spec->catfile($self->output_folder(),$md5 . ".wav"); } else { croak "invalid captcha type [" . $self->type() . "]"; } $self->_save_file($captcha_data_ref,$output_filename); $self->_save_code($code,$md5); # return crypt (md5)... or, if they want it, the code as well. return wantarray ? ($md5,$code) : $md5; } sub version { return $VERSION; } 1; __END__ # Below is stub documentation for your module. You'd better edit it! =head1 NAME Authen::Captcha - Perl extension for creating captcha's to verify the human element in transactions. =head1 SYNOPSIS use Authen::Captcha; # create a new object my $captcha = Authen::Captcha->new(); # set the data_folder. contains flatfile db to maintain state $captcha->data_folder('/some/folder'); # set directory to hold publicly accessable images $captcha->output_folder('/some/http/folder'); # Alternitively, any of the methods to set variables may also be # used directly in the constructor my $captcha = Authen::Captcha->new( data_folder => '/some/folder', output_folder => '/some/http/folder', ); # create a captcha. Image filename is "$md5sum.png" my $md5sum = $captcha->generate_code($number_of_characters); # check for a valid submitted captcha # $code is the submitted letter combination guess from the user # $md5sum is the submitted md5sum from the user (that we gave them) my $results = $captcha->check_code($code,$md5sum); # $results will be one of: # 1 : Passed # 0 : Code not checked (file error) # -1 : Failed: code expired # -2 : Failed: invalid code (not in database) # -3 : Failed: invalid code (code does not match crypt) ############## =head1 ABSTRACT Authen::Captcha provides an object oriented interface to captcha file creations. Captcha stands for Completely Automated Public Turning test to tell Computers and Humans Apart. A Captcha is a program that can generate and grade tests that: - most humans can pass. - current computer programs can't pass The most common form is an image file containing distorted text, which humans are adept at reading, and computers (generally) do a poor job. This module currently implements that method. We plan to add other methods, such as distorted sound files, and plain text riddles. =head1 REQUIRES GD (see http://search.cpan.org/~lds/GD-2.11/) Digest::MD5 (standard perl module) In most common situations, you'll also want to have: A web server (untested on windows, but it should work) cgi-bin or mod-perl access Perl: Perl 5.00503 or later must be installed on the web server. GD.pm (with PNG support) =head1 INSTALLATION Download the zipped tar file from: http://search.cpan.org/search?dist=Authen-Captcha Unzip the module as follows or use winzip: tar -zxvf Authen-Captcha-1.xxx.tar.gz The module can be installed using the standard Perl procedure: perl Makefile.PL make make test make install # you need to be root Windows users without a working "make" can get nmake from: ftp://ftp.microsoft.com/Softlib/MSLFILES/nmake15.exe =head1 METHODS =head2 MAIN METHODS =over =item C<$captcha = Authen::Captcha-Enew();> This creates a new Captcha object. Optionally, you can pass in a hash with configuration information. See the method descriptions for more detail on what they mean. =over 2 data_folder => '/some/folder', # required output_folder => '/some/http/folder', # required expire => 300, # optional. default 300 width => 25, # optional. default 25 height => 35, # optional. default 35 images_folder => '/some/folder', # optional. default to lib dir keep_failures => 0, # optional, defaults to 0(false) debug => 0, # optional. default 0 =back =item C<$md5sum = $captcha-Egenerate_code( $number_of_characters );> Creates a captcha. Image filename is "$md5sum.png" It can also be called in array context to retrieve the string of characters used to generate the captcha (the string the user is expected to respond with). This is useful for debugging. ex. C<($md5sum,$chars) = $captcha-Egenerate_code( $number_of_characters );> =item C<$results = $captcha-Echeck_code($code,$md5sum);> check for a valid submitted captcha $code is the submitted letter combination guess from the user $md5sum is the submitted md5sum from the user (that we gave them) If the $code and $md5sum are correct, the image file and database entry will be removed. If the $md5sum matches one in the database, and "keep_failures" is false (the default), the image file and database entry will be removed to avoid repeated attempts on the same captcha. $results will be one of: 1 : Passed 0 : Code not checked (file error) -1 : Failed: code expired -2 : Failed: invalid code (not in database) -3 : Failed: invalid code (code does not match crypt) =back =head2 ACCESSOR METHODS =over =item C<$captcha-Edata_folder( '/some/folder' );> Required. Sets the directory to hold the flatfile database that will be used to store the current non-expired valid captcha md5sum's. Must be writable by the process running the script (usually the web server user, which is usually either "apache" or "http"), but should not be accessable to the end user. =item C<$captcha-Eoutput_folder( '/some/folder' );> Required. Sets the directory to hold the generated Captcha image files. This is usually a web accessable directory so that the user can view the images in here, but it doesn't have to be web accessable (you could be attaching the images to an e-mail for some verification, or some other Captcha implementation). Must be writable by the process running the script (usually the web server user, which is usually either "apache" or "http"). =item C<$captcha-Eimages_folder( '/some/folder' );> Optional, and may greatly affect the results... use with caution. Allows you to override the default character graphic png's and backgrounds with your own set of graphics. These are used in the generation of the final captcha image file. The defaults are held in: [lib install dir]/Authen/Captcha/images =item C<$captcha-Eexpire( 300 );> Optional. Sets the number of seconds this captcha will remain valid. This means that the created captcha's will not remain valid forever, just as long as you want them to be active. Set to an appropriate value for your application. Defaults to 300. =item C<$captcha-Ewidth( 25 );> Optional. Number of pixels high for the character graphics. Defaults to 25. =item C<$captcha-Eheight( 35 );> Optional. Number of pixels wide for the character graphics. Defaults to 35. =item C<$captcha-Ekeep_failures( [0|1] );> Optional. Defaults to zero. This option controls whether or not the captcha will remain valid after a failed attempt. By default, we only allow one attempt to solve it. This greatly reduces the possibility that a bot could brute force a correct answer. Change it at your own risk. =item C<$captcha-Edebug( [0|1|2] );> Optional. Sets the debugging bit. 1 turns it on, 0 turns it off. 2 will print out verbose messages to STDERR. =back =head1 TODO sound file captcha: Incorporating distorted sound file creation. =head1 SEE ALSO The Captcha project: http://www.captcha.net/ The origonal perl script this came from: http://www.firstproductions.com/cgi/ =head1 AUTHORS Seth T. Jackson, Esjackson@purifieddata.netE Josh I. Miller, Ejmiller@purifieddata.netE First Productions, Inc. created the cgi-script distributed under the GPL which was used as the basis for this module. Much work has gone into making this more robust, and suitable for other applications, but much of the origonal code remains. =head1 COPYRIGHT AND LICENSE Copyright 2003, First Productions, Inc. (FIRSTPRODUCTIONS HUMAN TEST 1.0) Copyright 2003 by Seth Jackson This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. (see license.txt). This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA =cut Authen-Captcha-1.023/Changes0000644000175000017500000001372507770230445014257 0ustar emhnemhnRevision history for Perl extension Authen::Captcha. 2003-12-17 23:47 jmiller * Changes: updated changes - tagged as Rel-1_023 2003-12-17 23:44 jmiller * Captcha.pm, t/1.t: Added keep_failures option, to keep the captcha around when the check failes one wants. Added initial untested sound file support (no distortion yet) 2003-12-04 15:50 jmiller * Changes: updated changes - tagged as Rel-1_022 2003-12-04 15:46 jmiller * Captcha.pm: removed item from TODO - fixing srand() portability 2003-12-04 15:44 jmiller * Captcha.pm: added data validation to expire(), width(), and height() to verify set's use a possitive integer. check_code() - have it creating database file codes.txt if it doesn't exist (touch it). 2003-12-04 15:25 jmiller * Captcha.pm, Makefile.PL, t/1.t: Portability update. Modified directory/file handling to use File::Spec for portable operations. Added warnings for when unlink's failed. Made srand() in new() of Captcha.pm more portable. 2003-12-04 11:08 jmiller * t/1.t: adjusted test t/1.t... it was writing captcha out to /tmp/captcha_temp/etc, changed it to use t/captcha_temp/etc using __FILE__ to figure out where the test is at. 2003-12-04 00:45 jmiller * Captcha.pm, Makefile.PL, t/1.t: Removed nasty hack to hardcode in the lib/Authen/Captcha/images directory. Replaced with the solution that lib/Net/Config.pm uses (thanks to Andrew Savige for helping me out). The new solution uses __FILE__ to find the module's filename, and regex's it into the path to the images directory. 2003-12-03 22:12 jmiller * Captcha.pm, examples/wwwtest.cgi, t/1.t: MAJOR INTERFACE CHANGE! method names have changed. All two word method names have been lowercased and split with an underscore for propper style and consistency: datafolder => data_folder outputfolder => output_folder imagesfolder => images_folder generateCode => generate_code checkCode => check_code Also, though less important, an audit of all variable names in the module has been done in order to put them into the correct naming conventions as well. 2003-12-03 21:53 jmiller * Captcha.pm: added TODO to docs 2003-12-03 15:21 jmiller * Captcha.pm, Makefile.PL: added PREREQ_PM's to the Makefile.PL, fixed docs on requirements (GD doesn't have to be a 2.x release, I have it working fine on a 1.41 GD) 2003-12-02 21:19 jmiller * Changes: updated changes - tagged as Rel-1_015 2003-12-02 21:15 jmiller * README: updated REAME w/ new documentation format 2003-12-02 21:13 jmiller * Captcha.pm: More documentation tweeks 2003-12-02 20:18 sjackson * Captcha.pm: Fixing a few right and left brases. Added Josh's name to the Authors, due to the fact that he did all the leg work on getting this up on CPAN. 2003-12-02 19:32 jmiller * Changes: updated changes 2003-12-02 19:29 jmiller * Captcha.pm, README: Re-ordered documentation. Made SYNOPSIS more minimal. Correctted new() documentation (you can pass in hash, not a hash referance) 2003-12-02 19:11 jmiller * Captcha.pm: POD formatting update. 2003-12-02 14:45 jmiller * Captcha.pm: removed useless comment 2003-12-02 14:44 jmiller * MANIFEST: added examples to manifest 2003-12-02 11:20 jmiller * Changes: updated Changes file, and Tagged as release 1.010 2003-12-02 14:38 jmiller * examples/: README, wwwtest.cgi: added an example cgi script 2003-12-02 13:57 jmiller * README: replaced SRC_IMAGES with [lib install dir]/Authen/Captcha 2003-12-02 13:57 jmiller * Captcha.pm: fixed replacement definition for SRC_IMAGES in pod 2003-12-02 12:15 jmiller * Captcha.pm: Fixed file locking (they were all exclusive write locks... modified ones where we were just reading to read locks) 2003-12-02 12:10 jmiller * Captcha.pm: moved srand(...seed....) to new() 2003-12-02 11:46 jmiller * Captcha.pm, Changes, README: added INSTALLATION to pod documentation, dumped pod to README 2003-12-02 11:19 jmiller * Changes: updated changes 2003-12-02 11:20 jmiller * Changes: updated Changes file, and Tagged as release 1.006 2003-12-02 01:17 jmiller * MANIFEST: updated MANIFEST with all images 2003-12-02 00:36 jmiller * Captcha.pm, Changes, Makefile.PL, README, t/1.t: changed namespace from Crypt::Captcha to Authen::Captcha after looking over compete module list on CPAN... Authen now seems more appropriate. 2003-12-01 21:23 jmiller * Captcha.pm: updated documentation 2003-12-01 20:52 jmiller * Captcha/images/: 2.png, 3.png, 4.png, 5.png, 6.png, 7.png, 8.png, 9.png, Thumbs.db, a.png, b.png, background1.png, background2.png, background3.png, background4.png, background5.png, c.png, d.png, e.png, f.png, g.png, h.png, i.png, j.png, k.png, l.png, m.png, n.png, o.png, p.png, q.png, r.png, s.png, t.png, u.png, v.png, w.png, x.png, y.png, z.png: adding static image data 2003-12-01 20:45 jmiller * Makefile.PL, t/1.t: had to change the PM_FILTER, and the test to hack around the imagesfolder stuff 2003-12-01 20:23 jmiller * Captcha.pm, t/1.t: fixed "use of uninitialized value" that was in checkCode (last 4 lines... if $newdata was empty, it'd complain when warnings were on). Added tests for the new imagesfolder() method 2003-12-01 20:13 jmiller * Captcha.pm, Makefile.PL, t/1.t: Changed a LOT... fixed lots of bugs, changed imagesfolder to outputfolder, and added a new imagesfolder that does something completely different. 2003-12-01 11:02 jmiller * Captcha.pm: updated Captcha.pm to have default values for: expire, width, height 2003-12-01 01:06 jmiller * Captcha.pm, Changes, MANIFEST, Makefile.PL, README, license.txt, t/1.t: adding in Captcha distribution 2003-11-30 23:49 jmiller * original version; created by h2xs 1.22 with options -b 5.5.3 -XAn Authen::Captcha 2003-11-15 07:11 jmiller * branched off of "FirstProductions Human Test 1.0" - http://www.firstproductions.com/cgi/human/ - it's a "perl library" that can be require'd into other scripts but was written with many globals with hardcoded configs and poor structure. Authen-Captcha-1.023/t/0002755000175000017500000000000007770230760013221 5ustar emhnemhnAuthen-Captcha-1.023/t/1.t0000644000175000017500000001023507770227657013560 0ustar emhnemhn# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl 1.t' ######################### # figure out where we are, and where we will be storing stuff use File::Basename; use File::Spec; my $file = __FILE__; my $this_dir = dirname($file); my @this_dirs = File::Spec->splitdir( $this_dir ); my $temp_dir = File::Spec->catdir(@this_dirs,'captcha_temp'); my $temp_datadir = "$temp_dir/data"; my $temp_outputdir = "$temp_dir/img"; # we set this only for testing, it is not actually used my $temp_imagesdir = 'Captcha/images'; use Test; # (tests => 28); plan tests => 32; use Authen::Captcha; ok(1); # If we made it this far, we are fine. my $captcha = Authen::Captcha->new(); ok( defined $captcha, 1, 'new() did not return anything' ); ok( $captcha->isa('Authen::Captcha') ); # make temp directories ok( (-e $temp_dir) || mkdir($temp_dir) ); # made temp dir ok( (-e $temp_datadir) || mkdir($temp_datadir) ); # made temp data dir ok( (-e $temp_outputdir) || mkdir($temp_outputdir) ); # made temp image dir my $captcha2 = Authen::Captcha->new( debug => 1, data_folder => $temp_datadir, output_folder => $temp_outputdir, expire => 301, width => 26, height => 36, keep_failures => 1, ); ok( defined $captcha2, 1, 'new() did not return anything' ); ok( $captcha2->isa('Authen::Captcha') ); $captcha->debug(1); ok( $captcha->debug(), '1', "couldn't set debug to 1" ); ok( $captcha2->debug(), '1', "couldn't set debug to 1" ); $captcha->data_folder($temp_datadir); ok( $captcha->data_folder(), $temp_datadir, "couldn't set data folder to $temp_datadir" ); ok( $captcha2->data_folder(), $temp_datadir, "couldn't set data folder to $temp_datadir" ); $captcha->output_folder($temp_outputdir); ok( $captcha->output_folder(), $temp_outputdir, "couldn't set data folder to $temp_outputdir" ); ok( $captcha2->output_folder(), $temp_outputdir, "couldn't set data folder to $temp_outputdir" ); $captcha->expire(301); ok( $captcha->expire(), '301', "couldn't set expire to 301" ); ok( $captcha2->expire(), '301', "couldn't set expire to 301" ); $captcha->width(26); ok( $captcha->width(), '26', "couldn't set width to 26" ); ok( $captcha2->width(), '26', "couldn't set width to 26" ); $captcha->height(36); ok( $captcha->height(), '36', "couldn't set height to 36" ); ok( $captcha2->height(), '36', "couldn't set height to 36" ); $captcha->keep_failures(1); ok( $captcha->keep_failures(), '1', "couldn't set keep_failures to 1" ); ok( $captcha2->keep_failures(), '1', "couldn't set keep_failures to 1" ); my $default_images_folder = $captcha->images_folder(); $captcha->images_folder($temp_imagesdir); ok( $captcha->images_folder(), $temp_imagesdir, "Couldn't override the images_folder to $temp_imagesdir"); $captcha->images_folder($default_images_folder); ok( $captcha->images_folder(), $default_images_folder, "Couldn't set the images_folder back to $default_images_folder"); my ($md5sum,$code) = $captcha->generate_code(5); ok( sub { return 1 if (length($code) == 5) }, 1, "didn't set the number of captcha characters correctly" ); # we have keep_failures on, so this should not get rid of the database entry my $bad_results = $captcha2->check_code($code . 'x',$md5sum); ok( sub { return 1 if ($bad_results == -3) }, 1, "Failed on check_code: it did not fail correctly" ); $captcha2->keep_failures(0); my $results = $captcha2->check_code($code,$md5sum); # check for different error states ok( sub { return 1 if ($results != -3) }, 1, "Failed on check_code: invalid code (code does not match crypt)" ); ok( sub { return 1 if ($results != -2) }, 1, "Failed on check_code: invalid code (not in database)" ); ok( sub { return 1 if ($results != -1) }, 1, "Failed on check_code: code expired" ); ok( sub { return 1 if ($results != 0) }, 1, "Failed on check_code: code not checked (file error)" ); ok( $results, 1, "Failed on check_code, didn't return 1, but didn't return the other error codes either." ); # we disabled keep_failures, so the check should fail my $bad_results2 = $captcha2->check_code($code,$md5sum); ok( sub { return 1 if ($bad_results2 == -2) }, 1, "Failed on check_code: disabling keep_failures did not work right, it failed incorrectly" ); Authen-Captcha-1.023/README0000644000175000017500000001747707763716445013667 0ustar emhnemhnNAME Authen::Captcha - Perl extension for creating captcha's to verify the human element in transactions. SYNOPSIS use Authen::Captcha; # create a new object my $captcha = Authen::Captcha->new(); # set the data_folder. contains flatfile db to maintain state $captcha->data_folder('/some/folder'); # set directory to hold publicly accessable images $captcha->output_folder('/some/http/folder'); # Alternitively, any of the methods to set variables may also be # used directly in the constructor my $captcha = Authen::Captcha->new( data_folder => '/some/folder', output_folder => '/some/http/folder', ); # create a captcha. Image filename is "$md5sum.png" my $md5sum = $captcha->generate_code($number_of_characters); # check for a valid submitted captcha # $code is the submitted letter combination guess from the user # $md5sum is the submitted md5sum from the user (that we gave them) my $results = $captcha->check_code($code,$md5sum); # $results will be one of: # 1 : Passed # 0 : Code not checked (file error) # -1 : Failed: code expired # -2 : Failed: invalid code (not in database) # -3 : Failed: invalid code (code does not match crypt) ############## ABSTRACT Authen::Captcha provides an object oriented interface to captcha file creations. Captcha stands for Completely Automated Public Turning test to tell Computers and Humans Apart. A Captcha is a program that can generate and grade tests that: - most humans can pass. - current computer programs can't pass The most common form is an image file containing distorted text, which humans are adept at reading, and computers (generally) do a poor job. This module currently implements that method. We plan to add other methods, such as distorted sound files, and plain text riddles. REQUIRES GD (see http://search.cpan.org/~lds/GD-2.11/) Digest::MD5 (standard perl module) In most common situations, you'll also want to have: A web server (untested on windows, but it should work) cgi-bin or mod-perl access Perl: Perl 5.00503 or later must be installed on the web server. GD.pm (with PNG support) INSTALLATION Download the zipped tar file from: http://search.cpan.org/search?dist=Authen-Captcha Unzip the module as follows or use winzip: tar -zxvf Authen-Captcha-1.xxx.tar.gz The module can be installed using the standard Perl procedure: perl Makefile.PL make make test make install # you need to be root Windows users without a working "make" can get nmake from: ftp://ftp.microsoft.com/Softlib/MSLFILES/nmake15.exe METHODS MAIN METHODS "$captcha = Authen::Captcha->new();" This creates a new Captcha object. Optionally, you can pass in a hash with configuration information. See the method descriptions for more detail on what they mean. data_folder => '/some/folder', # required output_folder => '/some/http/folder', # required expire => 300, # optional. default 300 width => 25, # optional. default 25 height => 35, # optional. default 35 images_folder => '/some/folder', # optional. default to lib dir debug => 0, # optional. default 0 "$md5sum = $captcha->generate_code( $number_of_characters );" Creates a captcha. Image filename is "$md5sum.png" It can also be called in array context to retrieve the string of characters used to generate the captcha (the string the user is expected to respond with). This is useful for debugging. ex. "($md5sum,$chars) = $captcha->generate_code( $number_of_characters );" "$results = $captcha->check_code($code,$md5sum);" check for a valid submitted captcha $code is the submitted letter combination guess from the user $md5sum is the submitted md5sum from the user (that we gave them) $results will be one of: 1 : Passed 0 : Code not checked (file error) -1 : Failed: code expired -2 : Failed: invalid code (not in database) -3 : Failed: invalid code (code does not match crypt) ACCESSOR METHODS "$captcha->data_folder( '/some/folder' );" Required. Sets the directory to hold the flatfile database that will be used to store the current non-expired valid captcha md5sum's. Must be writable by the process running the script (usually the web server user, which is usually either "apache" or "http"), but should not be accessable to the end user. "$captcha->output_folder( '/some/folder' );" Required. Sets the directory to hold the generated Captcha image files. This is usually a web accessable directory so that the user can view the images in here, but it doesn't have to be web accessable (you could be attaching the images to an e-mail for some verification, or some other Captcha implementation). Must be writable by the process running the script (usually the web server user, which is usually either "apache" or "http"). "$captcha->images_folder( '/some/folder' );" Optional, and may greatly affect the results... use with caution. Allows you to override the default character graphic png's and backgrounds with your own set of graphics. These are used in the generation of the final captcha image file. The defaults are held in: [lib install dir]/Authen/Captcha/images "$captcha->expire( 300 );" Optional. Sets the number of seconds this captcha will remain valid. This means that the created captcha's will not remain valid forever, just as long as you want them to be active. Set to an appropriate value for your application. Defaults to 300. "$captcha->width( 25 );" Optional. Number of pixels high for the character graphics. Defaults to 25. "$captcha->height( 35 );" Optional. Number of pixels wide for the character graphics. Defaults to 35. "$captcha->debug( [0|1|2] );" Optional. Sets the debugging bit. 1 turns it on, 0 turns it off. 2 will print out verbose messages to STDERR. TODO sound file captcha: Incorporating distorted sound file creation. SEE ALSO The Captcha project: http://www.captcha.net/ The origonal perl script this came from: http://www.firstproductions.com/cgi/ AUTHORS Seth T. Jackson, Josh I. Miller, First Productions, Inc. created the cgi-script distributed under the GPL which was used as the basis for this module. Much work has gone into making this more robust, and suitable for other applications, but much of the origonal code remains. COPYRIGHT AND LICENSE Copyright 2003, First Productions, Inc. (FIRSTPRODUCTIONS HUMAN TEST 1.0) Copyright 2003 by Seth Jackson This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. (see license.txt). This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Authen-Captcha-1.023/examples/0002755000175000017500000000000007770230760014574 5ustar emhnemhnAuthen-Captcha-1.023/examples/wwwtest.cgi0000644000175000017500000000272707763522354017017 0ustar emhnemhn#!/usr/bin/perl use strict; use CGI qw(:standard); use Authen::Captcha; my $output_dir = "/var/www/html/captcha"; my $www_output_dir = "/captcha"; my $db_dir = "/var/www/captchadb"; my $num_of_characters = 5; my $captcha = Authen::Captcha->new( output_folder => $output_dir, data_folder => $db_dir ); &main; sub main { # import any get or post variables into the Q namespace &load_cgi_variables(); if ($Q::code && $Q::crypt) { &check_code($Q::code, $Q::crypt); } else { &default; } } sub default { my $md5sum = $captcha->generate_code($num_of_characters); print header; print "
Please enter the characters in the image below:

\n"; } sub check_code { my ($code,$md5sum) = @_; my $results = $captcha->check_code($code,$md5sum); # $results will be one of: my %result = ( 1 => 'Passed', 0 => 'Code not checked (file error)', -1 => 'Failed: code expired', -2 => 'Failed: invalid code (not in database)', -3 => 'Failed: invalid code (code does not match crypt)', ); print header; print "Result was:
\n"; print "$results : $result{$results}\n"; print "\n"; } sub load_cgi_variables { my $cgi = new CGI; $cgi->import_names('Q'); } Authen-Captcha-1.023/examples/README0000644000175000017500000000230607763165025015456 0ustar emhnemhnThis is the readme file for the example scripts. wwwtest.cgi ----------- Functional as a cgi-script or in a mod_perl setup. To install (on a machine with Authen::Captcha installed): - copy it to your cgi-bin - modify permissions so that it is executable: chmod a+rx wwwtest.cgi - edit the script, setting the variables at it's top to appropriate values: $output_dir : should be set to a directory that is within your DocumentRoot. This directory must be writable by the web server user, eg: chgrp apache /var/www/html/captcha chmod g+rwx /var/www/html/captcha $www_output_dir : should be set to where the $output_dir maps to the outside world. In the above example, if /var/www/html is the DocumentRoot, $www_output_dir should be set to '/captcha' $db_dir : should be set to a directory that is NOT accessable from the web, and is writable by the web server user. $num_of_characters : controls how many characters will be displayed in the resulting Captcha. - Pull up the script in a browser, and test it. If it doesn't work, check your web server log files. Authen-Captcha-1.023/license.txt0000644000175000017500000004365507762545443015164 0ustar emhnemhn GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. Authen-Captcha-1.023/Makefile.PL0000644000175000017500000000124007763713712014730 0ustar emhnemhnuse 5.00503; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'Authen::Captcha', 'VERSION_FROM' => 'Captcha.pm', # finds $VERSION 'PREREQ_PM' => { 'File::Spec' => 0, 'File::Basename' => 0, 'Digest::MD5' => 0, 'GD' => 0, }, ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'Captcha.pm', # retrieve abstract from module AUTHOR => 'Seth T. Jackson ') : ()), );