How give trust to an external application accessing the Outlook Object Model (with all security options on) - outlook

I have a .NET application that interacts with Outlook like this:
Microsoft.Office.Interop.Outlook.Application app = new
Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem item = app.CreateItem((Microsoft.Office.Interop.Outlook.OlItemType.olMailItem));
item.PropertyAccessor.SetProperty(PsInternetHeaders + Foobar, 1031);
item.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
item.To = "a#test.com;b#test.com;c#test.com";
item.BCC = "cc#test.com";
item.Body = "Hello There!";
item.Display();
Be aware that I need to access the "PropertyAccessor" property.
In a normal environment this runs fine, but in a "secure" enviroment with this registry keys in place it just fails with Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT)):
[HKEY_CURRENT_USER\Software\Policies\Microsoft\office\16.0\outlook\security]
"PromptOOMAddressBookAccess"=dword:00000000
"AdminSecurityMode"=dword:00000003
"PromptOOMAddressInformationAccess"=dword:00000000
Outlooks security model seems to have a "trustedaddins" list, but I'm not really sure if this applies to "external applications" as well and that exactly I need to register unter TrustedAddins (see here).
My main question would be: Can I just register and foobar.exe unter trustedaddins or is this not possible at all?
I know that I could lower or disable the security stuff, but this is not my choice ;)

Your only options are listed at How to avoid Outlook Security Alert when sending Outlook message from VBScript?
You also might want to set PsInternetHeaders properties to strings only, not ints.

Related

MAPI showing details of contacts

We are currently using MAPI to load contact information into a form.
Within a MapiSession we are creating a RDOAddressEntry "recepient" with this bit of code
using (MapiSession session = new MapiSession())
{
//open outlook contact dialog
RDOAddressEntry recipient = session.GetAddressEntryFromID(contact.EntryId);
if (recipient.Type == null)
{
throw new ArgumentException("type not defined");
}
recipient.Details(handle.ToInt32());
}
Our problem seems to be that the dialog that opens with the last line of code creates two different dialogs. One for exchange contacts and another one for SMTP contacts.
In the last version of our application it was always opening the same dialog for both RDOAddressEntry-types and we did NOT change anything in our code...
Can you help me fix this issue so that both SMTP and exchange will bring the same dialogs again?
I am not sure why you were getting the same dialog for both before - the dialog is actually provided by the particular address book provider, so it will be different for the entries from different providers.

Best Way to Send Scheduled E-Mail in .NET MVC3 Application using MVCMailer

I am working on a .NET MVC3 C# Application. This application is hosted on our own Server.
Now I want to Send Scheduled Email in my application like daily(at a specific time),Weekly, monthly and so on...
Currently I am using MVCMailer to send Emails in my application.
I tried Fluent Scheduler to send scheduled Emails, but it doesn't works with MVCMailer. It Works fine if I send mails without MVCMailer and for other scheduling jobs.
It gives me a ERROR NULLReferenceException and says HTTPContext cannot be null.
What can I do to solve this problem.
Also suggest me which will be the best way to send E-mails in my applicaton.
Windows Service (Having own server)
Scheduler (Fluent Scheduler)
SQL Scheduled jobs
I am attaching ERROR snapshot:
It could be that MVCMailer depends on an HttpContext, which will not exist on your scheduled threadlocal's.
You could consider scrapping MvcMailer and implementing your own templating solution. Something like RazorEngine (https://github.com/Antaris/RazorEngine), which gives you the full power of Razor without having to run ontop on an Http stack. You could still source your templates from disk so that your designers could modify it.
Then you could mail the results using the standard classes available from .net.
For e.g.:
string template = File.ReadAllText(fileLocation);//"Hello #Model.Name, welcome to RazorEngine!";
string emailBody = Razor.Parse(template, new { Name = "World" });
SmtpClient client = new SmtpClient();
client.Host = "mail.yourserver.com";
MailMessage mm = new MailMessage();
mm.Sender = new MailAddress("foo#bar.com", "Foo Bar");
mm.From = new MailAddress("foo#bar.com", "Foo Bar");
mm.To.Add = new MailAddress("foo#bar.com", "Foo Bar");
mm.Subject = "Test";
mm.Body = emailBody;
mm.IsBodyHtml = true;
client.Send(mm);
Obviously you could clean this all up. But it wouldn't take to much effort to use the above code and create some reusable classes. :)
Since you already have the FluentScheduler code set up, you may as well stick with that I guess. A windows service does also sound appealing, however I think that it's your call to make. If it's a simple mail service you are after I can't think of any reason not to do it via FluentScheduler.
I have created a full example of this available here: https://bitbucket.org/acleancoder/razorengine-email-example/src/dfee804d526ef3cd17fb448970fbbe33f4e4bb79?at=default
You can download the website to run locally here: https://bitbucket.org/acleancoder/razorengine-email-example/downloads
Just make sure to change the Default.aspx.cs file to have your correct mail server details.
Hope this helps.
Since MVC Mailer works best in the HTTP stack (i.e. from controllers), I've found that a very reliable way to accomplish this is by using Windows Task Schedule from a server somewhere. You could even spin up a micro instance on Amazon Web Server.
Use "curl" to call the URL of your controller that does the work and sends the emails.
Just setup a Scheduled Task (or Cron if you want to use *IX) to call "c:\path_to_curl\curl.exe http://yourserver.com/your_controller/your_action".
You could even spin up a *IX server on AWS to make it even cheaper.

Detect url the user is viewing in chrome/firefox/safari

How can you detect the url that I am browsing in chrome/safari/firefox via cocoa (desktop app)?
As a side but related note, are there any security restrictions when developing a desktop app that the user will be alerted and asked if they want to allow? e.g. if the app accesses their contact information etc.
Looking for a cocoa based solution, not javascript.
I would do this as an extension, and because you would like to target Chrome, Safari, and Firefox, I'd use a cross-browser extension framework like Crossrider.
So go to crossrider.com, set up an account and create a new extension. Then open the background.js file and paste in code like this:
appAPI.ready(function($) {
appAPI.message.addListener({channel: "notifyPageUrl"}, function(msg) {
//Do something, like send an xhr post somewhere
// notifying you of the pageUrl that the user visited.
// The url is contained within msg.pageUrl
});
var opts = { listen: true};
// Note: When defining the callback function, the first parameter is an object that
// contains the page URL, and the second parameter contains the data passed
// to the context of the callback function.
appAPI.webRequest.onBeforeNavigate.addListener(function(details, opaqueData) {
// Where:
// * details.pageUrl is the URL of the tab requesting the page
// * opaqueData is the data passed to the context of the callback function
if(opaqueData.listen){
appAPI.message.toBackground({
msg: details.pageUrl
}, {channel: "notifyPageUrl"});
}
}, opts ); // opts is the opaque parameter that is passed to the callback function
});
Then install the extension! In the example above, nothing is being done with the detected pageUrl that the user is visiting, but you can do whatever you like here - you could send a message to the user, you could restrict access utilizing the cancel or redirectTo return parameters, you could log it locally utilizing the crossrider appAPI.db API or you could send the notification elsewhere, cross-domain, to wherever you like utilizing an XHR request from the background directly.
Hope that helps!
And to answer the question on security issues desktop-side, just note that desktop applications will have the permissions of the user under which they run. So if you are thinking of providing a desktop app that your users will run locally, say something that will detect urls they access by tapping into the network stream using something like winpcap on windows or libpcap on *nix varieties, then just be aware of that - and also that libpcap and friends would have to have access to a network card that can be placed in promiscuous mode in the first place, by the user in question.
the pcap / installed desktop app solutions are pretty invasive - most folks don't want you listening in on literally everything and may actually violate some security policies depending on where your users work - their network administrators may not appreciate you "sniffing", whether that is the actual purpose or not. Security guys can get real spooky so-to-speak on these kinds of topics.
The extension via Crossrider is probably the easiest and least intrusive way of accomplishing your goal if I understand the goal correctly.
One last note, you can get the current tab urls for all tabs using Crossrider's tabs API:
// retrieves the array of tabs
appAPI.tabs.getAllTabs(function(allTabInfo) {
// Display the array
for (var i=0; i<allTabInfo.length; i++) {
console.log(
'tabId: ' + allTabInfo[i].tabId +
' tabUrl: ' + allTabInfo[i].tabUrl
);
}
});
For the tab API, refer to:
http://docs.crossrider.com/#!/api/appAPI.tabs
For the background navigation API:
http://docs.crossrider.com/#!/api/appAPI.webRequest.onBeforeNavigate
And for the messaging:
http://docs.crossrider.com/#!/api/appAPI.message
And for the appAPI.db stuff:
http://docs.crossrider.com/#!/api/appAPI.db
Have you looked into the Scripting Bridge? You could have an app that launches, say, an Applescript which verifies if any of the well known browser is opened and ask them which documents (URL) they are viewing.
Note: It doesn't necessarily need to be an applescript; you can access the Scripting Bridge through cocoa.
It would, however, require the browser to support it. I know Safari supports it but ignore if the others do.
Just as a quick note:
There are ways to do it via AppleScript, and you can easily wrap this code into NSAppleScript calls.
Here's gist with AppleScript commands for Safari and Chrome. Firefox seems to not support AE.
Well obviously this is what I had come across on google.
chrome.tabs.
getSelected
(null,
function
(tab) {
alert
(tab.url);
}) ;
in pure javascript we can use
alert(document.URL);
alert(window.location.href)
function to get current url

Registering a protocol handler in Windows 8

I'm trying to register my application that will handle opening of links, e,g, http://stackoverflow.com. I need to do this explicitly for Windows 8, I have itworking in earlier versions of Windows. According to MSDN this has changed in Win8.
I've been through the Default Programs page on MSDN (msdn.microsoft.com/en-us/library/cc144154.aspx) page on MSDN. It provides a great walkthrough on handling file types but is light on details for protocols. Registering an Application to a URL Protocol only goes over the steps involved in setting up a new protocol, but not how to correctly add a new handler to an existing protocol.
I've also tried the registry settings outlined in other SO posts.
One more thing, the application is not a Metro/Windows Store App, so adding an entry in the manifest won't work for me.
You were on the right track with the Default Programs web page - in fact, it's my reference for this post.
The following adapts their example:
First, you need a ProgID in HKLM\SOFTWARE\Classes that dictates how to handle any input given to it (yours may already exist):
HKLM\SOFTWARE\Classes
MyApp.ProtocolHandler //this is the ProgID, subkeys are its properties
(Default) = My Protocol //name of any type passed to this
DefaultIcon
(Default) = %ProgramFiles%\MyApp\MyApp.exe, 0 //for example
shell
open
command
(Default) = %ProgramFiles%\MyApp\MyApp.exe %1 //for example
Then fill the registry with DefaultProgram info inside a Capabilities key:
HKLM\SOFTWARE\MyApp
Capabilities
ApplicationDescription
URLAssociations
myprotocol = MyApp.ProtocolHandler //Associated with your ProgID
Finally, register your application's capabilities with DefaultPrograms:
HKLM\SOFTWARE
RegisteredApplications
MyApplication = HKLM\SOFTWARE\MyApp\Capabilities
Now all "myprotocol:" links should trigger %ProgramFiles%\MyApp\MyApp.exe %1.
Side note since this is a top answer found when googling this kind of an issue:
Make sure the path in the shell command open is a proper path to your application.
I spent an entire day debugging issue that seemed only to affect Chrome and Edge on Windows 10. They never triggered the protocol handler while Firefox did.
What was the issue? The path to the .bat file used mixed
\ and / slashes.
Using only proper \ slashes in the path made Edge & Chrome suddenly able to pick up the request.
LaunchUriAsync(Uri)
Starts the default app associated with the URI scheme name for the specified URI.
You can allow the user to specify, in this case.
http://msdn.microsoft.com/library/windows/apps/Hh701476
// Create the URI to launch from a string.
var uri = new Uri(uriToLaunch);
// Calulcate the position for the Open With dialog.
// An alternative to using the point is to set the rect of the UI element that triggered the launch.
Point openWithPosition = GetOpenWithPosition(LaunchUriOpenWithButton);
// Next, configure the Open With dialog.
// Here is where you choose the program.
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = true;
options.UI.InvocationPoint = openWithPosition;
options.UI.PreferredPlacement = Windows.UI.Popups.Placement.Below;
// Launch the URI.
bool success = await Windows.System.Launcher.LaunchUriAsync(uri, options);
if (success)
{
// URI launched: uri.AbsoluteUri
}
else
{
// URI launch failed. uri.AbsoluteUri
}

Using Pgp.exe from a MVC application

I've been tasked with converting a legacy application to mvc. The app used pgp.exe to pgp sign user input and send it as an email. The application works locally and on a test server but won't run on a live server. I've had to jump though hoops such as running a specified user in the application pool so that we can set the keys in the users profile BUT it worked.
For some reason on the live server which is windows 2003 IIS 6 and identical to the testing server it fails. The problem is pgp.exe just wont seem to sign and create files the message I get from the console out put is. "Signature Error"?? When I put the command into a shell window logged in as the app pool user it runs no problem (after a fight with some permissions) but when running through the mvc application/IIS server it fails. The code used to call the process is below.
var startInfo = new ProcessStartInfo();
startInfo.FileName = _pgpexeLocation;
//startInfo.FileName = "pgp.exe";
startInfo.Arguments = string.Format("-sta \"{0}\" -u keyuser-z keypass +COMPATIBLE +FORCE", _tempFilePath);
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.LoadUserProfile = true;
using (Process exeProcess = Process.Start(startInfo))
{
// TODO: set limit to wait for and deal with exit
exeProcess.WaitForExit();
//var stringItem = exeProcess.StandardOutput.ReadToEnd();
//Logger.Info(stringItem);
}
I'm clutching at straws here hoping somebody has done something similar before and can help. I'm guessing it's key location or file location not being picked up somewhere but not sure what else to try?
Turns out that even though the app pool was using a specific user and I'd set the keys up in that users appdata folder when I checked the underlying process call it was actually trying to pick the keys up from the Default User profile. Not sure if this was an IIS config or something similar but moving the keys and pgp folder to this appdata instead worked?

Resources