1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  package uk.co.westhawk.snmp.stack;
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  import uk.co.westhawk.snmp.beans.UsmDiscoveryBean;
52  import uk.co.westhawk.snmp.event.RequestPduListener;
53  import uk.co.westhawk.snmp.pdu.DiscoveryPdu;
54  import uk.co.westhawk.snmp.util.SnmpUtilities;
55  
56  import java.io.ByteArrayInputStream;
57  import java.io.IOException;
58  import java.util.Enumeration;
59  import java.util.Hashtable;
60  import java.util.function.BiFunction;
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 public abstract class SnmpContextv3Basis extends AbstractSnmpContext
115         implements SnmpContextv3Face, Cloneable {
116     private static final String version_id = "@(#)$Id: SnmpContextv3Basis.java,v 3.17 2009/03/05 15:51:42 birgita Exp $ Copyright Westhawk Ltd";
117 
118     public static final int AES128_KEY_LENGTH = 16;
119     public static final int AES192_KEY_LENGTH = 24;
120     public static final int AES256_KEY_LENGTH = 32;
121 
122     protected String userName = DEFAULT_USERNAME;
123     protected boolean useAuthentication = false;
124     protected String userAuthenticationPassword;
125     protected byte[] userAuthKeyMD5 = null;
126     protected byte[] userAuthKeySHA1 = null;
127     protected byte[] userAuthKeySHA256 = null;
128     protected byte[] userAuthKeySHA512 = null;
129     protected byte[] userAuthKeySHA224 = null;
130     protected byte[] userAuthKeySHA384 = null;
131     protected int authenticationProtocol = MD5_PROTOCOL;
132     protected int privacyProtocol = DES_ENCRYPT;
133     protected boolean usePrivacy = false;
134     protected String userPrivacyPassword;
135     protected byte[] userPrivKeyMD5 = null;
136     protected byte[] userPrivKeySHA1 = null;
137     protected byte[] userPrivKeySHA256 = null;
138     protected byte[] userPrivKeySHA512 = null;
139     protected byte[] userPrivKeySHA224 = null;
140     protected byte[] userPrivKeySHA384 = null;
141     protected byte[] contextEngineId = new byte[0];
142     protected String contextName = DEFAULT_CONTEXT_NAME;
143     protected UsmAgent usmAgent = null;
144 
145     private Hashtable msgIdHash = new Hashtable(MAXPDU);
146     private static int next_id = 1;
147 
148     
149 
150 
151 
152 
153 
154 
155     public SnmpContextv3Basis(String host, int port) throws IOException {
156         this(host, port, null, STANDARD_SOCKET);
157     }
158 
159     
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170     public SnmpContextv3Basis(String host, int port, String typeSocketA)
171             throws IOException {
172         this(host, port, null, typeSocketA);
173     }
174 
175     
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190     public SnmpContextv3Basis(String host, int port, String bindAddress, String typeSocketA)
191             throws IOException {
192         super(host, port, bindAddress, typeSocketA);
193 
194         if (TimeWindow.getCurrent() == null) {
195             TimeWindow timew = new TimeWindow();
196         }
197         setUsmAgent(createUsmAgent());
198     }
199 
200     public int getVersion() {
201         return SnmpConstants.SNMP_VERSION_3;
202     }
203 
204     
205 
206 
207 
208 
209     public String getUserName() {
210         return userName;
211     }
212 
213     
214 
215 
216 
217 
218 
219 
220 
221 
222 
223     public void setUserName(String newUserName) {
224         userName = newUserName;
225     }
226 
227     
228 
229 
230 
231 
232 
233     public boolean isUseAuthentication() {
234         return useAuthentication;
235     }
236 
237     
238 
239 
240 
241 
242 
243     public void setUseAuthentication(boolean newUseAuthentication) {
244         useAuthentication = newUseAuthentication;
245     }
246 
247     
248 
249 
250 
251 
252 
253     public String getUserAuthenticationPassword() {
254         return userAuthenticationPassword;
255     }
256 
257     
258 
259 
260 
261 
262 
263 
264     public void setUserAuthenticationPassword(String newUserAuthPassword) {
265         if (newUserAuthPassword != null
266                 &&
267                 newUserAuthPassword.equals(userAuthenticationPassword) == false) {
268             userAuthenticationPassword = newUserAuthPassword;
269             userAuthKeyMD5 = null;
270             userAuthKeySHA1 = null;
271             userAuthKeySHA256 = null;
272             userAuthKeySHA512 = null;
273             userAuthKeySHA224 = null;
274             userAuthKeySHA384 = null;
275         }
276     }
277 
278     
279 
280 
281 
282 
283 
284 
285 
286 
287     public void setAuthenticationProtocol(int protocol)
288             throws IllegalArgumentException {
289         if (AUTH_PROTOCOLS.contains(protocol)) {
290             if (protocol != authenticationProtocol) {
291                 authenticationProtocol = protocol;
292             }
293         } else {
294             throw new IllegalArgumentException("Authentication Protocol "
295                     + "should be MD5 or SHA1 or SHA256 or SHA512 or SHA224 or SHA384");
296         }
297     }
298 
299     
300 
301 
302 
303 
304 
305 
306 
307 
308     public int getAuthenticationProtocol() {
309         return authenticationProtocol;
310     }
311 
312     
313 
314 
315 
316 
317 
318 
319 
320 
321     public void setPrivacyProtocol(int protocol)
322             throws IllegalArgumentException {
323         if (PRIVACY_PROTOCOLS.contains(protocol)) {
324             if (protocol != privacyProtocol) {
325                 privacyProtocol = protocol;
326             }
327         } else {
328             throw new IllegalArgumentException("Privacy Encryption "
329                     + "should be AES, AES192, AES256 or DES");
330         }
331     }
332 
333     
334 
335 
336 
337 
338 
339 
340 
341 
342     public int getPrivacyProtocol() {
343         return privacyProtocol;
344     }
345 
346     byte[] getAuthenticationPasswordKeyMD5() {
347         if (userAuthKeyMD5 == null) {
348             userAuthKeyMD5 = SnmpUtilities.passwordToKeyMD5(userAuthenticationPassword);
349         }
350         return userAuthKeyMD5;
351     }
352 
353     byte[] getAuthenticationPasswordKeySHA1() {
354         if (userAuthKeySHA1 == null) {
355             userAuthKeySHA1 = SnmpUtilities.passwordToKeySHA1(userAuthenticationPassword);
356         }
357         return userAuthKeySHA1;
358     }
359 
360     
361 
362 
363 
364 
365     byte[] getAuthenticationPasswordKeySHA256() {
366         if (userAuthKeySHA256 == null) {
367             userAuthKeySHA256 = SnmpUtilities.passwordToKeySHA256(userAuthenticationPassword);
368         }
369         return userAuthKeySHA256;
370     }
371 
372     
373 
374 
375 
376 
377     byte[] getAuthenticationPasswordKeySHA384() {
378         if (userAuthKeySHA384 == null) {
379             userAuthKeySHA384 = SnmpUtilities.passwordToKeySHA384(userAuthenticationPassword);
380         }
381         return userAuthKeySHA384;
382     }
383 
384     
385 
386 
387 
388 
389     byte[] getAuthenticationPasswordKeySHA224() {
390         if (userAuthKeySHA224 == null) {
391             userAuthKeySHA224 = SnmpUtilities.passwordToKeySHA224(userAuthenticationPassword);
392         }
393         return userAuthKeySHA224;
394     }
395 
396     
397 
398 
399 
400 
401     byte[] getAuthenticationPasswordKeySHA512() {
402         if (userAuthKeySHA512 == null) {
403             userAuthKeySHA512 = SnmpUtilities.passwordToKeySHA512(userAuthenticationPassword);
404         }
405         return userAuthKeySHA512;
406     }
407 
408     byte[] getPrivacyPasswordKeyMD5() {
409         if (userPrivKeyMD5 == null) {
410             userPrivKeyMD5 = SnmpUtilities.passwordToKeyMD5(userPrivacyPassword);
411         }
412         return userPrivKeyMD5;
413     }
414 
415     byte[] getPrivacyPasswordKeySHA1() {
416         if (userPrivKeySHA1 == null) {
417             userPrivKeySHA1 = SnmpUtilities.passwordToKeySHA1(userPrivacyPassword);
418         }
419         return userPrivKeySHA1;
420     }
421 
422     
423 
424 
425 
426 
427     byte[] getPrivacyPasswordKeySHA256() {
428         if (userPrivKeySHA256 == null) {
429             userPrivKeySHA256 = SnmpUtilities.passwordToKeySHA256(userPrivacyPassword);
430         }
431         return userPrivKeySHA256;
432     }
433 
434     
435 
436 
437 
438 
439     byte[] getPrivacyPasswordKeySHA224() {
440         if (userPrivKeySHA224 == null) {
441             userPrivKeySHA224 = SnmpUtilities.passwordToKeySHA224(userPrivacyPassword);
442         }
443         return userPrivKeySHA224;
444     }
445 
446     
447 
448 
449 
450 
451     byte[] getPrivacyPasswordKeySHA384() {
452         if (userPrivKeySHA384 == null) {
453             userPrivKeySHA384 = SnmpUtilities.passwordToKeySHA384(userPrivacyPassword);
454         }
455         return userPrivKeySHA384;
456     }
457 
458     
459 
460 
461 
462 
463     byte[] getPrivacyPasswordKeySHA512() {
464         if (userPrivKeySHA512 == null) {
465             userPrivKeySHA512 = SnmpUtilities.passwordToKeySHA512(userPrivacyPassword);
466         }
467         return userPrivKeySHA512;
468     }
469 
470     
471 
472 
473 
474 
475 
476     public boolean isUsePrivacy() {
477         return usePrivacy;
478     }
479 
480     
481 
482 
483 
484 
485 
486 
487     public void setUsePrivacy(boolean newUsePrivacy) {
488         usePrivacy = newUsePrivacy;
489     }
490 
491     
492 
493 
494 
495 
496 
497     public String getUserPrivacyPassword() {
498         return userPrivacyPassword;
499     }
500 
501     
502 
503 
504 
505 
506 
507 
508     public void setUserPrivacyPassword(String newUserPrivacyPassword) {
509         if (newUserPrivacyPassword != null
510                 &&
511                 newUserPrivacyPassword.equals(userPrivacyPassword) == false) {
512             userPrivacyPassword = newUserPrivacyPassword;
513             userPrivKeyMD5 = null;
514             userPrivKeySHA1 = null;
515             userPrivKeySHA256 = null;
516             userPrivKeySHA512 = null;
517             userPrivKeySHA224 = null;
518             userPrivKeySHA384 = null;
519         }
520     }
521 
522     
523 
524 
525 
526 
527 
528 
529 
530 
531 
532 
533 
534 
535 
536 
537 
538 
539 
540 
541 
542 
543 
544 
545     public void setContextEngineId(byte[] newContextEngineId)
546             throws IllegalArgumentException {
547         if (newContextEngineId != null) {
548             contextEngineId = newContextEngineId;
549         } else {
550             throw new IllegalArgumentException("contextEngineId is null");
551         }
552     }
553 
554     
555 
556 
557 
558 
559     public byte[] getContextEngineId() {
560         return contextEngineId;
561     }
562 
563     
564 
565 
566 
567 
568 
569 
570 
571 
572 
573 
574     public void setContextName(String newContextName) {
575         contextName = newContextName;
576     }
577 
578     
579 
580 
581 
582 
583     public String getContextName() {
584         return contextName;
585     }
586 
587     
588 
589 
590 
591 
592 
593 
594 
595 
596     public boolean addDiscoveryPdu(DiscoveryPdu pdu)
597             throws IOException, PduException {
598         
599         return this.addPdu(pdu, false);
600     }
601 
602     
603 
604 
605 
606 
607 
608 
609 
610 
611     public boolean addPdu(Pdu pdu)
612             throws IOException, PduException {
613         return this.addPdu(pdu, true);
614     }
615 
616     
617 
618 
619 
620 
621 
622     protected UsmAgent createUsmAgent() {
623         return new DefaultUsmAgent();
624     }
625 
626     
627 
628 
629 
630 
631 
632 
633 
634 
635     public void setUsmAgent(UsmAgent agent) {
636         usmAgent = agent;
637     }
638 
639     
640 
641 
642 
643 
644 
645     public UsmAgent getUsmAgent() {
646         return usmAgent;
647     }
648 
649     
650 
651 
652 
653 
654 
655 
656 
657 
658 
659 
660 
661 
662 
663 
664 
665 
666 
667 
668 
669     protected boolean addPdu(Pdu pdu, boolean checkDiscovery)
670             throws IOException, PduException {
671         
672         Integer msgId = pdu.snmpv3MsgId;
673         if (msgId == null) {
674             msgId = new Integer(next_id++);
675         } else if (pdu.isExpectingResponse() == true) {
676             
677             
678             
679             msgId = new Integer(next_id++);
680         }
681         pdu.snmpv3MsgId = msgId;
682 
683         msgIdHash.put(msgId, new Integer(pdu.req_id));
684         if (AsnObject.debug > 6) {
685             System.out.println(getClass().getName() + ".addPdu(): msgId="
686                     + msgId.toString() + ", Pdu reqId=" + pdu.req_id);
687         }
688 
689         if (checkDiscovery == true && isAuthoritative(pdu.getMsgType()) == false) {
690             discoverIfNeeded(pdu);
691         }
692 
693         boolean added = super.addPdu(pdu);
694         return added;
695     }
696 
697     
698 
699 
700 
701 
702 
703 
704 
705     public synchronized boolean removePdu(int rid) {
706         boolean removed = super.removePdu(rid);
707         if (removed) {
708             Enumeration keys = msgIdHash.keys();
709             Integer msgIdI = null;
710             boolean found = false;
711             while (keys.hasMoreElements() && found == false) {
712                 msgIdI = (Integer) keys.nextElement();
713                 Integer pduIdI = (Integer) msgIdHash.get(msgIdI);
714                 found = (pduIdI.intValue() == rid);
715             }
716             if (found) {
717                 msgIdHash.remove(msgIdI);
718             }
719         }
720         return removed;
721     }
722 
723     
724 
725 
726 
727     public byte[] encodeDiscoveryPacket(byte msg_type, int rId, int errstat,
728             int errind, Enumeration ve, Object obj)
729             throws IOException, EncodingException {
730         String engineId = "";
731         TimeWindow tWindow = TimeWindow.getCurrent();
732         if (tWindow.isSnmpEngineIdKnown(getSendToHostAddress(), hostPort) == true) {
733             engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort);
734         }
735         TimeWindowNode node = new TimeWindowNode(engineId, 0, 0);
736 
737         return actualEncodePacket(msg_type, rId, errstat, errind, ve, node,
738                 obj);
739     }
740 
741     
742 
743 
744 
745 
746 
747 
748 
749 
750 
751 
752 
753 
754 
755 
756 
757 
758 
759 
760 
761 
762 
763 
764 
765 
766 
767 
768 
769 
770 
771 
772 
773 
774 
775 
776 
777     public byte[] encodePacket(byte msg_type, int rId, int errstat,
778             int errind, Enumeration ve, Object obj)
779             throws IOException, EncodingException {
780         TimeWindowNode node = null;
781         if (isDestroyed == true) {
782             throw new EncodingException("Context can no longer be used, since it is already destroyed");
783         } else {
784             TimeWindow tWindow = TimeWindow.getCurrent();
785             if (isAuthoritative(msg_type) == true) {
786                 usmAgent.setSnmpContext(this);
787                 if (usmAgent.getSnmpEngineId() == null) {
788                     throw new EncodingException("UsmAgent "
789                             + usmAgent.getClass().getName()
790                             + " should provide Engine ID!");
791                 }
792                 tWindow.updateTimeWindow(usmAgent.getSnmpEngineId(),
793                         usmAgent.getSnmpEngineBoots(), usmAgent.getSnmpEngineTime(),
794                         this.isUseAuthentication());
795                 node = tWindow.getTimeLine(usmAgent.getSnmpEngineId());
796             } else {
797                 if (tWindow.isSnmpEngineIdKnown(getSendToHostAddress(), hostPort) == false) {
798                     throw new EncodingException("Engine ID of host "
799                             + getSendToHostAddress()
800                             + ", port " + hostPort
801                             + " is unknown (rId="
802                             + rId + "). Perform discovery.");
803                 }
804                 String engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort);
805                 node = new TimeWindowNode(engineId, 0, 0);
806 
807                 if (isUseAuthentication()) {
808                     if (tWindow.isTimeLineKnown(engineId) == true) {
809                         node = tWindow.getTimeLine(engineId);
810                     } else {
811                         throw new EncodingException("Time Line of Engine ID of host "
812                                 + getSendToHostAddress() + ", port " + hostPort + " is unknown. "
813                                 + "Perform discovery.");
814                     }
815                 }
816             }
817         }
818         return actualEncodePacket(msg_type, rId, errstat, errind, ve, node,
819                 obj);
820     }
821 
822     
823 
824 
825 
826     protected String checkContextSanity() {
827         String ret = null;
828         if (usePrivacy == true) {
829             if (userPrivacyPassword == null) {
830                 ret = "userPrivacyPassword is null, but usePrivacy is true";
831             } else if (userPrivacyPassword.length() == 0) {
832                 ret = "userPrivacyPassword is empty, but usePrivacy is true";
833             } else if (useAuthentication == false) {
834                 ret = "useAuthentication is false, but usePrivacy is true";
835             }
836         }
837 
838         if (useAuthentication == true) {
839             if (userAuthenticationPassword == null) {
840                 ret = "userAuthenticationPassword is null, but useAuthentication is true";
841             } else if (userAuthenticationPassword.length() == 0) {
842                 ret = "userAuthenticationPassword is empty, but useAuthentication is true";
843             }
844         }
845         return ret;
846     }
847 
848     
849 
850 
851 
852 
853 
854     protected byte[] actualEncodePacket(byte msg_type, int rId, int errstat,
855             int errind, Enumeration ve, TimeWindowNode node, Object obj)
856             throws IOException, EncodingException {
857         AsnEncoderv3 enc = new AsnEncoderv3();
858         String msg = checkContextSanity();
859         if (msg != null) {
860             throw new EncodingException(msg);
861         }
862 
863         int msgId = ((Integer) obj).intValue();
864         if (AsnObject.debug > 6) {
865             System.out.println(getClass().getName() + ".actualEncodePacket(): msgId="
866                     + msgId + ", Pdu reqId=" + rId);
867         }
868         byte[] packet = enc.EncodeSNMPv3(this, msgId, node,
869                 msg_type, rId, errstat, errind, ve);
870 
871         return packet;
872     }
873 
874     
875 
876 
877     protected void processIncomingResponse(ByteArrayInputStream in)
878             throws DecodingException, IOException {
879         AsnDecoderv3 rpdu = new AsnDecoderv3();
880         
881         
882         byte[] bu = null;
883         
884         int nb = in.available();
885         bu = new byte[nb];
886         in.read(bu);
887         in = new ByteArrayInputStream(bu);
888 
889         AsnSequence asnTopSeq = rpdu.DecodeSNMPv3(in);
890         int msgId = rpdu.getMessageId(asnTopSeq);
891         Integer rid = (Integer) msgIdHash.get(new Integer(msgId));
892         if (rid != null) {
893             if (AsnObject.debug > 6) {
894                 System.out.println(getClass().getName() + ".processIncomingResponse(): msgId="
895                         + msgId + ", Pdu reqId=" + rid);
896             }
897             Pdu pdu = getPdu(rid);
898             try {
899                 AsnPduSequence pduSeq = rpdu.processSNMPv3(this, asnTopSeq, bu, false);
900                 if (pduSeq != null) {
901                     
902                     Integer rid2 = new Integer(pduSeq.getReqId());
903                     if (AsnObject.debug > 6) {
904                         System.out.println(getClass().getName() + ".processIncomingResponse():"
905                                 + " rid2=" + rid2);
906                     }
907 
908                     Pdu newPdu = null;
909                     if (rid2.intValue() != rid.intValue()) {
910                         newPdu = getPdu(rid2);
911                         if (AsnObject.debug > 3) {
912                             System.out.println(getClass().getName() + ".processIncomingResponse(): "
913                                     + "pduReqId of msgId (" + rid.intValue()
914                                     + ") != pduReqId of Pdu (" + rid2.intValue()
915                                     + ")");
916                         }
917                         if (newPdu == null) {
918                             if (AsnObject.debug > 3) {
919                                 System.out.println(getClass().getName() + ".processIncomingResponse(): "
920                                         + "Using pduReqId of msgId (" + rid.intValue() + ")");
921                             }
922                         }
923                     }
924 
925                     if (newPdu != null) {
926                         pdu = newPdu;
927                     }
928                 } else {
929                     if (AsnObject.debug > 6) {
930                         System.out.println(getClass().getName() + ".processIncomingResponse():"
931                                 + " pduSeq is null.");
932                     }
933                 }
934 
935                 if (pdu != null) {
936                     pdu.fillin(pduSeq);
937                 } else {
938                     if (AsnObject.debug > 6) {
939                         System.out.println(getClass().getName() + ".processIncomingResponse(): No Pdu with reqid "
940                                 + rid.intValue());
941                     }
942                 }
943             } catch (DecodingException exc) {
944                 if (pdu != null) {
945                     pdu.setErrorStatus(AsnObject.SNMP_ERR_DECODING_EXC, exc);
946                     pdu.fillin(null);
947                 } else {
948                     throw exc;
949                 }
950             }
951         } else {
952             if (AsnObject.debug > 3) {
953                 System.out.println(getClass().getName() + ".processIncomingResponse(): Pdu of msgId " + msgId
954                         + " is already answered");
955             }
956             rid = new Integer(-1);
957         }
958     }
959 
960     
961 
962 
963 
964 
965 
966 
967 
968     
969     
970     
971     protected boolean isAuthoritative(byte msg_type) {
972         return (msg_type == AsnObject.GET_RSP_MSG
973                 ||
974                 msg_type == AsnObject.TRPV2_REQ_MSG
975                 ||
976                 msg_type == AsnObject.GET_RPRT_MSG);
977     }
978 
979     void discoverIfNeeded(Pdu pdu)
980             throws IOException, PduException {
981         UsmDiscoveryBean discBean = null;
982         boolean isNeeded = false;
983 
984         TimeWindow tWindow = TimeWindow.getCurrent();
985         String engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort);
986         if (engineId == null) {
987             isNeeded = true;
988             discBean = new UsmDiscoveryBean(
989                     getSendToHostAddress(), hostPort, bindAddr, typeSocket);
990             discBean.setRetryIntervals(pdu.getRetryIntervals());
991         }
992 
993         if (isUseAuthentication()) {
994             if (isNeeded) {
995                 discBean.setAuthenticationDetails(userName,
996                         userAuthenticationPassword, authenticationProtocol);
997             } else if (tWindow.isTimeLineKnown(engineId) == false) {
998                 isNeeded = true;
999                 discBean = new UsmDiscoveryBean(
1000                         getSendToHostAddress(), hostPort, bindAddr, typeSocket);
1001                 discBean.setAuthenticationDetails(userName,
1002                         userAuthenticationPassword, authenticationProtocol);
1003                 discBean.setRetryIntervals(pdu.getRetryIntervals());
1004             }
1005 
1006             if (isNeeded && isUsePrivacy()) {
1007                 discBean.setPrivacyDetails(userPrivacyPassword, privacyProtocol);
1008             }
1009         }
1010 
1011         if (isNeeded) {
1012             discBean.startDiscovery();
1013 
1014         }
1015 
1016         
1017         
1018         if (contextEngineId == null || contextEngineId.length == 0) {
1019             engineId = tWindow.getSnmpEngineId(getSendToHostAddress(), hostPort);
1020             setContextEngineId(SnmpUtilities.toBytes(engineId));
1021         }
1022     }
1023 
1024     
1025 
1026 
1027 
1028 
1029 
1030 
1031 
1032 
1033 
1034 
1035 
1036 
1037 
1038 
1039 
1040     public void addRequestPduListener(RequestPduListener l, ListeningContextPool lcontext)
1041             throws IOException {
1042         super.addRequestPduListener(l, lcontext);
1043 
1044         usmAgent.setSnmpContext(this);
1045         TimeWindow tWindow = TimeWindow.getCurrent();
1046         if (usmAgent.getSnmpEngineId() == null) {
1047             throw new IOException("UsmAgent "
1048                     + usmAgent.getClass().getName()
1049                     + " should provide Engine ID!");
1050         }
1051         tWindow.setSnmpEngineId(usmAgent.MYFAKEHOSTNAME, hostPort, usmAgent.getSnmpEngineId());
1052         tWindow.updateTimeWindow(usmAgent.getSnmpEngineId(),
1053                 usmAgent.getSnmpEngineBoots(), usmAgent.getSnmpEngineTime(),
1054                 this.isUseAuthentication());
1055     }
1056 
1057     
1058 
1059 
1060     public Object cloneParameters(SnmpContextv3Face clContext) {
1061         clContext.setUserName(new String(userName));
1062         clContext.setUseAuthentication(useAuthentication);
1063         if (userAuthenticationPassword != null) {
1064             clContext.setUserAuthenticationPassword(
1065                     new String(userAuthenticationPassword));
1066         }
1067         clContext.setAuthenticationProtocol(authenticationProtocol);
1068 
1069         clContext.setUsePrivacy(usePrivacy);
1070         if (userPrivacyPassword != null) {
1071             clContext.setUserPrivacyPassword(new String(userPrivacyPassword));
1072         }
1073         clContext.setPrivacyProtocol(privacyProtocol);
1074 
1075         clContext.setContextName(new String(contextName));
1076 
1077         int l = contextEngineId.length;
1078         byte[] newContextEngineId = new byte[l];
1079         System.arraycopy(contextEngineId, 0, newContextEngineId, 0, l);
1080         clContext.setContextEngineId(newContextEngineId);
1081 
1082         clContext.setUsmAgent(usmAgent);
1083         return clContext;
1084     }
1085 
1086     
1087 
1088 
1089 
1090 
1091 
1092 
1093     public String getHashKey() {
1094         StringBuffer buffer = new StringBuffer();
1095         buffer.append(hostname);
1096         buffer.append("_").append(hostPort);
1097         buffer.append("_").append(bindAddr);
1098         buffer.append("_").append(typeSocket);
1099         buffer.append("_").append(useAuthentication);
1100         buffer.append("_").append(PROTOCOL_NAMES[authenticationProtocol]);
1101         buffer.append("_").append(PROTOCOL_NAMES[privacyProtocol]);
1102         buffer.append("_").append(userAuthenticationPassword);
1103         buffer.append("_").append(userName);
1104         buffer.append("_").append(usePrivacy);
1105         buffer.append("_").append(userPrivacyPassword);
1106         buffer.append("_").append(SnmpUtilities.toHexString(contextEngineId));
1107         buffer.append("_").append(contextName);
1108         buffer.append("_v").append(getVersion());
1109 
1110         return buffer.toString();
1111     }
1112 
1113     
1114 
1115 
1116 
1117 
1118     public String toString() {
1119         StringBuffer buffer = new StringBuffer(getClass().getName() + "[");
1120         buffer.append("host=").append(hostname);
1121         buffer.append(", sendToHost=").append(getSendToHostAddress());
1122         buffer.append(", port=").append(hostPort);
1123         buffer.append(", bindAddress=").append(bindAddr);
1124         buffer.append(", socketType=").append(typeSocket);
1125         buffer.append(", contextEngineId=").append(SnmpUtilities.toHexString(contextEngineId));
1126         buffer.append(", contextName=").append(contextName);
1127         buffer.append(", userName=").append(userName);
1128         buffer.append(", useAuthentication=").append(useAuthentication);
1129         buffer.append(", authenticationProtocol=").append(PROTOCOL_NAMES[authenticationProtocol]);
1130         buffer.append(", userAuthenticationPassword=").append(userAuthenticationPassword);
1131         buffer.append(", usePrivacy=").append(usePrivacy);
1132         buffer.append(", privacyProtocol=").append(PROTOCOL_NAMES[privacyProtocol]);
1133         buffer.append(", userPrivacyPassword=").append(userPrivacyPassword);
1134         buffer.append(", #trapListeners=").append(trapSupport.getListenerCount());
1135         buffer.append(", #pduListeners=").append(pduSupport.getListenerCount());
1136         buffer.append("]");
1137         return buffer.toString();
1138     }
1139 
1140     
1141 
1142 
1143 
1144 
1145 
1146 
1147 
1148 	protected byte[] generatePrivacyKey(String engineId, int authenticationProtocol, int privacyProtocol) {
1149 		byte[] derivedPrivacyKey;
1150 		byte[] localizedPrivacyKey = null;
1151 		switch (authenticationProtocol) {
1152 			case MD5_PROTOCOL:
1153 				if (privacyProtocol != AES_ENCRYPT && privacyProtocol != DES_ENCRYPT) {
1154 					throw new IllegalArgumentException(
1155 							"Unsupported privacy protocol for MD5: " + PROTOCOL_NAMES[privacyProtocol]);
1156 				}
1157 				derivedPrivacyKey = getPrivacyPasswordKeyMD5();
1158 				return SnmpUtilities.getLocalizedKeyMD5(derivedPrivacyKey, engineId);
1159 			case SHA1_PROTOCOL:
1160 				if (privacyProtocol != AES_ENCRYPT && privacyProtocol != DES_ENCRYPT) {
1161 					throw new IllegalArgumentException(
1162 							"Unsupported privacy protocol for SHA1: " + PROTOCOL_NAMES[privacyProtocol]);
1163 				}
1164 				derivedPrivacyKey = getPrivacyPasswordKeySHA1();
1165 				return SnmpUtilities.getLocalizedKeySHA1(derivedPrivacyKey, engineId);
1166 			case SHA224_PROTOCOL: {
1167 				if (privacyProtocol != AES_ENCRYPT && privacyProtocol != DES_ENCRYPT
1168 						&& privacyProtocol != AES192_ENCRYPT) {
1169 					throw new IllegalArgumentException(
1170 							"Unsupported privacy protocol for SHA224: " + PROTOCOL_NAMES[privacyProtocol]);
1171 				}
1172 				derivedPrivacyKey = getPrivacyPasswordKeySHA224();
1173 				return SnmpUtilities.getLocalizedKeySHA224(derivedPrivacyKey, engineId);
1174 			}
1175 			case SHA256_PROTOCOL: {
1176 				derivedPrivacyKey = getPrivacyPasswordKeySHA256();
1177 				localizedPrivacyKey = deriveKey(engineId, derivedPrivacyKey, SnmpUtilities::getLocalizedKeySHA256,
1178 						privacyProtocol);
1179 				return localizedPrivacyKey;
1180 			}
1181 			case SHA384_PROTOCOL: {
1182 				derivedPrivacyKey = getPrivacyPasswordKeySHA384();
1183 				localizedPrivacyKey = deriveKey(engineId, derivedPrivacyKey, SnmpUtilities::getLocalizedKeySHA384,
1184 						privacyProtocol);
1185 				return localizedPrivacyKey;
1186 			}
1187 			case SHA512_PROTOCOL: {
1188 				derivedPrivacyKey = getPrivacyPasswordKeySHA512();
1189 				localizedPrivacyKey = deriveKey(engineId, derivedPrivacyKey, SnmpUtilities::getLocalizedKeySHA512,
1190 						privacyProtocol);
1191 				return localizedPrivacyKey;
1192 			}
1193 			default:
1194 				throw new IllegalArgumentException("Unsupported authentication protocol: " + authenticationProtocol);
1195 			}
1196 	}
1197     
1198     
1199 
1200 
1201 
1202 
1203 
1204 
1205 
1206 
1207     private static byte[] deriveKey(
1208     		String engineId,
1209     		byte[] derivedPrivacyKey,
1210     		BiFunction<byte[],
1211     		String, byte[]> localizeKey,
1212     		int privacyProtocol) {
1213         byte[] localizedPrivacyKeyBase = localizeKey.apply(derivedPrivacyKey, engineId);
1214         switch (privacyProtocol) {
1215             case AES_ENCRYPT:
1216             case AES192_ENCRYPT:
1217             case AES256_ENCRYPT:
1218             case DES_ENCRYPT:
1219 				return localizedPrivacyKeyBase;
1220             default:
1221                 throw new IllegalArgumentException("Unsupported privacy protocol: " + PROTOCOL_NAMES[privacyProtocol]);
1222         }
1223      }
1224  
1225 
1226     
1227 
1228 
1229 
1230 
1231 
1232 
1233 
1234 
1235     protected byte[] computeFingerprint(String snmpEngineId, int authenticationProtocol, byte[] computedFingerprint,
1236             byte[] message) {
1237         if (authenticationProtocol == MD5_PROTOCOL) {
1238             byte[] passwKey = getAuthenticationPasswordKeyMD5();
1239             byte[] authkey = SnmpUtilities.getLocalizedKeyMD5(passwKey, snmpEngineId);
1240             computedFingerprint = SnmpUtilities.getFingerPrintMD5(authkey, message);
1241         } else if (authenticationProtocol == SHA1_PROTOCOL) {
1242             byte[] passwKey = getAuthenticationPasswordKeySHA1();
1243             byte[] authkey = SnmpUtilities.getLocalizedKeySHA1(passwKey, snmpEngineId);
1244             computedFingerprint = SnmpUtilities.getFingerPrintSHA1(authkey, message);
1245         } else if (authenticationProtocol == SHA256_PROTOCOL) {
1246             byte[] passwKey = getAuthenticationPasswordKeySHA256();
1247             byte[] authkey = SnmpUtilities.getLocalizedKeySHA256(passwKey, snmpEngineId);
1248             computedFingerprint = SnmpUtilities.getFingerPrintSHA256(authkey, message);
1249         } else if (authenticationProtocol == SHA512_PROTOCOL) {
1250             byte[] passwKey = getAuthenticationPasswordKeySHA512();
1251             byte[] authkey = SnmpUtilities.getLocalizedKeySHA512(passwKey, snmpEngineId);
1252             computedFingerprint = SnmpUtilities.getFingerPrintSHA512(authkey, message);
1253         } else if (authenticationProtocol == SHA224_PROTOCOL) {
1254             byte[] passwKey = getAuthenticationPasswordKeySHA224();
1255             byte[] authkey = SnmpUtilities.getLocalizedKeySHA224(passwKey, snmpEngineId);
1256             computedFingerprint = SnmpUtilities.getFingerPrintSHA224(authkey, message);
1257         } else if (authenticationProtocol == SHA384_PROTOCOL) {
1258             byte[] passwKey = getAuthenticationPasswordKeySHA384();
1259             byte[] authkey = SnmpUtilities.getLocalizedKeySHA384(passwKey, snmpEngineId);
1260             computedFingerprint = SnmpUtilities.getFingerPrintSHA384(authkey, message);
1261         }
1262         return computedFingerprint;
1263     }
1264 
1265 }