Check-in [9c00913b70]
Not logged in
Overview
Comment:Improvements to the OpenPGP (e.g. GPG) integration.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9c00913b709de8d4f9f14c18414b9a0b3e4bbe1c
User & Date: mistachkin on 2017-08-10 17:46:29
Other Links: manifest | tags
Context
2017-08-15
15:46
Unless the '-overwrite' option is specificed, skip downloading persistent files that already exist. check-in: e4d6fd9866 user: mistachkin tags: trunk
2017-08-11
20:03
Unless the '-overwrite' option is specificed, skip downloading persistent files that already exist. Closed-Leaf check-in: 7e9a724b58 user: mistachkin tags: overwrite
2017-08-10
17:46
Improvements to the OpenPGP (e.g. GPG) integration. check-in: 9c00913b70 user: mistachkin tags: trunk
02:55
Consistently check for the 'openPgpFileNameOnly' variable before trying to use it. Closed-Leaf check-in: 195273da17 user: mistachkin tags: openPgpVars
2017-07-21
22:01
Fix automatic package platform detection that was broken by the previous check-in (split file name off-by-one error). check-in: 73c4a2b205 user: mistachkin tags: trunk
Changes

Modified client/1.0/neutral/pkgr.eagle from [9a56a1bf87] to [4084937617].

392
393
394
395
396
397
398
399
400


401
402
403
404








405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440


441
442
443
444
445
446
447
448
449
450
451
452
453
454



455
456
457
458




459
460
461
462
463
464
465
466









































467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486

487




488
489
490
491
492
493
494
392
393
394
395
396
397
398


399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467




468
469
470
471








472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545







-
-
+
+




+
+
+
+
+
+
+
+



















-
+
















+
+














+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




















+

+
+
+
+







  #       OpenPGP installation directory was successfully detected and added
  #       to the PATH -OR- detecting and adding it was not necessary because
  #       it already appeared to be available for use.
  #
  # <internal>
  proc probeForOpenPgpInstallation {} {
    global env
    variable openPgpInstalledDirectory
    variable openPgpInstalledFileName
    variable openPgpFileNameOnly
    variable openPgpInstalledDirectory

    if {[catch {openPgpMustBeInstalled}] == 0} then {
      return true
    }

    if {![info exists openPgpFileNameOnly]} then {
      return false
    }

    if {![info exists openPgpInstalledDirectory]} then {
      return false
    }

    if {[isWindows]} then {
      if {[info exists env(ProgramFiles(x86))]} then {
        set programFiles $env(ProgramFiles\(x86\))
      } elseif {[info exists env(ProgramFiles)]} then {
        set programFiles $env(ProgramFiles)
      } else {
        return false
      }

      set directory [file join $programFiles $openPgpInstalledDirectory]
    } else {
      set directory $openPgpInstalledDirectory
    }

    if {![file isdirectory $directory]} then {
      return false
    }

    set fileName [file join $directory $openPgpInstalledFileName]
    set fileName [file join $directory $openPgpFileNameOnly]

    if {[file exists $fileName] && [file isfile $fileName]} then {
      return [addToPath $directory]
    }

    return false
  }

  #
  # NOTE: This procedure attempts to verify that a configured implementation
  #       of OpenPGP is installed locally.  There are no arguments.  Script
  #       errors are raised if any problems are found.  The return value is
  #       undefined.
  #
  # <public>
  proc openPgpMustBeInstalled {} {
    variable openPgpFileNameOnly
    variable openPgpFileNamesOnly
    variable openPgpInstalledCommand
    variable openPgpInstalledPattern

    set message {
      Cannot use OpenPGP: it does not appear to be installed.

      GNU Privacy Guard (GPG) may be downloaded from "https://www.gnupg.org/"
      and then installed.  Signed binaries for Windows may be available from
      "https://www.gpg4win.org/".

      Alternatively, it may be possible to install GNU Privacy Guard (GPG) via
      the package management subsystem included with your operating system.
    }

    set found false

    foreach fileName $openPgpFileNamesOnly {
    if {[isEagle]} then {
      if {[catch {
        eval exec -success Success $openPgpInstalledCommand
      } result]} then {
      if {[isEagle]} then {
        if {[catch {
          eval exec -success Success [subst $openPgpInstalledCommand]
        } result] == 0} then {
        error $message
      }
    } else {
      if {[catch {
        eval exec $openPgpInstalledCommand
      } result]} then {
        error $message
      }
          set found true; break
        }
      } else {
        if {[catch {
          eval exec [subst $openPgpInstalledCommand]
        } result] == 0} then {
          set found true; break
        }
      }
    }

    if {$found} then {
      #
      # NOTE: Was this procedure already run -AND- did it actually find a
      #       viable OpenPGP file name?
      #
      if {[info exists openPgpFileNameOnly]} then {
        #
        # NOTE: If the OpenPGP file name that we found before (?) does not
        #       match what we already have, issue a log message.
        #
        if {$fileName ne $openPgpFileNameOnly} then {
          pkgLog [appendArgs \
              "the OpenPGP file name is being changed from \"" \
              $openPgpFileNameOnly "\" to \"" $fileName \"]

          set openPgpFileNameOnly $fileName
        }
      } else {
        #
        # NOTE: Configure the OpenPGP file name to the one that was just
        #       found.
        #
        set openPgpFileNameOnly $fileName
      }
    } else {
      #
      # NOTE: If no viable OpenPGP file name was found, raise the error
      #       message.
      #
      error $message
    }

    if {![info exists result] || \
        ![regexp -- $openPgpInstalledPattern $result]} then {
      error "cannot use OpenPGP: unknown or unsupported version"
    }

    return ""
  }

  #
  # NOTE: This procedure attempts to verify the OpenPGP signature contained
  #       in the specified (named) file.  Non-zero is only returned if the
  #       OpenPGP signature is verified successfully.  A script error should
  #       not be raised by this procedure.  The fileName argument must be
  #       the fully qualified path and file name of the OpenPGP signature
  #       file to verify.
  #
  # <public>
  proc verifyOpenPgpSignature { fileName } {
    variable openPgpFileNameOnly
    variable openPgpVerifyCommand

    if {![info exists openPgpFileNameOnly]} then {
      return false
    }

    if {[isEagle]} then {
      set fileName [formatExecArgument $fileName]

      if {[catch {
        eval exec -success Success [subst $openPgpVerifyCommand]
      }] == 0} then {
585
586
587
588
589
590
591

592




593
594
595
596
597
598
599
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655







+

+
+
+
+







  #       signature is created successfully.  A script error should not be
  #       raised by this procedure.  The fileName argument must be the fully
  #       qualified path and file name of the file to be signed.
  #
  # <public>
  proc createOpenPgpSignature { fileName } {
    global env
    variable openPgpFileNameOnly
    variable openPgpSignCommand

    if {![info exists openPgpFileNameOnly]} then {
      return false
    }

    if {[isEagle]} then {
      set fileName [formatExecArgument $fileName]

      if {[catch {
        eval exec -success Success [subst $openPgpSignCommand]
      }] == 0} then {
618
619
620
621
622
623
624

625
626




627
628
629
630
631
632
633
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694







+


+
+
+
+







  #       the fully qualified path and file name of the OpenPGP key file
  #       to import.  This procedure is only intended to be used from the
  #       "pkgr_setup.eagle" tool script and may go away in later versions
  #       of this package.
  #
  # <internal>
  proc importOpenPgpKeyFile { fileName varName } {
    variable openPgpFileNameOnly
    variable openPgpImportCommand
    variable openPgpImportPattern

    if {![info exists openPgpFileNameOnly]} then {
      return false
    }

    if {[string length $varName] > 0} then {
      upvar 1 $varName result
    }

    if {[isEagle]} then {
      set fileName [formatExecArgument $fileName]
2065
2066
2067
2068
2069
2070
2071























































































































2072
2073
2074
2075
2076
2077
2078
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








      if {[file exists $fileName] && [file isfile $fileName]} then {
        uplevel 1 [list source $fileName]
      }
    }
  }

  #
  # NOTE: This procedure sets up the default values for all configuration
  #       parameters used to interact with the OpenPGP implementation.
  #       There are no arguments.
  #
  proc setupRepositoryOpenPgpVars {} {
    #
    # NOTE: This is the name of the sub-directory containing the OpenPGP
    #       implementation.  It is platform-specific.  On Windows, this
    #       sub-directory is relative to the "Program Files" directory.
    #
    variable openPgpInstalledDirectory; # DEFAULT: [file join GNU GnuPG]

    if {![info exists openPgpInstalledDirectory]} then {
      if {[isWindows]} then {
        set openPgpInstalledDirectory [file join GNU GnuPG]
      } else {
        set openPgpInstalledDirectory [file join / usr bin]
      }
    }

    #
    # NOTE: These are the candidate names of the executable file used to
    #       invoke the OpenPGP implementation, possibly without a file
    #       extension.
    #
    variable openPgpFileNamesOnly; # DEFAULT: [list gpg2 gpg]

    if {![info exists openPgpFileNamesOnly]} then {
      if {[isWindows]} then {
        set openPgpFileNamesOnly [list gpg2.exe gpg.exe]
      } else {
        set openPgpFileNamesOnly [list gpg2 gpg]
      }
    }

    #
    # NOTE: This is the name of the executable file used to invoke the
    #       OpenPGP implementation, possibly without a file extension.
    #
    variable openPgpFileNameOnly; # DEFAULT: <unset>

    #
    # NOTE: The command to use when attempting to import an OpenPGP key
    #       file.  This must be configured according to the implementation
    #       of OpenPGP in use.
    #
    variable openPgpImportCommand; # DEFAULT: gpg2 --import

    if {![info exists openPgpImportCommand]} then {
      set openPgpImportCommand \
          {{${openPgpFileNameOnly}} --import {${fileName}}}
    }

    #
    # NOTE: The regular expression pattern used when attempting to verify
    #       that OpenPGP successfully imported one or more keys.  This must
    #       be configured according to the implementation of OpenPGP in use.
    #
    variable openPgpImportPattern; # DEFAULT: ^gpg: Total number processed: 1$

    if {![info exists openPgpImportPattern]} then {
      set openPgpImportPattern {^gpg: Total number processed: 1$}
    }

    #
    # NOTE: The command to use when attempting to verify that OpenPGP is
    #       installed locally.  This must be configured according to the
    #       implementation of OpenPGP in use.
    #
    variable openPgpInstalledCommand; # DEFAULT: gpg2 --version

    if {![info exists openPgpInstalledCommand]} then {
      set openPgpInstalledCommand {{${fileName}} --version}
    }

    #
    # NOTE: The regular expression pattern used when attempting to verify
    #       that OpenPGP is installed locally.  This must be configured
    #       according to the implementation of OpenPGP in use.
    #
    variable openPgpInstalledPattern; # DEFAULT: ^gpg \(GnuPG\) 2\.[012]\.

    if {![info exists openPgpInstalledPattern]} then {
      set openPgpInstalledPattern {^gpg \(GnuPG\) 2\.[012]\.}
    }

    #
    # NOTE: The command to use when verifying OpenPGP signatures for the
    #       downloaded package scripts.  This must be configured according
    #       to the implementation of OpenPGP in use.
    #
    variable openPgpVerifyCommand; # DEFAULT: gpg2 --verify {${fileName}}

    if {![info exists openPgpVerifyCommand]} then {
      set openPgpVerifyCommand \
          {{${openPgpFileNameOnly}} --verify {${fileName}}}
    }

    #
    # NOTE: The command to use when creating OpenPGP signatures for the
    #       downloaded package scripts.  This must be configured according
    #       to the implementation of OpenPGP in use.
    #
    variable openPgpSignCommand; # DEFAULT: gpg2 --detach-sign ...

    if {![info exists openPgpSignCommand]} then {
      set openPgpSignCommand ""

      append openPgpSignCommand \
          {{${openPgpFileNameOnly}} --detach-sign --armor}

      append openPgpSignCommand \
          { --passphrase-file [formatExecArgument [getOpenPgpPassphraseFile]]}

      append openPgpSignCommand { --batch --yes {${fileName}}}
    }
  }

  #
  # NOTE: This procedure sets up the default values for all configuration
  #       parameters used by the package repository client.  There are no
  #       arguments.
  #
  proc setupPackageUnknownVars {} {
    #
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2308
2309
2310
2311
2312
2313
2314






































































































2315
2316
2317
2318
2319
2320
2321







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







          [llength [package versions Garuda]] > 0} then {
        set autoRequireGaruda true
      } else {
        set autoRequireGaruda false
      }
    }

    #
    # NOTE: This is the name of the sub-directory containing the OpenPGP
    #       implementation.  It is platform-specific.  On Windows, this
    #       sub-directory is relative to the "Program Files" directory.
    #
    variable openPgpInstalledDirectory; # DEFAULT: [file join GNU GnuPG]

    if {![info exists openPgpInstalledDirectory]} then {
      if {[isWindows]} then {
        set openPgpInstalledDirectory [file join GNU GnuPG]
      } else {
        set openPgpInstalledDirectory [file join / usr bin]
      }
    }

    #
    # NOTE: This is the name of the executable file used to invoke the
    #       OpenPGP implementation, without an extension.
    #
    variable openPgpInstalledFileName; # DEFAULT: gpg2

    if {![info exists openPgpInstalledFileName]} then {
      if {[isWindows]} then {
        set openPgpInstalledFileName gpg2.exe
      } else {
        set openPgpInstalledFileName gpg2
      }
    }

    #
    # NOTE: The command to use when attempting to import an OpenPGP key
    #       file.  This must be configured according to the implementation
    #       of OpenPGP in use.
    #
    variable openPgpImportCommand; # DEFAULT: gpg2 --import

    if {![info exists openPgpImportCommand]} then {
      set openPgpImportCommand {gpg2 --import {${fileName}}}
    }

    #
    # NOTE: The regular expression pattern used when attempting to verify
    #       that OpenPGP successfully imported one or more keys.  This must
    #       be configured according to the implementation of OpenPGP in use.
    #
    variable openPgpImportPattern; # DEFAULT: ^gpg: Total number processed: 1$

    if {![info exists openPgpImportPattern]} then {
      set openPgpImportPattern {^gpg: Total number processed: 1$}
    }

    #
    # NOTE: The command to use when attempting to verify that OpenPGP is
    #       installed locally.  This must be configured according to the
    #       implementation of OpenPGP in use.
    #
    variable openPgpInstalledCommand; # DEFAULT: gpg2 --version

    if {![info exists openPgpInstalledCommand]} then {
      set openPgpInstalledCommand {gpg2 --version}
    }

    #
    # NOTE: The regular expression pattern used when attempting to verify
    #       that OpenPGP is installed locally.  This must be configured
    #       according to the implementation of OpenPGP in use.
    #
    variable openPgpInstalledPattern; # DEFAULT: ^gpg \(GnuPG\) 2\.[01]\.

    if {![info exists openPgpInstalledPattern]} then {
      set openPgpInstalledPattern {^gpg \(GnuPG\) 2\.[01]\.}
    }

    #
    # NOTE: The command to use when verifying OpenPGP signatures for the
    #       downloaded package scripts.  This must be configured according
    #       to the implementation of OpenPGP in use.
    #
    variable openPgpVerifyCommand; # DEFAULT: gpg2 --verify {${fileName}}

    if {![info exists openPgpVerifyCommand]} then {
      set openPgpVerifyCommand {gpg2 --verify {${fileName}}}
    }

    #
    # NOTE: The command to use when creating OpenPGP signatures for the
    #       downloaded package scripts.  This must be configured according
    #       to the implementation of OpenPGP in use.
    #
    variable openPgpSignCommand; # DEFAULT: gpg2 --detach-sign ...

    if {![info exists openPgpSignCommand]} then {
      set openPgpSignCommand ""

      append openPgpSignCommand {gpg2 --detach-sign --armor}

      append openPgpSignCommand \
          { --passphrase-file [formatExecArgument [getOpenPgpPassphraseFile]]}

      append openPgpSignCommand { --batch --yes {${fileName}}}
    }

    #
    # NOTE: The command to use when creating Harpy signatures for downloaded
    #       package scripts.
    #
    variable harpySignCommand; # DEFAULT: {${shellFileName}} -file ...

    if {![info exists harpySignCommand]} then {
2381
2382
2383
2384
2385
2386
2387






2388
2389
2390
2391
2392
2393
2394
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478







+
+
+
+
+
+







  #
  # NOTE: Setup the server and URI variables, in this namespace, that are
  #       used by this script.
  #
  setupRepositoryServerVars false
  setupRepositoryUriVars false

  #
  # NOTE: Setup the OpenPGP implementation related variables, in this
  #       namespace, that are used by this script.
  #
  setupRepositoryOpenPgpVars

  #
  # NOTE: Setup the variables, within this namespace, used by this script.
  #
  setupPackageUnknownVars

  #
  # NOTE: Setup for our [package unknown] handler, which may involve a few

Modified client/1.0/neutral/pkgr.eagle.asc from [18d0d4d390] to [4fa28513fa].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17













18
1
2
3
4













5
6
7
8
9
10
11
12
13
14
15
16
17
18




-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
Comment: Eagle Package Repository

iQIcBAABCAAGBQJZKOG5AAoJEFAslq9JXcLZq+MQAKJg08ojgZp4y1o7XbEyR1m9
E0Y7/IjBkVcCEUedseeCpsh4Qjs3/w1gnYrRol1YddOnYNsZPYoJr3xvoq1L7800
VToiglUl3FXBqPxDIVyBTvW3gJsfcrTFfzyyKicz+pcmPg89VV8UoX7BFQT9xPSw
7I5e2I3pLDikki+37dd71ISitIbRppjmACPHvrj5mDTtTLukgQkM/6gR+NPf+svc
8pucqdkl93iQjr044mXVi+OxFX7n8y+llW6Cqaa/hEWN6COM9gV/IAMKS+7BtUwW
jVFdzqoCykriDl4EsG7337paDXUW1p5ixD6vCBX6bVrVSkKSzAujmWtttPWAcaF9
ZIqMQCtHRGHQE0FSjgws1OcF1huOueJmNtO/lizorgMqnRjZQh4Nb20R+gaKGiSt
oul+yxLgD3v/Yqs1soicnvzn1mqYLp+0g+j6xsvbzwpbjGpODIMGsNCpP5zPDipr
X6AbX+jjnX7ldGv8LvR+sUzewiOfs7ZT86ofgKhOdXELEYMlgEMMVewieV349Qzc
DTz0UjDPu6cGrub4Y9nmjPV/lzdfuMmthKPiI2xOVUZmPFiLnzN7KDpLZ8MAB/xZ
IO8zk5XYuJMpOatNpZw+ZLQIJJ+2/0lWETjxonRoxVf/ReCA/4+m0wpP6WTByXbX
lM7uzf0fHDoUAMZ4Jpee
=ohqW
iQIcBAABCAAGBQJZjJueAAoJEFAslq9JXcLZYzQQAJyY4yI3Nem7xhhg/Wcs9kGd
IjxvC9MZBLdIkeiq/tvP4s4EtsmlCSZFApUkU3Bmkurdpv/8QKdY56PVPGIkghow
40uQSU1pvVw4t2IbZXvYEuQqBcK3ZSuBfhV2urPOjO4JqP3XnFkLIB/uVjzgzW+q
e+G+52pO77l82TyMYfHNOHYAkPaqFs+Omds9Wzn5GaXE1/BIND403T4AxZulDXPW
ges+BVCzfnyGB0ZMb0mZXzNDJNEisgjDAh1JQl2ox1IzspKaHT9AAT+x/2AKtl4R
nqh7B+P97KJOYzhGR/v/gFg3IHisKI9YIJjw7eE8O+URIrqZ24BXZtl7cEScluas
xlNXRTrb2ANeiTSMgzYe/3L68g4pFUUhWpd/GnaC3CTX1n/AzesKEVTDI74rTOgw
NFFGiY7A6L+zlR87zmhnF1ahUAbONl4eiXYttfRFBbMjJIeqe7zxyGjt1VS9Hhu3
gZzK1YdpFSjNV0ab7Kzm9nSi7N5MBgSGsiS0bTK34YBSd1LwNu54IBPZgl3Q8Bai
rQnGrH929fF/5ziEZDU/a001EIdFGQHA/hcQkMmBNyqeiRXjda5vzClWkVaMj1pU
Cn4dlJCezTAjA+xOapo5BLj+eFdBh1zvAIklouDHvOGblX93ul72hWvEn/3azS88
ZxjLZpQQKNBQf681le3J
=HV3f
-----END PGP SIGNATURE-----

Modified client/1.0/neutral/pkgr.eagle.harpy from [7b081aa93d] to [42c02b7858].

17
18
19
20
21
22
23
24

25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66




































67
68
17
18
19
20
21
22
23

24
25
26

27
28
29
30




































31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68







-
+


-
+



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


    THE ASSOCIATED SOFTWARE MAY NOT WORK PROPERLY IF THIS FILE IS ALTERED.
-->
<Certificate xmlns="https://eagle.to/2011/harpy"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Protocol>None</Protocol>
  <Vendor>Mistachkin Systems</Vendor>
  <Id>7590b736-64b0-4598-925e-924484083f08</Id>
  <Id>602e33df-e6f1-48a0-b7d2-bbb936411905</Id>
  <HashAlgorithm>SHA512</HashAlgorithm>
  <EntityType>Script</EntityType>
  <TimeStamp>2017-05-27T02:17:02.6838102Z</TimeStamp>
  <TimeStamp>2017-08-10T17:44:18.8973494Z</TimeStamp>
  <Duration>-1.00:00:00</Duration>
  <Key>0x9559f6017247e3e2</Key>
  <Signature>
    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
  </Signature>
</Certificate>

Modified client/1.0/neutral/pkgr.eagle.harpy.asc from [664d125131] to [e4989daacc].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17













18
1
2
3
4













5
6
7
8
9
10
11
12
13
14
15
16
17
18




-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
Comment: Eagle Package Repository

iQIcBAABCAAGBQJZKOG8AAoJEFAslq9JXcLZRQUP/jCyOlugDL8PMyH2LUUuPYlQ
Jji4+WENTnJ+5gu/hfZZfSmnbHq8wyLGS8Z7rgOQ0+HQC/Vk8dBRst6MpbgHQJcf
UM4ZDvKHENGZ5/Hni79YLfLVXtROs4p/AEGQ3nmuFbRAQxE9GHT3QKKIl8xd7EkK
MqI4d+SdFM77JUBEPPMFurKJJTiU6M9pVPhSAeVn651vVVJMADm2NBlIhEwAg8Mn
8OVQuUkvrk7Yh4gnf97kMFfO91gYCTWF13S8xbvih2KPVJxEkdSDuzuEdobjjLGO
+SGbD4WwYYt5I2pmnN3h0OaE/KHfupjJuWiDTO1nSn8uTtGlTbfmOLLEgEiP2blt
oeRjqWHYrMazOYWfYLDvccJCK1Ltvws+wwld2TKqypcaPMhEXqDZ+FIPYcPBq/oO
btkv90d9WQ+xDQAwPiZ275G1LulEqk6qgMqHnEzW2NWvcpkiICYed5nyR9XQi3qW
swHelZFV6b1HclgghEAb9SBsRat5Qr4GF3puA7LWsrrjJHw/cyQLEXWISx7gHiWi
u+87Ep6kutAXc9sVbldexIoZKoMMPn1Tg52UO535CtCJK2lciPohGuoJZxsVakYV
EV12pQ9xOioRjWzMzXy6Sykqd7snQr4ujzgh5Lx+0PUnViM7GMK6yfME8UF7HgJT
W6Cn5MwDMUB8ojzuZVjk
=TE7u
iQIcBAABCAAGBQJZjJuiAAoJEFAslq9JXcLZY3sP/1+/muBQf4YBo6l919NyDDKU
yUUF5ko9zA2+tpSp5xf6pnuJG+WIrNfphu4Wh12ce2W3J5huW+dDaJi5Mqbcms/p
hoCUvqSXHopN+VOx4kScNOYyCc1n/3SLvrEy3vgXFBxOxMsn/sPtTuATuBgtlx8J
ukdpbFpGB94IuRL8ga5ewYwMaaLqjA7N6zH8CMbMXv94Byp052yrHyZaIVJDz24F
3AREACq46RXRximD3jASOy6HiPgLdCsYsDg6/94Iv0Ux+1CpwfBjfNelW7HEPoSE
IJadamB4ZuAkmxFNQ2XdrqOLfENMXJQg6YpSnYNHHzyclrGf3nIQ6o08AML+ZxoJ
pUFcazZ5FcuI0Yahv35yofLk/wv6PeBkYbMHyNgy2h1MLtn8FRsnEc1UEKBD6tKd
CZPw9PkmODmJLcPBR+QxzxE+x5o1OzZPwZnEtOwb5IO2xgop1/vrypLiWdeBb14y
sY6xlGf3J4qOCIxd/sdHDnVSWj1JwoJOFe1VZf+XJGUsS2PiYgF4rIa0be6LcYEM
c75YRW/5QVA9k4PSyt8A3L7A1/V+tnLpDBnQhkaWMcYxC6KJZ+eiv/a53axD752q
qfoEFp6h2fIATS8cmpYFjda2yuhDzycQprqWkQIMlFIOPVQYSz2vw9RlBrz0I6Vw
2EUg6EsD5A1XClkG/KJV
=EpTz
-----END PGP SIGNATURE-----