diff --git a/docker-compose.patch b/docker-compose.patch index 837ee8d..747ef8c 100644 --- a/docker-compose.patch +++ b/docker-compose.patch @@ -33,7 +33,7 @@ index 5f93fe866..b4a0b75e0 100644 + max-file: "5" + restart: always bmysql: - image: mariadb:10.3 + image: mariadb:10.5 + volumes: + - dbdata:/var/lib/mysql networks: diff --git a/gui/acme.go b/gui/acme.go index b60eda5..b44d4b8 100644 --- a/gui/acme.go +++ b/gui/acme.go @@ -6,6 +6,7 @@ import ( "net" "net/http" "strconv" + "strings" ) // BaseList is the generic base struct for showing lists of data @@ -73,10 +74,11 @@ func GetAccounts(w http.ResponseWriter, r *http.Request) (AccountList, error) { type Order struct { ID int RegistrationID int - Expires string CertSerial string + RequestedName string BeganProc bool Created string + Expires string } // OrderList is a list of Order records @@ -117,7 +119,7 @@ func GetAccount(w http.ResponseWriter, r *http.Request, id int) (AccountShow, er defer db.Close() - rows, err := db.Query("SELECT c.id, c.registrationID, c.serial, CASE WHEN cs.notAfter < NOW() THEN 'expired' ELSE cs.status END AS status, c.issued, c.expires FROM certificates c JOIN certificateStatus cs ON cs.id = c.id WHERE registrationID=?", strconv.Itoa(id)) + rows, err := db.Query("SELECT c.id, c.registrationID, c.serial, n.reversedName, CASE WHEN cs.notAfter < NOW() THEN 'expired' ELSE cs.status END AS status, c.issued, c.expires FROM certificates c JOIN certificateStatus cs ON cs.id = c.id JOIN issuedNames n ON n.serial = c.serial WHERE registrationID=?", strconv.Itoa(id)) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AccountShow{}, err @@ -127,22 +129,23 @@ func GetAccount(w http.ResponseWriter, r *http.Request, id int) (AccountShow, er BaseList: BaseList{ Title: "Certificates", TableClass: "rel_certificates_list", - Header: []template.HTML{"ID", "Account ID", "Serial", "Status", "Issued", "Expires"}, + Header: []template.HTML{"ID", "Account ID", "Serial", "Issued Name", "Status", "Issued", "Expires"}, }, Rows: []Certificate{}, } for rows.Next() { row := Certificate{} - err = rows.Scan(&row.ID, &row.RegistrationID, &row.Serial, &row.Status, &row.Issued, &row.Expires) + err = rows.Scan(&row.ID, &row.RegistrationID, &row.Serial, &row.IssuedName, &row.Status, &row.Issued, &row.Expires) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AccountShow{}, err } + row.IssuedName = ReverseName(row.IssuedName) Certificates.Rows = append(Certificates.Rows, row) } - rows, err = db.Query("SELECT id, registrationID, expires, certificateSerial, beganProcessing, created FROM orders WHERE registrationID=?", strconv.Itoa(id)) + rows, err = db.Query("SELECT o.id, o.registrationID, o.certificateSerial, n.reversedName, o.beganProcessing, o.created, o.expires FROM orders o JOIN requestedNames n ON n.orderID = o.id WHERE o.registrationID=?", strconv.Itoa(id)) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AccountShow{}, err @@ -152,18 +155,19 @@ func GetAccount(w http.ResponseWriter, r *http.Request, id int) (AccountShow, er BaseList: BaseList{ Title: "Orders", TableClass: "rel_orders_list", - Header: []template.HTML{"ID", "Account ID", "Expires", "Certificate Serial", "Began Processing?", "Created"}, + Header: []template.HTML{"ID", "Account ID", "Certificate Serial", "Requested Name", "Began Processing?", "Created", "Expires", }, }, Rows: []Order{}, } for rows.Next() { row := Order{} - err = rows.Scan(&row.ID, &row.RegistrationID, &row.Expires, &row.CertSerial, &row.BeganProc, &row.Created) + err = rows.Scan(&row.ID, &row.RegistrationID, &row.CertSerial, &row.RequestedName, &row.BeganProc, &row.Created, &row.Expires) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AccountShow{}, err } + row.RequestedName = ReverseName(row.RequestedName) Orders.Rows = append(Orders.Rows, row) } @@ -211,7 +215,7 @@ func GetOrders(w http.ResponseWriter, r *http.Request) (OrderList, error) { defer db.Close() - rows, err := db.Query("SELECT id, registrationID, expires, certificateSerial, beganProcessing, created FROM orders") + rows, err := db.Query("SELECT o.id, o.registrationID, o.certificateSerial, n.reversedName, o.beganProcessing, o.created, o.expires FROM orders o JOIN requestedNames n ON n.orderID = o.id") if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return OrderList{}, err @@ -221,18 +225,19 @@ func GetOrders(w http.ResponseWriter, r *http.Request) (OrderList, error) { BaseList: BaseList{ Title: "Orders", TableClass: "orders_list", - Header: []template.HTML{"ID", "Account ID", "Expires", "Certificate Serial", "Began Processing?", "Created"}, + Header: []template.HTML{"ID", "Account ID", "Certificate Serial", "Requested Name", "Began Processing?", "Created", "Expires"}, }, Rows: []Order{}, } for rows.Next() { row := Order{} - err = rows.Scan(&row.ID, &row.RegistrationID, &row.Expires, &row.CertSerial, &row.BeganProc, &row.Created) + err = rows.Scan(&row.ID, &row.RegistrationID, &row.CertSerial, &row.RequestedName, &row.BeganProc, &row.Created, &row.Expires) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return OrderList{}, err } + row.RequestedName = ReverseName(row.RequestedName) Orders.Rows = append(Orders.Rows, row) } @@ -241,12 +246,11 @@ func GetOrders(w http.ResponseWriter, r *http.Request) (OrderList, error) { // Auth contains the data representing an ACME auth type Auth struct { - ID string - Identifier string - RegistrationID int - Status string - Expires string - Combinations string + ID string + Identifier string + RegistrationID int + Status string + Expires string } // AuthList is a list of Auth records @@ -262,6 +266,15 @@ type OrderShow struct { Related2 []BaseList } +// Helper method from sa/model.go +var uintToStatus = map[int]string{ + 0: "pending", + 1: "valid", + 2: "invalid", + 3: "deactivated", + 4: "revoked", +} + // GetOrder returns an order with the given id func GetOrder(w http.ResponseWriter, r *http.Request, id int) (OrderShow, error) { db, err := sql.Open(dbType, dbConn) @@ -272,9 +285,11 @@ func GetOrder(w http.ResponseWriter, r *http.Request, id int) (OrderShow, error) defer db.Close() - partial := "SELECT id, identifier, registrationID, status, expires, combinations FROM " + partial := "SELECT id, identifier, registrationID, status, expires FROM " where := " WHERE id IN (SELECT authzID FROM orderToAuthz WHERE orderID=?)" - rows, err := db.Query(partial+"authz"+where+" UNION "+partial+"pendingAuthorizations"+where, strconv.Itoa(id), strconv.Itoa(id)) + partial2 := "SELECT id, identifierValue, registrationID, status, expires FROM " + where2 := " WHERE id IN (SELECT authzID FROM orderToAuthz2 WHERE orderID=?)" + rows, err := db.Query(partial+"authz"+where+" UNION "+partial+"pendingAuthorizations"+where+" UNION "+partial2+"authz2"+where2, strconv.Itoa(id), strconv.Itoa(id), strconv.Itoa(id)) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return OrderShow{}, err @@ -284,22 +299,25 @@ func GetOrder(w http.ResponseWriter, r *http.Request, id int) (OrderShow, error) BaseList: BaseList{ Title: "Authorizations", TableClass: "rel_authz_list", - Header: []template.HTML{"ID", "Identifier", "Account ID", "Status", "Expires", "Combinations"}, + Header: []template.HTML{"ID", "Identifier", "Account ID", "Status", "Expires"}, }, Rows: []Auth{}, } for rows.Next() { row := Auth{} - err = rows.Scan(&row.ID, &row.Identifier, &row.RegistrationID, &row.Status, &row.Expires, &row.Combinations) + err = rows.Scan(&row.ID, &row.Identifier, &row.RegistrationID, &row.Status, &row.Expires) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return OrderShow{}, err } + if s, err := strconv.Atoi(row.Status); err == nil { + row.Status = uintToStatus[s] + } Authz.Rows = append(Authz.Rows, row) } - rows, err = db.Query("SELECT id, registrationID, expires, certificateSerial, beganProcessing, created FROM orders WHERE id=?", strconv.Itoa(id)) + rows, err = db.Query("SELECT o.id, o.registrationID, o.certificateSerial, n.reversedName, o.beganProcessing, o.created, o.expires FROM orders o JOIN requestedNames n ON n.orderID = o.id WHERE o.id=?", strconv.Itoa(id)) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return OrderShow{}, err @@ -317,21 +335,22 @@ func GetOrder(w http.ResponseWriter, r *http.Request, id int) (OrderShow, error) for rows.Next() { row := Order{} - err = rows.Scan(&row.ID, &row.RegistrationID, &row.Expires, &row.CertSerial, &row.BeganProc, &row.Created) + err = rows.Scan(&row.ID, &row.RegistrationID, &row.CertSerial, &row.RequestedName, &row.BeganProc, &row.Created, &row.Expires) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return OrderShow{}, err } OrderDetails.Rows = append(OrderDetails.Rows, NameValue{"ID", strconv.Itoa(row.ID)}) - OrderDetails.Rows = append(OrderDetails.Rows, NameValue{"Expires", row.Expires}) v := "false" if row.BeganProc { v = "true" } OrderDetails.Rows = append(OrderDetails.Rows, NameValue{"Began Processing?", v}) OrderDetails.Rows = append(OrderDetails.Rows, NameValue{"Created", row.Created}) + OrderDetails.Rows = append(OrderDetails.Rows, NameValue{"Expires", row.Expires}) OrderDetails.Links = append(OrderDetails.Links, NameValHTML{"Certificate", template.HTML("" + row.CertSerial + "")}) + OrderDetails.Rows = append(OrderDetails.Rows, NameValue{"Requested Name", ReverseName(row.RequestedName)}) OrderDetails.Links = append(OrderDetails.Links, NameValHTML{"Account", template.HTML("" + strconv.Itoa(row.RegistrationID) + "")}) } @@ -348,7 +367,7 @@ func GetAuthz(w http.ResponseWriter, r *http.Request) (AuthList, error) { defer db.Close() - rows, err := db.Query("SELECT id, identifier, registrationID, status, expires, combinations FROM authz UNION SELECT id, identifier, registrationID, status, expires, combinations FROM pendingAuthorizations") + rows, err := db.Query("SELECT id, identifier, registrationID, status, expires FROM authz UNION SELECT id, identifier, registrationID, status, expires FROM pendingAuthorizations UNION SELECT id, identifierValue, registrationID, status, expires FROM authz2") if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AuthList{}, err @@ -358,18 +377,21 @@ func GetAuthz(w http.ResponseWriter, r *http.Request) (AuthList, error) { BaseList: BaseList{ Title: "Authorizations", TableClass: "authz_list", - Header: []template.HTML{"ID", "Identifier", "Account ID", "Status", "Expires", "Combinations"}, + Header: []template.HTML{"ID", "Identifier", "Account ID", "Status", "Expires"}, }, Rows: []Auth{}, } for rows.Next() { row := Auth{} - err = rows.Scan(&row.ID, &row.Identifier, &row.RegistrationID, &row.Status, &row.Expires, &row.Combinations) + err = rows.Scan(&row.ID, &row.Identifier, &row.RegistrationID, &row.Status, &row.Expires) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AuthList{}, err } + if s, err := strconv.Atoi(row.Status); err == nil { + row.Status = uintToStatus[s] + } Authz.Rows = append(Authz.Rows, row) } @@ -441,9 +463,11 @@ func GetAuth(w http.ResponseWriter, r *http.Request, id string) (AuthShow, error Challenges.Rows = append(Challenges.Rows, row) } - partial := "SELECT id, identifier, registrationID, status, expires, combinations FROM " + partial := "SELECT id, identifier, registrationID, status, expires, '', '' FROM " where := " WHERE id IN (SELECT authzID FROM orderToAuthz WHERE id=?)" - rows, err = db.Query(partial+"authz"+where+" UNION "+partial+"pendingAuthorizations"+where, id, id) + partial2 := "SELECT id, identifierValue, registrationID, status, expires, validationError, validationRecord FROM " + where2 := " WHERE id IN (SELECT authzID FROM orderToAuthz2 WHERE id=?)" + rows, err = db.Query(partial+"authz"+where+" UNION "+partial+"pendingAuthorizations"+where+" UNION "+partial2+"authz2"+where2, id, id, id) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AuthShow{}, err @@ -461,16 +485,26 @@ func GetAuth(w http.ResponseWriter, r *http.Request, id string) (AuthShow, error for rows.Next() { row := Auth{} - err = rows.Scan(&row.ID, &row.Identifier, &row.RegistrationID, &row.Status, &row.Expires, &row.Combinations) + validationError := sql.NullString{} + validationRecord := sql.NullString{} + err = rows.Scan(&row.ID, &row.Identifier, &row.RegistrationID, &row.Status, &row.Expires, &validationError, &validationRecord) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return AuthShow{}, err } AuthDetails.Rows = append(AuthDetails.Rows, NameValue{"ID", row.ID}) AuthDetails.Rows = append(AuthDetails.Rows, NameValue{"Identifier", row.Identifier}) + if s, err := strconv.Atoi(row.Status); err == nil { + row.Status = uintToStatus[s] + } AuthDetails.Rows = append(AuthDetails.Rows, NameValue{"Status", row.Status}) AuthDetails.Rows = append(AuthDetails.Rows, NameValue{"Expires", row.Expires}) - AuthDetails.Rows = append(AuthDetails.Rows, NameValue{"Combinations", row.Combinations}) + if validationError.Valid && validationError.String != "" { + AuthDetails.Rows = append(AuthDetails.Rows, NameValue{"Validation Error", validationError.String}) + } + if validationRecord.Valid && validationRecord.String != "" { + AuthDetails.Rows = append(AuthDetails.Rows, NameValue{"Validation Record", validationRecord.String}) + } Link := NameValHTML{"Account", template.HTML("" + strconv.Itoa(row.RegistrationID) + "")} AuthDetails.Links = append(AuthDetails.Links, Link) @@ -576,6 +610,7 @@ type Certificate struct { ID int RegistrationID int Serial string + IssuedName string Status string Issued string Expires string @@ -587,6 +622,15 @@ type CertificateList struct { Rows []Certificate } +// domains are stored in reverse order... +func ReverseName(domain string) string { + labels := strings.Split(domain, ".") + for i, j := 0, len(labels)-1; i < j; i, j = i+1, j-1 { + labels[i], labels[j] = labels[j], labels[i] + } + return strings.Join(labels, ".") +} + // GetCertificates returns the list of certificates func GetCertificates(w http.ResponseWriter, r *http.Request) (CertificateList, error) { db, err := sql.Open(dbType, dbConn) @@ -606,7 +650,7 @@ func GetCertificates(w http.ResponseWriter, r *http.Request) (CertificateList, e where = " WHERE cs.revokedDate<>'0000-00-00 00:00:00'" } - rows, err := db.Query("SELECT c.id, c.registrationID, c.serial, CASE WHEN cs.notAfter < NOW() THEN 'expired' ELSE cs.status END AS status, c.issued, c.expires FROM certificates c JOIN certificateStatus cs ON cs.id = c.id" + where) + rows, err := db.Query("SELECT c.id, c.registrationID, c.serial, n.reversedName, CASE WHEN cs.notAfter < NOW() THEN 'expired' ELSE cs.status END AS status, c.issued, c.expires FROM certificates c JOIN certificateStatus cs ON cs.id = c.id JOIN issuedNames n ON n.serial = c.serial" + where) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return CertificateList{}, err @@ -616,18 +660,19 @@ func GetCertificates(w http.ResponseWriter, r *http.Request) (CertificateList, e BaseList: BaseList{ Title: "Certificates", TableClass: "certificates_list", - Header: []template.HTML{"ID", "Account ID", "Serial", "Status", "Issued", "Expires"}, + Header: []template.HTML{"ID", "Account ID", "Serial", "Issued Name", "Status", "Issued", "Expires"}, }, Rows: []Certificate{}, } for rows.Next() { row := Certificate{} - err = rows.Scan(&row.ID, &row.RegistrationID, &row.Serial, &row.Status, &row.Issued, &row.Expires) + err = rows.Scan(&row.ID, &row.RegistrationID, &row.Serial, &row.IssuedName, &row.Status, &row.Issued, &row.Expires) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return CertificateList{}, err } + row.IssuedName = ReverseName(row.IssuedName) Certificates.Rows = append(Certificates.Rows, row) } @@ -646,6 +691,7 @@ type CertificateExtra struct { ID int RegistrationID int Serial string + IssuedName string Digest string Issued string Expires string @@ -700,7 +746,7 @@ func GetCertificate(w http.ResponseWriter, r *http.Request, id int, serial strin defer db.Close() var rows *sql.Rows - selectWhere := "SELECT c.id, c.registrationID, c.serial, c.digest, c.issued, c.expires, cs.subscriberApproved, CASE WHEN cs.notAfter < NOW() THEN 'expired' ELSE cs.status END AS status, cs.ocspLastUpdated, cs.revokedDate, cs.revokedReason, cs.lastExpirationNagSent, cs.notAfter, cs.isExpired FROM certificates c JOIN certificateStatus cs ON cs.id = c.id WHERE " + selectWhere := "SELECT c.id, c.registrationID, c.serial, n.reversedName, c.digest, c.issued, c.expires, cs.subscriberApproved, CASE WHEN cs.notAfter < NOW() THEN 'expired' ELSE cs.status END AS status, cs.ocspLastUpdated, cs.revokedDate, cs.revokedReason, cs.lastExpirationNagSent, cs.notAfter, cs.isExpired FROM certificates c JOIN certificateStatus cs ON cs.id = c.id JOIN issuedNames n ON n.serial = c.serial WHERE " if serial != "" { rows, err = db.Query(selectWhere+"c.serial=?", serial) @@ -723,13 +769,14 @@ func GetCertificate(w http.ResponseWriter, r *http.Request, id int, serial strin for rows.Next() { row := CertificateExtra{} - err = rows.Scan(&row.ID, &row.RegistrationID, &row.Serial, &row.Digest, &row.Issued, &row.Expires, &row.SubscriberApproved, &row.Status, &row.OCSPLastUpdate, &row.Revoked, &row.RevokedReason, &row.LastNagSent, &row.NotAfter, &row.IsExpired) + err = rows.Scan(&row.ID, &row.RegistrationID, &row.Serial, &row.IssuedName, &row.Digest, &row.Issued, &row.Expires, &row.SubscriberApproved, &row.Status, &row.OCSPLastUpdate, &row.Revoked, &row.RevokedReason, &row.LastNagSent, &row.NotAfter, &row.IsExpired) if err != nil { errorHandler(w, r, err, http.StatusInternalServerError) return CertificateShow{}, err } CertificateDetails.Rows = append(CertificateDetails.Rows, NameValue{"ID", strconv.Itoa(row.ID)}) CertificateDetails.Rows = append(CertificateDetails.Rows, NameValue{"Serial", row.Serial}) + CertificateDetails.Rows = append(CertificateDetails.Rows, NameValue{"Issued Name", ReverseName(row.IssuedName)}) CertificateDetails.Rows = append(CertificateDetails.Rows, NameValue{"Digest", row.Digest}) CertificateDetails.Rows = append(CertificateDetails.Rows, NameValue{"Issued", row.Issued}) CertificateDetails.Rows = append(CertificateDetails.Rows, NameValue{"Expires", row.Expires}) diff --git a/gui/apply-boulder b/gui/apply-boulder index 97bfeee..00f8473 100755 --- a/gui/apply-boulder +++ b/gui/apply-boulder @@ -27,6 +27,9 @@ fi if [ "$PKI_DOMAIN_MODE" == "lockdown" ] || [ "$PKI_DOMAIN_MODE" == "whitelist" ]; then sed -i -e "s/^\(.*\)\(\"n_subject_common_name_included\"\)/\1\2,\n\1\"e_dnsname_not_valid_tld\"/" config/ca-a.json sed -i -e "s/^\(.*\)\(\"n_subject_common_name_included\"\)/\1\2,\n\1\"e_dnsname_not_valid_tld\"/" config/ca-b.json + + sed -i -e "s/\( registrationOverrides:\)/ $PKI_LOCKDOWN_DOMAINS: 10000\n\1/" rate-limit-policies.yml + echo " $PKI_LOCKDOWN_DOMAINS: 10000" >> rate-limit-policies.yml fi if [ "$PKI_EXTENDED_TIMEOUT" == "1" ]; then @@ -85,4 +88,4 @@ cp -p $PKI_ROOT_CERT_BASE.pem test-root.pem openssl rsa -in $PKI_ROOT_CERT_BASE.key -pubout > test-root.pubkey.pem openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in test-root.key -out test-root.p8 -chown -R `ls -l rate-limit-policies.yml | cut -d" " -f 3,4 | sed 's/ /:/g'` . +chown -R `ls -l PKI.md | cut -d" " -f 3,4 | sed 's/ /:/g'` . diff --git a/gui/main.go b/gui/main.go index f6b1d9f..41da3db 100644 --- a/gui/main.go +++ b/gui/main.go @@ -2255,7 +2255,7 @@ func activeNav(active string, uri string, requestBase string) []navItem { Name: "Public Area", Icon: "fa-home", Attrs: map[template.HTMLAttr]string{ - "href": "/", + "href": "http://" + viper.GetString("labca.fqdn"), "title": "The non-Admin pages of this LabCA instance", }, } diff --git a/gui/templates/views/about.tmpl b/gui/templates/views/about.tmpl index 394b8c0..758be9d 100644 --- a/gui/templates/views/about.tmpl +++ b/gui/templates/views/about.tmpl @@ -17,7 +17,7 @@

Also if you are developing your own client application or integrating one into your own application, a local test ACME can be very handy. There is a lot of information on the internet about setting up your own PKI (Public Key Infrastructure) but those are usually not automated.

-

Getting Boulder up and running has quite a learning curve though and that is where LabCA comes in. It is a self-contained installation with a nice web GUI built on top of Boulder so you can quickly start using it. All regular management tasks can be done from the web interface. It is best installed in a Virtual Machine and uses Debian Linux as a base.

+

Getting Boulder up and running has quite a learning curve though and that is where LabCA comes in. It is a self-contained installation with a nice web GUI built on top of Boulder so you can quickly start using it. All regular management tasks can be done from the web interface. It is best installed in a Virtual Machine and uses Debian Linux as a base.

NOTE: although LabCA tries to be as robust as possible, use it at your own risk. If you depend on it, make sure that you know what you are doing!

{{ end }} diff --git a/install b/install index c683818..0f796bf 100755 --- a/install +++ b/install @@ -1,7 +1,7 @@ #!/usr/bin/env bash # LabCA: a private Certificate Authority for internal lab usage -# (c) 2018 Arjan Hakkesteegt +# (c) 2018-2020 Arjan Hakkesteegt # # Install with this command from a Linux machine (only tested with Debian 9): # curl -sSL https://raw.githubusercontent.com/hakwerk/labca/master/install | bash @@ -24,7 +24,7 @@ dockerComposeVersion="1.22.0" labcaUrl="https://github.com/hakwerk/labca/" boulderUrl="https://github.com/letsencrypt/boulder/" -boulderTag="release-2020-09-09" +boulderTag="release-2020-10-13" # # Color configuration diff --git a/mail_mailer.patch b/mail_mailer.patch index 33fcb4c..084fc48 100644 --- a/mail_mailer.patch +++ b/mail_mailer.patch @@ -1,5 +1,5 @@ diff --git a/mail/mailer.go b/mail/mailer.go -index de6b1de20..60c58128b 100644 +index bb5bacaf2..946992dca 100644 --- a/mail/mailer.go +++ b/mail/mailer.go @@ -20,10 +20,14 @@ import ( @@ -17,7 +17,7 @@ index de6b1de20..60c58128b 100644 ) type idGenerator interface { -@@ -119,6 +123,7 @@ func New( +@@ -121,6 +125,7 @@ func New( username, password string, rootCAs *x509.CertPool, @@ -25,7 +25,7 @@ index de6b1de20..60c58128b 100644 from mail.Address, logger blog.Logger, stats prometheus.Registerer, -@@ -138,6 +143,7 @@ func New( +@@ -140,6 +145,7 @@ func New( server: server, port: port, rootCAs: rootCAs, @@ -33,7 +33,7 @@ index de6b1de20..60c58128b 100644 }, log: logger, from: from, -@@ -178,7 +184,7 @@ func (m *MailerImpl) generateMessage(to []string, subject, body string) ([]byte, +@@ -180,7 +186,7 @@ func (m *MailerImpl) generateMessage(to []string, subject, body string) ([]byte, fmt.Sprintf("To: %s", strings.Join(addrs, ", ")), fmt.Sprintf("From: %s", m.from.String()), fmt.Sprintf("Subject: %s", subject), @@ -42,7 +42,7 @@ index de6b1de20..60c58128b 100644 fmt.Sprintf("Message-Id: <%s.%s.%s>", now.Format("20060102T150405"), mid.String(), m.from.Address), "MIME-Version: 1.0", "Content-Type: text/plain; charset=UTF-8", -@@ -235,23 +241,32 @@ func (m *MailerImpl) Connect() error { +@@ -237,23 +243,32 @@ func (m *MailerImpl) Connect() error { type dialerImpl struct { username, password, server, port string rootCAs *x509.CertPool diff --git a/nginx.conf b/nginx.conf index 6cf37f4..7408689 100644 --- a/nginx.conf +++ b/nginx.conf @@ -23,6 +23,10 @@ server { proxy_pass http://127.0.0.1:4002/; } + location /rate-limits { + try_files $uri $uri.html $uri/ =404; + } + location /terms/ { try_files $uri $uri.html $uri/ =404; } @@ -77,6 +81,10 @@ server { proxy_pass http://127.0.0.1:4002/; } + location /rate-limits { + try_files $uri $uri.html $uri/ =404; + } + location /terms/ { try_files $uri $uri.html $uri/ =404; } diff --git a/notify-mailer_main.patch b/notify-mailer_main.patch index 7576a1e..7249fc0 100644 --- a/notify-mailer_main.patch +++ b/notify-mailer_main.patch @@ -1,8 +1,8 @@ diff --git a/cmd/notify-mailer/main.go b/cmd/notify-mailer/main.go -index 0445a04c0..ba2be9e2f 100644 +index e00541cb1..39af62530 100644 --- a/cmd/notify-mailer/main.go +++ b/cmd/notify-mailer/main.go -@@ -37,6 +37,7 @@ type mailer struct { +@@ -38,6 +38,7 @@ type mailer struct { destinations []recipient targetRange interval sleepInterval time.Duration @@ -10,7 +10,7 @@ index 0445a04c0..ba2be9e2f 100644 } // interval defines a range of email addresses to send to, alphabetically. -@@ -146,7 +147,7 @@ func (m *mailer) run() error { +@@ -147,7 +148,7 @@ func (m *mailer) run() error { m.log.Debugf("skipping %q: out of target range") continue } diff --git a/ra_ra.patch b/ra_ra.patch index 7296023..77cdc37 100644 --- a/ra_ra.patch +++ b/ra_ra.patch @@ -1,16 +1,16 @@ diff --git a/ra/ra.go b/ra/ra.go -index a92965189..aeccb9c3c 100644 +index ca21ace0e..6d90d7eff 100644 --- a/ra/ra.go +++ b/ra/ra.go -@@ -28,7 +28,6 @@ import ( - "github.com/letsencrypt/boulder/identifier" +@@ -29,7 +29,6 @@ import ( + "github.com/letsencrypt/boulder/issuance" blog "github.com/letsencrypt/boulder/log" "github.com/letsencrypt/boulder/metrics" - "github.com/letsencrypt/boulder/policy" "github.com/letsencrypt/boulder/probs" rapb "github.com/letsencrypt/boulder/ra/proto" "github.com/letsencrypt/boulder/ratelimit" -@@ -399,7 +398,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(ctx context.Context, conta +@@ -400,7 +399,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(ctx context.Context, conta contact, ) } diff --git a/test_config_ca_a.patch b/test_config_ca_a.patch index 1b316d6..0387bc2 100644 --- a/test_config_ca_a.patch +++ b/test_config_ca_a.patch @@ -4,14 +4,14 @@ index be064a52e..e7ef8fcf6 100644 +++ b/test/config/ca-a.json @@ -30,11 +30,7 @@ }, - "Issuers": [{ - "ConfigFile": "test/test-ca.key-pkcs11.json", -- "CertFile": "/tmp/intermediate-cert-rsa-a.pem", -- "NumSessions": 2 + "issuers": [{ + "configFile": "test/test-ca.key-pkcs11.json", +- "certFile": "/tmp/intermediate-cert-rsa-a.pem", +- "numSessions": 2 - },{ -- "ConfigFile": "test/test-ca.key-pkcs11.json", -- "CertFile": "/tmp/intermediate-cert-rsa-b.pem", -+ "CertFile": "test/test-ca.pem", - "NumSessions": 2 +- "configFile": "test/test-ca.key-pkcs11.json", +- "certFile": "/tmp/intermediate-cert-rsa-b.pem", ++ "certFile": "test/test-ca.pem", + "numSessions": 2 }], "expiry": "2160h", diff --git a/test_config_ca_b.patch b/test_config_ca_b.patch index 04eeaeb..86463a0 100644 --- a/test_config_ca_b.patch +++ b/test_config_ca_b.patch @@ -4,14 +4,14 @@ index ed2498f1a..4d24ffa94 100644 +++ b/test/config/ca-b.json @@ -30,11 +30,7 @@ }, - "Issuers": [{ - "ConfigFile": "test/test-ca.key-pkcs11.json", -- "CertFile": "/tmp/intermediate-cert-rsa-a.pem", -- "NumSessions": 2 + "issuers": [{ + "configFile": "test/test-ca.key-pkcs11.json", +- "certFile": "/tmp/intermediate-cert-rsa-a.pem", +- "numSessions": 2 - },{ -- "ConfigFile": "test/test-ca.key-pkcs11.json", -- "CertFile": "/tmp/intermediate-cert-rsa-b.pem", -+ "CertFile": "test/test-ca.pem", - "NumSessions": 2 +- "configFile": "test/test-ca.key-pkcs11.json", +- "certFile": "/tmp/intermediate-cert-rsa-b.pem", ++ "certFile": "test/test-ca.pem", + "numSessions": 2 }], "expiry": "2160h", diff --git a/www/502.html b/www/502.html index a8af721..2c3e5ff 100644 --- a/www/502.html +++ b/www/502.html @@ -118,7 +118,7 @@ diff --git a/www/css/labca.css b/www/css/labca.css index 2daeb87..0f12baa 100644 --- a/www/css/labca.css +++ b/www/css/labca.css @@ -151,3 +151,10 @@ a.update:hover { .rel-notes-title { font-weight: bold; } + +pre.json { + background-color: transparent; + border: none; + margin: 0px; + padding: 0px; +} diff --git a/www/js/dataTables.bootstrap.min.js b/www/js/dataTables.bootstrap.min.js index c27dcb5..781eb7b 100644 --- a/www/js/dataTables.bootstrap.min.js +++ b/www/js/dataTables.bootstrap.min.js @@ -1,4 +1,14 @@ -/*! DataTables Bootstrap 3 integration - * ©2011-2015 SpryMedia Ltd - datatables.net/license - */ -(function(a){if(typeof define==="function"&&define.amd){define(["jquery","datatables.net"],function(b){return a(b,window,document)})}else{if(typeof exports==="object"){module.exports=function(b,c){if(!b){b=window}if(!c||!c.fn.dataTable){c=require("datatables.net")(b,c).$}return a(c,b,b.document)}}else{a(jQuery,window,document)}}}(function(d,b,a,e){var c=d.fn.dataTable;d.extend(true,c.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});d.extend(c.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});c.ext.renderer.pageButton.bootstrap=function(l,u,t,r,q,j){var o=new c.Api(l);var m=l.oClasses;var i=l.oLanguage.oPaginate;var s=l.oLanguage.oAria.paginate||{};var h,g,f=0;var n=function(w,A){var y,v,z,x;var B=function(C){C.preventDefault();if(!d(C.currentTarget).hasClass("disabled")&&o.page()!=C.data.action){o.page(C.data.action).draw("page")}};for(y=0,v=A.length;y0?"":" disabled");break;case"previous":h=i.sPrevious;g=x+(q>0?"":" disabled");break;case"next":h=i.sNext;g=x+(q",{"class":m.sPageButton+" "+g,id:t===0&&typeof x==="string"?l.sTableId+"_"+x:null}).append(d("",{href:"#","aria-controls":l.sTableId,"aria-label":s[x],"data-dt-idx":f,tabindex:l.iTabIndex}).html(h)).appendTo(w);l.oApi._fnBindAction(z,{action:x},B);f++}}}};var k;try{k=d(u).find(a.activeElement).data("dt-idx")}catch(p){}n(d(u).empty().html('