Compare commits

..

No commits in common. "main" and "v1.1.0" have entirely different histories.
main ... v1.1.0

10 changed files with 29 additions and 322 deletions

View file

@ -8,11 +8,11 @@ on:
env:
GITHUB_REF: ${{ github.ref }}
GO_VERSION: '1.24.2'
GO_VERSION: '1.23.1'
jobs:
build-common:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Checkout Main Repo
@ -40,10 +40,8 @@ jobs:
name: CHANGELOG.md
path: ./CHANGELOG.md
###
build-linux-arm64:
runs-on: ubuntu-24.04-arm
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
@ -52,6 +50,12 @@ jobs:
ref: ${{ env.GITHUB_REF }}
fetch-depth: 0
- name: Update apt
run: sudo apt update
- name: Install cross-compiler for linux/arm64
run: sudo apt-get -y install gcc-aarch64-linux-gnu
- name: Set up Go
uses: actions/setup-go@v5
with:
@ -62,6 +66,7 @@ jobs:
env:
GOOS: linux
GOARCH: arm64
CC: aarch64-linux-gnu-gcc
CGO_ENABLED: 0
- name: Save Compiled Binary
@ -85,7 +90,7 @@ jobs:
path: ./apc-p15-install
build-linux-amd64:
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Checkout Backend Repo
uses: actions/checkout@v4
@ -166,93 +171,9 @@ jobs:
name: apc-p15-install-windows-amd64
path: ./apc-p15-install.exe
build-darwin-arm64:
runs-on: macos-15
steps:
- name: Checkout Backend Repo
uses: actions/checkout@v4
with:
repository: gregtwallace/apc-p15-tool
ref: ${{ env.GITHUB_REF }}
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '${{ env.GO_VERSION }}'
- name: Build Tool
run: go build -o ./apc-p15-tool -v ./cmd/tool
env:
GOOS: darwin
GOARCH: arm64
CGO_ENABLED: 0
- name: Save Compiled Binary
uses: actions/upload-artifact@v4
with:
name: apc-p15-tool-darwin-arm64
path: ./apc-p15-tool
- name: Build Install Only
run: go build -o ./apc-p15-install -v ./cmd/install_only
env:
GOOS: darwin
GOARCH: arm64
CGO_ENABLED: 0
- name: Save Compiled Binary
uses: actions/upload-artifact@v4
with:
name: apc-p15-install-darwin-arm64
path: ./apc-p15-install
build-darwin-amd64:
runs-on: macos-13
steps:
- name: Checkout Backend Repo
uses: actions/checkout@v4
with:
repository: gregtwallace/apc-p15-tool
ref: ${{ env.GITHUB_REF }}
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '${{ env.GO_VERSION }}'
- name: Build Tool
run: go build -o ./apc-p15-tool -v ./cmd/tool
env:
GOOS: darwin
GOARCH: amd64
CGO_ENABLED: 0
- name: Save Compiled Binary
uses: actions/upload-artifact@v4
with:
name: apc-p15-tool-darwin-amd64
path: ./apc-p15-tool
- name: Build Install Only
run: go build -o ./apc-p15-install -v ./cmd/install_only
env:
GOOS: darwin
GOARCH: amd64
CGO_ENABLED: 0
- name: Save Compiled Binary
uses: actions/upload-artifact@v4
with:
name: apc-p15-install-darwin-amd64
path: ./apc-p15-install
###
release-file-linux-arm64:
needs: [build-common, build-linux-arm64]
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Make release directory
@ -296,7 +217,7 @@ jobs:
release-file-linux-amd64:
needs: [build-common, build-linux-amd64]
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Make release directory
@ -340,7 +261,7 @@ jobs:
release-file-windows-amd64:
needs: [build-common, build-windows-amd64]
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Make release directory
@ -381,91 +302,3 @@ jobs:
with:
name: apc-p15-tool_windows_amd64
path: ./release
release-file-darwin-arm64:
needs: [build-common, build-darwin-arm64]
runs-on: ubuntu-24.04
steps:
- name: Make release directory
run: mkdir ./release
- name: Download Tool Binary
uses: actions/download-artifact@v4
with:
name: apc-p15-tool-darwin-arm64
path: ./release
- name: Download Install Binary
uses: actions/download-artifact@v4
with:
name: apc-p15-install-darwin-arm64
path: ./release
- name: Download README
uses: actions/download-artifact@v4
with:
name: README.md
path: ./release
- name: Download LICENSE
uses: actions/download-artifact@v4
with:
name: LICENSE.md
path: ./release
- name: Download CHANGELOG
uses: actions/download-artifact@v4
with:
name: CHANGELOG.md
path: ./release
- name: Save Release
uses: actions/upload-artifact@v4
with:
name: apc-p15-tool_darwin_arm64
path: ./release
release-file-darwin-amd64:
needs: [build-common, build-darwin-amd64]
runs-on: ubuntu-24.04
steps:
- name: Make release directory
run: mkdir ./release
- name: Download Tool Binary
uses: actions/download-artifact@v4
with:
name: apc-p15-tool-darwin-amd64
path: ./release
- name: Download Install Binary
uses: actions/download-artifact@v4
with:
name: apc-p15-install-darwin-amd64
path: ./release
- name: Download README
uses: actions/download-artifact@v4
with:
name: README.md
path: ./release
- name: Download LICENSE
uses: actions/download-artifact@v4
with:
name: LICENSE.md
path: ./release
- name: Download CHANGELOG
uses: actions/download-artifact@v4
with:
name: CHANGELOG.md
path: ./release
- name: Save Release
uses: actions/upload-artifact@v4
with:
name: apc-p15-tool_darwin_amd64
path: ./release

View file

@ -1,29 +1,5 @@
# APC P15 Tool Changelog
## [v1.2.2] - 2025-04-22
All dependencies updated.
Add darwin arm64 and amd64 builds.
## [v1.2.1] - 2025-03-17
Fix time check for UPS when it is set to GMT timezone.
All dependencies updated.
## [v1.2.0] - 2025-01-27
Add a new feature to `install` that checks the time of the UPS to confirm
it is accurate. A log message is added that advises either way. Even if
the check fails, the install still proceeds with attempting to install
the new certificate.
Dependencies were also all updated.
## [v1.1.0] - 2024-09-17
> [!IMPORTANT]

View file

@ -67,10 +67,9 @@ NMC3*:
- RSA 1,024, 2,048, 3,072, and 4,092 bit lengths.
- ECDSA curves P-256, P-384, and P-521.
\* 3,072 bit length is not officially supported by my NMC2, but appears to work
* 3,072 bit length is not officially supported by my NMC2, but appears to work
fine.
\* The additional key types supported by NMC3 require newer firmware on the
* The additional key types supported by NMC3 require newer firmware on the
device. I am unsure what the version cutoff is, but you can check support
by connecting to the UPS via SSH and typing `ssl`. If `Command Not Found`
is returned, the firmware is too old and only the key types listed under
@ -171,11 +170,6 @@ separate script.
![Cert Warden with APC P15 Tool](https://raw.githubusercontent.com/gregtwallace/apc-p15-tool/main/img/apc-p15-tool.png)
## Links
@Owl-Tec's write up using this tool with ACDS:
https://owltec.ca/Windows+Server/Deploying+An+Internal+HTTPS+Certificate+for+a+UPS+APC+with+ADCS+(Active+Directory+Certificate+Services)+with+APC+P15+Tool
## Thanks
Special thanks to the following people and resources which helped me

View file

@ -34,25 +34,3 @@ $env:GOARCH = "arm64"
$env:GOOS = "linux"
$env:CGO_ENABLED = 0
go build -o $outDir/apc-p15-install-arm64 ./cmd/install_only
# Darwin (MacOS) amd64
$env:GOARCH = "amd64"
$env:GOOS = "darwin"
$env:CGO_ENABLED = 0
go build -o $outDir/apc-p15-tool-darwin-amd64 ./cmd/tool
$env:GOARCH = "amd64"
$env:GOOS = "darwin"
$env:CGO_ENABLED = 0
go build -o $outDir/apc-p15-install-darwin-amd64 ./cmd/install_only
# Darwin (MacOS) arm64
$env:GOARCH = "arm64"
$env:GOOS = "darwin"
$env:CGO_ENABLED = 0
go build -o $outDir/apc-p15-tool-darwin-arm64 ./cmd/tool
$env:GOARCH = "arm64"
$env:GOOS = "darwin"
$env:CGO_ENABLED = 0
go build -o $outDir/apc-p15-install-darwin-arm64 ./cmd/install_only

8
go.mod
View file

@ -1,14 +1,14 @@
module apc-p15-tool
go 1.24.2
go 1.23.1
require (
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1
golang.org/x/crypto v0.37.0
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
golang.org/x/crypto v0.18.0
)
require golang.org/x/sys v0.32.0 // indirect
require golang.org/x/sys v0.16.0 // indirect
replace apc-p15-tool/cmd/install_only => /cmd/install_only

16
go.sum
View file

@ -2,13 +2,13 @@ github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4 h1:aiqS8aBlF9PsAKeMddMSfbwp3smONCn3UO8QfUg0Z7Y=
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4/go.mod h1:H/13DK46DKXy7EaIxPhk2Y0EC8aubKm35nBjBe8AAGc=
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1 h1:NVK+OqnavpyFmUiKfUMHrpvbCi2VFoWTrcpI7aDaJ2I=
github.com/sigurn/crc16 v0.0.0-20240131213347-83fcde1e29d1/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

Binary file not shown.

Before

(image error) Size: 93 KiB

After

(image error) Size: 102 KiB

Before After
Before After

View file

@ -1,62 +0,0 @@
package apcssh
import (
"fmt"
"regexp"
"strings"
"time"
)
// GetTime sends the APC `system` command and then attempts to parse the
// response to determine the UPS current date/time.
func (cli *Client) GetTime() (time.Time, error) {
result, err := cli.cmd("date")
if err != nil {
return time.Time{}, fmt.Errorf("apcssh: failed to get time (%s)", err)
} else if !strings.EqualFold(result.code, "e000") {
return time.Time{}, fmt.Errorf("apcssh: failed to get time (%s: %s)", result.code, result.codeText)
}
// capture each portion of the date information
regex := regexp.MustCompile(`Date:\s*(\S*)\s*[\r\n]Time:\s*(\S*)\s*[\r\n]Format:\s*(\S*)\s*[\r\n]Time Zone:\s*(\S*)\s*[\r\n]?`)
datePieces := regex.FindStringSubmatch(result.resultText)
if len(datePieces) != 5 {
return time.Time{}, fmt.Errorf("apcssh: failed to get time (length of datetime value pieces was %d (expected: 5))", len(datePieces))
}
dateVal := datePieces[1]
timeVal := datePieces[2]
formatUPSVal := datePieces[3]
timeZoneVal := datePieces[4]
// GMT time requires + prefix
// APC UPS fails to use the required +, so add it
if timeZoneVal == "00:00" {
timeZoneVal = "+" + timeZoneVal
}
// known APC UPS format strings
dateFormatVal := ""
switch formatUPSVal {
case "mm/dd/yyyy":
dateFormatVal = "01/02/2006"
case "dd.mm.yyyy":
dateFormatVal = "02.01.2006"
case "mmm-dd-yy":
dateFormatVal = "Jan-02-06"
case "dd-mmm-yy":
dateFormatVal = "02-Jan-06"
case "yyyy-mm-dd":
dateFormatVal = "2006-01-02"
default:
return time.Time{}, fmt.Errorf("apcssh: failed to get time (ups returned unknown format string (%s)", formatUPSVal)
}
// convert to time.Time
t, err := time.Parse(dateFormatVal+" 15:04:05 -07:00", dateVal+" "+timeVal+" "+timeZoneVal)
if err != nil {
return time.Time{}, fmt.Errorf("apcssh: failed to get time (time parse failed: %s)", err)
}
return t, nil
}

View file

@ -12,7 +12,7 @@ import (
)
const (
appVersion = "1.2.2"
appVersion = "1.1.0"
)
// struct for receivers to use common app pieces

View file

@ -12,8 +12,6 @@ import (
"time"
)
const timeLoggingFormat = time.RFC1123Z
// cmdInstall is the app's command to create apc p15 file content from key and cert
// pem files and upload the p15 to the specified APC UPS
func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
@ -77,16 +75,6 @@ func (app *app) cmdInstall(cmdCtx context.Context, args []string) error {
}
app.stdLogger.Println("install: connected to ups ssh, installing ssl key and cert...")
// check time - don't fail it time is no good, just do logging here
upsT, err := client.GetTime()
if err != nil {
app.errLogger.Printf("warn: install: failed to fetch UPS time (%s), you should manually verify the time is correct on the UPS", err)
} else if upsT.After(time.Now().Add(1*time.Hour)) || upsT.Before(time.Now().Add(-1*time.Hour)) {
app.errLogger.Printf("warn: install: UPS clock skew detected (this system's time is %s vs. UPS time %s", time.Now().Format(timeLoggingFormat), upsT.Format(timeLoggingFormat))
} else {
app.stdLogger.Printf("install: UPS clock appears correct (%s)", upsT.Format(timeLoggingFormat))
}
// install SSL Cert
err = client.InstallSSLCert(keyP15, certPem, keyCertP15)
if err != nil {