source: trunk/CrypPlugins/PeerToPeerManager_NEW/P2PManager_KeyPattern.cs @ 1173

Last change on this file since 1173 was 1173, checked in by arnold, 12 years ago

some bug fixes.

File size: 22.0 KB
Line 
1/* Copyright 2010 Team CrypTool (Christian Arnold), Uni Duisburg-Essen
2
3   Licensed under the Apache License, Version 2.0 (the "License");
4   you may not use this file except in compliance with the License.
5   You may obtain a copy of the License at
6
7       http://www.apache.org/licenses/LICENSE-2.0
8
9   Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14*/
15
16using System;
17using System.Collections.Generic;
18using System.Linq;
19using System.Text;
20using System.Threading;
21using Cryptool.PluginBase;
22using Cryptool.PluginBase.IO;
23using Cryptool.PluginBase.Control;
24using Cryptool.PluginBase.Miscellaneous;
25using System.ComponentModel;
26using KeySearcher;
27using System.Windows.Controls;
28using System.Windows.Threading;
29using Cryptool.Plugins.PeerToPeer.Jobs;
30
31/*TODO:
32 * - Execute: If InitVector is null, try to create a fitting InitVector with the format 0...0
33 * - No linebreaks in the global result list
34 * - 2 Output values (Top1-Key and Top1-Decryption)
35 * - Display the job stati in a kind of a defragmentation list
36 */
37
38namespace Cryptool.Plugins.PeerToPeer
39{
40    /// <summary>
41    /// This PlugIn only works, when its connected with a P2P_Peer object.
42    /// </summary>
43    [Author("Christian Arnold", "arnold@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
44    [PluginInfo(false, "P2P_Manager_KeyPattern", "Creates a new Manager-Peer for distributable KeyPattern-Jobs", "", "PeerToPeerManager_NEW/manager_medium_neutral.png", "PeerToPeerManager_NEW/manager_medium_working.png", "PeerToPeerManager_NEW/manager_medium_finished.png")]
45    public class P2PManager_KeyPattern : IInput
46    {
47        private P2PManagerBase_NEW p2pManager;
48        private P2PManager_KeyPatternSettings settings;
49        // IInput
50        private CryptoolStream decryptedData;
51        private byte[] initVector;
52        // IControls       
53        private IControlEncryption encryptionControl;
54        private IP2PControl p2pControl;
55
56        private KeyPattern pattern = null;
57        public KeyPattern Pattern
58        {
59            get
60            {
61                return pattern;
62            }
63            set
64            {
65                pattern = value;
66                if ((settings.Key == null) || ((settings.Key != null) && !pattern.testWildcardKey(settings.Key)))
67                    settings.Key = pattern.giveInputPattern();
68            }
69        }
70
71        /// <summary>
72        /// after starting the execution, set this value, so after receiving
73        /// a Job result, the WPF UpdateQuickWatch can use this value, without
74        /// accessing the Settings every time.
75        /// </summary>
76        private int bytesToUseForDecryption = 0;
77
78        #region In and Output
79
80        [PropertyInfo(Direction.InputData, "Encrypted Data", "Encrypted data out of an Encryption PlugIn", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, "")]
81        public CryptoolStream DecryptedData
82        {
83            get { return this.decryptedData; }
84            set
85            {
86                if (value != this.decryptedData)
87                {
88                    this.decryptedData = value;
89                }
90            }
91        }
92
93        [PropertyInfo(Direction.InputData, "Initialization Vector", "Initialization vector with which the data were encrypted", "", DisplayLevel.Beginner)]
94        public byte[] InitVector
95        {
96            get { return this.initVector; }
97            set
98            {
99                if (value != this.initVector)
100                    this.initVector = value;
101            }
102        }
103
104        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
105        public IControlEncryption EncryptionControl
106        {
107            get { return this.encryptionControl; }
108            set
109            {
110                if (this.encryptionControl != null)
111                {
112                    this.encryptionControl.keyPatternChanged -= encryptionControl_keyPatternChanged;
113                    this.encryptionControl.OnStatusChanged -= encryptionControl_onStatusChanged;
114                }
115                if (value != null)
116                {
117                    Pattern = new KeyPattern(value.getKeyPattern());
118                    value.keyPatternChanged += encryptionControl_keyPatternChanged;
119                    value.OnStatusChanged += encryptionControl_onStatusChanged;
120                    this.encryptionControl = value;
121                    OnPropertyChanged("ControlMaster");
122
123                }
124                else
125                    this.encryptionControl = null;
126            }
127        }
128
129        private void encryptionControl_keyPatternChanged()
130        {
131            Pattern = new KeyPattern(this.encryptionControl.getKeyPattern());
132        }
133        private void encryptionControl_onStatusChanged(IControl sender, bool readyForExecution)
134        {
135            // obsolete stuff
136            if (readyForExecution)
137            {
138                this.process((IControlEncryption)sender);
139            }
140        }
141
142        /// <summary>
143        /// Catches the completely configurated, initialized and joined P2P object from the P2PPeer-Slave-PlugIn.
144        /// </summary>
145        [PropertyInfo(Direction.ControlMaster, "P2P Slave", "Input the P2P-Peer-PlugIn", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
146        public IP2PControl P2PControl
147        {
148            get
149            {
150                return this.p2pControl;
151            }
152            set
153            {
154                if (this.p2pControl != null)
155                {
156                    this.p2pControl.OnStatusChanged -= P2PControl_OnStatusChanged;
157                }
158                if (value != null)
159                {
160                    this.p2pControl = (P2PPeerMaster)value;
161                    this.p2pControl.OnStatusChanged += new IControlStatusChangedEventHandler(P2PControl_OnStatusChanged);
162                    OnPropertyChanged("P2PMaster");
163                }
164                else
165                {
166                    this.p2pControl = null;
167                }
168            }
169        }
170
171        private void P2PControl_OnStatusChanged(IControl sender, bool readyForExecution)
172        {
173            //throw new NotImplementedException();
174        }
175
176        #endregion
177
178        #region Events
179
180        public event StatusChangedEventHandler OnPluginStatusChanged;
181
182        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
183
184        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
185
186        #endregion
187
188        #region Standard PlugIn-Functionality
189
190        public P2PManager_KeyPattern()
191        {
192            this.settings = new P2PManager_KeyPatternSettings();
193            this.settings.PropertyChanged += new PropertyChangedEventHandler(settings_PropertyChanged);
194            this.settings.TaskPaneAttributeChanged += new TaskPaneAttributeChangedHandler(settings_TaskPaneAttributeChanged);
195            this.settings.OnPluginStatusChanged += new StatusChangedEventHandler(settings_OnPluginStatusChanged);
196
197            QuickWatchPresentation = new P2PManagerPresentation();
198        }
199
200        #region QuickWatchPresentation Stuff
201
202        public UserControl QuickWatchPresentation
203        {
204            get;
205            private set;
206        }
207
208        public UserControl Presentation
209        {
210            get { return QuickWatchPresentation; }
211        }
212
213        private void UpdateQuickWatch(double progressInPercent)
214        {
215            UpdateQuickWatch(this.distributableKeyPatternJob.GlobalResultList, this.distributableKeyPatternJob.TotalAmount,
216                this.distributableKeyPatternJob.AllocatedAmount, this.distributableKeyPatternJob.FinishedAmount, 
217                progressInPercent, this.p2pManager.FreeWorkers(), this.p2pManager.BusyWorkers());
218        }
219
220        private void UpdateQuickWatch(LinkedList<KeySearcher.KeySearcher.ValueKey> globalTop10List,
221            BigInteger jobsTotalAmount, BigInteger jobsInProgress, BigInteger jobsFinished, double progressInPercent,
222            int freeWorkers, int busyWorkers)
223        {
224            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
225            LinkedListNode<KeySearcher.KeySearcher.ValueKey> listNode;
226
227            if (QuickWatchPresentation.IsVisible)
228            {
229                ((P2PManagerPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
230                {
231                    ((P2PManagerPresentation)QuickWatchPresentation).txtProgressInPercent.Text = "" + Math.Round(progressInPercent, 2) + "%";
232                    ((P2PManagerPresentation)QuickWatchPresentation).txtTotal.Text = "" + jobsTotalAmount.ToString();
233                    ((P2PManagerPresentation)QuickWatchPresentation).txtInProgress.Text = "" + jobsInProgress.ToString();
234                    ((P2PManagerPresentation)QuickWatchPresentation).txtLeft.Text = "" + new BigInteger((jobsTotalAmount - jobsInProgress - jobsFinished)).ToString();
235                    ((P2PManagerPresentation)QuickWatchPresentation).txtFinished.Text = "" + jobsFinished.ToString();
236
237                    ((P2PManagerPresentation)QuickWatchPresentation).txtTotalWorker.Text = "" + (freeWorkers + busyWorkers);
238                    ((P2PManagerPresentation)QuickWatchPresentation).txtFreeWorker.Text = "" + freeWorkers;
239                    ((P2PManagerPresentation)QuickWatchPresentation).txtBusyWorker.Text = "" + busyWorkers;
240
241                    /* START approximation of end time */
242                    // this value is MinValue until the first job is allocated to a worker
243                    DateTime estimatedDateTime = this.p2pManager.EstimatedEndTime();
244                    if(estimatedDateTime != DateTime.MaxValue)
245                    {
246                        ((P2PManagerPresentation)QuickWatchPresentation).txtEstimatedEndTime.Text = estimatedDateTime.ToString();
247                    }
248                    /* END approximation of end time */
249
250                    ((P2PManagerPresentation)QuickWatchPresentation).entries.Clear();
251                    listNode = globalTop10List.First;
252
253                    int i = 0;
254                    while (listNode != null)
255                    {
256                        i++;
257
258                        ResultEntry entry = new ResultEntry();
259                        entry.Ranking = "" + i;
260                        entry.Value = "" + Math.Round(listNode.Value.value, 3);
261                        entry.Key = listNode.Value.key;
262                        // remove all linebreaks, tabs and so on
263                        string decryptText = enc.GetString(listNode.Value.decryption, 0, this.bytesToUseForDecryption);
264                        decryptText = decryptText.Replace("\n", String.Empty);
265                        decryptText = decryptText.Replace("\t", String.Empty);
266                        decryptText = decryptText.Replace("\r", String.Empty);
267                        entry.Text = decryptText;//enc.GetString(listNode.Value.decryption, 0, this.bytesToUseForDecryption);
268
269                        ((P2PManagerPresentation)QuickWatchPresentation).entries.Add(entry);
270                        listNode = listNode.Next;
271                    }
272                    // to resize the WPF Presentation, so it will fit in the PlugIn-Borders
273                    ((P2PManagerPresentation)QuickWatchPresentation).P2PManagerPresentation_SizeChanged(null, null);
274                }, null);
275            }
276        }
277
278        #endregion
279
280        void settings_OnPluginStatusChanged(IPlugin sender, StatusEventArgs args)
281        {
282            if (OnPluginStatusChanged != null)
283                OnPluginStatusChanged(this, args);
284        }
285
286        void settings_TaskPaneAttributeChanged(ISettings settings, TaskPaneAttributeChangedEventArgs args)
287        {
288            //throw new NotImplementedException();
289        }
290
291        void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
292        {
293            if (e.PropertyName == "Key")
294            {
295                if (this.EncryptionControl != null)
296                {
297                    KeyPattern checkPattern = new KeyPattern(this.EncryptionControl.getKeyPattern());
298                    if (!checkPattern.testWildcardKey(this.settings.Key))
299                    {
300                        GuiLogMessage("The set Pattern doesn't fit to the encryption plugin connected with this manager!", NotificationLevel.Warning);
301                    }
302                    else
303                        GuiLogMessage("Successfully changed the KeyPattern in the settings.", NotificationLevel.Info);
304                }
305            }
306
307            if (this.p2pControl == null)
308                return;
309            if (e.PropertyName == "BtnUnregister")
310            {
311                if (this.p2pManager != null && this.p2pManager.Started)
312                {
313                    Stop();
314                    //this.p2pManager.Stop(PubSubMessageType.Unregister);
315                    GuiLogMessage("Unregister button pressed, Publisher has stopped!", NotificationLevel.Info);
316                }
317            }
318            if (e.PropertyName == "BtnRegister")
319            {
320                if (this.p2pManager == null || !this.p2pManager.Started)
321                {
322                    this.process(this.EncryptionControl);
323                    GuiLogMessage("Register button pressed, Publisher has been started!", NotificationLevel.Info);
324                }
325            }
326            if (e.PropertyName == "BtnSolutionFound")
327            {
328                if (this.p2pManager != null && this.p2pManager.Started)
329                {
330                    Stop();
331                    //this.p2pManager.Stop(PubSubMessageType.Solution);
332                    GuiLogMessage("TEST: Emulate Solution-Found-message", NotificationLevel.Info);
333                }
334            }
335        }
336
337        public ISettings Settings
338        {
339            set { this.settings = (P2PManager_KeyPatternSettings)value; }
340            get { return this.settings; }
341        }
342
343        // Pre-Execute Method is below this region
344
345        // Execute-Method is below this region
346
347        public void PostExecution()
348        {
349            //throw new NotImplementedException();
350        }
351
352        public void Pause()
353        {
354            //throw new NotImplementedException();
355        }
356
357        public void Stop()
358        {
359
360            if (this.p2pManager != null && this.p2pManager.Started)
361            {
362                this.p2pManager.Stop(PubSubMessageType.Unregister);
363                this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Neutral);
364                this.p2pManager.OnGuiMessage -= p2pManager_OnGuiMessage;
365                this.p2pManager.OnProcessProgress -= p2pManager_OnProcessProgress;
366                this.p2pManager.OnNewJobAllocated -= p2pManager_OnNewJobAllocated;
367                this.p2pManager.OnNoMoreJobsLeft -= p2pManager_OnNoMoreJobsLeft;
368                this.p2pManager.OnResultReceived -= p2pManager_OnResultReceived;
369                // set Manager to null, so after restarting the Workspace,
370                // a new Distributable stop will be initialized with (maybe)
371                // changed settings
372                this.p2pManager = null;
373            }
374        }
375
376        public void Initialize()
377        {
378        }
379
380        public void Dispose()
381        {
382        }
383
384        #endregion
385
386        public void PreExecution()
387        {
388            // if no P2P Slave PlugIn is connected with this PlugIn --> No execution!
389            if (P2PControl == null)
390            {
391                GuiLogMessage("No P2P_Peer connected with this PlugIn!", NotificationLevel.Error);
392                return;
393            }
394        }
395
396        void p2pManager_OnProcessProgress(double progressInPercent)
397        {
398            ProgressChanged(progressInPercent, 100.0);
399            UpdateQuickWatch(progressInPercent);
400        }
401
402        void p2pManager_OnGuiMessage(string sData, NotificationLevel notificationLevel)
403        {
404            GuiLogMessage(sData, notificationLevel);
405        }
406
407        DistributableKeyPatternJob distributableKeyPatternJob;
408        public void Execute()
409        {
410            if (this.DecryptedData != null)
411            {
412                // TODO: dirty hack because of a missing Initialization vector
413                // it can't be null, because serialization will throw an exception in this case
414                if (this.InitVector == null)
415                {
416                    this.InitVector = new byte[8]{0,0,0,0,0,0,0,0};
417                    GuiLogMessage("Initialization vector not set, so set a standard value - dirty hack!", NotificationLevel.Info);
418                }
419                this.process(this.EncryptionControl);
420            }               
421        }
422
423        private void process(IControlEncryption iControlEncryption)
424        {
425            // if no P2P Slave PlugIn is connected with this PlugIn --> No execution!
426            if (P2PControl == null)
427            {
428                GuiLogMessage("No P2P_Peer connected with this PlugIn!", NotificationLevel.Error);
429                return;
430            }
431            if (iControlEncryption == null)
432            {
433                GuiLogMessage("No Encryption Control connected with this PlugIn", NotificationLevel.Error);
434                return;
435            }
436
437            if (this.p2pManager == null)
438            {
439                byte[] byteEncryptedData = null;
440                CryptoolStream newEncryptedData = new CryptoolStream();
441                try
442                {
443                    newEncryptedData.OpenRead(this.DecryptedData.FileName);
444                    // Convert CryptoolStream to an byte Array and store it in the DHT
445                    if (newEncryptedData.Length > Int32.MaxValue)
446                        throw (new Exception("Encrypted Data are too long for this PlugIn. The maximum size of Data is " + Int32.MaxValue + "!"));
447                    byteEncryptedData = new byte[newEncryptedData.Length];
448                    int k = newEncryptedData.Read(byteEncryptedData, 0, byteEncryptedData.Length);
449                    if (k < byteEncryptedData.Length)
450                        throw (new Exception("Read Data are shorter than byteArrayLen"));
451                }
452                catch (Exception ex)
453                {
454                    throw (new Exception("Fatal error while reading the CryptoolStream. Exception: " + ex.ToString()));
455                }
456                finally
457                {
458                    newEncryptedData.Close();
459                    newEncryptedData.Dispose();
460                }
461                             
462                string pattern = this.encryptionControl.getKeyPattern();
463                KeyPattern kp = new KeyPattern(pattern);
464                if (kp.testWildcardKey(this.settings.Key))
465                {
466                    kp.WildcardKey = this.settings.Key;
467                }
468                else
469                {
470                    GuiLogMessage("The Key Pattern in the settings isn't valid for the given Encryption!", NotificationLevel.Error);
471                    return;
472                }
473
474                // create a new DistributableJob instance
475                distributableKeyPatternJob = new DistributableKeyPatternJob
476                    (kp, this.settings.KeyPatternSize * 10000, byteEncryptedData, this.InitVector);
477
478                this.p2pManager = new P2PManagerBase_NEW(this.P2PControl, distributableKeyPatternJob);
479                this.p2pManager.OnGuiMessage += new P2PPublisherBase.GuiMessage(p2pManager_OnGuiMessage);
480                this.p2pManager.OnProcessProgress += new P2PManagerBase_NEW.ProcessProgress(p2pManager_OnProcessProgress);
481                this.p2pManager.OnNewJobAllocated += new P2PManagerBase_NEW.NewJobAllocated(p2pManager_OnNewJobAllocated);
482                this.p2pManager.OnNoMoreJobsLeft += new P2PManagerBase_NEW.NoMoreJobsLeft(p2pManager_OnNoMoreJobsLeft);
483                this.p2pManager.OnResultReceived += new P2PManagerBase_NEW.ResultReceived(p2pManager_OnResultReceived);
484            }
485
486            this.bytesToUseForDecryption = this.settings.BytesToUse;
487
488            this.p2pManager.StartManager(this.settings.TopicName, this.settings.SendAliveMessageInterval * 1000);
489
490            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Working);
491        }
492
493        void p2pManager_OnResultReceived(BigInteger jobId)
494        {
495            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Finished);
496        }
497
498        void p2pManager_OnNoMoreJobsLeft()
499        {
500            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Finished);
501        }
502
503        void p2pManager_OnNewJobAllocated(BigInteger jobId)
504        {
505            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Working);
506        }
507
508
509        #region INotifyPropertyChanged Members
510
511        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
512
513        public void OnPropertyChanged(string name)
514        {
515            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
516        }
517
518        public event PluginProgressChangedEventHandler OnPluginProcessChanged;
519
520        private void ProgressChanged(double value, double max)
521        {
522            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
523        }
524
525        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
526        {
527            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
528        }
529
530        #endregion
531    }
532
533}
Note: See TracBrowser for help on using the repository browser.