55
IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public

Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

  • Upload
    others

  • View
    15

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

IST Amigo Project

Amigo Training Document: Using Amigo Security

Services Version 2.0

IST-2004-004182

Public

Page 2: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 1/54

Project Number : IST-004182

Project Title : Amigo

Deliverable Type : Tutorial

Deliverable Number :

Title of Deliverable : Using Amigo Security Services

Nature of Deliverable : Public

Internal Document Number :

Contractual Delivery Date :

Actual Delivery Date :

Contributing WPs :

Version : 2.0

Author(s) : Edwin Naroska, Ron Mevissen, Stephan Tobies, Rich Hanbidge, Todor Dimitrov

Abstract This document is a tutorial about gives an introduction on how to use the Amigo Security Services in order to setup secure communication channels between client and services. The tutorial will show how to write a secured service, how to write a client that makes use of a secured service. Further, it will explain how to authenticate a user/device within the Amigo network.

Keyword list Security Service, Symmetric Encryption, Decryption

Page 3: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 2/54

Table of Contents

Table of Contents................................................................................................... 2

1 Introduction ..................................................................................................... 4

1.1 Prerequisites..............................................................................................................................4

1.2 How to use this document ........................................................................................................4

2 System and software requirements ............................................................... 5

2.1 Installation of the security Java environment........................................................................5 2.1.1 Configure............................................................................................................................6 2.1.2 Compile ..............................................................................................................................6

2.2 Installation of the .Net security environment.........................................................................6

3 Amigo security................................................................................................. 7

3.1 Overview ...................................................................................................................................7 3.1.1 Objectives...........................................................................................................................7 3.1.2 Principles ............................................................................................................................7 3.1.3 Assessment .........................................................................................................................8

3.2 How to develop a simple secure service for .NET: example 1 ..............................................9 3.2.1 Service implementation......................................................................................................9 3.2.2 Registering and hosting a secured service........................................................................11 3.2.3 Complete server code .......................................................................................................13

3.3 How to develop a simple secure service for Java / OSGi: example 1.................................15 3.3.1 Definition of the service class interface ...........................................................................15 3.3.2 Service implementation....................................................................................................15 3.3.3 Complete server code .......................................................................................................18 3.3.4 Service bundle metadata...................................................................................................21 3.3.5 Service bundle manifest ...................................................................................................21 3.3.6 Service activator ...............................................................................................................22 3.3.7 Registering the service with the security service..............................................................22

3.4 Security Control Center.........................................................................................................24 3.4.1 Starting the Security Control Center ................................................................................24 3.4.2 Register a new user...........................................................................................................27 3.4.3 Register a new device.......................................................................................................27 3.4.4 Register a new service......................................................................................................31

3.5 How to develop a secure service client for .NET: example 1..............................................33 3.5.1 Complete client code ........................................................................................................35

3.6 How to develop a secure service client for Java / OSGi: example 1 ..................................37 3.6.1 Complete client code ........................................................................................................39 3.6.2 Cliebt bundle metadata .....................................................................................................41 3.6.3 Client bundle manifest......................................................................................................42

Page 4: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 3/54

3.6.4 Service activator ...............................................................................................................42

3.7 How to develop a simple secure service for .NET: example 2 ............................................44 3.7.1 Service implementation....................................................................................................44 3.7.2 Registering and hosting a secured service........................................................................45 3.7.3 Complete server code .......................................................................................................47 3.7.4 Registering the service with the Security Control Centre ................................................49

3.8 How to develop a secure service client .NET: example 2 ....................................................50

4 Recommended next steps.............................................................................. 53

5 Troubleshooting............................................................................................. 54

Page 5: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 4/54

1 Introduction This document is a tutorial about gives an introduction on how to use the Amigo Security Services in order to setup secure communication channels between client and services. In detail the tutorial will show how to write a secured service, how to write a client that makes use of a secured service. Further, it will explain how to authenticate a user/device within the Amigo network.

1.1 Prerequisites Amigo training blocks typically requires some Amigo related as well as non Amigo related skills or knowledge. These are given in the following:

� Non Amigo related prerequisites:

o The reader should be familiar with either Java or C# to easily follow the explanations.

o The reader should be familiar with an integrated development environment (IDE) for the programming language that shall be used. It is suggested to use either Eclipse 3.2 (or higher) for Java or Visual Studio 2005 for C#.

� Amigo related prerequisites: None.

For some general information on the Amigo project please refer to the Amigo project web site at http://www.hitech-projects.com/euprojects/amigo/index.htm.

1.2 How to use this document This document aims at providing the reader with valuable information about how to use the Amigo middleware. To this end it gives a step by step introduction where explanations are accompanied with short programming assignments. Please proceed to the document section by section and step by step and try to do the assignments. In order to save some typing, an appropriate set of template files is given that can be used to fulfill the assignments. These template files already include a programming frame that must be extend by you in order to complete the assignment. For information on how where to obtain these template files please refer to Chapter 2.

If code is printed in normal text, it is shown in italic. This example shows how the method name unsubscribe() is printed. Entire code blocks are embedded in a box as shown below:

using ( Service service = new AddService (securedService)) { WebServer .AddWebService(serviceLocation, service); Console .WriteLine( "Sample service 2 running." + Environment .NewLine + "Press <return> to quit" ); Console .ReadLine(); }

Page 6: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 5/54

2 System and software requirements For the tutorial you need a PC compatible system with the following properties:

� PC running Windows XP, Vista or Windows Server 2003.

� A working network connection if server and client applications shall be executed on different machines.

For the tutorial you need an installed version of the Java Development Kit, including the javac compiler and the jar tools (Java Version 1.5.x).

If your are using Java, then the following software is needed:

� Java Software Development Kit. This is a general package needed for Java software development. The package is available from http://java.sun.com.

� Oscar. Oscar is a open source OSGi framework. This software is available from http://amigo.gforge.inria.fr/obr/tools/.

� JCE Unlimited Strength Jurisdiction Policy Files for the used JRE. These can be downloaded from the normal JRE/JDK download pages. For JDK1.5 see for example http://java.sun.com/javase/downloads/index_jdk5.jsp, near the bottom (‘Other Downloads’).

� Cryptography provider (e.g. BouncyCastle) if none is installed, see Install section below. Normally, Sun’s JRE/JDK provides a default cryptography provider.

For the .Net Security Service, following software components should be installed:

� Microsoft .Net Framework 3.0

Download: http://www.microsoft.com/downloads/details.aspx?FamilyID=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en

� Microsoft HomeFx Security

Download: https://gforge.inria.fr/frs/download.php/3176/component.zip

� Microsoft Management Console

Download: https://gforge.inria.fr/frs/download.php/3173/component.zip

A set of template files have been prepared in order to help you running the practical parts of this tutorial. It is recommended that you use these templates. A package that includes this template along with some other files can be downloaded from https://gforge.inria.fr/frs/?group_id=160. Note that all path names that are referred to in this document are relative to the folder the package has been extracted to. Note further, that there is a separate directory names “Code_Solution” which contains the complete programs.

2.1 Installation of the security Java environment Setup a default Amigo deployment environment without any export and binding factories. Install the ‘amigo_security’ bundle. Installation instructions for the policy files are provided in the download archive. How to install BouncyCastle is described under the following link: http://www.bouncycastle.org/wiki/display/JA1/Provider+Installation

The short form is:

1. Go to http://www.bouncycastle.org/latest_releases.html and download the release specific for the JVM version you have, e.g. bcprov-jdk15-136.jar

Page 7: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 6/54

2. Copy this file to <JDK_HOME>/jre/lib/ext - This folder contains the default global libraries for your JVM. If you have a separate JRE installed copy it there as well: <JRE_HOME>/lib/ext

Other than suggested in various installation instructions; DO NOT EDIT the file <JDK_HOME>/jre/lib/security/java.security.

2.1.1 Configure Since the implementation of the security framework is compatible with the storage directory structure of the .Net counterpart, a system property named ‘amigo-security-persisting-dir’ should be set up. This is preferably done in the ‘system.properties’ of the Oscar distribution, e.g.

amigo-security-persisting-dir=C:\\Documents and Settings\\%USER%\\Local Settings\\ApplicationData\\HomeFx\\Security\\

2.1.2 Compile Compile & build using either ‘build.xml’ (JRE >= 5.0) or ‘build-jre13.xml’. Note that in the build target ‘CompileWSDL’ a HTTP proxy is set which should be changed or removed according to the network configuration. The output files of the build process are stored in a directory which can be set in the ‘build.properties’ file under the property name ‘amigo.repository’. An Oscar repository file at the specified location will be automatically created or updated.

When the projects are checked out using Eclipse, there are some compile errors initially. This is due to the fact that some of the classes are generated from WSDL descriptions (e.g. the proxy of the EMIC security service). That is why, after building the projects (using one of the build files), they should be refreshed (select the corresponding project in the Eclipse workspace and press F5).

2.2 Installation of the .Net security environment Installing the needed .Net components is straight-forward. After the .Net Framework 3.0 has been installed, run the setup files from the two download packages. Note, that administrative privileges are needed in order to set up and run the EMIC security service and the EMIC management console.

After installation, the program menu ‘EMIC - Microsoft’ is created. From there, you can start the ‘Security Control Center’ and the ‘Device Registrar’ applications. In addition, the solution with the .Net version of the presented examples in this tutorial can be accessed under the menu entry ‘HomeFx Security.sln’.

The management console can be started from its installation folder, e.g. ‘C:\Program Files\EMIC - Microsoft\Management Console\Management Console Application’.

Page 8: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 7/54

3 Amigo security

3.1 Overview

3.1.1 Objectives The Amigo security framework is responsible of securing access to the services in the home. The Amigo security model is based on the Kerberos protocol, with shared secrets to establish mutual authentication. The security service is the mutually trusted Kerberos authority and acts as a trust broker between users and services inside the home and grants or denies access to services. The employed access control scheme in Amigo is role based with few, well-known user, device, and service roles, thus enabling non-technical users to setup a secure system easily. As usual with Kerberos, access is granted or denied centrally by the security service and is relayed to users and services with encrypted tickets.

3.1.2 Principles Accordingly, the implementation of Amigo security is split into two major components: the security service, which needs to be deployed in the home to enable secure use of services, and the security API that enables secure communication with the security service and between clients and services in the home. The security service as such is, from the service developer’s point of view, a fixed service that is only communicated with via the security API. Thus, the security service is irrelevant for the purposes of this document.

The security API is available both as a Java OSGi bundle and as a .Net library, and uses lower level middleware functionality like WS-Discovery.

Before we go into more details though, it will help to quickly recapitulate the principles of Kerberos [Kerberos]. In Kerberos, security and privacy are achieved via a mutually trusted authority that shares a secret – a key for a symmetric cipher like AES, Triple DES, or Blowfish – with each of the participants of the security scheme. Using some coarse simplification1, a typical exchange that enables secure and authorized of a client to a service has the following steps:

1. The client C requests a ticket granting ticket from the authority A; this request is sent unencrypted.

2. If the client is known, then A sends a ticket granting ticket TGT, which is encrypted with the secret KC, which is known only to C and A.

3. C decrypts the TGT with KC, which proves that it really came from A (because only A and C know KC).

4. C uses information from TGT to create a ticket request for the service S that it wants to use and sends it to A.

5. A checks that the ticket request has been sent from C. It determines if A has permission to use S.

6. A sends a ticket TS to C, which contains information that is encrypted with KS, the key that is shared between A and S.

7. C uses TS to prove to S that is has A’s authorization to access S. 8. S attempts to decrypt TS with KS, and if it does so successfully, grants access to C.

1 This simplification is here only for didactic purposes; the implementation does not use this simplification.

Page 9: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 8/54

In addition to this protocol, we need a way to initially establish the keys that are shared between the C (or S) and A. This is part of the registration procedure, which is covered in the subsequent sections.

In the remainder of this chapter, we will discuss how to use the .Net and Java version of the security API to implement and consume secure services. Note that .NET and Java implementation use the same object model so that the principles are the same for both domains.

3.1.3 Assessment The Amigo security libraries enable authenticated and authorized service use in the Amigo home, based on a simple, role-based, security concept. Using the API presented in this chapter, use of these mechanisms is significantly simplified, because the security protocol is abstracted into a comprehensive API that supports easy service and client implementation.

Page 10: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 9/54

3.2 How to develop a simple secure service for .NET: example 1 In the following, we will describe the necessary steps to develop a secure Amigo service. We do this by walking through the code sample that is installed as part of installing the Amigo security package. All relevant files for the .NET example are found in the directory tree starting at “Using Amigo Security Services\Code\DOT_NET\”. If you are using Visual Studio, then double-click on the Microsoft Visual Studio Solution project file “Using Amigo Security Services\Code\DOT_NET\HomeFx Security.sln” to load the entire sample environment into Visual Studio.

3.2.1 Service implementation As a first step, we are going to develop a secured service. This is done by adding secured methods to a web service. The appropriate templates are in “Using Amigo Security Services\Code\DOT_NET\Samples\Service”.

The following C# example shows the code that is necessary to implement a web service with secured methods. Hosting, registration, and persisting are handled in the next section. Detailed API documentation is available from the help files installed with the security package.

// ==++== // // // Copyright (c) 2006 Microsoft Corporation. Al l rights reserved. // // The use and distribution terms for this softw are are contained in the // file named license.txt, which can be found in the root of this // distribution. // By using this software in any fashion, you ar e agreeing to be bound by // the terms of this license. // // You must not remove this notice, or any other , from this software. // // // ==--== using System; using System.Web.Services; using EMIC.HomeFx.Security; using EMIC.WSDiscovery.Server;

These declarations import the necessary namespaces – note that we are also importing the EMIC.WSDiscovery.Server namespace, which contains the .Net implementation of WS-Discovery.

namespace SecuredServiceSample1 { [ Scope ( "urn:amigo-security-sample" )] [ Type ( "sample-service1" , "urn:amigo-security-sample1" )] public class Service : EMIC.HomeFx.Security. Service { The service implementations inherits from EMIC.HomeFx.Security.Service, which contains the necessary primitives to validate incoming requests. EMIC.HomeFx.Security.Service in turn inherits from EMIC.WSDiscovery.Server.Discoverable service, which enables automatic discovery of our service. The Type and Scope attribute specify the WS-Discovery type and scope for this service.

First, let us define the constructor of our Service. The C# code is:

Page 11: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 10/54

public Service(EMIC.HomeFx.Security. Service securedService) : base (securedService){}

The only means of creating an EMIC.HomeFx.Security.Service is by copying from another instance of that class. Such an instance can be created by either registering a service with the security authority or by deserializing a persisted instance. Both possibilities are discussed in the next section.

We now define our first secured method. As it is a web service, its declaration must be prepended with [WebMethod]:

[ WebMethod] public SecuredResult <string > Hello( SecuredRequest <string > request) {

A secure service has one of several web methods, which will be reachable once the service is hosted by the web server. In the current version, security has to be added explicitly to the service behaviour as shown in the example above. For this, the web method accepts one generic argument of type SecuredRequest<T0, T2, …, Tn>. The types T0,…,Tn are instantiated with the actual types of the unsecured version of the web method. Currently, up to five arguments are supported. Return type of the function is SecuredResult<T>, where T is the return type of the unsecured function.

return ValidateAndDispatchRequest< string , string >(request, Hello); }

Inside the secured function, the request is dispatched to the unsecured, private version of the secured function via the ValidateAndDispatchRequest<T, T0, …, Tn> member function of EMIC.HomeFx.Security.Service. Based on the result of the validation of the incoming secured request, this function will either decrypt the encrypted parameters, pass them to the unsecured function, and return the encrypted result, or – in case of an unsuccessful validation – will return an error result. In either case, the return value of this dispatched function can directly be passed to the invoker of the secure web method.

private string Hello( string name) { return String .Format( "Hello {0} ({1}@{2})!" , name, InvocationContext.User == null ? "<unknown>" : InvocationContext.User.ToString(), InvocationContext.Device); } } } The unsecured version of the function can assume that the caller has been successfully authenticated and authorized to use the service. If necessary, access to the authentication information, i.e., identity of the calling user and device, are available via the InvocationContex.User and InvocationContext.Device properties.

This finishes the code of our first simple secured service. For your convenience, the entire secure service example code in C# is given below:

using System; using System.Web.Services; using EMIC.HomeFx.Security; using EMIC.WSDiscovery.Server; namespace SecuredServiceSample1 { [ Scope ( "urn:amigo-security-sample" )]

Page 12: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 11/54

[ Type ( "sample-service1" , "urn:amigo-security-sample1" )] public class Service : EMIC.HomeFx.Security. Service { public Service(EMIC.HomeFx.Security. Service securedService) : base (securedService){} [ WebMethod] public SecuredResult <string > Hello( SecuredRequest <string > request) { return ValidateAndDispatchRequest< string , string >(request, Hello); } private string Hello( string name) { return String .Format( "Hello {0} ({1}@{2})!" , name, InvocationContext.User == null ? "<unknown>" : InvocationContext.User.ToString(), InvocationContext.Device); } } }

3.2.2 Registering and hosting a secured service Now that we created the code for our service, the next step is to actually create and host the service. In the following, we develop a small program that is capable of registering the secured service from the previous section with the security service (or retrieve a previous registration if it exists) and host the services with the Amigo .Net web server component.

Import of the required namespaces for hosting and communication with the security service (in EMIC.HomeFx.Security.Proxies) is done by the following C# code:

// ==++== // // // Copyright (c) 2006 Microsoft Corporation. Al l rights reserved. // // The use and distribution terms for this softw are are contained in the // file named license.txt, which can be found in the root of this // distribution. // By using this software in any fashion, you ar e agreeing to be bound by // the terms of this license. // // You must not remove this notice, or any other , from this software. // // // ==--== using System; using System.Xml.Serialization; using System.Xml; using System.Net; using EMIC.WebServer; using EMIC.HomeFx.Security; using EMIC.HomeFx.Security.Proxies; using EMIC.WSAddressing;

Page 13: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 12/54

The first step is to register the services using a password based approach:

namespace SecuredServiceSample1 { class Program { static int Main( string [] args) { EMIC.HomeFx.Security. Service securedService = null ; XmlSerializer xmlSerializer = new XmlSerializer ( typeof (EMIC.HomeFx.Security. Service )); string password = PronounceablePasswordGenerator .GeneratePassword(8); Console .WriteLine( "Attempting to register with password " + password); try { securedService = EMIC.HomeFx.Security. Service .RegisterNewService( "Amigo Security Sample Service" , System.Net. Dns.GetHostName(), password, ServiceRole .Unrestricted, RediscoveringSecurityServiceProxy .Instance); }

For this, we create a new password that is used to encrypt the registration process (and will need to be transferred out of band to the security service). Then, we call RegisterNewService with the registration information of this service. We specify its requested service role (which controls client authorization for this service at the security service) and again provide the singleton instance provided by the RediscoveringSecurityServiceProxy to enable communication with the security service.

catch ( RediscoveryException ) { Console .WriteLine( "Could not locate security service" ); return -1; } catch ( RegistrationException e) { Console .WriteLine( "Could not register with security" " service: " + e.Message); return -1; }

During this process, irrecoverable communication errors will lead to a RediscoveryException. A registration attempt that is rejected from the security service for some reason will lead to a Registration exception. In either case, the service has not been successfully registered and we terminate the program with an error code.

If the program has successfully executed up to here, then we have created an instance of EMIC.HomeFx.Security.Service.Service, which we can use to create and host an instance of the secured service from the previous section:

WebServer .Port = 0; WebServer .Start(); using ( Service service = new Service (securedService)) { WebServer .AddWebService(serviceLocation, service);

Page 14: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 13/54

Console .WriteLine( "Sample service running." + Environment .NewLine + "Press <return> to quit" ); Console .ReadLine(); } return 0; } } }

3.2.3 Complete server code This concludes our explanation of how to develop secured Amigo services. For convenience, the entire code is showed gain below:

// ==++== // // // Copyright (c) 2006 Microsoft Corporation. Al l rights reserved. // // The use and distribution terms for this softw are are contained in the // file named license.txt, which can be found in the root of this // distribution. // By using this software in any fashion, you ar e agreeing to be bound by // the terms of this license. // // You must not remove this notice, or any other , from this software. // // // ==--== using System; using System.Xml.Serialization; using System.Xml; using System.Net; using EMIC.WebServer; using EMIC.HomeFx.Security; using EMIC.HomeFx.Security.Proxies; using EMIC.WSAddressing; namespace SecuredServiceSample1 { class Program { static int Main( string [] args) { EMIC.HomeFx.Security. Service securedService = null ; XmlSerializer xmlSerializer = new XmlSerializer ( typeof (EMIC.HomeFx.Security. Service )); string password = PronounceablePasswordGenerator .GeneratePassword(8); Console .WriteLine( "Attempting to register with password " + password); try { securedService = EMIC.HomeFx.Security. Service .RegisterNewService( "Amigo Security Sample Service" , System.Net. Dns.GetHostName(), password,

Page 15: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 14/54

ServiceRole .Unrestricted, RediscoveringSecurityServiceProxy .Instance); } catch ( RediscoveryException ) { Console .WriteLine( "Could not locate security service" ); return -1; } catch ( RegistrationException e) { Console .WriteLine( "Could not register with security service: " + e.Message); return -1; } WebServer .Port = 0; WebServer .Start(); using ( Service service = new Service (securedService)) { WebServer .AddWebService(serviceLocation, service); Console .WriteLine( "Sample service running." + Environment .NewLine + "Press <return> to quit" ); Console .ReadLine(); } return 0; } } }

Page 16: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 15/54

3.3 How to develop a simple secure service for Java / OSGi: example 1 In the following, we will describe the necessary steps to develop a secure Amigo service in Java that is going to run as a OSGi bundle. We do this by walking through the code sample that is installed as part of installing the Amigo security package. All relevant files for the Java example are found in the directory tree starting at “Using Amigo Security Services\Code\Java\”.

3.3.1 Definition of the service class interface In order to define the service, we first have to provide an interface definition for it:

package de.ims.fraunhofer.amigo.tutorial.security.server;

public interface ISampleService {

String Hello(String parameter);

}

This definition should go to file “Using Amigo Security Services\Code\Java\tutorial_security_server\src\de\ims\fraunhofer\amigo\tutorial\security\server\ISampleService.java”.

3.3.2 Service implementation To improve readability and maintainability of the code, put the most important constants into a separate file. The file should be named “Using Amigo Security Services\Code\Java\tutorial_security_server\src\de\ims\fraunhofer\amigo\tutorial\security\server\Constants.java”. Within this package define two constant named SCOPE and SERVICE_TYPE as defined below:

package de.ims.fraunhofer.amigo.tutorial.security.server; public final class Constants { private Constants() { } public static final String SCOPE = "urn:amigo-security-sample"; public static final String SERVICE_TYPE = "urn:amigo-security-sample:sample-service"; }

Note that this class has a private constructor in order to prevent instantiation.

As a first step, we are going to develop a secured service. This is done by adding secured methods to a web service. The code for the service should go to “Using Amigo Security Services\Code\Java\tutorial_security_server\src\de\ims\fraunhofer\amigo\tutorial\security\server\SecuredAmigoService.java” if not stated different.

First, we need to define some packages that are needed by our service:

package de.ims.fraunhofer.amigo.tutorial.security.server; import org.apache.log4j.Logger; import org.ungoverned.gravity.servicebinder.Lifecycle; import com.francetelecom.amigo.core.AmigoException; import com.francetelecom.amigo.core.AmigoExportedService; import com.francetelecom.amigo.core.AmigoLdapLookup;

Page 17: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 16/54

import com.francetelecom.amigo.core.AmigoReference; import com.francetelecom.amigo.core.AmigoServiceExporter; import de.fraunhofer.ims.amigo.security.ISecurityIdentifier; import de.fraunhofer.ims.amigo.security.InvocationContext;

The actual class that will embed our new service is called SecuredAmigoService. It implement the interfaces Lifecyle and ISampleService defined above. Along with the class there are numerous members and methods defined which will be used in the code:

public class SecuredAmigoService implements Lifecycle, ISampleService { private AmigoServiceExporter m_serviceExporter = null; private AmigoExportedService m_myService = null; private AmigoLdapLookup m_lookup = null; public static final String SERVICE_OID = "SampleSecuredAmigoService"; private final Logger m_logger = Logger.getLogger(SecuredAmigoService.class); …

Additionally to the member, we define some methods that support life cycle management of the service. First, a method to register our service is defined. Note that this method is called automatically whenever a lookup server becomes available. Note further, that the name of the method is defined in the file metadata.xml. Within

public void bindLookupService(AmigoLdapLookup lookup) { this.m_lookup = lookup; if (m_myService != null) { try { registerService(); } catch (AmigoException ex) { throw new RuntimeException(ex); } } } …

Note that bindLookupService uses registerService which is defined below:

private void registerService() throws AmigoException { m_myService.addProperty("ServiceType", Constants.SERVICE_TYPE); m_myService.addProperty("Scope", Constants.SCOPE); m_lookup.registerService(m_myService); } …

In order to un-register the service a method unregisterService shall be defined. Similar the method unbindLookupService handles the case that the service is going to be shut down.

public void unregisterService() { try { m_lookup.unregisterService(m_myService); } catch (AmigoException e) { m_logger.error("Failed to unregister sample service", e);

Page 18: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 17/54

} } public void unbindLookupService(AmigoLdapLookup lookup) { if (m_lookup == lookup) { if (m_myService != null) { unregisterService(); } m_lookup = null; } } …

Similarly, we bind or unbind the service exporter:

public void bindServiceExporter(AmigoServiceExporter serviceExporter) { m_serviceExporter = serviceExporter; } public void unbindServiceExporter(AmigoServiceExporter serviceExporter) { if (m_serviceExporter == serviceExporter) { m_serviceExporter = null; } } …

The core stat-up code shall go the method activate. Note that this method is called by OSGi if the bundle is started. Note that the code is very similar to a none secure service. The major difference is only that exportSecureInterface is used instead of exportInterface (or exportMethods):

public void activate() { m_myService = m_serviceExporter.createService(this); m_myService.addProperty("oid", SERVICE_OID); try { try { m_myService.exportSecureInterface( AmigoReference.DEFAULT, ISampleService.class); m_logger.info("Exported SECURE service at address " + m_myService.getReference()); } catch (UnsupportedOperationException ex) { m_myService.exportInterface(AmigoReference.DEFAULT, ISampleService.class); m_logger.warn("No security enabled export factory " + "found --> exported UNSECURED “ + service at address " + m_myService.getReference()); } } catch (AmigoException e) { throw new RuntimeException(e); } if (m_lookup != null) { try {

Page 19: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 18/54

registerService(); } catch (AmigoException ex) { throw new RuntimeException(ex); } } }

In order to shutdown the service, OSGi will call deactivate. To this end, the service is unregistered first, then it is unexported:

public void deactivate() { if (m_myService != null) { if (m_lookup != null) { unregisterService(); } try { m_myService.unexport(); } catch (AmigoException ex) { m_logger.debug("Error occurred while " + unexporting service", ex); } } m_logger.debug("Component is being deactivated!"); }

Finally, we need to define the actual exported method Hello. The code below returns the string that has been passed over as a parameter and prints some information to the log screen. Note that most of the methods code is to obtain information about the device and the user that have been issuing the service call.

public String Hello(String request) { try { final ISecurityIdentifier device = InvocationContext.getDevice(); if (device == null) { throw new NullPointerException( "Invocation done from unknown device"); } final ISecurityIdentifier user = InvocationContext.getUser(); m_logger.info("Invocation from: device = " + device + "; user = " + user); return "Hello " + request + " (" + (user == null ? "unknown" : user.toString()) + "@" + device + ")!"; } catch (RuntimeException ex) { m_logger.error(ex); throw ex; } }

3.3.3 Complete server code For convenience, the entire code is showed gain below:

package de.ims.fraunhofer.amigo.tutorial.security.server;

Page 20: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 19/54

import org.apache.log4j.Logger; import org.ungoverned.gravity.servicebinder.Lifecycle; import com.francetelecom.amigo.core.AmigoException; import com.francetelecom.amigo.core.AmigoExportedService; import com.francetelecom.amigo.core.AmigoLdapLookup; import com.francetelecom.amigo.core.AmigoReference; import com.francetelecom.amigo.core.AmigoServiceExporter; import de.fraunhofer.ims.amigo.security.ISecurityIdentifier; import de.fraunhofer.ims.amigo.security.InvocationContext; public class SecuredAmigoService implements Lifecycle, ISampleService { private AmigoServiceExporter m_serviceExporter = null; private AmigoExportedService m_myService = null; private AmigoLdapLookup m_lookup = null; public static final String SERVICE_OID = "SampleSecuredAmigoService"; private final Logger m_logger = Logger.getLogger(SecuredAmigoService.class); public void bindLookupService(AmigoLdapLookup lookup) { this.m_lookup = lookup; if (m_myService != null) { try { registerService(); } catch (AmigoException ex) { throw new RuntimeException(ex); } } } private void registerService() throws AmigoException { m_myService.addProperty("ServiceType", Constants.SERVICE_TYPE); m_myService.addProperty("Scope", Constants.SCOPE); m_lookup.registerService(m_myService); } public void unregisterService() { try { m_lookup.unregisterService(m_myService); } catch (AmigoException e) { m_logger.error("Failed to unregister sample service", e); } } public void unbindLookupService(AmigoLdapLookup lookup) { if (m_lookup == lookup) { if (m_myService != null) { unregisterService(); } m_lookup = null; }

Page 21: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 20/54

} public void bindServiceExporter(AmigoServiceExporter serviceExporter) { m_serviceExporter = serviceExporter; } public void unbindServiceExporter(AmigoServiceExporter serviceExporter) { if (m_serviceExporter == serviceExporter) { m_serviceExporter = null; } } public void activate() { m_myService = m_serviceExporter.createService(this); m_myService.addProperty("oid", SERVICE_OID); try { try { m_myService.exportSecureInterface( AmigoReference.DEFAULT, ISampleService.class); m_logger.info("Exported SECURE service at address " + m_myService.getReference()); } catch (UnsupportedOperationException ex) { m_myService.exportInterface(AmigoReference.DEFAULT, ISampleService.class); m_logger.warn("No security enabled export factory " + "found --> exported UNSECURED “ + service at address " + m_myService.getReference()); } } catch (AmigoException e) { throw new RuntimeException(e); } if (m_lookup != null) { try { registerService(); } catch (AmigoException ex) { throw new RuntimeException(ex); } } } public void deactivate() { if (m_myService != null) { if (m_lookup != null) { unregisterService(); } try { m_myService.unexport(); } catch (AmigoException ex) { m_logger.debug("Error occurred while " + unexporting service", ex); } } m_logger.debug("Component is being deactivated!"); }

Page 22: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 21/54

public String Hello(String request) { try { final ISecurityIdentifier device = InvocationContext.getDevice(); if (device == null) { throw new NullPointerException( "Invocation done from unknown device"); } final ISecurityIdentifier user = InvocationContext.getUser(); m_logger.info("Invocation from: device = " + device + "; user = " + user); return "Hello " + request + " (" + (user == null ? "unknown" : user.toString()) + "@" + device + ")!"; } catch (RuntimeException ex) { m_logger.error(ex); throw ex; } } }

3.3.4 Service bundle metadata In order to run this software as an OSGi bundle, a data structure is needed that describes some dependencies of the software:

<?xml version="1.0" encoding="UTF-8" ?> <bundle> <component

class="de.ims.fraunhofer.amigo.tutorial.security.server.SecuredAmigoService">

<requires service="com.francetelecom.amigo.core.AmigoServiceExporter"

filter="" cardinality="1..n" policy="dynamic"

bind-method="bindServiceExporter" unbind-method="unbindServiceExporter

/>

<requires service="com.francetelecom.amigo.core.AmigoLdapLookup"

filter="" cardinality="0..n" policy="dynamic"

bind-method="bindLookupService"

unbind-method="unbindLookupService" />

</component>

</bundle>

Note that this data structure states that there are two other services required in order to run our Web Service. The first is the AmigoServiceExporter, the other is AmigoLdapLookup. Further, the metadata also defines which routines shall be called in case of one of these services becomes available or unavailable.

The XML data is stored in “Using Amigo Security Services\Code\Java\tutorial_ security_server\res\metadata.xml”.

3.3.5 Service bundle manifest Each OSGi bundle requires a “manifest”. This a plain text file that stores some general information about the bundle. For example, it also includes the name of the metadata file:

Manifest-Version: 1.0

Page 23: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 22/54

Bundle-Description: Tutorial server bundle for Amig o security Bundle-Name: tutorial_amigo_security_server Bundle-Activator: de.ims.fraunhofer.amigo.tutorial.security.server.Bu ndleActivator Created-By: Fraunhofer IMS Bundle-Vendor: Fraunhofer IMS Import-Package: com.francetelecom.amigo.core, com.francetelecom.amigo.core.util, org.ungoverned.gravity.servicebinder, org.apache.log4j, de.fraunhofer.ims.amigo.security Bundle-Copyright: GNU Lesser General Public License Metadata-location: res/metadata.xml

This manifest (named manifest.mf) is stored in the same directory as the metadata file.

3.3.6 Service activator To start or service as a OSGi bundle an activator class is needed. This class will be used by OSGi to start the service. Here it is located in “Using Amigo Security Services\Code\Java\tutorial_security_server\src\de\ims\fraunhofer\amigo\tutorial\security\server\BundleActivator.java”.

package de.ims.fraunhofer.amigo.tutorial.security.server; import org.apache.log4j.Logger; import org.osgi.framework.BundleContext; import org.ungoverned.gravity.servicebinder.GenericActivator; public class AmigoCoreActivator extends GenericActivator { private final Logger m_logger = Logger.getLogger(AmigoCoreActivator.class); public void start(BundleContext context) throws Exception { super.start(context); m_logger.info("Server started."); } public void stop(BundleContext context) throws Exception { super.stop(context); m_logger.info("Server stopped."); } }

3.3.7 Registering the service with the security service In order to be able to register the new service with the security service, it is required that the security services trusts the new service. This is done by executing the following program:

package de.ims.fraunhofer.amigo.tutorial.security.server; import java.util.Properties; import com.microsoft.emic.homefx.security.ServiceRole; import de.fraunhofer.ims.amigo.security.discovery.StaticLocator; import de.fraunhofer.ims.amigo.security.internal.Constants; import de.fraunhofer.ims.amigo.security.service.SecuredService; import de.fraunhofer.ims.amigo.security.service.ServiceHelper; import de.fraunhofer.ims.amigo.security.utils.PronounceablePasswordGenerator; import de.ims.fraunhofer.amigo.tutorial.security.server.SecuredAmigoService; public class RegisterSecuredService {

Page 24: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 23/54

public static void main(String[] args) { final String homeId = "7f9d1019-f738-4e21-8c73-0c9c0aaab78b"; // 1. Optionally set the url of the preferred security service final Properties properties = System.getProperties(); properties.setProperty( StaticLocator.SECURITY_SERVICE_URL_PROP_KEY, "http://localhost:4380/"); properties.setProperty( Constants.PERSISTING_DIR_SYSTEM_PROPERTY, "C:\\Dokumente und Einstellungen\\dimitrov" + "\\Lokale Einstellungen\\Anwendungsdaten\\HomeFx\\Security"); // 2. Register service final ServiceHelper serviceHelper = new ServiceHelper(); final String password = PronounceablePasswordGenerator .generatePassword(8); System.out.println("Trying to retrieve or register'" + SecuredAmigoService.SERVICE_OID + "' service --> password = " + password); final SecuredService securedService = serviceHelper .retrieveOrRegisterService( SecuredAmigoService.SERVICE_OID, "Sample secured service", ServiceRole.Unrestricted, password, homeId); System.out.println("Service '" + SecuredAmigoService.SERVICE_OID + "' is registered :: sid = " + securedService.getSid()); } }

Note that the program source can be found in \Using Amigo Security Services\Code\Java\tutorial_security_server\src\de\ims\fraunhofer\amigo\tutorial\security\server\utils\RegisterSecuredService.java. Remember to set up the value of the system property ‘Constants.PERSISTING_DIR_SYSTEM_PROPERTY’.

Page 25: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 24/54

3.4 Security Control Center In order to be able to use security within the Amigo powered home, a secured home environment must be created. All devices and all service have to register to this secured home in order to join the secured domain. The secured home is under control of the “Security Control Center” which is in fact a service that must be running somewhere in the home network. This Security Control Center provides a interface for the administrator of the home network to control all security related features. For example, it allows adding or removing users, devices and services.

Note that all the steps that are described in the following may also be performed via the API of the security framework.

3.4.1 Starting the Security Control Center To start the control center just execute Start -> All Programs -> EMIC Microsoft -> HomeFx Security->Security Control Center. Make sure not to close the application as it is needed by the secure services and clients in order to operate properly. During the start up of the control center, a window is shown, which displays the available network interfaces. The EMIC security web service will be bound to the selected interface. If the list of available interfaces is empty, please refer to the troubleshooting section of this document.

If the tool is started for the first time, a wizard will pop up in order to guide you through the process of creating a new home environment.

The configuration interface will allow you to add a new secured home. Just activate the “Start a new home” button and then press “OK”.

Page 26: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 25/54

Pressing “OK” will bring up another window where the new home environment can be specified. Please proceed with the setup process by providing appropriate information to the system. Note that the “Home Name” is a unique name that defines the home while the “Instance Name” is the name of the currently running Security Control Center. Note that within the home network there may be several security centers which all belong to the same home environment (of course you may also set up and run several home environments within a home network).

During the “Home creation” process, several registrations will be automatically done. The first one is the device registration for the instance (PC) on which the EMIC security service is running (in the given example AV82). The second one is the user registration for the administrator of the system. Note that the administrator account is later used for managing the deployed security service(s) in the home (see next section).

Page 27: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 26/54

After pressing “Finish”, the control center will create the new home and will start the EMIC HomeFx security service. The next step is to start the management console. Remember that, in order to run the management console, administrative privileges are required. The management console will automatically try to discover any deployed security services. If it finds one, it will log into it and retrieve the information about the available device and user registrations. To do so, please provide the login credentials of the administrative user, which was created in the previous step.

After successful login, all registrations are listed in the ‘Users view’.

Registration for device AV82

Registration for admin user John

Page 28: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 27/54

3.4.2 Register a new user Registering a new user in the system is accomplished by double clicking the ‘Add user’ button. A new window appears on the screen. Type an appropriate user name and password and select the most appropriate user class as well as an expiration date.

After successful registration a new entry will show up in the “Users view” of the management console.

3.4.3 Register a new device All devices that host a secured service or access a secured service within the home network should be registered with the EMIC security service. To start the device registration process,

Newly created registration for user Maria

Page 29: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 28/54

run “Start -> Programs -> EMIC Microsoft -> HomeFx Security -> Device Registrar” on the device that has to be registered. This will bring up the registration tool. Note that in order to run the Device Registrar on the target device, it is required to install it on that device. However, another option is to use the security API (available both in Java & .Net) in order to do the registration. In this case, the Device Registrar application does not have to be installed on the target machine.

Next, click on one of the discovered EMIC security services and then press the “Register” button. This will bring up a new window in order to collect some information about the new device. Choose an appropriate name and device class. For convenience reasons mark “Make this my default home”. As a result, the device will always automatically trying to connect the selected Security Service instead of looking up all possible services. Then press “Register” to continue with the registration process.

Page 30: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 29/54

Once the “Register” button has been pressed, the device connects the chosen Security Control Center and asks it to complete the registration. To make sure that this process is not intercepted by somebody on the network, the new device generates a random one time PIN that is displayed on the screen of the device. Write down this PIN as it is needed to complete the registration request.

Page 31: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 30/54

On the machine that is hosting the corresponding Security Control Center, the administrator is informed about the request and now has the option to accept or decline the registration request. In order to accept it, the PIN generated in the previous step must be entered in the appropriate field. As the PIN is not transmitted over the network, the administrator can be sure that the correct device is actually asking for registration and no other device is pretending to be “John’s Mobile Phone”.

Page 32: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 31/54

If registration is successfully, the “Registrar” window should look like:

3.4.4 Register a new service Now we are ready to register the new service that has been developed in the previous steps of the tutorial. To this end, execute the service. As has been shown in the service code, the service will try to connect to the Security Control Center in order to register with it. If this has been done in an previous step and appropriate registration information has been stored on the disk, re-connection is done in the background without any user interaction.

Otherwise, if the service connects to the center for the first time or the registration information has not be stored during a previous registration procedure, the following window will pop on site that is running the Security Control Center:

Page 33: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 32/54

Note that the PIN that is to be entered by the administrator into this form has been selected by the service. Typically, it should use a random generated on-time-string for this.

After the request has been accepted by the administrator, the service is connected to the security domain and is ready to be used.

Page 34: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 33/54

3.5 How to develop a secure service client for .NET: example 1 In a similar manner, we will now explore the steps necessary to access a secured Amigo client. All relevant files for the .NET example are found in the directory tree starting at “Using Amigo Security Services\Code\DOT_NET\Samples\Client”. If you are using Visual Studio, then double-click on the Microsoft Visual Studio Solution project file “Using Amigo Security Services\Code\DOT_NET\HomeFx Security.sln” to load the entire sample environment into Visual Studio.

// ==++== // // // Copyright (c) 2006 Microsoft Corporation. Al l rights reserved. // // The use and distribution terms for this softw are are contained in the // file named license.txt, which can be found in the root of this // distribution. // By using this software in any fashion, you ar e agreeing to be bound by // the terms of this license. // // You must not remove this notice, or any other , from this software. // // // ==--== using System; using System.Net; using System.Threading; using EMIC.HomeFx.Security; using EMIC.HomeFx.Security.Proxies; using EMIC.WSDiscovery; using EMIC.WSDiscovery.Client;

Import of the necessary namespaces for Amigo security.

Now we create the actual client program:

namespace SecuredClientSample { class Program { static int Main( string [] args) { if (! Device .IsRegistered()) { Console .Error.WriteLine( "The device has not been registered." ); return -1; }

Instead of an explicit registration step, we assume that registration of the device and user of this client program has been performed separately. The Amigo security package contains an application that serves exactly that purpose. If the device has not previously been registered, access to secured Amigo services is not possible and we exit with an error code.

Device thisDevice = Device . ThisDevice( RediscoveringSecurityServiceProxy .Instance); Authentication authentication = thisDevice.AuthenticateDevice();

Page 35: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 34/54

In the next step, we create an object represention of this device and authenticate it with the security service that is reachable via the singleton instance of RediscoveringSecurityServiceProxy. This will obtain the ticket grating ticket from the security service and store it locally on the device. If other clients on this have recently obtained such a ticket, it will be reused until it expires.

using ( ProbeClient probeClient = new ProbeClient ()) { probeClient.AddServiceScope( new ServiceScope ( new Uri ( "urn:amigo-security-sample" ))); probeClient.AddServiceType( new ServiceType ( "sample-service" , "urn:amigo-security-sample" )); while (probeClient.ProbeMatches == null || probeClient.ProbeMatches.Count == 0) { Console .WriteLine( "Probing for service..." ); probeClient.SendProbe(); Thread .Sleep(2000); }

We probe for the service that we want to use until we find one, using the WS-Discovery implementation.

ServiceInfo match = probeClient.ProbeMatches[0]; Sid sid = Sid .GetSidFromServiceInfo(match);

We retrieve the unique name under which this service is known to the security service. This name is included into the meta data transmitted in the ProbeMatch message from the service.

EMIC.HomeFx.Security. Authorization authorization = thisDevice.Authorize(sid, authe ntication, new TimeSpan (1, 0, 0)); SessionCredentials credentials = authorization.NewSessionCredentials();

We try to obtain a ticket for the service, with a validity period of at least one hour. Then we use this ticket to create the necessary credentials to start a new session with the service.

using ( ServiceProxy proxy = new ServiceProxy ()) { proxy.Proxy = new WebProxy (); proxy.Url = match.FirstXaddr.Ab soluteUri;

We prepare a proxy to contact the service, using the address from its ProbeMatch reply.

string response = thisDevice.InvokeSecuredServic e<string , string >( credentials, proxy.Hello, "Amigo Security Client" );

Finally, we use the InvokeSecuredService<T, T0,…Tn> method of the Device class to issue a secured call to the service. As parameters, this method takes the credentials that have been created in the previous step, a delegate to the method that is responsible to send the secured request to the service, and the service call’s arguments of type T0, …, Tn.

Page 36: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 35/54

Console .WriteLine( "Response = \"" + response + "\"" ); Console .ReadLine(); } } return 0; } } }

3.5.1 Complete client code For your convenience, the complete C# code for the client is shown below:

// ==++== // // // Copyright (c) 2006 Microsoft Corporation. All r ights reserved. // // The use and distribution terms for this software are contained in the // file named license.txt, which can be found in th e root of // this distribution. // By using this software in any fashion, you are a greeing to be bound // by the terms of this license. // // You must not remove this notice, or any other, f rom this software. // // // ==--== using System; using System.Net; using System.Threading; using EMIC.HomeFx.Security; using EMIC.HomeFx.Security.Proxies; using EMIC.WSDiscovery; using EMIC.WSDiscovery.Client; namespace SecuredClientSample { class Program { static int Main( string [] args) { if (! Device .IsRegistered()) { Console .Error.WriteLine( "The device has not been registered." ); return -1; } Device thisDevice = Device .ThisDevice( RediscoveringSecurityServiceProxy .Instance); Authentication authentication = thisDevice.AuthenticateDevice(); using ( ProbeClient probeClient = new ProbeClient ()) { probeClient.AddServiceScope( new ServiceScope ( new Uri ( "urn:amigo-security-sample" ))); probeClient.AddServiceType( new ServiceType ( "sample-service1" , "urn:amigo-security-sample1" ));

Page 37: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 36/54

while (probeClient.ProbeMatches == null || probeClient.ProbeMatches.Count == 0) { Console .WriteLine( "Probing for service..." ); probeClient.SendProbe(); Thread .Sleep(2000); } ServiceInfo match = probeClient.ProbeMatches[0]; Sid sid = Sid .GetSidFromServiceInfo(match); EMIC.HomeFx.Security. Authorization authorization = thisDevice.Authorize(sid, authe ntication, new TimeSpan (1, 0, 0)); SessionCredentials credentials = authorization.NewSessionCredentials(); using ( ServiceProxy proxy = new ServiceProxy ()) { proxy.Proxy = new WebProxy (); proxy.Url = match.FirstXaddr.Ab soluteUri; string response = thisDevice.InvokeSecuredService< string , string >( credentials, proxy.Hello, "Amigo Security Client" );

Console .WriteLine( "Response = \"" + response + "\"" ); Console .ReadLine(); } } return 0; } } }

Page 38: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 37/54

3.6 How to develop a secure service client for Java / OSGi: example 1 In a similar manner, we will now explore the steps necessary to access a secured Amigo client. First of all, we need the appropriate package and header definitions:

package de.ims.fraunhofer.amigo.tutorial.security.client; import java.rmi.RemoteException; import org.apache.log4j.Logger; import org.ungoverned.gravity.servicebinder.Lifecycle; import com.francetelecom.amigo.core.AmigoException; import com.francetelecom.amigo.core.AmigoLdapLookup; import com.francetelecom.amigo.core.AmigoService; import com.francetelecom.amigo.core.GenericStub; import de.fraunhofer.ims.amigo.security.UserAuthentication; import de.fraunhofer.ims.amigo.security.UserCredentials; import de.ims.fraunhofer.amigo.tutorial.security.client.gen.UnsecuredAmigoService; …

Note that we need imports for both, authentication as well as credentials.

The actual code for the client is stored in class AmigoServiceTester. This class ,ust implement the Lifecycle interface. Further, it needs to provide methods activate and deactivate in order to run it as an OSGi bundle. Note that the purpose of the activate method is to start the actual tests. Finally, some additional service methods handle events like discovery of a lookup service.

public class AmigoServiceTester implements Lifecycle { private final Logger m_logger = Logger.getLogger(AmigoServiceTester.class); private AmigoLdapLookup m_lookup = null; public void activate() { try { doTests(); } catch (Exception ex) { m_logger.debug("Exception occurred while doing tests", ex); } } public void deactivate() { } public void bindLookupService(AmigoLdapLookup lookup) { this.m_lookup = lookup; } public void unbindLookupService(AmigoLdapLookup lookup) { if (m_lookup == lookup) { m_lookup = null; } }

Page 39: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 38/54

The actual code to run the tests is embedded in method doTests. Note that the actual call to the service is done in runTests and runTestsGenericStub. As a first step in doTests, the actual service is looked up:

private void doTests() throws Exception { final AmigoService[] amigoServices = m_lookup.lookup(Constants.SCOPE, Constants.SERVICE_TYPE, 3); if (amigoServices == null || amigoServices.length == 0) { m_logger.info("Sample amigo service is not available!"); return; } …

Next, iterate over the matching service and call the remote method on each of them. To call the remote method there are in fact two possible ways. First, a generic stub may be used. It uses Java reflection in order to explore the interface of the remote service to call. Note that this puts some limits to the type of parameters that can be used for the remote call. Another solution is to derive a specific stub which in fact has the same interface as the remote method.

for (int i = 0; i < amigoServices.length; i++) { final AmigoService service = amigoServices[i]; final UnsecuredAmigoService specificStub; try { specificStub = (UnsecuredAmigoService) service . getSpecificStub(UnsecuredAmigoService.class); m_logger.info("Obtained specific stub '" + specificStub + "' for service '" + service.getReference()); } catch (Exception ex) { m_logger.debug( "Error occurred while trying to obtain" + "stub for service '" + service.getReference() + "' :: message = " + ex.getMessage(), ex); continue; } …

If the service is secured, then provide user credentials in order to authenticate the client against the service. Here, we authenticate by proving a user name (ressel) and a password (123456):

if (service.isSecure()) { // TODO set user name if applicable UserAuthentication.setUser( new UserCredentials("ressel", "123456")); m_logger.debug("Running tests on secured service!"); } …

Page 40: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 39/54

Note that in this example the user “ressel” has to be registered with the EMIC Security Service using the ‘Security Control Center’. Finally, call runTests and runTestsGenericStub which actually do the remote calls:

runTests(specificStub); runTestsGenericStub(service.getGenericStub()); } } …

Below the code is shown to use a generic stub in order to call the remote serice method. Note that the method takes the genericStub as a parameter. This stub has been generated by calling service.getGenericStub. Note that the actual call is done via the invoke method. Further, the parameters of the call must be packed into an object array:

private void runTestsGenericStub(GenericStub genericStub) { try { m_logger.info("[GenericStub] 'Hello' :: " + genericStub.invoke("Hello", new String[] { "hello" }, new Object[] { "Amigo Security Client" }, String.class.getName())); } catch (AmigoException ex) { m_logger.error("[GenericStub] 'Hello' failed!", ex); } }

Note that the actual remote call is somehow cumbersome. A more “natural” way of performing the remote call is to use the service specific stub.

Calling the remote method now looks like calling a local method:

private void runTests(UnsecuredAmigoService serviceStub) { try { m_logger.info("Hello :: " + serviceStub.hello("Amigo Security Client")); } catch (RemoteException ex) { m_logger.error("'Hello' failed!", ex); } }

3.6.1 Complete client code For your convenience, the complete Java code for the client is shown below:

package de.ims.fraunhofer.amigo.tutorial.security.client; import java.rmi.RemoteException; import org.apache.log4j.Logger; import org.ungoverned.gravity.servicebinder.Lifecycle; import com.francetelecom.amigo.core.AmigoException; import com.francetelecom.amigo.core.AmigoLdapLookup; import com.francetelecom.amigo.core.AmigoService; import com.francetelecom.amigo.core.GenericStub; import de.fraunhofer.ims.amigo.security.UserAuthentication; import de.fraunhofer.ims.amigo.security.UserCredentials;

Page 41: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 40/54

import de.ims.fraunhofer.amigo.tutorial.security.client.gen.UnsecuredAmigoService; public class AmigoServiceTester implements Lifecycle { private final Logger m_logger = Logger.getLogger(AmigoServiceTester.class); private AmigoLdapLookup m_lookup = null; public void activate() { try { doTests(); } catch (Exception ex) { m_logger.debug("Exception occurred while doing tests", ex); } } public void deactivate() { } public void bindLookupService(AmigoLdapLookup lookup) { this.m_lookup = lookup; } public void unbindLookupService(AmigoLdapLookup lookup) { if (m_lookup == lookup) { m_lookup = null; } } private void doTests() throws Exception { final AmigoService[] amigoServices = m_lookup.lookup(Constants.SCOPE, Constants.SERVICE_TYPE, 3); if (amigoServices == null || amigoServices.length == 0) { m_logger.info("Sample amigo service is not available!"); return; } for (int i = 0; i < amigoServices.length; i++) { final AmigoService service = amigoServices[i]; final UnsecuredAmigoService specificStub; try { specificStub = (UnsecuredAmigoService) service . getSpecificStub(UnsecuredAmigoService.class); m_logger.info("Obtained specific stub '" + specificStub + "' for service '" + service.getReference()); } catch (Exception ex) { m_logger.debug( "Error occurred while trying to obtain" + "stub for service '" + service.getReference() + "' :: message = " + ex.getMessage(), ex); continue; }

Page 42: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 41/54

if (service.isSecure()) { // TODO set user name if applicable UserAuthentication.setUser( new UserCredentials("ressel", "123456")); m_logger.debug("Running tests on secured service!"); } runTests(specificStub); runTestsGenericStub(service.getGenericStub()); } } private void runTestsGenericStub(GenericStub genericStub) { try { m_logger.info("[GenericStub] 'Hello' :: " + genericStub.invoke("Hello", new String[] { "hello" }, new Object[] { "Amigo Security Client" }, String.class.getName())); } catch (AmigoException ex) { m_logger.error("[GenericStub] 'Hello' failed!", ex); } } private void runTests(UnsecuredAmigoService serviceStub) { try { m_logger.info("Hello :: " + serviceStub.hello("Amigo Security Client")); } catch (RemoteException ex) { m_logger.error("'Hello' failed!", ex); } } }

3.6.2 Cliebt bundle metadata In order to run this software as an OSGi bundle, a data structure is needed that describes some dependencies of the software:

<?xml version="1.0" encoding="UTF-8" ?> <bundle> <component

class=

"de.ims.fraunhofer.amigo.tutorial.security.client.AmigoServiceTester"> <requires service="com.francetelecom.amigo.core.AmigoLdapLookup"

filter="" cardinality="0..n" policy="dynamic"

bind-method="bindLookupService"

unbind-method="unbindLookupService" /> </component> </bundle> Note that this data structure states that there are another services required in order to run our Web client: AmigoLdapLookup. Further, the metadata also defines which routines shall be called if the lookup service becomes available or unavailable.

The XML data is stored in “Using Amigo Security Services\Code\Java\tutorial_security_client\res\metadata.xml”.

Page 43: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 42/54

3.6.3 Client bundle manifest Each OSGi bundle requires a “manifest”. This a plain text file that stores some general information about the bundle. For example, it also includes the name of the metadata file:

Manifest-Version: 1.0 Bundle-Description: Test client bundle for Amigo se curity Bundle-Name: tutorial_amigo_security_client Bundle-Activator: de.ims.fraunhofer.amigo.tutorial.security.client.Bu ndleActivator Created-By: Fraunhofer IMS Bundle-Vendor: Fraunhofer IMS Import-Package: de.fraunhofer.ims.amigo.security, com.francetelecom.amigo.core, com.francetelecom.amigo.core.util, org.ungoverned.gravity.servicebinder, org.apache.log4j, javax.xml.rpc.handler.soap, javax.xml.rpc.handler, javax.xml.rpc.holders, javax.xml.rpc.encoding, javax.xml.namespace, javax.xml.rpc, javax.xml.soap, javax.wsdl, javax.wsdl.extensions, javax.wsdl.factory, javax.wsdl.xml, org.apache.axis.client, org.apache.axis, org.apache.axis.message, org.apache.axis.description, org.apache.axis.constants, org.apache.axis.encoding.ser, org.apache.axis.encoding, org.apache.axis.soap, org.apache.axis.wsdl, org.apache.axis.types, org.apache.axis.transport, org.apache.axis.enum, org.apache.axis.utils Bundle-Copyright: GNU Lesser General Public License Metadata-location: res/metadata.xml

This manifest (named manifest.mf) is stored in the same directory as the metadata file.

3.6.4 Service activator To start or service as a OSGi bundle an activator class is needed. This class will be used by OSGi to start the service. Here it is located in “Using Amigo Security Services\Code\Java\tutorial_security_client\src\de\ims\fraunhofer\amigo\tutorial\security\client\BundleActivator.java”.

package de.ims.fraunhofer.amigo.tutorial.security.client; import org.apache.log4j.Logger; import org.osgi.framework.BundleContext; import org.ungoverned.gravity.servicebinder.GenericActivator; public class BundleActivator extends GenericActivator {

Page 44: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 43/54

private final Logger m_logger = Logger.getLogger(BundleActivator.class); public void start(BundleContext bundleContext) throws Exception { super.start(bundleContext); m_logger.debug("Amigo security client bundle started!"); } public void stop(BundleContext bundleContext) throws Exception { m_logger.debug("Amigo security client bundle stopped!"); super.stop(bundleContext); } }

Page 45: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 44/54

3.7 How to develop a simple secure service for .NET: example 2 Now that we have dome a step by step walkthrough we will try to develop a more complex example. The new service to be designed shall take two integers as a parameter and returns the sum. The name of the service class is now AdderService and the Web method that shall be called in a secure manner is named add. Again, we start with designing the service.

3.7.1 Service implementation In order to reduce the typing effort, take the sample service created in the previous example as a reference. Create a new file and copy the server code from the first example into it. Then, rename the namespace of the new service to SecuredSericeSample2. Further, change type of the service to “sample-service2” and “urn:amigo-security-sample2”. As a result, the appropriate section of the C# code will look like:

namespace SecuredServiceSample2 { [ Scope ( "urn:amigo-security-sample" )] [ Type ( "sample-service2" , "urn:amigo-security-sample2" )] public class Service : EMIC.HomeFx.Security. Service { … The next step is to modify the web method that is going to be secured. The method now takes two integer parameters as a parameter and returns a int value:

[ WebMethod] public SecuredResult <int > add( SecuredRequest <int,int > request) {

Note that SecuredRequest now has two template parameters, both of type int.

Similar, the body of the we method must be modified to match the new method signature:

return ValidateAndDispatchRequest< int , int, int >(request, add); }

Please note that the first template paremeter is the return type, while the other parameters denote the type of the web service arguments.

The actual

private int add( int a, int b ) { return a + b; } } } The unsecured version of the function can assume that the caller has been successfully authenticated and authorized to use the service. If necessary, access to the authentication information, i.e., identity of the calling user and device, are available via the InvocationContex.User and InvocationContext.Device properties.

This finishes the code of our second simple secured service. For your convenience, the entire secure service example code in C# is given below:

using System; using System.Web.Services;

Page 46: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 45/54

using EMIC.HomeFx.Security; using EMIC.WSDiscovery.Server; namespace SecuredServiceSample2 { [ Scope ( "urn:amigo-security-sample" )] [ Type ( "sample-service2" , "urn:amigo-security-sample2" )] public class AdderService : EMIC.HomeFx.Security. Service { public AdderService(EMIC.HomeFx.Security. Service securedService) : base (securedService){} [ WebMethod] public SecuredResult <int> Hello( SecuredRequest <int, int > request) { return ValidateAndDispatchRequest< int, int, int >(request, add); } private int add( int a, int b ) { return a + b; } } }

3.7.2 Registering and hosting a secured service Similar to the first example, registration and hosting the service is :

In order to run a real service, it is useful not to register the servicec from scratch each time it is started. Instead, it is useful to store the registration information. For this example, we store it in the user path for this application. Of course, other choices are possible.

namespace SecuredServiceSample2 { class Program { static readonly string registrationFileLocation = System.Windows.Forms. Application .LocalUserAppDataPath + @"\registration.xml" ;

Care should be taken to secure the stored information because it enables and attacker to impersonate the service.

The first step is to try to recreate the service form the data stored at the user path.

static int Main( string [] args) { EMIC.HomeFx.Security. Service securedService = null ; XmlSerializer xmlSerializer = new XmlSerializer ( typeof (EMIC.HomeFx.Security. Service )); try { using ( XmlReader xmlReader = XmlReader .Create(registrationFileLocation)) { securedService = (EMIC.HomeFx.S ecurity. Service ) xmlSerializer.Deserialize(xmlReader); securedService.SecurityServiceP roxy = RediscoveringSecurityServiceProxy .Instance; } }

Page 47: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 46/54

If possible, we retry to recreate a EMIC.HomeFx.Security.Service.Service from information stored at the designated location. If this succeeds, we set the SecurityServiceProxy field of the service to the singleton instance provided by the RediscoveringSecurityServiceProxy, which supports automatic finding of the security service and automatic fail-over to alternative security services in case of communication failures. In case retrieving the registration infromation form the file is not successful, we (re-)register the service with the security service as in the first example using the password approach:

catch { string password = PronounceablePasswordGenerator .GeneratePassword(8); Console .WriteLine( "Attempting to register with password " + password); try { securedService = EMIC.HomeFx.Security. Service .RegisterNewService( "Amigo Security Sample Service" , System.Net. Dns.GetHostName(), password, ServiceRole .Unrestricted, RediscoveringSecurityServiceProxy .Instance); } catch ( RediscoveryException ) { Console .WriteLine( "Could not locate security service" ); return -1; } catch ( RegistrationException e) { Console .WriteLine( "Could not register with security" " service: " + e.Message); return -1; }

As in the previous example, irrecoverable communication errors will lead to a RediscoveryException. A registration attempt that is rejected from the security service for some reason will lead to a Registration exception. In either case, the service has not been successfully registered and we terminate the program with an error code.

In contrast to the previous service example, upon successful registration, we attempt to persist the registration information to the designated location:

try { using ( XmlWriter xmlWriter = XmlWriter .Create(registrationFileLocation)) { xmlSerializer.Serialize(xml Writer, securedService); } } catch { Console .WriteLine( "Warning: Could not persist " "registration information" ); } }

If the program has successfully executed up to here, then we have created an instance of EMIC.HomeFx.Security.Service.Service, which we can use to create and host an instance of the secured service from the previous section. Note that now an AddService is created!

Page 48: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 47/54

WebServer .Port = 0; WebServer .Start(); using ( Service service = new AddService (securedService)) { WebServer .AddWebService(serviceLocation, service); Console .WriteLine( "Sample service 2 running." + Environment .NewLine + "Press <return> to quit" ); Console .ReadLine(); } return 0; } } }

3.7.3 Complete server code This concludes our explanation of how to develop secured Amigo services. For convenience, the entire code is showed gain below:

// ==++== // // // Copyright (c) 2006 Microsoft Corporation. Al l rights reserved. // // The use and distribution terms for this softw are are contained in the // file named license.txt, which can be found in the root of this // distribution. // By using this software in any fashion, you ar e agreeing to be bound by // the terms of this license. // // You must not remove this notice, or any other , from this software. // // // ==--== using System; using System.Xml.Serialization; using System.Xml; using System.Net; using EMIC.WebServer; using EMIC.HomeFx.Security; using EMIC.HomeFx.Security.Proxies; using EMIC.WSAddressing; namespace SecuredServiceSample1 { class Program { static readonly string registrationFileLocation = System.Windows.Forms. Application .LocalUserAppDataPath + @"\registration.xml" ; static int Main( string [] args) { EMIC.HomeFx.Security. Service securedService = null ; XmlSerializer xmlSerializer = new XmlSerializer ( typeof (EMIC.HomeFx.Security. Service )); try { using ( XmlReader xmlReader =

Page 49: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 48/54

XmlReader .Create(registrationFileLocation)) { securedService = (EMIC.HomeFx.S ecurity. Service ) xmlSerializer.Deserialize(xmlReader); securedService.SecurityServiceP roxy = RediscoveringSecurityServiceProxy .Instance; } } catch { string password = PronounceablePasswordGenerator .GeneratePassword(8); Console .WriteLine( "Attempting to register with password " + password); try { securedService = EMIC.HomeFx.Security. Service .RegisterNewService( "Amigo Security Sample Service" , System.Net. Dns.GetHostName(), password, ServiceRole .Unrestricted, RediscoveringSecurityServiceProxy .Instance); } catch ( RediscoveryException ) { Console .WriteLine( "Could not locate security service" ); return -1; } catch ( RegistrationException e) { Console .WriteLine( "Could not register with security service: " + e.Message); return -1; } try { using ( XmlWriter xmlWriter = XmlWriter .Create(registrationFileLocation)) { xmlSerializer.Serialize(xml Writer, securedService); } } catch { Console .WriteLine( "Warning: Could not persist registration " "information" ); } } WebServer .Port = 0; WebServer .Start(); using ( Service service = new AddService (securedService)) { WebServer .AddWebService(serviceLocation, service); Console .WriteLine( "Sample service 2 running." + Environment .NewLine + "Press <return> to quit" ); Console .ReadLine(); } return 0; }

Page 50: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 49/54

} }

3.7.4 Registering the service with the Security Control Centre In order to register the service with the Security Control Centre, execute the service code. It will connect to the available control centre and as for registration. The actual procedure is described in Section 3.4.4.

Page 51: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 50/54

3.8 How to develop a secure service client .NET: example 2 As expected, the mechanisms to access the adding service developed in the previous sections is very similar to what have been described for the first example. Note again, that the code assumes that registration of the device and user of this client program has been performed separately.

We probe for the service that we want to use until we find one, using the WS-Discovery implementation. Then; we retrieve the unique name under which this service is known to the security service. This name is included into the meta data transmitted in the ProbeMatch message from the service and finally, try to obtain a ticket for the service, with a validity period of at least one hour. Then we use this ticket to create the necessary credentials to start a new session with the service.

using ( ProbeClient probeClient = new ProbeClient ()) { probeClient.AddServiceScope( new ServiceScope ( new Uri ( "urn:amigo-security-sample" ))); probeClient.AddServiceType( new ServiceType ( "sample-service2" , "urn:amigo-security-sample2" )); while (probeClient.ProbeMatches == null || probeClient.ProbeMatches.Count == 0) { Console .WriteLine( "Probing for service..." ); probeClient.SendProbe(); Thread .Sleep(2000); } ServiceInfo match = probeClient.ProbeMatches[0]; Sid sid = Sid .GetSidFromServiceInfo(match); EMIC.HomeFx.Security. Authorization authorization = thisDevice.Authorize(sid, authe ntication, new TimeSpan (1, 0, 0)); SessionCredentials credentials = authorization.NewSessionCredentials();

We prepare a proxy to contact the service, using the address from its ProbeMatch reply and finally the InvokeSecuredService<T, T0,…Tn> method of the Device class to issue a secured call to the service. As parameters, this method takes the credentials that have been created in the previous step, a delegate to the method that is responsible to send the secured request to the service, and the service call’s arguments of type T0, …, Tn. In this case, the T, T0 and T1 are all int.

using ( ServiceProxy proxy = new ServiceProxy ()) { proxy.Proxy = new WebProxy (); proxy.Url = match.FirstXaddr.Ab soluteUri; string response = thisDevice. InvokeSecuredService< int , int , int >( credentials, proxy.add, 1, 2 ).ToString ();

Page 52: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 51/54

Console .WriteLine( "Response = \"" + response + "\"" ); Console .ReadLine(); } } return 0; } } }

For your convenience, the complete C# code for the client is shown below:

// ==++== // // // Copyright (c) 2006 Microsoft Corporation. Al l rights reserved. // // The use and distribution terms for this softw are are contained in the // file named license.txt, which can be found in the root of this // distribution. By using this software in any f ashion, you are agreeing // to be bound by the terms of this license. // // You must not remove this notice, or any other , from this software. // // // ==--== using System; using System.Net; using System.Threading; using EMIC.HomeFx.Security; using EMIC.HomeFx.Security.Proxies; using EMIC.WSDiscovery; using EMIC.WSDiscovery.Client; namespace SecuredClientSample { class Program { static int Main( string [] args) { if (! Device .IsRegistered()) { Console .Error.WriteLine( "The device has not been registered." ); return -1; } Device thisDevice = Device .ThisDevice( RediscoveringSecurityServiceProxy .Instance); Authentication authentication = thisDevice.AuthenticateDevice(); using ( ProbeClient probeClient = new ProbeClient ()) { probeClient.AddServiceScope( new ServiceScope ( new Uri ( "urn:amigo-security-sample" ))); probeClient.AddServiceType( new ServiceType ( "sample-service3" , "urn:amigo-security-sample2" )); while (probeClient.ProbeMatches == null || probeClient.ProbeMatches.Count == 0)

Page 53: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 52/54

{ Console .WriteLine( "Probing for service..." ); probeClient.SendProbe(); Thread .Sleep(2000); } ServiceInfo match = probeClient.ProbeMatches[0]; Sid sid = Sid .GetSidFromServiceInfo(match); EMIC.HomeFx.Security. Authorization authorization = thisDevice.Authorize(sid, authe ntication, new TimeSpan (1, 0, 0)); SessionCredentials credentials = authorization.NewSessionCredentials(); using ( ServiceProxy proxy = new ServiceProxy ()) { proxy.Proxy = new WebProxy (); proxy.Url = match.FirstXaddr.Ab soluteUri; string response = thisDevice. InvokeSecuredService< int, int, int >( credentials, proxy.add, 1, 2 ).ToString ();

Console .WriteLine( "Response = \"" + response + "\"" ); Console .ReadLine(); } } return 0; } } }

The Amigo OSGi security framework is designed and implemented using Axis handlers. Thus, most of the security protocol mechanisms (authentication, authorization, etc.) remain transparent to the application developer. Still, information about discovered homes as well as the calling parties (i.e. invocation context) is easily accessible.

Page 54: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 53/54

4 Recommended next steps Now that you have learned about securing communication between client and server you may be interested in how to continue in the most efficient way in order to become more familiar with the Amigo middleware. You may proceed as follows:

� UMPS Tutorial: a tutorial about using the User modeling and profiling service. UPMS provides the methodology to enhance the effectiveness and usability of services and interfaces in order to (a) tailor information presentation to user and context, (b) reason about user’s future behavior, (c) help the user to find relevant information, (d) adapt interface features to the user and the context in which it is used, (e) indicate interface features and information presentation features for their adaptation to a multi-user environment. It can be downloaded from https://gforge.inria.fr/frs/?group_id=160.

� In fact, when you followed the sequence of recommended tutorials you should now have sufficient knowledge to develop your own simple services and applications. Depending on your specific needs you may also browse the Amigo repository (https://gforge.inria.fr/frs/?group_id=160) to check out further packages, tools and documentation.

Page 55: Amigo Training Document: Using Amigo Security Services · IST Amigo Project Amigo Training Document: Using Amigo Security Services Version 2.0 IST-2004-004182 Public . June 2007 Confidential

June 2007 Confidential

Amigo IST-2004-004182 54/54

5 Troubleshooting In order to be able to run the EMIC HomeFx software on Windows XP machines, the following Windows components and updates are necessary:

1. Update KB920342 (http://support.microsoft.com/default.aspx/kb/920342)

2. The IPv6 and the P2P components should be installed (these are by default not installed during the Windows setup).

The P2P component can be installed by going to Start � Control Panel � Add or Remove Programs � Add/Remove Windows Components.

The IPv6 component is installed by typing the following command in a command prompt window:

netsh interface ipv6 install

To execute the command, administrative privileges are required.