Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PL/SQL 12.93 KB | None | 0 0
  1. CREATE OR REPLACE PACKAGE utl_jabber
  2.     IS
  3.  
  4.     /*
  5.     begin
  6.       -- UTL_JABBER.debug( true );
  7.       IF ( UTL_JABBER.attach( 'testserver' )) THEN
  8.         IF ( UTL_JABBER.logon( 'test', 'password', false )) THEN
  9.           UTL_JABBER.status( UTL_JABBER.STATUS_ONLINE, 'Hello world!' );
  10.           UTL_JABBER.send( 'user@'testserver', 'Message' );
  11.         END IF;
  12.         UTL_JABBER.detach;
  13.       END IF;
  14.       EXCEPTION WHEN OTHERS THEN
  15.         UTL_TCP.CLOSE_ALL_CONNECTIONS;
  16.     end;
  17.     */
  18.  
  19.     FUNCTION attach(v_host IN VARCHAR2,
  20.                                     v_hostname IN VARCHAR2 := NULL,
  21.                                     v_port IN NUMBER := 5222)
  22.         RETURN BOOLEAN;
  23.     PROCEDURE detach;
  24.  
  25.     FUNCTION logon(v_user IN VARCHAR2,
  26.                                  v_password IN VARCHAR2,
  27.                                  b_plaintext IN BOOLEAN := TRUE)
  28.         RETURN BOOLEAN;
  29.  
  30.     status_online CONSTANT PLS_INTEGER := 0;
  31.     status_offline CONSTANT PLS_INTEGER := 1;
  32.     status_invisible CONSTANT PLS_INTEGER := 2;
  33.     status_chat CONSTANT PLS_INTEGER := 3;
  34.     status_away CONSTANT PLS_INTEGER := 4;
  35.     status_na CONSTANT PLS_INTEGER := 5;
  36.     status_dnd CONSTANT PLS_INTEGER := 6;
  37.     PROCEDURE status(n_value IN PLS_INTEGER,
  38.                                      v_note IN VARCHAR2 := NULL,
  39.                                      n_priority IN NUMBER := 5);
  40.  
  41.     PROCEDURE send(v_to IN VARCHAR2,
  42.                                  v_message IN VARCHAR2);
  43.     PROCEDURE debug(b_enable IN BOOLEAN);
  44.  
  45. END utl_jabber;
  46. /
  47.  
  48. CREATE OR REPLACE PACKAGE BODY user_setup.utl_jabber
  49.     IS
  50.     tcp_timeout_min NUMBER(1, 3) := 0.001;
  51.     tcp_timeout_max NUMBER(2, 0) := 2;
  52.     vc_resource CONSTANT VARCHAR2(10 CHAR) := 'utl_jabber';
  53.  
  54.     tcp_connection UTL_TCP.connection := NULL;
  55.     v_session_id VARCHAR2(256 CHAR) := NULL;
  56.     v_hostconnect VARCHAR2(1024 CHAR) := NULL;
  57.     b_connect BOOLEAN := FALSE;
  58.     b_logon BOOLEAN := FALSE;
  59.     b_debug BOOLEAN := FALSE;
  60.     n_status PLS_INTEGER := status_offline;
  61.  
  62.     TYPE t_iq IS RECORD (
  63.             id              VARCHAR2(256 CHAR),
  64.             TYPE            VARCHAR2(256 CHAR),
  65.             xmlns           VARCHAR2(256 CHAR),
  66.             sender      VARCHAR2(1024 CHAR),
  67.             recipient VARCHAR2(1024 CHAR),
  68.             BODY            VARCHAR2(32767 CHAR)
  69.         );
  70.  
  71.     TYPE t_message IS RECORD (
  72.             id              VARCHAR2(256 CHAR),
  73.             TYPE            VARCHAR2(256 CHAR),
  74.             recipient VARCHAR2(1024 CHAR),
  75.             BODY            VARCHAR2(32767 CHAR)
  76.         );
  77.  
  78.     TYPE t_presence IS RECORD (
  79.             TYPE         VARCHAR2(12 CHAR),
  80.             isshow   BOOLEAN,
  81.             status   VARCHAR2(256 CHAR),
  82.             priority NUMBER
  83.         );
  84.  
  85.     PROCEDURE put(v_string IN VARCHAR2,
  86.                                 len_delimiter IN NUMBER := 250)
  87.         IS
  88.             v_startloc PLS_INTEGER DEFAULT 0;
  89.             v_endloc PLS_INTEGER DEFAULT 0;
  90.             v_len PLS_INTEGER;
  91.             v_atom VARCHAR2(255 CHAR);
  92.         BEGIN
  93.             IF (v_string IS NOT NULL) THEN
  94.                 v_len := LENGTH(v_string);
  95.                 LOOP
  96.                     v_endloc := LEAST(v_len, NVL(len_delimiter, 250) + v_startloc);
  97.                     v_atom := SUBSTR(v_string, v_startloc, v_endloc - v_startloc + 1);
  98.                     DBMS_OUTPUT.put_line(v_atom);
  99.                     v_startloc := v_endloc - 1;
  100.                     EXIT WHEN v_endloc = v_len;
  101.                 END LOOP;
  102.             END IF;
  103.         EXCEPTION
  104.             WHEN OTHERS THEN NULL;
  105.         END put;
  106.  
  107.     FUNCTION md5(v_value IN VARCHAR2)
  108.         RETURN VARCHAR2 deterministic
  109.         IS
  110.         BEGIN
  111.             RETURN UTL_RAW.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.md5(input_string => v_value));
  112.         END md5;
  113.  
  114.     PROCEDURE fix_id(v_id IN OUT VARCHAR2)
  115.         IS
  116.         BEGIN
  117.             IF (v_id IS NULL) THEN
  118.                 v_id := md5(TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS') || SYS_CONTEXT('USERENV', 'IP_ADDRESS') || DBMS_RANDOM.VALUE);
  119.             END IF;
  120.         END fix_id;
  121.  
  122.     PROCEDURE debug(b_enable IN BOOLEAN)
  123.         IS
  124.         BEGIN
  125.             b_debug := b_enable;
  126.         END debug;
  127.  
  128.     FUNCTION value_get(v_xml IN VARCHAR2,
  129.                                          v_element IN VARCHAR2,
  130.                                          v_attribute IN VARCHAR2)
  131.         RETURN VARCHAR2
  132.         IS
  133.             n_pos PLS_INTEGER;
  134.             n_last PLS_INTEGER;
  135.             v_answer VARCHAR2(32767 CHAR);
  136.             v_result VARCHAR2(32767 CHAR);
  137.         BEGIN
  138.             v_result := NULL;
  139.             v_answer := REPLACE(v_xml, '''', NULL);
  140.             v_answer := REPLACE(v_answer, '"', NULL);
  141.             n_pos := INSTR(v_answer, v_attribute, INSTR(v_answer, v_element)) + LENGTH(v_attribute) + 1;
  142.             IF (n_pos > LENGTH(v_attribute) + 1) THEN
  143.                 n_last := INSTR(v_answer, ' ', n_pos);
  144.                 IF (n_last = 0) THEN
  145.                     n_last := INSTR(v_answer, '>', n_pos);
  146.                 ELSE
  147.                     n_last := LEAST(n_last, INSTR(v_answer, '>', n_pos));
  148.                 END IF;
  149.                 v_result := SUBSTR(v_answer, n_pos, n_last - n_pos);
  150.             END IF;
  151.             RETURN v_result;
  152.         END value_get;
  153.  
  154.     PROCEDURE server_logoff
  155.         IS
  156.         BEGIN
  157.             b_connect := FALSE;
  158.             UTL_TCP.close_connection(tcp_connection);
  159.         EXCEPTION
  160.             WHEN OTHERS THEN IF (b_debug) THEN
  161.                         put(SQLERRM);
  162.                     END IF;
  163.         END server_logoff;
  164.  
  165.     PROCEDURE server_logon(v_host IN VARCHAR2,
  166.                                                  n_port IN NUMBER := 5222)
  167.         IS
  168.         BEGIN
  169.             IF (b_connect) THEN
  170.                 server_logoff;
  171.             END IF;
  172.             tcp_connection := UTL_TCP.open_connection(v_host, n_port);
  173.             b_connect := TRUE;
  174.         EXCEPTION
  175.             WHEN OTHERS THEN b_connect := FALSE;
  176.                     IF (b_debug) THEN
  177.                         put(SQLERRM);
  178.                     END IF;
  179.         END server_logon;
  180.  
  181.     FUNCTION server_read
  182.         RETURN VARCHAR2
  183.         IS
  184.             v_char VARCHAR2(1 CHAR);
  185.             v_result VARCHAR2(32767 CHAR);
  186.             n_timeout NUMBER(5, 3);
  187.         BEGIN
  188.             v_result := NULL;
  189.             n_timeout := 0;
  190.             WHILE (v_result IS NULL)
  191.                 AND (n_timeout < tcp_timeout_max) LOOP
  192.                     --    DBMS_LOCK.SLEEP( tcp_timeout_min );
  193.                     --    WHILE UTL_TCP.AVAILABLE( tcp_connection ) > 0 LOOP
  194.                     WHILE UTL_TCP.available(tcp_connection, tcp_timeout_min) > 0 LOOP
  195.                             v_char := UTL_TCP.get_text(tcp_connection);
  196.                             v_result := v_result || v_char;
  197.                         END LOOP;
  198.                     n_timeout := n_timeout + tcp_timeout_min;
  199.                 END LOOP;
  200.             IF (b_debug) THEN
  201.                 put('TIMEOUT:' || n_timeout);
  202.                 put(v_result);
  203.             END IF;
  204.             RETURN v_result;
  205.         EXCEPTION
  206.             WHEN OTHERS THEN IF (b_debug) THEN
  207.                         put(v_result);
  208.                         put(SQLERRM);
  209.                     END IF;
  210.                     RETURN v_result;
  211.         END server_read;
  212.  
  213.     PROCEDURE server_send(v_pack IN VARCHAR2)
  214.         IS
  215.             v_bytes PLS_INTEGER;
  216.         BEGIN
  217.             IF (b_debug) THEN
  218.                 put(v_pack);
  219.             END IF;
  220.             IF (b_connect) THEN
  221.                 IF (v_pack IS NOT NULL) THEN
  222.                     v_bytes := UTL_TCP.write_line(tcp_connection, CONVERT(v_pack, 'UTF8'));
  223.                 ELSE
  224.                     v_bytes := UTL_TCP.write_line(tcp_connection);
  225.                 END IF;
  226.             END IF;
  227.         EXCEPTION
  228.             WHEN OTHERS THEN IF (b_debug) THEN
  229.                         put('get ' || v_bytes || ' bytes');
  230.                         put(SQLERRM);
  231.                     END IF;
  232.         END server_send;
  233.  
  234.     FUNCTION pack_iq(iq IN OUT t_iq)
  235.         RETURN VARCHAR2 deterministic
  236.         IS
  237.             v_pack VARCHAR2(32767 CHAR);
  238.         BEGIN
  239.             fix_id(iq.id);
  240.             v_pack := '<iq type="' || iq.TYPE || '" id="' || iq.id || '"';
  241.             IF (iq.recipient IS NOT NULL) THEN
  242.                 v_pack := v_pack || ' to="' || iq.recipient || '"';
  243.             END IF;
  244.             IF (iq.sender IS NOT NULL) THEN
  245.                 v_pack := v_pack || ' from="' || iq.sender || '"';
  246.             END IF;
  247.             v_pack := v_pack || '>';
  248.             IF (iq.xmlns IS NOT NULL) THEN
  249.                 v_pack := v_pack || '<query xmlns="' || iq.xmlns || '"';
  250.                 IF (iq.BODY IS NOT NULL) THEN
  251.                     v_pack := v_pack || '>' || iq.BODY || '</query>';
  252.                 ELSE
  253.                     v_pack := v_pack || '/>';
  254.                 END IF;
  255.             END IF;
  256.             v_pack := v_pack || '</iq>';
  257.             RETURN v_pack;
  258.         END pack_iq;
  259.  
  260.     FUNCTION pack_message(message IN OUT t_message)
  261.         RETURN VARCHAR2 deterministic
  262.         IS
  263.             v_pack VARCHAR2(32767 CHAR);
  264.         BEGIN
  265.             fix_id(message.id);
  266.             v_pack := '<message';
  267.             IF (message.TYPE IS NOT NULL) THEN
  268.                 v_pack := v_pack || ' type="' || message.TYPE || '"';
  269.             END IF;
  270.             v_pack := v_pack || ' id="' || message.id || '"';
  271.             IF (message.recipient IS NOT NULL) THEN
  272.                 v_pack := v_pack || ' to="' || message.recipient || '"';
  273.             END IF;
  274.             v_pack := v_pack || '>';
  275.             IF (message.BODY IS NOT NULL) THEN
  276.                 v_pack := v_pack || '<body>' || message.BODY || '</body>';
  277.             END IF;
  278.             v_pack := v_pack || '<x xmlns="jabber:x:event"><composing/></x></message>';
  279.             RETURN v_pack;
  280.         END pack_message;
  281.  
  282.     FUNCTION pack_presence(presence IN t_presence)
  283.         RETURN VARCHAR2 deterministic
  284.         IS
  285.             v_pack VARCHAR2(32767 CHAR);
  286.         BEGIN
  287.             v_pack := '<presence';
  288.             IF (NOT presence.isshow) THEN
  289.                 v_pack := v_pack || ' type="' || presence.TYPE || '"';
  290.             END IF;
  291.             v_pack := v_pack || '>';
  292.             IF ((presence.isshow) AND (presence.TYPE IS NOT NULL)) THEN
  293.                 v_pack := v_pack || '<show>' || presence.TYPE || '</show>';
  294.             END IF;
  295.             IF (presence.status IS NOT NULL) THEN
  296.                 v_pack := v_pack || '<status>' || presence.status || '</status>';
  297.             END IF;
  298.             IF (presence.priority IS NOT NULL) THEN
  299.                 v_pack := v_pack || '<priority>' || presence.priority || '</priority>';
  300.             END IF;
  301.             RETURN v_pack || '</presence>';
  302.         END pack_presence;
  303.  
  304.     PROCEDURE stream_start
  305.         IS
  306.             v_answer VARCHAR2(32767 CHAR);
  307.         BEGIN
  308.             server_send('<?xml version="1.0" encoding="utf-8" ?>');
  309.             server_send('<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" to="' || v_hostconnect || '">');
  310.             v_answer := server_read;
  311.             v_session_id := value_get(v_answer, 'stream:stream', 'id');
  312.             IF (b_debug) THEN
  313.                 put('Session Id:' || v_session_id);
  314.             END IF;
  315.         END stream_start;
  316.  
  317.     PROCEDURE stream_end
  318.         IS
  319.         BEGIN
  320.             server_send('</stream:stream>');
  321.         END stream_end;
  322.  
  323.     PROCEDURE auth_get(v_user IN VARCHAR2,
  324.                                          v_md5 IN OUT VARCHAR2)
  325.         IS
  326.             iq t_iq;
  327.         BEGIN
  328.             iq.id := v_md5;
  329.             iq.TYPE := 'get';
  330.             iq.xmlns := 'jabber:iq:auth';
  331.             iq.recipient := v_hostconnect;
  332.             iq.BODY := v_user;
  333.             server_send(pack_iq(iq));
  334.             v_md5 := iq.id;
  335.         END auth_get;
  336.  
  337.     PROCEDURE auth_set(v_user IN VARCHAR2,
  338.                                          v_password IN VARCHAR2,
  339.                                          v_resource IN VARCHAR2,
  340.                                          v_md5 IN OUT VARCHAR2)
  341.         IS
  342.             iq t_iq;
  343.         BEGIN
  344.             iq.id := v_md5;
  345.             iq.TYPE := 'set';
  346.             iq.xmlns := 'jabber:iq:auth';
  347.             iq.recipient := v_hostconnect;
  348.             iq.BODY := v_user || v_password || v_resource;
  349.             server_send(pack_iq(iq));
  350.             v_md5 := iq.id;
  351.         END auth_set;
  352.  
  353.     FUNCTION logon(v_user IN VARCHAR2,
  354.                                  v_password IN VARCHAR2,
  355.                                  b_plaintext IN BOOLEAN := TRUE)
  356.         RETURN BOOLEAN
  357.         IS
  358.             v_md5 VARCHAR2(32 CHAR);
  359.             v_auth_usr VARCHAR2(256 CHAR);
  360.             v_auth_pwd VARCHAR2(256 CHAR);
  361.             v_resource VARCHAR2(256 CHAR);
  362.             v_answer VARCHAR2(32767 CHAR);
  363.  
  364.             FUNCTION username(v_user IN VARCHAR2)
  365.                 RETURN VARCHAR2 deterministic
  366.                 IS
  367.                     n_pos PLS_INTEGER;
  368.                     v_name VARCHAR2(256 CHAR);
  369.                 BEGIN
  370.                     n_pos := INSTR(v_user, '@') - 1;
  371.                     IF (n_pos > 0) THEN
  372.                         v_name := SUBSTR(v_user, 1, n_pos);
  373.                     ELSE
  374.                         v_name := SUBSTR(v_user, 1);
  375.                     END IF;
  376.                     RETURN TRIM(v_name);
  377.                 END username;
  378.  
  379.         BEGIN
  380.             IF (NOT b_logon) THEN
  381.                 v_md5 := NULL;
  382.                 v_auth_usr := '<username>' || username(v_user) || '</username>';
  383.                 auth_get(v_auth_usr, v_md5);
  384.                 v_answer := server_read;
  385.                 IF (value_get(v_answer, 'iq', 'type') = 'result') THEN
  386.                     v_md5 := NULL;
  387.                     IF ((b_plaintext) OR (v_session_id IS NULL)) THEN
  388.                         v_auth_pwd := '<password>' || v_password || '</password>';
  389.                     ELSE
  390.                         raise_application_error(-20100, 'digest auth not implemented for 9i');
  391.                     -- v_auth_pwd := '<digest>' || LOWER( DBMS_CRYPTO.HASH( UTL_RAW.CAST_TO_RAW( CONVERT( v_session_id || v_password, 'UTF8' )), DBMS_CRYPTO.HASH_SH1 )) || '</digest>';
  392.                     END IF;
  393.                     v_resource := '<resource>' || vc_resource || '</resource>';
  394.                     auth_set(v_auth_usr, v_auth_pwd, v_resource, v_md5);
  395.                     v_answer := server_read;
  396.                     b_logon := (value_get(v_answer, 'iq', 'type') = 'result');
  397.                 END IF;
  398.             END IF;
  399.             RETURN b_logon;
  400.         END logon;
  401.  
  402.     PROCEDURE logoff
  403.         IS
  404.         BEGIN
  405.             status(status_offline);
  406.             b_logon := FALSE;
  407.         END logoff;
  408.  
  409.     FUNCTION attach(v_host IN VARCHAR2,
  410.                                     v_hostname IN VARCHAR2 := NULL,
  411.                                     v_port IN NUMBER := 5222)
  412.         RETURN BOOLEAN
  413.         IS
  414.         BEGIN
  415.             IF (NOT b_connect) THEN
  416.                 server_logon(v_host, v_port);
  417.                 IF (b_connect) THEN
  418.                     IF (v_hostname IS NULL) THEN
  419.                         v_hostconnect := v_host;
  420.                     ELSE
  421.                         v_hostconnect := v_hostname;
  422.                     END IF;
  423.                     stream_start;
  424.                 END IF;
  425.             END IF;
  426.             RETURN b_connect;
  427.         END attach;
  428.  
  429.     PROCEDURE detach
  430.         IS
  431.         BEGIN
  432.             logoff;
  433.             stream_end;
  434.             server_logoff;
  435.         END detach;
  436.  
  437.     PROCEDURE status(n_value IN PLS_INTEGER,
  438.                                      v_note IN VARCHAR2 := NULL,
  439.                                      n_priority IN NUMBER := 5)
  440.         IS
  441.             presence t_presence;
  442.         BEGIN
  443.             --IF ( n_status <> n_value ) THEN
  444.             CASE n_value
  445.                 WHEN status_na THEN presence.TYPE := 'xa';
  446.                 WHEN status_dnd THEN presence.TYPE := 'dnd';
  447.                 WHEN status_away THEN presence.TYPE := 'away';
  448.                 WHEN status_chat THEN presence.TYPE := 'chat';
  449.                 WHEN status_offline THEN presence.TYPE := 'unavailable';
  450.                 WHEN status_invisible THEN presence.TYPE := 'invisible';
  451.                 ELSE NULL;
  452.             END CASE;
  453.             presence.isshow := (n_value NOT IN (status_offline, status_invisible));
  454.             presence.status := v_note;
  455.             presence.priority := n_priority;
  456.             server_send(pack_presence(presence));
  457.             n_status := n_value;
  458.         --END IF;
  459.         END status;
  460.  
  461.     PROCEDURE send(v_to IN VARCHAR2,
  462.                                  v_message IN VARCHAR2)
  463.         IS
  464.             message t_message;
  465.         BEGIN
  466.             IF (b_connect) THEN
  467.                 message.TYPE := 'chat';
  468.                 message.recipient := v_to;
  469.                 message.BODY := v_message;
  470.                 server_send(pack_message(message));
  471.             ELSE
  472.                 IF (b_debug) THEN
  473.                     put('Logon need');
  474.                 END IF;
  475.             END IF;
  476.         END send;
  477.  
  478. END utl_jabber;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement