1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization.Formatters;
namespace Rainbird.Tools.EasyRemoting
{
// NICHT VERGESSEN: System.Runtime.Remoting.dll ALS VERWEIS ZUFÜGEN!
/// <summary>
/// Enthält eine Sammlung von statischen Funktionen, die einfaches
/// Remoting ermöglichen.
/// </summary>
public class RemotingHelper
{
/// <summary>
/// Veröffentlicht ein beliebiges von MarshalByRef abgeleitetes Objekt über einen TCP-Kanal für entfernten Zugriff.
///
/// Bei aktivierung der Sicherheit über den Parameter "enableSecurity", wird die Kommunikation
/// vom Absender signiert, um die Integrität sicherzustellen und zusätzlich verschlüsselt.
/// Über den Parameter "impersonate" kann Impersonierung eingeschaltet werden. Bei eingeschalteter
/// Impersonierung, wird der Remoteaufruf im Kontext des Client-Benutzers ausgeführt.
/// </summary>
/// <remarks>
/// Der TCP-Kanal wird automatisch konfiguriert und registriert. Die Kanal-Registrierung bleibt
/// über diesen Prozeduraufruf hinaus gültig. Wenn sie die selbe TCP-Anschlussnummer mehrmals an
/// diese Methode übergeben, wird der bestehene Kanal verwendet. Die Sicherheitskonfiguration des
/// ersten Aufrufs ist deshalb entscheidend. Wenn sie für spätere Aufrufe andere Werte für die
/// Parameter "enableSecurity" oder "impersonate" angeben, werden diese nicht berücksichtigt,
/// da der bestehende Kanal verwendet wird!
/// </remarks>
/// <param name="instance">Zu veröffentlichendes Objekt</param>
/// <param name="publicName">Öffentlicher Name (Über diesen Namen greifen Clients entfernt auf das Objekt zu!)</param>
/// <param name="tcpPort">TCP-Anschlussnummer</param>
/// <param name="enableSecurity">Schalter für Sicherheit</param>
/// <param name="impersonate">Schalter für Impersonierung</param>
public static void PublishObjectOverTCP(MarshalByRefObject instance,string publicName,int tcpPort, bool enableSecurity,bool impersonate)
{
// Kanal einrichten (Falls dies noch nicht geschehen ist!)
SetupServerChannel(tcpPort, enableSecurity, impersonate);
// Objektinstanz über den TCP-Kanal für entfernten Zugriff veröffentlichen
RemotingServices.Marshal(instance, publicName);
}
/// <summary>
/// Gibt einen Proxy auf ein entferntes Objekt zurück.
///
/// Das entfernte Objekt wird über eine TCP-Verbindung ferngesteuert.
/// Der Proxy vermittelt lokale Methodenaufrufe an das entfernte Objekt.
/// Rückgabe-Werte können lokal über den proxy entgegen genommen werden.
///
/// Bei aktivierung der Sicherheit über den Parameter "enableSecurity", wird die Kommunikation
/// vom Absender signiert, um die Integrität sicherzustellen und zusätzlich verschlüsselt.
/// Über den Parameter "impersonate" kann Impersonierung eingeschaltet werden. Bei eingeschalteter
/// Impersonierung, wird der Remoteaufruf im Kontext des Client-Benutzers ausgeführt.
/// </summary>
/// <param name="remoteType">Typ-Informationen des entfernten Objekts (übergeben Sie entweder den Typ der Klasse oder den typ einer, vom entfernten Objekt, implementierten Schnittstelle an!)</param>
/// <param name="publicName">Öffentlicher Name des entfernten Objekts</param>
/// <param name="serverName">DNS-Computername des Servers oder dessen IP-Adresse</param>
/// <param name="tcpPort">TCP-Anschlussnummer des Servers</param>
/// <param name="enableSecurity">Schalter für Sicherheit</param>
/// <param name="impersonate">Schalter für Impersonierung</param>
/// <returns>Transparentes Proxy-Objekt</returns>
public static object GetRemoteObjectOverTCP(Type remoteType, string publicName, string serverName, int tcpPort, bool enableSecurity, bool impersonate)
{
// Kanal einrichten (Falls dies noch nicht geschehen ist!)
SetupClientChannel(enableSecurity, impersonate);
// URI für die Adressierung des entfernten Objekts generieren
StringBuilder uriBuilder = new StringBuilder(@"tcp://");
uriBuilder.Append(serverName);
uriBuilder.Append(':');
uriBuilder.Append(tcpPort);
uriBuilder.Append('/');
uriBuilder.Append(publicName);
// Verbindung zum entfernten Objekt herstellen und einen Proxy erzeugen
return Activator.GetObject(remoteType, uriBuilder.ToString());
}
/// <summary>
/// Richtet einen TCP-Serverkanal ein. Serverkanäle nehmen Anfragen von Clients entgegen.
///
/// Bei aktivierung der Sicherheit über den Parameter "enableSecurity", wird die Kommunikation
/// vom Absender signiert, um die Integrität sicherzustellen und zusätzlich verschlüsselt.
/// Über den Parameter "impersonate" kann Impersonierung eingeschaltet werden. Bei eingeschalteter
/// Impersonierung, wird der Remoteaufruf im Kontext des Client-Benutzers ausgeführt.
/// </summary>
/// <param name="tcpPort">TCP-Anschlussnummer</param>
/// <param name="enableSecurity">Schalter für Sicherheit</param>
/// <param name="impersonate">Schalter für Impersonierung</param>
public static void SetupServerChannel(int tcpPort, bool enableSecurity,bool impersonate)
{
// Kanalnamen erzeugen
string channelName = "RainbirdEasyRemotingServer" + Convert.ToString(tcpPort);
// Kanal suchen
IChannel channel = ChannelServices.GetChannel(channelName);
// Wenn der Kanal nicht gefunden wurde ...
if (channel == null)
{
// Konfiguration für den TCP-Kanal erstellen
System.Collections.IDictionary channelSettings = new System.Collections.Hashtable();
channelSettings["name"] = channelName;
channelSettings["port"] = tcpPort;
channelSettings["secure"] = enableSecurity;
// Wenn Sicherheit aktiviert ist ...
if (enableSecurity)
{
// Impersonierung entsprechend der Einstellung aktivieren oder deaktivieren
channelSettings["tokenImpersonationLevel"] = impersonate ? System.Security.Principal.TokenImpersonationLevel.Impersonation : System.Security.Principal.TokenImpersonationLevel.Identification;
// Signatur und Verschlüssung explizit aktivieren
channelSettings["protectionLevel"] = System.Net.Security.ProtectionLevel.EncryptAndSign;
}
// Binäre Serialisierung von komplexen Objekten aktivieren
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
// Neuen TCP-Kanal erzeugen
channel = new TcpChannel(channelSettings, null, provider);
// Kanal registrieren
ChannelServices.RegisterChannel(channel, enableSecurity);
}
}
/// <summary>
/// Richtet einen TCP-Clientkanal ein. Clientkanäle senden Anfragen an Serverkanäle.
///
/// Bei aktivierung der Sicherheit über den Parameter "enableSecurity", wird die Kommunikation
/// vom Absender signiert, um die Integrität sicherzustellen und zusätzlich verschlüsselt.
/// Über den Parameter "impersonate" kann Impersonierung eingeschaltet werden. Bei eingeschalteter
/// Impersonierung, wird der Remoteaufruf im Kontext des Client-Benutzers ausgeführt.
/// <remarks>
/// Achtung!
///
/// Die Sicherheitseinstellungen des Client-Kanals müssen mit denen des Server-Kanals genau
/// übereinstimmen. Ansonsten werden Sicherheitsprobleme auftreten.
/// </remarks>
/// </summary>
/// <param name="enableSecurity">Schalter für Sicherheit</param>
/// <param name="impersonate">Schalter für Impersonierung</param>
public static void SetupClientChannel(bool enableSecurity, bool impersonate)
{
// Kanalnamen erzeugen
string channelName = "RainbirdEasyRemotingClient";
// Kanal suchen
IChannel channel = ChannelServices.GetChannel(channelName);
// Wenn der Kanal nicht gefunden wurde ...
if (channel == null)
{
// Konfiguration für den TCP-Kanal erstellen
System.Collections.IDictionary channelSettings = new System.Collections.Hashtable();
channelSettings["name"] = channelName;
channelSettings["secure"] = enableSecurity;
// Wenn Sicherheit aktiviert ist ...
if (enableSecurity)
{
// Impersonierung entsprechend der Einstellung aktivieren oder deaktivieren
channelSettings["tokenImpersonationLevel"] = impersonate ? System.Security.Principal.TokenImpersonationLevel.Impersonation : System.Security.Principal.TokenImpersonationLevel.Identification;
// Signatur und Verschlüssung explizit aktivieren
channelSettings["protectionLevel"] = System.Net.Security.ProtectionLevel.EncryptAndSign;
}
// Binäre Serialisierung von komplexen Objekten aktivieren
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
// Neuen TCP-Kanal erzeugen
channel = new TcpChannel(channelSettings, null, provider);
// Kanal registrieren
ChannelServices.RegisterChannel(channel, enableSecurity);
}
}
}
}
|