Monday, 7 February 2011

Experiment of SMSLib on GPRS Modem in Ubuntu

I spent a lot of time on this GPRS 609 MODEM. Somehow this device I purchased on Ebay is faulty, or it isn't powerful enough in my area. Anyway it doesn't work very well. Basically, it can connect with "cu -l /dev/ttyUSB0", but sometimes it had no echo even I tried "AT+ATE1". The command AT+CMGS almost failed with error 33825, altough I did manage to send SMS twice. However, SMSLib SendMessage never succeeded. Interestingly enough, all other commands(listed below) were OK on the condition that the echo was fine.


Finally, I gave up the lame duck(I am afraid say so), as my friend offered me his Motorola V3 mobile phone which can be taken as a GPRS modem. Life became much easier with this mobile phone. Almost everything was straightforward.



With Ubuntu 10.10 32bit guest OS in Vmware Workstation,

dmesg shows this device is recognized as ttyACM0, no additional driver needed.



[ 233.820553] usb 2-1: new full speed USB device using uhci_hcd and address 3
[ 234.057913] usb 2-1: configuration #1 chosen from 2 choices
[ 234.284872] cdc_acm 2-1:1.0: ttyACM0: USB ACM device
[ 234.297306] usbcore: registered new interface driver cdc_acm
[ 234.297901] cdc_acm: v0.26:USB Abstract Control Model driver for USB modems and ISDN adapters


No hassle at all when using AT commands to send SMS. However, the tricks suggested by SMSLib Troubleshooting are applied during SMSLib tests. In details, the parameter -Dsmslib.serial.polling is used for no response exception. A symbolic link (sudo ln -s /dev/ttyACM0 /dev/ttyS20) is created for NoSuchPortException, but I haven't tried the alternative - gnu.io.rxtx.SerialPorts.



/*
* Register ports specified in the file "gnu.io.rxtx.properties"
* Key system properties:
* gnu.io.rxtx.SerialPorts
* gnu.io.rxtx.ParallelPorts
*
* The file gnu.io.rxtx.properties must reside in the java extension dir
*
* Example: /usr/local/java/jre/lib/ext/gnu.io.rxtx.properties
*
* The file contains the following key properties:
*
* gnu.io.rxtx.SerialPorts=/dev/ttyS0:/dev/ttyS1:
* gnu.io.rxtx.ParallelPorts=/dev/lp0:
*
*/

In addition, I chose the RXTX library distribution from CloudHopper's web site. Also I installed Sun Java, as I know the folder structure of Sun Java better than built-in Open JDK on Ubuntu. The command to run this jar is,


 /opt/java/bin/java -Dsmslib.serial.polling -Djava.library.path=/opt/java/bin -jar smslearn.jar


The modified java source code of SendMessage example.




// SendMessage.java - Sample application.
//
// This application shows you the basic procedure for sending messages.
// You will find how to send synchronous and asynchronous messages.
//
// For asynchronous dispatch, the example application sets a callback
// notification, to see what's happened with messages.

package com.deepnet.smslearn;

import org.smslib.AGateway;
import org.smslib.IOutboundMessageNotification;
import org.smslib.Library;
import org.smslib.OutboundMessage;
import org.smslib.Service;
import org.smslib.modem.SerialModemGateway;

public class SendMessage
{
public void doIt(String device, String speed, String phone, String message) throws Exception
{
OutboundNotification outboundNotification = new OutboundNotification();
System.out.println("Example: Send message from a serial gsm modem.");
System.out.println(Library.getLibraryDescription());
System.out.println("Version: " + Library.getLibraryVersion());
SerialModemGateway gateway = new SerialModemGateway("modem.ttyS20", device, Integer.parseInt(speed), "NoSuchPortException", "V3");
gateway.setInbound(true);
gateway.setOutbound(true);
// gateway.setSimPin("0000");
// Explicit SMSC address set is required for some modems.
// Below is for VODAFONE GREECE - be sure to set your own!
// gateway.setSmscNumber("+306942190000");
Service.getInstance().setOutboundMessageNotification(outboundNotification);
Service.getInstance().addGateway(gateway);
Service.getInstance().startService();
System.out.println();
System.out.println("Modem Information:");
System.out.println(" Manufacturer: " + gateway.getManufacturer());
System.out.println(" Model: " + gateway.getModel());
System.out.println(" Serial No: " + gateway.getSerialNo());
System.out.println(" SIM IMSI: " + gateway.getImsi());
System.out.println(" Signal Level: " + gateway.getSignalLevel() + " dBm");
System.out.println(" Battery Level: " + gateway.getBatteryLevel() + "%");
System.out.println();
// Send a message synchronously.
OutboundMessage msg = new OutboundMessage(phone, message);
Service.getInstance().sendMessage(msg);
System.out.println(msg);
// Or, send out a WAP SI message.
//OutboundWapSIMessage wapMsg = new OutboundWapSIMessage("+306974000000", new URL("http://www.smslib.org/"), "Visit SMSLib now!");
//Service.getInstance().sendMessage(wapMsg);
//System.out.println(wapMsg);
// You can also queue some asynchronous messages to see how the callbacks
// are called...
//msg = new OutboundMessage("+309999999999", "Wrong number!");
//srv.queueMessage(msg, gateway.getGatewayId());
//msg = new OutboundMessage("+308888888888", "Wrong number!");
//srv.queueMessage(msg, gateway.getGatewayId());
// System.out.println("Now Sleeping - Hit to terminate.");
// System.in.read();
Service.getInstance().stopService();
}

public class OutboundNotification implements IOutboundMessageNotification
{
public void process(AGateway gateway, OutboundMessage msg)
{
System.out.println("Outbound handler called from Gateway: " + gateway.getGatewayId());
System.out.println(msg);
}
}

public static void main(String args[])
{
if(args.length < 4)
{
System.out.println("Usage:smslearn device speed phone message");
return;
}

SendMessage app = new SendMessage();
try
{
app.doIt(args[0],args[1],args[2],args[3]);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}



Basic AT commands


you can try minicom instead.



$ cu -l /dev/ttyACM0
Connected.

//Phone activity status +CPAS. 0 Ready, 1 Unavailable,2 Unknown,3 Ringing,4 Call in progress,5 Asleep
at+cpas
+CPAS: 0

//Request manufacturer identification +CGMI
at+cgmi
+CGMI: "Motorola CE, Copyright 2004"

//Request model identification +CGMM
at+cgmm
+CGMM: "GSM900","GSM1800","GSM1900","GSM850","MODEL=V3"

//Request revision identification +CGMR
at+cgmr
+CGMR: "R374_G_0E.42.10R_A"

//Request product serial number identification +CGSN
at+cgsn
+CGSN: IMEI354759009930994

//AT+ATE1 : enable echo;

//Service Centre Address +CSCA
at+csca?
+CSCA: "+447973100973",145

//Report Mobile Equipment error +CMEE
AT+CMEE=1 //Report Mobile Equipment extend error. 0 = Disable, 1 = result code and use numeric values, 2 = result code and use verbose value

//Message Format +CMGF
AT+CMGF? // Query current format
AT+CMGF=1 // 0 = PDU mode (default), 1 = text mode

//Enter PIN +CPIN
at+cpin?
+CPIN: READY

//Send Message +CMGS
AT+CMGS="+31638740161"
Hello World !
+CMGS: 62
//Replace the above phone number with your own cell phone number. The modem will respond with: >
//You can now type the message text and send the message using the - key combination:
//After some seconds the modem will respond with the message ID of the message, indicating that the message was sent correctly:
//The message will arrive on the mobile phone shortly.


It is worth writing here how to exit cu: type '~' first, once you see computer name, then type '.'.




Reference



Send SMS using AT commands

USB Tri-band GPRS Modem / Cell Phone Radio (GSM 900/1800/1900Mhz)

Modify PL2303 PID & VID

Monday, 31 January 2011

LDAP Connection Errors

When using LDAP connection to import the external identity source(user names) in Deepnet Authentication Server, you must specify the correct user DN string and its password in order to connect LDAP server successfully. Otherwise you will get some errors like "AcceptSecurityContext error, data 525(or 52e etc)".



I often use two utilities to confirm the user DN string, dsquery and ADSIEdit.



Dsquery is a command-line tool that is built into Windows Server 2008. It is available if you have the Active Directory Domain Services (AD DS) server role installed. To use dsquery, you must run the dsquery command from an elevated command prompt. To open an elevated command prompt, click Start, right-click Command Prompt, and then click Run as administrator. On Windows 2003, you may need to install Support Tools on the domain controller to use dsquery.


Here is an example. the command "dsquery user" is executed on domain controller.



C:\>dsquery user
"CN=Administrator,CN=Users,DC=nanoart,DC=local"
"CN=Guest,CN=Users,DC=nanoart,DC=local"
"CN=SUPPORT_388945a0,CN=Users,DC=nanoart,DC=local"
"CN=krbtgt,CN=Users,DC=nanoart,DC=local"

Alternatively, we can use ADSIEdit. I prefer to run it on domain controller as well, although it can run on another machine, but you must know how to login.





References



LDAP Troubleshooting

Common Active Directory LDAP bind errors

Saturday, 22 January 2011

Redundant cluster settings

First of all, let us look at the content of server.xml file which is located at the folder "C:\Program Files\Deepnet Authentication Server\Tomcat\conf". There are 3 occurrences of Cluster.



<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster" clusterLogName="clusterlog" clusterName="localhost" manager.className="org.apache.catalina.cluster.session.DeltaManager" manager.expireSessionsOnShutdown="false" manager.notifyListenersOnReplication="false" manager.notifySessionListenersOnReplication="false" manager.sendAllSessions="false" manager.sendAllSessionsSize="500" manager.sendAllSessionsWaitTime="20" manager.sendClusterDomainOnly="true">
<Membership className="org.apache.catalina.cluster.mcast.McastService" mcastAddr="228.1.1.4" mcastClusterDomain="das_cluster" mcastDropTime="30000" mcastFrequency="1000" mcastPort="24282" recoveryEnabled="true"/>
<Sender className="org.apache.catalina.cluster.tcp.ReplicationTransmitter" doProcessingStats="true" doTransmitterProcessingStats="true" doWaitAckStats="true" keepAliveMaxRequestCount="-1" keepAliveTimeout="80000" queueCheckLock="true" queueDoStats="true" queueTimeWait="true" recoverCounter="6" recoverTimeout="5000" replicationMode="fastasyncqueue"/>
<Receiver className="org.apache.catalina.cluster.tcp.ReplicationListener" compress="false" sendAck="true" tcpListenAddress="x.x.x.x" tcpListenPort="4000" tcpSelectorTimeout="100" tcpThreadCount="6"/>
<Valve className="org.apache.catalina.cluster.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.css;.*\.png;.*\.jpeg;.*\.jpg;.*\.htm;.*\.html;.*\.txt;" primaryIndicator="true"/>
<Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve"/>
<ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
<ClusterListener className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener"/>
</Cluster>

What will this result in? With some traffic monitor, you will see a lot of connection attempts to IP "228.1.1.4" configured in server.xml (see above). Suspicious and scary, isn't it? I am not comfortable with that, although this address doesn't exist on Internet.


According to Deepnet Support, this tech(multicast) was adopted at the very beginning for deepnet authentication server cluster configuration, but they abandoned it as another approach was used to implement the cluster/load balancing.


So these settings are redundant, why not remove them!



  • backup the file server.xml;
  • open the file server.xml with your favourite editor;
  • locate these pairs <Cluster ..>....</Cluster>, delete them;
  • save the file;
  • restart deepnet service "das";

Now it is nice and clean. Happy!

Monday, 10 January 2011

Deepnet ActiveSync solution doesn't work on some Android devices.

You may have some problems to add Deepnet ActiveSync protection onto Android phone device. Here is the effective remedy.



1, go to the folder "C:\Program Files\Deepnet Security\IIS" on your Exchange server where Deepnet IIS agent is installed;

2, open the file "config.xml" with your favourite editor;

3, locate <serv desc="Microsoft Server ActiveSync" code="sas">, which is around line 64;



<serv desc="Microsoft Server ActiveSync" code="sas">
<requests>

4, insert the following after <requests>;



<req match="Microsoft-Server-ActiveSync/Android" source="${_url}">
<params>
<par name="UserName" value="User={.*?}&" source="${_url}"/>
<par name="DeviceID" value="/{android.+}/*.*$" source="${_url}"/>
</params>
<variables>
<var name="x-deviceID" value="$$encrypt(<uuid>${DeviceID}</uuid>)"/>
</variables>
<actions>
<condition property="${_Authenticator}" value="devicePass" op="iquals">

<condition property="${UserName}" value="" op="equals">
<act type="assign" var="UserName" value="${_authuser}"/>
</condition>


<condition property="${UserName}" value="" op="notequals">

<act type="xmlrpc">
<methodCall>
<methodName>das.login</methodName>
<params>
<param>
<value><string>${_appId}</string></value>
</param>
<param>
<value><string>${UserName}</string></value>
</param>
<param>
<value><string><![CDATA[<?xml version="1.0"?>
<credential>
<method>${_Authenticator}</method>
<token>
<deviceID>${DeviceID}</deviceID>
</token>
<credentialData>
<devicePrint>
${x-deviceID}
</devicePrint>
</credentialData>
</credential>]]></string></value>
</param>
<param>
<value><string>${_clientip}</string></value>
</param>
<param>
<value><string></string></value>
</param>
<param>
<value><boolean>0</boolean></value>
</param>
</params>
</methodCall>
</act>
</condition>
</condition>
</actions>
<errors page="/dasweb/sas/error.aspx?errcode=$$urlencode(${_return})&username=$$urlencode(${UserName})&appid=$$urlencode(${_appId})&method=$$urlencode(${_Authenticator})">
<err code="E-METHOD-NOT-FOUND" page="/dasweb/sas/method_not_found.aspx?errcode=$$urlencode(${_return})&username=$$urlencode(${UserName})&appid=$$urlencode(${_appId})&method=$$urlencode(${_Authenticator})"/>
<err code="E-TOKEN-INACTIVE" page="/dasweb/sas/token_inactive.aspx?errcode=$$urlencode(${_return})&username=$$urlencode(${UserName})&appid=$$urlencode(${_appId})&method=$$urlencode(${_Authenticator})&deviceid=$$urlencode(${DeviceID})"/>
<err code="E-CONNECT-DAS" page="/dasweb/sas/connect_das_error.aspx?errcode=$$urlencode(${_return})&das=$$urlencode(${_das})"/>
</errors>
</req>

For your convenience, the working configuration file can be downloaded from here. Simply replace the original one, then restart IIS service.

Friday, 19 November 2010

Deepnet Server v3.x migration

The migration of deepnet server (v3.x) is very simple.



  • stop Deepnet Authentication Server(das) service


  • It can be done by typing "net stop das" in Command Prompt

  • stop MySQL(dasmysql) service(if applicable)


  • Do it with "net stop dasmysql"

  • backup whole deepnet folder


  • By default, it is called "Deepnet Authentication Server" in the folder "C:\Program Files"

  • copy the backup to the new server


  • For simplicity, you should copy the backup to "C:\Program Files" on the new machine, just keep the path same.

  • start the services on existing server


  • If you still need the deepnet service running on the existing machine for a while, you can start them by the reverse order, which are

    net start dasmysql

    net start das

  • save the following code to a batch file(migration.bat) on the new machine



  • "%cd%\mysql\bin\mysqld.exe" --install DASMYSQL --defaults-file="%cd%\mysql\das.ini"
    net start dasmysql

    "%cd%\Tomcat\bin\tomcat5.exe" //IS//DAS --Startup=auto --StartMode jvm --StopMode jvm --StartClass org.apache.catalina.startup.Bootstrap --StopClass org.apache.catalina.startup.Bootstrap --StartParams start --StopParams stop --Install "%cd%\Tomcat\bin\tomcat5.exe" --LogPath "%cd%\Tomcat\logs" --Classpath "%cd%\Tomcat\bin\bootstrap.jar";"%cd%\jython\jython.jar" --Jvm "%cd%\jre\bin\server\jvm.dll" --DisplayName "DAS" --Description "DAS SERVICE" --StartPath "%cd%\Tomcat" --StopPath "%cd%\Tomcat" --JvmOptions "-Dcatalina.home=%cd%\Tomcat;-Dcatalina.base=%cd%\Tomcat;-Djava.endorsed.dirs=%cd%\Tomcat\common\endorsed;-Djava.io.tmpdir=%cd%\Tomcat\temp;-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager;-Djava.util.logging.config.file=%cd%\Tomcat\conf\logging.properties;-Dpython.home=%cd%\jython"

    net start das


  • move the batch file to Deepnet folder


  • You must place the batch file in the deepnet folder, which is "C:\Program Files\Deepnet Authentication Server"

  • run the batch file


  • On the new machine, open a Command Prompt, go to deepnet folder, run migration.bat

  • open a web page http://localhost:8080


  • Still on the new machine, launch a browser, access http://localhost:8080, assume you are using the default port of deepnet management console. It will ask you to input new IP address of the new machine. Don't forget to click Submit button to finish.


Mind you, it is against Deepnet license agreement if you run the same license on two different machine simultaneously(unless it is a load-balance/failover infrastructure), so please fully shutdwon the deepnet server on the old machine once the migration is completed.

Wednesday, 17 November 2010

Two Factor Authentication on RDWeb


Some vendors provide a solution to protect MS Remote Desktop Service(RDWeb) with OTP, the implementation and deployment are very easy, just customize the RDWeb login page(C:\Windows\Web\RDWeb\Pages\en-US\login.aspx) and add a OTP authentication dll to BIN folder (C:\Windows\Web\RDWeb\Pages\Bin).



Really it is very neat, but is it safe? I was a bit wary of that.


In order to answer my own question, we have to understand how RDWeb works. Thank my friend Craig who provided me this link How TSWeb / TSAC / Remote Desktop Web Connection Client Works. In this article, the author Tristan Kingston says,



There's a common misconception that TSWeb allows you to connect to a Terminal Server over HTTP. The reality is that you just use HTTP to transfer the Remote Desktop Client ActiveX control to the client browser, which then runs and makes a regular RDP connection to the Terminal Server, just like the regular Remote Desktop client would, but presented in a browser window.

Short version: HTTP and RDP are used to connect to a TSWeb server. HTTP (TCP 80) is used to download the ActiveX control, which then connects directly using RDP (TCP 3389) to whatever server is specified by the page for the actual Terminal Server interface. Clients that can't use port 3389 through a firewall won't be able to connect, so clients that exclusively have Web protocol access are not able to use this method to connect. (They'll be able to download the client and the page, but not able to do the actual Terminal Server part)."


It was posted almost six years ago, however the conclusion is still correct.


Recently I had time to play with RDWeb. I published 2 applications.



When I tried to click one of them, Remote Desktop(mstsc.exe) was launched



From the result of Process Explorer, it was evident that mstsc took part in this job!



Still not convinced? try the option "Don't allow connections to this computer" on the RDWeb server



Unluckily, I got the result which was expected though. Without Remote Desktop, RemoteApp doesn't work at all!




Now imagine if I were an intruder, do you think I would bother to access RdWeb? No, I would access Remote Desktop directly!


Frankly, the protection through RDWeb is still feasible if there is an easy way to block Remote Desktop while allow RemoteApp only. Unfortunately, ServerFault has a verdict on this question - Allow only RemoteApp, not Remote Desktop,



There isn't an "officially sanctioned" way to do this because, fundamentally, TS RemoteApp functionality is just leveraging existing Remote Desktop code. You could do something silly like use Group Policy to set the user's shell to be "logoff.exe" such that if they attempted to access the machine's desktop they'd be immediately logged-off. Any application that uses a common "File / Open" dialog, though, can be used to get a command prompt or other programs open on the server's desktop.

You're better off making sure that you follow the principle of least privilege and give your TS RemoteApp users as few rights as they need to run the intended software. If they do end up on the server computer's desktop their restricted rights should prevent them from doing anything damaging to the server computer.


Is it a neccessary burden to the administrator for enhancing the secure access? Do you want to completely block the Remote Desktop? You'd better think it twice! Nervertheless, I think it is very possible to leave a back door open if you only customize the RDWeb login page to do a two factor authentication.


All of a sudden, I realized why Deepnet always recommended adding the second factor protection at credential provider level(LOGONUI.exe). Even if you are using RemoteApp only, the second factor login kicks in at some stage.




Reference



TS RemoteApp Step-by-Step Guide

How TSWeb / TSAC / Remote Desktop Web Connection Client Works

Allow only RemoteApp, not Remote Desktop

Thursday, 11 November 2010

Deepnet Windows Logon Solution


There are a few cases that the user can't login with OTP after installing Deepnet Windows Logon Solution.

In Event Viewer on the domain controller, you see some error logs emitted from a source called "DasDCAgent", and the error detail reads:




Get ticket from client failed: Domain MYDOMAIN
Domain Controller: DC IP
Workstation: MYWS
User: me
Connect to client failed
ErrorCode: E-FAIL


This error message means the domain controller(actually Deepnet DC Agent) is unable to contact a service (Deepnet Client Agent)installed on client machine(workstation). There are two possibities.



Workstation Side



Deepnet Client Agent port 14283 is blocked by Windows Firewall(or other software firewall installed)


Deepnet Client Agent default port 14283 is taken by another process(rather than dasclientagent.exe)


The service "DAS Client Agent" doesn't start properly




Domain Controller Side



Somehow the DC can't resolve the workstation name to a correct IP address which is allocated on the workstation. Generally it is down to a DNS problem. You can confirm it by executing a ping command in Command Prompt.


ping MYWS


Check the result to see if it matches the one returned by doing "ipconfig" at your workstation side.




Ironically, the inverstigaton on all of the reported cases only goes to prove the problem was caused by incorrect IP resolve at DC side - DNS corruption!