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

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

P2P Manager: Made IV-Input optional with a dirty hack (internal a 8 byte IV with 0...0 will be created)

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