Changeset 68996


Ignore:
Timestamp:
Jun 19, 2010, 11:21:02 PM (10 years ago)
Author:
jmr@…
Message:

Added integrity checking for fetched archives via signed digests. New pubkeys.conf file allows configuring keys to trust. The private counterpart of the installed public key will of course need to live on our binary building server.

Location:
trunk/base
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/Makefile.in

    r65497 r68996  
    3535        [ ! -f $(DESTDIR)${sysconfdir}/macports/mp_version ] || rm -vf $(DESTDIR)${sysconfdir}/macports/mp_version
    3636        $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 444 setupenv.bash  $(DESTDIR)${datadir}/macports/
     37        $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 444 macports-pubkey.pem  $(DESTDIR)${datadir}/macports/
    3738# Only run these scripts when not building in a destroot
    3839ifeq ($(DESTDIR),)
  • trunk/base/configure

    r67298 r68996  
    689689TAR
    690690SED
     691OPENSSL
    691692RSYNC
    692693RMDIR
     
    817818CVS
    818819SVN
     820OPENSSL
    819821RSYNC
    820822SED
     
    14961498  CVS         path to cvs command
    14971499  SVN         path to svn command
     1500  OPENSSL     path to openssl command
    14981501  RSYNC       path to rsync command
    14991502  SED         path to sed command
     
    48114814
    48124815
     4816# Extract the first word of "openssl", so it can be a program name with args.
     4817set dummy openssl; ac_word=$2
     4818{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
     4819$as_echo_n "checking for $ac_word... " >&6; }
     4820if test "${ac_cv_path_OPENSSL+set}" = set; then :
     4821  $as_echo_n "(cached) " >&6
     4822else
     4823  case $OPENSSL in
     4824  [\\/]* | ?:[\\/]*)
     4825  ac_cv_path_OPENSSL="$OPENSSL" # Let the user override the test with a path.
     4826  ;;
     4827  *)
     4828  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
     4829for as_dir in $PATH
     4830do
     4831  IFS=$as_save_IFS
     4832  test -z "$as_dir" && as_dir=.
     4833    for ac_exec_ext in '' $ac_executable_extensions; do
     4834  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
     4835    ac_cv_path_OPENSSL="$as_dir/$ac_word$ac_exec_ext"
     4836    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     4837    break 2
     4838  fi
     4839done
     4840  done
     4841IFS=$as_save_IFS
     4842
     4843  ;;
     4844esac
     4845fi
     4846OPENSSL=$ac_cv_path_OPENSSL
     4847if test -n "$OPENSSL"; then
     4848  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL" >&5
     4849$as_echo "$OPENSSL" >&6; }
     4850else
     4851  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
     4852$as_echo "no" >&6; }
     4853fi
     4854
     4855
    48134856# Extract the first word of "sed", so it can be a program name with args.
    48144857set dummy sed; ac_word=$2
     
    55935636
    55945637# Define some precious variables allowing user to override PATH for some programs
     5638
    55955639
    55965640
     
    93669410
    93679411# Output
    9368 ac_config_files="$ac_config_files Doxyfile Makefile Mk/macports.autoconf.mk doc/prefix.mtree doc/macosx.mtree doc/macports.conf portmgr/freebsd/Makefile src/Makefile src/macports1.0/macports_autoconf.tcl src/port1.0/port_autoconf.tcl src/registry2.0/registry_autoconf.tcl src/programs/Makefile src/macports1.0/macports_fastload.tcl setupenv.bash"
     9412ac_config_files="$ac_config_files Doxyfile Makefile Mk/macports.autoconf.mk doc/prefix.mtree doc/macosx.mtree doc/macports.conf doc/pubkeys.conf portmgr/freebsd/Makefile src/Makefile src/macports1.0/macports_autoconf.tcl src/port1.0/port_autoconf.tcl src/registry2.0/registry_autoconf.tcl src/programs/Makefile src/macports1.0/macports_fastload.tcl setupenv.bash"
    93699413
    93709414
     
    1006310107    "doc/macosx.mtree") CONFIG_FILES="$CONFIG_FILES doc/macosx.mtree" ;;
    1006410108    "doc/macports.conf") CONFIG_FILES="$CONFIG_FILES doc/macports.conf" ;;
     10109    "doc/pubkeys.conf") CONFIG_FILES="$CONFIG_FILES doc/pubkeys.conf" ;;
    1006510110    "portmgr/freebsd/Makefile") CONFIG_FILES="$CONFIG_FILES portmgr/freebsd/Makefile" ;;
    1006610111    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
  • trunk/base/configure.ac

    r66331 r68996  
    104104AC_PATH_PROG(RMDIR, [rmdir], [])
    105105AC_PATH_PROG(RSYNC, [rsync], [])
     106AC_PATH_PROG(OPENSSL, [openssl], [])
    106107AC_PATH_PROG(SED, [sed])
    107108AC_PATH_PROG(TAR, [tar])
     
    128129AC_ARG_VAR(CVS, [path to cvs command])
    129130AC_ARG_VAR(SVN, [path to svn command])
     131AC_ARG_VAR(OPENSSL, [path to openssl command])
    130132AC_ARG_VAR(RSYNC, [path to rsync command])
    131133AC_ARG_VAR(SED, [path to sed command])
     
    347349        doc/macosx.mtree
    348350        doc/macports.conf
     351        doc/pubkeys.conf
    349352        portmgr/freebsd/Makefile
    350353        src/Makefile
  • trunk/base/doc

    • Property svn:ignore
      •  

        old new  
        11macports.conf
         2pubkeys.conf
        23prefix.mtree
        34macosx.mtree
  • trunk/base/doc/Makefile

    r51147 r68996  
    22MAN5=           macports.conf.5
    33MAN7=           portfile.7 portstyle.7 porthier.7 portgroup.7
     4CONF=       macports.conf pubkeys.conf sources.conf variants.conf
    45INSTALLDIR=     ${DESTDIR}${prefix}
    56TOPSRCDIR=      ..
     
    1718
    1819distclean: clean
    19         rm -f prefix.mtree macports.conf macosx.mtree
     20        rm -f macports.conf macosx.mtree prefix.mtree pubkeys.conf
    2021
    2122%.1.gz: %.1
     
    4142        fi
    4243
    43         $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 444 macports.conf ${DESTDIR}${mpconfigdir}/macports.conf.default
    44         if test ! -e ${DESTDIR}${mpconfigdir}/macports.conf ; then \
    45                 set -x; \
    46                 $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 644 macports.conf ${DESTDIR}${mpconfigdir}; \
    47         fi
    48         $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 444 sources.conf ${DESTDIR}${mpconfigdir}/sources.conf.default
    49         if test ! -e ${DESTDIR}${mpconfigdir}/sources.conf ; then \
    50                 set -x; \
    51                 $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 644 sources.conf ${DESTDIR}${mpconfigdir}; \
    52         fi
    53         $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 444 variants.conf ${DESTDIR}${mpconfigdir}/variants.conf.default
    54         if test ! -e ${DESTDIR}${mpconfigdir}/variants.conf ; then \
    55                 set -x; \
    56                 $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 644 variants.conf ${DESTDIR}${mpconfigdir}; \
    57         fi
     44        for f in ${CONF}; do \
     45                $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 444 $$f ${DESTDIR}${mpconfigdir}/$${f}.default; \
     46                if test ! -e ${DESTDIR}${mpconfigdir}/$$f ; then \
     47                        set -x; \
     48                        $(INSTALL) -o ${DSTUSR} -g ${DSTGRP} -m 644 $$f ${DESTDIR}${mpconfigdir}; \
     49                fi; \
     50        done
    5851
    5952        # delete old uncompressed man pages if they exist
  • trunk/base/src/macports1.0/macports.tcl

    r68902 r68996  
    5252        portdbpath porturl portpath portbuildpath auto_path prefix prefix_frozen portsharepath \
    5353        registry.path registry.format registry.installtype portarchivemode portarchivepath \
    54         portarchivetype portautoclean porttrace keeplogs portverbose destroot_umask rsync_server \
    55         rsync_options rsync_dir startupitem_type place_worksymlink macportsuser \
     54        portarchivetype archivefetch_pubkeys portautoclean porttrace keeplogs portverbose destroot_umask \
     55        rsync_server rsync_options rsync_dir startupitem_type place_worksymlink macportsuser \
    5656        mp_remote_url mp_remote_submit_url configureccache configuredistcc configurepipe buildnicevalue buildmakejobs \
    5757        applications_dir current_phase frameworks_dir developer_dir universal_archs build_arch \
     
    465465    global macports::macosx_version
    466466    global macports::macosx_deployment_target
     467    global macports::archivefetch_pubkeys
    467468
    468469    # Set the system encoding to utf-8
     
    602603    global macports::global_variations
    603604    array set macports::global_variations [array get variations]
     605
     606    # pubkeys.conf
     607    set macports::archivefetch_pubkeys {}
     608    if {[file isfile [file join ${macports_conf_path} pubkeys.conf]]} {
     609        set fd [open [file join ${macports_conf_path} pubkeys.conf] r]
     610        while {[gets $fd line] >= 0} {
     611            set line [string trim $line]
     612            if {![regexp {^[\ \t]*#.*$|^$} $line]} {
     613                lappend macports::archivefetch_pubkeys $line
     614            }
     615        }
     616        close $fd
     617    } else {
     618        ui_debug "pubkeys.conf does not exist."
     619    }
    604620
    605621    if {![info exists portdbpath]} {
  • trunk/base/src/package1.0/portarchivefetch.tcl

    r68965 r68996  
    4848options archive_sites archivefetch.user archivefetch.password \
    4949    archivefetch.use_epsv archivefetch.ignore_sslcert \
    50     archive_sites.mirror_subdir
     50    archive_sites.mirror_subdir archivefetch.pubkeys
    5151
    5252# user name & password
     
    5757# Ignore SSL certificate
    5858default archivefetch.ignore_sslcert no
     59default archivefetch.pubkeys {$archivefetch_pubkeys}
    5960
    6061default archive_sites macports_archives
     
    126127# the listed url variable and associated archive file
    127128proc portarchivefetch::fetchfiles {args} {
    128     global archivefetch.fulldestpath UI_PREFIX
     129    global portarchivepath archivefetch.fulldestpath UI_PREFIX
    129130    global archivefetch.user archivefetch.password archivefetch.use_epsv \
    130131           archivefetch.ignore_sslcert
     
    142143        }
    143144    }
     145    set incoming_path [file join ${portarchivepath} incoming]
     146    if {![file isdirectory $incoming_path]} {
     147        if {[catch {file mkdir $incoming_path} result]} {
     148            elevateToRoot "archivefetch"
     149            set elevated yes
     150            if {[catch {file mkdir $incoming_path} result]} {
     151                return -code error [format [msgcat::mc "Unable to create archive fetch path: %s"] $result]
     152            }
     153        }
     154    }
    144155    chownAsRoot ${archivefetch.fulldestpath}
     156    chownAsRoot $incoming_path
    145157    if {[info exists elevated] && $elevated == yes} {
    146158        dropPrivileges
     
    169181                return -code error [format [msgcat::mc "%s must be writable"] ${archivefetch.fulldestpath}]
    170182            }
     183            if {![file writable $incoming_path]} {
     184                return -code error [format [msgcat::mc "%s must be writable"] $incoming_path]
     185            }
    171186            if {!$sorted} {
    172187                portfetch::sortsites archivefetch_urls {} archive_sites
     
    182197                set file_url [portfetch::assemble_url $site $archive]
    183198                set effectiveURL ""
    184                 if {![catch {eval curl fetch --effective-url effectiveURL $fetch_options {$file_url} ${archivefetch.fulldestpath}/${archive}.TMP} result] &&
    185                     ![catch {file rename -force "${archivefetch.fulldestpath}/${archive}.TMP" "${archivefetch.fulldestpath}/${archive}"} result]} {
     199                if {![catch {eval curl fetch --effective-url effectiveURL $fetch_options {$file_url} {"${incoming_path}/${archive}.TMP"}} result]} {
    186200                    # Successful fetch
    187201                    set fetched 1
     
    189203                } else {
    190204                    ui_debug "[msgcat::mc "Fetching archive failed:"]: $result"
    191                     file delete -force "${archivefetch.fulldestpath}/${archive}.TMP"
     205                    file delete -force "${incoming_path}/${archive}.TMP"
    192206                }
    193207            }
    194208            if {[info exists fetched]} {
     209                # there should be an rmd160 digest of the archive signed with one of the trusted keys
     210                set signature "${incoming_path}/${archive}.rmd160"
     211                ui_msg "$UI_PREFIX [format [msgcat::mc "Attempting to fetch %s from %s"] ${archive}.rmd160 $site]"
     212                # reusing $file_url from the last iteration of the loop above
     213                if {[catch {eval curl fetch --effective-url effectiveURL $fetch_options {${file_url}.rmd160} {$signature}} result]} {
     214                    ui_debug "$::errorInfo"
     215                    return -code error "Failed to fetch signature for archive: $result"
     216                }
     217                set verified 0
     218                foreach pubkey [option archivefetch.pubkeys] {
     219                    set openssl [findBinary openssl $portutil::autoconf::openssl_path]
     220                    if {![catch {exec $openssl dgst -ripemd160 -verify $pubkey -signature $signature "${incoming_path}/${archive}.TMP"} result]} {
     221                        set verified 1
     222                        break
     223                    } else {
     224                        ui_debug "failed verification with key $pubkey"
     225                        ui_debug "openssl output: $result"
     226                    }
     227                }
     228                if {!$verified} {
     229                    return -code error "Failed to verify signature for archive!"
     230                }
     231                if {[catch {file rename -force "${incoming_path}/${archive}.TMP" "${archivefetch.fulldestpath}/${archive}"} result]} {
     232                    ui_debug "$::errorInfo"
     233                    return -code error "Failed to move downloaded archive into place: $result"
     234                }
     235                file delete -force $signature
    195236                return 0
    196237            }
  • trunk/base/src/port1.0/port_autoconf.tcl.in

    r65096 r68996  
    4545        variable gzip_path "@GZIP@"
    4646        variable lipo_path "@LIPO@"
     47        variable openssl_path "@OPENSSL@"
    4748        variable patch_path "@PATCH@"
    4849        variable gnupatch_path "@GNUPATCH@"
Note: See TracChangeset for help on using the changeset viewer.