Using Messaging API For Remote Code Execution

Messaging API gives you an easy and powerful tool for remote code execution. The short overview of the API is in Messaging chapter.

All you will need to do is to define specific message class or classes (should be shared between client and server).

The client side can issue messages using:

c#: IMessageSender#Send(message)

VB: IMessageSender#Send(message)

The server side should register a message listener:

c#: Configuration#SetMessageRecipient(IMessageRecipient)

VB: Configuration#SetMessageRecipient(IMessageRecipient)

Message recipient should define a response to the different messages received in

c#: ProcessMessage(IObjectContainer objectContainer, object message)

vb: ProcessMessage(ByVal objectContainer As IObjectContainer, ByVal message As Object)

method. ObjectContainer parameter gives full control over the database.

Let's reset our database and try updating using special UpdateServer message.

RemoteExample.cs: SetObjects
01private static void SetObjects() 02 { 03 File.Delete(Db4oFileName); 04 IObjectContainer db = Db4oFactory.OpenFile(Db4oFileName); 05 try 06 { 07 for (int i = 0; i < 5; i++) 08 { 09 Car car = new Car("car"+i); 10 db.Set(car); 11 } 12 db.Set(new RemoteExample()); 13 } 14 finally 15 { 16 db.Close(); 17 } 18 CheckCars(); 19 }
RemoteExample.cs: UpdateCarsWithMessage
01private static void UpdateCarsWithMessage() 02 { 03 IConfiguration configuration = Db4oFactory.NewConfiguration(); 04 // create message handler on the server 05 configuration.ClientServer().SetMessageRecipient( 06 new UpdateMessageRecipient()); 07 IObjectServer server=Db4oFactory.OpenServer(configuration, Db4oFileName,0xdb40); 08 server.GrantAccess("user", "password"); 09 try 10 { 11 // send message object to the server 12 IConfiguration clientConfiguration = Db4oFactory.NewConfiguration(); 13 IMessageSender sender = clientConfiguration.ClientServer().GetMessageSender(); 14 IObjectContainer client = Db4oFactory.OpenClient(clientConfiguration, 15 "localhost", 0xdb40, "user", "password"); 16 sender.Send(new UpdateServer()); 17 client.Close(); 18 } 19 finally 20 { 21 server.Close(); 22 } 23 CheckCars(); 24 }

RemoteExample.vb: SetObjects
01Private Shared Sub SetObjects() 02 File.Delete(Db4oFileName) 03 Dim db As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04 Try 05 Dim i As Integer 06 For i = 0 To 5 - 1 Step i + 1 07 Dim car As Car = New Car("car" + i.ToString()) 08 db.Set(car) 09 Next 10 db.Set(New RemoteExample()) 11 Finally 12 db.Close() 13 End Try 14 CheckCars() 15 End Sub
RemoteExample.vb: UpdateCarsWithMessage
01Private Shared Sub UpdateCarsWithMessage() 02 ' create message handler on the server 03 Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 04 configuration.ClientServer.SetMessageRecipient(New UpdateMessageRecipient()) 05 Dim server As IObjectServer = Db4oFactory.OpenServer(configuration, Db4oFileName, &HDB40) 06 server.GrantAccess("user", "password") 07 Try 08 Dim clientConfiguration As IConfiguration = Db4oFactory.NewConfiguration() 09 Dim sender As IMessageSender = clientConfiguration.ClientServer().GetMessageSender() 10 Dim client As IObjectContainer = Db4oFactory.OpenClient(clientConfiguration, "localhost", &HDB40, "user", "password") 11 ' send message object to the server 12 sender.Send(New UpdateServer()) 13 client.Close() 14 Finally 15 server.Close() 16 End Try 17 CheckCars() 18 End Sub

You can also put some information in the message being sent (UpdateServer class).

The advantage of this method is that having predefined message types you can make any changes to the handling code only on the server side. In the situations with many distributed clients it can really save you lots of time on support.