case 4724 - SMTP certificate checked, password never returned

Mailer checks the SMTP server's certificate (trust and name; no revocation
check). New config setting AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE accepts any
certificate (boot warning, shown in server info, manual page).
The notification settings GET returns ******** instead of the SMTP
password; a PUT with ******** or empty keeps the stored password.
F30 and F31 fixed. Changelog and manual updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 19:09:02 -07:00
parent 94a6f3b653
commit 4141217c04
13 changed files with 98 additions and 7 deletions

View File

@@ -190,7 +190,7 @@ John's "next release" cases for AyaNova (exported 2026-10-24). Each is its own s
| 4721 | Client escaping of record text | F33. **Done** (raven-client: `escapeHtml` helper for the warranty summary; address dialog as text; search excerpt escaped with the terms highlighted as plain text; dialog messages through DOMPurify. The excerpt is not encoded on the server as well: the client escaping covers it. John checked search, warranty info with `<b>` in a vendor name, the address dialog and confirmation dialogs) | | 4721 | Client escaping of record text | F33. **Done** (raven-client: `escapeHtml` helper for the warranty summary; address dialog as text; search excerpt escaped with the terms highlighted as plain text; dialog messages through DOMPurify. The excerpt is not encoded on the server as well: the client escaping covers it. John checked search, warranty info with `<b>` in a vendor name, the address dialog and confirmation dialogs) |
| 4722 | DOMPurify and Vuetify upgrades (raven-client) | F34. **Done** (raven-client `44411ec1`: DOMPurify 2.5.9, Vuetify 2.7.2, builds on Node 12.22.9; Vuetify 2.7's calendar `eventSummary()` returns an element, so the six calendar event templates render it with a new `gz-vnodes` component instead of `v-html`. John checked wiki, schedules (drag, stretch, lock icons), date pickers, lists, dialogs and the reminder and review widgets. John also checked the scheduled work order widget as a Tech user. Still to do: Cypress on `devtestn10` at the final gate) | | 4722 | DOMPurify and Vuetify upgrades (raven-client) | F34. **Done** (raven-client `44411ec1`: DOMPurify 2.5.9, Vuetify 2.7.2, builds on Node 12.22.9; Vuetify 2.7's calendar `eventSummary()` returns an element, so the six calendar event templates render it with a new `gz-vnodes` component instead of `v-html`. John checked wiki, schedules (drag, stretch, lock icons), date pickers, lists, dialogs and the reminder and review widgets. John also checked the scheduled work order widget as a Tech user. Still to do: Cypress on `devtestn10` at the final gate) |
| 4723 | Direct SMTP and direct notification: staff only, record rights | F3, F4. **Done**, plan revised with John: staff keep sending to any address (stock report template and a customer script use it); contacts refused in both actions, an address from a record needs read rights on it, direct notifications refused to subcontractors. Test `DirectSend` (the subcontractor case returned 204 on the old code). No changelog line: nothing that works changes | | 4723 | Direct SMTP and direct notification: staff only, record rights | F3, F4. **Done**, plan revised with John: staff keep sending to any address (stock report template and a customer script use it); contacts refused in both actions, an address from a record needs read rights on it, direct notifications refused to subcontractors. Test `DirectSend` (the subcontractor case returned 204 on the old code). No changelog line: nothing that works changes |
| 4724 | SMTP: certificate checked, password never returned | F30, F31 | | 4724 | SMTP: certificate checked, password never returned | F30, F31. **Done** (certificate checked, opt-out config setting `AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE` with manual page; password masked as `********` and kept on save; test `SmtpPasswordHidden`; self-signed listener proof; changelog lines for both) |
| 4725 | Sessions: password change ends sessions, exact-path token exemption, default SuperUser refused when licensed | F7, F8, F9 | | 4725 | Sessions: password change ends sessions, exact-path token exemption, default SuperUser refused when licensed | F7, F8, F9 |
| 4726 | Login throttling/lockout | F6 | | 4726 | Login throttling/lockout | F6 |
| 4727 | Low severity hardening | F10, F11, F12, F22, F23, F25, F29, F35, F36, F38; the AyaNova half of F39 (DB ID not shown anonymously) | | 4727 | Low severity hardening | F10, F11, F12, F22, F23, F25, F29, F35, F36, F38; the AyaNova half of F39 (DB ID not shown anonymously) |
@@ -250,6 +250,8 @@ FastMail password after the old Sockeye server is retired), John's cases.
Found during the port, out of scope. One line each. Found during the port, out of scope. One line each.
- `NotifyController.SendNotifySmtpDirectMessage`, User branch: the missing-address and inactive messages say "Vendor" instead of "User" (found in case 4723) - `NotifyController.SendNotifySmtpDirectMessage`, User branch: the missing-address and inactive messages say "Vendor" instead of "User" (found in case 4723)
- SMTP connection security mapping (`Mailer.cs`): "StartTls" connects with `useSsl: true`, which MailKit treats as TLS from the start (port 465), not STARTTLS (587); "None" uses STARTTLS when offered, which can be stripped. Correcting it could break customers using "StartTls" on port 465 (found in case 4724)
- Race in the notification system: a record saved while a matching notification subscription is being deleted fails with 500 (`anotifyevent_notifysubscriptionid_fkey` violation), and the user's save fails with it. Seen once in the integration suite (`CustomerCrud.CRUD`, run in parallel with subscription tests) during case 4724
- **Case 4731 (John, priority 1, after 8.3.0):** a global notification setting "allow email to any address from the API and report scripts" for `notify/direct-smtp`; off for new installs, on for upgraded databases; when off, only a record's saved address. Follows from F3 / case 4723 - **Case 4731 (John, priority 1, after 8.3.0):** a global notification setting "allow email to any address from the API and report scripts" for `notify/direct-smtp`; off for new installs, on for upgraded databases; when off, only a record's saved address. Follows from F3 / case 4723
- `License.DoFetchAsync` (`License.cs:629-661`) rethrows at `x == 3`, so the fifth server (Sockeye) is never tried, and it can return `null` to a caller that dereferences it - `License.DoFetchAsync` (`License.cs:629-661`) rethrows at `x == 3`, so the fifth server (Sockeye) is never tried, and it can return `null` to a caller that dereferences it
- Stray `raven-client\ayanova\cypress.json`: the Cypress suite lives in `raven-test\e2e` - Stray `raven-client\ayanova\cypress.json`: the Cypress suite lives in `raven-test\e2e`

View File

@@ -210,8 +210,8 @@ take the next free number; a fixed or accepted finding keeps its ID and changes
| F3 | High | **fixed in cases 4712 and 4723** (staff sending to any address kept, by design) | Any logged-in user, customer contacts included, can send arbitrary email through the company's SMTP server | | F3 | High | **fixed in cases 4712 and 4723** (staff sending to any address kept, by design) | Any logged-in user, customer contacts included, can send arbitrary email through the company's SMTP server |
| F23 | Medium | confirmed (code) | Logo upload accepts any content type and the anonymous logo route serves it inline from the app's origin (stored XSS) | | F23 | Medium | confirmed (code) | Logo upload accepts any content type and the anonymous logo route serves it inline from the app's origin (stored XSS) |
| F24 | Medium | **fixed in case 4718** | Translation import has no role check: any login can add translations | | F24 | Medium | **fixed in case 4718** | Translation import has no role check: any login can add translations |
| F30 | Medium | confirmed (code) | SMTP: the mail server's TLS certificate is never checked | | F30 | Medium | **fixed in case 4724** | SMTP: the mail server's TLS certificate is never checked |
| F31 | Medium | confirmed (code) | The SMTP password is returned to read-only roles (OpsAdminRestricted, BizAdmin, BizAdminRestricted) | | F31 | Medium | **fixed in case 4724** | The SMTP password is returned to read-only roles (OpsAdminRestricted, BizAdmin, BizAdminRestricted) |
| F32 | Medium | confirmed (code) | A real-looking SMTP account and password are in the DEBUG defaults in `raven` and `sockeye` source | | F32 | Medium | confirmed (code) | A real-looking SMTP account and password are in the DEBUG defaults in `raven` and `sockeye` source |
| F34 | Medium | **fixed in case 4722** | Shipped client libraries behind on security fixes: DOMPurify 2.3.8 (wiki sanitiser), Vuetify 2.6.6 | | F34 | Medium | **fixed in case 4722** | Shipped client libraries behind on security fixes: DOMPurify 2.3.8 (wiki sanitiser), Vuetify 2.6.6 |
| F6 | Medium | confirmed | No lockout or rate limit on login or the 2FA step; no password rules | | F6 | Medium | confirmed | No lockout or rate limit on login or the 2FA step; no password rules |
@@ -647,7 +647,7 @@ so any certificate is accepted. Anyone who can intercept the connection (a hosti
DNS) can pose as the mail server and collect the SMTP account and password and every message. DNS) can pose as the mail server and collect the SMTP account and password and every message.
Also, with security set to none, MailKit's `ConnectAsync(host, port, false)` uses STARTTLS only Also, with security set to none, MailKit's `ConnectAsync(host, port, false)` uses STARTTLS only
if offered, which an attacker can suppress. Fix: remove the callback (validate normally); if a if offered, which an attacker can suppress. Fix: remove the callback (validate normally); if a
customer needs a self-signed mail server, make that an explicit setting. customer needs a self-signed mail server, make that an explicit setting. **Fixed in case 4724 (2026-10-24):** the callback is set only when the new config setting `AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE` is true (boot warning when it is; shown in server info; manual page `ops-config-smtp-accept-any-certificate.md`). Revocation checking is off (`CheckCertificateRevocation = false`) so an unreachable revocation server can't stop email; trust and name are checked. Proved locally against a TLS listener with a self-signed certificate: refused ("root certificate which is not trusted") without the setting, accepted with it. The STARTTLS-stripping point for security None stays as chosen by the customer; the security option mapping is in Deferred.
### F31 SMTP password returned to read-only roles (pass 8, from code) ### F31 SMTP password returned to read-only roles (pass 8, from code)
@@ -655,7 +655,7 @@ customer needs a self-signed mail server, make that an explicit setting.
to every role with read rights on `OpsNotificationSettings`: OpsAdminRestricted, BizAdmin and to every role with read rights on `OpsNotificationSettings`: OpsAdminRestricted, BizAdmin and
BizAdminRestricted, while only OpsAdmin may change it. Those users can then use the company's BizAdminRestricted, while only OpsAdmin may change it. Those users can then use the company's
mail account directly. Fix: never send the password to the client (return a "set" flag; keep the mail account directly. Fix: never send the password to the client (return a "set" flag; keep the
stored value when the PUT leaves it empty). stored value when the PUT leaves it empty). **Fixed in case 4724 (2026-10-24):** the GET returns `********` (entity detached first); a PUT with `********` or an empty value keeps the stored password. Test `SmtpPasswordHidden`; the stored password's fingerprint was unchanged after the round trip. Before the fix BizAdmin received the full password.
### F32 SMTP credentials in source (pass 8) ### F32 SMTP credentials in source (pass 8)

View File

@@ -26,6 +26,8 @@ IN PROGRESS
- Server: the automatic internal backup now runs the database backup utility directly instead of through a command shell, so the database password can contain any characters, and a failed backup is now reported as an error instead of appearing to succeed. See [backup](ops-form-backup.md). - Server: the automatic internal backup now runs the database backup utility directly instead of through a command shell, so the database password can contain any characters, and a failed backup is now reported as an error instead of appearing to succeed. See [backup](ops-form-backup.md).
- Server: log files are now named with an increasing number when they are archived; the [server log](ops-log.md) form lists them newest first. - Server: log files are now named with an increasing number when they are archived; the [server log](ops-log.md) form lists them newest first.
- Server: removed an unused internal performance profiling component. - Server: removed an unused internal performance profiling component.
- Server: AyaNova now checks the email (SMTP) server's security certificate when sending email. If your mail server uses a self-signed or internal certificate and email notifications stop after upgrading, see [SMTP certificate check](ops-config-smtp-accept-any-certificate.md).
- Server: the SMTP server password is no longer shown in the [notification settings](ops-notification-system.md) form; it shows `********` when a password is set. Type a new password to change it.
- Linux: Ubuntu 24.04 and 26.04 are now tested and supported. On Ubuntu 24.04 and newer the .NET runtime is installed from Ubuntu's own package archive. - Linux: Ubuntu 24.04 and 26.04 are now tested and supported. On Ubuntu 24.04 and newer the .NET runtime is installed from Ubuntu's own package archive.
- Docs: updated the [Linux server](ops-install-linux-server.md), [Linux desktop](ops-install-linux-desktop.md), [Windows local network](ops-install-windows-lan.md) and [Windows IIS](ops-install-windows-iis.md) installation and upgrade instructions for .NET 10 and Ubuntu 24.04 / 26.04. - Docs: updated the [Linux server](ops-install-linux-server.md), [Linux desktop](ops-install-linux-desktop.md), [Windows local network](ops-install-windows-lan.md) and [Windows IIS](ops-install-windows-iis.md) installation and upgrade instructions for .NET 10 and Ubuntu 24.04 / 26.04.
- Docs: updated the database password guidance in the installation and [backup](ops-form-backup.md) documentation. - Docs: updated the database password guidance in the installation and [backup](ops-form-backup.md) documentation.

View File

@@ -95,6 +95,10 @@ Command line parameters are appended to the command to start the ayanova server,
- [AYANOVA_REPORT_RENDERING_TIMEOUT](ops-config-report-rendering-timeout.md) - [AYANOVA_REPORT_RENDERING_TIMEOUT](ops-config-report-rendering-timeout.md)
- [AYANOVA_REPORT_RENDER_API_URL_OVERRIDE](ops-config-report-rendering-api-url-override.md) - [AYANOVA_REPORT_RENDER_API_URL_OVERRIDE](ops-config-report-rendering-api-url-override.md)
### EMAIL
- [AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE](ops-config-smtp-accept-any-certificate.md)
### SECURITY ### SECURITY
- [AYANOVA_SET_SUPERUSER_PW](ops-config-set-superuser-pw.md) - [AYANOVA_SET_SUPERUSER_PW](ops-config-set-superuser-pw.md)

View File

@@ -0,0 +1,53 @@
# SMTP certificate check setting
When AyaNova connects to the SMTP server set in the [notification settings](ops-notification-system.md) to send email, it checks the mail server's security certificate. The certificate must be issued by a trusted certificate authority and must match the SMTP server address entered in the notification settings. This prevents someone on the network from posing as your mail server to collect the SMTP account password and the messages being sent.
Most mail servers and email providers have a certificate that passes this check and nothing needs to be done.
## When the check fails
If the mail server's certificate can not be validated, email notifications are not sent. The Send test message option in the notification settings shows an error such as "The server's SSL certificate could not be validated", and failed deliveries are reported in the [notification system](ops-notification-system.md) as usual.
This can happen when:
- the mail server uses a self-signed certificate or one issued by your organization's own internal certificate authority
- the SMTP server address is entered as an IP address or a name that the certificate does not cover
The best fix is to correct the cause: enter the SMTP server address exactly as named in its certificate, or install your internal certificate authority as trusted on the computer running the AyaNova server. If neither is possible, the check can be switched off with this setting.
## Default
If this setting is not specified the certificate is checked.
## Overriding
AyaNova expects this value to be provided by a config.json property, environment variable or command line parameter named
`AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE`
Set it to `true` to accept any certificate from the mail server. Only do this for a mail server on a network you trust: without the check, the connection to the mail server is encrypted but AyaNova can not tell if it is talking to your real mail server.
When it is set, the AyaNova server log records a warning each time the server starts.
Example config.json entry
```json
{
...other properties...
"AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE": "true"
}
```
Example command line parameter
`ayanova.exe --AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE="true"`
Example environment variable
Windows
`set "AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE=true"`
Linux
`export AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE="true"`

View File

@@ -46,7 +46,7 @@ Typically this is an email address, for example `noreply@example.com` but some m
#### SMTP server password #### SMTP server password
The password the SMTP server requires to send email using the SMTP server account address. Note that this password is visible in this form to system operators and the read only roles listed above. The password the SMTP server requires to send email using the SMTP server account address. Once saved, the password is never shown in this form: it shows `********` when a password is set. To change it, type the new password and save. Leaving `********` in place keeps the saved password.
We recommend a dedicated email account used only for sending notifications. We recommend a dedicated email account used only for sending notifications.
@@ -60,6 +60,8 @@ The choices are:
- SSL \ TLS recommended and most secure. Implicit forced security. - SSL \ TLS recommended and most secure. Implicit forced security.
- StartTLS not recommended, negotiated security, may or may not be secure depending on the capabilities of the mail server. - StartTLS not recommended, negotiated security, may or may not be secure depending on the capabilities of the mail server.
AyaNova checks the mail server's security certificate when it connects. See [SMTP certificate check](ops-config-smtp-accept-any-certificate.md) if the test message reports that the certificate could not be validated.
#### SMTP server port #### SMTP server port
This is the port that must match the SMTP server's mail port. Most modern mail servers use port `587` which is the current recommended standard port for encrypted mail transmission. This is the port that must match the SMTP server's mail port. Most modern mail servers use port `587` which is the current recommended standard port for encrypted mail transmission.

View File

@@ -197,6 +197,7 @@ nav:
- "Reporting render browser path": "ops-config-report-render-browser-path.md" - "Reporting render browser path": "ops-config-report-render-browser-path.md"
- "Reporting timeout configuration": "ops-config-report-rendering-timeout.md" - "Reporting timeout configuration": "ops-config-report-rendering-timeout.md"
- "Environment variable reference": "ops-config-environment-variables.md" - "Environment variable reference": "ops-config-environment-variables.md"
- "SMTP certificate check": "ops-config-smtp-accept-any-certificate.md"
- "Security and JWT web tokens": "ops-config-jwt-secret.md" - "Security and JWT web tokens": "ops-config-jwt-secret.md"
- "SuperUser password reset": "ops-config-set-superuser-pw.md" - "SuperUser password reset": "ops-config-set-superuser-pw.md"
- "Server error codes": "ops-error-codes.md" - "Server error codes": "ops-error-codes.md"

View File

@@ -60,6 +60,10 @@ namespace AyaNova.Api.Controllers
if (o == null) if (o == null)
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
//case 4724: the SMTP password never goes to the client (detached first so the mask can't be saved)
ct.Entry(o).State = EntityState.Detached;
o.SmtpPassword = GlobalOpsNotificationSettingsBiz.SMTP_PASSWORD_MASK;
return Ok(ApiOkResponse.Response(o)); return Ok(ApiOkResponse.Response(o));
} }

View File

@@ -193,6 +193,7 @@ namespace AyaNova.Api.Controllers
AYANOVA_LOG_PATH = ServerBootConfig.AYANOVA_LOG_PATH, AYANOVA_LOG_PATH = ServerBootConfig.AYANOVA_LOG_PATH,
AYANOVA_LOG_LEVEL = ServerBootConfig.AYANOVA_LOG_LEVEL, AYANOVA_LOG_LEVEL = ServerBootConfig.AYANOVA_LOG_LEVEL,
AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG = ServerBootConfig.AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG, AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG = ServerBootConfig.AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG,
AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE = ServerBootConfig.AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE,
serverinfo = ServerBootConfig.BOOT_DIAGNOSTIC_INFO, serverinfo = ServerBootConfig.BOOT_DIAGNOSTIC_INFO,
dbserverinfo = ServerBootConfig.DBSERVER_DIAGNOSTIC_INFO dbserverinfo = ServerBootConfig.DBSERVER_DIAGNOSTIC_INFO
})); }));
@@ -315,6 +316,7 @@ namespace AyaNova.Api.Controllers
sbRet.AppendLine($"AYANOVA_LOG_PATH: {ServerBootConfig.AYANOVA_LOG_PATH}"); sbRet.AppendLine($"AYANOVA_LOG_PATH: {ServerBootConfig.AYANOVA_LOG_PATH}");
sbRet.AppendLine($"AYANOVA_LOG_LEVEL: {ServerBootConfig.AYANOVA_LOG_LEVEL}"); sbRet.AppendLine($"AYANOVA_LOG_LEVEL: {ServerBootConfig.AYANOVA_LOG_LEVEL}");
sbRet.AppendLine($"AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG: {ServerBootConfig.AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG}"); sbRet.AppendLine($"AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG: {ServerBootConfig.AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG}");
sbRet.AppendLine($"AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE: {ServerBootConfig.AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE}");
sbRet.AppendLine("#########################################################"); sbRet.AppendLine("#########################################################");
sbRet.AppendLine("SERVER DIAGNOSTICS"); sbRet.AppendLine("SERVER DIAGNOSTICS");

View File

@@ -228,6 +228,9 @@ namespace AyaNova
if (ServerBootConfig.AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG) if (ServerBootConfig.AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG)
logger.Warn("AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG is enabled, this will cause the server to run very slowly"); logger.Warn("AYANOVA_LOG_ENABLE_LOGGER_DIAGNOSTIC_LOG is enabled, this will cause the server to run very slowly");
if (ServerBootConfig.AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE)
logger.Warn("AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE is enabled, the SMTP server's certificate is not checked");
//Log environmental settings //Log environmental settings
long UtilityFilesAvailableSpace = 0; long UtilityFilesAvailableSpace = 0;

View File

@@ -10,6 +10,8 @@ namespace AyaNova.Biz
internal class GlobalOpsNotificationSettingsBiz : BizObject internal class GlobalOpsNotificationSettingsBiz : BizObject
{ {
//case 4724: shown to the client in place of the SMTP password, which never leaves the server
internal const string SMTP_PASSWORD_MASK = "********";
internal GlobalOpsNotificationSettingsBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles) internal GlobalOpsNotificationSettingsBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
{ {
@@ -62,6 +64,9 @@ namespace AyaNova.Biz
if (dbObject == null) if (dbObject == null)
throw new System.Exception("GlobalOpsNotificationSettings::PutAsync -> Settings object not found in database!!"); throw new System.Exception("GlobalOpsNotificationSettings::PutAsync -> Settings object not found in database!!");
//case 4724: the client gets the mask, not the password; the mask or an empty value keeps the stored password
if (string.IsNullOrEmpty(putObject.SmtpPassword) || putObject.SmtpPassword == SMTP_PASSWORD_MASK)
putObject.SmtpPassword = dbObject.SmtpPassword;
CopyObject.Copy(putObject, dbObject, "Id"); CopyObject.Copy(putObject, dbObject, "Id");
ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency; ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
Validate(dbObject); Validate(dbObject);

View File

@@ -83,7 +83,12 @@ namespace AyaNova.Util
using (var client = new SmtpClient()) using (var client = new SmtpClient())
{ {
client.ServerCertificateValidationCallback = (s, c, h, e) => true; //case 4724: the server's certificate must be trusted and match the server name, unless the
//AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE setting says otherwise. No revocation check: it fails the
//connection whenever the certificate authority's revocation server can't be reached
client.CheckCertificateRevocation = false;
if (ServerBootConfig.AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE)
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
bool UseSSL = smtpSettings.ConnectionSecurity != Biz.NotifyMailSecurity.None; bool UseSSL = smtpSettings.ConnectionSecurity != Biz.NotifyMailSecurity.None;
await client.ConnectAsync(smtpSettings.SmtpServerAddress, smtpSettings.SmtpServerPort, UseSSL); await client.ConnectAsync(smtpSettings.SmtpServerAddress, smtpSettings.SmtpServerPort, UseSSL);

View File

@@ -108,6 +108,10 @@ namespace AyaNova.Util
//SECURITY //SECURITY
internal static string AYANOVA_SET_SUPERUSER_PW { get; set; } internal static string AYANOVA_SET_SUPERUSER_PW { get; set; }
//EMAIL
//case 4724: the SMTP server's certificate is checked unless this is set (a mail server with a self-signed or internal certificate)
internal static bool AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE { get; set; }
//HELPFUL INFORMATION FOR DIAGNOSTICS //HELPFUL INFORMATION FOR DIAGNOSTICS
internal static Dictionary<string, string> BOOT_DIAGNOSTIC_INFO { get; set; } = internal static Dictionary<string, string> BOOT_DIAGNOSTIC_INFO { get; set; } =
new Dictionary<string, string>(); new Dictionary<string, string>();
@@ -218,6 +222,10 @@ namespace AyaNova.Util
bTemp = config.GetValue<bool?>("AYANOVA_REMOVE_LICENSE_FROM_DB"); bTemp = config.GetValue<bool?>("AYANOVA_REMOVE_LICENSE_FROM_DB");
AYANOVA_REMOVE_LICENSE_FROM_DB = (null == bTemp) ? false : (bool)bTemp; AYANOVA_REMOVE_LICENSE_FROM_DB = (null == bTemp) ? false : (bool)bTemp;
//EMAIL
bTemp = config.GetValue<bool?>("AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE");
AYANOVA_SMTP_ACCEPT_ANY_CERTIFICATE = (null == bTemp) ? false : (bool)bTemp;
//FOLDERS //FOLDERS
string DataFolderPath = ActualFullPath(config.GetValue<string>("AYANOVA_DATA_PATH")); string DataFolderPath = ActualFullPath(config.GetValue<string>("AYANOVA_DATA_PATH"));
string LogPath = ActualFullPath(config.GetValue<string>("AYANOVA_LOG_PATH")); string LogPath = ActualFullPath(config.GetValue<string>("AYANOVA_LOG_PATH"));