a =*f>@s*dZdZddlZddlZddlZddlZddlZddlZddlZddl m Z ddl m Z ddl Z zddlZedZWndZYn0eZedrejrejjdurejjdsejjZned d d Drd Zed fddZddZddZddZddZddZGdddeZGdddejZ de_!dGdd Z"ej#j$Z%d!d"Z&e&ej#_$ej'j(Z)d#d$Z*e*ej'_(d%d&Z+d'd(Z,dHd+d,Z-d-d.Z.d/d0Z/d1d2Z0d3d4Z1e2d5ej3Z4e2d6ej3Z5e2d7ej3Z6d8d9Z7d:d;Z8d0r )LANGUAGELC_ALLLC_CTYPELANGUTF-8strictc CsPzt|tr|||WS|WSttfyJ|dkr:||dYS0dS)Nrreplace) isinstancebytesdecodeUnicodeDecodeErrorUnicodeEncodeError)xencerrorsr r r uni_decode@s rcCst|tst|S|tdS)Nr)rrstrr PREFER_ENCrr r r uni_stringIs r"cCs t|dS)Nr)rr!r r r uni_bytesMsr#cCst|tst|S|dvS)N)1ZontrueZyes)rrboollower)valr r r _as_boolPs r)cCs"tdd\}}|jt|fS)z+ Consistently format exception information N)sysexc_info__name__r")Zclaexcr r r formatExceptionInfoUsr/cCsRtj|}|dr"|dd}|tddgvrNtjtj|d|}|S)zaCustom function to include directory name if filename is too common Also strip .py at the end z.pyNbase__init__.)rpathbasenameendswithsetdirname)sr1r r r mbasenameas    r:c@s"eZdZdZdddZddZdS) TraceBackz7Customized traceback to be included in debug messages FcCsd|_||_dS)zInitialize TrackBack metric Parameters ---------- compress : bool if True then prefix common with previous invocation gets replaced with ... rN)_TraceBack__prev_TraceBack__compress)selfcompressr r r r2rs zTraceBack.__init__c Cstjdddd}dd|D}dd|D}|dg}|ddD]@}|d|d dkr||d dd |d7<qF||qFd d d|D}|jr|}tj|j|f}t d d|}|dkrd|t |d}||_|S)Nd)limitcSs2g|]*}t|dtj|dt|dgqS)rr)r:rr4r8rr rr r r sz&TraceBack.__call__..cSs6g|].}|ddvs|dds|d|dgqS)r)Zunittestzlogging.__init__rz /unittestr*)r6)r er r r rDs rrz,%s>cSs$g|]}dt|d|dfqS)z%s:%srr)r:rCr r r rDs z>[^>]*$rz...) traceback extract_stackappendjoinr=rr4 commonprefixr<resublen) r>ZftbentriesZ entries_outentryZsftbZ prev_nextZ common_prefixZcommon_prefix2r r r __call__~s*   zTraceBack.__call__N)F)r- __module__ __qualname____doc__r2rRr r r r r;ns r;c@s eZdZdZddZddZdS)FormatterWithTraceBackz}Custom formatter which expands %(tb) and %(tbc) with tracebacks TODO: might need locking in case of compressed tracebacks cOs6tjj|g|Rd|i|d|v}t|d|_dS)Nfmtz%(tbc)s)r?)logging Formatterr2r;_tb)r>rWargskwargsr?r r r r2szFormatterWithTraceBack.__init__cCs||_|_tj||SN)rZZtbctbrXrYformat)r>recordr r r r_szFormatterWithTraceBack.formatN)r-rSrTrUr2r_r r r r rVsrVFcCsh|rt|jr||jd|r,dd|_ddtj_tjrdztj Wn Yn0t ddS)NrcSsdSr]r r r r r rz!__stopOnIOError..cSsdSr]r r>r r r rar) rOhandlersZ removeHandlercloserX StreamHandlerflush exitOnIOErrorr+stderrexit)ZlogSysZlogHndlrr r r __stopOnIOErrors  rjc Kszt||||fi|WnttfyV}z |jdkr@t|WYd}~nd}~0ty}zlzRd|t|ffddd|DfffD](}zt||g|RWqYq0qWn Yn0WYd}~n d}~00dS)aSafe log inject to avoid possible errors by unsafe log-handlers, concat, str. conversion, representation fails, etc. Used to intrude exception-safe _log-method instead of _log-method of Logger class to be always safe by logging and to get more-info about. See testSafeLogging test-case for more information. At least the errors covered in phase 3 seems to affected in all known pypy/python versions until now. Nzlogging failed: %r on %sz args: %rcSsg|] }t|qSr )r")r ar r r rDrz__safeLog..) __origLogBrokenPipeErrorIOErrorerrnorj Exceptionr")r>levelmsgr[r\rEr r r __safeLogs"   rtc CsPz t|Wn>ttfyJ}z"|jdkr4td|WYd}~n d}~00dS)zQSafe flush inject stopping endless logging on closed streams (redirected pipe). rkN)__origLogFlushrnrorprj)r>rEr r r __safeLogFlushs    rvcCs$d|vrd|dd}t|S)zBGet logging.Logger instance with Fail2Ban logger name convention r3z fail2ban.%srF) rpartitionrX getLoggernamer r r rxsrxcCsRz.t|ts|rt|}ntt|}WntyLtd|Yn0|S)NzInvalid log level %r)rintisdigitgetattrrXupperAttributeError ValueError)valueZllr r r str2LogLevels  r %(message)sTcCsn|dkr@|dkrd|}|dkr*d|}qTd|}|rTd|}nd|}|rTd |}|sjtd d d |}|S) z(Custom log format for the verbose runs rz6 | %(module)15.15s-%(levelno)-2d: %(funcName)-20.20s |r*zB +%(relativeCreated)5d %(thread)X %(name)-25.25s %(levelname)-5.5sz %(thread)X %(levelname)-5.5sz %(asctime)-15sz)%(name)-24s[%(process)d]: %(levelname)-7sz %(asctime)s z(?<=\))-?\d+(?:\.\d+)?scSsdS)Nr9r )mr r r ra rz$getVerbosityFormat..)rMrN) verbosityrWZaddtimeZpaddingr r r getVerbosityFormats  rcCs tdjdddt|||S)z>Except hook used to log unhandled exceptions to Fail2Ban log Zfail2banz Unhandled exception in Fail2Ban:T)r,)rxZcriticalr+__excepthook__)exctyperrHr r r excepthooksrcCs(|sgStttddtd|DS)zHelper to split words on any comma, space, or a new line Returns empty list if input is empty (or None) and filters out empty entries cSsg|] }|qSr )striprr r r rDrzsplitwords..z[\s,]+)listfilterr&rMsplit)r9r r r splitwordssrcCs|ri||S|S)zHelper to merge dicts. r ryr r r _merge_dictss rcCs i||S)zBHelper to merge dicts to guarantee a copy result (r is never x). r rr r r _merge_copy_dicts&srz^([^\[]+)(?:\[(.*)\])?\s*$zf\s*([\w\-_\.]+)=(?:"([^"]*)"|\'([^\']*)\'|([^,\]]*))(?:,|\]\s*\[|$|(?P.+))|,?\s*$|(?P.+)zs(?:[^\[\s]+(?:\s*\[\s*(?:[\w\-_\.]+=(?:"[^"]*"|\'[^\']*\'|[^,\]]*)\s*(?:,|\]\s*\[)?\s*)*\])?\s*|\S+)(?=\n\s*|\s+|$)cCst|}|std|\}}t}|rt|D]}|drptd|d|d|dddf|drtd|d|dddf|d}|sq6d d |d d d Dd}| || <q6||fS)Nzunexpected option syntaxZwrngAz+unexpected syntax at %d after option %r: %srrZwrngBz'expected option, wrong syntax at %d: %scSsg|]}|dur|qSr]r )r r(r r r rDKsz"extractOptions..r*r) OPTION_CREmatchrgroupsdictOPTION_EXTRACT_CREfinditergroupstartr)optionrZ option_nameZoptstrZ option_optsZoptmatchoptrr r r extractOptions;s0       rcCs t|Sr])OPTION_SPLIT_CREfindall)rr r r splitWithOptionsPsrrz <([^ <>]+)>rr cCstj}|}t|}t}t|d}i}d} |D]} | |vs2| |vrJq2|r^t|| r^q2t|| } } || } || i}| r| d}||vr|| | } q|| ks||dt krt d| ||| fd}|r||d|}|dur ||}|dur |dur ||}|dur:|| | } qt |tsNt|}| d||} ||dd||<|| | } q| | kr|| r||| <d } t|t|kr|}| || <d | vr2|| q2| s&qq&|S) a|Sort out tag definitions within other tags. Since v.0.9.2 supports embedded interpolation (see test cases for examples). so: becomes: a = 3 a = 3 b = _3 b = 3_3 Parameters ---------- inptags : dict Dictionary of tags(keys) and their values. Returns ------- dict Dictionary of tags(keys) and their values, with tags within the values recursively replaced. getRawItemFrzpproperties contain self referencing definitions and cannot be resolved, fail tag: %s, found: %s in %s, value: %sN?z<%s>rT<)TAG_CREsearchr7hasattrkeyscallablerr"getrendMAX_TAG_REPLACE_COUNTrrrrridcopyadd)ZinptagsZ conditionalignoreZaddreplZ tre_searchtagsZdoneZ noRecReplZ repCountsZrepFlagtagrZorgvalrZrplcZrtagreplr r r substituteRecursiveTags^sb         rcCs*z|}td|Wn Yn0dS)zHelper to set real thread name (used for identification and diagnostic purposes). Side effect: name can be silently truncated to 15 bytes (16 bytes with NTS zero) N)encode_libcapZprctlryr r r prctl_set_th_names rcCsdSr]r ryr r r rscs<eZdZdZeZdZfddZddZd dd Z Z S) BgServicez{Background servicing Prevents memory leak on some platforms/python versions, using forced GC in periodical intervals. Ncs|jstt|||_|jSr]) _instancesuperr__new__)cls __class__r r rszBgService.__new__cCs2d|_d|_d|_|j|_ttdr.tddS)Nir@ set_thresholdr)_BgService__serviceTime_BgService__periodTime_BgService__threshold_BgService__countrgcrrbr r r r2s  zBgService.__init__FcCs|jd8_|s.|jdks*t|jkr.dStj|s>dSzNt|jkr^WtjdSt t|j |_|j |_WtjdStj0dS)NrrFT) rrtimerr_mutexacquirereleaserZcollectrr)r>forcewaitr r r services$    zBgService.service)FF) r-rSrTrUrrrrr2r __classcell__r r rr rs   r)NN)rTT)rr N)> __author__Z __license__rlocalerXrrMr+rH threadingrZ server.mytimer importlibZctypesZCDLLrgetpreferredencodingr startswithstdoutencodingallrr"r#r)r/r:objectr;rYrVrgrjZLoggerZ_logrmrtrerfrurvrxrrrrrrcompileDOTALLrrrrrrrrrrr r r r s~         .        c