1 18 19 package sync4j.server.engine.dm; 20 21 import java.net.URI ; 22 import java.net.URISyntaxException ; 23 import java.util.Date ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 import java.util.logging.Level ; 27 import java.util.logging.Logger ; 28 29 import org.apache.commons.lang.StringUtils; 30 31 import sync4j.framework.config.Configuration; 32 import sync4j.framework.config.ConfigurationConstants; 33 import sync4j.framework.core.bootstrap.BootStrap; 34 import sync4j.framework.core.dm.ddf.DMAcc; 35 import sync4j.framework.core.dm.ddf.DMAccount; 36 import sync4j.framework.core.dm.ddf.SyncMLDM; 37 import sync4j.framework.engine.dm.DeviceDMState; 38 import sync4j.framework.notification.NotificationConstants; 39 import sync4j.framework.notification.NotificationEngine; 40 import sync4j.framework.notification.NotificationException; 41 import sync4j.framework.security.Officer; 42 import sync4j.framework.security.Sync4jPrincipal; 43 import sync4j.framework.server.Sync4jDevice; 44 import sync4j.framework.server.SyncUser; 45 import sync4j.framework.server.store.*; 46 import sync4j.framework.tools.Base64; 47 import sync4j.framework.tools.MD5; 48 import sync4j.framework.tools.SecurityTools; 49 import sync4j.framework.tools.beans.BeanFactory; 50 51 import sync4j.server.admin.DBUserManager; 52 import sync4j.server.engine.Sync4jEngine; 53 import sync4j.server.notification.NotificationEngineImpl; 54 55 56 57 58 65 public class ManagementEngine extends Sync4jEngine { 66 67 69 74 private static final int DEFAULT_ADDRESS_TYPE = 1; 75 private static final int DEFAULT_PORT_NUMBER = 80; 76 77 80 public static final String SYNCML_DM_BOOTSTRAP_MESSAGE = 81 "sync4j/server/engine/dm/SyncMLDMbootstrapMessage.xml"; 82 83 private static final String NS_MSSID = "mssid" ; 85 86 private static final String OPERATION_AFTER_BOOTSTRAP = "GetDeviceDetail"; 87 88 private Configuration config = null; 90 private Logger log = null; 91 private DBUserManager dbUserManager = null; 92 private Officer officer = null; 93 94 96 99 private ManagementEngine() {} 100 101 102 107 public ManagementEngine(Configuration config) { 108 super(config); 109 this.config = config; 110 log = Logger.getLogger("sync4j.dm"); 111 112 dbUserManager = (DBUserManager)config.getBeanInstance(CFG_USER_MANAGER); 113 officer = (Officer)config.getBeanInstance(CFG_SECURITY_OFFICER); 114 } 115 116 117 132 public void bootstrap(int messageType, 133 int transportType, 134 String deviceUri, 135 String phoneNumber, 136 String username, 137 String password, 138 String info, 139 boolean updateDeviceInfo) throws NotificationException { 140 141 if (log.isLoggable(Level.INFO)) { 142 log.info("Start bootstrap process in ManagementEngine for: " + phoneNumber); 143 } 144 145 String serverUri = config.getStringValue(ConfigurationConstants.CFG_SERVER_URI); 146 147 SyncMLDM syncMLDMBootstrapMessage = preBootstrapOperation(deviceUri, 148 phoneNumber, 149 username, 150 password, 151 info, 152 updateDeviceInfo); 153 154 NotificationEngine notificationEngine = new NotificationEngineImpl(config); 155 156 notificationEngine.sendBootstrapMessage(messageType, transportType, serverUri, deviceUri, 157 phoneNumber, syncMLDMBootstrapMessage, info); 158 } 159 160 161 170 public void bootstrapWithDigest(int messageType, 171 int transportType, 172 String info, 173 BootStrap[] bootstrap, 174 boolean updateDeviceInfo) throws NotificationException { 175 176 if (log.isLoggable(Level.INFO)) { 177 log.info("Start bootstrap process in ManagementEngine for " + bootstrap.length + 178 " devices"); 179 } 180 181 String serverUri = config.getStringValue(ConfigurationConstants.CFG_SERVER_URI); 182 183 int numDevices = bootstrap.length; 184 String phoneNumber = null; 185 String username = null; 186 String password = null; 187 String deviceId = null; 188 189 SyncMLDM[] syncMLDMMessages = new SyncMLDM[numDevices]; 190 String applicationInfo = null; 191 192 for (int i = 0; i < numDevices; i++) { 193 verifyBootStrap(bootstrap[i]); 194 195 phoneNumber = bootstrap[i].getMsisdn(); 196 username = bootstrap[i].getUsername(); 197 password = bootstrap[i].getPassword(); 198 deviceId = bootstrap[i].getDeviceId(); 200 if (numDevices == 1) { 201 applicationInfo = info; 202 } else { 203 applicationInfo = info + ":" + phoneNumber; 204 } 205 206 syncMLDMMessages[i] = preBootstrapOperation(deviceId, 208 phoneNumber, 209 username, 210 password, 211 applicationInfo, 212 updateDeviceInfo); 213 } 214 215 NotificationEngine notificationEngine = new NotificationEngineImpl(config); 216 217 notificationEngine.sendBootstrapMessages(messageType, 218 transportType, 219 bootstrap, 220 serverUri, 221 syncMLDMMessages, 222 info); 223 224 } 225 226 236 public void bootstrapWithIMSI(int messageType, 237 int transportType, 238 String info, 239 BootStrap[] bootstrap, 240 boolean updateDeviceInfo) throws NotificationException { 241 242 if (log.isLoggable(Level.INFO)) { 243 log.info("Start bootstrap process in ManagementEngine for " + bootstrap.length + " devices"); 244 } 245 246 String serverUri = config.getStringValue(ConfigurationConstants.CFG_SERVER_URI); 247 248 int numDevices = bootstrap.length; 249 String phoneNumber = null; 250 String username = null; 251 String password = null; 252 String deviceId = null; 253 254 SyncMLDM[] syncMLDMMessage = new SyncMLDM[numDevices]; 255 String applicationInfo = null; 256 for (int i = 0; i < numDevices; i++) { 257 verifyBootStrap(bootstrap[i]); 258 259 phoneNumber = bootstrap[i].getMsisdn(); 260 username = bootstrap[i].getUsername(); 261 password = bootstrap[i].getPassword(); 262 deviceId = bootstrap[i].getDeviceId(); 264 if (numDevices == 1) { 265 applicationInfo = info; 266 } else { 267 applicationInfo = info + ":" + phoneNumber; 268 } 269 270 syncMLDMMessage[i] = preBootstrapOperation(deviceId, 272 phoneNumber, 273 username, 274 password, 275 applicationInfo, 276 updateDeviceInfo); 277 } 278 279 NotificationEngine notificationEngine = new NotificationEngineImpl(config); 280 281 notificationEngine.sendBootstrapMessages(messageType, 282 transportType, 283 bootstrap, 284 serverUri, 285 syncMLDMMessage, 286 info); 287 288 } 289 290 301 public BootStrap[] prepareBootstrap(int messageType, 302 int transportType, 303 String info, 304 BootStrap[] bootstrap, 305 boolean updateDeviceInfo) throws NotificationException { 306 307 if (log.isLoggable(Level.INFO)) { 308 log.info("Generate bootstrap message in ManagementEngine for " + bootstrap.length + " devices"); 309 } 310 311 String serverUri = config.getStringValue(ConfigurationConstants.CFG_SERVER_URI); 312 313 int numDevices = bootstrap.length; 314 String phoneNumber = null; 315 String username = null; 316 String password = null; 317 String deviceId = null; 318 319 SyncMLDM[] syncMLDMMessage = new SyncMLDM[numDevices]; 320 String applicationInfo = null; 321 for (int i = 0; i < numDevices; i++) { 322 verifyBootStrap(bootstrap[i]); 323 324 phoneNumber = bootstrap[i].getMsisdn(); 325 username = bootstrap[i].getUsername(); 326 password = bootstrap[i].getPassword(); 327 deviceId = bootstrap[i].getDeviceId(); 329 if (numDevices == 1) { 330 applicationInfo = info; 331 } else { 332 applicationInfo = info + ":" + phoneNumber; 333 } 334 syncMLDMMessage[i] = preBootstrapOperation(deviceId, 336 phoneNumber, 337 username, 338 password, 339 applicationInfo, 340 updateDeviceInfo); 341 } 342 343 NotificationEngine notificationEngine = new NotificationEngineImpl(config); 344 345 BootStrap[] bootstrapToReturn = 346 notificationEngine.prepareBootstrap(messageType, 347 bootstrap, 348 serverUri, 349 syncMLDMMessage, 350 info); 351 352 return bootstrapToReturn; 353 } 354 355 356 362 public void sendBootstrapWithDigest(int messageType, 363 int transportType, 364 String info, 365 BootStrap[] bootstrap) throws NotificationException { 366 367 if (log.isLoggable(Level.INFO)) { 368 log.info("Send bootstrap message in ManagementEngine for " + bootstrap.length + 369 " devices"); 370 } 371 372 String serverUri = config.getStringValue(ConfigurationConstants.CFG_SERVER_URI); 373 374 int numDevices = bootstrap.length; 375 String [] phoneNumbers = new String [numDevices]; 376 String [] macs = new String [numDevices]; 377 int[] authMethods = new int[numDevices]; 378 byte[][] messages = new byte[numDevices][]; 379 380 for (int i = 0; i < numDevices; i++) { 381 verifyBootStrap(bootstrap[i]); 382 383 phoneNumbers[i] = bootstrap[i].getMsisdn(); 384 messages[i] = bootstrap[i].getBootstrapMessage(); 385 macs[i] = bootstrap[i].getDigest(); 386 authMethods[i] = bootstrap[i].getAuthMethod(); 387 } 388 389 NotificationEngine notificationEngine = new NotificationEngineImpl(config); 390 391 notificationEngine.sendBootstrapMessages(messageType, 392 transportType, 393 phoneNumbers, 394 macs, 395 authMethods, 396 messages, 397 info); 398 399 } 400 401 412 public void sendNotification( int messageType , 413 int transportType, 414 String phoneNumber , 415 String operation , 416 String info ) 417 throws NotificationException { 418 419 if (log.isLoggable(Level.INFO)) { 420 log.info("Executing sendNotification with: " + 421 "\n\tmessageType: " + messageType + 422 "\n\ttransportType: " + transportType + 423 "\n\tphoneNumber: " + phoneNumber + 424 "\n\toperation: " + operation + 425 "\n\tinfo: " + info 426 ); 427 } 428 429 int sessionId = getNextNotificationSessionIds(1)[0]; 430 431 String serverId = config.getStringValue(ConfigurationConstants.CFG_SERVER_ID); 432 433 Sync4jDevice device = getSync4jDevice(phoneNumber); 434 435 if (device == null) { 436 throw new NotificationException("Device with phone number '" + phoneNumber + "' not found"); 437 } 438 439 String serverPassword = device.getServerPassword(); 440 byte[] serverNonce = device.getServerNonce(); 441 442 NotificationEngine notificationEngine = new NotificationEngineImpl(config); 443 444 notificationEngine.sendNotificationMessage( 445 messageType, transportType, sessionId, phoneNumber, 446 info, serverId, serverPassword, serverNonce 447 ); 448 449 DeviceDMState dms = new DeviceDMState(); 457 458 dms.mssid = String.valueOf(sessionId) ; 459 dms.state = DeviceDMState.STATE_NOTIFIED ; 460 dms.start = new Date (System.currentTimeMillis()); 461 dms.operation = operation ; 462 dms.info = info ; 463 dms.deviceId = device.getDeviceId() ; 464 465 storeDeviceDMState(dms); 466 } 467 468 479 public void sendNotification(int messageType , 480 int transportType, 481 String [] phoneNumbers , 482 String operation , 483 String info ) 484 throws NotificationException { 485 486 if (log.isLoggable(Level.INFO)) { 487 log.info("Executing sendNotification to " + phoneNumbers.length + " devices with: " + 488 "\n\tmessageType: " + messageType + 489 "\n\ttransportType: " + transportType + 490 "\n\toperation: " + operation + 491 "\n\tinfo: " + info 492 ); 493 } 494 495 int numDevices = phoneNumbers.length; 496 int[] sessionIds = getNextNotificationSessionIds(numDevices); 497 498 String serverId = config.getStringValue(ConfigurationConstants.CFG_SERVER_ID); 499 500 Sync4jDevice device = null; 501 DeviceDMState dms = null; 502 503 String [] serverPasswords = new String [numDevices]; 504 byte[][] serverNonces = new byte[numDevices][]; 505 for (int i=0; i<numDevices; i++) { 506 507 device = getSync4jDevice(phoneNumbers[i]); 508 509 if (device == null) { 510 throw new NotificationException("Device with phone number '" + phoneNumbers[i] + "' not found"); 511 } 512 513 serverPasswords[i] = device.getServerPassword(); 514 serverNonces[i] = device.getServerNonce(); 515 516 dms = new DeviceDMState(); 524 525 dms.mssid = String.valueOf(sessionIds[i]); 526 dms.state = DeviceDMState.STATE_NOTIFIED; 527 dms.start = new Date (System.currentTimeMillis()); 528 dms.operation = operation; 529 dms.info = info + ":" + phoneNumbers[i]; 530 dms.deviceId = device.getDeviceId(); 531 storeDeviceDMState(dms); 532 } 533 534 NotificationEngine notificationEngine = new NotificationEngineImpl(config); 535 notificationEngine.sendNotificationMessages(messageType, 536 transportType, 537 sessionIds, 538 phoneNumbers, 539 info, 540 serverId, 541 serverPasswords, 542 serverNonces); 543 } 544 545 546 552 public void storeDeviceDMState(DeviceDMState d) { 553 try{ 554 getStore().store(d); 555 } catch (PersistentStoreException e) { 556 if (log.isLoggable(Level.SEVERE)) { 557 log.severe( "Error storing the device DM state " 558 + d.toString() 559 + ": " 560 + e.getMessage() 561 ); 562 log.throwing(getClass().getName(), "storeDeviceDMState", e); 563 } 564 } 565 } 566 567 574 public void readDeviceDMState(DeviceDMState d) 575 throws NotFoundException { 576 WhereClause where = new WhereClause( 577 DeviceDMState.PROPERTY_DEVICE_ID, 578 new String [] { d.deviceId }, 579 WhereClause.OPT_EQ, 580 true 581 ); 582 583 try{ 584 DeviceDMState[] rows = (DeviceDMState[])getStore().read(d, where); 585 586 if (rows.length == 0) { 587 throw new NotFoundException("No device DM state found with deviceId " + d.deviceId ); 588 } 589 590 d.copyFrom(rows[0]); 591 } catch (NotFoundException e) { 592 throw e; 593 } catch (PersistentStoreException e) { 594 if (log.isLoggable(Level.SEVERE)) { 595 log.severe( "Error reading the device DM state " 596 + d.toString() 597 + ": " 598 + e.getMessage() 599 ); 600 log.throwing(getClass().getName(), "storeDeviceDMState", e); 601 } 602 } 603 } 604 605 611 public void deleteDeviceDMState(DeviceDMState d) { 612 try { 613 getStore().delete(d); 614 } catch (PersistentStoreException e) { 615 if (log.isLoggable(Level.SEVERE)) { 616 log.severe( "Error deleting the device DM state " 617 + d.toString() 618 + ": " 619 + e.getMessage() 620 ); 621 log.throwing(getClass().getName(), "storeDeviceDMState", e); 622 } 623 } 624 } 625 626 643 public boolean resolveDMState(DeviceDMState dms, Sync4jDevice deviceConnected) { 644 WhereClause wc1 = new WhereClause( 648 DeviceDMState.PROPERTY_STATE, 649 new String [] { String.valueOf((char)DeviceDMState.STATE_NOTIFIED) }, 650 WhereClause.OPT_EQ, 651 true 652 ); 653 654 WhereClause wc2 = new WhereClause( 655 DeviceDMState.PROPERTY_SESSION_ID, 656 new String [] {dms.mssid}, 657 WhereClause.OPT_EQ, 658 true 659 ); 660 661 LogicalClause select = new LogicalClause( 662 LogicalClause.OPT_AND, 663 new Clause[] {wc1, wc2} 664 ); 665 666 dms.state = DeviceDMState.STATE_NOTIFIED; 667 668 try { 669 DeviceDMState[] rows = (DeviceDMState[])getStore().read(dms, select); 670 671 if (rows.length > 0) { 672 String deviceConnectedId = dms.deviceId; 677 dms.copyFrom(rows[0]); 678 679 if (!dms.deviceId.equalsIgnoreCase(deviceConnectedId)) { 680 Sync4jDevice deviceNotified = new Sync4jDevice(dms.deviceId); 685 686 store.read(deviceNotified); 687 store.read(deviceConnected); 688 689 String descriptionDeviceNotified = deviceNotified.getDescription(); 690 String descriptionDeviceConnected = deviceConnected.getDescription(); 691 692 deviceNotified.setDescription(descriptionDeviceConnected); 693 deviceConnected.setDescription(descriptionDeviceNotified); 694 695 store.store(deviceNotified); 696 store.store(deviceConnected); 697 } 698 dms.deviceId = deviceConnectedId; 699 700 return true; 701 } 702 } catch (PersistentStoreException e) { 703 if (log.isLoggable(Level.SEVERE)) { 704 log.severe("Error reading the device DM state " 705 + dms.toString() 706 + ": " 707 + e.getMessage() 708 ); 709 log.throwing(getClass().getName(), "resolveDMState", e); 710 } 711 712 return false; 713 } 714 715 wc1 = new WhereClause( 719 DeviceDMState.PROPERTY_STATE, 720 new String [] {String.valueOf((char)DeviceDMState.STATE_IN_PROGRESS)}, 721 WhereClause.OPT_EQ, 722 true 723 ); 724 725 wc2 = new WhereClause( 726 DeviceDMState.PROPERTY_DEVICE_ID, 727 new String [] {dms.deviceId}, 728 WhereClause.OPT_EQ, 729 true 730 ); 731 732 select = new LogicalClause( 733 LogicalClause.OPT_AND, 734 new Clause[] { wc1, wc2} 735 ); 736 737 try { 738 DeviceDMState[] rows = (DeviceDMState[])getStore().read(dms, select); 739 740 if (rows.length > 0) { 741 dms.copyFrom(rows[0]); 742 743 return true; 744 } 745 } catch (PersistentStoreException e) { 746 if (log.isLoggable(Level.SEVERE)) { 747 log.severe( "Error reading the device DM state " 748 + dms.toString() 749 + ": " 750 + e.getMessage() 751 ); 752 log.throwing(getClass().getName(), "resolveDMState", e); 753 } 754 } 755 756 return false; 757 } 758 759 761 773 private void completeSyncMLDMBootstrapMessage(SyncMLDM bootstrapMessage, 774 URI serverUri, 775 String serverId, 776 String serverPwd, int serverPort, 777 String username, String password, 778 byte[] serverNonce, byte[] clienteNonce) { 779 780 String host = serverUri.getHost(); 781 String path = serverUri.getPath(); 782 String query = serverUri.getQuery(); 783 784 DMAcc dmAcc = bootstrapMessage.getDmAcc(); 785 Map dmAccounts = dmAcc.getDMAccounts(); 786 787 Iterator keys = dmAccounts.keySet().iterator(); 788 String accountName = (String )keys.next(); 789 790 DMAccount dmAccount = dmAcc.getDMAccount(accountName); 791 792 795 dmAcc.renameDMAccount(accountName, username); 796 797 dmAccount.setServerId(serverId); 798 dmAccount.setServerPassword(serverPwd); 799 dmAccount.setServerNonce(serverNonce); 800 801 dmAccount.setName(username); 802 dmAccount.setUserName(username); 803 dmAccount.setClientPassword(password); 804 dmAccount.setClientNonce(clienteNonce); 805 806 dmAccount.setAddress("http://" + host + path + (query != null ? ("?" + query) : "") ); 807 dmAccount.setAddressType(DEFAULT_ADDRESS_TYPE); 808 809 if (serverPort == -1) { 810 dmAccount.setPortNumber(DEFAULT_PORT_NUMBER); 811 } else { 812 dmAccount.setPortNumber(serverPort); 813 } 814 815 dmAccount.setAuthPref(officer.getAuthType()); 816 } 817 818 832 private Sync4jDevice createSync4jUserDevicePrincipal(String deviceId, 833 String username, 834 String password, 835 String phoneNumber, 836 boolean updateDeviceInfo) 837 throws PersistentStoreException { 838 839 String userDigest = calculateDigest(username, password); 841 842 Sync4jDevice device = new Sync4jDevice(deviceId); 843 boolean deviceFound = false; 844 845 try { 846 readDevice(device); 847 deviceFound = true; 848 } catch (NotFoundException ex) { 849 deviceFound = false; 850 } 851 852 if (!deviceFound) { 853 Sync4jDevice[] devices = getSync4jDevices(phoneNumber); 857 if (devices.length > 0) { 858 for (int i=0; i<devices.length; i++) { 870 getStore().read(devices[i]); 871 devices[i].setDescription(""); 872 getStore().store(devices[i]); 873 } 874 } 875 876 877 SyncUser user = new SyncUser(); 881 user.setUsername(userDigest); 882 user.setPassword(" "); 883 user.setFirstname(""); 884 user.setLastname(phoneNumber); 885 String [] role = {"sync_user"}; 886 user.setRoles(role); 887 dbUserManager.insertUser(user); 888 device = new Sync4jDevice(); 892 device.setDeviceId(deviceId); 893 device.setType("phone"); 894 device.setDescription(phoneNumber); 895 device.setDigest(userDigest); 896 897 byte[] serverNonce = MD5.getNextNonce(); 898 byte[] clientNonce = MD5.getNextNonce(); 899 device.setServerNonce(serverNonce); 900 device.setClientNonce(clientNonce); 901 902 String serverPassword = SecurityTools.getRandomPassword(); 903 device.setServerPassword(serverPassword); 904 905 storeDevice(device); 906 Sync4jPrincipal principal = new Sync4jPrincipal(userDigest, deviceId); 909 getStore().store(principal); 910 return device; 911 } 912 913 917 Sync4jDevice[] devices = getSync4jDevices(phoneNumber); 921 if (devices.length == 1) { 922 Sync4jDevice deviceA = null; 935 Sync4jDevice deviceB = device; 936 937 getStore().read(devices[0]); 938 939 deviceA = devices[0]; 940 941 deviceA.setDescription(deviceB.getDescription()); 944 getStore().store(deviceA); 945 946 } else if (devices.length > 1) { 947 throw new IllegalStateException ("There are more devices with phone number '" + 952 phoneNumber + "' then the swap of this is not possible"); 953 } 954 955 956 if (updateDeviceInfo) { 957 byte[] serverNonce = MD5.getNextNonce(); 958 byte[] clientNonce = MD5.getNextNonce(); 959 device.setServerNonce(serverNonce); 960 device.setClientNonce(clientNonce); 961 962 String serverPassword = SecurityTools.getRandomPassword(); 963 device.setServerPassword(serverPassword); 964 } 965 966 if (!phoneNumber.equals(device.getDescription()) || updateDeviceInfo) { 967 device.setDescription(phoneNumber); 973 storeDevice(device); 974 } 975 976 977 String deviceDigest = device.getDigest(); 978 979 if (StringUtils.equals(deviceDigest, userDigest)) { 983 return device; 984 } 985 986 996 device.setDigest(userDigest); 1000 storeDevice(device); 1001 1002 SyncUser user = new SyncUser(); 1006 user.setUsername(userDigest); 1007 user.setPassword(" "); 1008 user.setFirstname(""); 1009 user.setLastname(phoneNumber); 1010 String [] role = {"sync_user"}; 1011 user.setRoles(role); 1012 dbUserManager.insertUser(user); 1013 1014 Sync4jPrincipal principal = new Sync4jPrincipal(userDigest, deviceId); 1018 getStore().store(principal); 1019 1020 Sync4jPrincipal previousPrincipal = new Sync4jPrincipal(deviceDigest, deviceId); 1024 getStore().read(previousPrincipal); 1025 getStore().delete(previousPrincipal); 1026 1027 WhereClause wc1 = new WhereClause( 1031 Sync4jPrincipal.PROPERTY_USERNAME, 1032 new String [] { deviceDigest }, 1033 WhereClause.OPT_EQ, 1034 true 1035 ); 1036 1037 Sync4jPrincipal[] principals = (Sync4jPrincipal[])(getStore().read(principal, wc1)); 1038 1039 if (principals.length == 0) { 1040 SyncUser previousUser = new SyncUser(); 1044 previousUser.setUsername(deviceDigest); 1045 dbUserManager.deleteUser(previousUser); 1046 } 1047 return device; 1048 } 1049 1050 1058 private String calculateDigest(String username, String password) { 1059 String cred = username + ":" + password; 1060 1061 byte[] md5 = null; 1062 1063 md5 = MD5.digest(cred.getBytes()); 1065 byte[] digest = Base64.encode(md5); 1066 1067 return new String (digest); 1068 } 1069 1070 1076 private Sync4jDevice getSync4jDevice(String phoneNumber) throws NotificationException { 1077 1078 Clause clause = new WhereClause(Sync4jDevice.PROPERTY_DESCRIPTION, 1080 new String [] {phoneNumber}, 1081 WhereClause.OPT_EQ, 1082 true); 1083 1084 Sync4jDevice[] devices = null; 1085 1086 1087 try { 1088 devices = (Sync4jDevice[]) getStore().read(new Sync4jDevice(), clause); 1090 1091 } catch (PersistentStoreException e) { 1092 throw new NotificationException("Unable to get device information", e); 1093 } 1094 1095 if (devices == null) { 1096 return null; 1097 } else if (devices.length == 0) { 1098 throw new NotificationException("Device with phone number '" + phoneNumber + "' not found"); 1099 } else if (devices.length > 1) { 1100 throw new NotificationException("There are more devices with the same phone number [" + phoneNumber + "]"); 1101 } 1102 1103 try { 1104 readDevice(devices[0]); 1106 1107 } catch (PersistentStoreException e) { 1108 throw new NotificationException("Unable to get device information", e); 1109 } 1110 1111 return devices[0]; 1112 } 1113 1114 1119 private Sync4jDevice[] getSync4jDevices(String phoneNumber) throws PersistentStoreException { 1120 1121 Clause clause = new WhereClause(Sync4jDevice.PROPERTY_DESCRIPTION, 1123 new String [] {phoneNumber}, 1124 WhereClause.OPT_EQ, 1125 true); 1126 1127 Sync4jDevice[] devices = null; 1128 1129 devices = (Sync4jDevice[]) getStore().read(new Sync4jDevice(), clause); 1131 1132 return devices; 1133 } 1134 1135 1152 private SyncMLDM preBootstrapOperation(String deviceId, 1153 String phoneNumber, 1154 String username, 1155 String password, 1156 String info, 1157 boolean updateDeviceInfo) throws NotificationException { 1158 1159 ClassLoader classLoader = config.getClassLoader(); 1161 1162 SyncMLDM syncMLDMBootstrapMessage = null; 1163 1164 try { 1165 syncMLDMBootstrapMessage = 1166 (SyncMLDM)BeanFactory.getBeanInstance(classLoader, SYNCML_DM_BOOTSTRAP_MESSAGE); 1167 } catch (Exception ex) { 1168 log.throwing(getClass().getName(), "bootstrap", ex); 1169 throw new NotificationException("Error reading bootstrap message", ex); 1170 } 1171 1172 1177 Sync4jDevice device = null; 1179 1180 try { 1181 device = createSync4jUserDevicePrincipal(deviceId, 1182 username, 1183 password, 1184 phoneNumber, 1185 updateDeviceInfo); 1186 } catch (PersistentStoreException e) { 1187 log.throwing("ManagementEngine", "bootstrap", e); 1188 throw new NotificationException("Error during store sync object", e); 1189 } 1190 1191 try { 1192 createDMStateToExecuteAfterBootstrap(deviceId, info); 1193 } catch (PersistentStoreException e) { 1194 log.throwing("ManagementEngine", "bootstrap", e); 1195 throw new NotificationException("Error during create dmstate", e); 1196 } 1197 1198 byte[] serverNonce = device.getServerNonce(); 1199 byte[] clientNonce = device.getClientNonce(); 1200 1201 String serverUri = config.getStringValue(ConfigurationConstants.CFG_SERVER_URI); 1202 1203 int serverPort = -1; 1204 1205 URI uri = null; 1206 1207 try { 1208 uri = new URI (serverUri); 1209 serverPort = uri.getPort(); 1210 } catch (URISyntaxException e) { 1211 throw new NotificationException("The server uri isn't a valid uri", e); 1212 } 1213 1214 String serverId = config.getStringValue(ConfigurationConstants.CFG_SERVER_ID); 1215 String serverPassword = device.getServerPassword(); 1216 1217 completeSyncMLDMBootstrapMessage(syncMLDMBootstrapMessage, 1218 uri, 1219 serverId, 1220 serverPassword, 1221 serverPort, 1222 username, 1223 password, 1224 serverNonce, 1225 clientNonce); 1226 1227 return syncMLDMBootstrapMessage; 1228 } 1229 1230 1237 private synchronized int[] getNextNotificationSessionIds(int numOfSessionsId) 1238 throws NotificationException { 1239 1240 int counter = 0; 1241 try { 1242 counter = getStore().readCounter(NS_MSSID, numOfSessionsId); 1243 } catch (PersistentStoreException ex) { 1244 throw new NotificationException("Error reading session ids"); 1245 } 1246 1247 int[] sessionIds = new int[numOfSessionsId]; 1248 for (int i = 0; i<numOfSessionsId; i++) { 1249 sessionIds[i] = (counter + i) & 0xffff; } 1251 return sessionIds; 1252 } 1253 1254 1259 private void verifyBootStrap(BootStrap bootstrap) throws NotificationException { 1260 1261 if (bootstrap == null) { 1262 throw new NotificationException( 1263 "Unable to send the bootstrap (is null)"); 1264 } 1265 1266 String imsi = bootstrap.getImsi(); 1267 String userPin = bootstrap.getUserPin(); 1268 int authMethod = bootstrap.getAuthMethod(); 1269 String digest = bootstrap.getDigest(); 1270 1271 if (StringUtils.isNotEmpty(digest)) { 1272 return; 1273 } 1274 1275 if (authMethod == NotificationConstants.AUTH_METHOD_NETWPIN) { 1276 if (StringUtils.isEmpty(imsi)) { 1277 throw new NotificationException( 1278 "Imsi can't be null using NETWPIN authentication method"); 1279 } 1280 } else if (authMethod == NotificationConstants.AUTH_METHOD_USERPIN) { 1281 if (StringUtils.isEmpty(userPin) && StringUtils.isEmpty(imsi)) { 1282 throw new NotificationException( 1283 "Userpin or imsi must be not null using USERPIN authentication method"); 1284 } 1285 } else if (authMethod == NotificationConstants.AUTH_METHOD_USERNETWPIN) { 1286 if (StringUtils.isEmpty(imsi)) { 1287 throw new NotificationException( 1288 "Imsi can't be null using USERNETWPIN authentication method"); 1289 } 1290 1291 if (StringUtils.isEmpty(userPin)) { 1292 throw new NotificationException( 1293 "Userpin can't be null using USERNETWPIN authentication method"); 1294 } 1295 } 1296 } 1297 1298 1302 private void createDMStateToExecuteAfterBootstrap(String deviceId, String info) throws 1303 PersistentStoreException { 1304 1305 DeviceDMState dmState = new DeviceDMState(); 1306 dmState.deviceId = deviceId; 1307 dmState.state = DeviceDMState.STATE_IN_PROGRESS; 1308 dmState.operation = OPERATION_AFTER_BOOTSTRAP; 1309 dmState.info = info; 1310 store.store(dmState); 1311 1312 } 1313 1314} | Popular Tags |