PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/lib64/perl5/vendor_perl/Net
Viewing File: /usr/lib64/perl5/vendor_perl/Net/SSL.pm
package Net::SSL; use strict; use MIME::Base64; use Socket; use Carp; use vars qw(@ISA $VERSION $NEW_ARGS); $VERSION = '2.85'; require IO::Socket; @ISA=qw(IO::Socket::INET); my %REAL; # private to this package only my $DEFAULT_VERSION = '23'; my $CRLF = "\015\012"; my $SEND_USERAGENT_TO_PROXY = 0; require Crypt::SSLeay; sub _default_context { require Crypt::SSLeay::MainContext; Crypt::SSLeay::MainContext::main_ctx(@_); } sub _alarm_set { return if $^O eq 'MSWin32' or $^O eq 'NetWare'; alarm(shift); } sub new { my($class, %arg) = @_; local $NEW_ARGS = \%arg; $class->SUPER::new(%arg); } sub DESTROY { my $self = shift; delete $REAL{$self}; local $@; eval { $self->SUPER::DESTROY; }; } sub configure { my($self, $arg) = @_; my $ssl_version = delete $arg->{SSL_Version} || $ENV{HTTPS_VERSION} || $DEFAULT_VERSION; my $ssl_debug = delete $arg->{SSL_Debug} || $ENV{HTTPS_DEBUG} || 0; my $ctx = delete $arg->{SSL_Context} || _default_context($ssl_version); *$self->{ssl_ctx} = $ctx; *$self->{ssl_version} = $ssl_version; *$self->{ssl_debug} = $ssl_debug; *$self->{ssl_arg} = $arg; *$self->{ssl_peer_addr} = $arg->{PeerAddr}; *$self->{ssl_peer_port} = $arg->{PeerPort}; *$self->{ssl_new_arg} = $NEW_ARGS; *$self->{ssl_peer_verify} = 0; ## Crypt::SSLeay must also aware the SSL Proxy before calling ## $socket->configure($args). Because the $sock->configure() will ## die when failed to resolve the destination server IP address, ## whether the SSL proxy is used or not! ## - dqbai, 2003-05-10 if (my $proxy = $self->proxy) { ($arg->{PeerAddr}, $arg->{PeerPort}) = split(':',$proxy); $arg->{PeerPort} || croak("no port given for proxy server $proxy"); } $self->SUPER::configure($arg); } # override to make sure there is really a timeout sub timeout { shift->SUPER::timeout || 60; } sub blocking { my $self = shift; $self->SUPER::blocking(@_); } sub connect { my $self = shift; # configure certs on connect() time, so we can throw an undef # and have LWP understand the error eval { $self->configure_certs() }; if($@) { $@ = "configure certs failed: $@; $!"; $self->die_with_error($@); } # finished, update set_verify status if(my $rv = *$self->{ssl_ctx}->set_verify()) { *$self->{ssl_peer_verify} = $rv; } if ($self->proxy) { # don't die() in connect, just return undef and set $@ my $proxy_connect = eval { $self->proxy_connect_helper(@_) }; if(! $proxy_connect || $@) { $@ = "proxy connect failed: $@; $!"; croak($@); } } else { *$self->{io_socket_peername}=@_ == 1 ? $_[0] : IO::Socket::sockaddr_in(@_); if(!$self->SUPER::connect(@_)) { # better to die than return here $@ = "Connect failed: $@; $!"; croak($@); } } my $debug = *$self->{ssl_debug} || 0; my $ssl = Crypt::SSLeay::Conn->new(*$self->{ssl_ctx}, $debug, $self); my $arg = *$self->{ssl_arg}; my $new_arg = *$self->{ssl_new_arg}; $arg->{SSL_Debug} = $debug; # setup SNI if available $ssl->can("set_tlsext_host_name") and $ssl->set_tlsext_host_name(*$self->{ssl_peer_addr}); eval { local $SIG{ALRM} = sub { $self->die_with_error("SSL connect timeout") }; # timeout / 2 because we have 3 possible connects here _alarm_set($self->timeout / 2); my $rv; { local $SIG{PIPE} = \&die; $rv = eval { $ssl->connect; }; } if (not defined $rv or $rv <= 0) { _alarm_set(0); $ssl = undef; # See RT #59312 my %args = (%$arg, %$new_arg); if(*$self->{ssl_version} == 23) { $args{SSL_Version} = 3; # the new connect might itself be overridden with a REAL SSL my $new_ssl = Net::SSL->new(%args); $REAL{$self} = $REAL{$new_ssl} || $new_ssl; return $REAL{$self}; } elsif(*$self->{ssl_version} == 3) { # $self->die_with_error("SSL negotiation failed"); $args{SSL_Version} = 2; my $new_ssl = Net::SSL->new(%args); $REAL{$self} = $new_ssl; return $new_ssl; } else { # don't die, but do set $@, and return undef eval { $self->die_with_error("SSL negotiation failed") }; croak($@); } } _alarm_set(0); }; # odd error in eval {} block, maybe alarm outside the evals if($@) { $@ = "$@; $!"; croak($@); } # successful SSL connection gets stored *$self->{ssl_ssl} = $ssl; $self; } # Delegate these calls to the Crypt::SSLeay::Conn object sub get_peer_certificate { my $self = shift; $self = $REAL{$self} || $self; *$self->{ssl_ssl}->get_peer_certificate(@_); } sub get_peer_verify { my $self = shift; $self = $REAL{$self} || $self; *$self->{ssl_peer_verify}; } sub get_shared_ciphers { my $self = shift; $self = $REAL{$self} || $self; *$self->{ssl_ssl}->get_shared_ciphers(@_); } sub get_cipher { my $self = shift; $self = $REAL{$self} || $self; *$self->{ssl_ssl}->get_cipher(@_); } sub ssl_context { my $self = shift; $self = $REAL{$self} || $self; *$self->{ssl_ctx}; } sub die_with_error { my $self=shift; my $reason=shift; my @err; while(my $err=Crypt::SSLeay::Err::get_error_string()) { push @err, $err; } croak("$reason: " . join( ' | ', @err )); } sub read { my $self = shift; $self = $REAL{$self} || $self; local $SIG{__DIE__} = \&Carp::confess; local $SIG{ALRM} = sub { $self->die_with_error("SSL read timeout") }; _alarm_set($self->timeout); my $n = *$self->{ssl_ssl}->read(@_); _alarm_set(0); $self->die_with_error("read failed") if !defined $n; $n; } sub write { my $self = shift; $self = $REAL{$self} || $self; my $n = *$self->{ssl_ssl}->write(@_); $self->die_with_error("write failed") if !defined $n; $n; } *sysread = \&read; *syswrite = \&write; sub print { my $self = shift; $self = $REAL{$self} || $self; # should we care about $, and $\?? # I think it is too expensive... $self->write(join("", @_)); } sub printf { my $self = shift; $self = $REAL{$self} || $self; my $fmt = shift; $self->write(sprintf($fmt, @_)); } sub getchunk { my $self = shift; $self = $REAL{$self} || $self; my $buf = ''; # warnings my $n = $self->read($buf, 32768); return unless defined $n; $buf; } # This is really inefficient, but we only use it for reading the proxy response # so that does not really matter. sub getline { my $self = shift; $self = $REAL{$self} || $self; my $val=""; my $buf; do { $self->SUPER::recv($buf, 1); $val .= $buf; } until ($buf eq "\n"); $val; } # XXX: no way to disable <$sock>?? (tied handle perhaps?) sub get_lwp_object { my $self = shift; my $lwp_object; my $i = 0; while(1) { package DB; my @stack = caller($i++); last unless @stack; my @stack_args = @DB::args; my $stack_object = $stack_args[0] || next; return $stack_object if ref($stack_object) and $stack_object->isa('LWP::UserAgent'); } return undef; } sub send_useragent_to_proxy { if (my $val = shift) { $SEND_USERAGENT_TO_PROXY = $val; } return $SEND_USERAGENT_TO_PROXY; } sub proxy_connect_helper { my $self = shift; my $proxy = $self->proxy; my ($proxy_host, $proxy_port) = split(':',$proxy); $proxy_port || croak("no port given for proxy server $proxy"); my $proxy_addr = gethostbyname($proxy_host); $proxy_addr || croak("can't resolve proxy server name: $proxy_host, $!"); my($peer_port, $peer_addr) = (*$self->{ssl_peer_port}, *$self->{ssl_peer_addr}); $peer_addr || croak("no peer addr given"); $peer_port || croak("no peer port given"); # see if the proxy should be bypassed my @no_proxy = split( /\s*,\s*/, $ENV{NO_PROXY} || $ENV{no_proxy} || ''); my $is_proxied = 1; my $domain; for $domain (@no_proxy) { if ($peer_addr =~ /\Q$domain\E$/) { $is_proxied = 0; last; } } if ($is_proxied) { $self->SUPER::connect($proxy_port, $proxy_addr) || croak("proxy connect to $proxy_host:$proxy_port failed: $!"); } else { # see RT #57836 my $peer_addr_packed = gethostbyname($peer_addr); $self->SUPER::connect($peer_port, $peer_addr_packed) || croak("proxy bypass to $peer_addr:$peer_addr failed: $!"); } my $connect_string; if ($ENV{"HTTPS_PROXY_USERNAME"} || $ENV{"HTTPS_PROXY_PASSWORD"}) { my $user = $ENV{"HTTPS_PROXY_USERNAME"}; my $pass = $ENV{"HTTPS_PROXY_PASSWORD"}; my $credentials = encode_base64("$user:$pass", ""); $connect_string = join($CRLF, "CONNECT $peer_addr:$peer_port HTTP/1.0", "Proxy-authorization: Basic $credentials" ); } else { $connect_string = "CONNECT $peer_addr:$peer_port HTTP/1.0"; } $connect_string .= $CRLF; if (send_useragent_to_proxy()) { my $lwp_object = $self->get_lwp_object; if($lwp_object && $lwp_object->agent) { $connect_string .= "User-Agent: ".$lwp_object->agent.$CRLF; } } $connect_string .= $CRLF; $self->SUPER::send($connect_string); my $timeout; my $header = ''; # See RT #33954 # See also RT #64054 # Handling incomplete reads and writes better (for some values of # better) may actually make this problem go away, but either way, # there is no good reason to use \d when checking for 0-9 while ($header !~ m{HTTP/[0-9][.][0-9]\s+200\s+.*$CRLF$CRLF}) { $timeout = $self->timeout(5) unless length $header; my $n = $self->SUPER::sysread($header, 8192, length $header); last if $n <= 0; } $self->timeout($timeout) if defined $timeout; my $conn_ok = ($header =~ m{HTTP/[0-9]+[.][0-9]+\s+200\s+}is) ? 1 : 0; if (not $conn_ok) { croak("PROXY ERROR HEADER, could be non-SSL URL:\n$header"); } $conn_ok; } # code adapted from LWP::UserAgent, with $ua->env_proxy API # see also RT #57836 sub proxy { my $self = shift; my $proxy_server = $ENV{HTTPS_PROXY} || $ENV{https_proxy}; return unless $proxy_server; my($peer_port, $peer_addr) = ( *$self->{ssl_peer_port}, *$self->{ssl_peer_addr} ); $peer_addr || croak("no peer addr given"); $peer_port || croak("no peer port given"); # see if the proxy should be bypassed my @no_proxy = split( /\s*,\s*/, $ENV{NO_PROXY} || $ENV{no_proxy} || '' ); my $is_proxied = 1; for my $domain (@no_proxy) { if ($peer_addr =~ /\Q$domain\E\z/) { return; } } $proxy_server =~ s|\Ahttps?://||i; $proxy_server; } sub configure_certs { my $self = shift; my $ctx = *$self->{ssl_ctx}; my $count = 0; for (qw(HTTPS_PKCS12_FILE HTTPS_CERT_FILE HTTPS_KEY_FILE)) { my $file = $ENV{$_}; if ($file) { (-e $file) or croak("$file file does not exist: $!"); (-r $file) or croak("$file file is not readable"); $count++; if (/PKCS12/) { $count++; $ctx->use_pkcs12_file($file ,$ENV{'HTTPS_PKCS12_PASSWORD'}) || croak("failed to load $file: $!"); last; } elsif (/CERT/) { $ctx->use_certificate_file($file ,1) || croak("failed to load $file: $!"); } elsif (/KEY/) { $ctx->use_PrivateKey_file($file, 1) || croak("failed to load $file: $!"); } else { croak("setting $_ not supported"); } } } # if both configs are set, then verify them if ($count == 2) { if (! $ctx->check_private_key) { croak("Private key and certificate do not match"); } } $count; # number of successful cert loads/checks } sub accept { shift->_unimpl("accept") } sub getc { shift->_unimpl("getc") } sub ungetc { shift->_unimpl("ungetc") } sub getlines { shift->_unimpl("getlines"); } sub _unimpl { my($self, $meth) = @_; croak("$meth not implemented for Net::SSL sockets"); } 1; __END__ =head1 NAME Net::SSL - support for Secure Sockets Layer =head1 METHODS =over 4 =item new Creates a new C<Net::SSL> object. =item configure Configures a C<Net::SSL> socket for operation. =item configure_certs Sets up a certificate file to use for communicating with on the socket. =item connect =item die_with_error =item get_cipher =item get_lwp_object Walks up the caller stack and looks for something blessed into the C<LWP::UserAgent> namespace and returns it. Vaguely deprecated. =item get_peer_certificate Gets the peer certificate from the underlying C<Crypt::SSLeay::Conn> object. =item get_peer_verify =item get_shared_ciphers =item getchunk Attempts to read up to 32KiB of data from the socket. Returns C<undef> if nothing was read, otherwise returns the data as a scalar. =item getline Reads one character at a time until a newline is encountered, and returns the line, including the newline. Grossly inefficient. =item print Concatenates the input parameters and writes them to the socket. Does not honour C<$,> nor C<$/>. Returns the number of bytes written. =item printf Performs a C<sprintf> of the input parameters (thus, the first parameter must be the format), and writes the result to the socket. Returns the number of bytes written. =item proxy Returns the hostname of an https proxy server, as specified by the C<HTTPS_PROXY> environment variable. =item proxy_connect_helper Helps set up a connection through a proxy. =item read Performs a read on the socket and returns the result. =item ssl_context =item sysread Is an alias of C<read>. =item timeout Returns the timeout value of the socket as defined by the implementing class or 60 seconds by default. =item blocking Returns a boolean indicating whether the underlying socket is in blocking mode. By default, Net::SSL sockets are in blocking mode. $sock->blocking(0); # set to non-blocking mode This method simply calls the underlying C<blocking> method of the IO::Socket object. =item write Writes the parameters passed in (thus, a list) to the socket. Returns the number of bytes written. =item syswrite Is an alias of C<write>. =item accept Not yet implemented. Will die if called. =item getc Not yet implemented. Will die if called. =item getlines Not yet implemented. Will die if called. =item ungetc Not yet implemented. Will die if called. =item send_useragent_to_proxy By default (as of version 2.80 of C<Net::SSL> in the 0.54 distribution of Crypt::SSLeay), the user agent string is no longer sent to the proxy (but will continue to be sent to the remote host). The previous behaviour was of marginal benefit, and could cause fatal errors in certain scenarios (see CPAN bug #4759) and so no longer happens by default. To reinstate the old behaviour, call C<Net::SSL::send_useragent_to_proxy> with a true value (usually 1). =back =head1 DIAGNOSTICS "no port given for proxy server <proxy>" A proxy was specified for configuring a socket, but no port number was given. Ensure that the proxy is specified as a host:port pair, such as C<proxy.example.com:8086>. "configure certs failed: <contents of $@>; <contents of $!>" "proxy connect failed: <contents of $@>; <contents of $!>" "Connect failed: <contents of $@>; <contents of $!>" During connect(). =head2 SEE ALSO =over 4 =item IO::Socket::INET C<Net::SSL> is implemented by subclassing C<IO::Socket::INET>, hence methods not specifically overridden are defined by that package. =item Net::SSLeay A package that provides a Perl-level interface to the C<openssl> secure sockets layer library. =back =cut