J0mhW:dZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlmZddlmZe j,j/ddZe j,j/ddZd Zd Zd ZGd d ej:j<ZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)e jTdZ+dejXde-e.e.ffdZ/ej`de-e.e.ffdZ1de2fdZ3de2fdZ4dZ5d Z6d!Z7d"Z8d#Z9d$Z:d%ed&e.ddfd'Z;d;d(Zz0Functions to manage apport problem report files.N)impl) ProblemReportAPPORT_REPORT_DIRz /var/crashAPPORT_COREDUMP_DIRz/var/lib/apport/coredumpz~/.config/apport/settingsz/run/snapd.socketceZdZdZdZy)UHTTPConnectioncftjjj|d||_y)N localhost)httpclientHTTPConnection__init__path)selfrs 2/usr/lib/python3/dist-packages/apport/fileutils.pyrzUHTTPConnection.__init__/s# ""++D+> ctjtjtj}|j|j||_yN)socketAF_UNIX SOCK_STREAMconnectrsock)rrs rrzUHTTPConnection.connect3s3}}V^^V-?-?@ TYY rN)__name__ __module__ __qualname__rrrrr r .s rr ctjdtjsy gd}tj|dk(S#t $rYywxYw)z)Check whether crash reporting is enabled.z/usr/bin/whoopsieT)z/bin/systemctlz-qz is-enabledz whoopsie.pathrF)osaccessX_OK subprocesscallOSError)cmds rallowed_to_reportr'9sH 99("'' 2Es#q(( sA AAc|sy|jdsyd|vrydD]}||vsy|jd}t|dk7ry|dS)z'Extract the socket from a DBus address.Nzunix:path=/run/user/z../)%,;=) startswithsplitlen) dbus_addrsearchpartss rget_dbus_socketr5Esl     6 7 " Y  OOC E 5zQ 8Orc@|yd}tj|D]e}|jds|jds|jds8|ry t |d5}d|j vr|}dddg|S#1swY xYw#t $rYwxYw)zReturn a package's .desktop file. If given package is installed and has a single .desktop file, return the path to it, otherwise return None. Nz.desktopz/etc/xdg/autostartz/usr/share/applications/rbsNoDisplay=true) packaging get_filesendswithr/openreadFileNotFoundError)package desktopfilelinefs rfind_package_desktopfilerB_s K##G, == $??#78*B $%+(8&* +&  ++%  s* B$B9BB B BBcgd}d}|D]}|j|sd}n|xr&|jd xr|jd S)a2Check whether the given file is likely to belong to a package. This is semi-decidable: A return value of False is definitive, a True value is only a guess which needs to be checked with find_file_package(). However, this function is very fast and does not access the package database. ) z/bin/z/bootz/etc/z/initrdz/libz/sbin/z/optz/usr/z/varFTz /usr/local/z /var/lib/)r/)file pkg_allowlistallowlist_matchis rlikely_packagedrHse MO  ??1 "O   - . . - , ,rcDtjj|\}}tjj|}tjj |r tjj ||}t |sytj|S)z[Return the package that ships the given file. Return None if no package ships it. N) r rr0realpathisdirjoinrHr8get_file_package)rD directoryname resolved_dirs rfind_file_packagerQso  d+Y77##I.L ww}}\"ww||L$/ 4   % %d ++rc tjtt5}d|}|j d||j }|j dk(r/tj|jdcdddS dddy#1swYyxYw#tjjtjtf$rYywxYw)zbReturn the data of the given snap. Return None if the snap is not found to be installed. z /v2/snaps/GETresultN) contextlibclosingr SNAPD_SOCKETrequest getresponsestatusjsonloadsr<r r HTTPExceptionJSONDecodeErrorr%)snapcurlresponses r find_snaprds     = > =!tf%C IIeS !}}H#%zz(--/28<  = =&  =  =  KK % %t';';W Es5"B AB B B BB B 2CCctj|}|j|jkDxs|jdk(S)zACheck whether the report file has already been processed earlier.r)r statst_atimest_mtimest_size)reportsts r seen_reportrls/ B KK"++ % ;2::?;rc|jdddd}|jdddd}tjj|rwtjj|rXtj|}tj|}|j |j krtj |t|dd5 dddy#1swYyxYw) N.r.rz.uploadz .uploadedautf-8encoding)rsplitr rexistsrfrhunlinkr;)rjuploaduploaded report_st upload_sts rmark_report_uploadrzs c1%a() 1F--Q'*+95H ww~~hBGGNN6$:GGFO GGFO    2 2 2 IIf  fcG ,     s C  C)c.d|vr|djdd}n tdtj}|dt |d|d}tj j t|}t|dd 5 dddy#1swYyxYw) NExecutablePath/_z1report does not have the ExecutablePath attributernz.hangingrorprq) replace ValueErrorr geteuidstrrrL report_dirr;)rjpidsubjectuidbasers rmark_hanging_processrs6!)*223<LMM **,CYaCz3%x 0D 77<< D )D dC' *     s B  Bctj|} tj||j|jdz fy#t$rd}|dkDrt |d5}|j ddddn #1swYnxYw tj|}n#t$rYYywxYw|j|jkDrn tjd|dz}|dkDr|dk(r t|YyYywxYw)zMark given report file as seen.r. rrprqNg?) r rfutimerhr%r;r<rgtimesleep delete_report)rjrktimeout report_files rmark_report_seenrs B" "++r{{Q78 " kfw/ $;  # $ $ $ WWV_  {{R[[( JJsO qLGk a< & ! '"sS/AD$A?6 D?B D B"!D" B/+D.B//[A-Z0-9_]+)\s+(?P[\"\']?)(?P.*)(?P=quote)\s*$linesreturnci}|D]=}tj|}|s|jd||jd<?|S)NvaluerO)_LOGIN_DEFS_REmatchgroup)rdefsr@rs r_parse_login_defsrsO D9$$T* $)KK$8U[[ ! 9 Krc tdd5}t|cdddS#1swYyxYw#t$ricYSwxYw)z?Parse /etc/login.defs and return a dictionary with its content.z/etc/login.defsrprqN)r;rr=)login_defs_files rget_login_defsrsD #g 6 6/$_5 6 6 6  s 0 $ 0-00 >>cZ ttdS#ttf$rYywxYw)zBReturn maximum system group ID (SYS_GID_MAX from /etc/login.defs). SYS_GID_MAXintrKeyErrorrrrrget_sys_gid_maxr1>#M233 j ! **cZ ttdS#ttf$rYywxYw)zAReturn maximum system user ID (SYS_UID_MAX from /etc/login.defs). SYS_UID_MAXrrrrrget_sys_uid_maxr!rrcrg}tjtjjtdD]k} tjj |dkDrFtj |tjtjzr|j|m|S#t$rY{wxYw)zCReturn a list with all report files accessible to the calling user.*.crashr) globr rrLrgetsizer!R_OKW_OKappendr%reportsrs rget_all_reportsr)sG YYrww||J : ; wwq!A%"))Arww7H*Iq! N    sA(B** B65B6cg}tD]} t|s|j|!|S#t$rY/wxYw)zGet new reports for calling user. Return a list with all report files which have not yet been processed and are accessible to the calling user. )rrlrr%rs rget_new_reportsr7sQ G   q>q! N    s 1 ==cg}t}tjtjj t dD]} tj |}|jdkDr]|j|krN tj|j}|jjdrs |j||S#t$rY wxYw#t$rYwxYw)aGet all system reports. Return a list with all report files which belong to a system user. The maximum system user group ID is taken from SYS_UID_MAX from /etc/login.defs (defaults to 999 on Debian based systems and LSB specifies 499 in "User ID Ranges"). rrguest)rrr rrLrrfrist_uidpwdgetpwuidpw_namer/rrr%)r sys_uid_maxrrkpws rget_all_system_reportsrIsG!#K YYrww||J : ; BzzA~")){":bii0Bzz,,W5 6 q!$ N    s63C<:C 7C CCCC C('C(cTtDcgc]}t|r|c}Scc}w)a5Get new system reports. Return a list with all report files which have not yet been processed and belong to a system user. The maximum system user group ID is taken from SYS_UID_MAX from /etc/login.defs (defaults to 999 on Debian based systems and LSB specifies 499 in "User ID Ranges"). )rrl)rs rget_new_system_reportsrhs!./ F!{1~A FF Fs%%c tj|y#t$r8t|dd5}|j ddddYy#1swYYyxYwwxYw)zDelete the given report file. If unlinking the file fails due to a permission error (if report_dir is not writable to normal users), the file will be truncated to 0 bytes instead. wrprqrN)r rur%r;truncate)rjrAs rrrssP  &  &# 0 A JJqM   s&AA A A AAcDt}|j|dddg t|d}tjtj |d}tjtj }||z dkDry|S#ttf$rYywxYw)zReturn the number of recent crashes for the given report file. Return the number of recent crashes (currently, crashes which happened more than 24 hours ago are discarded). F CrashCounterDate) key_filteriQr) rloadrrmktimestrptime localtimerr)rjprcount report_timecur_times rget_recent_crashesrs BGGFE~v&>G? B~&'kk$--6 ";< ;;t~~/0 k !I -  !sA(B B BBrjfilenamect|sytj|tjtjztj z}tj |}tj|jr>' "" " ^^ D'*   FA J $$&1136 == "   dkk#q1!4 56 rrctjd}d}d}d} tj|tjtj z}tj |}tj|jr'tj|d}|jd}||jn|tj| |j||S#t$rYJwxYw#||jw|tj|wwxYw#tj$rY|SwxYw)N) interpolationri) configparser ConfigParserr r;rrrrfrrrr<r%close read_stringMissingSectionHeaderError)rconfigcontentsrrArks r_get_config_parserrs  & &T :FH B A  WWT2==2;;6 7 XXb\ << # "c"Avvc{H = GGI ^ HHRL 8$ M     = GGI ^ HHRL  1 1  M s6BC-D,- C96C<8C99C<<-D),EEc@|s@tjtjd}tj d|}t |} |r|j||S|j||S#tjtjf$r|cYSwxYw)zReturn a setting from user configuration. This is read from ~/.config/apport/settings or path. If bool is True, the value is interpreted as a boolean. Privileges may need to be dropped before calling this. r~) rrr r _config_filerr getbooleangetr NoOptionErrorNoSectionError)sectionsettingdefaultrbooleanhomedirrs r get_configr s ,,rzz|,Q/##C1  %F $$Wg6 6zz'7++  & & (C(C DsA5#A55%BBrch||jddzd}t|jdS)z7Extract the starttime from the contents of a stat file.)r-N)rfindrr0)rstrippeds r get_starttimer s6 s+a/12H x~~# $$rcfd}d}|jD]}|jdr9t|jdkDrt |jd}M|jds_t|jdkDs|t |jd}||fS)z;Extract the uid and gid from the contents of a status file.NzUid:r.zGid:)rr/r1r0r)rreal_uidreal_gidr@s rget_uid_and_gidrsHH##%, ??6 "s4::<'81'<4::<?+H __V $TZZ\):Q)>4::<?+H, h rc|D]O}|j}t|dk7r"t|d}|t|dz}||cxkr|ksMyQy)zSearch for an ID in a map fd.r.r-TF)r0r1r)mapfdrr@fields host_starthost_ends r search_mapr#sd  v;!  ^ F1I.  ( ( )  rctdd5}|jj}ddd|S#1swYSxYw)zGet the kernel boot id.z/proc/sys/kernel/random/boot_idrprqN)r;r<strip)rAboot_ids r get_boot_idr3s; /' B#a&&(.."# N# Ns 7A proc_pid_fdc vdttjtzdtdtffd }t ddd|5}|j j d }d d d siSt|jd Dcgc]}d |vs|jd d c}S#1swYJxYwcc}w)zGet the process environ from a proc directory file descriptor. Raises an OSError in case the environ file could not been read. rflagsrc4tj||SNdir_fdr r;rr"r s ropenerz#get_process_environ..opener@wwtU;77renvironrpr)rrerrorsr)z Nr,r.) rr PathLikerr;r<rstripdictr0)r r) environ_fdr+entrys` rget_process_environr3:s 8S2;;s++8C8C8 GIf 2 //#**512  '--2EVPUS!$V WW22Ws B* B6B6*B3cV|y tjd|S#t$rYywxYw)z;Get the process path from a proc directory file descriptor.unknownexer%)r readlinkr%)r s rget_process_pathr8Ms3{{555 s  ((c 8dttjtzdtdtffd }|d}d}n?|=d}nd|d }t |d | 5}|j }dddt }| t}|jd d jdd }|tj}d|d|dtdt|dt| } tjjt| } | | fS#1swYxYw)zGet the path to a core file.rr"rc4tj||Sr$r'r(s rr)zget_core_path..openerZr*rNr5rfz/proc/z/statrp)rrr)r}r~rnzcore.)rr r.rr;r<rr8rgetuidrrrLcore_dir) rr6r timestampr r) stat_filename stat_file stat_contents core_name core_paths ` r get_core_pathrCWs 8S2;;s++8C8C8 {    ""M$SE/M -'& A -Y%NN,M -!-0  {{+ ++c3  ' 'S 1C {iikuAcU!KM?!CH:Qs9~>NOI Xy1I y !!# - -s DDct|}g}g}tjjtrtj t}|D]n} |j dd|k(rTtjjtjjt|}|j||gp|S#ttf$rYwxYw)zSearch the core file directory for files that belong to a specified uid. Returns a list of lists containing the filename and the file modification time. )rrnr-) rr rrtr<listdirr0getmtimerLr IndexErrorr=)r core_files uid_filesrAcore_file_times rfind_core_files_by_uidrKys c(CJI ww~~hZZX.  wws|A#%!#!1!1"'',,x2K!L  !^!45  -.   sA+CCCcnt|}t|tjd}t |t dz kDrut t |t z dzD]S}tjtjjt|dd|j|dUyy)zeRemove old files from the core directory if there are more than the maximum allowed per uid. r.)keyrN) rKsortedoperator itemgetterr1max_corefiles_per_uidranger removerrLr<)rrI sorted_filesr~s rclean_core_directoryrUs's+I))<) path mapping, for example 'libc.so.6' -> '/lib/x86_64-linux-gnu/libc.so.6'. lddT)rruniversal_newlinesz=>r.z linux-vdsor(N) r#PopenrSTDOUTrr0rrr/rr)rlibsrWr@rOrests rshared_librariesr^s D          JJ D !ZZa0 d::23 q1-@PQQ ww~~h H(=hZ 0 1   j ! sA A A c^t|}||vry|D]}|j|dsyy)zCheck if the binary at path links with the library named lib. path should be a fully qualified path (e.g. report['ExecutablePath']), lib may be of the form 'lib' or 'lib.so.' Tz.so.F)r^r/)rlibr\ linked_libs rlinks_with_shared_libraryrdsC D !D d{  C5 . rr)NNF)NNNNN)M__doc__rrV functoolsr http.clientr ior\rOr rrerrfr#rapport.packaging_implrr8problem_reportrr+rrr<rQrrXr rr r'r5rBrHrQrdrlrzrrcompiler TextIOWrapperr0rrcacherrrrrrrrrrrrrrrr rrrrr3r8rCrKrUr^r`rdrrrros)6    3( ZZ^^/ > ::>>/1K L* " dkk00 4BB,""<    ":O R--$sCx. S#X $>G ( 4M 4S 4T 4.: S\%>%>8.%C%C%    XSXT#s(^X&"D, 1!HmssTz*r