IMAP protocol violation: EXPUNGE response for unknown messages? - jakarta-mail

I have a question about the IMAP protocol (if my server violates it or I misunderstood something):
I am running into a javax.mail.MessagingException (caused by com.sun.mail.iap.CommandFailedException) because I am trying to access a message which does not exist anymore (actually the connected client never knew about it).
Using Javamail (almost current version, behavior does not change with the current version) I have two application [C1 and C2] accessing one IMAP mailbox/same folder [S].
Both clients [C1 and C2] regularly pull for new messages (using the javax.mail.Folder.getMessages() method). If a message is available it is read, deleted and the folder is expunged.
C1 is already connected and regularly does this job. Now C2 also connects and has the following communication with the IMAP server:
S: * OK The Microsoft Exchange IMAP4 service is ready.
C2: a001 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=NTLM AUTH=GSSAPI AUTH=PLAIN STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+
S: a001 OK CAPABILITY completed.
C2: a002 AUTHENTICATE PLAIN
S: +
C2: [...]
S: a002 OK AUTHENTICATE completed.
C2: a003 NOOP
S: a003 OK NOOP completed.
C2: a004 NOOP
S: a004 OK NOOP completed.
C2: a005 LIST "" MyFolder
S: * LIST (\HasNoChildren) "/" MyFolder
C2: a005 OK LIST completed.
S: a006 SELECT MyFolder
S: * 0 EXISTS
S: * 0 RECENT
S: * FLAGS (\Seen \Answered \Flagged \Deleted \Draft $MDNSent)
S: * OK [PERMANENTFLAGS (\Seen \Answered \Flagged \Deleted \Draft $MDNSent)] Permanent flags
S: * OK [UIDVALIDITY 11369] UIDVALIDITY value
S: * OK [UIDNEXT 39] The next unique identifier value
S: a006 OK [READ-WRITE] SELECT completed.
C2: a007 NOOP
S: a007 OK NOOP completed.
Obviously no messages are available, so C2 will just wait a few minutes and check again. Meanwhile C1 checks and receives one message, it flags it as deleted and expunges the folder.
The next time C2 asks for new messages (using the Javamail method mentioned above), my IMAP server returns:
C2: a008 NOOP
S: * 1 EXPUNGE
S: * 0 EXISTS
S: a008 OK NOOP completed.
Now javax.mail.Folder.getMessages() returns one message (with pretty much nothing filled), also javax.mail.Message.isExpunged() returns false.
Pretty much any method of the Message fails with the exception mentioned above com.sun.mail.iap.CommandFailedException: a010 NO The specified message set is invalid.
What am I doing wrong here?
Is my IMAP server reacting strange? Does it violate the IMAP protocol? Should it really inform my client (C2) about one expunged message it never knew?
Should I not keep the IMAPFolder open in JavaMail to use it later?
Could it be a bug in JavaMail (of course I do not know every line of the code, but the code seems to be around quite a while)?

Related

How do I grant a capability to an account after a module has been deployed?

I have my contract deployed on the testnet and I am trying to call (mint-nft) which has no arguments, but it does have a require-capability ACCOUNT_GUARD. I am getting error as follows:
Error from (api.testnet.chainweb.com): : Failure: require-capability: not granted:
(free.slightly-less-shitty-nft-project.ACCOUNT_GUARD "k:ab7cef70e1d91a138b8f65d26d6917ffcb852b84525b7dc2193843e8dfebf799")
ACCOUNT_GUARD capability defined: (taken from kitty-kad contract)
(defcap ACCOUNT_GUARD(account:string) ; Used for admin functions
#doc "Verifies account meets format and belongs to caller"
(enforce (= "k:" (take 2 account)) "For security, only support k: accounts")
(enforce-guard
(at "guard" (coin.details account))
)
)
A simplified mint-nft is defined as follows:
(defun mint-nft()
#doc "Allows any k: address to mint an nft"
(require-capability (ACCOUNT_GUARD (at "sender" (chain-data))))
(insert nft-main-table id {
"id":id,
"generation":0,
"owner-address":(at "sender" (chain-data))
})
)
From my understanding, ACCOUNT_GUARD is simply checking to see that the account calling the contract is a valid k: address and that the account calling it is the owner of said account.
Why would the ACCOUNT_GUARD not be granted to the caller of (mint-nft) in this case?
How do I grant the ACCOUNT_GUARD capability to any user that calls (mint-nft)?
Capabilities must be acquired before require-capability will succeed. See https://pact-language.readthedocs.io/en/stable/pact-reference.html#expressing-capabilities-in-code-defcap for discussion of this.
Capabilities are acquired with with-capability such that code within the body of the with-capability expression have the granted capability in scope. At that point you could call mint-nft, if that was a "protected function" that you did not want users to call at top level.
However if mint-nft is the intended top-level call, then use with-capability instead of require-capability, and include the insert call in the body. (Your indentation already looks like this even though there is no body in require-capability btw).
Lastly, you should not base anything on sender -- this is the gas payer only and in Kadena gas can be paid by a gas station or really anybody. Instead you should manage a user table with the associated guard, and validate the principal when creating the user. k: without any associated guard is meaningless.

Negative Number in SPID

I am constantly getting Azure SQL Server sessions with (blocked by) "Blk By" column of -5.
What could this session be please? I have searched for negative number SPID and I can see information for -2, -3, -4 but not for -5.
(I have removed identifiable information for hostname, login dbname columns)
Copied below is a listing from sp_who2
According to the documentation for blocking_session_id
-5 = Session ID of the blocking latch owner could not be determined because it is not tracked for this latch type (for example, for an SH latch).
Edit: I came across this from a Microsoft engineer. The bit I found interesting:
A​​ blocking session id of -5 alone does not indicate a performance problem. ​​ The addition of -5 is just an indication that the session is waiting on an asynchronous action to complete where-as​​ prior to the addition,​​ the same session wait would have showed​​ blocking session = 0​​ but​​ was still in a wait state.

VOLTTRON actuator agent RPC revert not working

I have a BACnet system for HVAC controls where I am using the VOLTTRON actuator agent to write # priority 10 in BACnet to a value of 2 which works good.
result = self.vip.rpc.call('platform.actuator', 'set_multiple_points', self.core.identity, set_multi_topic_values_master).get(timeout=20)
_log.debug(f'*** [Setter Agent INFO] *** - set_multiple_points ON ALL VAVs WRITE SUCCESS!')
Then the system sleeps for some time period for testing purposes:
_log.debug(f'*** [Setter Agent INFO] *** - SETTING UP GEVENT SLEEP!')
gevent.sleep(120)
_log.debug(f'*** [Setter Agent INFO] *** - GEVENT SLEEP DONE!')
Where after the gevent sleep I am running into some issues on the revert point not working. The code below executes just fine but using a BACnet scanning tool the priority 10 value of 2 are still present on the HVAC controls, like the revert point isn't doing anything.
for device in revert_topic_devices_jci:
response = self.vip.rpc.call('platform.actuator', 'revert_point', self.core.identity, topic_jci, self.jci_setpoint_topic).get(timeout=20)
_log.debug(f'*** [Setter Agent INFO] *** - REVERT POINTS ON {device} SUCCESS!')
_log.debug(f'*** [Setter Agent INFO] *** - REVERT POINTS JCI DONE DEAL SUCCESS!')
One thing I notice is the building automation writes occupancy/unoccupancy to the HVAC controls # BACnet priority 12. Its either ALWAYS a 1 for occupancy or a 2 for unoccupancy.
What I am trying to do with VOLTTRON is write in BACnet at priority 10 a value of 2, and then release to nothing on the revert. Could this by the revert isnt doing anything because there was nothing to revert too? I was hoping that VOLTTRON could write # BACnet priority 10 and then just release. On BACnet scan tool I can do the same thing write # priority 10 then release priority 10 with a priority 10 write null
Should I just be writing at priority 12 same as the building automation system so VOLTTRON can just revert back too whatever the building automation was doing?
I have a few observations:
In your revert loop, the third code-block above, you're not actually
changing the topic being passed to the RPC call. Each call will use
the device topic which is not in that code-block (but that we can
see is not being changed inside the block) and a device topic, which
similarly is not defined in the block but at least appears not to be
being changed. It is likely worth setting some breakpoints and/or
debug statements here to be sure that you're passing the correct
topics to revert on.
Your use of priority appears to be consistent
with BACnet protocol specification, and with the VOLTTRON BACnet
driver implementation. We would not recommend that you attempt to
write at the same priority as an existing building automation
system.
The BACnet driver code will send a NULL (None) value in a "writeProperty"
service request when the "revert_point" function is called by the
Platform Driver. This functionality I am frankly not terribly
familiar with, but given that your scan tool performs the expected
revert functionality when passed a NULL value, I suspect this is the expected
way of performing a "revert to previous value" type function in BACnet protocol.
I do not have reason to believe that the behavior you're experiencing is the
result of a bug in the driver code base.
Overall, I suggest debugging the topics being passed in the "revert_point" RPC call.
I am having a good luck to revert point using set_multiple_points to None
Something like this:
self.jci_device_map = {
'VMA-2-6': '27',
'VMA-2-4': '29',
'VMA-2-7': '30',
'VMA-1-8': '6',
}
revert_multi_topic_values_master = []
set_multi_topic_values_master = []
for device in self.jci_device_map.values():
topic_jci = '/'.join([self.building_topic, device])
final_topic_jci = '/'.join([topic_jci, self.jci_setpoint_topic])
# BACnet enum point for VAV occ
# 1 == occ, 2 == unnoc
# create a (topic, value) tuple and add it to our topic values
set_multi_topic_values_master.append((final_topic_jci, self.unnoccupied_value)) # TO SET UNNOCUPIED
revert_multi_topic_values_master.append((final_topic_jci, None)) # TO SET FOR REVERT
result = self.vip.rpc.call('platform.actuator', 'set_multiple_points', self.core.identity, revert_multi_topic_values_master).get(timeout=20)

JavaMail SEARCH returns BADCHARSET

I have developed an email client at work using JavaMail. Some customers have reported massive delays when searching for subjects with non-English characters (e.g. "Kühlgut").
It turned out that some mail providers (in this case Office 365) do not support searching with UTF-8 charset (resulting in a BadCommandException). Therefore, JavaMail fetches and performs the search locally (as fallback).
This behaviour caused the massive delays.
Code:
String searchTerm = "Kühlgut";
SearchTerm[] searchTerms = new SearchTerm[3];
searchTerms[0] = new FromStringTerm(searchTerm);
searchTerms[1] = new SubjectTerm(searchTerm);
searchTerms[2] = new BodyTerm(searchTerm);
OrTerm orTerm = new OrTerm(searchTerms);
folder.search(orTerm);
JavaMail debug output of the search command:
C18 SEARCH CHARSET UTF-8 OR OR FROM {8+}
Kühlgut SUBJECT {8+}
Kühlgut BODY {8+}
Kühlgut ALL
C18 NO [BADCHARSET (US-ASCII)] The specified charset is not supported.
C19 SEARCH CHARSET Cp1252 OR OR FROM {7+}
Kühlgut SUBJECT {7+}
Kühlgut BODY {7+}
Kühlgut ALL
C19 NO [BADCHARSET (US-ASCII)] The specified charset is not supported.
B20 FETCH 1 (ENVELOPE INTERNALDATE RFC822.SIZE)
* 1 FETCH (ENVELOPE ....)
B20 OK FETCH completed.
B21 FETCH 1 (BODYSTRUCTURE)
* 1 FETCH (BODYSTRUCTURE ...
B21 OK FETCH completed.
I do have two questions:
Is it possible to check if the IMAP server supports searching with UTF-8 charset (e.g. via capabilities)?
How can I stop JavaMail from fetching all emails if the former is not possible (no exception is thrown)?
I don't think there's a way to do #1, but for #2 try setting the mail.imap.throwsearchexception property to true.
And submit a bug to Microsoft since Office 365 really should support searching with utf-8.

Failure scenarios for ADB Adapter

I want to test failure scenarios for ADB Adapter in tibco. The states are C,N,F,P.
P = indicates pending acknowledgement.
N = indicates that a new message has arrived, but has not yet been published.
C = indicates complete.
F = indicates failed.
Can someone tell me in which scenario can I get status as F or P.
AFAIK, C stands for "confirmed", not "complete".
The message goes into the C state after a subscriber has confirmed its reception using the activity "Confirm".
So you can obtain a P state, for instance, by turning off the subscriber process while the publisher process is producing. All the messages sent but not consumed are in "P" (and you should find them into the ledger file)
I'm sorry, I've never seen the F state :-)

Resources