use of dev.hawala.xns.level4.mailing.MailTransport4.ServiceErrorRecord in project dodo by devhawala.
the class MailingOldImpl method inbasket_logon.
/*
* ************************* implementation of Inbasket service procedures
*/
/*
* logon
* = procedure 5
*/
private static void inbasket_logon(LogonParams params, LogonResults results) {
// log ingoing data
if (logParamsAndResults) {
StringBuilder sb = new StringBuilder();
params.append(sb, " ", "params");
log("##\n## procedure MailingImpl.inbasket_logon() -- params\n%s\n##\n", sb.toString());
}
// check user credentials
Credentials credentials = params.mbx.creds.credentials;
Verifier verifier = params.mbx.creds.verifier;
StrongVerifier decodedVerifier = StrongVerifier.make();
int[] decodedConversationKey = new int[4];
// throws an exception on invalid credentials
mailService.checkCredentials(mailService.getServiceName(), mailService.getMachineId(), credentials, verifier, decodedConversationKey, decodedVerifier);
// check if the mailbox is available
Name reqMbxName = params.mbx.name;
// mbxName.getLcFqn();
String mailboxFqn = mailService.getChsDatabase().resolveName(reqMbxName);
if (mailboxFqn == null) {
new AccessErrorRecord(AccessProblem.noSuchMailbox).raise();
}
log("## logon to mailbox: %s\n", mailboxFqn);
Name mbxName = Name.make();
mbxName.from(mailboxFqn);
if (!mailService.hasMailbox(mailboxFqn)) {
new AccessErrorRecord(AccessProblem.noSuchMailbox).raise();
}
// prevent concurrent sessions to the same mailbox if sharing is disallowed
if (!params.allowSharing.get() && mailService.hasSession(mailboxFqn)) {
new AccessErrorRecord(AccessProblem.mailboxBusy).raise();
}
// start the new session
long remoteHostId = credentials.remoteHostId.get();
MailSession session;
try {
session = mailService.createSession(mbxName, remoteHostId, decodedConversationKey);
} catch (IOException ioe) {
new ServiceErrorRecord(ServiceProblem.serviceUnavailable).raise();
// prevent the 'session not initialized' compiler warning as it cannot know that .raise() never returns...
return;
}
// build results (verifier encrypted in analogy to FilingImpl, see comments in 'innerLogon')
int sessionId = session.getSessionId();
results.session.token.set(sessionId);
if (credentials.type.get() == CredentialsType.simple) {
// return the initiators verifier
results.session.verifier.add().set(verifier.get(0).get());
} else {
// create a strong verifier based on the received verifier
int[] conversationKey = session.getConversationKey();
if (conversationKey != null && conversationKey.length == 4) {
// xor-ing values
// the server machine, not(!) the remoteHostId extracted from the Logon request
long xorHostId = machineId;
// left justified machine-id => upper 32 bits
long rcptTimestampMachineId32Bits = (xorHostId >> 16) & 0xFFFFFFFFL;
// left justified machine-id => lower 32 bits
long rcptTicksMachineId32Bits = (xorHostId & 0x0000FFFFL) << 16;
// new verifier values
long newTicks = decodedVerifier.ticks.get() + 1;
long newTimestamp = decodedVerifier.timeStamp.get();
if (newTicks > 0xFFFFFFFFL) {
newTicks = 0;
newTimestamp++;
}
// plain (unencrypted) verifier with xor-ed values
StrongVerifier verfr = StrongVerifier.make();
verfr.ticks.set(newTicks ^ rcptTicksMachineId32Bits);
verfr.timeStamp.set(newTimestamp ^ rcptTimestampMachineId32Bits);
// encrypt verifier and transfer into results
try {
WireWriter writer = new WireWriter();
verfr.serialize(writer);
int[] sourceBytes = writer.getWords();
int[] encrypted = StrongAuthUtils.xnsDesEncrypt(conversationKey, sourceBytes);
for (int i = 0; i < encrypted.length; i++) {
results.session.verifier.add().set(encrypted[i]);
}
} catch (Exception e) {
// log and set no verifier => let the invoker decide if acceptable
log("** !! unable to serialize or encrypt the verifier in logon results: " + e.getMessage());
}
}
}
results.cacheStatus.set(CacheStatus.invalid);
// log outgoing data
if (logParamsAndResults) {
StringBuilder sb = new StringBuilder();
results.append(sb, " ", "results");
log("##\n## procedure MailingImpl.inbasket_logon() -- results\n%s\n##\n", sb.toString());
}
}
use of dev.hawala.xns.level4.mailing.MailTransport4.ServiceErrorRecord in project dodo by devhawala.
the class MailService method readMail.
/**
* Access a mail and retrieve its various data.
*
* @param mail the mailbox entry to access
* @param mailContentSink the destination to send the mail content to
* @param transportEnvelope the (Courier-) object to fill with the mail-post envelope
* @param inbasketEnvelope the (Courier-) object to fill with the mailbox-status envelope
* @return {@code null} if accessing the mail was successful, otherwise the Courier error
* holding the problem to report to the client (in which case the possibly partially
* filled / transmitted data must be discarded)
*/
public ErrorRECORD readMail(MailboxEntry mail, ByteContentSink mailContentSink, EncodedList transportEnvelope, EncodedList inbasketEnvelope) {
// build the inbasket envelope
inbasketEnvelope.add(Attribute.make().set(MailingCommon.atIbMessageStatus, MailingCommon.mkMessageStatus, a -> a.set(mail.messageStatus())));
// get the transport envelope from the mail reference file
try {
ValueContentSink envMaker = new ValueContentSink(transportEnvelope);
mail.transferPostboxEnvelope(envMaker);
} catch (IOException e) {
return new ServiceErrorRecord(ServiceProblem.serviceUnavailable);
}
// transfer mail content
try {
mail.transferContent(mailContentSink);
} catch (IOException e) {
return new TransferErrorRecord(TransferProblem.aborted);
}
// successfully done
return null;
}
use of dev.hawala.xns.level4.mailing.MailTransport4.ServiceErrorRecord in project dodo by devhawala.
the class ErrorRaiser method serviceUnavailable.
@Override
public void serviceUnavailable(String msg) {
this.log(msg);
new ServiceErrorRecord(ServiceProblem.serviceUnavailable).raise();
}
use of dev.hawala.xns.level4.mailing.MailTransport4.ServiceErrorRecord in project dodo by devhawala.
the class MailingNewImpl method inbasket2_logon.
/*
* logon
* = procedure 5
*/
private static void inbasket2_logon(LogonParams params, LogonResults results) {
// log ingoing data
if (logParamsAndResults) {
StringBuilder sb = new StringBuilder();
params.append(sb, " ", "params");
logf("##\n## procedure MailingNewImpl.inbasket2_logon() -- params\n%s\n##\n", sb.toString());
}
// check user credentials
Credentials credentials = params.credentials;
Verifier verifier = params.verifier;
StrongVerifier decodedVerifier = StrongVerifier.make();
int[] decodedConversationKey = new int[4];
// throws an exception on invalid credentials
mailService.checkCredentials(mailService.getServiceName(), mailService.getMachineId(), credentials, verifier, decodedConversationKey, decodedVerifier);
// check if the mailbox is available
ThreePartName reqMbxName = params.mailboxName;
// mbxName.getLcFqn();
String mailboxFqn = mailService.getChsDatabase().resolveName(reqMbxName);
if (mailboxFqn == null) {
new AccessErrorRecord(AccessProblem.noSuchMailbox).raise();
}
logf("## logon to mailbox: %s\n", mailboxFqn);
Name mbxName = Name.make();
mbxName.from(mailboxFqn);
if (!mailService.hasMailbox(mailboxFqn)) {
new AccessErrorRecord(AccessProblem.noSuchMailbox).raise();
}
// start the new session
long remoteHostId = credentials.remoteHostId.get();
MailSession session;
try {
session = mailService.createSession(mbxName, remoteHostId, decodedConversationKey);
} catch (IOException ioe) {
new ServiceErrorRecord(ServiceProblem.serviceUnavailable).raise();
// prevent the 'session not initialized' compiler warning as it cannot know that .raise() never returns...
return;
}
// build results (verifier encrypted in analogy to FilingImpl, see comments in 'innerLogon')
int sessionId = session.getSessionId();
results.sessionId.set(sessionId);
if (credentials.type.get() == CredentialsType.simple) {
// return the initiators verifier
results.verifier.add().set(verifier.get(0).get());
} else {
// create a strong verifier based on the received verifier
int[] conversationKey = session.getConversationKey();
if (conversationKey != null && conversationKey.length == 4) {
// xor-ing values
// the server machine, not(!) the remoteHostId extracted from the Logon request
long xorHostId = machineId;
// left justified machine-id => upper 32 bits
long rcptTimestampMachineId32Bits = (xorHostId >> 16) & 0xFFFFFFFFL;
// left justified machine-id => lower 32 bits
long rcptTicksMachineId32Bits = (xorHostId & 0x0000FFFFL) << 16;
// new verifier values
long newTicks = decodedVerifier.ticks.get() + 1;
long newTimestamp = decodedVerifier.timeStamp.get();
if (newTicks > 0xFFFFFFFFL) {
newTicks = 0;
newTimestamp++;
}
// plain (unencrypted) verifier with xor-ed values
StrongVerifier verfr = StrongVerifier.make();
verfr.ticks.set(newTicks ^ rcptTicksMachineId32Bits);
verfr.timeStamp.set(newTimestamp ^ rcptTimestampMachineId32Bits);
// encrypt verifier and transfer into results
try {
WireWriter writer = new WireWriter();
verfr.serialize(writer);
int[] sourceBytes = writer.getWords();
int[] encrypted = StrongAuthUtils.xnsDesEncrypt(conversationKey, sourceBytes);
for (int i = 0; i < encrypted.length; i++) {
results.verifier.add().set(encrypted[i]);
}
} catch (Exception e) {
// log and set no verifier => let the invoker decide if acceptable
logf("** !! unable to serialize or encrypt the verifier in logon results: " + e.getMessage());
}
}
}
// fill the mail server's machine-id
results.machineId.set(machineId);
// fill in the mailbox counts
// State pollState = State.make();
// mailService.getMailboxState(mbxName, pollState);
// results.lastIndex.set(pollState.lastIndex.get());
// results.newCount.set(pollState.newCount.get());
results.lastIndex.set(session.getMailCount());
results.newCount.set(session.getMailCount());
// log outgoing data
if (logParamsAndResults) {
StringBuilder sb = new StringBuilder();
results.append(sb, " ", "results");
logf("##\n## procedure MailingNewImpl.inbasket2_logon() -- results\n%s\n##\n", sb.toString());
}
}
use of dev.hawala.xns.level4.mailing.MailTransport4.ServiceErrorRecord in project dodo by devhawala.
the class MailService method postMail.
/**
* Create a new mail posted to one or more recipients.
*
* @param sender the user sending the mail
* @param recipients list of already verified recipients of the mail, having
* groups (aka distribution-lists) already expanded
* @param contentsType the type id for the mail content
* @param source the filing source for the mail content
* @return the mail identification for the created mail
*/
public int[] postMail(ThreePartName sender, NameList recipients, long contentsType, iContentSource source) {
try (Session fSession = this.mailsVolume.startModificationSession()) {
// get the next free mail-id
int[] mailId = this.allocateMailId(fSession);
String mailFileName = String.format("%08X-%04X-%04X", System.currentTimeMillis(), mailId[3], mailId[4]);
// create the meta-data for the mail content file
MailMetaData postedMetaData = new MailMetaData();
postedMetaData.sender.from(sender);
for (int i = 0; i < recipients.size(); i++) {
postedMetaData.recipients.add(recipients.get(i));
}
postedMetaData.contentsType.set(contentsType);
postedMetaData.mailboxReferences.set(recipients.size());
UninterpretedAttribute postedMetaDataAttr = new UninterpretedAttribute(atPostedMetaData);
postedMetaData.to(postedMetaDataAttr);
// create the mail content file
FileEntry mailFile = fSession.createFile(// . parentId
mailfilesFolder.getFileID(), // ....................... isDirectory
false, // ................ name
mailFileName, // ........................... version
1, // .................. type
ftMailFile, // ......... creatingUser
this.serviceNameFqn, Arrays.asList(fe -> fe.getUninterpretedAttributes().add(postedMetaDataAttr)), source);
// create the envelope
EncodedList env = EncodedList.make();
env.add(Attribute.make().set(MailingCommon.atMtPostmark, Postmark::make, a -> {
a.server.from(this.chsDatabase.getMailServiceFqn());
a.time.fromUnixMillisecs(System.currentTimeMillis());
}));
env.add(Attribute.make().set(MailingCommon.atMtMessageID, MessageID::make, a -> {
for (int i = 0; i < mailId.length; i++) {
a.get(i).set(mailId[i]);
}
}));
env.add(Attribute.make().setAsLongCardinal(MailingCommon.atMtContentsType, contentsType));
env.add(Attribute.make().setAsLongCardinal(MailingCommon.atMtContentsSize, mailFile.getDataSize()));
env.add(Attribute.make().setAsChsName(MailingCommon.atMtOriginator, sender));
env.add(Attribute.make().setAsChsName(MailingCommon.atMtReturnToName, sender));
ValueContentSource envelopeSource = new ValueContentSource(env);
// create the inbox-references in the mailboxes of all recipients
String inboxMailFileName = mailFileName + INBOX_SUFFIX_NEW;
for (int i = 0; i < recipients.size(); i++) {
Name rcpt = recipients.get(i);
FileEntry mailbox = this.mailboxes.get(rcpt.getLcFqn());
// should never happen...
if (mailbox == null) {
continue;
}
fSession.createFile(// ......... parentId
mailbox.getFileID(), // ....................... isDirectory
false, // ........... name
inboxMailFileName, // ........................... version
1, // ................. type
ftInboxMail, // ......... creatingUser
this.serviceNameFqn, Collections.emptyList(), envelopeSource.reset());
}
// done
return mailId;
} catch (IllegalStateException e) {
Log.C.printf("MS", "postMail() -> rejecting with ServiceError[serviceUnavailable], cause: %s\n", e.getMessage());
new ServiceErrorRecord(ServiceProblem.serviceUnavailable).raise();
} catch (InterruptedException e) {
Log.C.printf("MS", "postMail() -> rejecting with ServiceError[serviceUnavailable], cause: %s\n", e.getMessage());
new ServiceErrorRecord(ServiceProblem.serviceUnavailable).raise();
} catch (Exception e) {
Log.C.printf("MS", "postMail() -> rejecting with ServiceError[serviceUnavailable], cause: %s\n", e.getMessage());
new ServiceErrorRecord(ServiceProblem.serviceUnavailable).raise();
}
// keep the compiler happy (errors raised do not return)
return null;
}
Aggregations