Shared posts

07 May 12:01

Crypto101 - Programmer focused introduction to cryptography

by Greg Duncan

404 Tech Support - Crypto 101, a free intro to encryption for developers

Crypto 101 is an introductory course on cryptography intended to help programmers understand encryption in order to write better code. It is currently available in a DRM-free PDF with EPUB and Mobi also listed on the website. Crypto 101 uses Python for exercises which can run on OS X, Windows, and Linux.

The book is available now in its pre-release form with a Creative Commons – Attribution-Noncommercial license. It is being written as an open-source project using github. The 252 page book, written by Laurens Van Houtven, is almost entirely complete at this point. It stems from an extension of a presentation given at PyCon 2013.

...

Crypto101

Crypto 101 is an introductory course on cryptography, freely available for programmers of all ages and skill levels.

Start to finish.

Comes with everything you need to understand complete systems such as SSL/TLS: block ciphers, stream ciphers, hash functions, message authentication codes, public key encryption, key agreement protocols, and signature algorithms.

Learn by doing.

Learn how to exploit common cryptographic flaws, armed with nothing but a little time and your favorite programming language.

Forge administrator cookies, recover passwords, and even backdoor your own random number generator.

Works everywhere.

DRM-free and available in all common formats:

Exercises run on OS X, Windows, Linux and BSDs.

Donations

Crypto 101 is available for everyone, for free, forever. Development is hosted on Github, funded by free time and your donations. You are free to donate any amount you want, and all donations are of course entirely voluntary. Learn more about contributing. ...

image

CHAPTER 1. ABOUT THIS BOOK

This book is intended as an introduction to cryptography for programmers of any skill level. It’s a continuation of a talk of the same name, which was given by the author at PyCon 2013.

The structure of this book is very similar: it starts with very simple primitives, and gradually introduces new ones, demonstrating why they’re necessary. Eventually, all of this is put together into complete, practical cryptosystems, such as TLS, GPG and OTR. T

he goal of this book is not to make anyone a cryptographer or a security researcher. The goal of this book is to understand how complete cryptosystems work from a bird’s eye view, and how to apply them in real software.

The exercises accompanying this book focus on teaching cryptography by breaking inferior systems. That way, you won’t just “know” that some particular thing is broken; you’ll know exactly how it’s broken, and that you, yourself, armed with little more than some spare time and your favorite programming language, can break them. By seeing how these ostensibly secure systems are actually completely broken, you will understand why all these primitives and constructions are necessary for complete cryptosystems. Hopefully, these exercises will also leave you with healthy distrust of DIY cryptography in all its forms

This book hopes to be a bridge: to teach everyday programmers from any field or specialization to understand just enough cryptography to do their jobs, or maybe just satisfy their appetite.

...

With all that's been happening in the past weeks, months, years, I thought you might find interesting...

05 May 07:51

Composite UI for Service Oriented Systems – Challenges Part I

by Daniel Marbach

This blogpost is part of a larger blog post series. Get the overview of the content here.

Slide88

Speaking about trade-offs. You’ll face some challenges regarding decomposition. But rest assured composition isn’t a piece of cake either. There are a number of challenges you’ll face and I’m sure there are even more I haven’t discovered yet. But surely you’ll tell me when you stumble over one in your project, don’t you?

For example:

  • How do you handle queries?
  • How do you handle responses which need to be correlated back to the UI?
  • How does a message map to a given User Interface Screen?
  • How do you updates status bars?
  • How shall the system be deployed?
  • How do you do contract sharing?
  • How do you manage dependencies?
  • How dynamic is dynamic enough?

Slide90

For querying just don’t use messages. It is going to get you into more trouble then you’ll benefit from it. Queries need a response as immediate as possible. If you use messaging for queries you’ll need complex synchronization logic on the composite UI to bridge from the asynchronous world of messaging back to the UI. Use precomputed read models (see CQRS and Event Source) or just query the data from the database! Databases scale really well as long as you only read from it. Your autonomous “thing” can divide the data as needed (i.e. separate read from write) and use any storage technology which fits the scalability needs.

Slide91

When responses arrive for a certain message you need to map it back to the UI which triggered the initial request. But wait: Why are you doing request/response style communication? Seriously! Try to talk to the business if this is really necessary. You have all the tools in your tool belt to guarantee delivery, so why on earth does every request need a confirmation? If you nonetheless come up with a business case where you need request/response style communication then please don’t block the UI thread. It is 2014 and we just don’t need to do that! You can use Event Aggregators which are wired up to the controllers or view models. When you send a request you can cache the message id locally. When a correlated message arrives as a response you can use a convention based approach to map from the correlation id to the right screen. And by the way, just don’t use callbacks, they suck! Both from a programming, scalability and maintenance perspective. And if the users insist in having a “synchronous” style behavior on your UI, just trick them as any decent site does (for example Stackoverflow or blog engines).

Slide92

A screen can trigger multiple messages which is fine. Try to design your User Interface with task orientation. What is the intent of the user? This can usually be mapped pretty well to business scenarios which are fully backed up by your carefully chosen “thing” architecture. Microsoft called the task oriented design Inductive User Interface Design. A well-designed inductive interface helps users answer two fundamental questions they face when looking at a screen:

  • What am I supposed to do now?
  • Where do I go from here to accomplish my next task?

A screen with a single, clearly stated, explicit purpose is easier to understand than a page without such a purpose. The following steps help to fulfill this premise:

  1. Focus each screen on a single task
  2. State the task
  3. Make the screen’s contents suit the task.
  4. Offer links to secondary tasks

Talk to your users, get a usability engineer on board, talk with the domain experts, reveal the tasks and mapping messages to UIs will be a breeze!

Slide93

Have you ever seen a progress bar telling you the truth how long an operation might take? I haven’t! Just don’t use them. In my opinion the best User experience in business applications is when a User can actually carry on with his work while a long running operation is started. Why block the user and force him to stare at progress indicators? That time the user could actually do something productive. If you absolutely need to have progress bars then why not fake the duration? Progress bars lie anyways, just make and educated guess or use indeterminate progress bars. But I’m no UI expert. So talk to yours, I’m sure she/he has better answers!

In the next blog post we’ll cover more challenges.

18 Apr 11:25

Introducing GitHubLink: let everyone step through your GitHub code!

by Geert

Last week I have been working on a new project called GitHubLink. It let’s users step through your code hosted on GitHub! This makes symbol servers obsolete which saves you both time with uploading source files with symbols and the user no longer has to specify custom symbol servers (such as symbolsource.org).

GitHubLink_example

The idea is based on the SourceLink project. However it requires FAKE and not everyone likes to write code in F#. GitHubLink is available as console application and can be references as assembly as well to be used in other .NET assemblies.

The advantage of GitHubLink is that it is fully customized for GitHub. It also works with GitHub urls so it does not require a local git repository to work. This makes it perfectly usable in continuous integration servers such as Continua CI.

Updating all the pdb files is very fast. A solution with over 85 projects will be handled in less than 30 seconds.

When using GitHubLink, the user no longer has to specify symbol servers. He/she only has to enable the support for source servers in Visual Studio as shown in the image below:

visualstudio_enablesourceserversupport

How to use it?

Using GitHubLink is very simple:

  1. Build the software (in release mode with pdb files enabled)
  2. Run the console application with the right command line parameters

Below are a few examples:

Running for the default branch

GitHubLink.exe c:\source\catel -u https://github.com/catel/catel

This will use the default branch (which is in most cases master). You can find out the default branch by checking what branch is loaded by default on the GitHub page.

Running for a specific branch

GitHubLink.exe c:\source\catel -u https://github.com/catel/catel -b develop

This will use the develop branch.

Running for a specific branch and configuration

GitHubLink.exe c:\source\catel -u https://github.com/catel/catel -b develop -c debug

This will use the develop branch and the debug configuration.

How to get it?

You can grab the first official release at GitHub:

https://github.com/GeertvanHorrik/GitHubLink/releases

The post Introducing GitHubLink: let everyone step through your GitHub code! appeared first on Geert van Horrik.

16 Apr 06:50

LOB Business Apps - .NET Broker App und Windows Store Apps

by Christian Giesswein

UPDATEMittlerweile geht es auch einfacher

Mit Windows 8.1 Update 1 ist es nun möglich, Side-Loaded Apps (also Apps die am Store vorbei ausgeliefert werden) per „Broker-Mode“ mit einer „alten“ .NET Anwendung interagieren zu lassen. Das bedeutet, für Unternehmenskunden und Unternehmen die eine ganze Reihe an Anwendungen für den In-House Betrieb bereits haben, können die Anwendungen wiederverwenden und dabei sehr schnell eine Windows Store App „herzaubern“ (Stimmt natürlich nur fast..).

Nachdem der gesamte Prozess aber noch sehr undokumentiert und noch sehr viel händisch gemacht werden muss, ein kleines Walkthrough zur Windows Store App mit dem großen .NET Framework und co.

Achtung: Einige Schritte erfordern Administratorenrechte! Visual Studio 2013 also mit Admin-Rechten starten. Weiters wird das Windows 8.1 SDK Benötigt.

Zur Architektur

1)      Eine Windows Runtime Component, die zurechtgebogen wird, damit wir mit .NET arbeiten können. Daraus werden sich im weiteren Verlauf zwei Dinge ergeben:

  • Eine „reference“ Komponente - Quasi – das Interface für die Windows Store App
  • Die Implementierung - Dies hat für mich bereits einiges an Verwirrung gesorgt, da die Dateien ident benannt werden müssen aber unterschiedliche Inhalte haben.

2)      Eine C++ Proxy-DLL die automatisch erzeugt wird aber die Kommunikation zwischen Reference und Implementation übernimmt

3)      Die Windows 8.1 App

Die Reiseroute

Dementsprechend wird es am Ende mindestens drei Projekte geben.

Zuerst müssen wir uns eine frische Solution anlegen und darin eine Windows Runtime Component. Ich habe diese Komponente mal „NETBroker.LegacyCode“ getauft da hier unser alter .NET Code „gehostet“ wird. In diesem Projekt gibt es anschließend zwei simple Dinge, ein Interface und eine Implementierung des Interfaces. Zu Erst muss aber die *.csproj bearbeitet werden. Hierbei müssen folgende Änderungen vorgenommen werden:

1)      In Zeile 18, muss in der ersten ProerptyGroup folgender Eintrag hinzugefügt werden:

<ImplicitlyExpandTargetFramework>false</ImplicitlyExpandTargetFramework>

2)      In Zeile 105, in dem ItemGroup Knoten müssen die .NET Referenzen hinzugefügt werden:

 <ItemGroup>
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\mscorlib.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.ComponentModel.Composition.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Configuration.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Core.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\System.Threading.Tasks.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\System.Runtime.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\System.Runtime.InteropServices.WindowsRuntime.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Xml.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Data.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Windows.winmd" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5.1\System.Runtime.WindowsRuntime.dll" />
</ItemGroup>

Sobald man diese Änderungen übernommen hat, hat man bereits wieder Zugriff auf die .NET Klassen aus den referenzierten Bibliotheken.

Ich habe hier nun folgendes Interface:

[ComVisible(true), Guid("B604ECD3-D034-42C4-B11D-F7E1C8D7F70E")]
public interface ICustomerRepository
{
  IEnumerable<string> GetCustomers();
}

Und folgende Implementierung:

[ComVisible(true), Guid("420541B2-7FF9-4109-BE5B-68BD0351EE41")]
public sealed class CustomerRepository : ICustomerRepository
{
  public IEnumerable<string> GetCustomers()
   {
      using (var sql = new SqlConnection(@"Data Source=(localdb)\Projects;Initial Catalog=Northwind;"))
      {
      sql.Open();
      using (var cmd = sql.CreateCommand())
      {
        cmd.CommandText = "SELECT * FROM CUSTOMERS";
        using (var reader = cmd.ExecuteReader())
        {
           while (reader.Read())
           {
             yield return reader["CustomerId"].ToString();
          }
        }
      }
    }
  }
}

Daher aus einer LocalDB Datenbank per ADO.NET ein SQL-Befehl ausführen und alle Ergebnisse der Kundentabelle zurückgeben (bzw. die IDs davon). Die Klasse als auch das Interface werden jeweils für COM sichtbar gemacht, per Attribute.

Nun steht also unser „legacy“ Code bereits, und wir kümmern uns nun als nächster um den Proxy-Code. Dafür benötigen wir ein simples C++ Projekt. Ich nannte das ganze „NETBroker.Proxy“. Sobald das Template von Visual Studio erzeugt wurde, müssen hier alle Header und CPP-Dateien gelöscht werden. 

So nun wird das ganze etwas knifflig, den C++ Code lassen wir uns vollständig durch Boardmittel erzeugen, dafür ist im .NET Projekt NETBroker.LegacyCode ein POST-Build notwendig.

call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
md "$(TargetDir)impl"
md "$(TargetDir)reference"
erase "$(TargetDir)\impl\*.winmd"
erase "$(TargetDir)\impl\*.pdb"
rem erase "$(TargetDir)\reference\*.winmd"
xcopy /y "$(TargetPath)" "$(TargetDir)impl"
xcopy /y "$(TargetDir)*.pdb" "$(TargetDir)impl"
winmdidl /nosystemdeclares /metadata_dir:C:\Windows\System32\Winmetadata "$(TargetPath)"
midl /metadata_dir "C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral" /iid "$(SolutionDir)NETBroker.Proxy\$(TargetName)_i.c" /env win32 /x86 /h "$(SolutionDir)NETBroker.Proxy\$(TargetName).h" /winmd "$(TargetName).winmd" /W1 /char signed /nologo /winrt /dlldata "$(SolutionDir)NETBroker.Proxy\dlldata.c" /proxy "$(SolutionDir)NETBroker.Proxy\$(TargetName)_p.c" "$(TargetName).idl"
mdmerge -n 1 -i "$(ProjectDir)bin\$(PlatformName)\$(ConfigurationName)" -o "$(TargetDir)reference" -metadata_dir "C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral" -partial
rem erase "$(TargetPath)"

Achtung, hier kommt viermal der Name des C++ Projektes vor, da hier automatisch die Quelldateien hineinkopiert werden. Sobald man nun das NETBroker.LegacyCode Projekt erneut baut, sollte es keinen Fehler mehr geben. Nun hat man aber im C++ Projekt dafür vier neue Dateien:

  • NETBroker.LegacyCode.h
  • NETBroker.LegacyCode_i.c
  • NETBroker.LegacyCode_p.c
  • Dlldata.c

Diese 4 Dateien muss man nun noch in das C++ Projekt einfügen und damit ist der Code-Teil im C++ Reich bereits abgeschlossen – aber Achtung compilieren funktioniert noch nicht. Der Konfigurationsspaß fängt erst an. Nun benötigen wir noch eine DEF-Datei im C++ Projekt, das bedeutet im Projekt erst noch per Rechtsklick eine DEF-Datei erzeugen, und in diese kommen folgende fünf Zeilen:

LIBRARY NETBroker.Proxy.dll
EXPORTS
   DllCanUnloadNow PRIVATE
   DllGetClassObject PRIVATE
   DllRegisterServer PRIVATE
   DllUnregisterServer PRIVATE

Anschließend, müssen im C++ Projekt noch folgende Einstellungen vorgenommen werden:

Danach sollte das Projekt compilieren, oder es wurde ein Fehler gemacht. Nun muss dafür gesorgt werden, dass die Proxy-DLL und die implementierte WINMD Datei (also die größere!) zusammen in einem Verzeichnis liegen, dass im späteren Verlauf von der App verwendet wird. Dafür habe ich mir folgendes Verzeichnis angelegt: C:\WindowsStoreApp. Dementsprechend empfiehlt es sich, beim C++ Projekt eine Projektabhängig einzutragen, und das C++ Projekt erhält auch ein POST-Build:

Dadurch liegen in diesem Verzeichnis immer die aktuellsten Dateien. Daraufhin müssen die Rechte des Verzeichnisses noch korrekt gesetzt werden, d.h. im Windows Explorer per Rechtsklick zur Sicherheit des Ordners.

 

Und zwar benötigen „ALLE ANWENDUNGSPAKETE“ Vollzugriff auf den Ordner damit diese darauf auch zugreifen können. Sobald dies geschehen ist, muss der Proxy nur noch registriert werden per regsvr32. Daher wird eine CMD-Shell (Administratorrechte!) aufgerufen werden, und in das Verzeichnis „C:\WindowsStoreApp“ gewechselt werden. Da erledigt der Befehl:

Regsvr32 NETBroker.Proxy.dll

… den Rest.

Dadurch benötigen wir nun nur noch unsere neue Windows 8.1 App, NETBroker.App und dieser können wir nun eine neue Referenz hinzufügen und zwar auf die reference-Winmd Datei (die kleinere!). Diese befindet sich im Ordner „NETBroker.LegacyCode\bin\x86\Debug\reference“. Eine kleine Änderung im Manifest (Package.appx) ist noch manuell zu tätigen, dafür muss diese mit einem Beliebigen Texteditor geöffnet werden (Notepad++ zum Beispiel).

Am Ende der Datei wird eine kleine „Extension“ benötigt die einerseits bekannt gibt, welche Klasse angefordert wird, und wo diese liegt (C:\WindowsStoreApp).

 <Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>clrhost.dll</Path>
<ActivatableClass ActivatableClassId="NETBroker.LegacyCode.CustomerRepository" ThreadingModel="both">
<ActivatableClassAttribute Name="DesktopApplicationPath" Type="string" Value="C:\WindowsStoreApp" />
</ActivatableClass>
</InProcessServer>
</Extension>
</Extensions

Damit ist man nun bereits am Ende angelangt und kann in der Windows Store App, die Klasse CustomerRepository komplett „normal“ verwenden.

Und daraus wurde eine "einfache" App die ADO.NET (aber vollen Zugriff auf das .NET Framework) verwendet:

Das ganze basiert auf folgendem Paper von Microsoft: http://msdn.microsoft.com/en-us/library/windows/apps/dn630195.aspx sollte wer Fragen oder Tipps haben gern per Mail oder Twitter @giessweinweb. Download

UPDATE:

Nachdem ich mit Harry Pierson von Microsoft ein paar Mails ausgetauscht habe folgende Dinge noch:

  • You don’t need comvisible or guid attributes on the class
  • You don’t need to declare a separate comvisible interface on the class if you don’t want to. If you choose to, you don’t need the com visible attribute but you do still need the guid attribute
  • We have a template coming soon that should make all the manual project file hacking a thing of the past. 

Das heißt es ist auch hierbei etwas im Ofen bei Microsoft.

10 Apr 06:50

Everything you need to know about the Heartbleed SSL bug

by Troy Hunt

Massive. Huge. Catastrophic. These are all headlines I’ve seen today that basically say we’re now well and truly screwed when it comes to security on the internet. Specifically though, it’s this:

The Heartbleed bug allows anyone on the Internet to read the memory of the systems protected by the vulnerable versions of the OpenSSL software.

Every now and then in the world of security, something rather serious and broad-reaching happens and we all run around like headless chicken wondering what on earth it means. Did the NSA finally “get us”? Is SSL dead? Is the sky falling? Well it’s bad, but not for everyone and quite possibly not as bad as many are saying it is. Most of the early news has come via heartbleed.com (a site created by Codenomicon) which, if I may say so, has done an excellent job of standing up a very nice little website and branding the bug:

Heartbleed logo

But it’s actually a lot more complex than the shiny logo suggests. It doesn’t help that it’s not an easy concept to grasp and that alone compounds the confusion and speculation about what the bug really is, what the bug is not and perhaps most importantly, what you need to do about it. I’m going to try and distil the issue into a set of common questions people are asking – Heartbleed in a nutshell, if you like.

What’s OpenSSL and what versions are affected?

Let’s start here: the Heartbleed bug is only present in the OpenSSL implementation of SSL and TLS (note that even whilst not always the same thing, these acronyms tend to be used interchangeably and usually refer to their implementation over HTTP or in other words, HTTPS). As the name suggestions, this is an open source software product that facilitates communication over the SSL protocol and it is extremely common. At the time of disclosure, about 17% of the world’s “secure” websites were said to be vulnerable to the bug.

Typically, OpenSSL implementations are present on servers running Apache and nginx. Unfortunately, Apache remains the dominant web server today with more than half of the internet’s active sites running on it and nginx has about another 14%:

Netcraft server stats

The Heartbleed bug itself was introduced in December 2011, in fact it appears to have been committed about an hour before New Year’s Eve (read into that what you will). The bug affects OpenSSL version 1.0.1 which was released in March 2012 through to 1.0.1f which hit on Jan 6 of this year. The unfortunate thing about this timing is that you’re only vulnerable if you’ve been doing “the right thing” and keeping your versions up to date! Then again, for those that believe you need to give new releases a little while to get the bugs out before adopting them, would they really have expected it to take more than two years? Probably not.

Edit: Note that if you're running a beta of OpenSSL, version 1.0.2 is also vulnerable.

Is it only sites on Apache and nginx that are affected?

Not all web servers are dependent on OpenSSL. IIS, for example, uses Microsoft’s SChannel implementation which is not at risk of this bug. Does that mean that sites on IIS are not vulnerable to Heartbleed? For the most part, yes, but don’t get too cocky because OpenSSL may still be present within the server farm. A case in point: Tim Post from Stack Overflow tweeted this earlier today:

#stackoverflow, heartbeat, we know.

But aren’t they running all ASP.NET MVC on IIS? Yep, they sure are, it’s made very clear in Nick Craver’s excellent post last year on the road to SSL, in fact you can see the (IIS) web servers all sitting over there to the right in this image:

Stackoverflow server farm topology

Wait – is that nginx in there too??? Yeah, about that:

HTTPS traffic goes to nginx on the load balancer machines and terminates there.

You see the problem? Yes, they may be using IIS but no, it doesn’t mean that OpenSSL doesn’t feature in their server farm architecture and indeed it’s sitting out there at the front of everything else terminating the SSL. The same issue exists if a machine acting as a reverse proxy is sitting in front of IIS and running Apache or nginx.

Edit: Nick and Ben from Stack Overflow have clarified that they now use HAProxy for SSL termination which uses… OpenSSL.

Here’s another one, in fact I received this myself last night from AppHarbor regarding ASP.NET hosting I have with them:

AppHarbor notice about Heartbleed

The point is that often server infrastructure is much more than just the web server alone and not consciously running on Apache or nginx doesn’t mean it doesn’t feature in your environment.

Who found it and why make it public?

The first public evidence of the bug appeared as an OpenSSL advisory on April 7 and warns of “A missing bounds check in the handling of the TLS heartbeat extension”. The bug was discovered and reported by Neel Mehta of Google Security and simply states the impacted versions and recommends upgrading OpenSSL or if that’s not feasible, recompiling it and disabling the heartbeats.

As for why it was made public, this is the age old debate of whether public disclosure fast-tracks remediation or opens vulnerable systems up to attack. Probably a bit of both, the problem with a risk like this as opposed to a single discrete vulnerability on a website is that in order to fix it you need mass uptake of the revised version and until the risk gets socialised, that’s not going to happen. You then have this problem where it only takes one party with malicious intent to start running rampant against sites that are entirely ignorant of the risk and you’ve got a really serious problem.

Regardless, you can’t argue with the focus it’s getting now or the speed with which many are now remediating vulnerable sites. Of course there’ll be others that lag behind and they’ll be the ones at serious risk, let’s take a look at just what that could mean for them.

What’s an SSL heartbeat?

Let’s first understand the feature that this bug has made its way into. The bug we’re talking about here exists in OpenSSL’s implementation of the heartbeat extension, a feature described by the IETF as follows:

The Heartbeat Extension provides a new protocol for TLS/DTLS allowing the usage of keep-alive functionality without performing a renegotiation and a basis for path MTU (PMTU) discovery for DTLS.

In other words, it’s a heartbeat in the same vein as we commonly know it in other aspects of computer systems, namely it’s a check to see if the other party is still present or if they’ve dropped off. When they’re still there, the heartbeat keeps the context between the peers alive hence the “keep-alive” nomenclature. In the context of SSL, the initial negotiation between the client and the server has a communication overhead that the heartbeat helps avoid repeating by establishing if the peer is still “alive”. Without the heartbeat, the only way to do this is by renegotiation which in relative terms, is costly.

How is the risk exploited? And how was it fixed?

There’s plenty of proof of concept code around already, I particularly like Rahul Sasi’s example in his Heartbleed Attack POC and Mass Scanner as he clearly explains the vulnerable code, the fix and what he’s written to test the bug. In short, the original risk in OpenSSL all boils down to this line of code:

buffer = OPENSSL_malloc(1 + 2 + payload + padding);

As Rahul explains:

In the above code memory is allocated from the payload + padding with a user controlled value. There was no length check for this particular allocation and an attacker could force the Openssl server to read arbitrary memory locations.

In other words, an attacker can control the heartbeat size and structure it to be larger than expected, fire it off to the target server using TCP on port 443 and receive a response that contains up to 64kb data in a memory allocation outside the bounds of what the heartbeat should be able to access. Do it again with a different heartbeat size, get another 64kb response from another memory space. Lather, rinse, repeat. Easy peasy.

You can go and inspect the code and the consequent fix in this commit on GitHub if you want to get down into the nitty gritty but in short, the payload is now “bound checked” (it can’t exceed 16 bytes) and the entire heartbeat is now validated to ensure it does not exceed the maximum allowable length. Ultimately this boiled down to a very simple bug in a very small piece of code that required a very small fix. Now it just needs to be installed on half a million vulnerable websites.

What’s the risk? What goes wrong if it’s exploited?

Let’s begin with the techie description courtesy of Wikipedia:

missing bounds check in the handling of the TLS heartbeat extension can be used to reveal up to 64k of memory to a connected client or server

Ok, but what does that actually mean? It means an attacker can do stuff like this:

Do not login to Yahoo! The OpenSSL bug #heartbleed allows extraction of usernames and plain passwords!

In case the gravity of this is not clear, what’s being asserted here is that Mark was able to read the credentials of another user (in this case "agnesaduboateng@yahoo.com" and their password which has been obfuscated) directly from memory in Yahoo’s service and he’s done all that remotely just by issuing an SSL heartbeat. Whoa.

More specifically, we’re looking at what was an encrypted HTTPS request to Yahoo’s website (inevitably a POST request to the login page), and we’re seeing a component of that request that was still resident in memory when Mark exercised the exploit and pulled the data. So what else can an attacker gain access to via this bug? Credentials are one thing, but of course this is just by virtue of them occupying memory space which is inevitably but one piece of data in there. Another is the session ID or auth token; even if you can’t pull a user’s credentials via the bug (it’d have to still be in memory at the time), you can still pull the ID that persists their session across requests and consequently enables the attacker to hijack that session and impersonate the user.

The other really serious piece of data that could be pulled is the private key of the certificate. I’m going to repeat precisely what heartbleed.com summarises with regards to leaked primary key material because they summarise it so eloquently:

These are the crown jewels, the encryption keys themselves. Leaked secret keys allows the attacker to decrypt any past and future traffic to the protected services and to impersonate the service at will. Any protection given by the encryption and the signatures in the X.509 certificates can be bypassed. Recovery from this leak requires patching the vulnerability, revocation of the compromised keys and reissuing and redistributing new keys. Even doing all this will still leave any traffic intercepted by the attacker in the past still vulnerable to decryption. All this has to be done by the owners of the services.

Don’t miss the severity of that piece around past interception; the exposure of the private key presents the opportunity to decrypt data that was previously sent over the wire before this vulnerability was even known. If someone was to have been storing these pcaps (*cough* NSA *cough*) and they’ve then been able to pull the keys by exploiting this bug, all your previous data are belong to them.

It can be that bad. In theory – but then there’s this:

Heap allocation patterns make private key exposure unlikely for #heartbleed #dontpanic.

Remember Neel? Yeah, he’s the guy that found the bug to begin with. Is he right and everyone else is wrong? Maybe. Maybe not:

@bengrubb We're very certain. #heartbleed

What about Codenomicon – remember them too? They’re the guys who created the heartbleed.com website I keep referring to which has become such a canonical reference for the bug.

Regardless of whether keys are or are not remotely accessible, there’s still all that other addressable memory that leads to exposed credentials and session IDs. Then there’s all the other data in the HTTPS comms that you really don’t want being remotely and anonymously accessible, it’s just a question of whether the bug also compromises the certificates themselves and there are enough whispers of people having been able to do that to plan for the worst and hope for the best.

How do you tell if a site is vulnerable?

The easiest way to test this remotely is to jump on over to the Heartbleed test page created by Filippo Valsorda. A vulnerable site looks like this:

Heartbleed test page

Ok, so what are we looking at here? Filippo has kindly open sourced the code on GitHub so we can take a peek inside. In short, he’s simply committing the string “YELLOW SUBMARINE” to the padding of the heartbeat (go back to the earlier piece by Rahul Sasi for context), sending the heartbeat off then watching to see if it appears in the response. There’s a bit more to it than that, but you get the idea.

Why did it take 2 years to find the risk – isn’t open source “secure”?!

The theory goes like this – “Open source software is more secure because the community can inspect it and identify bugs much earlier”. The key word in that statement, of course, is can, not will.

The OpenSSL project on GitHub has over 10,000 commits spanning 21 contributors and 25 branches across 57MB of source code. It’s not huge, but there’s enough in there and the bug is obscure enough in retrospect that it went unnoticed until now. We think – perhaps others noticed earlier on and exploited it. Speaking of which…

Is the NSA / GCHQ / Russian Mafia in on it?

Yes. Next question?

Seriously though, we’ve now got an insight into the extent that governments will go to in order to intercept and decrypt private communications en masse and without targeting (and don’t for a moment think it’s just the US doing this – have we forgotten China et al already?!), can you imagine how attractive this would be to organisations that have been performing mass packet captures? If indeed it is possible to pull private keys remotely from servers, this would be an absolute goldmine and it’s a hell of a lot easier than some of the things we now know the governments have been up to.

Governments are one things, what about career criminals? One of the worrying things about this risk is the ease with which it can be automated. We’re already seeing this happen both for good (mass testing of an organisation’s web assets) and bad (mass testing of another organisation’s web assets). That it can be done remotely, expeditiously and by enumerating through multiple hosts makes it all the more attractive and I’ll be massively surprised if criminals haven’t already weaponised this into a mass data exfiltration tool.

Will reissuing certs fix the problem?

Yes and no. Firstly, there’s no point in doing this until you first patch the servers OpenSSL is running on otherwise you’re simply putting a brand new cert at risk.

Moving on, if you work on the assumption that private keys on vulnerable sites have been compromised (and that’s the safest assumption if you’re being cautious), then yes, certificates should be reissued and the old ones revoked. But here’s the problem with revocation – check out Chrome’s default setting:

Chrome will not check for revoked certificates by default

Yeah, no default check for revoked certs in Chrome. How about Internet Explorer:

Internet Explorer *does* check for revoked certificates by default

Yes, that’s the default setting and it has been since IE 7. But of course Chrome now has the lion’s share of the browsing audience so whilst reissuing the cert and revoking the old one is a good move where vulnerable versions of OpenSSL have been present, that’s not necessarily going to stop clients from trusting revoked certs. Nasty.

But beyond just the technical logistics of how revoked certs are validated (or not), there’s also the cost impact. Usually, certs cost money. Sometimes cert revocation costs money. As friend and all round smart security guy Casey Ellis said this morning, there are a whole bunch of cert vendors sitting around doing this right now:

Dumb and Dumber - happy!!!

There’s rarely a serious security incident without big opportunities being presented to players in the security industry.

How do you tell if you’ve already been compromised?

Yeah, about that – you can’t simply trawl back through the usual logs on find traces of a compromise. Again from heartbleed.com:

Exploitation of this bug leaves no traces of anything abnormal happening to the logs.

The problem is that this bug isn’t exploited via channels that would typically be logged. If, for example, you get pwned by a SQL injection vulnerability then your web server logs are full of dodgy HTTP requests. Of course this then raises a very uncomfortable question: if your site was vulnerable, do you work on the assumption that you’ve been compromised?

There’s a whole range of things that need to fall into place for an attack to have been successful (see the final section of this blog) but nonetheless, it’s going to leave a lot of companies in a very tricky position when they know that both the potential for exploit and the knowledge of how to do it were both out there. Take Yahoo for example – what should they do in light of Mark’s documented example? Force everyone to reset their passwords? Tell customers their data may have been compromised? It’s a very, very dicey situation for them to find themselves in.

Can attacks be identified by intrusion detection / protection systems?

Possibly, and I’ve seen evidence that it may already be happening plus various IDS providers are starting touting blocking capability. For example, the Bro Network Security Monitor claims that:

Bro can detect this attack in several different ways. In the simplest incarnation, which is the only one we have seen in the wild so far, the heartbeat message is sent very early, before the TLS encryption kicks in.

In these cases, Bro just compares the payload and message sizes. If there is a mismatch, we know that an exploit has been tried. If the server responds to the message it very probably was vulnerable to the attack.

Of course there’s also the risk that an overzealous IPS (Intrusion Protection System such as Snort) may block heartbeat requests altogether (a risk heartbleed.com refers to), but frankly, if the site is indeed vulnerable to the risk then that’s not a bad position to be in and it’s the same end result as recompiling OpenSSL with heartbeats disabled. Yes, it may do unpleasant things to your perf for a little bit, but the possible alternative is much, much worse.

If you’re running an IPS and you’ve not been able to patch the underlying risk then it’s worthwhile taking just a little look at whether signatures may be available to mitigate the problem in the interim.

What’s impacted beyond just HTTPS?

Anything that has an OpenSSL dependency which could include VPN implementations, instant messaging clients, email and a bunch of other things I almost certainly haven’t thought of. Just because you’re not seeing HTTPS in the address bar doesn’t mean you don’t have a risk.

Does perfect forward secrecy fix all this?

Yes, but not retrospectively and only the potential risk of exposed keys, not the scenario where memory contents are exposed. The idea of perfect forward secrecy is that the exposure of one key shouldn’t bring the whole house of cards crashing down:

Public-key systems which generate random public keys per session for the purposes of key agreement which are not based on any sort of deterministic algorithm demonstrate a property referred to as perfect forward secrecy. This means that the compromise of one message cannot lead to the compromise of others, and also that there is not a single secret value which can lead to the compromise of multiple messages.

In the context of Heartbleed, if the private key can be pulled from memory it wouldn’t lead to the compromise of every single message as they’d be uniquely keyed. But again, this is something that you put in place now for the future, it’s not a solution to Heartbleed, it’s too late for that.

I’m a sys admin – what do I do?

If you’re responsible for maintaining the infrastructure and web server on which sites run, there’s a one clear immediate step: update your OpenSSL to version 1.0.1g as a matter of priority. If that’s not feasible, you can recompile OpenSSL and have it disable the heartbeat with this switch:

-DOPENSSL_NO_HEARTBEATS

As I explained earlier though, heartbeats serve a purpose and turning them off may have a perf impact so treat that as stop gap only.

The next steps depend on your risk aversion or paranoia level depending on how you look at it. That and the value of the information you’re protecting. Those steps may also be the domain of the developer and could include:

  1. Reissuing any impacted certificates
  2. Revoking any impacted certificates
  3. Looking at the availability of blocking malicious heartbeat requests at the IPS level
  4. Expiring any active user sessions
  5. Forcing password resets on any user accounts

This is the advice I’ve received from AppHarbor with regards to my websites hosted with them (although I’ve added the point on the IPS) and whilst you could argue that this is erring on the safe side, you could also argue that’s precisely what we should be doing just now.

I’m a developer – what do I do?

First of all, make sure you’ve read the previous section for sys admins. Many developers find themselves doing all sorts of stuff that’s theoretically the domain of server people who get their hands dirty making all the infrastructure work for the rest of us.

The frustrating part for me as someone who tries very hard to bridge the gap between development and security disciplines is that this bug means I can no longer simply say “Developers, focus on implementing SSL in your web apps and don’t worry about the underlying protocol”. Of course you still want to make sure that SSL is configured appropriately to begin with (have a go of the Qualsys SSL Labs test for a free check), but it’s no longer just a matter of getting that right from the outset then proceeding to focus solely on marking cookies as secure and not loading login pages over HTTP and so on and so forth.

One extremely pragmatic piece of advice I can give is simply this: don’t collect or store what you don’t need. I recently had to deal with an incident involving the collection of registrants’ religion, a piece of very sensitive data to many people and this was in a foreign country that’s not always particularly tolerant if your world view doesn’t line up with theirs. Why did they need it? They didn’t, it just “seemed like a good idea at the time”. You can’t lose what you don’t have and that approach will protect data not just from exposure via Heartbleed, but from SQL injection attacks and insecure direct object references and session hijacking and a whole bunch of other nasties that have the potential to exploit customer data.

I run an online service – what do I do?

The thing to consider now is what damage could be done by an attacker if they’ve been able to obtain user credentials, sensitive data or hijack sessions. What could an attacker access if they were logged in as a user? What could they authorise? What could they then do with that information?

One of the biggest problems here is that you’re almost certainly not going to be able to tell if you’ve been compromised. You can tell if you were at risk and know that you’ve been left vulnerable, but you can only speculate about the window of vulnerability. You don’t know when an attacker first became aware of that risk – it was only socialised in the last couple of days, but it was introduced more than two years ago. Even if it only took you hours to patch, was enough time to be exploited?

The most cautious approach in the security sense is to force password resets and explain to customers that there may have been “an incident”. That’s not a pleasant experience for you nor for your customers and there's a trade-off to be considered between what makes sense security wise and what the impact on trust and the general user experience might be. It’ll be a case-by-case decision and it won’t be easy.

What do I tell my non-technical friends to do?

Break out the tinfoil hats? Turn off all their things? Take a break on a desert island until things calm down? This is one of those things where consumers won’t be the ones that need to take direction action in relation to the bug, at least not in the same way as, say, the goto bug in iOS recently which resulted in an update to the OS. They’re not the ones patching bad OpenSSL on web servers (although we’re yet to see if this risk may impact clients with OpenSSL dependencies).

On the other hand, they may need to take action if the bug has resulted in the exposure of their credentials or other personal data. Ideally this will be advice given to them by websites that have reason to believe there may have been a compromise, that is if they’re proactive enough to identify the risk and (arguably) responsible enough to advise their customers to take preventative action. It’s also an activity that should only be performed after a vulnerable site is patched and a new certificate installed – it’s no good going and putting a shiny new password into a site that may still expose it to an attacker.

Of course it also serves as another valuable reminder to consumers – The only secure password is the one you can’t remember. This is an oldie but a goodie and the premise remains the same; we must always make the assumption that passwords will eventually be compromised and that they must be both strong and unique which means that committing them to memory – human memory – is out. Two factor is another biggie and you want to make sure this is turned on at every possible location (Dropbox, GitHub, Evernote, Microsoft Live ID, etc). This won’t all solve the problems of Heartbleed, but it’s about the extent to which consumers can influence it.

But is it really that bad? And what happens next?

Multiple things have to line up in order for this bug to lead to successful exploitation:

  1. The site has to implement SSL in the first place – no SSL means no OpenSSL means no Heartbleed bug.
  2. The site has to be running OpenSSL. That rules out a significant chunk of the internet, including most IIS websites.
  3. The OpenSSL version has to be somewhere between 1.0.1 and 1.0.1f; anything older or newer and the bug isn’t present.
  4. An attacker needs to have had access to an at-risk environment somewhere between learning of the bug and it being patched by the provider.
  5. If all these things line up, there must have been something useful and retrievable from memory at the time of the attack. That’s highly likely in all but the most dormant sites.
  6. But regardless of current site activity, if the attacker had previous pcaps of traffic (hello again, NSA!) and could then pull the private key from the site, that’s a serious problem.

The problem, of course, is that whilst points 1 through 3 are clearly definable, in most cases we’ll have no idea of whether points 4 and on actually happened. How long did an attacker know about the risk before it was patched? Were they then able to gain access to the server? Was there anything useful in memory at the time? Or could they use exfiltrated keys against prior data captures?

It’s very early days right now and a number of different things could happen next. One likelihood is that we’ll see impacted sites requesting password resets; Mark showed how Yahoo is vulnerable, surely they can’t not now ask people to reset their passwords? I don’t mean to call out Mark specifically either, a quick trawl through pastebin shows extensive public documentation of vulnerable sites. Or how about all those on the list of the Alexa Top 10,000 that have all been tested and many shown to be vulnerable? That’s a very big list and in fact the password resets are already happening, I received this one today from AppHarbor:

AppHarbor password reset email

Of course the other risk is that we’ll see exploitation of credentials that have been pulled from vulnerable sites. This could take on many forms; we’ve seen Acai Berry spam on Twitter after the Gawker breach and many significantly more serious events as a result of stolen credentials. The problem now is that every time an account is compromised by stolen credentials the question is going to be asked: “Were these popped from a vulnerable site via Heartbleed”? This bug could have a very, very long tail.

30 Mar 16:42

#1,039 – Intercepting Bad Date Strings Entered into a DatePicker

by Sean

When a user manually enters a date into a DatePicker, the DatePicker control automatically checks to see whether what they entered is a valid date.  If the date is valid, it’s converted to the proper display format and the DatePicker’s SelectedDate property is set.

If the date is not valid, the DatePicker by automatically reverts to the last valid string contained in this field, or to an empty string.

You can react to the user entering an invalid date by handling the DateValidationError event.

For example, if we have a bindable string property ErrorMessage, we can do the following:

        <Label Content="Pick a date:" Margin="5"/>
        <DatePicker Margin="5,0,5,5"
                    DateValidationError="DatePicker_DateValidationError"
                    SelectedDateChanged="DatePicker_SelectedDateChanged"/>
        <TextBlock Margin="5" Text="{Binding ErrorMessage}"
                   Foreground="Red"
                   TextWrapping="Wrap"/>

Code-behind:

        private void DatePicker_DateValidationError(object sender, DatePickerDateValidationErrorEventArgs e)
        {
            ErrorMessage = e.Exception.Message;
        }

        private void DatePicker_SelectedDateChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            ErrorMessage = "";
        }

1039-001
1039-002


Filed under: Controls Tagged: Controls, DatePicker, Validation, WPF
10 Mar 16:26

Upcoming (Mostly Free) SQL Server Training Events

by Brent Ozar

Tired of giving your boss dumb looks when she asks you a tough SQL Server question? Let’s fix that – get yourself registered for any of these upcoming events. Most of ‘em are free, and many of ‘em are virtual so you can attend at work:

Kendra Little

Mar 11

How to Get Your First DBA Job

Triage Tuesday 30 minute Webcast starting at 11:30 AM Central
You’d love to become a Database Administrator, but how do you get your foot in the door? Ten years ago, Kendra Little was in your position. Since then, she landed her first job as a SQL Server DBA, worked her way up to Senior DBA, and is now a partner in a database consulting company. Along the way, she’s hired Junior and Senior DBAs and she helps employers develop interview procedures for database administrators. In this 30 minute session you’ll learn what employers look for, steps you can take to make yourself a great candidate, and how to build the right resume to get your first DBA job. Register now.


Brent Ozar

March 11

Your Database Server is a Loser

Sponsored by Dell – 1 Hour Webcast starting at 1PM Central, 2PM Eastern
If your database server goes down at a certain date/time, it’s likely to lose much more data. If you’re responsible for making sure SQL Server doesn’t lose data, you need to understand how your backup schedule really works. You can’t just monitor for backup job success – you have to learn how to query MSDB to check your risk exposure. Microsoft Certified Master Brent Ozar will explain:

  • Where SQL Server stores RPO/RTO data
  • How to query it to find out how much data you’ll lose
  • How to monitor it going forward to protect your job

Register now.


Brent Ozar

March 12

Philadelphia SQL Server User Group:
How to Think Like the SQL Server Engine

You’re a developer or a DBA, and you’re comfortable writing queries to get the data you need. You’re much less comfortable trying to design the right indexes for your database server. In this 90-minute session with Microsoft Certified Master Brent Ozar, you’ll role play as the database engine while Brent gives you queries. You’ll learn first-hand about clustered indexes, nonclustered indexes, execution plans, sargability, statistics, TempDB spills, and T-SQL anti-patterns. Register here.


Brent Ozar

March 13

PASS DC (Chevy Chase) User Group:
How to Think Like the SQL Server Engine

You’re a developer or a DBA, and you’re comfortable writing queries to get the data you need. You’re much less comfortable trying to design the right indexes for your database server. In this 90-minute session with Microsoft Certified Master Brent Ozar, you’ll role play as the database engine while Brent gives you queries. You’ll learn first-hand about clustered indexes, nonclustered indexes, execution plans, sargability, statistics, TempDB spills, and T-SQL anti-patterns. Register here.


Brent Ozar

March 14

Richmond SQL Server User Group:
How to Think Like the SQL Server Engine

You’re a developer or a DBA, and you’re comfortable writing queries to get the data you need. You’re much less comfortable trying to design the right indexes for your database server. In this 90-minute session with Microsoft Certified Master Brent Ozar, you’ll role play as the database engine while Brent gives you queries. You’ll learn first-hand about clustered indexes, nonclustered indexes, execution plans, sargability, statistics, TempDB spills, and T-SQL anti-patterns. Register now.


Jes Schultz Borland

March 18

Don’t Fear the Execution Plan

Triage Tuesday 30 minute Webcast starting at 11:30 AM Central
Have you ever been curious about how SQL Server returns the results of your queries to you? Have you ever opened an execution plan but been bewildered by the results? Have you dabbled in query tuning, but weren’t sure where to focus your efforts? Join Jes as she takes you through the basics of execution plans. She’ll show you how to read them, how to spot common problems, how to spot help, and tools that will make your job easier. Register now.


Brent Ozar

March 25

Get to Know Our Free SQL Server Scripts

Triage Tuesday 30 minute Webcast starting at 11:30 AM Central
You’ve heard about sp_Blitz®, sp_BlitzIndex®, sp_AskBrent®, and our First Responder Kit, but you’ve never gotten around to using them yourself. Brent will demo all of them, show you how to use them effectively, and take your questions and ideas about what you’d like to see added to them. Register now.


Brent Ozar

March 26

How to Get Ready for SQL Server 2014

Dell 1-Hour Webcast starting at 1:00PM Central
Stay one step ahead of the significant changes coming to SQL Server. Even if you’re not using SQL Server 2014 yet — heck, maybe you’re not even using SQL Server 2012 — this webcast is something you shouldn’t miss, whether you’re a DBA or a developer.. If you learn about the new ways SQL Server stores data, you can start making your apps and databases 2014-friendly today. Register now.


Kendra Little

Apr 1

World’s Worst Performance Tuning Techniques

Triage Tuesday 30 minute Webcast starting at 11:30 AM Central
Could your attempts to improve performance be slowing down your SQL Server? Learn which performance tuning techniques have hidden pitfalls in this free 30 minute talk by Microsoft Certified Master Kendra Little. Register now.


Brent Ozar

April 11-12

SQLSaturday #267 Lisbon, Portugal

Brent is flying across the pond to go visit one of the best-regarded SQLSaturdays in Europe. He’s doing:

Virtualization, Storage, and Hardware for SQL Server (Pre-Con) – You’re a DBA who manages SQL Servers, and you’re frustrated with slow performance. The VMware and SAN admins tell you it must be a SQL Server problem, but you’re not so sure. Microsoft Certified Master Brent Ozar went through the same problems, and he decided to go behind enemy lines. He became a SAN admin and VMware admin, learned how to tie these parts together, and figured out how to configure both sides of it to work well. This all-day pre-conference session is 100€. Seats are limited – register now.

How to Think Like the Engine – You’re a developer or a DBA, and you’re comfortable writing queries to get the data you need. You’re much less comfortable trying to design the right indexes for your database server. In this session with Microsoft Certified Master Brent Ozar, you’ll role play as the database engine while Brent gives you queries. You’ll learn first-hand about clustered indexes, nonclustered indexes, execution plans, sargability, statistics, TempDB spills, and T-SQL anti-patterns. (This is a regular session at SQLSaturday Lisbon.)

Real-Life SQL 2012 and 2014 Availability Group Deployments – You want to deploy AlwaysOn, but you’re concerned about hidden drawbacks, performance impacts, and how it affects development. Brent Ozar has deployed SQL 2012 and SQL 2014 Availability Groups at big web sites including StackOverflow.com and the Discovery Channel, plus used it to scale out reads at data warehouses. Come learn what he’s found in real-life deployments of AlwaysOn.

Register for SQLSaturday Lisbon.


Brent Ozar Jeremiah Peschka Kendra Little

April 13-16, 2014

SQL Intersection Spring

This spring, you can join us in Orlando, Florida for a pre-con, sessions, and a post-con focused on developer and architect topics:

Pre-Con: Developer’s Guide to SQL Server Operations with Jeremiah Peschka and Kendra Little – You’re a developer who has to administer SQL Servers, but you’ve never had formal training. You’re not entirely sure what’s going on inside this black box, and you need a fast education on how SQL Server works. In one day, you’ll learn how to make your SQL Server faster and more reliable. You’ll leave armed with free scripts to help you find health problems and bottlenecks, the knowledge to avoid common pitfalls, and a plan to get SQL Server under control.

Post-Con: Make SQL Server Apps Go Faster with Brent Ozar, Jeremiah Peschka, and Kendra Little – You’re a developer or DBA stuck with a database server that’s not going fast enough. You’ve got a hunch that the biggest bottleneck is inside the database server somewhere, but where? In just one day, you’ll learn how to use powerful scripts to identify which queries are killing your server, what parts of the database server are holding you back, how to tackle indexing improvements, and how to identify query anti-patterns.

Conference Sessions:

  • Defining a Data Strategy – Jeremiah – If you’ve worried about outgrowing your current database or wasting countless hours moving to the wrong data platform, listen up. There is an overwhelming array of database options on the market, knowing which to pick is difficult. Before jumping in, it’s important to have a list of questions to make your decision easier. In this session, we’ll cover a set of questions to get your team started in the decision making process. This session is for senior developers and software architects looking to expand their horizons.
  • Developers: Who Needs a DBA? (200) – Brent – You store data in SQL Server, but you don’t have enough work to keep a full-time DBA busy. In just one session, you’ll learn the basics of performance troubleshooting, backup, index tuning, and security. Brent Ozar will teach you the basic care and feeding of a Microsoft SQL Server 2005, 2008, or 2012 instance and give you scripts to keep you out of trouble.
  • Find and Fix Your Worst Query Patterns (300) – Kendra – You’d love to make your queries faster, but you’re not sure what to change. Kendra Little will teach you how to identify bad patterns in the execution plans of the biggest, baddest queries running against your SQL Server. You’ll see Kendra triage bad queries in action and get an easy-to-use reference you can use to diagnose problems in your query execution plans back at work.
  • Hadoop By Example – Jeremiah – By now you’ve probably heard the words “Big Data” and “Hadoop”, but you’re not sure what they mean, much less how to get started. Maybe you’re struggling with storing a lot of data, rapidly processing a huge volume of data, or maybe you’re just curious. There are a bewildering array of options and use cases within the Hadoop ecosystem. Every day I help customers understand their data problems, understand where Hadoop fits into their environment, and determine how they can use Hadoop to solve their problem. This session provides an introduction to the components of Hadoop, a discussion of when it’s appropriate to use Hadoop, and examples to help you get started.
  • How to Attract and Hire Top Talent (200) – KendraYou need to hire a talented SQL Server developer or DBA, but you don’t know a clock hand from a lock escalation. Kendra Little will teach you how to write a job description that attracts the right candidates, and which anti-patterns cause experienced applicants to look elsewhere. You’ll learn how to filter out unqualified candidates–even if you’re not a SQL Server expert–while asking questions that make the best data professionals eager to join your team.
  • How to Tune Queries (300) – Brent – You’re in a dark room with an ugly query. What do you do next? Microsoft Certified Master Brent Ozar shares his time-tested method of tuning queries starting with simplifying, analyzing the execution plan, making index tweaks, and measuring improvements with statistics. You’ll learn a repeatable process you can use to make queries go faster.
  • Increase Application Concurrency with Optimistic Locking (200) – Kendra – You need to scale up a transactional application using SQL Server–without being dragged down by locking and blocking. Kendra Little will teach you how to use optimistic locking to increase throughput while keeping performance fast.
  • Scale Out! Scale Out! An Introduction to Riak – Jeremiah – Developers have a lot of choices when it comes to storing data. In this session, we’ll introduce .NET developers to Riak, a distributed key-value database. Through a combination of concepts and practical examples, attendees will learn when Riak might be appropriate, how to get started with Riak using CorrugatedIron (a full-featured .NET client for Riak), and how to solve data modeling problems they’re likely to encounter. This talk is for developers who are interested in backing their applications with a fault-tolerant, distributed database.
  • Think Like the Engine: SQL Server for Developers (200) – Brent – You’re comfortable writing queries to get the data you need, but you’re much less comfortable trying to design the right indexes for your database server. In this class with Microsoft Certified Master Brent Ozar, you’ll learn how SQL Server uses clustered indexes, nonclustered indexes, and statistics to build execution plans.
  • The Art of Search – Jeremiah – Are you sick of full table scans caused by `LIKE` queries? Are the users clamoring for additional functionality in searches that will bring your database server to its knees? Or, worse, require an upgrade to Enterprise Edition? In session, Jeremiah Peschka will introduce attendees to the SOLR search engine. We’ll look at ways to index and search information, create complex searches, and keep SQL Server performing well. This session is for anyone who is interested in taking their search functionality to a different level.

Register now.


Jes Schultz Borland

April 8

What the Execution Plan Doesn’t Tell You

Triage Tuesday 30 minute Webcast starting at 11:30 AM Central
The execution plan is a gold mine of information about how your query performed. You can tell the steps that were taken, the number of rows that were processed, and even get index or statistics hint. But what isn’t the execution plan telling you? Jes will show things that you might not realize are problems – and how to fix them! Register now.


Doug Lane

April 15

The Developers Guide to Understanding DBAs

Triage Tuesday 30 minute Webcast starting at 11:30 AM Central
Developers, when your DBA asks how much memory your new SQL Server needs, do you know how to answer? Do you worry about the DBA judging your code? In this free 30-minute session, join Doug Lane to learn what really matters to DBAs and what they expect you to know. Register now.


Jeremiah Peschka

April 22

Introduction to Extended Events

Triage Tuesday 30 minute Webcast starting at 11:30 AM Central
Extended Events were introduced with SQL Server 2008R2. Extended Events is a replacement for Server Side Traces and so much more – it’s a lightweight way to look at SQL Server performance, events, deadlocks, locking, blocking, and more. In this webcast, Jeremiah Peschka provides a high-level introduction to Extended Events. You’ll learn about how Extended Events are structured, how to find out what’s available, and where to get started. Register now.


Brent Ozar

April 26

SQLSaturday Chicago

The sessions haven’t been picked yet, but Brent’s fingers are crossed that he’ll be one of the chosen ones. You can register now.


Brent Ozar

June 4

FoxPASS Northeast Wisconsin:
Troubleshooting Shared Storage for DBAs

Your SQL Server’s data lives on the SAN, and you’re not happy about that. All the Perfmon metrics you gather seem to point to a storage problem, but the SAN admin says the storage is sitting around bored, so it must be a SQL Server problem. Brent Ozar feels your pain – years ago, he was a DBA in the same position, so when his SAN admin quit, Brent took the job. In just 90 minutes, he’ll teach you what’s inside the SAN, why multipathing is so important, how to test storage throughput, and why TempDB should be on local SSDs.

When it's time to troubleshoot an outage, start with our First Responder kit.

27 Feb 13:36

The WhatsApp Architecture Facebook Bought For $19 Billion

by Todd Hoff

Rick Reed in an upcoming talk in March titled That's 'Billion' with a 'B': Scaling to the next level at WhatsApp reveals some eye popping WhatsApp stats:

What has hundreds of nodes, thousands of cores, hundreds of terabytes of RAM, and hopes to serve the billions of smartphones that will soon be a reality around the globe? The Erlang/FreeBSD-based server infrastructure at WhatsApp. We've faced many challenges in meeting the ever-growing demand for our messaging services, but as we continue to push the envelope on size (>8000 cores) and speed (>70M Erlang messages per second) of our serving system.

But since we don’t have that talk yet, let’s take a look at a talk Rick Reed gave two years ago on WhatsApp: Scaling to Millions of Simultaneous Connections.

Having built a high performance messaging bus in C++ while at Yahoo, Rick Reed is not new to the world of high scalability architectures. The founders are also ex-Yahoo guys with not a little experience scaling systems. So WhatsApp comes by their scaling prowess honestly. And since they have a Big Hairy Audacious of Goal of being on every smartphone in the world, which could be as many as 5 billion phones in a few years, they’ll need to make the most of that experience.

Before we get to the facts, let’s digress for a moment on this absolutely fascinating conundrum: How can WhatsApp possibly be worth $19 billion to Facebook?

As a programmer if you ask me if WhatsApp is worth that much I’ll answer expletive no! It’s just sending stuff over a network. Get real. But I’m also the guy that thought we don’t need blogging platforms because how hard is it to remote login to your own server, edit the index.html file with vi, then write your post in HTML? It has taken quite a while for me to realize it’s not the code stupid, it’s getting all those users to love and use your product that is the hard part. You can’t buy love

What is it that makes WhatsApp so valuable? The technology? Ignore all those people who say they could write WhatsApp in a week with PHP. That’s simply not true. It is as we’ll see pretty cool technology. But certainly Facebook has sufficient chops to build WhatsApp if they wished.

Let’s look at features. We know WhatsApp is a no gimmicks (no ads, no gimmicks, no games) product with loyal users from across the world. It offers free texting in a cruel world where SMS charges can be abusive. As a sheltered American it has surprised me the most to see how many real people use WhatsApp to really stay in touch with family and friends. So when you get on WhatsApp it’s likely people you know are already on it, since everyone has a phone, which mitigates the empty social network problem. It is aggressively cross platform so everyone you know can use it and it will just work. It “just works” is a phrase often used. It is full featured (shared locations, video, audio, pictures, push-to-talk, voice-messages and photos, read receipt, group-chats, send messages via WiFi, and all can be done regardless of whether the recipient is online or not). It handles the display of native languages well. And using your cell number as identity and your contacts list as a social graph is diabolically simple. There’s no email verification, username and password, and no credit card number required. So it just works.

All impressive, but that can’t be worth $19 billion. Other products can compete on features.

Google wanted it is a possible reason. It’s a threat. It’s for the .99 cents a user. Facebook is just desperate. It’s for your phone book. It’s for the meta-data (even though WhatsApp keeps none).

It’s for the 450 million active users, with a user based growing at one million users a day, with a potential for a billion users. Facebook needs WhatApp for its next billion users. Certainly that must be part if it. And a cost of about $40 a user doesn’t seem unreasonable, especially with the bulk paid out in stock.  Facebook acquired Instagram for about $30 per user. A Twitter user is worth $110.

Benedict Evans makes a great case that Mobile is a 1+ trillion dollar business, WhatsApp is disrupting the SMS part of this industry, which globally has over $100 billion in revenue, by sending 18 billion SMS messages a day when the global SMS system only sends 20 billion SMS messages a day.  With a fundamental change in the transition from PCs to nearly universal smartphone adoption, the size of the opportunity is a much larger addressable market than where Facebook normally plays.

But Facebook has promised no ads and no interference, so where’s the win?

There’s the interesting development of business use over mobile. WhatsApp is used to create group conversations for project teams and venture capitalists carry out deal flow conversations over WhatsApp.

Instagram is used in Kuwait to sell sheep.

WeChat, a WhatsApp competitor, launched a taxi-cab hailing service in January. In the first month 21 million cabs were hailed.

With the future of e-commerce looking like it will be funneled through mobile messaging apps, it must be an e-commerce play?

It’s not just businesses using WhatsApp for applications that were once on the desktop or on the web. Police officers in Spain use WhatsApp to catch criminals. People in Italy use it to organize basketball games.

Commerce and other applications are jumping on to mobile for obvious reasons. Everyone has mobile and these messaging applications are powerful, free, and cheap to use. No longer do you need a desktop or a web application to get things done. A lot of functionality can be overlayed on a messaging app.

So messaging is a threat to Google and Facebook. The desktop is dead. The web is dying. Messaging + mobile is an entire ecosystem that sidesteps their channel.

Facebook needs to get into this market or become irrelevant?

With the move to mobile we are seeing deportalization of Facebook. The desktop web interface for Facebook is a portal style interface providing access to all the features made available by the backend. It’s big, complicated, and creaky. Who really loves the Facebook UI?

When Facebook moved to mobile they tried the portal approach and it didn’t work. So they are going with a strategy of smaller, more focussed, purpose built apps. Mobile first! There’s only so much you can do on a small screen. On mobile it’s easier to go find a special app than it is to find a menu buried deep within a complicated portal style application.

But Facebook is going one step further. They are not only creating purpose built apps, they are providing multiple competing apps that provide similar functionality and these apps may not even share a backend infrastructure. We see this with Messenger and WhatsApp, Instagram and Facebook’s photo app. Paper is an alternate interface to Facebook that provides very limited functionality, but it does what it does very well.

Conway's law may be operating here. The idea that “organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations.” With a monolithic backend infrastructure we get a Borg-like portal design. The move to mobile frees the organization from this way of thinking. If apps can be built that provide a view of just a slice of the Facebook infrastructure then apps can be built that don’t use Facebook’s infrastructure at all. And if they don't need Facebook's infrastructure then they are free not to be built by Facebook at all. So exactly what is Facebook then?

Facebook CEO Mark Zuckerberg has his own take, saying in a keynote presentation at the Mobile World Congress that Facebook's acquisition of WhatsApp was closely related to the Internet.org vision:

The idea is to develop a group of basic internet services that would be free of charge to use — “a 911 for the internet." These could be a social networking service like Facebook, a messaging service, maybe search and other things like weather. Providing a bundle of these free of charge to users will work like a gateway drug of sorts — users who may be able to afford data services and phones these days just don’t see the point of why they would pay for those data services. This would give them some context for why they are important, and that will lead them to paying for more services like this — or so the hope goes.

This is the long play, which is a game that having a huge reservoir of valuable stock allows you to play. 

Have we reached a conclusion? I don’t think so. It’s such a stunning dollar amount with such tenuous apparent immediate rewards, that the long term play explanation actually does make some sense. We are still in the very early days of mobile. Nobody knows what the future will look like, so it pays not try to force the future to look like your past. Facebook seems to be doing just that.

But enough of this. How do you support 450 million active users with only 32 engineers? Let’s find out...

02 Jan 10:39

Aaron Gustafson – Designing Across Devices with Progressive Enhancement

by Sean Carmichael

[ Transcript Available ]

Aaron Gustafson

Responsive web design seems to come up in every other discussion or article about UX these days. And rightfully so as it’s an elegant way to make sure your design adapts to the multitude of devices on the market. But with the Internet of Things looming, it’s becoming more than just the visuals of your site that are of major concern. How your content displays on a car dashboard, “can a watch handle this page weight?”, or “is this refrigerator JavaScript enabled?” are not unrealistic issues moving forward.

Aaron Gustafson believes that progressive enhancement can go a long way to addressing these questions. In his virtual seminar, Designing Across Devices with Progressive Enhancement, Aaron discusses strategies for layering the experience. By thinking of the interface as a continuum, it can not only adapt to devices, but can become more robust with browser capabilities.

The audience had a lot of questions for Aaron during the live seminar and he joins Adam Churchill to address some of those in this podcast.

  • How can you approach pages where JavaScript is required to complete a task?
  • How do you prioritize design considerations?
  • Are semantic ID classes useful?
  • Are there performance issues with lazy-loading?
  • When can we stop supporting older browsers?

Recorded: December, 2013
[ Subscribe to our podcast via Use iTunes to subscribe to UIE's RSS feed. ←This link will launch the iTunes application.]
[ Subscribe with other podcast applications.]

Full Transcript.


Adam: Welcome to another edition of the SpoolCast. Earlier this fall, Aaron Gustafson presented his virtual seminar, “Designing Across Devices with Progressive Enhancement.”

The recording of this seminar has been added to our library of over 115 seminars on all things user experience design. A library soon to be unveiled as UIE’s “All You Can Learn.” If you’re interested in early access, you can email us aycl@uie.com. Forgive us for the acronyms. Again, that’s aycl@uie.com.

In Aaron’s seminar, he addressed the sea of considerations designers need to take into account, such as browsers, accessibility, device compatibility and responsive or adaptive design. With new techniques and devices coming out daily it’s easy to feel overwhelmed. But in the seminar, Aaron showed how to wrangle all these elements using progressive enhancement.

Today, Aaron joins us to discuss the concept some more and answer a few of the questions that remain from the seminar. Hello, sir. Welcome back.

Aaron: Thanks for having me.

Adam: Aaron, for those that weren’t with us that day, can you summarize your presentation?

Aaron: Sure, I’ll do my best. I started off discussing sort of where we are in terms of dealing with devices nowadays. I mean, we’re all fairly well schooled in the worlds of laptops and desktops and tablets and stuff like that, and certainly smartphones. But we often don’t think about things like gaming systems, televisions, e-readers, crappy netbooks that you can buy at CVS or Walgreens or something like that.

Then kind of the breadth of all of these different feature phones. Low quality smartphones that I would kind of lump into that feature phone category that may be running an operating system like the latest version of Android. But it’s on, really, less than stellar hardware.

This is kind of where we are right now. The future is really kind of questionable as to where things are going, at least with commodity hardware. Obviously, the development world is kind of interested in what’s going on with things like Google Glass. But we also have a lot of heads up units in cars that are starting to become web enabled, refrigerators that are starting to have this sort of stuff. We’ve got watches starting to hit the markets that have some connectivity to the Internet.

How do we develop a sane strategy for reaching all of these different devices with all of these variable screen sizes? That’s sort of what responsive web design is all about and what it’s meant to achieve. It does that from the standpoint of looking at fluid grids, flexible media and media queries as a means of dealing with the visual representation of a web page and across a variety of screen sizes.

But once you get kind of beyond that relatively, not to trivialize it, certainly, but relatively simple visual rearrangement. You end up with the really difficult things like content strategy, dealing with page weight, thinking about JavaScript support.

Not just a binary, is JavaScript on or is it off, but what are the capabilities on the given device. What capabilities are there in the browser? Do we have access to some of the alternate interaction methods or sensors within the device? Is the device powerful enough to be able to actually execute our JavaScript or is that going to be problematic?

We have different interaction methods like touch. We have, obviously, gestures like swipe, pinch, zoom, etc. We have the traditional keyboard for interacting with pages. We have now motion detection things like the connect on Xbox, but also leap motion. Then we kind of have the traditional scroll wheels and stuff like that that we had in early BlackBerries and Trios and various other rockers and things like that that we need to use to navigate pages.

We have to deal with network latency and performance issues when we’re dealing with mobile networks. I mentioned hardware performance as an issue. Then of course, screen resolution, when we’re talking about kind of a normal resolution screen versus a high resolution screen. We start getting into retina displays that are two, sometimes even three times as dense, pixel wise, as kind of traditional desktop screens have been.

All of this stuff is kind of the more complicated things that are swirling around the concerns of responsive web design.

In the seminar, I walk through the concept of progressive enhancement and that philosophy and that approach to web design. How, if we focus on our content very much in the same way that the mobile first philosophy asks us to focus on our content as the primary driver, the main reason that we build websites to begin with.

If we focus on those core tasks, if we focus on the pros and then we build up the experience from there, based on capabilities that we can actually reach more devices for less. That means both less cost wise, less overall effort, less headaches, less gray hair.

The way that we get there is by beginning to think about interface as a continuum. You may have one way of experiencing a given page or a particular component on a page, and that component may adapt based on the capabilities.

Whether it’s screen resolution, whether it’s input method, JavaScript availability, whatever, it will adapt to become a tailor made component for any user that comes to that page. Two users may not have the same exact experience of that content. But as long as the experience is a positive one, then we’re golden. That’s what Progressive Enhancement strives for.

That’s what I talked about in the seminar. I went through the different ways that we built up an experience using HTML, CSS, JavaScript, and that sort of thing, then gave them some solid strategies and some techniques that I had found useful for organizing our thoughts around this continuum of experience.

To create maps that help us to be a little bit more cognizant or have a little bit more forethought about what the different experiences or what the different ways of experiencing our content should be put together. As opposed to leaving it in the hands of just development team, actually having designers and content authors, project managers, et cetera all involved in them.

Adam: Very cool. Let’s get to some of the questions that were left over. The folks at Anthology Marketing Group, they asked about what’s a Progressive Enhancement philosophy on pages where JavaScript is required for accomplishing a task.

The examples would be calculations or maybe a presentation of content-based choices, and say a bit more about JavaScript. Doesn’t everybody have that?

Aaron: It’s not so much a question of, “Do users have or not have JavaScript,” so much anymore. There certainly are a number of users who do not have JavaScript. I think that the numbers that I saw recently from gov.uk, from their traffic was putting it somewhere around one percent of their users, which depending on your volume of users could be a significant amount of your traffic.

Beyond that, the over reliance on JavaScript…First of all, I love JavaScript, and I program in it all the time. I enjoy it as a language. I think it’s a great tool, but I think it’s also important to recognize what the tool is good for and where its failings are.

One of the problems with relying on JavaScript is that when we’re, let’s say programming a back-end for a website, and we’re building that in some language like PHP or Ruby or Python or even JavaScript, if we’re using Node.

We have control over the server stack. We have control over the environment within which that application code is being executed. We know where the problems are. We can address those, and we can fix those right away.

With JavaScript that we’re writing to be used in the browser by clients, we have no control over their environment within which they’re executing that JavaScript. For that reason, when we put all our eggs in that JavaScript basket. If they don’t have the appropriate environment for that code to be executed, none of that code will be executed.

In fact, depending on the issues with the environment, other JavaScript that it may encountering in that environment or what have you, our code may not execute at all. In fact, no JavaScript code may execute, so the user may have the ability to execute JavaScript, but something they’ve precluded from happening.

When we build interfaces that are wholly reliant on JavaScript for the user to be able to experience anything, there’s a risk there that the user may not have, not just a good experience, but they may have no experience at all.

The classic example that I’ve used for a number of years is when Gawker Media launched their new Web platform. Every piece of content was being delivered by JavaScript. They were using this same platform to run all of the different blogs that they run, like Lifehacker and Gawker, et cetera.

There was an accidental error in the JavaScript code that was produced by the team that made it out into production. What happened is that it was severe enough to cause JavaScript to stop executing altogether, and no content was being loaded into those pages.

That was a really bad experience for all of their customers, not just on one site, but on every site that was using that same platform. To think about, what is the experience that we want users to have? We always want them to have a good experience with our brands and our products.

We want to have a site that’s going to work for them regardless. We want to build something that’s robust. I think there are opportunities to use JavaScript to great effect, but we need to have a fallback.

When people say, “Oh, I need to be able to have a calculator on this page,” or “I need to be able to have this, that, or the other,” you can have that. You can certainly have that, but if you think about what we used to do back in the early days of the Web. For those of us who’ve been on the Web for a really long time. Before we had JavaScript, we used to do round trips to the server, to run calculations or to load new content or what have you. That works whether you’re on a text-based browser or an awesome Chrome 30 running on a really fast machine.

That same old code that runs using HTTP requests and just reloads the page based on values that you supplied in a form is going to continue to work now and into the future. There’s no reason we couldn’t have that and then have a JavaScript that comes in and says, “Hey, here’s the calculator. Here are all of the fields. I don’t have to do a round trip to the server because I can run this calculation just in JavaScript.” There’s not a big problem with that, so you can create a better experience for people who do have JavaScript.

Some of the larger applications on the Web — say your Twitters, your Airbnbs — had jumped very whole-hog into this world of JavaScript and having JavaScript render every Web page that you went to. They’ve actually both pulled back from that, because they found that the speed of delivery of content and the time to actual display of the page was much faster if they actually loaded a normal HTML page from the server, with actual static assets and such. Then once the page was loaded, took the page over with JavaScript and started doing all of the enhancement stuff that they wanted to do to make a richer experience for their users.

It’s just about finding a good balance between wanting to give users a great experience, but still wanting to have a core experience that’s always going to continue functioning even if something really bad happens.

Adam: Aaron, early on in the presentation, you were talking about those factors that we talked about at the beginning of this podcast, all those design considerations, and you had a graphic where they were stacked on top of each other. Mike asks this question. Do you have a process that you use for prioritizing all of them? How do you then turn around and communicate the reason for those priorities to your clients?

Aaron: For us, the priority is always the key task, whatever that is. We need to make sure that a user can sign up for an account or a user has access to the content that they need in order to be able to submit their taxes, for lack of a better example. That is the core, and everything on top of that is gravy to us.

The core tasks are always the priority, and then we start to think about how can we make the experience better for people who have a greater capability. Sometimes there’s trade-offs. We were working on a project recently, and our client wanted to compress the print version of a calendar listing to be making better use of space.

Because the calendar events themselves, when they’re in a linear list, when you’re printing that out, you’re going to use a lot of paper, potentially. In this case, they actually did have a lot of people who did want to print the calendars from the Web page, and they didn’t want to lay it out in a typical, boxed, calendar format because that didn’t give them enough leeway to put in a lot of information in some of the days, so a list was the most appropriate display of that content.

When we started to look at options in print, the first thing that we thought about is, well, CSS3 has columns, and we should be able to use CSS3 columns to essentially make different aggregate groupings of dates, wrap around a couple of columns on the print version, and then it would be the next aggregate group with its own columns, et cetera, et cetera, continuing down the page.

We wouldn’t have to make any determinations about how tall a page is and what size paper somebody’s printing something on, that sort of stuff, which is fairly similar to trying to figure out where the, quote/unquote, “fold” is on a desktop screen. It’s not a fun task to try and figure that out. It’s pretty much a fool’s errand.

We were trying to make something flexible. The problem that we ran into was that there are a lot of browsers that support CSS3 multi-col right now, but some of them — most of the ones that are based on WebKit — don’t actually implement that in print. Whereas, Firefox and Internet Explorer were having pretty good luck doing multi-column in print.

We had to try and figure out, what are the different experiences that we’re going to be providing in those instances? Do we give just the one linear view to users of Chrome and Safari and then do the multi-column for the browsers that can support it, or do we do single-column for both and try and float things to try and take up less space?

We always try to keep in mind what is the best thing for the user, not necessarily what’s easy for us. Where we ended up with that is trying, to the best of our ability, to determine, does this browser support multi-column layout? If so, is it a WebKit browser? Because, as we know, currently WebKit doesn’t support this.

Then we had JavaScript actually add a class to the HTML element that told us which mode they were in, in terms of having multi-column support for print or not. Then we adjusted what the styles were that were applied for the print medium in order to provide the best possible viewing experience for the user when they printed it out.

Adam: There’s some debate over the usefulness of semantic class ID names. What are your thoughts there?

Aaron: In a sense, classes and IDs, they don’t have much use, beyond for us to communicate with each other as designers and developers, by themselves. IDs were intended to be used for identification purposes, for identifying a specific element on the page, in order to be able to anchor to it, in order to be able to find it via the Document Object Model or what have you.

Classes were originally intended for classification of similar elements, as a way of us being able to extend the semantics of HTML beyond what the actual built-in lexicon was at various stages in the development of HTML. On the surface, they don’t really have much meaning beyond that. It’s good to have class names that make sense from a semantic point of view, because it’s easier, as a team, to know which class to apply. If you’re just applying class EF or EF3 or something like that, you don’t know what that is, whereas if you’re using a class of article or carousel or something like that, that makes human sense, right?

There are some systems out there that do apply these non-semantic class names. When they’re generating HTML, for instance, a lot of CMSes do this. A lot of back-end systems that are just churning out markup will create these, I don’t know, non-readable or nonsensical class names and IDs and such, and I don’t find them all that helpful because it’s hard for me to figure out what’s going on, even though it may be smaller in terms of file size that’s being delivered to the actual browser client.

The added importance of the semantic stuff, to me, is, if we’re using semantic class names and we’re looking at each other’s code, we start to gravitate towards similar constructs. This is how the micro-formats community continued beyond the Xhtml Friends Network. This is how we got kind of the h-card spec, the h-calendar micro format, etc. And, by using these class names consistently, from site to site, that content could then be repurposed. We could extract event information.

We could extract people’s cards, addresses, stuff like that and add them directly to our address book. So that was a really cool thing.

But also, our decision to use specific classes and ids, came back to help influence the html spec as it moved forward. A lot of the new html 5 elements were based on class names that we were using. Things like ‘article’ and ‘section’, these were all concepts that we were creating – “header”, “footer”, “main” – and these have worked their way back into the spec and become kind of codified as actual tags. So, in some ways, the semantics that we choose to use in our class names and IDs, really do help to influence the future of the language that we all use. So, from that standpoint, I think that they’re a good thing as well.

Adam: Aaron, in the seminar you gave some examples of lazy loading, could you speak a bit more about what that is and are there performance issues associated with it?

Aaron: Sure. So, lazy loading is the idea of having a core set of content that’s loaded into the browser that’s sent from the server that comprises your, sort of, minimum viable product, sort of speak. It is absolutely what users need to have access to, no more, no less. And then, lazy loading is a way that we then bring in additional content to the page either when we feel it’s a good time to do so.

Maybe after the page is initially loaded, we then load in the contents of the comments section of that blog post. Or maybe we load in images as a user scrolls down the page and they get to within 300px or so of the image, we then load the image in.

And, the effect that this has is we’re kind of streamlining what the initial package is, so to speak. We’re giving somebody kind of a minimum download to begin whatever it is that they’re trying to do on a given page. And then, we’re bringing in assets as they’re needed or as they are requested by the user. And, as I said, these could be triggered by user actions like scrolling, or maybe clicking a button or something like that. Then maybe we make a request for an additional piece of content.

Sometimes we want to do that in a little bit more of an anticipatory fashion. So, in some cases, let’s say, clicking a button is going to reveal more content, but you don’t have that content on the page to begin with because it’s sort of ancillary to the primary purpose of the page. What you could do is you could track when the mouse gets within 400px, circle around the element and then when it gets within 400px, you make a request to the server to obtain that additional information and load it into the page to have it at the ready if the user clicks the button.

What this allows us to do is kind of deliver experience in a little bit more of an a la carte fashion. Which is much more bandwidth friendly and much better for users who just want to get access to the content right away. And don’t want to have to wait to download two megs of JavaScript or something like that in order to be able to have the page assemble and then be able to potentially do everything when they only want to do one thing on the page.

Adam: Aaron, when can we stop supporting older browsers?

Aaron: That’s always the big question, right? So, obviously, paying attention to your stats is an important thing, looking at your analytics data. But, I think it’s important to look at your analytics data with a little bit of a different perspective in that, if you look at your analytics data and you see, “Oh we don’t have any ie6 users or we don’t have any Blackberry four users”, it’s important to kind of ask a follow up question to yourself of, “What is that experience in that browser or on that device”?

If your answer to yourself is, “Well, it’s a crappy experience”, that may be kind of the reason right there. It may be a self-fulfilling prophesy, or at least self-deterministic, that you’re not having any users have x, y, or z browser. So, I think that that’s an important thing but I also think that, as we begin to think more about building sites from a progressive enhancement standpoint. The “problem browsers,” like IE6 become less of a problem because you’re thinking about a continuum of experience instead of trying to achieve exactly the same experience in every browser.

So, for most of the projects that we’re building these days, we still support IE6 and Internet explorer 7, but we don’t optimize for them. We serve them a very basic experience. We give them the mobile first experience without all the bells and whistles. So, for many of those users, they’ll have a single column layout of the text but it will still be usable to them. They’ll be able to find the information they need. They’ll be able to submit the forms they need to.

They won’t have all of the awesome bells and whistles that somebody on the latest version of pro will but, they’ll still have a good experience and they can still accomplish what they need to which is really what we should be striving to do anyway. To be able to reach our users wherever they are and give them a good experience.

Adam: Does IE support media queries?

Aaron: No, not until IE9. So, I don’t remember. I believe that it was, Stephanie Reiger, who… It was either Stephanie or Brian. I can’t remember for sure. Stephanie or Brian Reiger mentioned that, in fact, lack of support for media queries is like the first media query. Because if you use a media query to link a stylesheet. You won’t get that stylesheet loaded in a browser that doesn’t understand media queries. So, it’s a good way to create kind of a base stylesheet that you load for everybody that has your basic typography.

Your margins and stuff like that for elements relationship to one another, but then load a second stylesheet that uses a media query to assign a medium to it. That gets delivered to any browser that understands media queries. And that one contains kind of your additional layouts, your multi-column layouts, and stuff like that.

Those are more aimed at a more advanced browser that has more real estate. And that way the user of a browser like IE6, or even IE8, isn’t penalized by having to download all of these styles that they’re not ever going to use.

Adam: Aaron, in the seminar, you shared a light box example towards the end of the presentation and there was an inquiry. Wouldn’t a link to the larger image still be useful for somebody who maybe is on a device so they can still pinch and zoom?

Aaron: It’s something that certainly could be done and there wouldn’t be really any harm in that, I don’t think. But, in that particular example, my feeling was that the image that we were showing in the light box was really not going to be that much bigger and it wasn’t going to give a great experience to somebody who is on one of those phones or just in a browser that has a smaller screen resolution. So, that was kind of a judgment call, on that particular example.

You could certainly have a link to the image and then still do the light box as a progressive enhancement for browsers that do support it. But I would still probably do a check to determine whether it makes sense to actually show the content in the light box or not because, I don’t know about you. But I’ve had way too many experiences where something has come up in a light box or some sort of overlay.

I have to chase it around the page pinching or zooming, to try to get the content focused. And so, we don’t want to give frustrating experiences to our users. We want to take the friction out of their lives. So, for that reason, I think that we need to be really thoughtful about how we apply JavaScript effects like a light box and such.

Adam: All right. Cool. Aaron, thanks for joining us again to talk more about progressive enhancement.

Aaron: Yes, thank you very much, Adam.

Adam: To our audience, thanks for listening and thanks for your support of the UIE virtual seminar program. Good bye, for now…

11 Dec 14:29

CityMaps 2 Go Pro (Android) für 48 Stunden gratis

by kafuzz

Android-Usre können ab 17 Uhr für 24 Stunden die App CityMaps 2 Go kostenlos herunterladen. Die Pro-Version wird sonst für 1,99 € verkauft.

NEU: Interaktive Offline-Karten und Wikipedia Reiseführer für die ganze Welt. INKLUSIVE unlimitierte Karten- und Reiseführer-Downloads. 100% offline. Kein Daten-Roaming oder WLAN nötig. Die meistgeladene App seiner Art. Ideal für Reisen und daheim.

♕ chip.de sagt: "Für den nächsten Urlaub perfekt gerüstet".

1.) Offline-Karten:
✚ 6.700 interaktive Karten weltweit verfügbar
✚ Millionen POI (Restaurants, Shops, Bars, ...)
✚ 220.000 dt. Wikipedia-Auszüge von Attraktionen
✚ GPS: eigener Standort und Umgebungssuche
✚ Offline-Suche nach Adressen und Orten

2.) Wikipedia Reiseführer:
✚ Umfassende deutsche Artikel mit Bildern
✚ Sehenswürdigkeiten und interessante Orte
✚ Zur Karte dazuladen und offline nutzen

3.) Power Features inkludiert:
✚ Für Vielreisende und Mobile Heroes :-)
✚ Eigene Orte auf der Karte anlegen
✚ Favoriten-Liste erstellen
✚ Hotelbewertungen von booking.com sehen

02 Dec 08:46

Talking about Elixir and the Erlang VM with José Valim

by pdincau
Hello! CodeMesh 2013 is coming and if you are planning to attend this wonderful event you may have the chance of learning more about Elixir from his creator: José Valim. For those of you who will not be able to be in London the 4th, 5th  December I prepared this interview to José. In the interview we talked about Elixir, its roots in the Erlang VM and the future of this newborn language. Enjoy! 😀

Elixir of life

Paolo – Hello José! It is a great thing to have you here in my blog for an interview. Would you like to introduce yourself in few words?
 
José – Hello Paolo! In few words, I am co-founder of Plataformatec, a consultancy based in Brazil and the creator of the Elixir programming language!
 
Paolo – José, you were previously known for you work in the Ruby on Rails Core Team. What was you experience with Erlang before writing Elixir? Why did you decide to write a new language and for what reason did
you choose the Erlang VM?
 
José – Before writing Elixir, I already had a good knowledge of the Erlang language and the Erlang VM. At the time, I was unhappy with the tools available to solve the concurrency issues in the Ruby ecosystem and the fantastic Seven Languages in Seven Weeks book helped me lay out the options out there. After reading the book, it solidified my opinion that the Erlang VM is one of the best environments to build and deploy robust concurrent software (my goals at the time).
 
After digging deeper into the Erlang language, I missed some of the flexibility and constructs that I find important in my toolbox, like meta-programming and polymorphism, as well as a better unicode support and other things, which led me to write Elixir.
 
Paolo – Elixir is based on the Erlang VM but has a syntax close to Ruby: for what reasons an Erlang developer should learn Elixir? What about Ruby developers?
 
José – Erlang developers know quite well syntax is often one of the first things that come up when discussing a new language. So while the syntax is similar to Ruby, the semantics are mostly from the Erlang VM. So leaving syntax out, an Erlang developer would find appeal in Elixir if he/she misses the same tools I missed when I started it. For example, we provide a macro system which gives developers the ability to meta-program, i.e. to write code that generates code. Another example is polymorphism, where Elixir provides something called protocols, heavily inspired by Clojure’s protocols, which allows developers to provide well-defined extension points in their libraries.
 
It is hard to explain such features in broad terms, so let me try to give some examples. Erlang developers are familiar with typespecs. In Elixir, we also have typespecs, except they were all implemented in Elixir itself using macros. There is no language extension because macros give users the ability to access and modify existing code. Another good example of macros is how we embed the unicode database into Elixir, at compilation time, which allows us to speed up many Elixir string operations by avoiding work at runtime.
 
Elixir also aims to provide a tidier standard library. For example, we provide an Enum module that is able to enumerate (i.e. map, fold, take, etc) all the collections in the language and such module is powered by protocols: Elixir knows how to enumerate your collection as long as you implement a protocol. After all, it is preferable to have a small set of functions that work well with a handful of collections than a completely different set of APIs for each data structure.
 
For any other developer, be a Ruby, Java, Python or Javascript programmer, learning Elixir means learning the semantics in the Erlang VM and all the amazing tooling existent for building robust, concurrent, fault-tolerant applications and that is more than enough reason for giving it a go.
 
Paolo – I have read the enthusiastic blog post “A week with Elixir” by Joe Armstrong. I also know that you are giving several talks around the world about Elixir. What kind of feedback do you receive from the Erlang community?
 
José – In general the feedback is quite good as the community agrees that the power lies on the Erlang VM and, while Elixir offers a slightly different perspective on it, the more developers using the Erlang VM translates into more knowledge, tools and enthusiasm in the ecosystem altogether.
 
Paolo – Some of our readers maybe want to contribute to some open source project based on Elixir. Do you want to suggest some projects in particular?
 
José – The community is still very young so the best suggestion right now is to try to solve a problem and see if there are any tools available and, if not, wright your own! We see some efforts converging though, we already have an “official” monad library, another for talking to postgresql, other to work with data and time, and so on.
 
Also I want to point out that Elixir is mostly written in Elixir, with the exception of a dozen of macros that we call “special forms”. This makes it very easy to contribute to Elixir itself, once you start learning the language!
 
Paolo – The 4th and 5th December you will give a talk at Code Mesh 2013. The talk title is: “Ecto: A language integrated query for Elixir”. Can you give to our readers some insights on you talk?
 
José – Besides the keynote about programming and Elixir, which I will give with Dave Thomas, I will also talk about Ecto.
 
In a nutshell, Ecto is a language integrated query to talk to relational databases in Elixir, heavily inspired by LINQ (from .NET). The goal of the talk is to introduce Ecto but, more importantly, also show how features provided by Elixir made the implementation of Ecto in the first place!
 
Paolo – Looking at the future: what should we expect from the new Elixir releases? In which part of the language will you focus the most?
 
José – In the short-term, we want to integrate with maps (when Erlang R17 comes out) while we work on a solid logging system to be shipped with the language, that builds on Erlang’s logger. Once that is done, we will release Elixir v1.0.
 
After Elixir v1.0 is out, we have many options to explore and the interesting thing is that we can explore those outside of the language, because macros give us all support we need. Some plans include providing better comprehensions, improving how we work with nested data structures, support to discriminated unions and more!
26 Nov 15:11

Four short links: 26 November 2013

by Nat Torkington
  1. The Death and Life of Great Internet Cities“The sense that you were given some space on the Internet, and allowed to do anything you wanted to in that space, it’s completely gone from these new social sites,” said Scott. “Like prisoners, or livestock, or anybody locked in institution, I am sure the residents of these new places don’t even notice the walls anymore.”
  2. What You’re Not Supposed To Do With Google Glass (Esquire) — Maybe I can put these interruptions to good use. I once read that in ancient Rome, when a general came home victorious, they’d throw him a triumphal parade. But there was always a slave who walked behind the general, whispering in his ear to keep him humble. “You are mortal,” the slave would say. I’ve always wanted a modern nonslave version of this — a way to remind myself to keep perspective. And Glass seemed the first gadget that would allow me to do that. In the morning, I schedule a series of messages to e-mail myself throughout the day. “You are mortal.” “You are going to die someday.” “Stop being a selfish bastard and think about others.” (via BoingBoing)
  3. Neural Networks and Deep Learning — Chapter 1 up and free, and there’s an IndieGogo campaign to fund the rest.
  4. What We Know and Don’t KnowThat highly controlled approach creates the misconception that fossils come out of the ground with labels attached. Or worse, that discovery comes from cloaked geniuses instead of open discussion. We’re hoping to combat these misconceptions by pursuing an open approach. This is today’s evolutionary science, not the science of fifty years ago We’re here sharing science. [...] Science isn’t the answers, science is the process. Open science in paleoanthropology.
19 Nov 09:20

Don’t trust the .NET web forms email regex validator (or most others)

by Troy Hunt

I’ve been working on a little project recently that involves handling hundreds of millions of email addresses from various sources. More on that in a later post, but for now let’s just assume that I want to have a reasonable degree of confidence that each of these addresses from an untrusted source is valid. Indeed many of them are just rubbish – beyond the obvious “does it have an @ symbol”, a bunch of them don’t have dots in the domains or contain illegal characters in places where they just shouldn’t be. Clearly it’s time for a regex because you can fix anything with a regex, right? Guys…?

I thought the easiest way to get this right straight off the bat would be to just grab a regex validator from an ASP.NET web forms project and copy the pattern into my project. It looks like this:

Regex for an email address

Regexes are never much fun to read but on the surface of it, this doesn’t look too bad. So I drop the pattern into the project and start parsing addresses and a heap of them come back as invalid. Stuff like foo.foo@bar and foo@bar get binned and that’s just great. But then foo-@bar.com gets binned too. Hang on – has .NET got it wrong?! (In fairness it’s not .NET as in the framework itself that has it wrong, rather it’s the default value Visual Studio provides when selecting the expression above)

Now you can read the spec and get a headache or you can take a look at Wikipedia’s description of the “local part” of an email address:

The local-part of the email address may use any of these ASCII characters RFC 5322 Section 3.2.3, RFC 6531 permits Unicode beyond the ASCII range:

  • Uppercase and lowercase English letters (a–z, A–Z) (ASCII: 65–90, 97–122)
  • Digits 0 to 9 (ASCII: 48–57)
  • Characters !#$%&'*+-/=?^_`{|}~ (ASCII: 33, 35–39, 42, 43, 45, 47, 61, 63, 94–96, 123–126)
  • Character . (dot, period, full stop) (ASCII: 46) provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively (e.g. John..Doe@example.com is not allowed.).
  • Special characters are allowed with restrictions. They are:
    • Space and "(),:;<>@[\] (ASCII: 32, 34, 40, 41, 44, 58, 59, 60, 62, 64, 91–93)
The restrictions for special characters are that they must only be used when contained between quotation marks, and that 2 of them (the backslash \ and quotation mark " (ASCII: 92, 34)) must also be preceded by a backslash \ (e.g. "\\\"").
  • Comments are allowed with parentheses at either end of the local part; e.g. "john.smith(comment)@example.com" and "(comment)john.smith@example.com" are both equivalent to "john.smith@example.com".
  • International characters above U+007F are permitted by RFC 6531, though mail systems may restrict which characters to use when assigning local parts.

The third bullet says dashes are good – what gives?! Going back to the regex, the problem is that whilst is allows dashes in the local part of the address, it won’t allow them immediately before the @ symbol. This is incorrect.

Screwy regexes are nothing new and much has been written about them for many years, including this great one by Phil Haack. Certainly when asking around on Twitter there was a lot of ire at the inconsistency of email regexes and as some said, it’s actually not even possible, at least not without excluding various valid patterns.

The point of all this is firstly to say “Don’t trust the default validator in the regex control of ASP.NET”. It’s a fair assumption to make – that Microsoft will give you a validator that actually works – but it’s an incorrect assumption.

Secondly, clearly we need something more decent and obviously it’s easy to replace the one in the validator or drop it into your C# as required. I grabbed Phil’s from the post above which looks like this:

^(?!\.)("([^"\r\\]|\\["\r\\])*"|([-a-z0-9!#$%&'*+/=?^_`{|}~] |(?@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$

Yeah, um, that looks good?

More importantly though, here are the stats from the analysis I did on a bunch of user-provided email addresses:

  1. Total “addresses” (including invalid ones): 859,248
  2. Rejected with ASP.NET validator: 1,864
  3. Rejected with Phil’s validator: 3,423

Huh? Why is Phil rejecting nearly twice as many? Because ASP.NET’s validator is also too liberal in many cases. For example, it believes foo@bar.c0m. is valid which is just wrong. It also reckons foo..foo@bar.com is good which is also not the case:

Character . (dot, period, full stop) (ASCII: 46) provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively (e.g. John..Doe@example.com is not allowed.).

The ASP.NET validator also allows foo@f.com which is an invalid host name as is foo@foo.c0m. There are many similar examples of various flavours that show in many cases the “native” validator is just too liberal.

Edit: foo@f.com is a valid address – sorry Phil! There are a number of single char names such as t.co and x.co. The part of the regex immediately after the last @ symbol was expecting an alphanumeric character and a word character before the next dot. Here’s a revision that fixes that case:

^(?!\.)("([^"\r\\]|\\["\r\\])*"|([-a-z0-9!#$%&'*+/=?^_`{|}~] |(?@[\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$

At the end of the day, being too liberal is probably not a bad thing – is it really so bad if someone registers with an invalid address? Probably not. On the other hand, being too stringent can mean losing a customer which is probably a whole lot worse. But then again, any half-reasonable validator is probably only going to find false positives in addresses that people have plenty of problems getting into sites with anyway!

Email address validation is an absolute quagmire. Phil’s solution is more accurate than the others I’ve seen but if it doesn’t have flaws I’ll be massively surprised and that’s not to cast a dispersion on Phil, it’s just that this game is a very, very imprecise science. He does go on to point out a very poignant comment in his subsequent post:

The only way to validate an email address is to deliver a message to it!

Now of course that’s very context-sensitive statement too; yes, this would work well at the point of registration on a website but no, it doesn’t work well when you’re parsing hundreds of millions of addresses in a data dump! My case is special and again, I’ll detail it more later, but my particular priorities are on having a higher degree of confidence in the integrity data I have rather than ensuring obscure edge-case addresses are allowed through.

Oh – and just in case anyone is interested, here’s a dump of those 3,423 rejected email addresses (alpha chars substituted with “x’ for the sake of anonymity then distilled to a distinct list of 1,905 records). If, for argument’s sake, 10% of those are false positives (and I highly doubt it’s that high), we’re looking at 0.04% of the original dataset being invalid. If you applied Phil’s regex on a live site that means one in every 2,500 emails would be spat back out. That may be too high for some people (but again, I think the reality is much lower), but I thought it was good context for people debating the virtues of less validation and more junk versus the alternative.

Edit: After the revision above in the previous edit, the number rejected email addresses came down to 2,378 so a 31% reduction – so much for my 10% theory! That said, many of those single char domain examples look like junk but they do now pass the pattern. The list below still includes these. Oh – and there are other legit patterns that get rejected even by the revised regex but I’ll touch on those in a follow-up post shortly.

If you see any reckon are actually legal per the spec, yell out:

!@1.xxx, $xxxxxxx@47, .x.xxxxx@xxx.xxx, .x.xxxxx@xxxxxxx.xxx, .x.xxxxxx2@xxxxxxxxxx.xxx, .xxx51896@xxxxxxx.xxx, .xxxxx.xxxxx@xxxxx.xxx, .xxxxx@xxxxx.xxx, .xxxxx1@xxxxxxxxx.xxx, .xxxxx313@xxxxxx.xx, .xxxxxx@xxxxx.xxx, .xxxxxx44@xxxxx.xxx, .xxxxxxx@xxxx-xxxxxxxx-xx.xxx, .xxxxxxxx@xxxx.xxxxxxx.xxx, .xxxxxxxxx@xxxxxxxxxxxxxx, .xxxxxxxxxx@xxxxxxxxxxxxxxx.xxx, .xxxxxxxxxx22@xx.xx, .xxxxxxxxxxxx@xxxxxxx.xxx, .xxxxxxxxxxxx@xxxxxxxxx, .xxxxxxxxxxxxx@xxxxx.xxx, .xxxxxxxxxxxxxxx@xxxxx.xxx, _xxxxxxxx@xxxxxx, 0@2, 000xxxx@000xxxx.xxx0, 001xxxx@001xxxx.xxx0, 04%2x81.51744@xxxxx.xxx, 1@1, 1@1.1, 1@1.2, 1@1.xxx, 1@2.3, 1@2.31, 1@2.xxx, 11@1.xxx, 11xxx%2xx2@xxxxx.xx.xxx, 123@123.x0x, 123@x.xxx, 12xxxxxxx@x.xx, 13_xxxxxxx@x.xx, 138@xx, 14xxxxxxx@x.xx, 1996@xxx, 1xxxx1@1xxxxxxx1.1xxx, 1xxxxxxx@xxxxx, 2@2.xxx, 2@3.xxx, 2@x.xxx, 200xxxx@x.xx, 21559879xx@xxxxxxxx, 22@22, 27_xxx_2505@x.xxx, 27_xxx2_505@x.xxx, 2x_@9.xx, 2xxx.@xxxx.xxx, 300xxx@x.xx, 34@x.xx, 357xx@xxxxxxxxxxxx, 3xx%2xx9x@xxxxxxxx.xx.xxx, 400xxx@x.xx, 44x@x.xxx, 5.5xxxxx@x.xxx, 500xxx@x.xx, 500xxxx@x.xx, 51072905022@xxxx, 555xxxx@555xxxx.xxx4, 5xxx%2xx2@xxxxx.xx.xxx, 600xxxx@x.xx, 60xxxxxxxxxxxxx@xxxxx, 6xxxxx@xxxxx, 7xxxx@xxxxxxx, 822xxxxxxx@x.xxx, 84@xxxxx.xxxxxxx84, x%2xx@xx.xx, x%2xxxxxxx@xxxxxxx.xxx, x%2xxxxxxx@xxxxxxxxx.xxx, x..x.x.xxxxxx@xx4xxx.xx, x..x.xxxxx@xxxxxxxxxx.xxx, x..xxxx@xxxx.xxx, x.x%2xxxxxxxxx@xxxxx.xx.xx, x.x.@xxxxx.xxx, x.x.@xxxxxxx.xx, x.x.xxxx@x.xx, x.x.xxxxx@x, x.x.xxxxx@xxxxx, x.x.xxxxxxx.xxxxxxxxxxxx@x, x.x.xxxxxxxxx@xxxxxxxx, x.x@x.x, x.x@x.xxx, x.x@xxx, x.xx@x.xxx, x.xxxxx.@xxxxxxx.xxx, x.xxxxx.xxxxxxx@xxxxxxxxxxx.x0x, x.xxxxx@x.xxx, x.xxxxx@xxxx.x, x.xxxxx@xxxxxxx.x123xx, x.xxxxx@xxxxxxxx, x.xxxxxx@x.xxx, x.xxxxxx@xxxx, x.xxxxxx@xxxxxx, x.xxxxxx@xxxxxxxxx, x.xxxxxx@xxxxxxxxxx.x0x, x.xxxxxx@xxxxxxxxxx.x123xx, x.xxxxxx@xxxxxxxxxxxx, x.xxxxxx@xxxxxxxxxxxxxxxxxx, x.xxxxxxx@x.xx, x.xxxxxxx@xxxxxxx, x.xxxxxxx@xxxxxxx.x3x, x.xxxxxxx@xxxxxxxxxx.xx., x.xxxxxxx01@xxxxx.xx9x, x.xxxxxxxx@xxxxxxx, x.xxxxxxxx@xxxxxxxxxx, x.xxxxxxxx5@xxxxx, x.xxxxxxxx80@xxxxx, x.xxxxxxxxx@x.xxx, x.xxxxxxxxx@xx.x0x, x.xxxxxxxxx1@xxxxxxx, x.xxxxxxxxxxx@xx, x.xxxxxxxxxxx@xxxxxxxxxx, x.xxxxxxxxxxxxx@x, x@1.xxx, x@x, x@x.x, x@x.xx, x@x.xxx, x@x.xxxx, x@xx.x, x@xxx, x@xxx7, x_@x.xxx, x_xxxx@xxxxxx, x_xxxxx@xxxxxxxxxx, x_xxxxxx@xxx.x123xx, x_xxxxxx@xxxxx.x, x_xxxxxxx@xxxxxxx, x_xxxxxxx@xxxxxxxxx, x_xxxxxxxx@xxx.x, x11@x.xxx, x1234567@x.xx, x2@x., x2@x.xxx, x212521@xxxxx., x2xxxxxxx@xxxxxxxxx, x3@xxxxxxxx, x3142323@x.xxx, x321@x.xx, x4xxxxx@xxxxx, x4xxxxxxx@xxxxx.xxx., x51xxxx@xxxxxxx.xxx., x6745@xxx.x132xx, x6x5x3x1962@x6x0x53.x60, x700x@xxx.x123xx, x851864@xxxxxx, x99@xxxxxxx.xxx., xx%3x54@xxxxxxx.xxx, xx..xx.xxxx@xxxxx.xxx, xx..xxxxxx@xxxxx.xxx, xx.1025@xxxxxx, xx.xxx@x.xxx, xx.xxx1@x, xx.xxxx.xxxxxxx@xxx.xxxx.x1x, xx.xxxx@xxxxxx, xx.xxxxx@x.xxx, xx.xxxxx1@x.xxx, xx.xxxxxx@xxx.x0x, xx.xxxxxx@xxxxx.x, xx.xxxxxx@xxxxxxxx, xx.xxxxxxxx@xxx, xx.xxxxxxxx@xxxxxxxxxxxxxxx, xx.xxxxxxxxx@xxxx., xx.xxxxxxxxxxxxx@xxxxxxxx, xx.xxxxxxxxxxxxxx@xxxxx, xx@x, xx@x.x, xx@x.xx, xx@x.xxx, xx@xx, xx@xxx.x3x, xx@xxxx, xx@xxxx.xxx1, xx@xxxxxx, xx@xxxxxxx, xx@xxxxxxxxx, xx@xxxxxxxxxx.x0x, xx@xxxxxxxxxxx, xx@xxxxxxxxxxx.x0x, xx@xxxxxxxxxxxx, xx@xxxxxxxxxxxxxxx, xx@xxxxxxxxxxxxxxxx, xx@xxxxxxxxxxxxxxxxx.xxx., xx_xxxxx.@xxx.xxx, xx_xxxxx@xxxxxxxxxx, xx_xxxxxx@xxxxxxxxxx, xx_xxxxxxxxx@xxxx.x, xx1035@xxxxxxxx.x0x, xx106600@xxxxx, xx1095@xxxxxxx, xx1115.xx@xxxxx, xx123@x.xxx, xx14xxx@xxxxxx, xx1877@xxxxx, xx1944@x.xxx, xx1964@xxxxx, xx2@x.xxx, xx2@xxxxxxx.x12xx, xx290@xxxxxx, xx3xxxx@xxxxxx, xx3xxxxx@xxxxxxxxx.x3x, xx4715x@xxxxx.x123xx, xx4xxxx@x.xxx, xx5664@x.xxx, xx599341@xxxxxx, xx5xx@xxx, xx761@x.xxx, xx7xxx@x.xxx, xx8x@xxxxxxxxxx, xx92733@xxx, xxx%2394299@xxx44, xxx.........xxxx@xxxxx.xxx, xxx..x1.xxxxx@xxxx.xxx, xxx..xxxx3@xxxxxxx.xxx, xxx..xxxxxxxx.xx@xxxxx.xxx, xxx.@xxx.xxx, xxx.38@x.xxx, xxx.x...x.xx@xxxxx.xxx, xxx.x.x@x.xx, xxx.xx@x.xxx, xxx.xx73@xxxxx, xxx.xxx.@xxxx.xx, xxx.xxx@xxx, xxx.xxx@xxxxxxxx, xxx.xxxx.@xxxxxxxxx.xxx, xxx.xxxx.xxxxxxxxx@xxxx, xxx.xxxx@xxxxx.x123xx, xxx.xxxx@xxxxxxxx.x0x, xxx.xxxxx.@xxx.xxx.xx, xxx.xxxxx@x, xxx.xxxxx@xxxxx, xxx.xxxxx@xxxxxxxxxxxxxx, xxx.xxxxxx@xxxxx.xxxx.x123xx, xxx.xxxxxx@xxxxxxx.x0x, xxx.xxxxxx@xx-xxxx-xxx, xxx.xxxxxx@xxxxxxxxxxxxxx., xxx.xxxxxx10@xxxxx, xxx.xxxxxx546@xxxxxxx, xxx.xxxxxxx.xxxxxxx@x, xxx.xxxxxxx@x.xx, xxx.xxxxxxx@xxx.xxx., xxx.xxxxxxx@xxxxx, xxx.xxxxxxx@xxx-xxx, xxx.xxxxxxx@xxxxxxxxxx., xxx.xxxxxxx@xxxxxxxxxxxxx.x0x, xxx.xxxxxxx77@xxxxx, xxx.xxxxxxxx@x.xxx, xxx.xxxxxxxx@xxxxxxxxx, xxx.xxxxxxxx243@xxxxx, xxx.xxxxxxxxx@xxx, xxx.xxxxxxxxx@xxxx, xxx.xxxxxxxxx@xxxxx.x0x, xxx.xxxxxxxxx@xxxxxxxxx, xxx.xxxxxxxxx@xxxxxxxxxxx.x0000xx, xxx.xxxxxxxxxx@xxxxxxxx, xxx.xxxxxxxxxxx@xxxxxx., xxx.xxxxxxxxxxxx@xx, xxx.xxxxxxxxxxxxx@xxxxx, xxx@1982, xxx@245, xxx@x.x, xxx@x.xx, xxx@x.xxx, xxx@x.xxxx, xxx@xx, xxx@xx3.x3x, xxx@xxx, xxx@xxx.xxx.1, xxx@xxx.xxx123, xxx@xxxx, xxx@xxxx.x, xxx@xxxxx, xxx@xxxxx.x213xx, xxx@xxxxxx, xxx@xxxxxx.x, xxx@xxxxxx.x123xx, xxx@xxxxxx78745, xxx@xxxxxxx, xxx@xxxxxxx.x123xx, xxx@xxxxxxxx, xxx@xxxxxxxx.x3x, xxx@xxxxxxxxx, xxx@xxxxxxxxx.0xx, xxx@xxxxxxxxx.x, xxx@xxxxxxxxxx, xxx@xxxxxxx-xxx, xxx@xxxxxxxxxxx3, xxx@xxxxxxxxxxxx, xxx@xxxxx-xxxxxxx, xxx@xxxxxxxxxxxxx, xxx@xxxxxxxxxxxxxxx, xxx@xxxxxxxxxxxxxxxx.x123xx, xxx@xxxxxxxxxxxxxxxxxxx, xxx@xxxxxxxxxxxxxxxxxxxx, xxx_15432@x.xxx, xxx_1991@xxxxxx, xxx_22xxxxxxxxx.@xxx.xx, xxx_447_@xxxxxxxxxx, xxx_77@x.xx, xxx_xx@xxxxx, xxx_xxx@x.xx, xxx_xxx@xxxxx.xxx., xxx_xxx@xxxxxxxxx, xxx_xxxxx@x.xxx, xxx_xxxxx@xxxxxxxx, xxx_xxxxx67@xxxxxxxxxx, xxx_xxxxxx@xxxxxxx., xxx_xxxxxxx@xxxxx.x0x, xxx_xxxxxxx@xxxxxxxx, xxx0006@xxxxxx.xxx., xxx001@xxxx.xxxxx.xxxx., xxx0123@xxxxxxxxxxxxxx.x213xx, xxx05@x.xxx, xxx1@x.xx, xxx1@x.xxx, xxx1@xxx, xxx1072@x.xxx, xxx111@xxx.x123xx, xxx1121@xxxxx, xxx1126@xxx, xxx123@x.xxx, xxx1291@xx2000, xxx1429@xxxxxxxxxxxx, xxx14x@xxxxxxxx, xxx150967@xxxxx.xxx., xxx168x@x, xxx1778@xxxxxxxxxx, xxx1919@xx.x0x, xxx1939@x.xxx, xxx1966@xxxxxxxx, xxx19762009@xxxxxxx, xxx1977xx@xxxxx, xxx19890527@xxxxxxx, xxx210@xxxxxx, xxx21xxx@xxxxx, xxx2323@xxx, xxx252@x.xxx, xxx2706@x.xxx, xxx2708@x.xxx, xxx279@xxxxx.x213xx, xxx2839@x.xxx, xxx28409@xxxxxxxxx.x123xx, xxx29@x.xxx, xxx2xxxx@x.xxx, xxx3@xxxxxxx.234xxx, xxx3006@x.xxx, xxx31@xxxxx., xxx333@x.xxx, xxx35@x, xxx37312@xxxxxxxx, xxx38%2x5@xxxx.xxx, xxx46xxx@xxxxxxx, xxx49@xxxxxxx, xxx4xxx@xxx, xxx5@xxxxxxxxx.x, xxx50@xxxxxxx, xxx6313@xxxxx, xxx661@xxxxx, xxx67@xxx, xxx7@x.xxx, xxx7@xxxxxxx, xxx7_xxx_xxxxx@xxxx, xxx702@xxxxxx, xxx72@xxx, xxx74502@xxx, xxx7554@xxxxxxxx, xxx765xxxxxxxx@xxx, xxx76xxxxx@x.xxx, xxx7xx%2x@xxx.xxx, xxx818254@xxxxx.xxx.xx., xxx86@xxxxxxx.x123xx, xxx9@9.xx, xxx9026@9026, xxx97334@xxxxx.xxx., xxx983@xx, xxx99@xxxxxx, xxx9999999@xx, xxxx%2xxxxxxxx@xxxxxxxxx.xxx, xxxx...2@xxxxx.xxx, xxxx..x.xxxxxx@xxx.xxxx.xxx, xxxx..x0722@xxx.xxxxx.xxx, xxxx..xxx1991@xxxxx.xxx, xxxx..xxxxxx@xxxxx.xxx, xxxx.@xxx.xxx, xxxx.x.xxxxx@xxxx.xxx., xxxx.x.xxxxxx@xxxxx.x0x, xxxx.x.xxxxxxx@xxxxx, xxxx.x.xxxxxxxx@xxxxxxxx, xxxx.x.xxxxxxxx@xxxxxxxxxx, xxxx.x@x.xxx, xxxx.xxx.@xxxxx.xxx, xxxx.xxx@xxxxx, xxxx.xxx@xxxxxxxx, xxxx.xxxx.@xxxxxx.xxx, xxxx.xxxx@x.xxx, xxxx.xxxx@xxx, xxxx.xxxx@xxxxx., xxxx.xxxx@xxxxxxx, xxxx.xxxx@x-xxxxxx.x0x, xxxx.xxxx@xxxxxxxx.x3, xxxx.xxxx@xxxxxxxxxx, xxxx.xxxx@xxxxxxxxxx.x, xxxx.xxxx_xxxxxxx@xxxxx, xxxx.xxxx01@xxxxx.x0x, xxxx.xxxxx@x.xxx, xxxx.xxxxx@xxx.x0x, xxxx.xxxxx@xxxx.x0x, xxxx.xxxxx@xxxx.xxxxx.x0x, xxxx.xxxxx@xxxxx.x123xx, xxxx.xxxxx@xxxxxx, xxxx.xxxxx@xxxxxxxx, xxxx.xxxxx@xxxxxxxxxx.x0x, xxxx.xxxxx@xxxxxxxxxxxxxxxx, xxxx.xxxxx1@xx.xxxx.x213xx, xxxx.xxxxxx.@xxxxx.xx.xx, xxxx.xxxxxx.@xxxxxxx.xxx, xxxx.xxxxxx.06@xxxxxxxx, xxxx.xxxxxx@x, xxxx.xxxxxx@x.xxx, xxxx.xxxxxx@xxx, xxxx.xxxxxx@xxx.xx.x0x, xxxx.xxxxxx@xxxx, xxxx.xxxxxx@xxxx.x123xx, xxxx.xxxxxx@xxxxx, xxxx.xxxxxx@xxxxxxx, xxxx.xxxxxx@xxxxxxxx, xxxx.xxxxxx@xxxxxxxxx, xxxx.xxxxxx@xxxxxxxxx.x0x, xxxx.xxxxxx@xxxxxxxxx.x3x, xxxx.xxxxxxx@xx.xxxx.x123xx, xxxx.xxxxxxx@xxx, xxxx.xxxxxxx@xxx.x0x, xxxx.xxxxxxx@xxx.x234xx, xxxx.xxxxxxx@xxx.xxxxx.xx.123xx, xxxx.xxxxxxx@xxxx.x0x, xxxx.xxxxxxx@xxxxx, xxxx.x'xxxxxx@xxxxx., xxxx.xxxxxxx@xxxxx.x0x, xxxx.xxxxxxx@xxxxxxxx, xxxx.xxxxxxxx.xx@xxxxxxx.x123xx, xxxx.xxxxxxxx@xx.xxxx.x123xx, xxxx.xxxxxxxx@xxx.x123xx, xxxx.xxxxxxxx@xxxx, xxxx.xxxxxxxx@xxxx.x1x, xxxx.xxxxxxxx@xxxxx, xxxx.xxxxxxxx@xxxxxxx, xxxx.xxxxxxxx@xxxxxxxx.x0x, xxxx.xxxxxxxxx@x, xxxx.xxxxxxxxx@x.xxx, xxxx.xxxxxxxxx@xxxxxxxxx, xxxx.xxxxxxxxx@xxxxxxxxxxxx, xxxx.xxxxxxxxxxx@x, xxxx.xxxxxxxxxxx@xxxxxxxx, xxxx.xxxxxxxxxxxxxx353@xxx, xxxx@127.0.0.1, xxxx@1321.0xx, xxxx@x.xx, xxxx@x.xx.x, xxxx@x.xxx, xxxx@xx, xxxx@xx2009, xxxx@xxx, xxxx@xxx.x, xxxx@xxx.x123xx, xxxx@xxx.xx.x213xx, xxxx@xxxx, xxxx@xxxx.xxx.x2, xxxx@xxxx194672946, xxxx@xxxxx, xxxx@xxxxx.x0x, xxxx@xxxxx31, xxxx@xxxxxx, xxxx@xxx-xxx, xxxx@xxxxxx.x123xx, xxxx@xxxxxxx, xxxx@xxxxxxx.3x, xxxx@xxxxxxx.x0x, xxxx@xxxxxxx.x21xx, xxxx@xxxxxxxx, xxxx@xxxxxxxx.x, xxxx@xxxxxxxx.x00000xx, xxxx@xxxxxxxxx, xxxx@xxxxxxxxx.x123xx, xxxx@xxxxxxxxx.x3x.xx., xxxx@xxxxxxxxxx, xxxx@xxxxxxx-xxx, xxxx@xxxxxxxxxxx, xxxx@xxxxxxxxxxxx, xxxx@xxxxxxxxxxxx.x, xxxx@xxxxxxxxxxxx.x0x, xxxx@xxxxxxxxxxxxx.x123xx, xxxx@xxxxxxxxxxxxxx, xxxx@xxxxxxxxxxxxxxx, xxxx@xxxxxxxxxxxxxxxxx, xxxx@xxxxxxxxxxxxxxxxxx, xxxx@xxxxxxxxxxxxxxxxxxx.x0x, xxxx@xxxxxxxxxxxxxxxxxxx-xxx, xxxx__xxxxxxxx@xxxxxxx.xxx., xxxx_21@xxxxx.x, xxxx_281@xxxxxxx, xxxx_9230@xxxxxxx.xx9x, xxxx_x@x.xx, xxxx_x3@xxxxxxxxxx, xxxx_xx3@xxxxxxxx, xxxx_xxxx104@xxxxxxxxx, xxxx_xxxx47@xxxxx, xxxx_xxxxx.xx.xxxxxx@xx, xxxx_xxxxx@xxx.xx123x, xxxx_xxxxx@xxxxx, xxxx_xxxxxx@xxxxx, xxxx_xxxxxx@xxxxx.x0x, xxxx_xxxxxx@xxxxxxxxxx, xxxx_xxxxxxx@x.xxx, xxxx_xxxxxxx@xxxxx, xxxx_xxxxxxx@xxxxxxx.x0x, xxxx_xxxxxxx_@xxxxxxx, xxxx_xxxxxxxx%3x@xxxxxx.xxx, xxxx_xxxxxxxx@xxxxx.x123xx, xxxx0@x.xxx, xxxx007@xxxxxxxx, xxxx00723@xxxxxxx, xxxx0146@xxxxx, xxxx07@xxxxx, xxxx077@xxxxx, xxxx1@x.xx, xxxx1@xxx, xxxx1@xxxxxxx, xxxx111@x.xxx, xxxx1111@xxxxxxxxxx, xxxx13@xxxxx, xxxx13@xxxxxxxx, xxxx1820@x.xxx, xxxx1958@xxx, xxxx1979@xxxx.x, xxxx1989@x.xxx, xxxx2@xxxxxxx, xxxx21@xxxxx, xxxx22@x.xxx, xxxx29@x.xx, xxxx2x@xxxxxxx.x123xx, xxxx2xxx@x.xxx, xxxx3@x.xxx, xxxx3000xx@xxxxx., xxxx316@xxx3, xxxx32605@xxxxx, xxxx32xx@xxx, xxxx36@xxxxx., xxxx39@xxxxxxxxx.x123xx, xxxx3x@xxxx.x, xxxx4@xxxxxxxx, xxxx42@xxx, xxxx45xxxxx@x.xxx, xxxx48@xxxxxxxx, xxxx480000%3x@xxxxx.xxx, xxxx5@xxxxx, xxxx51@x.xxx, xxxx52@xxxxxxxx, xxxx5201@xxxx, xxxx526@x.xxx, xxxx55@x.xxx, xxxx59@x.xxx, xxxx621@xxxxxxxxxxx, xxxx64@xxxxx, xxxx70@xxxxxxx, xxxx714@x.xxx, xxxx77@xxx.x123xx, xxxx8%2x5@xxxxx.xxx, xxxx-801@x, xxxx812@xxx, xxxx84@xxxxxxxxxx, xxxx8xxx@xxx, xxxxx%2xxxxx@xxxxxxxxx.xxx, xxxxx..x.xxxxxx@xxxxx.xxxx.xxx, xxxxx..xxxx@xxxxxxx.xxx, xxxxx..xxxxxxxx@xxxxxxxxxx.xxx, xxxxx..xxxxxxxxx@xxxxx.xxx, xxxxx..xxxxxxxxxx@xxx.xxx, xxxxx.@xxx.xxx, xx-xxx.@xxxx.xx, xxxxx.@xxxxx.xxx, xxxxx.@xxxxxx.xx, xxxxx.@xxxxxx.xxx, xxxxx.@xxxxxxx.xxx, xxxxx.@xxxxxxxx.xxx, xxxxx.x.xx.x...xxx10@xxxxx.xxx, xxxxx.x.xxx.@xxxxxxxxx.xxx, xxxxx.x.xxxx@xxxxx, xxxxx.x.xxxxx@x, xxxxx.x.xxxxx@xxxx.x0x, xxxxx.x.xxxxxxx@xxxx.x123xx, xxxxx.x.xxxxxxxxx@xxx, xxxxx.x.xxxxxxxxx@xxxx.x1x, xxxxx.x@x.xxx, xxxxx.xx.xxxxxx@2, xxxxx.xx@xxxxx., xxxxx.xx@xxxxxxxx, xxxxx.xxx@xxxxxxxx, xxxxx.xxxx.@xxxx.xxx.xx, xxxxx.xxxx.xxxxx@xxxxx.x, xxxxx.xxxx@x.xxx, xxxxx.xxxx@xxxx.x0x, xxxxx.xxxx@xxxxx., xxxxx.xxxx@xxxxx.x0x, xxxxx.xxxx@xxxxx.xxx., xxxxx.xxxx@xxxxxxxx, xxxxx.xxxx@xxxxxxxx.xxx.x3x, xxxxx.xxxx@xxx-xxxxxxxxxx, xxxxx.xxxx@xxxxxxxxxxxxxxxxxxx, xxxxx.xxxxx%2xxxx@xxxx.xxx, xxxxx.xxxxx.@xxxxx.xxx., xxxxx.xxxxx.xxxxxx@xxx.xx., xxxxx.xxxxx@x, xxxxx.xxxxx@x.xxx, xxxxx.xxxxx@xxx, xxxxx.xxxxx@xxxx, xxxxx.xxxxx@xxxxx, xxxxx.xxxxx@xxxxx.x0x, xxxxx.xxxxx@xxxxx.xxx., xxxxx.xxxxx@xxxxxx, xxxxx.xxxxx@xxxxxxx, xxxxx.xxxxx@xxxxxxxx, xxxxx.xxxxx@xxxxxxxxx-xxxxxxxx, xxxxx.xxxxxx..@xxx.xxx, xxxxx.xxxxxx@x.xxx, xxxxx.xxxxxx@xxxx.x1x, xxxxx.xxxxxx@xxxxx, xxxxx.xxxxxx@xxxxxx.x0x, xxxxx.xxxxxx@xxxxxxx, xxxxx.xxxxxx@xxxxxxxx, xxxxx.xxxxxx@xxxxxxxx.xxx.xx., xxxxx.xxxxxx@xxxxxxxxx.x3x, xxxxx.xxxxxx@xxxxxxxxxx.xxx., xxxxx.xxxxxx@xxxxxxxxxxxxxxxx.xx., xxxxx.xxxxxx21@xxxxx, xxxxx.xxxxxxx.@xxxxx.xxx.xxx, xxxxx.xxxxxxx@x.xxx, xxxxx.xxxxxxx@xxxx.xxxxxxx., xxxxx.xxxxxxx@xxxxx, xxxxx.xxxxxxx@xxxxx.x123xx, xxxxx.xxxxxxx@xxxxxx.xxxã‚â, xxxxx.xxxxxxx52@xxxxxxxx, xxxxx.xxxxxxxx.@xxxxx.xxx, xxxxx.xxxxxxxx.@xxxxx.xxx., xxxxx.xxxxxxxx@x, xxxxx.xxxxxxxx@x.xxx, xxxxx.xxxxxxxx@xxx., xxxxx.xxxxxxxx@xxxxx, xxxxx.xxxxxxxx@xxxxx.xxx., xxxxx.xxxxxxxx@xxxxxxx, xxxxx.xxxxxxxx@xxxxxxx.0xx, xxxxx.xxxxxxxx@xxxxxxxxxx.x0x, xxxxx.xxxxxxxxx.xxx@xxxxxxxxxxx, xxxxx.xxxxxxxxx@xx, xxxxx.xxxxxxxxx@xxxxx, xxxxx.xxxxxxxxx@xxxxx., xxxxx.xxxxxxxxx@xxxxxx, xxxxx.xxxxxxxxx@xxxxxxxxx.xxx0., xxxxx.xxxxxxxxx@xxxxxxxxxx, xxxxx.xxxxxxxxx@xxxxxxxxxxxx, xxxxx.xxxxxxxxx3@xxxxx.x0x, xxxxx.xxxxxxxxxx@xxxx, xxxxx.xxxxxxxxxxx.@xxxx.xxx, xxxxx.xxxxxxxxxxx@x, xxxxx.xxxxxxxxxxxxxx@xx, xxxxx@127.0.0.1, xxxxx@20, xxxxx@3.xxx, xxxxx@x, xxxxx@x.xx, xxxxx@x.xxx, xxxxx@xx, xxxxx@xx.x, xxxxx@xx.x0x, xxxxx@xx.x123xx, xxxxx@xx.xxx., xxxxx@xx2009, xxxxx@xx4xxxx, xxxxx@xxx, xxxxx@xxx.x, xxxxx@xxx.x0x, xxxxx@xxx.x10x, xxxxx@xxx.xx3, xxxxx@xxx.xxx., xxxxx@xxxx, xxxxx@xxxx.x123xx, xxxxx@xxxx.xxx.x5x, xxxxx@xxxx2, xxxxx@xxxxx, xxxx-x@xxxxx, xxxxx@xxxxx., xxxxx@xx-xxx.x0x, xxxxx@xxxxxx, xxxxx@xxxxxx.x0x, xxxxx@xxxxxxx, xxxxx@xxxxxxx.x0x, xxxxx@xxxxxxxx, xxxxx@xxx-xxx-xx, xxxxx@xxxxxxxx., xxxxx@xxxxxxxxx, xxxxx@xxxxx-xxxx, xxxxx@xxxxxxxxx.x, xxxxx@xxxxxxxxx.x3x, xxxxx@xxxxxxxxxx, xxxxx@xxxxxxxxxx.x0x, xxxxx@xxxxxxxxxx.xxx.xx., xxxxx@xxxxxxxxxxx, xxxxx@xxxxxxxxxxxx, xxxxx@xxxxx-xxxx-xxx, xxxxx@xxxxx-xxxxxxx.x1212xx, xxxxx@xxxxxxxxxxxxx, xxxxx@xxxxxxxxxxxxxx, xxxxx@xxxxxxxxxxxxxx2xx, xxxxx@xxxxxxxxxxxxxxxx, xxxxx@xxxxxxx-xxxxxxxxx, xxxxx@xxxxxxxxxxxxxxxx9xx, xxxxx@xxxxxxxxxxxxxxxxxxx, xxxxx_81@xxxxx.xx., xxxxx_9@x.xxx, xxxxx_9@xxxxx.xxx6, xxxxx_x_xxxxxxxx@x.xxx, xxxxx_xxxx@x.xx, xxxxx_xxxx@xxxxx.x0x, xxxxx_xxxx@xxxxxxxxxxxx, xxxxx_xxxx007@xxxxx., xxxxx_xxxx1969@xxxxxxx, xxxxx_xxxxx_x@xxx.x123xx, xxxxx_xxxxxx@xxxxx, xxxxx_xxxxxx@xxxxxxx, xxxxx_xxxxxx@xxxxxxx.x123xx, xxxxx_xxxxxx@xxxxxxxxxx, xxxxx_xxxxxxx@xxxx, xxxxx_xxxxxxx@xxxxx28, xxxxx_xxxxxxx@xxxxxx, xxxxx_xxxxxxx@xxxxxxx, xxxxx_xxxxxxxx@x.xxx, xxxxx_xxxxxxxxx@xxxxxxx, xxxxx_xxxxxxxxxxx@xxxxxxxx, xxxxx0@xxxxx, xxxxx001@xx, xxxxx007@x.xxx, xxxxx008@x.xx, xxxxx013@xxx, xxxxx0215@xxxxxxxxxx, xxxxx05@xxxxxxxx, xxxxx0513@xxxxxxxx, xxxxx06@xxxxx, xxxxx07@xxxxxxx, xxxxx1@x.xxx, xxxxx1@xx, xxxxx1@xxx, xxxxx1@xxxx, xxxxx1@xxxxxx, xxxxx1@xxxxxxx, xxxxx1@xxxxxxxxx.x123xx, xxxxx100@xxx, xxxxx1061@x.xxx, xxxxx1123@x.xxx, xxxxx114@xxxxx, xxxxx12@xxx.x123xx, xxxxx1206@xxxxxxxx, xxxxx126@x.xxx, xxxxx150@xxxxxxx, xxxxx16@x.xxx, xxxxx16@xxx, xxxxx1633@xxxxxxx., xxxxx1961@xxx, xxxxx1968@x.xxx, xxxxx1983@xxxxx, xxxxx2@x.xxx, xxxxx2@xxxxx, xxxxx2000@x.xxx, xxxxx2000@xxx.x123xx, xxxxx2002@xxxxxxxx, xxxxx2008@x.xx, xxxxx2009@xxxxx, xxxxx22@xxx, xxxxx240@xxxxx, xxxxx28@xxxxxx, xxxxx2x@xxxxx.x0x, xxxxx2xx@xxx., xxxxx2xxxxxxxxxxx@xxxxxxxxxxxxxxxxxxx, xxxxx3.xxxxx@xxxxx, xxxxx3@xxx, xxxxx3@xxxxxxx., xxxxx30@xxxxx.x0x, xxxxx3000@xxxxxxx., xxxxx302@xxx, xxxxx31@xxxxxxx.x3x, xxxxx34@xxxxxxx, xxxxx346@x.xxx, xxxxx44@xxxxxx, xxxxx453.@xxxxx.xxx, xxxxx47.02@xxxxx, xxxxx4xxxx@xxxxx, xxxxx53@xxxx, xxxxx54@xxxxx.x0x, xxxxx55@xxxxxxx, xxxxx58750@x.xxx, xxxxx590@xxx.x0x, xxxxx5901@xxxxx, xxxxx6@x.xxx, xxxxx63@xxxxx, xxxxx63@xxxxxx, xxxxx64@xxx, xxxxx6862@xxxxxxxx, xxxxx6x@xxxxxxx, xxxxx7@xxxxxx, xxxxx7@xxxxxxxx, xxxxx713@x.xxx, xxxxx728@xxxxxxxxx.xxx., xxxxx75@xx.xxx., xxxxx777@x.xx, xxxxx777@xxxxx.xxx., xxxxx8@x.xxx, xxxxx80@xxxxxxx.x0x, xxxxx901@xxxxxx, xxxxx925@xxxxxxxxxx, xxxxx99@xxxxxxxxxx, xxxxx9903@xxxxx.x9x, xxxxx99xxx@xxxxx.xxx.xx., xxxxxx%2x@xxxxxxxxxxxxx.xxx, xxxxxx%3x@xxxxxxx.xxx, xxxxxx..x.xxxxxx@xxxxx.xxx, xxxxxx..x@xxxxx.xxx, xxxxxx..xxxxxxxx@xxx69.xxxx.xxx, xxxxxx..xxxxxxxx@xxxxxxxx.xxx, xxxxxx.@xx, xxxxxx.@xxxxx.xxx, xxxxxx.@xxxxxx.xxx.xxx, xxxxxx.x.%2xxxxxx2@xxxx.xxx, xxxxxx.x..xxxx@xxxxx.xxx, xxxxxx.x.@xxxxxxxxxxxx.xxx, xxxxxx.x.xxx@xxxx, xxxxxx.x.xxxx@xxxxxxxx, xxxxxx.x.xxxxx@xxxx, xxxxxx.x.xxxxxx@xx.xxx.xxxx.x123xx, xxxxxx.x.xxxxxx@xxxx.x0x, xxxxxx.x.xxxxxxx.@xxxx.xxx, xxxxxx.x.xxxxxxx@xxxx.x0x, xxxxxx.x.xxxxxxxx@xx.xxxx.xxx., xxxxxx.x.xxxxxxxx@xxxx.x0x, xxxxxx.x.xxxxxxxx@xxxxx, xxxxxx.x@x, xxxxxx.x@x.xxx, xxxxxx.xx.55@xxxxxxxx, xxxxxx.xx@xxxxxxx.xxx., xxxxxx.xxx@xxx.xxx.xx., xxxxxx.xxx@xxxxx, xxxxxx.xxx83@xxxxx, xxxxxx.xxxx.@xxxxx.xxx, xxxxxx.xxxx.xxx@xxxxxxxxxxxx, xxxxxx.xxxx@xxxx, xxxxxx.xxxx@xxxx.x0x, xxxxxx.xxxx@xxxx.x1x, xxxxxx.xxxx@xxxxxxxx, xxxxxx.xxxx@xxxxxxxxxx.x, xxxxxx.xxxx@xxxxxxxxxx.x123xx, xxxxxx.xxxx313@xxxx, xxxxxx.xxxxx@x.xxx, xxxxxx.xxxxx@xxx.x0x, xxxxxx.xxxxx@xxxxxxxx, xxxxxx.xxxxx@xxxxxxxx.xx., xxxxxx.xxxxx@xxxxxxxxxx, xxxxxx.xxxxx@xxxxxxxxxxxxxxx.xxxx2, xxxxxx.xxxxxx@xx, xxxxxx.xxxxxx@xx.xxx.xxx., xxxxxx.xxxxxx@xx.xxxx.x1x, xxxxxx.xxxxxx@xxx.x0x, xxxxxx.xxxxxx@xxx.x123xx, xxxxxx.xxxxxx@xxxxx, xxxxxx.xxxxxx@xxxxx., xxxxxx.xxxxxx@xxxxxx.xxx.xx.x123xx, xxxxxx.xxxxxx@xxxxxxx.x0x, xxxxxx.xxxxxx@xxxxxxxxx, xxxxxx.xxxxxxx.@xxxxxxxx.xxx, xxxxxx.xxxxxxx.@xxxxxxxxxxxxx.xxx, xxxxxx.xxxxxxx@x.xx, xxxxxx.xxxxxxx@x.xxx, xxxxxx.xxxxxxx@x-3xxx, xxxxxx.xxxxxxx@xx, xxxxxx.xxxxxxx@xxxx, xxxxxx.xxxxxxx@xxxx.x0x, xxxxxx.xxxxxxx@xxxx.xxxx.x123xx, xxxxxx.xxxxxxx@xxxxxx.xxx.xx.x123xx, xxxxxx.xxxxxxx@xxxxxxxx.x, xxxxxx.xxxxxxx@xxxxxxxx.x0x, xxxxxx.xxxxxxx@xxxxxxxxx.x, xxxxxx.xxxxxxx@xxxxxxxxxx, xxxxxx.xxxxxxx@xxxxxxxx-xx, xxxxxx.xxxxxxx4@xxxxxxxx, xxxxxx.xxxxxxxx@x.xxx, xxxxxx.xxxxxxxx@xx, xxxxxx.xxxxxxxx@xxx, xxxxxx.xxxxxxxx@xxx.x, xxxxxx.xxxxxxxx@xxxxx, xxxxxx.xxxxxxxx@xxxxx.xxx., xxxxxx.xxxxxxxx@xxxxxxx.x123xx, xxxxxx.xxxxxxxx@xxxxxxxx, xxxxxx.xxxxxxxx@xxxxxxxxxx, xxxxxx.xxxxxxxx@xxxxxxxxxxx, xxxxxx.xxxxxxxxx@x, xxxxxx.xxxxxxxxx@xxxxx-xxxxxxx.x0x, xxxxxx.xxxxxxxxx@xxxxxxxxxxx-xxx.x0, xxxxxx.xxxxxxxxxx@xxx, xxxxxx.xxxxxxxxxx@xxxx.xxx-xxxxx, xxxxxx.xxxxxxxxxx@xxxxx, xxxxxx.xxxxxxxxxx@xxxxx., xxxxxx.xxxxxxxxxx@xxxxx.x, xxxxxx.xxxxxxxxxxxxxx@xxx, xxxxxx@1.xxx, xxxxxx@306, xxxxxx@x, xxx-xxx@x, xxxxxx@x.x, xxxxxx@x.xx, xxx-xxx@x.xx, xxxxxx@x.xxx, xxxxxx@xx, xxxxxx@xx51xx, xxxxxx@xxx, xxxxxx@xxx., xxxxxx@xxx.x, xxxxxx@xxx.x0x, xxxxxx@xxx.x123xx, xxxxxx@xxx.xxx., xxxxxx@xxx.xxx.xxx., xxxxxx@xxx5.x12, xxxxxx@xxxx, xxxxxx@xxxx.x, xxxxxx@xxxx21xxx, xxxxxx@xxxxx, xxxxxx@xxxxx., xxxxxx@xxxxx.x0x, xxxxxx@xxxxx.x123xx, xxxxxx@xxxxx.x132xx, xxxxxx@xxxxx.x5465xx, xxxxxx@xxxxx.xxx., xxxxxx@xxxxx.xxx.xx., xxxxxx@xxxxx.xxx2, xxxxxx@xxxxxx, xxxxxx@xxxxxx., xxxxxx@xxxxxx.x0x, xxxxxx@xxxxxx.xx.x123xx, xxxxxx@xxxxxx123.x00xx, xxxxxx@xxxxxx2, xxxxxx@xxxxxx5, xxxxxx@xxxxxxx, x-xxxxx@xxxxxxx, xxxxxx@xxxxxxx.x, xxxxxx@x-xxxxxx.x, xxxxxx@xxxxxxx.x123xx, xxxxxx@xxxxxxx.x3x, xxxxxx@xxxxxxx.xxx5, xxxxxx@xxxxxxxx, xxxxxx@xxxxx-xxx, xxxxxx@xxxx-xxxx, xxxxxx@xxxxxxxx., xxxxxx@xxxxxxxxx, xxxxxx@xxxxx-xxxx, xxxxxx@xxxxxxxxxx, xxxxxx@xxxxxxxxxxx, xxxxxx@xxxx-xxxxxxx, xxxxxx@xxxxxxxxxxx.x45xx, xxxxxx@xxxxxxxxxxxx, xxxxxx@xxxxxxxxxxxx.x0x, xxxxxx@xxxxxxxxxxxxx, xxxxxx@xxxxxxxxxxxxxx, xxxxxx@xxxxxxxxxxxxxx.x, xxxxxx@xxxxxxxxxxxxxx.x0x, xxxxxx@xxxxxxxxxxxxxx.xxx., xxxxxx@xxxxxxxxxxxxxxx, xxxxxx@xxxxxxxxxxxxxxx.x123xx, xxxxxx@xxxxxxxxxxxxxxxxx, xxxxxx@xxxxxxxxxxxxxxxxxx, xxxxxx_23@xxxxxxxxxxx, xxxxxx_234@xxxxx, xxxxxx_75%2x@xxxxxxx.xxx, xxxxxx_x@xxx, xxxxxx_x_xxxxxxx@x.xxx, xxxxxx_xx@271956, xxxxxx_xx@xxxxxxx, xxxxxx_xx@xxxxxxxx, xxxxxx_xxx@xxxxx, xxxxxx_xxxx@x, xxxxxx_xxxx@xxxxxx, xxxxxx_xxxxxx.xxxx@x, xxxxxx_xxxxxx@xx.xxx1, xxxxxx_xxxxxx@xxx, xxxxxx_xxxxxx@xxxxx, xxxxxx_xxxxxx@xxxxxxxxx, xxxxxx_xxxxxx@xxxxxxxxxx, xxxxxx_xxxxxx_2@xxxxxxxxxx, xxxxxx_xxxxxxx@xxxxx.xxx., xxxxxx_xxxxxxx20@xxxxxxx, xxxxxx001@x.xxx, xxxxxx001@xxxxx., xxxxxx01@x.xxx, xxxxxx0329@xxx.x0x, xxxxxx048@xxxxxx., xxxxxx09@xxxxx, xxxxxx1@x.xx, xxxxxx1@x.xxx, xxxxxx1@xxx.x0x, xxxxxx1@xxxxx, xxxxxx1@xxxxxxx, xxxxxx1@xxxxxxx.xxx., xxxxxx1@xxxxxxxxxx, xxxxxx10@xxxxxxx, xxxxxx100@xxxx, xxxxxx1000@xxxxx.x, xxxxxx101@xxxxx., xxxxxx102@xxxxx, xxxxxx1030@xxx, xxxxxx121@xxxxxxx, xxxxxx1218@x.xxx, xxxxxx123@xxxxx, xxxxxx123@xxxxxxx.xxx., xxxxxx12xxxx@xxxx, xxxxxx1769@xxxxxxxxx.x, xxxxxx180@x.xxx, xxxxxx1974@x.xxx, xxxxxx19840920@126., xxxxxx1xxxxx@x.xxx, xxxxxx2@x.xx, xxxxxx2@x.xxx, xxxxxx2@xxxxx, xxxxxx2@xxxxxx, xx-xxxx2@xxxxxx-xx, xxxxxx2003@xxxxxxxxxx, xxxxxx2007@xxxxxxxx, xxxxxx215@xxxxxxx, xxxxxx21xxx@xxxxx, xxxxxx22@x.xxx, xxxxxx22@xxxxxxx, xxxxxx222@xx., xxxxxx23@xxx, xxxxxx234@xxxxxxx, xxxxxx24002003@x, xxxxxx248@xxxx, xxxxxx24x@x.xxx, xxxxxx25@xxxxx, xxxxxx260@x.xxx, xxxxxx27@xxxxxxx, xxxxxx27@xxxxxxxx., xxxxxx27@xxxxxxxxxxx, xxxxxx3@x, xxxxxx3@x.xx, xxxxxx3@xxxxxx, xxxxxx312@x.xxx, xxxxxx33@xxxxx.xxx., xxxxxx35@xxxxxxxx, xxxxxx35@xxxxxxxxxx.x, xxxxxx359@x.xxx, xxxxxx365@xxxxx, xxxxxx40x@xxxxxxx, xxxxxx411@xxxxxxxx, xxxxxx4176@xxx.x123xx, xxxxxx420@xxxxxxxx, xxxxxx44@xxxxx, xxxxxx45@xxx, xxxxxx4823@xxxxxxx.x3x, xxxxxx5@x.xxx, xxxxxx51943@xxxxxxx, xxxxxx55@xxxxx, xxxxxx56@x.xxx, xxxxxx61001@xxxxxxx, xxxxxx64@x, xxxxxx65@xxxxxxxx, xxxxxx69@x, xxxxxx7@x.xxx, xxxxxx7000@x.xxx, xxxxxx7104@xxxxx, xxxxxx75@x.xxx, xxxxxx77@xxx.xxx., xxxxxx77@xxxxxx, xxxxxx77@xxxxxxx, xxxxxx77@xxxxxxxx, xxxxxx784@xxxxx, xxxxxx8@x.xxx, xxxxxx8@xxxxx.x0x, xxxxxx807@x.xxx, xxxxxx808@x.xxx, xxxxxx82@xxxxxxxxxx, xxxxxx88%2x@xxxxx.xxx, xxxxxx88@x.xxx, xxxxxx88@xxxxx, xxxxxx888@xxxxxxxx, xxxxxx9@x.xxx, xxxxxx922@xxxxxxx, xxxxxx93@xxxxxxx., xxxxxx93561@xxxxxx, xxxxxx95@x.xxx, xxxxxx98@xxxxxx, xxxxxx9x@x.xxx, xxxxxxx%3x%3x%3x%3x%3x@xxxxx.xxx, xxxxxxx..@xxxxxx.xxx, xxxxxxx..xxxxxx@xxxxxxx.xx, xxxxxxx.@xxx.xxx, xxxxxxx.@xxxxxxx.xxx, xxxxxxx.x.xxxxx@xxx.x0x, xxxxxxx.x.xxxxx@xxxxx, xxxxxxx.x.xxxxx@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, xxxxxxx.x.xxxxxx@xxxxxxxxxx.x0x, xxxxxxx.x.xxxxxx@xxxxxxxxxxx.x0x, xxxxxxx.x.xxxxxxxx@xxxx.x0x, xxxxxxx.x@xxxxx, xxxxxxx.xx.@xxxxx.xxx, xxxxxxx.xx.xxxxxx@xxxxx, xxxxxxx.xxx.xxxxx.@xxxxxxx.xxx, xxxxxxx.xxx@xxxxx, xxxxxxx.xxxx@xxxxx, xxxxxxx.xxxx@xxxxx.xxx., xxxxxxx.xxxx@xxxxxxxx, xxxxxxx.xxxxx.xxxxx@xx.xxx.xxxx.x123xx, xxxxxxx.xxxxx@xxxxx, xxxxxxx.xxxxx@xxxxxxx, xxxxxxx.xxxxx@xxxxxxx.x0x, xxxxxxx.xxxxx@xxxxxxxx, xxxxxxx.xxxxxx@xxxxxx, xxxxxxx.xxxxxx@xxxxxxx, xxxxxxx.xxxxxx@xxxxxxx., xxxxxxx.xxxxxx@xxxxxxxx.x0x, xxxxxxx.xxxxxx@xxxxxxxxxx, xxxxxxx.xxxxxx@xxxxxxxxxxxxx, xxxxxxx.xxxxxx79@xxxxx, xxxxxxx.xxxxxxx@xx.xxxx.x123xx, xxxxxxx.xxxxxxx@xxx, xxxxxxx.xxxxxxx@xxxx.x1x, xxxxxxx.xxxxxxx@xxxxx.x123xx, xxxxxxx.xxxxxxx@xxxxxxx.x123xx, xxxxxxx.xxxxxxx@xxxxxxxx, xxxxxxx.xxxxxxx@xxxxxxxx.x0x, xxxxxxx.xxxxxxx12@xxxxxxxx, xxxxxxx.xxxxxxxx@xxxx.x0x, xxxxxxx.xxxxxxxx@xxxxxxxx, xxxxxxx.xxxxxxxx@xxxxxxxxxx, xxxxxxx.xxxxxxxxx@xxx, xxxxxxx.xxxxxxxxx@xxxx.x, xxxxxxx.xxxxxxxxx@xxxxx.x0x, xxxxxxx.xxxxxxxxxx@xxx, xxxxxxx.xxxxxxxxxx@xxxxx, xxxxxxx.xxxxxxxxxx@xxxxx.x, xxxxxxx.xxxxxxxxxxx@xxxxxxx, xxxxxxx@x, xxxxxxx@x.xx, xxxxxxx@x.xxx, xxxxxxx@xx, xxxxxxx@xx.xxx.xx., xxxxxxx@xxx, xxxxxxx@xxx., xxxxxxx@xxx.234xxx, xxxxxxx@xxx.x0x, xxxxxxx@xxx.x1234xx, xxxxxxx@xxx.x123xx, xxxxxxx@xxx.x213xx, xxxxxxx@xxx.xx., xxxxxxx@xxx.xx1, xxxxxxx@xxxx, xxxxxxx@xxxx.x, xxxxxxx@xxxx.x123xx, xxxxxxx@xxxx.xx.x0x, xxxxxxx@xxxx.xx0x, xxxxxxx@xxxx123, xxxxxxx@xxxxx, xxxxxxx@xx-xxx, xxxxxxx@xxxxx., xxxxxxx@xxxxx.x, xxxxxxx@xxxxx.x0x, xxxxxxx@xxxxx.x123xx, xxxxxxx@xxxxx.x3x, xxxxxxx@xxxxx.xxx., xxxxxxx@xxxxx.xxx.xx., xxxxxxx@xxxxx.xxxxxxx.3xx, xxxxxxx@xxxxxx, xxxxxxx@xxx-xxx, xxxxxxx@xxxxxx.x0x, xxxxxxx@xxxxxx.x123xx, xxxxxxx@xxxxxx.xx.x234xx, xxxxxxx@xxxxxx.xxx., xxxxxxx@xxxxxxx, xxxxxxx@xxxxxxx.x, xxxxxxx@xxxxxxx.x123xx, xxxxxxx@xxxxxxx.x3x, xxxxxxx@xxxxxxx.xxx., xxxxxxx@xxxxxxxx, xxxxxxx@xxxxxxxx.90., xxxxxxx@xxxxxxxx.x123xx, xxxxxxx@xxxxxxxx.x213xx, xxxxxxx@xxxxxxxxx, xxxxxxx@xxxxxxxxx.x0x, xxxxxxx@xxxxxxxxx.x123xx, xxxxxxx@xxxxxxxxx.x3x, xxxxxxx@xxxxxxxxx.xx123x, xxxxxxx@xxxxxxxxx.xxx.8xx, xxxxxxx@xxxxxxxxxx, xxxxxxx@xxxxxxxxxx.x0x, xxxxxxx@xxxxxxxxxx.xxx1, xxxxxxx@xxxxxxxxxxx, xxxxxxx@xxxxxxxxxxx.x3x, xxxxxxx@xxxxxxxxxxxx, xxxxxxx@xxxxxxxxxxxxx, xxxxxxx@xxxxxxxxxxxxxx, xxxxxxx@xxx-xxxxxxxxxxx, xxxxxxx@xxxxxxxxxxxxxxxx, xxxxxxx@xxxxxxxxxxxxxxxxx, xxxxxxx_1@x.xxx, xxxxxxx_2000@xxxxxxx, xxxxxxx_29@xxxxxxx, xxxxxxx_3000@x.xx, xxxxxxx_76@xxxxx, xxxxxxx_x@xxxx.xxx.x2, xxxxxxx_xxx@x.xxx, xxxxxxx_xxxx_@xxx.x, xxxxxxx_xxxxx@xxxxx, xxxxxxx_xxxxx@xxxxxxx, xxxxxxx_xxxxxxx@x.xxx, xxxxxxx_xxxxxxx@xxxxxxx.x, xxxxxxx007@x.xxx, xxxxxxx1@9697xx, xxxxxxx1@x.xx, xxxxxxx1@x.xxx, xxxxxxx1@xxxx, xxxxxxx1@xxxxxxx, xxxxxxx1@xxxxxxx., xxxxxxx1@xxxxxxxx.xx.xxx., xxxxxxx1@xxxxxxxxxx, xxxxxxx1@xxxxxxxxxxxx, xxxxxxx10@x.xxx, xxxxxxx12@xxx, xxxxxxx12@xxxxxxxx, xxxxxxx1238@x.xxx, xxxxxxx15@xxxxxxxxxx, xxxxxxx16@xxxxx, xxxxxxx18@x.xxx, xxxxxxx184@xxxxxxxx, xxxxxxx1956@xxxxxxxx, xxxxxxx2@193.17.41.103, xxxxxxx2@193.17.41.85, xxxxxxx2@x.xxx, xxxxxxx2@xxx, xxxxxxx2@xxxx, xxxxxxx2@xxxxxxx.x0x, xxxxxxx2@xxxxxxxx, xxxxxxx20@x.xx, xxxxxxx20@xxxxxxx, xxxxxxx2001@xxxxx, xxxxxxx2003@xxxxx.x0x, xxxxxxx2007@x.xx, xxxxxxx217@xxxxx, xxxxxxx222@xxxxxxx, xxxxxxx25@xxxxx, xxxxxxx254@xxxxxxx, xxxxxxx266@xxxxx.xx., xxxxxxx3@x.xxx, xxxxxxx3@xxxxx, xxxxxxx3@xxxxxxxx, xxxxxxx32@x.xxx, xxxxxxx33@xxxxx, xxxxxxx33@xxxxxxx, xxxxxxx34@x.xxx, xxxxxxx39@x.xxx, xxxxxxx3xxxxx@xxxxxxxx, xxxxxxx4@xxx.x3x, xxxxxxx40@x.xxx, xxxxxxx44xxxx@xxxxx.x123xx, xxxxxxx46@xxxx, xxxxxxx478@xxx, xxxxxxx482..5@xxxxx.xxx, xxxxxxx49@xxxxxxxxxx, xxxxxxx5@xxxxx., xxxxxxx5040@xxxxxxx, xxxxxxx5071@xxxxx.xx0x, xxxxxxx55@xxxxxxx, xxxxxxx57@xxxxx.x, xxxxxxx583@x.xxx, xxxxxxx65@xxxxx.x0x, xxxxxxx69@xxxxx, xxxxxxx7@x.xxx, xxx-xxxx-76@x.xxx, xxx-xxxx-76@x.xxxx, xxxxxxx76@xxxxx, xxxxxxx76@xxxxxxx, xxxxxxx768@xxxxx.x123xx, xxxxxxx777@xxx., xxxxxxx777@xxxxx, xxxxxxx8@xxxxxxx., xxxxxxx82@xxxxxxx, xxxxxxx90@xxxxx.x, xxxxxxx927@xxxxx, xxxxxxx94@xxxxxxxx, xxxxxxx974@xxx.x231xx, xxxxxxx99@xxxxxxx.xxx., xxxxxxxx%2x@xxxxxx.xxx.xx, xxxxxxxx%2xxxxx@xxx.xx, xxxxxxxx.@xxxx.xx, xxxxxxxx.@xxxxx.xxx, xxxxxxxx.@xxxxxx.xxx, xxxxxxxx.@xxxxxxx.xxx, xxxxxxxx.x.xxxxx@xxxxxxxx.x0x, xxxxxxxx.xx@xxxxxxx.x0x, xxxxxxxx.xxx@xxx.x123xx, xxxxxxxx.xxxx.xx@xx, xxxxxxxx.xxxx@xx, xxxxxxxx.xxxx@xxxxx, xxxxxxxx.xxxx@xxxxxxxxxx.x123xx, xxxxxxxx.xxxxx.@xxx.xx, xxxxxxxx.xxxxx@xxx., xxxxxxxx.xxxxx@xxxx.x0x, xxxxxxxx.xxxxx@xxxxx.xxx., xxxxxxxx.xxxxx@xxxxxxxxx., xxxxxxxx.xxxxxx@xx.xxxx.x123xx, xxxxxxxx.xxxxxx@xxx, xxxxxxxx.xxxxxx@xxxx., xxxxxxxx.xxxxxx@xxxxx, xxxxxxxx.xxxxxx@xxxxxxxxxx.xxxxx., xxxxxxxx.xxxxxx@xxxxx-xxxxxx, xxxxxxxx.xxxxxx15@xxxxx.x, xxxxxxxx.xxxxxxx.@xxxxx.xxxx.xxx, xxxxxxxx.xxxxxxxx.@xx.xxxx.xxx, xxxxxxxx.xxxxxxxx@x, xxxxxxxx.xxxxxxxx@xxx, xxxxxxxx.xxxxxxxx4@xxxx, xxxxxxxx.xxxxxxxxx@xxxxx, xxxxxxxx@1.xxx, xxxxxxxx@123, xxxxxxxx@2xxxxx, xxxxxxxx@x, xxxxxxxx@x.xx, xxxxxxxx@x.xxx, xxxxxxxx@x.xxxx, xxxxxxxx@xx, xxxxxxxx@xx.x, xxxxxxxx@xx.xxxx.x0x, xxxxxxxx@xx.xxxxx.3xx, xxxxxxxx@xx.xxxxx.x123xx, xxxxxx-xx@xx74xx, xxxxxxxx@xxx, xxxxxxxx@xxx., xxxxxxxx@xxx.x, xxxxxxxx@xxx.x0x, xxxxxxxx@xxx.x123xx, xxxxxxxx@xxx.x234xx, xxxxxxxx@xxx.xxx., xxxxxxxx@xxx.xxxx.x123xx, xxxxxxxx@xxx69.xxxx.x132xx, xxxxxxxx@xxxx, xxxxxxxx@xxxx.0xx, xxxxxxxx@xxxx.x, xxxxxxxx@xxxx.xx.xx., xxxxxxxx@xxxx.xxxx.x0x, xxxxxxxx@xxxxx, xxxxxxxx@xxxxx., xxxxxxxx@xxxxx.9xx, xxxxxxxx@xxxxx.x, xxxxxxxx@xxxxx.x0x, xxxxxxxx@xxxxx.x123xx, xxxxxxxx@xxxxx.x45xx, xxxxxxxx@xxxxx.xxx., xxxxxxxx@xxxxx.xxx1234, xxxxxxxx@xxxxx.xxxxxxx1234, xxxxxxxx@xxxxxx, xxxxxxxx@xxxxxx.x, xxxxxxxx@xxxxxx.xxxx.x123xx, xxxxxxxx@xxxxxxx, xxxxxxxx@xxxxx-xx, xxx-xxxxx@xxxxxxx.x, xxxxxxxx@xxxxxxx.x123xx, xxxxxxxx@xxxxxxx.x3x, xxxxxxxx@xxxxxxx.x45xx, xxxxxxxx@xxxxxxx.xxx., xxxxxxxx@xxxxxxxx, xxxxxxxx@xxxxx-xxx, xxxxxxxx@xxxxxxxx.x123xx, xxxxxxxx@xxxxxxxxx, xxxxxxxx@xxxxxxxxx.0xx, xxxxxxxx@xxxxxxxxx.x3x, xxxxxxxx@xxxxxxxxxx, xxxxxxxx@xxx-xxxxxxx, xxxxxxxx@xxxxxxxxxx.x123xx, xxxxxxxx@xxxxxxxxxxx, xxxxxxxx@xxx-xxxxxxxx, xxxxxxxx@xxxxxxxxxxx.x123xx, xxxxxxxx@xxxxxxxxxxxx, xxxxxxxx@xxx-xxxxxxx-xx, xxxxxxxx@xxxxxxxxxxxx., xxxxxxxx@xxxxxxxxxxxx.x123xx, xxxxxxxx@xxxxxxxxxxxxx, xxxxxxxx@xxxxxxxxxxxxxx, xxxxxxxx@xxxxxxxx-xxxxxx, xxxxxxxx@xxxxxxxxxxxxxx@xxx.xxx, xxxxxxxx@xxxxxxxxxxxxxxx, xxxxxxxx@xxxxxxxxxxxxxxxx.x0x, xxxxxxxx@xxxxxxxxxxxxxxxxxxx, xxxxxxxx@xxxxxxxxxxxxxxxxxxxx, xxxxxxxx_121@xxxxxxxxxx, xxxxxxxx_1980@xxxxxxx, xxxxxxxx_2@x.xxx, xxxxxxxx_xxxx95@xxxxx, xxxxxxxx_xxxxx@xxxxxxxxxx, xxxxxxxx_xxxxxx@xxxxx.x123xx, xxxxxxxx_xxxxxxx@xxxxx-xxx, xxxxxxxx_xxxxxxxx@xxxxx.xxx., xxxxxxxx_xxxxxxxx2009@xxxxx, xxxxxxxx001@xxxxxxx.x123xx, xxxxxxxx001@xxxxxxxxxx-xxx, xxxxxxxx03@xxxxx.xxx., xxxxxxxx06@xxxxxxxxxx, xxxxxxxx07@x.xxx, xxxxxxxx07@xxxxxxxxxx, xxxxxxxx08@x.xxx, xxxxxxxx1@x.xx, xxxxxxxx1@x.xxx, xxxxxxxx1@xxxxx, xxxxxxxx1@xxxxxxx.9xx, xxxxxxxx1@xxxxxxxx, xxxxxxxx1@xxxxxxxxxxx, xxxxxxxx11@xx, xxxxxxxx11@xxxxx.xxx-123456, xxxxxxxx12@xxxxx, xxxxxxxx12@xxxxxxx., xxxxxxxx13@xxx.x123xx, xxxxxxxx13@xxxxx, xxxxxxxx133@xxxxx, xxxxxxxx14@xxx, xxxxxxxx14@xxxxx, xxxxxxxx16@x.xxx, xxxxxxxx1738@xxxxxxx.x123xx, xxxxxxxx18@xxx, xxxxxxxx1953@xxxxxxx, xxxxxxxx2@xxxxxxxx, xxxxxxxx2000@xx, xxxxxxxx2000@xxxxx, xxxxxxxx2002@xxxxxxxx, xxxxxxxx2007@x.xx, xxxxxxxx2008@xxxxxxxx, xxxxxxxx2011@x.xxx, xxxxxxxx234@xxxxx.x0x, xxxxxxxx24x@x.xxx, xxxxxxxx28@xxx, xxxxxxxx28@xxxxx, xxxxxxxx3@x.xxx, xxxxxxxx3@xxxxx.x, xxxxxxxx32@xxxxxxxxxx.x123xx, xxxxxxxx33@xxx.x123xx, xxxxxxxx37@xx, xxxxxxxx38@xxxxx, xxxxxxxx38@xxxxx.x0x, xxxxxxxx4@x.xxx, xxxxxxxx422@x.xxx, xxxxxxxx44@x.xxx, xxxxxxxx45@xxxxx.x0x, xxxxxxxx47@x.xxx, xxxxxxxx4xx@xxxxx, xxxxxxxx50@xxx.xxx., xxxxxxxx56@xxxxx, xxxxxxxx57@x.xxx, xxxxxxxx6.@xxxxx.xxx, xxxxxxxx6@xxx.x123xx, xxxxxxxx60@x.xxx, xxxxxxxx60@xxx, xxxxxxxx61@x, xxxxxxxx616@xxx, xxxxxxxx63@xxxxxxxx, xxxxxxxx635@xxxxx, xxxxxxxx643@xxxxx.x123xx, xxxxxxxx66@xxxxx, xxxxxxxx70@x.xx, xxxxxxxx70@xxxxxxx.x3x, xxxxxxxx71@x.xxx, xxxxxxxx757@xxxxxxxxxx, xxxxxxxx76@x.xxx, xxxxxxxx76@xxxxxxxx, xxxxxxxx777@xxxxxxx, xxxxxxxx78@xxxxxxxxx.x12xx, xxxxxxxx79@xxxxx, xxxxxxxx84@xxxxxxxxxxxx, xxxxxxxx908@x.xxx, xxxxxxxx92@x.xxx, xxxxxxxx99@xxxxx.x0x, xxxxxxxxx%3x_x22@xxxxxxx.xxx, xxxxxxxxx.@xxxx.xxx, xxxxxxxxx.@xxxx.xxxxxx.xxx, xxxxxxxxx.x@xxxxx, xxxxxxxxx.xx@xxxxxxxxxxx, xxxxxxxxx.xxxx@xx, xxxxxxxxx.xxxx@xxxxxxxxxx, xxxxxxxxx.xxxxxx@x.xx, xxxxxxxxx.xxxxxx@xxxx, xxxxxxxxx.xxxxxx@xxxxxxx, xxxxxxxxx.xxxxxxx@xxxxx.x, xxxxxxxxx.xxxxxxx@xxxxxxxxxxxxxxxxx.x, xxxxxxxxx.xxxxxxxx@xxxxxx, xxxxxxxxx.xxxxxxxxx@xxx.x0x, xxxxxxxxx.xxxxxxxxxxxxxxx@x, xxxxxxxxx@0410, xxxxxxxxx@200xxxxxxxxxxx, xxxxxxxxx@x, xxxxxxxxx@x.xx, xxxxxxxxx@x.xxx, xxxxxxxxx@xx, xxxxxxxxx@xxx, xxxxxxxxx@xxx.123xxx, xxxxxxxxx@xxx.x, xxxxxxxxx@xxx.x123xx, xxxxxxxxx@xxx.xx.x123xx, xxxxxxxxx@xxx.xxx., xxxxxxxxx@xxx123, xxxxxxxxx@xxxx, xxxxxxxxx@xxxx.xxxxxx.xxx.xx., xxxxxxxxx@xxxxx, xxxxxxxxx@xxxxx., xxxxxxxxx@xxxxx.x, xxxxxxxxx@xxxxx.x0x, xxxxxxxxx@xxxxx.x123xx, xxxxxxxxx@xxxxx.xxx., xxxxxxxxx@xxxxx.xxx.xx., xxxxxxxxx@xxxxx.xxx.xxxx1234, xxxxxxxxx@xxxxxx, xxxxxxxxx@xxxxxxx, xxxxxxxxx@xxxxxxx.x0x, xxxxxxxxx@xxxxxxx.x123xx, xxxxxxxxx@xxxxxxx.x213xx, xxxxxxxxx@xxxxxxx.x3x, xxxxxxxxx@xxxxxxx.xx., xxxxxxxxx@xxxxxxx.xxx., xxxxxxxxx@xxxxxxx.xxx-xx, xxxxxxxxx@xxxxxxx7xx, xxxxxxxxx@xxxxxxxx, xxxxxxxxx@xxxxx-xxx, xxxxxxxxx@xxxxxxxx.x, xxxxxxxxx@xxxxxxxx.x123xx, xxxxxxxxx@xxxxxxxx.x3x, xxxxxxxxx@xxxxxxxx.xx.x0x, xxxxxxxxx@xxxxxxxx.xxx.x123xx, xxxxxxxxx@xxxxxxxxx, xxxxxxxxx@xxxxxxxxx.x123xx, xxxxxxxxx@xxxxxxxxx.x3x, xxxxxxxxx@xxxxxxxxx.xxx6, xxxxxxxxx@xxxxxxxxxx, xxxxxxxxx@xxxxxxxxxx., xxxxxxxxx@xxxxxxxxxx.x1232xx, xxxxxxxxx@xxxxxxxxxxx, xxxxxxxxx@xxxxxxxxxxx.0xx, xxxxxxxxx@xxxxxxxxxxx.x0x, xxxxxxxxx@xxxxxxxxxxx.xxx., xxxxxxxxx@xxxxxxxxxxxx, xxxxxxxxx@xxxxxxxxxxxxx, xxxxxxxxx@xxxxxxxxxxxxx.1x, xxxxxxxxx@xxxxxxxxxxxxxx, xxxxxxxxx@xxxxxxxxxxxxxxx, xxxxxxxxx@xxxxxxxxxxxxxxxx54, xxxxxxxxx@xxxxxxxxxxxxxxxxxxxx, xxxxxxxxx_89@xxxxxxx., xxxxxxxxx_xxxxxx@xxxxx, xxxxxxxxx03@xxxxx, xxxxxxxxx04@x.xxx, xxxxxxxxx05@xxxxx, xxxxxxxxx08@x.xxx, xxxxxxxxx1@x, xxxxxxxxx1@x.xx, xxxxxxxxx1@xxxxx, xxxxxxxxx1@xxxxxxx.x123xx, xxxxxxxxx1@xxxxxxxxxx, xxxxxxxxx103@xxx, xxxxxxxxx1031@xxxxxxx, xxxxxxxxx107@xxxxxxxx, xxxxxxxxx11@x.xxx, xxxxxxxxx12@xxxxxxxx, xxxxxxxxx122203@xxxxxxx., xxxxxxxxx13387@xxxxxxx.x123xx, xxxxxxxxx17@xxxxxxxxxx, xxxxxxxxx179@xxxxxxxx, xxxxxxxxx1966@xxxxxxxxxx, xxxxxxxxx1979@x.xx, xxxxxxxxx1998@xxxxx.x0x, xxxxxxxxx2@x.xxx, xxxxxxxxx2000@xxxxx, xxxxxxxxx2570@xxxx., xxxxxxxxx3@xxxxx.xxx., xxxxxxxxx3@xxxxxxxx, xxxxxxxxx30@xxxxxxx, xxxxxxxxx35@x, xxxxxxxxx4@x.xxx, xxxxxxxxx4@xxxx, xxxxxxxxx41@xxxxx, xxxxxxxxx45@x.xxx, xxxxxxxxx50@x, xxxxxxxxx547@xxxxxxx, xxxxxxxxx57@xxxxxxx, xxxxxxxxx58@xxxxx, xxxxxxxxx61@x.xxx, xxxxxxxxx64@x.xxx, xxxxxxxxx649@xxxxx., xxxxxxxxx696@xxxxxx, xxxxxxxxx7@xxx, xxxxxxxxx710.@xxx.xxx, xxxxxxxxx78@xxxxxxx, xxxxxxxxx83@xxxxxxxx, xxxxxxxxx8609@x.xxx, xxxxxxxxx88@xxxxx, xxxxxxxxx99@xxx, xxxxxxxxx99@xxxxx, xxxxxxxxx999@x.xxx, xxxxxxxxxx%2x1@xxxx.xxx, xxxxxxxxxx.@xxx.xxx, xxxxxxxxxx.@xxxxx.xxx, xxxxxxxxxx.@xxxxxx.xx.xxx, xxxxxxxxxx.x.xxxxx@xxxxx., xxxxxxxxxx.x@xxxxxxx, xxxxxxxxxx.xx.xx@xx, xxxxxxxxxx.xxx@xxxx, xxxxxxxxxx.xxxxxx@x.xxx, xxxxxxxxxx.xxxxxxxx@x, xxxxxxxxxx@19659, xxxxxxxxxx@x, xxxxxxxxxx@x.xx, xxxxxxxxxx@x.xxx, xxxxx-xxxxx@x.xxx, xxxxxxxxxx@x.xxxxxxx, xxxxxxxxxx@xx, xxxxxxxxxx@xx.xxxxxxxx.xxx., xxxxxxxxxx@xxx, xxxxxxxxxx@xxx., xxxxxxxxxx@xxx.x0x, xxxxxxxxxx@xxx.x123xx, xxxxxxxxxx@xxx.x132xx, xxxxxxxxxx@xxx.x13xx, xxxxxxxxxx@xxx.x3x, xxxxxxxxxx@xxx.xx9x, xxxxxxxxxx@xxx.xxx., xxxxxxxxxx@xxxx, xxxxxxxxxx@xxxx.xxx.3xx, xxxxxxxxxx@xxxxx, xxxxxxxxxx@xxxxx., xxxxxxxxxx@xxxxx.x0x, xxxxxxxxxx@xxxxx.xxx., xxxxxxxxxx@xxxxx1948, xxxxxxxxxx@xxxxxx, xxxxxxxxxx@xxx-xxx, xxxxxxxxxx@xxxxxx.xxx.x12, xxxxxxxxxx@xxxxxxx, xxxxxxxxxx@xxxxxxx., xxxxxxxxxx@xxxxxxx.x, xxxxxxxxxx@xxxxxxx.x0x, xxxxxxxxxx@xxxxxxx.x3x, xxxxxxxxxx@xxxxxxxx, xxxxxxxxxx@xxxxxxxx.x123xx, xxxxxxxxxx@xxxxxxxxx, xxxxxxxxxx@xxxxxxxxx.x, xxxxxxxxxx@xxxxxxxxx.x213xx, xxxxxxxxxx@xxxxxxxxx.x3x, xxxxxxxxxx@xxxxxxxxxx, xxxxxxxxxx@xxxxxxxxxx.xxx2, xxxxxxxxxx@xxxxxxxxxxx, xxxxxxxxxx@xxxxxxxxxxxxx, xxxxxxxxxx@xxxxxxxxxxxxxx.x123xx, xxxxxxxxxx@xxxxxxxxxxxxxxxxxxx.x, xxxxxxxxxx_xxx@xxxxx.xxx.3x, xxxxxxxxxx_xxxx@xxxxxxxxxx, xxxxxxxxxx_xxxxxxx@xxxxxxx, xxxxxxxxxx05@xxx, xxxxxxxxxx05@xxxx, xxxxxxxxxx1@x.xx, xxxxxxxxxx1@xxxxxxx, xxxxxxxxxx13@x.xxx, xxxxxxxxxx14@xxxxx, xxxxxxxxxx2233@x.xxx, xxxxxxxxxx26@xxxxxxxxxx, xxxxxxxxxx28@xxxxxxxx, xxxxxxxxxx3_xxxxxx@xxxxx, xxxxxxxxxx34@xxxxx, xxxxxxxxxx38@xxxxx, xxxxxxxxxx44.@xxxxx.xx, xxxxxxxxxx4xxx@xxxxxxxxx, xxxxxxxxxx518@xxxxx, xxxxxxxxxx60@x.xxx, xxxxxxxxxx726@xxxxx, xxxxxxxxxx76@xxxxx.xxx-xx, xxxxxxxxxx78@xxxxx, xxxxxxxxxx80@xxxxx.x0x, xxxxxxxxxx86@xxxxxx, xxxxxxxxxx88@x.xxx, xxxxxxxxxxx%2x@xxxxx.xxx, xxxxxxxxxxx..x.xxxxxxx@xxxxxxxxxxx.xxx, xxxxxxxxxxx.xxx_xxxxxxxx@x, xxxxxxxxxxx.xxxxx.x@xxxxx.x, xxxxxxxxxxx.xxxxx@xxxxxxx.xxx., xxxxxxxxxxx.xxxxx@xxxxxxxx, xxxxxxxxxxx.xxxxxxxxx@xxxxx, xxxxxxxxxxx.xxxxxxxxx1@xx, xxxxxxxxxxx@x, xxxxxxxxxxx@x.xx, xxxxxxxxxxx@x.xxx, xxxx-xxxxxxx@x.xxx, xxxxxxxxxxx@xx4xxx, xxxxxxxxxxx@xxx, xxxxxxxxxxx@xxxx, xxxxxxxxxxx@xxxxx, xxxxxxxxxxx@xxxxx., xxxxxxxxxxx@xxxxx.x, xxxxxxxxxxx@xxxxx.x0x, xxxxxxxxxxx@xxxxx.x123xx, xxxxxxxxxxx@xxxxx.xx6, xxxxxxxxxxx@xxxxx.xxx., xxxxxxxxxxx@xxxxxx, xxxxxxxxxxx@xxxxxxx, xxxx-xxxxxxx@xxxxxxx, xx-xxxxxxxxx@xxxxxxx., xxxxxxxxxxx@xxxxxxx.x2x, xxxxxxxxxxx@xxxxxxx.x3x, xxxxxx-xxxxx@x-xxxxxx.xx-xxxxxx, xxxxxxxxxxx@xxxxxxxx, xxxxxxxxxxx@xxxxxxxxx, xxxxxxxxxxx@xxxxxxxxx.x123xx, xxxxxxxxxxx@xxxxxxxxx.x3x, xxxxxxxxxxx@xxxxxxxxx.xxx3, xxxxxxxxxxx@xxxxxxxxxx, xxxxxxxxxxx@xxxxxxxxxx.xx12x, xxxxxxxxxxx@xxxxxxxxxx.xxx., xxxxxxxxxxx@xxxxxxxxxxx, xxxxxxxxxxx@xxxxxxxxxxxx, xxxxxxxxxxx@xxxxxxxxxxxxx, xxxxxxxxxxx@xxxxxxxxxxxxxxx, xxxxxxxxxxx07@xxxxxxxx, xxxxxxxxxxx1@xxxxx, xxxxxxxxxxx1@xxxxx.x123xx, xxxxxxxxxxx1@xxxxxxxx, xxxxxxxxxxx12@xxxxx, xxxxxxxxxxx151@xxxxx., xxxxxxxxxxx1946@xxxxxxxxxx, xxxxxxxxxxx2@x.xxx, xxxxxxxxxxx2001@xxxxx.x123xx, xxxxxxxxxxx2002@xxx, xxxxxxxxxxx2002@xxxxx, xxxxxxxxxxx21@xxx., xxxxxxxxxxx44@xxxxx., xxxxxxxxxxx45@xxxxxxx, xxxxxxxxxxx69@xxxxx, xxxxxxxxxxx7@xxxxx, xxxxxxxxxxx711@xxxxxxxxxxx, xxxxxxxxxxx8@x.xxx, xxxxxxxxxxx900@x.xxx, xxxxxxxxxxx92@x.xxx, xxxxxxxxxxx96@xxxxxx, xxxxxxxxxxx99@xxxxx, xxxxxx-xxxxxx.@xx.xxx, xxxxxxxxxxxx.@xxxxx.xxx, xxxxxxxxxxxx.x.x@xx, xxxxxxxxxxxx.xxx@xxx, xxxxxxxxxxxx.xxx@xxxx, xxxxxxxxxxxx.xxxxxxx@xxxxxxxxxx, xxxxxxxxxxxx@x.xx, xxxxxxxxxxxx@x.xxx, xxxxxxxxxxxx@x4xxx, xxxxxxxxxxxx@xxx, xxxxxxxx-xxxx@xxx, xxxxxxxxxxxx@xxx., xxxxxxxxxxxx@xxx.xx., xxxxxxxxxxxx@xxxx, xxxxxxxxxxxx@xxxxx, xxxxxxxxxxxx@xxxxx.x0x, xxxxxxxxxxxx@xxxxx.x3, xxxxxxxxxxxx@xxxxx.xx.x123x, xxxxxxxxxxxx@xxxxx.xx04, xxxxxxxxxxxx@xxxxx.xxx., xxxxxxxxxxxx@xxxxx.xxxx., xxxxxxxxxxxx@xxxxxx, xxxxxxxxxxxx@xxxxxxx, xxxxxxxxxxxx@xxxxxxx., xxxxxxxxxxxx@xxxxxxx.x, xxxxxxxxxxxx@xxxxxxx.x123xx, xxxxxxxxxxxx@xxxxxxx.xx0x, xxxxxxxxxxxx@xxxxxxxx, xxxxxxxxxxxx@xxxxx-xxx, xxxxxxxxxxxx@xxxxxxxx.x123xx, xxxxxxxxxxxx@xxxxxxxx.xxx., xxxxxxxxxxxx@xxxxxxxxx, xxxxxxxxxxxx@xxxxxxxxxx, xxx-xxxxxxx-xx@xxxxxxxxxx, xxxxxxxxxxxx@xxxxxxxxxxx, xxxxxxxxxxxx@xxxxxxxxxxxx.x, xxxxxxxxxxxx_23@xxxxxxxxxx, xxxxxxxxxxxx1@xxx.x0x, xxxxxxx-xxxxx1@xxx.xx9x, xxxxxxxxxxxx1@xxxxxxx, xxxxxxxxxxxx1@xxxxxxxx, xxxxxxxxxxxx100@xxxxx.x0x, xxxxxxxxxxxx123@xxxxxxx, xxxxxxxxxxxx14@xxxxx., xxxxxxxxxxxx1970@xxxxx-xxx, xxxxxxxxxxxx1975@xxxxx, xxxxxxxxxxxx20@xxxxxxx.x9x, xxxxxxxxxxxx2000.@xxxxxxx.xxx, xxxxxxxxxxxx3@xxxxx, xxxxxxxxxxxx7@xxxxx, xxxxxxxxxxxx88.@xxxxx.xxx, xxxxxxxxxxxx88@xxxxx., xxxxxxxxxxxx9@x.xxx, xxxxxxxxxxxxx.@xxx.xxx, xxxxxxxxxxxxx@12xxxxxxxx, xxxxxxxxxxxxx@x.xxx, xxxxxxxxxxxxx@xx, xxxxxxxxxxxxx@xxx, xxxxxxxxxxxxx@xxx.x0x, xxxxxxxxxxxxx@xxx.x213xx, xxxxxxxxxxxxx@xxxx, xxxxxxxxxxxxx@xxxxx, xxxxxxxxxxxxx@xxxxx., xxxxxxxxxxxxx@xxxxx.x123xx, xxxxxxxxxxxxx@xxxxxxx, xxxxxxxxxxxxx@xxxxxxx.x, xxxxxxxxxxxxx@xxxxxxx.x123xx, xxxxxxxxxxxxx@xxxxxxxx, xxxxxxxxxxxxx@xxxxxxxxx, xxxxxxxxxxxxx@xxxxxxxxxx, xxxxxxxxxxxxx@xxxxxxxxxx.x123xx, xxxxxxxxxxxxx_1@x.xxx, xxxxxxxxxxxxx1@xxxxxxxxx.x123xx, xxxxxxxxxxxxx100@xxxxxxxxxx, xxxxxxxxxxxxx2@x.xxx, xxxxxxxxxxxxx4x697xxxx9x25xx8..7@xxxxx.xxx, xxxxxxxxxxxxx6699@xxxxxxx, xxxxxxxxxxxxx8@xxx, xxxxxxxxxxxxxx.@xxxxx.xxx, xxxxxxxxxxxxxx@x.xxx, xxxxxxxxxxxxxx@xxx, xxxxxxxxxxxxxx@xxx.123xx, xxxxxxxxxxxxxx@xxx.x234xx, xxxxxxxxxxxxxx@xxxxx, xxxxxxxxxxxxxx@xxxxx.x, xxxxxxxxxxxxxx@xxxxx.x0x, xxxxxxxxxxxxxx@xxxxx.x123xx, xxxxxxxxxxxxxx@xxxxx.xxx., xxxxxxxxxxxxxx@xxxxx.xxx.xx., xxxxxxxxxxxxxx@xxxxxx, xxxxxxxxxxxxxx@xxxxxxx, xxxxxxxxxxxxxx@xxxxxxx.x123xx, xxxxxxxxxxxxxx@xxxxxxxx, xxxxxxxxxxxxxx@xxxxxxxxx, xxxxxxxxxxxxxx@xxxxxxxxx.x132xx, xxxxxxxxxxxxxx@xxxxxxxxxx, xxxxxxxxxxxxxx@xxxxxxxxxxxxxxx.x123xx, xxxxxxxxxxxxxx@xxxxxxxxxxxxxxxx.x0x, xxxxxxxxxxxxxx05@x, xxxxxxxxxxxxxx2003@xxxxx.xx., xxxxxxxxxxxxxx2008@xxxxxxxxxx, xxxxxxxxxxxxxx3@xxxxxxxx, xxxxxxxxxxxxxx55@xxx, xxxxxxxxxxxxxxx%2xxxx@xxxx, xxxxxxxxxxxxxxx.@xxxxxxxxx.xxx, xxxxxxxxxxxxxxx@x, xxxxxxxxxxxxxxx@x.xxx, xxxxxxx-xxxxxxxx@x.xxx, xxxxxxxxxxxxxxx@xx.x, xxxxxxxxxxxxxxx@xxx, xxxxxxxxxxxxxxx@xxxxx, xxxxxxxxxxxxxxx@xxxxx.x123xx, xxxxxxxxxxxxxxx@xxxxx.xxx., xxxxxxxxxxxxxxx@xxxxxxx, xxxxxxxxxxxxxxx@xxxxxxxx, xxxxxxxxxxxxxxx@xxxxxxxxx, xxxxxxxxxxxxxxx@xxxxxxxxx.x3x, xxxxxxxxxxxxxxx@xxxxxxxxxxxx, xxxxxx-xxxx-xxxxx2%2xxxxxxx@xxxxxx, xxxxxxxxxxxxxxx2@xxxxx.x0x, xxxxxxxxxxxxxxx85@xxxxx, xxxxxxxxxxxxxxxx%2xxxxx%2xxxxx@xxxx02, xxxxxxxxxxxxxxxx.@xxx.xxx, xxxxxxxxxxxxxxxx.x@x, xxxxxxxxxxxxxxxx@x.xxx, xxxxxxxxxxxxxxxx@xx, xxxxxxxxxxxxxxxx@xxxxx, xxxxxxxxxxxxxxxx@xxxxxxx, xxxxxxxxxxxxxxxx@xxxxxxxx, xxxxxxxxxxxxxxxx@xxxxxxxxxx, xxxxxxxxxxxxxxxx@xxxxxxxxxxx.x, xxxxxxxxxxxxxxxxx.xxxx2007@x, xxxxxxxxxxxxxxxxx@x.xxx, xxxxxxxxxxxxxxxxx@xxxxx, xxxxxxxxxxxxxxxxx@xxxxxx, xxxxxxxxxxxxxxxxx@xxxxxxx.x0, xxxxxxxxxxxxxxxxx@xxxxxxxx, xxxxxxxxxxxxxxxxx@xxxxxxxxx, xxxxxxxxxxxxxxxxxx@x.xxx, xxxxxxxxxxxxxxxxxx@xx, xxxxxxxxxxxxxxxxxx@xxxxx, xxxxxxxxxxxxxxxxxx@xxxxx.xx., xxxxxxxxxxxxxxxxxx2@xxxxxxxxxx, xxxxxxxxxxxxxxxxxx62@xxxxxxxx, xxxxxxxxxxxxxxxxxxx.@xxxxx.xxx, xxxxxxxxxxxxxxxxxxx@xxxxx, xxxxxxxxxxxxxxxxxxx@xxxxxxx, xxxxxxxxxxxxxxxxxxxx@786, xxxxxxxxxxxxxxxxxxxx@xxxxx, xxxxxxxxx-xxxxxxxxxxx@xxxxxxx.x3x, xxxxxxxxxxxxxxxxxxxxx@xxxxxxx, xxxxxxxxxxxxxxxxxxxxx@xxxxxxxxxx, xxxxxxxxxxxxxxxxxxxxxxx.@xxxxx.xxx, xxxxxxxxxxxxxxxxxxxxxxxxxxx3xxxxxxxxx@xxxxxxxxxxxxxxxxxxxxxxxxxx,

11 Nov 08:04

Free Download: Metro Tiles UI Kit (PSD)

by Jacob Gube

Free Download: Metro Tiles UI Kit (PSD)

Metro Tiles is a free Photoshop UI kit with all the user interface elements you’ll need for your Web and mobile apps.

This freebie is brought to you by PixelKit, creators of premium Web UI kits and other design resources.

Preview

Free Download: Metro Tiles UI Kit (PSD) - Full Preview

Download

Related Content

About the Author

Bogdan Condurache is one of the co-founders and a designer at PixelKit, which is a part of the ThemeFuse family. PixelKit creates premium UI kits and design resources. Bogdan loves to create detailed designs and GUIs. Follow his company on Twitter as @PixelKitCom and join PixelKit on Facebook.

The post Free Download: Metro Tiles UI Kit (PSD) appeared first on Six Revisions.

08 Nov 07:29

Inside Windows Phone 66: Windows Phone for Enterprise Developers

by Larry Lieberman

Matthijs Hoekstra gives us a complete run down on how Windows Phone meets the needs of enterprise developers.

 

If you’d like to review some of the topics we discussed more in depth, take a look at this list, and as always, we welcome your questions, comments and feedback.

From Tech Ed North America 2014:

From the official developer documentation:

06 Nov 07:33

Team learning

by Urs Enzler



Slide1

This is the hand-out of my talk at the Agile Leadership Day in November 2013.

Slide2

How much faster would your last project have been, if your team knew in the beginning, what it knew at the end of the project? What if your team knew all the technologies and how to use them correctly in the project setup? What if your team knew the domain of the project in detail right from the start of the project? Would they have been twice as fast? Or even faster?

Knowledge is one of the key factors regarding project success.

Your team needs to know the problem domain it wants to solve with the software it builds. The team needs to know the technology and tools it is using. The team needs to understand the process used to achieve the goal and many things more.

Slide3

Therefore, it is crucial to get a high level of knowledge as fast as possible. The steeper the learning curve, the faster your team gets performing. And of course, if you can start with a higher level in the beginning, this is even better. By acquiring the needed knowledge faster, the team finishes the project earlier.

This is the reason, why team learning is so important when starting a new project.

Slide4

But there are personal reasons too:

Slide5

People, especially software developers, like new things. Software developers can get very enthusiastic regarding new technologies and tools.

Slide6

When a project leader or project owner (Scrum) looks for people to staff her team, then she will surely prefer to get the best people available. Therefore, if you want to be part of the coolest projects, you’d better be good. To get good in anything, it needs learning.

Slide7

Finally, it just feels great to be with the best. But this doesn’t come for free, being with the best needs continuous improvement and continuous learning.

Slide8

Learning needs three basic things:

Slide9

Number one is feedback. Only through feedback, we can make learning visible. Be it the exam you passed in school, or that you noticed that you use now the shortcuts in your favourite development tool.

Let’s have a look at three ways of feedback for teams:

Slide10

The first is failure. Failure is hard but it forces you to change something and try again.

Slide11

The second are retrospectives. In a retrospective, the team looks back in time. In the Scrum Retrospective, the team looks back at the Sprint.

Normally, the team identifies the main things or happenings that

  • were good and should be done in the future, too
  • can be improved in the future
  • should just not occur again.

The team uses this feedback to learn how to improve for the next Sprint.

Slide12

The third kind of feedback is dog feeding. Whenever a team builds something, make them use it themselves.

This is especially important, if your team builds some sort of framework or library. The worst thing to do is to split the developers into a framework group and an application group. The framework group cannot close its feedback cycle because the developers do not use the framework to build an application. This will result with almost 100% certainty in a framework too complex and with missing features.

Only when you use what you build, you have to live with the consequences of your decisions and will learn what works and what doesn’t.

Slide13

The second thing needed to enable learning is repetition with variance. Evolution introduces into every generation a little change and checks whether it is better or worse. The better survive, the worse don’t.

The same applies when you want to learn for example a practice like Test Driven Development, or how to make good presentations. You should do it over and over again and vary every time a little thing. This way you can optimize what you are doing based on the feedback of each little change. The variance helps to keep teams excited about what they are building, too. Simple repetition without variance gets boring quickly.

Slide14

The third thing needed for learning is focus. You cannot learn everything at once. You have to focus on few things at a time. My experience tells me that you should keep under three topics for a team. Therefore, keep a backlog of stuff to be learnt and only take a new item when another is established in the team.

Slide15

Once again, if you want to foster learning, make sure the team meets an environment that provides fast feedback, allows repetition with variance and focus.

Slide16

There exist a lot of methods to enable team learning. I’ll show you what we tried in our company.

I’ll gather these methods on this diagram. Horizontally, you see whether a practice is good for individual (to the left) or team learning (to the right).

Vertically, the practices are sorted by the depth of knowledge you can acquire with it. On top are the practices providing the most in-depth know-how.

Slide17

Learning itself is a change process. You go through several phases when learning a new skill. If you want to introduce a learning culture in your organization, you have to find a way to quickly get people through this process.

Slide18

Before you can learn something new, you need to be aware that there is something out there that can be learned.

This can happen because the new guy in the team talks about this cool tool you don’t know (yet), you go to a conference and hear about new ideas, or you read blogs of some interesting people.

Slide19

In my company, we have so called technical leaders. Technical leaders have the ability to quickly get themselves through all the phases of the learning process without any external incentives.

Part of their job is it, to teach others. The first step is to make people aware that they do not know everything. This happens through announcements of workshops and courses or by talking with each other.

Slide20

Just knowing that there is something you don’t know is not enough. You need the desire to learn it.

Every step in learning is an investment. It is hard and needs real effort of the person who is learning.

Therefore, growing desire is often the most critical part in the process of learning and sometimes the hardest part to achieve. Technical leaders support others to overcome this hurdle by showing what they get out from this investment. Maybe work gets easier, more fun or less risky. I’ll get back to this later on.

Slide21

Once, you or your team knows what and why to learn something, you need to be able to do so.

Sometimes, time is enough. But most times, more is needed: a coach, or a kind of team learning.

Slide22

We work with Scrum and Scrum provides itself some good opportunities for learning.

Slide23

When the team talks together with the product owner about the product backlog – the so called product backlog grooming – the team learns a lot about the domain. The product owner explains why something is worth building and what business problem needs to be solved. The product backlog grooming should be done frequently so that a team can suggest better solutions due to better understanding of the business and end user needs.

Slide24

Every sprint planning meeting gives us the opportunity to learn to plan better. Try to introduce some variance into the repetitive task of planning. This is a good way to improve planning and estimation skills.

Slide25

In the sprint review, you talk with your stakeholders about what you learned during the sprint. This often leads to new insights on both the stakeholders and team side. And the discussions about the product increment during its demonstration help the team to better understand what has to be built.

Slide26

Finally, the sprint retrospective is the place to talk about what insights we had during the sprint, what we learned about the way we work and how we could improve it.

Slide27

The activities in Scrum help the team as a whole to learn about the domain of the project. The frequent discussions with the product owner and stakeholders support the team in acquiring a high level of knowledge in a short time frame.

Slide28

We use pair programming not only to get better quality in less time. We also use pair programming to transfer know-how between developers.

In a pair programming session, both developers learn from each other: they discuss and find solutions, they see how they use the development tools (yes, this can really by an eye opener), and they get immediate feedback on every action.

Slide29

Because pair programming happens between two programmers this practice is somewhere in the middle of individual and group learning. But because you go down to the code, the depth of knowledge is very deep.

Slide30

Whenever a developer in my team wants to commit changes in code to the source code repository then he asks another developer for a Commit Review. In a Commit Review, the developer, who has changed the code, explains these changes to the second developer.

Two things happen here: First, a know-how transfer from the developer to the reviewer. And second, the reviewer provides feedback to the developer. A great opportunity for learning.

Slide31

This is a perfect addition to pair programming for us because we do not develop all our code in pairs. The depth of knowledge transferred is however somewhat smaller.

Slide32

If you want to push team knowledge in technical and process skills, like Test Driven Development, Clean Code, tool usage and so on, then Coding Dojos are for you.

In a coding dojo, the team – or a group of developers – sit together in front of a beamer showing what happens on a computer while two developers practice pair programming. The members “watching” can provide inputs to the developing pair.

A coding dojo normally takes 1 to 2 hours.

Slide33

Coding Dojos push common understanding and common behaviour. Therefore, they are a perfect environment for a team to learn as a whole. You can focus on a specific topic during a coding dojo and the team can acquire a deep knowledge.

Slide34

In Focus Groups and Workshops individuals with the same interest in a topic meet to discuss. In a Scrum Focus Group, developers, Scrum Master and Product Owners meet to share their experiences and to find solutions to common problems. A focus group helps to boost knowledge over several teams. A workshop is a team internal meeting to increase knowledge on a certain aspect of the project, like architecture, continuous integration process and so on.

Slide35

This gives the whole group a common understanding of a topic. Therefore, it is a good group learning practice, however the depth of knowledge is limited. Keeping a focus group together over time increases the depth of knowledge and the effect on the whole team.

Slide36

The members of a book club read a book or blog, or they watch a video together and afterwards discuss about what they learned from it. Hearing about insights of others increases the personal learning effect.

Slide37

A book club is more about personal learning than team learning and the depth of knowledge from a team perspective is limited.

Slide38

In our company we have days reserved for learning at the company level. The bbv Techday is an internal conference day, on which we have presentations about what we learned during the year in our projects. This ranges from technology and tools to soft skills and management topics. The bbv Forum is held three times a year and focuses on workshops about topics relevant to larger groups within our company.

Slide39

The presentations and workshops provide insights into how others are working, but no in depth knowledge. The recurrence of the bbv Forum helps to foster learning as a group.

Slide40

Under the name bbv Academy, we run courses from 1 to 5 days about topics that we consider basics for our employees. These are things like Test Driven Development, Scrum, Clean Code, working with Legacy Code, Requirements Engineering, Testing, and much more.

Slide41

The academies cover basics, but whole teams can learn together.

Slide42

Once a year, we take a whole week off and focus completely on learning. Topics varied from learning Scrum when we introduced Scrum in our company to role specific topics like architecture training.

Slide43

Education weeks cost a lot of money but provide great team learning on a very high level of knowledge and boost common understanding and team efficiency and effectiveness in a short time frame (in only one week instead of probably over one year of working in a real project).

Slide44

There will always be the need for personal learning. Especially the technical leaders will need a lot of individual learning.

Slide45

With classical Individual Learning – like going to conferences, reading books and blogs (thanks for reading my blog by the way) – you can get a deep learning effect but the team benefits little directly.

We also use individual annual goals and Sprint goals to push individual learning.

Slide46

A Sprint goal is a little thing you pay attention to during a Sprint to make your daily work more efficient and effective: learning Visual Studio shortcuts, writing readable methods or something like that.

Slide47

After learning something new, it is important to celebrate.

This may be that you look back at the times before and pat yourself on the shoulder or a team celebration that the team has learned something new.

Slide48

Promotion of learning successes is very important to get other people onto their learning path. People get aware that others have a new skill or insight. It makes them aware. And seeing all the happy faces makes the others wanting to share this success and therefore increases their desire to learn the same thing. Promotion is a strong positive feedback loop to awareness and desire. I often hear that developers are not interested in learning something new. But that is probably because no one shows and tells them what their gain is.

Slide49

An easy way to promote learning successes is to visualize them. A team may put sticky notes onto a wall about what they learned. After a year, you get an impressing list of things the team learned. Others may take a look at get inspired to learn something, too.

Slide50

Or you even go public – like we do with our posters.

Slide51

At least, you should talk about it to your team members and to other employees.

Slide52

We Swiss are famous and laughed at for our Apéro culture. But never underestimate its power. You can do a lot of promotion there.

Slide53

Of course, you won’t discuss technical details at an Apéro, but people are in a good mood and a learning initiative is often started there.

Slide54

The last step in the learning process is to transfer the newly acquired knowledge to other people. One individual teaching someone else, or a whole team helping another team.

Slide55

If you want to understand a domain as deeply as possible, you should try to teach the topic to others. You’ll get challenged by questions and enforce your knowledge by explaining.

Slide56

This practice gives you the deepest possible knowledge on a topic.

Slide57

The transfer phase is used to enable others to learn. Your organization teaches itself. This scales also very well, which is important if you want learning to happen throughout a whole company.

Slide60

This is the summary of all learning variants I showed you.

There are even more on it.

A pet projects is a project that is initiated by an individual or a team to learn a certain technology or method.

In brown bag meetings, people meet during lunch hour to watch a presentation. This is the low cost, low focus variant in case you cannot do anything else on this slide.

Not every employee can do all of these activities. That would simply take too much time. But every employee can choose from all these activities what matches best for him or her.

Slide61

Learning should take place as much as possible in the project the employee is working in. That’s because we learn to be better in the project. But we also have time outside the project for employees to learn things that are not currently used by their projects. Either to get better for a next project or to get know-how about something that might be useful to the project. Finally, we expect from our employees that they give a bit of their spare time to keep up with the technology they are working with. But only a bit.

Slide62

I have shown you what it needs for team learning and some practices we use to boost it.

To sum everything up, there are two main insights we had while establishing a culture of learning in our company.

Slide63

If you want high-performing, fast learning teams, your teams need to develop a challenger spirit. Every team member is eager to learn from all others and challenges the team with new inputs. This gets you quickly through the awareness and desire steps in the learning process.

Kick off the learning spiral by supporting individuals willing to learn for themselves and support them to become technical leaders. Technical leaders, who help others to get through the learning phases quickly. Put a lot of effort into promotion of learning successes and the learning spiral gets spinning faster and faster.

Slide64

Finally, what I learned from all the effort we put into individual and team learning is that providing the environment for a good learning culture results in highly motivated teams.

And now, multiply the number you had in mind during the first slide – when I asked you how much faster your last project would have been when your team had known from the start what it knew in the end – with the factor a highly motivated team is more productive than a “normal” team. I leave you with that thought …

Slide65

Thanks for reading. If you have any feedback, please write a comment.

 
04 Nov 09:38

Undo/Redo

by moc@zuehlke.com (Christian Moser)

How to implement undo/redo using MVVM

Introduction

One feature that many users demand is a neatless undo/redo integration. This means that the application allows the user to revert any modification he made - one by one - back to the start of the application and than eventually reapply them again. This improves the usability a lot, because it allows the user to carelessly use an unclear command, because he is certain, that he can undo it if he was wrong. Today undo/redo has gotten almost standard for any modern data editing application.

The MVVM-Pattern

Because of the strong databinding functionality in WPF, most applications are using the popular MVVM (Model-View-ViewModel) pattern. The idea of this pattern is basically to define a class that aggregates all data and commands for a certain view and provides them to the view as properties where it can bind to. Changes on properties are notified by an event on the INotifyPropertyChanged interface.

A concept of implementing undo/redo

A classical approach to implement undo/redo is to allow changes on the model only through commands. And every command should be invertible. The user than executes an action, the application creates a command, executes it and puts an inverted command on the undo-stack. When the user clicks on undo, the application executes the top-most (inverse) command on the undo-stack, inverts it again (to get the original command again) and puts it on the redo-stack. That's it.

Scenario 1: Executing an action

Scenario 2: Undoing an action

Adoption for WPF

We start with a base class that implements the INotifyPropertyChanged interface and provides a private method Notify(string propertyName).

 
public class NotifyableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
 
    protected void Notify(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
 
 

Then we build the base class TrackableObject where all model objects or view models that are directly bound to the view should inherit from.

 
public class TrackableObject : NotifyableObject
{
    private readonly List<ITrackable> _trackableItems = new List<ITrackable>();
 
    public bool HasChanges
    {
        get { return _trackableItems.Any(i => i.HasChanges); }
    }
 
    public IModificationTracker ModificationTracker { get; set; }
 
    protected TrackableValue<T> RegisterTrackableValue<T>(string propertyName, 
           T defaultValue = default(T))
    {
        var property = new TrackableValue<T>(propertyName, Modify, Notify, defaultValue);
        _trackableItems.Add(property);
        return property;
    }
 
    protected TrackableCollection<T> RegisterTrackableCollection<T>()
    {
        var collection = new TrackableCollection<T>(Modify);
        _trackableItems.Add(collection);
        return collection;
    }
 
    private void Modify(Action doAction, Action undoAction, Action notification)
    {
        var modification = new Modification(doAction, undoAction, notification);
        modification.Execute();
        ModificationTracker.TrackModification(modification);
    }
}
 
 

To simplify the generation of modifactions when changing a property value, we build a generic wrapper for each property called TrackableValue.

 
public class TrackableValue<T> : ITrackable
{
    private readonly string _propertyName;
    private readonly Action<Action, Action, Action> _modifyCallback;
    private readonly Action<string> _notifyAction;
    private T _value;
 
    public TrackableValue(string propertyName, 
               Action<Action, Action, Action> modifyCallback,
               Action<string> notifyAction, T defaultValue)
    {
        _propertyName = propertyName;
        _modifyCallback = modifyCallback;
        _notifyAction = notifyAction;
        _value = defaultValue;
    }
 
    public bool HasChanges
    {
        get { return _originalValue.Equals(_value); }
    }
 
    public T Value
    {
        get { return _value; }
        set
        {
            var oldValue = _value;
            _modifyCallback(() => _value = value, 
                            () => _value = oldValue,
                            () => _notifyAction(_propertyName));
        }
    }
}
 
 

To same thing we need to do for collections to track add/remove of items from a collection

 
public class TrackableCollection<T> : IList<T>, ITrackable
{
    private readonly Action<Action, Action, Action> _modifyCallback;
    private readonly List<T> _list = new List<T>();
    private readonly List<T> _originalList = new List<T>();
 
    public TrackableCollection(Action<Action, Action, Action> modifyCallback)
    {
        _modifyCallback = modifyCallback;
    }
 
    public event EventHandler<EventArgs<T>> ItemAdded;
    public event EventHandler<EventArgs<T>> ItemRemoved;
    public event EventHandler CollectionChanged;
 
    public bool HasChanges
    {
        get
        {
            if( _list.Count == _originalList.Count)
            {
                return _list.Where((item, index) => 
                       !item.Equals(_originalList[index])).Any();
            }
            return true;
        }
    }
 
    public void AcceptChanges()
    {
        _originalList.Clear();
        _originalList.AddRange(_list);
    }
 
    public IEnumerator<T> GetEnumerator()
    { 
        return _list.GetEnumerator();    
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
 
    public void Add(T item)
    {
        _modifyCallback(() =>
        {
            _list.Add(item); 
            ItemAdded.Notify(this, new EventArgs<T>(item));
        }, 
        () =>
        {
            _list.Remove(item);
            ItemRemoved.Notify(this, new EventArgs<T>(item));
        }, 
        OnCollectionModified);
    }
 
    public void Clear()
    {
        var items = new T[_list.Count];
        _list.CopyTo(items);
        _modifyCallback(() =>
        {
            _list.ForEach(i => ItemRemoved.Notify(this, new EventArgs<T>(i)));
            _list.Clear();
        }, 
        () =>
        {
            _list.AddRange(items);
            _list.ForEach(i => ItemAdded.Notify(this, new EventArgs<T>(i)));
        }, 
        OnCollectionModified);
    }
 
    public bool Contains(T item)
    {
        return _list.Contains(item);
    }
 
    public void CopyTo(T[] array, int arrayIndex)
    {
        _list.CopyTo(array, arrayIndex);
    }
 
    public bool Remove(T item)
    {
        var result = _list.Contains(item);
        _modifyCallback(() =>
        {
            _list.Remove(item);
            ItemRemoved.Notify(this, new EventArgs<T>(item));
        }, 
        () =>
        {
            _list.Add(item);
            ItemAdded.Notify(this, new EventArgs<T>(item));
        }, 
        OnCollectionModified);
        return result;
    }
 
    public int Count
    {
        get { return _list.Count; }
    }
 
    public bool IsReadOnly
    {
        get { return false; }
    }
 
    public int IndexOf(T item)
    {
        return _list.IndexOf(item);
    }
 
    public void Insert(int index, T item)
    {
        _modifyCallback(() =>
        {
            _list.Insert(index, item);
            ItemAdded.Notify(this, new EventArgs<T>(item));
        }, 
        () =>
        {
            _list.Remove(item);
            ItemRemoved.Notify(this, new EventArgs<T>(item));
        }, 
        OnCollectionModified);
    }
 
    public void RemoveAt(int index)
    {
        var item = _list[index];
        _modifyCallback(() =>
        {
            _list.Remove(item);
            ItemRemoved.Notify(this, new EventArgs<T>(item));
        }, 
        () =>
        {
            _list.Insert(index, item);
            ItemAdded.Notify(this, new EventArgs<T>(item));
        }, 
        OnCollectionModified);
    }
 
    public T this[int index]
    {
        get { return _list[index]; }
        set
        {
            var oldItem = _list[index];
            _modifyCallback(() =>
           {
               _list[index] = value;
               ItemAdded.Notify(this, new EventArgs<T>(value));
           }, 
           () =>
           {
               _list[index] = oldItem;
               ItemRemoved.Notify(this, new EventArgs<T>(oldItem));
           }, 
           OnCollectionModified);
        }
    }
 
    private void OnCollectionModified()
    {
        CollectionChanged.Notify(this, EventArgs.Empty);   
    }
}
 
 
04 Nov 09:38

Grid Panel

by moc@zuehlke.com (Christian Moser)

Grid Panel

Introduction

How to define rows and columns

How to add controls to the grid

Resize columns or rows

How to share the width of a column over multiple grids

Using GridLenghts from code

Introduction

The grid is a layout panel that arranges its child controls in a tabular structure of rows and columns. Its functionality is similar to the HTML table but more flexible. A cell can contain multiple controls, they can span over multiple cells and even overlap themselves.

The resize behaviour of the controls is defined by the HorizontalAlignment and VerticalAlignment properties who define the anchors. The distance between the anchor and the grid line is specified by the margin of the control

Define Rows and Columns

The grid has one row and column by default. To create additional rows and columns, you have to add RowDefinition items to the RowDefinitions collection and ColumnDefinition items to the ColumnDefinitions collection. The following example shows a grid with three rows and two columns.

The size can be specified as an absolute amount of logical units, as a percentage value or automatically.

Fixed Fixed size of logical units (1/96 inch)
Auto Takes as much space as needed by the contained control
Star (*) Takes as much space as available (after filling all auto and fixed sized columns), proportionally divided over all star-sized columns. So 3*/5* means the same as 30*/50*. Remember that star-sizing does not work if the grid size is calculated based on its content.
 
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="28" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="200" />
    </Grid.ColumnDefinitions>
</Grid>
 
 

How to add controls to the grid

To add controls to the grid layout panel just put the declaration between the opening and closing tags of the Grid. Keep in mind that the row- and columndefinitions must precced any definition of child controls.

The grid layout panel provides the two attached properties Grid.Column and Grid.Row to define the location of the control.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="28" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="200" />
    </Grid.ColumnDefinitions>
    <Label Grid.Row="0" Grid.Column="0" Content="Name:"/>
    <Label Grid.Row="1" Grid.Column="0" Content="E-Mail:"/>
    <Label Grid.Row="2" Grid.Column="0" Content="Comment:"/>
    <TextBox Grid.Column="1" Grid.Row="0" Margin="3" />
    <TextBox Grid.Column="1" Grid.Row="1" Margin="3" />
    <TextBox Grid.Column="1" Grid.Row="2" Margin="3" />
    <Button Grid.Column="1" Grid.Row="3" HorizontalAlignment="Right" 
            MinWidth="80" Margin="3" Content="Send"  />
</Grid>
 

Resizable columns or rows

WPF provides a control called the GridSplitter. This control is added like any other control to a cell of the grid. The special thing is that is grabs itself the nearest gridline to change its width or height when you drag this control around.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Label Content="Left" Grid.Column="0" />
    <GridSplitter HorizontalAlignment="Right" 
                  VerticalAlignment="Stretch" 
                  Grid.Column="1" ResizeBehavior="PreviousAndNext"
                  Width="5" Background="#FFBCBCBC"/>
    <Label Content="Right" Grid.Column="2" />
</Grid>
 

The best way to align a grid splitter is to place it in its own auto-sized column. Doing it this way prevents overlapping to adjacent cells. To ensure that the grid splitter changes the size of the previous and next cell you have to set the ResizeBehavior to PreviousAndNext.

The splitter normally recognizes the resize direction according to the ratio between its height and width. But if you like you can also manually set the ResizeDirection to Columns or Rows.

<GridSplitter ResizeDirection="Columns"/>
 

How to share the width of a column over multiple grids

The shared size feature of the grid layout allows it to synchronize the width of columns over multiple grids. The feature is very useful if you want to realize a multi-column listview by using a grid as layout panel within the data template. Because each item contains its own grid, the columns will not have the same width.

By setting the attached property Grid.IsSharedSizeScope to true on a parent element you define a scope within the column-widths are shared.

To synchronize the width of two columndefinitions, set the SharedSizeGroup to the same name.

 
<ItemsControl Grid.IsSharedSizeScope="True" >
  <ItemsControl.ItemTemplate> 
    <DataTemplate>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition SharedSizeGroup="FirstColumn" Width="Auto"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="{Binding Path=Key}" TextWrapping="Wrap"/>
        <TextBlock Text="{Binding Path=Value}" Grid.Column="1" TextWrapping="Wrap"/>
      </Grid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
 
 

Useful Hints

Columns and rows that participate in size-sharing do not respect Star sizing. In the size-sharing scenario, Star sizing is treated as Auto. Since TextWrapping on TextBlocks within an SharedSize column does not work you can exclude your last column from the shared size. This often helps to resolve the problem.

Using GridLenghts from code

If you want to add columns or rows by code, you can use the GridLength class to define the differenz types of sizes.


Auto sized GridLength.Auto
Star sized new GridLength(1,GridUnitType.Star)
Fixed size new GridLength(100,GridUnitType.Pixel)
Grid grid = new Grid();
 
ColumnDefinition col1 = new ColumnDefinition();
col1.Width = GridLength.Auto;
ColumnDefinition col2 = new ColumnDefinition();
col2.Width = new GridLength(1,GridUnitType.Star);
 
grid.ColumnDefinitions.Add(col1);
grid.ColumnDefinitions.Add(col2);
 

More on this topic

How to create a resizable column
31 Oct 14:09

Disassembling the privacy implications of LinkedIn Intro

by Troy Hunt

LinkedIn Intro has already become known by many names: A dream for attackers, A nightmare for email security and privacy and A spectacularly bad idea to mention but a few. Harsh words. The general consensus of people I’ve spoken to is that it’s fundamentally stupid and about the worst thing you could consider doing with your privacy. It looks like this:

Sample of Intro running in iOS

You probably didn’t know this, but apparently you want a third party to access your email, pull some data out of it, manipulate the contents then send it on for you. That’s every email you send. Oh – and every email you receive too.

Others have outlined all the reasons why this makes about as much sense as tits on a bull, one of the more cohesive ones is LinkedIn ‘Intro’duces Insecurity which outlines 10 key reasons why they consider the approach to be pure insanity. In short, you’re handing control of your email over to LinkedIn and allowing them to read and modify the contents at will as you send and receive it. Surely this is some secret NSA plot to infiltrate private communications on a level never previously seen?!

What I haven’t seen yet though is an analysis of how the service is put together and what it actually means for your mail and your privacy. Let’s disassemble the thing, take an objective look at how it works and engage in some healthy speculation about what it means for privacy.

It’s not an app, it’s a profile

Let’s start here because one of the big questions I’m hearing is “Why would Apple allow this?” There’s an easy answer to that – they don’t. Apple in no way facilitates this feature and indeed it’s Apple’s security model which is sound enough that the only way LinkedIn can actually provide this feature is to mount a Man in the Middle attack (henceforth referred to as an MitM attack). Make no mistake, this is exactly what an MitM is; it is entirely dependent on introducing a third party into the middle of the communication between two other parties. In the security world we invest serious resources to protect against this form of attack – LinkedIn is actually asking you to opt into it. I know they don’t like this term but if it walks like a duck and it quacks like a duck, well, you know.

I’ll come back to Apple in a moment, let’s talk about the “feature” for a moment and to contextualise this I’ll point you in the direction of LinkedIn for Outlook. This is a “Social Connector” in that what it does is runs as an Outlook plugin so that it can do funky stuff like this:

LinkedIn Outlook Connector

“Agent Smith” is the pseudonym we’ll be using to test Intro and before you go looking for him, he’s already met with an untimely demise so as not to pollute LinkedIn’s system. What we’re seeing here is data that LinkedIn has on the participants in an email discussion and surfaces it in context at the bottom of the email. There’s one for Facebook too and there’s nothing wrong with this per se (assuming you don’t have a problem with seeing peoples’ public Farmville activity beside their serious corporate email), it’s simply making HTTP requests to the service and pulling back publicly accessible data.

You can do this in Outlook because Windows allows you so install all sorts of different things that interact with other standalone products. But in iOS, apps are sandboxed in such a way that this simply won’t fly; you can’t just add a third party connector into the mail app which then changes its behaviour. The only way LinkedIn were going to be able to achieve the same functionality was to manipulate the mail itself and that meant going back up the communication stack and getting their hands on the email before it even hits the device. Therein lies the MitM.

When you install Intro, you’re not installing an app from the Apple App Store and consequently you’re not coming under Apple’s purview. They’re not inspecting the app, they’re not approving it and they also can’t yoink it if they don’t like it. What you’re actually installing is a profile and that’s a fundamentally different proposition to installing an app. It’s also a very worrying proposition. Let me walk you through the mechanics of it.

“Installing” Intro

Let’s jump into it and I’m going to use a spare iPhone 4 and dummy email and LinkedIn accounts owned by our mate “Agent Smith” for this.

Firstly, everything kicks off over on intro.linked.com:

Starting the process at intro.linkedin.com

The Intro website is actually pretty neat and let’s face it, we all want to “be brilliant”, right?! Let’s get started:

The Intro website - "be brilliant with people"

You kick off by entering your email address. From here on in, I’m “Agent Smith”, thank you very much:

Entering your email address

It’s important to note here that Intro can’t MitM any old email account, it’s only Gmail, Yahoo! Mail, AOL Mail, iCloud and Google Apps. Fears of employees routing the corporate email through Intro are, for now, premature. Having said that, if they’re not actively planning how to make it available to services well beyond these, I’ll eat my hat.

Moving on, Intro asks you to authenticate to the mail provider:

Intro needs to authenticate to Google

This is now just your classic OAuth token pattern so let’s sign into Google:

Signing in to Google

Here’s where we get to the pointy end; Intro would like to “View and manage your mail”. This is exactly what it sounds like it is and proceeding beyond here that’s going to give LinkedIn unbridled access to your mail which, of course, is what all the fuss is about:

LinkedIn will have access to view and manage mail

Moving on, what Intro actually wants to do now is create an all new email account:

LinkedIn will create a new email account

This is important – Intro isn’t modifying email in storage and you won’t be able to go in later via the browser and see LinkedIn embedded within the mail client. They also make it quite clear that they don’t store your email (or your password, for that matter) and indeed with the model built the way it is, there’s no need to.

We’re going to get prompted to install that account so Intro sets an expectation of this up front:

Tap to "install" Intro

Here’s where a lot of the concern is being raised – Intro is now serving up a “profile” and asking the user to install it. What could you do with an iOS profile? Quite a lot actually, for example you could proxy HTTP traffic through another service, you could trust self-signed root certificates and in Intro’s case, you can install a new email account:

Install profile

The problem, of course, is that you have no idea what’s actually been installed. For all you know this profile could be designed to siphon off your web traffic or install a rogue cert. Remember, Apple don’t need to review or approve profiles, installing them is based on nothing more than trust. Let’s a look at the details:

The contents of the profile

So we’ve got a couple of certs and an “Encrypted Profile Service”. Uh, okie dokie, sounds legit! Let’s install:

Prompt to install the profile

This has been referred to in Bishop Fox article I mentioned earlier – and rebuffed by LinkedIn – as being a “Security Profile”. The nomenclature is a bit semantic and certainly many profile updates do have security implications. Ultimately this is what will configure access to email via the Intro service so call it what you will.

Back to the Bishop Fox article, they summarise profiles as being able to do the following:

Intro works by pushing a security profile to your device; they’re not just installing the Intro app. They have to do this in order to re-route your emails. But, these security profiles can do much, much more than just redirect your emails to different servers. A profile can be used to wipe your phone, install applications, delete applications, restrict functionality, and a whole heap of other things.

The subsequent rebuttal from LinkedIn effectively says “Yeah, but we don’t do that” and they’re right – they don’t. But the consumer doesn’t know that! Again, this is where much of the concern lies because profiles are just such powerful things not just because of what they can change in terms of device settings, but because they’re not provisioned via the App Store thus don’t go through Apple’s approval processes. I know I mentioned that earlier but it’s a key point as people tend to think that everything “installed” on their iOS devices is somehow reviewed and approved by Apple. Intro isn’t.

Moving on, installing a profile requires passcode validation which should be another indicator of just how significant an update like this is considered:

Enter your passcode to install the profile

That done, the profile will be successfully installed and a confirmation message is displayed:

Profile installed

One other thing the profile does when it’s installed is creates a shortcut on the desktop:

Intro shortcut on the desktop

This is not an app, it’s just a shortcut through to secure.intro.linkedin.com which then opens in Safari:

Confirmation on the website of Intro being installed

Once we exit out of the profile, we’re back to Safari and notified that a new mail account has been added. Usually this means that you’ll now have two email accounts: the original one on the phone and now the new one Intro added via the profile:

Prompt about the new email account

To avoid confusion, Intro now prompts you to turn off the original account:

Instructions to turn off the original email account

Indeed when we jump into the mail settings, there’s now a “Gmail +Intro” account in addition to the original Gmail account:"

A second account for "Gmail +Intro"

Let’s follow the earlier guidance from Safari and disable that Gmail mail account:

Disabling the original Gmail account

While we’re looking at mail, let’s check out what Intro has set up for us:

Details of the Intro account

This is just an inbound IMAP account with an outbound SMTP server, both obviously on LinkedIn’s domain.

Back to Safari, tell Intro we’ve disabled the account and she’s all wrapped up:

Safari confirming the process is complete

That’s the entire setup process, let’s now see what she does.

Using Intro

Now that we’re all setup, let’s get started using the service and the first thing we’ll do is to get Agent Smith to send me an email. Right back at the start of this post you saw what an email from Agent Smith looks like when opened in Outlook, here’s how it looks now post-Intro:

Email sent with the LinkedIn footer

The obvious change is the signature which promotes the Intro service and includes Agent Smith’s LinkedIn name and professional headline which link to his profile. This is worth being aware of – the use of Intro is advertised to all recipients of emails sent from the iPhone in what I can only assume is an attempt at self-propagation. To me, this wasn’t clear during the setup process (I’m sure there’s probably some fine print on it somewhere) and of course you don’t see this when composing an email like you would a normal signature as it’s added after you send it. Your email is modified not just when you receive it via Intro, but also when you send it.

Why is this a problem? Well other than the obvious issue of LinkedIn having access to your mail, it also means there’s a risk of things like this happening:

Modified email next to unmodified email

Hang on – what the? Intro has changed the format of the email. More specifically, Intro has converted the message from plain text to HTML and it’s then up to recipient’s email client as to how they want to format it. Of course it has to do this – Intro can’t render fonts in different sizes and colours and add hyperlinks when it’s plain text. This isn’t a major thing, but it’s frustrating. I don’t like Times New Roman, I like a nice sans-serif font, dammit! The point is that once you have an intermediary manipulating the mail structure, things will change.

Just to be clear on exactly where the mail is coming from, let’s also take a look at the headers:

Received: from smtp.proxy.rapportive.com ([8.22.120.100])
        by mx.google.com with ESMTPSA id ry4sm37728894pab.4.2013.10.28.15.05.43
        for 
        (version=TLSv1 cipher=RC4-SHA bits=128/128);
        Mon, 28 Oct 2013 15:05:45 -0700 (PDT)

Rapportive are the guys who “show you everything about your contacts right inside your inbox” and were acquired by LinkedIn last year. Inevitably it’s their smarts driving Intro and the name pops up here and there such as in the SMTP mail server above. The point is that it’s very clearly LinkedIn (or subsidiary) who are handling the mail and sending it out via their SMTP gateway.

Let’s move on and reply to the message because after all, the primary value proposition for Intro is that it brings LinkedIn data into email received by those using the tool. Let me respond from Outlook on the desktop and seek a bit more information. Here’s what it now looks like when it hits the iPhone:

Receiving an email through Intro

Right, now we can see the real value proposition for Intro kick in. My real LinkedIn profile – the one associated with my real email address – appears at the top of the mail. Frankly, I’m not real keen on losing 20% of my readable email space (yes, I measured it), and it is very overt. One thing for sure is that Intro grabs some very prime real estate in the message – you can’t escape its prominence.

Intro allows you to expand the banner it places in the email so that it can display various attributes of the sender’s profile:

Expanding the Intro banner

The template used to drive this is conveniently located over on GitHub Gist and essentially it’s just some data URIs for the images plus some CSS. Actually, it’s kind of clever the way they’ve done this and it works in their favour that they really only need to target one device in terms of compatibility so those data URIs work just fine. One side effect of this (and not one I’ve seen covered in the media to date), is that those data URIs in particular add quite a bit of bulk to the email, in fact it looks like an email such as the one above goes from a few bytes to many kilobytes which is quite a big jump on your data plan.

You get more of a sense of where this bulk comes from as you scroll down through the expanded panel:

Scrolling through the expanded email panel

And… keep scrolling:

Even more scrolling

Actually I skipped a big bit in the middle there and obviously the amount of content will depend on the profile of the person you’re viewing but regardless, it’s lengthy.

One of the things I wondered about with Intro was what happens when a participant of the program replies to a message? I mean does the recipient (who may well have nothing to do with Intro) get the same panel of data that was embedded into the markup? Easy answer – no:

Replying to a message through Intro

Inevitably this has been modified again on the outbound connection from the device to Intro and it’s simply stripped out the markup it originally injected. It also doesn’t appear in edit mode on the iPhone when you’re actually responding to a message with an Intro banner in it:

Editing a message parsed by Intro

This is actually a neat user experience (security issues aside) and it demonstrates that LinkedIn have invested a lot of effort in making this service what it is. In all fairness, it’s a very slick experience and I can’t imagine it being done much better with the technologies they have available to them.

So that’s the mechanics of the thing, now let’s tackle some of the security issues.

A self-defeating verification proposition

In the introduction of Intro, LinkedIn talks about the ability to verify the identity of the sender using their service (text bolded by me):

David says Crosswise would love to work with you. Is this spam, or the real deal?

With Intro, you can immediately see what David looks like, where he’s based, and what he does. You can see that he’s the CEO of Crosswise. This is the real deal.

Now of course this is just ludicrous; asserting that the mere presence of some HTML in an email somehow verifies and establishes the authenticity of the sender is entirely nonsensical. It’s not like, say, the public key infrastructure that underpins SSL where you have the whole concept of a certificate authority and a means of verifying the integrity of content served over the connection. There’s a good post on this by Jordan Wright where he likens it to saying “we’ve put a picture of a lock in your email, so you know for sure it’s secure” and, well, many of you already know how I feel about padlock icons.

In the link above, Jordan goes on to create his own spoof email by reconstructing the HTML complete with LinkedIn Intro “verification” of the identity that sent it. There’s nothing high tech or particularly clever about this but of course that’s the very point he’s making – this is not “the real deal” – this is a piece of HTML in a plain old email. That is all.

But it does raise some interesting potential…

Spoofing identities

This is easiest explained graphically by this:

Spoof email from OJ

This is fellow security aficionado, good friend and all round nice guy OJ Reeves. OJ was happy for me to use him as an example of how this is very much not the real deal. OJ didn’t send this email to Agent Smith, I did. All I needed to do was construct an email where the sender’s email address was OJ’s. In this case I sent the mail with a reply to address that’s my own so when Agent Smith responds, the email comes to me yet this is what he sees:

Responding to OJ

You have to actually tap through on the “To” name to see the email address you’re actually sending this to and in the case above, it’s not OJ, it’s me.

This is very trivial and there’s nothing newsworthy in the ability to send email with anyone’s address as the sender or in the “reply to” field, but it makes an extremely pertinent point: Intro gives you no assurance whatsoever that the profile you see in the email is that of the sender. Of course this is no different to the level of assurance you get from the Outlook connector mentioned earlier, it’s just that they don’t MitM your traffic for that and as best I’m aware, they also don’t claim that it gives you assurance that the sender is “the real deal”.

Just one other minor thing while we’re looking at that email from OJ – sometimes when flicking around in mail you’ll see this:

Photo 31-10-2013 13 15 28

This is OJ’s name, and it’s from OJ yet you’re seeing my LinkedIn profile info. It only flickers for a moment then correctly shows OJ’s info. Inevitably this is a redrawing issue on behalf of iOS mail, but it’s a bit disconcerting. Remember, we’re trying to see if this is “the real deal”!

In defence of the service

It’s worthwhile addressing LinkedIn’s defence of the service and particularly the article titled The Facts about LinkedIn Intro by Cory Scott. They copped a lot of flak very early so good on Cory and co for being proactive and having a shot at addressing the concerns. Anyway, the article talks about network segmentation, perimeter hardening, pen tests, TLS and so on and so forth and these are all undoubtedly good things. But effectively what it boils down to is “We know what we’re doing is risky so we’ve had to take extra precautions”. I just get the sense it’s a bit like saying that it hurts when you hit yourself.

The worrying thing though is that when you read statements like how they “challenged each other to consider possible threat scenarios” you kinda wonder – aren’t you doing this already? I mean aren’t these practices ingrained into the psyche of the developers as par for the course anyway? C’mon guys, you did lose those 6.5 million accounts last year, would that alone not suggest that by now you were thinking about threats anyway?!

I also find it odd that the defence talks about much what has been written being “purely speculative”. Of course it’s speculative – that’s what we do in security! We speculate that unprotected data may be observed or manipulated in transit so we apply SSL. We speculate that databases may be breached and credentials exposed so we use strong password hashing algorithms. The article does go on to support “healthy scepticism and speculation” so I don’t think the concerns others have raised are entirely lost, but it did strike me as an odd position to take in the opening paragraph.

Cory did also offer to help answer any questions I might have after I tweeted a query earlier in the week. To his and LinkedIn’s credit, Cory was very helpful on short notice and I’ve incorporated some of his feedback to my queries in this post. One of the issues that seems to come up a lot is around the “reading” of emails and LinkedIn asserts that they don’t “read” them per se, rather they look at the sender and they obviously change the format if required and inject some HTML at various points. Frankly, I think the whole “do they or don’t they read mail” misses the point: the capability exists to inspect and manipulate the contents of the mail and indeed this is exactly what Google asked us to grant permission to earlier on – to “view and manage your mail”. Look, despite all the effort invested in security and what we can only fairly assume to be the best of intentions, it’s this simple: LinkedIn has the capability to inspect and manipulate the contents of the mail – that’s the very design of the Intro service. By extension, if LinkedIn gets pwned (again), the potential is there for someone else to read and modify your email – that’s indisputable.

Another thing that strikes me as odd is that on the one hand LinkedIn can talk about all these excellent security measures (and there’s no argument that they talk about many good things), but then stand up a login form loaded over HTTP:

Loading the LinkedIn login page over HTTP

Yes, it posts to HTTPS but we know that’s useless. Facebook worked that out a long time ago after the Tunisian government kept pwning their users, I just can’t fathom why LinkedIn would do this. In their defence, this is apparently something they’re imminently addressing (in fact it may already be resolved for browsers in some locales) but it does seem to be an odd oversight in this day and age. And that’s another point worth nothing on the security front – what we deem to be “safe” today may not be what we deem to be safe tomorrow and it’s often only after serious incidents that sentiments change. That may well yet prove to be the case with Intro handling email.

In conclusion…

A lot of the contention around Intro is that it just feels a bit wrong on many different levels. It’s not just the MitM’ing of email or the manipulation of its contents or the inability to correctly establish “the real deal”, it’s the message that this is sending to everyday consumers. For one of the largest social media presences on the web to encourage hundreds of millions of users to install a profile on their iOS device sends a worrying message – that it’s ok. Desensitising people to the process of installing the profile sets a risky precedent. Trivialising the significance of installing profiles undermines so much of the positive work that the likes of Apple and Microsoft have done in sandboxing apps to protect from the very risks that this now introduces.

LinkedIn Intro may well be a neat tool for many people and I’m sure they’ll inevitably have millions sign up to it. The concept of entrusting your email with an external provider is nothing new. The big question is whether we’re really ready to trust our private email communications with a social media company with a strong focus on mining data. We worry about sharing small pieces of information with Facebook; are we ready to share every single email - every single attachment - with one of the world's largest social media companies? That Intro comes so closely after the NSA revelations where it’s now become clear that the US government is hell bent on getting their hands on as much data as possible is poor timing for LinkedIn, but opportune timing for those who may now be wondering just how much “sharing” of their data they really want to consciously opt into.

23 Oct 11:32

Guide to 3 Days in Vienna

by Vicky

Vienna is simply a marvelous city. To me it was exactly what I pictured when I thought of a classic European city; the grandiose palaces and historic architecture with it’s classical music concerts and sausage stands.

Vienna is the quintessential European city, not overwhelming but with just enough going on to keep you busy and excited for your time there.

We spent  a few days there and covered a lot of different sites and parts of the city. There is so much to do in Vienna that we barely even grazed the surface but with a few days you can get a brief introduction into what the city has to offer. If you’ll be spending 3 days in Vienna make sure to visit the attractions listed below.

 

  • Nasch MarketThis market is the oldest and most famous market in Vienna. You’ll simply be amazed by the variety of items on sale here and the international flare. The market is open everyday except Sunday and makes for a perfect lunch stop to start off a Vienna tour.

nasch market

 

nasch market

 

  • BelvedereThe Belvedere is a Baroque palace complex consisting of the upper and lower belvedere, the orangery, palace stables and gardens, and was the home of Price Eugene of Savoy. The Upper Belevedere houses an art museum which is what we visited before strolling through the beautiful gardens.

belvedere

 

belvedere

  • Hofburg Palace - The Hofburg Palace served as the home at the Habsburg dynasty – the rulers of the Austro-Hungarian Empire and is currently the official residence of the President of Austria. This was the Habsburg family’s winter home.

hofburg palace

 

  • Freud Residence - Museum covered the life of Sigmund Freud. He lived in this house from 1891 until 1938, when he was forced to leave due to his Jewish roots, and fled to London.

freud residence

 

  • Jewish Monument - This is the memorial to the 65,000 Austrian Jews who died in the Holocaust. In the nearby Misrachi house there is a museum with a permanent exhibition and information area with names and dates of the murdered Jews and the circumstances that led to their persecution.

 jewish monument

 

  • Soviet Victory Monument A monument built by the Red Army to commemorate 17,000 Soviet soldiers who died in the battle for Vienna in World War II. This is a controversial memorial which the Viennese attempted to blow up several times, always stopped by the police.

victory-monument

 

  • Karlskirche - This is a Baroque church dedicated to Saint Charles Borromeo, one of the great reformers of the 16th century. Admission includes panoramic elevator ride up to the dome where you can admire the artwork.

karlskirche

 

karlskirche

 

  • Schonbrunn Palace - As the Hofburg Palace was the winter home to the Habsburgs the Schonbrunn was their summer home. This 1,441 room Rococo residence is massive with the palace and the gardens equally impressive.

schonbrunn-palace

 

schonbrunn-palace

 

  • Stephansdom - Romanesque gothic cathedral in the old town of Vienna. After exploring the cathedral and catacombs go up to the top of the tower to get a great view of the whole city of Vienna.

stephansdom

 

  • Classical Music Concert - Vienna is a great place to spend an evening at a Mozart classical music concert. There are several venues to choose from including the State Opera, Musikverein Golden Hall, Hofburg (Imperial Palace) and the Vienna Konzerthaus. We saw a concert at the Konzerthaus and were able to purchase discounted student tickets.

listening-to-classical-music

 

  • The Sausage StandWe frequently ate at this sausage stand located right in the center of the city, at  Albertinaplatz. Delicious sausage with rye bread and beer. A must visit. We saw all sorts of characters buying from here – even the local policemen.

sausage-stand

sausage-stand

 

  • Wandering around central Vienna - One of the best ways to get a feel for a city is just to get lost in it. Put away the map and just explore the various streets and alleyways that make up central Vienna. Stop for a coffee, try a local dessert, and just take in everything that Vienna has to offer.

central-vienna

The post Guide to 3 Days in Vienna appeared first on .

23 Oct 08:51

Calca for Windows, you asked for it!

image

Calca for Windows has been the #1 asked for “feature” since Calca for iOS debuted in July. Today, I’m happy to announce that it’s finally available for purchase! For just $9.99 you can own this powerhouse of a calculator.

A very Windows app

Calca for Windows was designed to be fast and light weight. It ships as a single executable that doesn’t need to be installed (don’t worry, there’s an installer too if you want it) and presents a minimalist user interface. There is no drama of loading a big IDE or massive spreadsheets. Calca pops right up and begs you for something to do.

And, oh, it works on Windows XP. Yep, that’s right: Calca was designed to work where you have to work, no judgements.

If you’re just getting started with Calca, make sure you read the Introduction and Examples under the Help menu to get started.

A more powerful engine

One of the most exciting things about this release is that it ships with version 1.2 of the Calca engine. In addition to numerous bug fixes, this version also has fantastic units and currency support.

You can easily convert simple values:

12 tbsp in cups => 0.75 cups

Units have been implemented in a very general manner allowing you to do some pretty advanced computations.

Here is one of my favorites: how to calculate how much water falls on your land throughout the year.

land area = 0.25 acre

avg annual precip = 36.15 inch / year

daily rain accumulation

     = avg annual precip * land area in gallon/day

     => 671.9012 gallon/day

In order to perform this calculation, Calca had to know how to convert between acres, inches, days, years, and gallons and it does it all with a minimal amount of typing.

There are lots of other improvements, but since this is a new release, I won’t bore you all with details here. But watch this blog as I will be pointing out nice new features from time to time.

(And don’t worry Mac and iOS friends, updates are being submitted to Apple this week so that you will get these new features too.)

Code reuse numbers

For my developer friends out there who like to keep tabs on me, I was able to reuse 18,000 lines of code from the previous Calca versions and only had to write 3,000. The majority of that code is implementing a document-based application architecture.

Here the code reuse stats in picture form:

image

86% code reuse is great, though I do with it was in the 90s. The Mac is able to achieve this because of the powerful Cocoa library that has first-class support for document based applications. On Windows, I used Win Forms and had to implement all the file management by hand just like with iOS. Speaking of iOS, it’s numbers have grown a bit because I have some nice surprises in store for its updates.

14 Oct 11:29

Reverse Engineering a D-Link Backdoor

by Craig

All right. It’s Saturday night, I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape…let’s hack.

On a whim I downloaded firmware v1.13 for the DIR-100 revA. Binwalk quickly found and extracted a SquashFS file system, and soon I had the firmware’s web server (/bin/webs) loaded into IDA:

Strings inside /bin/webs

Strings inside /bin/webs

Based on the above strings listing, the /bin/webs binary is a modified version of thttpd which provides the administrative interface for the router. It appears to have been modified by Alphanetworks (a spin-off of D-Link). They were even thoughtful enough to prepend many of their custom function names with the string “alpha”:

Alphanetworks' custom functions

Alphanetworks’ custom functions

The alpha_auth_check function sounds interesting!

This function is called from a couple different locations, most notably from alpha_httpd_parse_request:

Function call to alpha_auth_check

Function call to alpha_auth_check

We can see that alpha_auth_check is passed one argument (whatever is stored in register $s2); if alpha_auth_check returns -1 (0xFFFFFFFF), the code jumps to the end of alpha_httpd_parse_request, otherwise it continues processing the request.

Some further examination of the use of register $s2 prior to the alpha_auth_check call indicates that it is a pointer to a data structure which contains char* pointers to various pieces of the received HTTP request, such as HTTP headers and the requested URL:

$s2 is a pointer to a data structure

$s2 is a pointer to a data structure

We can now define a function prototype for alpha_auth_check and begin to enumerate elements of the data structure:

struct http_request_t
{
    char unknown[0xB8];
    char *url; // At offset 0xB8 into the data structure
};

int alpha_auth_check(struct http_request_t *request);

alpha_auth_check itself is a fairly simple function. It does a few strstr’s and strcmp’s against some pointers in the http_request_t structure, then calls check_login, which actually does the authentication check. If the calls to any of the strstr’s / strcmp’s or check_login succeed, it returns 1; else, it redirects the browser to the login page and returns -1:

alpha_auth_check code snippet

alpha_auth_check code snippet

Those strstr’s look interesting. They take the requested URL (at offset 0xB8 into the http_request_t data structure, as previously noted) and check to see if it contains the strings “graphic/” or “public/”. These are sub-directories under the device’s web directory, and if the requested URL contains one of those strings, then the request is allowed without authentication.

It is the final strcmp however, which proves a bit more compelling:

An interesting string comparison in alpha_auth_check

An interesting string comparison in alpha_auth_check

This is performing a strcmp between the string pointer at offset 0xD0 inside the http_request_t structure and the string “xmlset_roodkcableoj28840ybtide”; if the strings match, the check_login function call is skipped and alpha_auth_check returns 1 (authentication OK).

A quick Google for the “xmlset_roodkcableoj28840ybtide” string turns up only a single Russian forum post from a few years ago, which notes that this is an “interesting line” inside the /bin/webs binary. I’d have to agree.

So what is this mystery string getting compared against? If we look back in the call tree, we see that the http_request_t structure pointer is passed around by a few functions:

call_graph

It turns out that the pointer at offset 0xD0 in the http_request_t structure is populated by the httpd_parse_request function:

Checks for the User-Agent HTTP header

Checks for the User-Agent HTTP header

Populates http_request_t + 0xD0 with a pointer to the User-Agent header string

Populates http_request_t + 0xD0 with a pointer to the User-Agent header string

This code is effectively:

if(strncasecmp(header, "User-Agent:", strlen("User-Agent:")) != NULL)
{
    http_request_t->0xD0 = header + strlen("User-Agent:") + strspn(header, " \t");
}

Knowing that offset 0xD0 in http_request_t contains a pointer to the User-Agent header, we can now re-construct the alpha_auth_check function:

#define AUTH_OK 1
#define AUTH_FAIL -1

int alpha_auth_check(struct http_request_t *request)
{
    if(strstr(request->url, "graphic/") ||
       strstr(request->url, "public/") ||
       strcmp(request->user_agent, "xmlset_roodkcableoj28840ybtide") == 0)
    {
        return AUTH_OK;
    }
    else
    {
        // These arguments are probably user/pass or session info
        if(check_login(request->0xC, request->0xE0) != 0)
        {
            return AUTH_OK;
        }
    }

    return AUTH_FAIL;
}

In other words, if your browser’s user agent string is “xmlset_roodkcableoj28840ybtide” (no quotes), you can access the web interface without any authentication and view/change the device settings (a DI-524UP is shown, as I don’t have a DIR-100 and the DI-524UP uses the same firmware):

Accessing the admin page of a DI-524UP

Accessing the admin page of a DI-524UP

Based on the source code of the HTML pages and some Shodan search results, it can be reasonably concluded that the following D-Link devices are likely affected:

  • DIR-100
  • DIR-120
  • DI-624S
  • DI-524UP
  • DI-604S
  • DI-604UP
  • DI-604+
  • TM-G5240

Additionally, several Planex routers also appear to use the same firmware:

  • BRL-04R
  • BRL-04UR
  • BRL-04CW

You stay classy, D-Link.

UPDATE:

The ever neighborly Travis Goodspeed pointed out that this backdoor is used by the /bin/xmlsetc binary in the D-Link firmware. After some grepping, I found several binaries that appear to use xmlsetc to automatically re-configure the device’s settings (example: dynamic DNS). My guess is that the developers realized that some programs/services needed to be able to change the device’s settings automatically; realizing that the web server already had all the code to change these settings, they decided to just send requests to the web server whenever they needed to change something. The only problem was that the web server required a username and password, which the end user could change. Then, in a eureka moment, Joel jumped up and said, “Don’t worry, for I have a cunning plan!”.

Also, several people have reported in the comments that some versions of the DIR-615 are also affected, including those distributed by Virgin Mobile. I have not yet verified this, but it seems quite reasonable.

UPDATE #2:

Arbitrary code execution is also possible, thanks to the backdoor. Proof of concept.

26 Sep 11:08

1 Tages-Aktion auf DVDs, Blu-rays und Boxsets bei Amazon

by Markus

Schnäppchen für ÖsterreichSchnäppchen für Deutschland

Zum Kinostart des Films “Keinohrhase & Zweiohrküken” mit den Stimmen von Til und Emma Schweiger, hat Amazon heute eine 1 Tagesaktion gestartet. Dabei bietet das Unternehmen in erster Linie Kinderfilme und Komödien auf DVD und Blu-ray günstiger an. Auch Boxsets wurden im Preis reduziert – die Angebote gelten aber nur heute.

Die 1 Tages-Aktion von Amazon ist in drei Bereiche unterteilt – Kinderfilme, Komödien und Boxsets. Mit 219 Titeln ist das Tagesangebot recht umfangreich und hier sollte für jeden etwas dabei sein. Ein paar Angebote haben wir euch nachfolgend zusammengefasst:

Kinderfilme

Komödien

Box-Sets

16 Sep 07:20

Great Opportunity For a Senior WPF/C# Developer

by Karl

Gayle Manufacturing Company (GMC) is seeking a senior WPF/C# developer with 3+ years’ of development experience to join the GMC IT Team that is developing a WPF application to replace our current Windows Forms material requirements planning (MRP) system. The MRP system manages all aspects of GMC’s daily operations including but not limited to Project Management, Drawing Management, Material Procurement, Product Manufacturing, and Shipping & Receiving.

This high profile position plays a critical role regarding the future operations and ongoing prosperity of GMC. GMC is prepared to offer an excellent compensation and benefits package to an outstanding individual.

The GMC IT Team is located at the Nampa, Idaho plant. This position has regular office hours without telecommuting.

The Ideal Candidate

The ideal candidate will be technically proficient developer with a solid background in WPF, OO programming concepts, an understanding of common design patterns, and who delivers quality, maintainable code. The candidate will have strong leadership skills and a proven track record of developing and delivering complex software.

The candidate will have the ability to thrive in a small team environment and who embraces new programming challenges; whose experience, creativity, and passion for WPF are demonstrated by their work product. Additionally, the candidate will have the ability to effectively interact and communicate with non-programmer company employees.

The candidate must have the following experience:

  • 3+ years of C# development
  • 3+ years of WPF development
  • WPF in-depth knowledge and experience that includes: authoring custom controls, data binding, control templates, styles, triggers, behaviors, data entry forms, nested forms and grids, data validation, and MVVM.
  • Proficient with C# object oriented programming
  • Understanding of cross-cutting concerns and solutions
  • 3+ years of SQL Server development using ADO.NET API’s.
  • Experience with the following would be helpful:
    • Prism
    • Infragistics WPF DataGrid control
    • Telerik reporting controls
    • TFS source control
    • Unit and integration testing

Qualified applicants will be vetted for technical proficiency in the above requirements.

About Us

Gayle Manufacturing Company has a 43 year history of growth and prosperity, whose motto is, “performance through innovation.” During those years, GMC has become an established leader and innovator in the Structural Steel Industry. GMC has a 25 year history of successful development and implementation of proprietary MRP software systems. These systems are comprehensive and sophisticated. They are very focused and tuned to the GMC business model and support the specific management and manufacturing methods developed at GMC.

How to Apply

Please download our job application at http://www.gaylemfg.com/Documents/Application.pdf, email the completed application along with your resume to wpfposition@gmcx.com or fax to (208) 468-0500.

If applicable, also include a link to your blog, links to speaking engagements, and links to other on-line WPF articles you have authored.

In the subject field of the email, please enter the following text: WPF Developer: <your first and last name>.

Have a great day,

Just a grain of sand on the worlds beaches.


Filed under: Job Posting
10 Sep 07:57

Erlang/ALE Update

by Ivan Iacono

We have spent the past couple of weeks adding more peripherals to Erlang/ALE, our library for embedded systems. The first version of ALE only had support for General Purpose I/O (GPIO) but with the recent commits we have added I2C, SPI and PWM. You can fetch the latest version at our Github repository.

Raspberry Pi is still our reference platform but in order to make ALE more universal we have started working on defining a platform abstraction mechanism that will enable supporting other boards and architectures easily. The way this works is simple: ALE consists of platform independent layers that interface with a collection of platform specific, low level drivers that provide access to hardware. This is demonstrated by the diagram below.

ale_architecture

The highest level provides the peripheral APIs, such as GPIO, I2C, SPI and PWM, allowing Erlang applications access these hardware units. These are implemented following the OTP standards, using gen_server and supervision hierarchies.

The Middle layer is the interface mechanism, a glue layer between Erlang and the low level C drivers. It deals with the translation of Erlang terms to and from C types, using the interfacing mechanisms provided by Erlang: Ports and NIFs.

In the lowest layer we find the peripheral implementations that contain the specific instructions to access the hardware peripheral on the silicon device. As mentioned before, ALE on its own does not include drivers for any specific architecture. On our reference platform, the Raspberry Pi, we achieve this by using pihwm as our peripheral implementation layer.

While the platform architecture is still under development, you can find the documentation for the peripheral APIs and the interface mechanism here.

As always, comments and suggestions are welcome. Drop us an email or post a comment here.

Until next time, cheers!

30 Aug 08:18

Best Practice Corporate Blog Erfolg: DAS Salesforce Blog zeigt, wie es gehen kann

by Michael Firnkes
Wie misst man den Erfolg eines Corporate Blogs? Welche Ziele gilt es festzulegen? Wie rentabel muss dieser sein? Und wie hat sich die Firmenblogger-Szene in den vergangenen Jahren verändert? Das und mehr in einem sehr spannenden Interview mit Meike Leopold von DAS Salesforce Blog. Lesenswert! Frau Leopold, CRM ist ein sehr dankbares Blog-Thema, was man
06 Aug 11:36

Book Review: The Complete Guide On How To Negotiate

by JD

image

“Diplomacy is the art of letting someone else have your way.” — Sir David Frost

Negotiation skills are a big deal in today’s world.  If you learn effective negotiation skills you can transform almost every area of your daily interactions in work and life.

Whether you’re negotiating for a raise, buying a car, selling your house, or getting agreements with colleagues, negotiation skills pay off, both in keeping your cool and helping you get the results you want.

I’m always on the look out for new ways to improve my negotiation skills.  I’ve been lucky to learn from some of the best and brightest, and I get to practice negotiation skills on a daily basis.  In fact, I regularly mentor others in the art and science of negotiation and influence without authority.

I received a review copy of The Complete Guide On How To Negotiate: Master the Art of Getting What You Want in Business and In Life, by Tali Raphaely.  I agreed to write a review of the book, if I found it useful for readers of Sources of Insight.

And I did.

I think what surprised me about the book, is how simple it makes things.  Negotiations is a complex topic and It’s easy to get lost among a sea of strategies and tactics.  Instead, The Complete Guide on How To Negotiate gives you an effective negotiator’s mindset, focused on creating win-win opportunities.  Then, it follows up with some proven practices for common scenarios.  Meanwhile, throughout the book, Raphaely ensures you have the chops to deal with tough negotiators, hard-bargainers, and extreme scenarios.

Raphaely himself is an attorney, real estate investor, and motivational speaker, who has mentored countless people on developing their negotiation skills.

With that in mind, let’s dive in to the book …

What’s In It For You?

Here’s a sample of some of the things that The Complete Guide On How To Negotiate helps you with:

  • How to be a skilled negotiator with the basic tools and knowledge of leverage
  • How to be likable and create connections
  • How to think ahead and look at a situation before you are in it
  • How to get what you want when dealing with people while placing them in a position where they get what they want as well
  • How to develop savvy and develop insight into analyzing differences, arguments, and confrontations in all types of give-and-take situations
  • How to make more effective offers
  • How to ask the right questions under pressure
  • How to know when to walk away from a deal
  • How to negotiate your salary
  • How to assess pressure and timelines on the other side in a negotiation
  • How to recognize and deal with “slippery slopes”
  • How to create an atmosphere of cooperation and collaboration

Chapters at a Glance

  • Introduction
  • Chapter 1 – Tale of Sad Sam and Skillful Sam
  • Chapter 2 – Getting Started with Some Basic Concepts
  • Chapter 3 – Talk Less, Listen More!
  • Chapter 4 – The Offer
  • Chapter 5 – The Fundamentals
  • Chapter 6 – Understanding and Using Precedents
  • Chapter 7 – Cooperation Not Competition
  • Chapter 8 – Hail and Farewell!

Key Features

Here are some of the key features of The Complete Guide On How To Negotiate:

  • Short.  The book is thin (~100 pages.)   The book is easy to read.  It’s compact, sets the stage, and then dives right in.
  • Actionable.  The book is extremely actionable.   In fact, every few pages you turn, you’ll likely want to try something.
  • Real-world advice.   It’s not academic theory.  It’s real-world lessons from the school of hard knocks.
  • Numbered concepts.  The concepts within each chapter are numbered for easy reference.  This is another factor that makes the book easy to read, and easy to pick up from wherever you left off, or easy to jump to a specific idea.

Here is a sampling of some of my favorite nuggets from the book …

Your Negotiation Skills Determine How You Live Your Life

I think Raphaely makes a great point right up front, how your negotiation skills can really make or break the quality of your daily life.

Raphaely writes:

“I believe that life presents us with a series of negotiations.  Further, I believe that it is your negotation and your people skills that will ultimately determine how you live your life and how easily things work out for you.  Imagine knowing how to get what you want in your life from interactions with friends, business associates, employees, your boss, clients, colleagues, store clerks, customer-service representatives, and complete strangers.  Using the techniques I’m about to share, you will be able to consistently achieve the results you want when dealing with others.”

Turn Dead-End Situations into Promising, Rewarding, and Positive Opportunities

One of the key attributes of a skilled negotiator is the ability to make lemonade from lemons.

Raphaely writes:

“I want to empower you with this ability to turn dead-end situations with no apparent possible solutions into promising, rewarding, and positive opportunities with multiple possible solutions.  This can be done without being manipulative, dishonest, or confrontational.  Instead, my techniques foster respect, courtesy, and cooperation.”

Sad Sam

To help contrast the life of a skilled negotiator, Raphaely shares the story of Sad Sam, who lacks negotation skills.

Raphaely writes:

“It’s 7 a.m. on Monday morning, and Sam is starting a relatively typical day in his life.  He and his wife are trying to wake up their kids for school, but, as usual, their kids want to stay in bed.  The struggle continues for a while until he has had enough of it and leaves the situation for his wife.  He knows that she’s going to be angry at him for giving up, but he decides there’s nothing more he can do.  Before he leaves the house, however, he also manages to engage in a quick skirmish with her about where the family will go on vacation this year.  He wants to go somewhere quiet so he can relax, while she wants to go where there will be many activities for family participation.  This year will probably end up like every year prior and they will fight about this particular topic until someone just gets too tired and gives up, agreeing to a trip that no one can enjoy.”

Skillful Sam

To help show what life as a skilled negotiator might look like, Raphaely shares the story of Skillful Sam.

Raphaely writes:

“Skillful Sam recognize that the daily struggle to wake up and activate his kids starts each day with unnecessary stress.  It’s time to negotiate this to his liking.  After all, they’re just kids and, more importantly, they’re his kids, and he loves them dearly.  Are there certain things they’ve been asking for — a trip somewhere, a toy, or permission to take on a new freedom?  Why not negotiate with his kids, promising them one of these things in return for their promise to get up on time every morning with no hassles? Now he’s given them incentive to make his life more peaceful, as well as a goal for them to work toward!”

15 Negotiation Skills

Raphaely shares 15 negotiation skills that will help you be a more skilled negotiator:

  1. Slow things down; negotiations are marathons and not sprints.
  2. Speak less and listen more.
  3. Don’t interrupt the other side.
  4. Go last; he or she who speaks first loses.
  5. Never make the other guy feel like he lost.
  6. View a negotiation as a series of steps and not as one action.
  7. Be respectful, polite, and likable.
  8. Think outside the box; come up with creative solutions.
  9. Always come prepared.
  10. Never assume anything.
  11. Ask for what you want.
  12. Keep on trying; don’t give up.
  13. Ask a lot of questions.
  14. Never start with your best, bottom-line number.
  15. Always make the other side feel satisfied with the deal.

The Slippery Slope

The slippery slope is a common trap, where you end up making concessions that don’t seem like much at first, but over time, snowball out of control.  It’s like a frog in the boiling pot.

Raphaely writes:

“Do your best to put up a good battle when even minor price or service changes or concessions are asked of you in an ongoing relationship.  Remember that this individual is storing that information and it will set the tone for future negotiations.”

Put Yourself in Their Shoes

To operate from a more effective perspective, Raphaely recommends putting yourself in the other person’s shoes.

Raphaely writes:

“When you do your best to put yourself in other people’s shoes, it becomes easier to keep your cool and understand where they’re coming from even if they aren’t appearing reasonable at the time.  As with all aspects of your life, try to see the good in other people and always remind yourself they are just doing the best they can with the emotional and intellectual resources they have available.

As long as you don’t take things personally, you will be less likely to react with anger or get rattled.  Consequently, you’ll be more patient and will foster an atmosphere more likely to promote collaboration and conversation instead of confrontation.”

Don’t Make People Feel Powerless

Don’t back people into a corner.  It always backfires and people will take you down with them.

Raphaely writes:

“If an individual feels like he or she was powerless and that you essentially got your way without offering him or her a choice, you will not win in the end.  Powerlessness leads to feelings of resentment.  He or she will either find any way possible to change terms after the fact, or you won’t receive the full performance when all is said and done.”

Negotiate with the Person Who Has Final Authority

If you want to cut to the chase, and avoid playing good cop/bad cop, make sure you have the person with the final authority actively participating face-to-face in the discussions.

Raphaely writes:

“If you aren’t dealing with the right individual, you will be subject to constant frustration when the person you are speaking with has to consult with someone else every time you try to get a concession.  You may even begin to feel like you’re bidding against yourself, because your concessions will come quickly while theirs will occur more slowly because of additional communication with a third party.  If you realize more than one person is involved in the negotiation, try to negotiate with both of them together at the same time.  You would ask something  like, ‘Can we get Sally to join us in these discussions  so that we are all together and this process can go much more smoothly.’”

Prepare in Case Things Change Later

Always leave yourself a way out.

Raphaely writes:

“When possible and applicable, negotiate an exit strategy for yourself into the terms of the deal.  People often assume that everything will work out as the parties had hoped, but in reality things change with time.  A wise negotiator, however, always leaves himself or herself with as many ‘outs’ as possible while being careful not to anger or offend the other side.

An example of an ‘out’ would be negotiating for an inspection clause as part of a sales contract for a home you are purchasing, a home that wasn’t your first choice.  This creates an opportunity to change your mind about buying the house with no penalty within a certain number of days from the date of the inspection.”

Get the Book

The Complete Guide On How To Negotiate, by Tali Raphaely is available on Amazon.

The Complete Guide On How To Negotiate: Master the Art of Getting What You Want in Business and In Life, by Tali Raphaely

You Might Also Like

Interpersonal Skills Books

Negotiation Books

How To Deal with Hard Bargainers

Image by jonny goldstein.

18 Jul 06:25

Don’t Push Agile, Pull It

by JD Meier

I wrote my first article for Projects at Work.   It’s called Don’t Push Agile, Pull It, and it’s a simple recipe for introducing Agile into established organizations, in a more effective way.  Here it is:

Don’t Push Agile, Pull It

If you’re ever rolled-up your sleeves and tried to champion new ways of doing things into an established organization, then you know how tough change can be.   In fact, it’s not just tough.  It’s often how, careers end.   If you don’t have the right sponsorship and the right change leadership skills to lead people through the organizational change, you take the brunt of the blame, or become the scape-goat for pain.

That’s why change leadership skills are an important part of your arsenal for getting results.

Even when you have a coalition of the willing, it can be incredibly tough to change the habits of people, the processes or the way things are done, and the tools and infrastructure that reinforces the well-established ways.

As you can imagine, this is a serious and significant challenge in today’s ultra-competitive marketplace, where change is on warp speed, and businesses are forced to adapt or die.

In fact, that’s largely why more and more organizations have a strong appetite for Agile -- Agile embraces change as a first-class citizen.

But, how do you get an organization to change from its waterfall ways, or less-than-agile culture?

That’s what I’ve had to learn, time and again, as I’ve helped individuals, teams, and leaders make the shift.  I’ve also had to make rapid shifts as I’ve moved around during my career.

Along the way, I’ve learned some very simple, but very powerful ways to help teams rapidly adopt Agile practices, and get results.  And, this goes well beyond the halls or walls of software.

Here’s the first blurb that introduces to the article:

“Introducing Agile methods to a team in an organization deeply rooted in waterfall ways is tough, especially when the culture is risk-averse and well-established. But you can be a catalyst for change and help your team learn to be more agile by following three simple practices.”

Please enjoy Don’t Push Agile, Pull It and be sure to share it with friends and colleagues that you know need some help in adopting Agile practices to help their team or business survive and thrive in our ever-changing landscape.

You Might Also Like

10 Big Ideas from Getting Results the Agile Way

Improve Your Execution Excellence with Roadmaps at a Glance

Team Execution Patterns

15 Jul 06:37

Building A Recommendation Engine - Machine Learning Using Azure, Hadoop And Mahout

by Anoop Madhusudanan
Doing some 'Big Data' and building a Recommendation Engine with Azure, Hadoop and Mahout
10 Jul 06:31

Webmagazin News: Selbsttest: Hast Du das Zeug zum Entrepreneur? [Infografik]

Steve Jobs gilt als einer der bedeutendsten Unternehmer unserer Zeit. Sein Werdegang war allerdings ziemlich holprig. Bevor Jobs eines der mächtigsten Unternehmen weltweit gründete, schmiss er die Uni und flog schließlich aus dem Unternehmen, das er ursprünglich selbst gegründet hatte. Seine Kreativität und sein rastloses Wesen halfen ihm jedoch aus Apple den Konzern zu machen, der er heute ist. Welche Wesenszüge gelten allgemeinhin als besonders hilfreich, wenn man sich als Entrepreneur durchschlagen will? Folgende Infografik von Funders and Founders zeigt neuen wesentliche Eigenschaften:…