Comment accéder à l'interface CORBA sans IDL ou méthodes de télévision invoquées en fin de fin

StackOverflow https://stackoverflow.com/questions/6031381

Question

Nous utilisons un «pont de licence SAP» SAP pour accéder à leur serveur de licences et interroger la clé matérielle d'un système par programme (pour réutiliser sans propre licence). Cela a bien fonctionné sur SAP Business One Versions 2007a, 2007b et 8.8, mais en 8.81, ils semblent avoir mis à jour leur interface CORBA sans mettre à jour le COM Wrapper, car nous obtenons maintenant des exceptions de mémoire lors de la tentative d'appel de la fonction GethardwareKey.

J'ai donc téléchargé iiop.net et j'ai commencé à essayer d'écrire ma propre interface. Je n'ai jamais aimé ce com wrapper de toute façon. Mais j'ai rencontré mon ancien ennemi juré de .NET à distance - l'incapacité d'invoquer une méthode distante sans avoir une interface commune définie à la fois dans le serveur et le client. J'ai essayé d'utiliser le compilateur IDL vers CLS inclus avec iiop.net, mais je continue à obtenir des erreurs sur l'interface Beign incompatible (SAP n'a pas fourni de fichier IDL). Je ne sais pas comment IIOP et Corba déterminent si une interface est compatible. Mais j'ai même essayé de déboguer dans le code IIOP.net et de le forcer à exécuter la méthode malgré l'incompatibilité, mais j'ai reçu une chaîne vide au lieu de la clé matérielle que je voulais.

Ma prochaine étape consiste à essayer de mettre en œuvre un faux serveur de licences et à examiner les demandes provenant du client de production dans l'espoir d'identifier ce qu'ils devrait Ressemble, mais je ne compte pas sur beaucoup de succès compte tenu de la difficulté que j'ai eu en regardant déjà dans les entrailles de .NET à distance.

Mon vrai problème est de savoir comment obtenir ou générer la clé de matériel SAP Business One, mais les questions découlant de celles-ci incluent:

  1. Comment réfléchir ou interroger les informations sur une interface CORBA? Je peux utiliser la méthode de liste de la classe NamingContext pour récupérer une liste des objets disponibles, mais je ne vois pas s'il existe un moyen de remettre en question les méthodes disponibles sur un objet.
  2. Puis-je invoquer dynamiquement des méthodes de télécommande .NET sans avoir d'interface? Je vois qu'il y a quelque chose appelé DII pour invoquer dynamiquement Corba, mais je ne vois pas comment l'utiliser à partir de iiop.net.
  3. Puis-je invoquer des méthodes de télécommande .NET avec juste une interface déléguée ou incomplète? J'ai essayé d'utiliser le mot-clé dynamique, mais il n'a pas pu invoquer une méthode sur mon objet distant Marshalbyref ... Je pense qu'il a dit que la méthode n'existait pas sur mon instance Marshalbyref ou quelque chose. Je n'ai cependant essayé que via iiop.net (je me demande si cela fonctionne pour le télécommande .NET normal).
  4. Comment créer ou inspecter les instances de message dans le framework éloigné .NET?
  5. Puis-je envoyer ou récupérer directement les messages à distance, en contournant les proxys sous-jacents?

Éditer: J'ai réussi à faire croire iiop.net / corba que j'avais une interface compatible en appliquant l'attribut RepositoryId:

[Ch.Elca.Iiop.Idl.InterfaceType(Ch.Elca.Iiop.Idl.IdlTypeInterface.ConcreteInterface)]
[Ch.Elca.Iiop.Idl.RepositoryID("IDL:LicenseInfo:1.0")]
public interface ILicenseInfo : Ch.Elca.Iiop.Idl.IIdlEntity
{
    void GetHardwareKey(out string hwKey);
}

Mais je reçois toujours un résultat de chaîne vide.

Edit 2: Après un peu plus d'expérimentation et de débogage, j'ai constaté que les messages de réponse contiennent les données que je recherche, mais ne sont pas analysées correctement dans les valeurs du client, probablement en raison de ma mauvaise définition d'interface. En espérant que le débogage dans le traitement de la réponse m'aidera à déterminer comment corriger mon interface. Étrangement, la première chose qu'il analyse la réponse est une valeur en boîte nulle, ce qui ne semble pas juste pour un paramètre "string".

Edit 3: J'ai trouvé que je dois appliquer des attributs de chaîne aux paramètres comme celui-ci pour les empêcher d'être traités comme des valeurs en boîte:

void GetHardwareKey([StringValue(), WideChar(true)] out string hwKey);

Mais malgré l'attribut widEchar, je reçois une erreur sur le codet ne prend pas en charge WCHAR ou quelque chose. Je suis en train vraiment près de comprendre cela.

Edit 4: Je suis perplexe sur la façon de définir l'ensemble de codes pour WCHAR. Si je ne le définis pas, je reçois une erreur: "WCHAD CODENET NON SPÉCIFIÉS OU NON PRIS APPARIÉ." Parce que le serveur a renvoyé une chaîne Unicode sans remplacer le jeu de caractères par défaut. Je ne trouve aucun moyen de remplacer cela du client. J'ai essayé d'appeler:

omg.org.CORBA.OrbServices.GetSingleton().OverrideDefaultCharSets(
    CharSet.UTF8, WCharSet.UTF16);

Mais cela ne semble pas avoir d'effet sur le client. L'exemple de code montre l'appel à l'extrémité du serveur. Mais je n'ai pas écrit le serveur, donc je ne peux pas contrôler cela. Est-ce que ma seule option pour réécrire le code IIOP.NET à mes propres fins forçant un ensemble de codes WCHA par défaut pour entrer en vigueur?

Était-ce utile?

La solution

Après 3 jours de débogage dans IIOP pour retrouver son comportement et inspecter les données qui reviennent dans la réponse, j'ai réglé cette solution.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using omg.org.CosNaming;
using Ch.Elca.Iiop;
using Ch.Elca.Iiop.Services;
using System.Runtime.Remoting.Channels;
using Ch.Elca.Iiop.Idl;

[RepositoryID("IDL:LicenseInfo:1.0")]
public interface ILicenseInfo
{
    Int32 GetHardwareKey([IdlSequence(0)] out byte[] hwKey);
    Int32 GetInstallationNumberList([IdlSequence(0)] out byte[] instNum);
}

class Program
{
    static void Main(string[] args)
    {
        IiopClientChannel channel = new IiopClientChannel();
        ChannelServices.RegisterChannel(channel, false);
        CorbaInit init = CorbaInit.GetInit();
        NamingContext context = init.GetNameService("MYLICSRV", 30000);
        NameComponent[] names = new NameComponent[] { new NameComponent("B1LicenseInfo") };
        ILicenseInfo li = (ILicenseInfo)context.resolve(names);
        byte[] hwKey;
        byte[] instNum;
        li.GetHardwareKey(out hwKey);
        li.GetInstallationNumberList(out instNum);
        Encoding encoding = new System.Text.UnicodeEncoding(false, false, true);
        Console.WriteLine(encoding.GetString(hwKey));
        Console.WriteLine(encoding.GetString(instNum));
    }
}

J'utilisais temporairement cela dans une tentative de faire en sorte que IIOP me donne les bonnes cordes. S'il m'était venu à l'esprit que je pouvais simplement accepter la réponse en tant que tableau d'octets et effectuer le décodage moi-même, je n'aurais pas perdu la moitié du temps à essayer de comprendre comment obtenir IIOP pour comprendre comment je voulais que ma chaîne revienne:

class MyOrbInitializer : omg.org.PortableInterceptor.ORBInitializer
{
    public void post_init(omg.org.PortableInterceptor.ORBInitInfo info)
    {
        // Nothing to do
    }

    public void pre_init(omg.org.PortableInterceptor.ORBInitInfo info)
    {
        omg.org.IOP.Codec codec = info.codec_factory.create_codec(
            new omg.org.IOP.Encoding(omg.org.IOP.ENCODING_CDR_ENCAPS.ConstVal, 1, 2));
        Program.m_codec = codec;
    }
}


class Program
{
    public static omg.org.IOP.Codec m_codec;

    static void Main(string[] args)
    {
        IOrbServices orb = OrbServices.GetSingleton();
        orb.OverrideDefaultCharSets(CharSet.UTF8, WCharSet.UTF16);
        orb.RegisterPortableInterceptorInitalizer(new MyOrbInitializer());
        orb.CompleteInterceptorRegistration();
...
        MarshalByRefObject objRef = context.resolve(names);
        string origObjData = orb.object_to_string(objRef);
        Ch.Elca.Iiop.CorbaObjRef.Ior iorObj = new Ch.Elca.Iiop.CorbaObjRef.Ior(origObjData);
        CodeSetComponentData cscd = new CodeSetComponentData(
            (int)Ch.Elca.Iiop.Services.CharSet.UTF8,
            new int[] { (int)Ch.Elca.Iiop.Services.CharSet.UTF8 },
            (int)Ch.Elca.Iiop.Services.WCharSet.UTF16,
            new int[] { (int)Ch.Elca.Iiop.Services.WCharSet.UTF16 });
        omg.org.IOP.TaggedComponent codesetcomp = new omg.org.IOP.TaggedComponent(
            omg.org.IOP.TAG_CODE_SETS.ConstVal, m_codec.encode_value(cscd));
        iorObj.Profiles[0].TaggedComponents.AddComponent(codesetcomp);
        string newObjData = iorObj.ToString();
        MarshalByRefObject newObj = (MarshalByRefObject)orb.string_to_object(newObjData);
        ILicenseInfo li = (ILicenseInfo)newObj;
...
    }

Après que beaucoup de code fonctionnent, j'avais un objet qui définirait l'ensemble de codes WCHAR afin qu'il analyse correctement les chaînes de retour, en évitant l'erreur "WCHAR CODEDET non spécifiée ou non prise en charge". Mais après tout cela, l'ordre des octets Unicode était aussi en arrière! Et la seule façon de résoudre ce problème, pour autant que je sache, était de rediffuser la chaîne en octets puis de revenir dans une chaîne Unicode. Mais c'est à ce moment-là que cela m'est venu à l'esprit, pourquoi même demander le résultat en tant que chaîne !? Je pourrais simplement prendre les octets directement et éviter une grande partie de cette complication. J'aurais aimé y avoir pensé plus tôt.

Autres conseils

SAP BO 882 //LICENNEINTERFACE.IDL

typedef sequence<octet> LicenseFileData;

interface LicenseInfo
{
  boolean IsUserLicensed(in wstring wstrUser, in wstring wstrModule, in wstring wstrInstallNo);
  long GetHardwareKey(out wstring pbstrHK);
  long GetInstallationNumberList(out wstring wbstrInstNum);
  long GetSystemNumber(out wstring wbstrSysNum, in wstring wstrInstallNo);
  long GetLicenseInfo(in wstring wstrModule, out long lNum, out long lAvailable, out long lStart, out long lEnd, in wstring wstrInstallNo);
  long GetLoggedInUsers(out wstring wbstrLogUsers);
  long StartLogging();
  long StopLogging();
  long GetLicenseNum(in wstring wstrKey, in wstring wstrInstallNo);
  long GetLogFileName(out wstring wstrLogFileName);
  boolean GetIsLogging();
  long LoadLicenseFile (in LicenseFileData arg_licenseFileData);
  boolean IsLicenseFileExist();
  long ResetAllLicenses();
  long GetVersion(out wstring sVersion);
  //long DeleteLicenseFile (in wstring wstrInstallNo);
};

Sbolinse.idl

typedef sequence<octet> usBuffer;

enum LicenseClientUTFType {LIC_UTF16 , LIC_UTF32};

exception NotAuthenticated {};
exception UserNotConnected {};

interface LicenseServer
{
    long SBOConnect (in usBuffer User, in usBuffer Company, in usBuffer PCName, out usBuffer SessionE, in long lDate, in usBuffer sInstallNo) raises(NotAuthenticated);
    long AddOnGetLicense (in usBuffer Identifier, in usBuffer User, in usBuffer Company, in usBuffer PCName, out long plSessionID, out usBuffer SessionE, in long lDate, in usBuffer sInstallNo) raises(NotAuthenticated);
    long PollSession (in usBuffer User, in usBuffer SIDs, out usBuffer RetE) raises(NotAuthenticated);
    long SessionsInfo (in usBuffer User, in usBuffer SessionsInfo, out usBuffer SessionsInfoE, in long lDate) raises(NotAuthenticated);
    long SessionVerify (in usBuffer User, in long lSessionID, out usBuffer pSessionIdE) raises(NotAuthenticated);
    long CloseSession (in usBuffer User, in long lSessionId) raises(NotAuthenticated);
    long LockServer (in usBuffer User, in long lSessionID) raises(NotAuthenticated);
    long UnLockServer (in usBuffer User, in long lSessionID) raises(NotAuthenticated);
    long GetUserLicenseInfo (in usBuffer User, out usBuffer pModules, out boolean pbIsConnected) raises(NotAuthenticated);
    long GetAllModulesStatus (out usBuffer pModulesInfo) raises(NotAuthenticated);
    long LoadLicenseFile (in usBuffer NewLicenseFile) raises(NotAuthenticated);
    long GetHardwareKey (out usBuffer pHK) raises(NotAuthenticated);
    long CreateIdentifier (in usBuffer Addon, out usBuffer pIdentifier, in usBuffer sInstallNo) raises(NotAuthenticated);
    long GetAllUsersLicenseInfo(out usBuffer pUsersLicInfo) raises(NotAuthenticated);
    long SetAllUsersLicenseInfo(in usBuffer User, in usBuffer UsersLicInfo, out usBuffer pConnectedUser) raises(NotAuthenticated,UserNotConnected);
    long IsDevExist (in usBuffer sInstallNo);
    long GetInstallationNumberList(out usBuffer pInstNum);
    long GetSystemNumber (out usBuffer pSysNum, in usBuffer sInstallNo);
    long GetFutureExpired(in long lFutureDate, out usBuffer pModules, in usBuffer sInstallNo);
    long GetUserSessionsInfo(in usBuffer UserName,out usBuffer pRsltSessionsInfo);
    long GetBIGSLicense (in usBuffer User, in usBuffer Company, in usBuffer PCName, in long lNum, out usBuffer pSessionsE, in long lDate, in usBuffer sInstallNo) raises(NotAuthenticated);
    boolean IsLicenseFileExist();
    long GetVersion(out usBuffer sVersion);
    long ClearUserLicenses (in usBuffer User) raises(NotAuthenticated);
    long UpdateUserLicenses (in usBuffer User, out usBuffer ModulesE, in long lDate, in long lSessionID, in usBuffer sCmpLocalization, in usBuffer sCmpVersion) raises(NotAuthenticated);
    long RequestNamedLicenses (in usBuffer User, out usBuffer ModulesE, in long lDate, in long lSessionID, in usBuffer sCmpLocalization, in usBuffer sCmpVersion) raises(NotAuthenticated);
    long IsLicenseConcurrent () raises(NotAuthenticated);
    long GetLicenseFileGenInfo(in usBuffer sInstallNo, out usBuffer sLicGenInfo);
    //long DeleteLicenseFile (in usBuffer sInstallNo) raises(NotAuthenticated);

    long HandShake(in long algorithm, in usBuffer publicKey, out usBuffer sessionKey) raises(NotAuthenticated);
    long GetCompanyDBCredentials(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword, out boolean useTrusted) raises(NotAuthenticated);
    long GetDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword, out boolean useTrusted) raises(NotAuthenticated);
    long GetCompanyReadOnlyDBCredentials(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword) raises(NotAuthenticated);
    long GetReadOnlyDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, out usBuffer dbUser, out usBuffer dbPassword) raises(NotAuthenticated);
    long GetListOfCompanies(in long dbType, in usBuffer server, in boolean refresh, out usBuffer listOfCompanies);
    long GetCompanyEncryptionConfig(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out long algorithm, out usBuffer keyId, out usBuffer key) raises(NotAuthenticated);
    long GetEncryptionConfig(in usBuffer siteUser, in usBuffer password, out long algorithm,  out usBuffer keyId, out usBuffer key) raises(NotAuthenticated);
    long SetDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, in usBuffer dbUser, in usBuffer dbPassword, in boolean useTrusted) raises(NotAuthenticated);
    long RemoveDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password) raises(NotAuthenticated);
    long GetServerVersion(in long dbType, in usBuffer server, out usBuffer version, in usBuffer commonDBName);
    long SetReadOnlyDBCredentials(in long dbType, in usBuffer server, in usBuffer siteUser, in usBuffer password, in usBuffer dbUser, in usBuffer dbPassword) raises(NotAuthenticated);
    long SetEncryptionAlghorithm(in usBuffer siteUser, in usBuffer password, in long algorithm) raises(NotAuthenticated);
    long GenerateEncryptionKey(in usBuffer siteUser, in usBuffer password) raises(NotAuthenticated);
    long GetServicesUserCredentials(in usBuffer siteUser, in usBuffer password, out usBuffer servicesUser, out usBuffer servicesPassword) raises(NotAuthenticated);
    long ExportSecuritySettings(in usBuffer siteUser, in usBuffer password, out usBuffer xmlSettings) raises(NotAuthenticated);
    long ImportSecuritySettings(in usBuffer siteUser, in usBuffer password, in usBuffer xmlSettings) raises(NotAuthenticated);
    long GetListOfConfiguredServers(out usBuffer listOfServers);
    long GetSiteUserName(out usBuffer siteUser);
    long AuthenticateSiteUser(in usBuffer siteUser, in usBuffer password, out boolean result) raises(NotAuthenticated);
    long AuthenticateServicesUser(in usBuffer siteUser, in usBuffer password, out boolean result) raises(NotAuthenticated);
    long ChangeSiteUserPassword(in usBuffer siteUser, in usBuffer oldPassword, in usBuffer password) raises(NotAuthenticated);
    long ChangeSiteUserPasswordByDB(in long dbType, in usBuffer server, in usBuffer dbUser, in usBuffer dbPassword, in usBuffer password) raises(NotAuthenticated);
    long GetCompanyStaticKey(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, out usBuffer key) raises(NotAuthenticated);
    long GetStaticKey(in usBuffer siteUser, in usBuffer password, out usBuffer key) raises(NotAuthenticated);
    long GetEncryptionAlgorithm(out long algorithm);
    long IsNTTrusted(in long dbType, in usBuffer server, out boolean isNTTrusted);
    long IsDKeyUsed(out boolean result);
    long ExportDKeys(in usBuffer siteUser, in usBuffer password, out usBuffer xmlDKeys) raises(NotAuthenticated);
    long ImportDKeys(in usBuffer siteUser, in usBuffer password, in usBuffer xmlDKeys) raises(NotAuthenticated);
    long GenerateDKey(in usBuffer siteUser, in usBuffer password, out usBuffer xmlDKeys) raises(NotAuthenticated);
    long EnableDKey(in usBuffer siteUser, in usBuffer password, out usBuffer xmlDKeys) raises(NotAuthenticated);
    long GetCompanyKeyAndKeyState(in long dbType, in usBuffer server, in usBuffer company, in usBuffer user, in usBuffer password, in usBuffer compKeyId, out long keyState, out usBuffer compKey)raises(NotAuthenticated);
    long GetKeyAndKeyState(in usBuffer siteUser, in usBuffer password, in usBuffer compKeyId, out long keyState, out usBuffer compKey)raises(NotAuthenticated);

};

interface LicenseServerFactory
{
  LicenseServer GetLicenseServer(in LicenseClientUTFType ClientUTFType);
};
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top