home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / submit / auth_submit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  25.3 KB  |  986 lines

  1. #include "util.h"
  2. #include "mmdf.h"
  3. #include "cmd.h"
  4. #include "ch.h"
  5. #include "dm.h"
  6. #include "ap.h"
  7.  
  8. /*
  9.  *  This module applies authorization on the basis of channel
  10.  *  sending host, receiving host,  sender, and recipient.
  11.  *
  12.  *  Initial coding Steve Kille.  Jan 84
  13.  */
  14.  
  15. extern struct ll_struct *logptr;
  16.  
  17. extern long tx_msize;
  18. extern int adruid;
  19.  
  20. extern char     *authfile;              /* file with warning message    */
  21. extern char     *authrequest;           /* where to send error request to */
  22.  
  23. extern char *locdomain;
  24. extern char *locname;
  25. extern char *adr_fulldmn;
  26. extern char *supportaddr;
  27. extern char *mgt_return;
  28.  
  29. Table *authtable;
  30.  
  31. char auth_msg [LINESIZE*2];
  32.  
  33.                 /* space for auth error message   */
  34.                 /* to be passed upwards by submit */
  35. extern char *logdfldir;
  36.  
  37. extern struct ll_struct authlog;
  38. struct ll_struct *alogptr = &authlog;
  39.  
  40. char *user_string = "username";
  41.  
  42. extern char *index();
  43. extern char *rindex();
  44. extern long atol();
  45. extern char *dupfpath();
  46. extern char *strdup();
  47. extern char *multcat();
  48.  
  49. char *get_route();
  50.  
  51. LOCFUN auth_warn(), auth_ok(), auth_fetch(), auth_log();
  52.  
  53.  
  54. /*
  55.  *  Structures needed for by user authorization
  56.  */
  57.  
  58.                 /* values for user auth */
  59.  
  60. #define AUTH_SEND 1             /* send only            */
  61. #define AUTH_RECV 2             /* receive only         */
  62. #define AUTH_BOTH 3             /* send + receive       */
  63. #define AUTH_LIST 4             /* mailing list         */
  64. #define AUTH_BAD  -1            /* not authorized       */
  65. #define AUTH_EXPIRE -2          /* authorization expired*/
  66.  
  67. #define AUTH_NCHANS 15          /* max channels can have */
  68.  
  69. struct auth_struct
  70. {
  71.     int         a_type;         /* auth type            */
  72.     int         a_nchans;       /* number of channels   */
  73.     Chan        *a_chans [AUTH_NCHANS];
  74.                 /* channel list         */
  75.     char        *a_addr;        /* the address          */
  76.     char        *a_reason;      /* rason for expiry     */
  77. };
  78.  
  79. LOCVAR
  80. struct auth_struct auth_sender, /* sender authorization         */
  81.            auth_rcvr;   /* current receiver auth        */
  82.  
  83.  
  84. LOCVAR
  85. int  auth_do;                   /* is this mesage being authorized?     */
  86.                 /* prevents logging on local and other  */
  87.                 /* uninteresting traffic                */
  88.  
  89. LOCVAR
  90. char *route_in;                 /* route assocaited with incoming       */
  91.                 /* address                              */
  92. LOCVAR
  93. char *route_out;
  94.  
  95. LOCVAR
  96. char *cn_in, *cn_out;           /* storage for channel names            */
  97.                 /* needed for bad auth logging          */
  98.  
  99.  
  100. /* */
  101.                 /* Authorization initialisation policy  */
  102.                 /* Store data on sender                 */
  103.  
  104. auth_init (sender, trust)
  105. char *sender;                   /* Message sender (normalized)          */
  106. int trust;                      /* can we trust this? (NRMFROM)         */
  107. {
  108.      char *p;
  109. #ifdef DEBUG
  110.      ll_log (logptr, LLOGBTR, "auth_init (%s)", sender);
  111. #endif
  112.  
  113.      auth_sender.a_type = AUTH_BAD;
  114.      auth_do = FALSE;
  115.                   /* SEK this is needed so that WARN/LOG  */
  116.                   /* work correctly for host auth         */
  117.  
  118.      if (alogptr -> ll_file[0] != '/')
  119.      alogptr -> ll_file = dupfpath (alogptr -> ll_file, logdfldir);
  120.  
  121.                 /* strip  local domain for loocup      */
  122.      auth_sender.a_addr= strdup (sender);
  123.      auth_sender.a_nchans = 0;    /* make sure this has safe value        */
  124.      auth_sender.a_reason = (char *) 0;
  125.  
  126.      if (isstr(sender))
  127.      route_in = get_route (sender);
  128.      else
  129.      route_in = (char *)0;
  130.  
  131.      if ((authtable = tb_nm2struct ("auth")) == (Table *) NOTOK)
  132.     return;
  133.  
  134.      if ( auth_sender.a_addr && auth_sender.a_addr[0] != '@')
  135.      {
  136.     if ((p = index (auth_sender.a_addr, '@')) != (char *) 0)
  137.        if (lexequ (p + 1, adr_fulldmn))
  138.         *p = '\0';
  139.      }
  140.                   /* Table exists, so look up sender      */
  141.      if (!trust && (adruid != 0))
  142.                 /* This can't be authorized             */
  143.     auth_sender.a_type = AUTH_BAD;
  144.      else
  145.     auth_fetch (&auth_sender);
  146. }
  147. /* */
  148.             /* initialise user check, as user may be */
  149.             /*  checked in the context of a number of */
  150.             /* channels                               */
  151. auth_uinit (adr)
  152. char *adr;               /* address being authorized             */
  153. {
  154.     char        *p,
  155.         *q;
  156. #ifdef DEBUG
  157.     ll_log (logptr, LLOGBTR, "auth_uinit (%s)", adr);
  158. #endif
  159.     auth_msg [0] = '\0';
  160.     route_out = (char *) 0;
  161.  
  162.     if (authtable == (Table *) NOTOK)
  163.     {
  164.     auth_rcvr.a_addr = strdup (adr);
  165.     auth_rcvr.a_type= AUTH_BAD;
  166.             /* Assume no authorization as default   */
  167.     return;
  168.     }
  169.  
  170.             /* this jiggling is to map local names */
  171.             /* on other local machines to just      */
  172.             /* user names                           */
  173.             /* e.g.  ~foo@44c.ucl-cs.ac.uk -> foo   */
  174.     if (adr[0] != '@')
  175.     {
  176.     p = index (adr, '@');
  177.     if (p != (char *) 0)
  178.     {
  179.         q = index (p + 1, '.');
  180.         if (lexequ (p+1, adr_fulldmn) ||
  181.             ((q != 0) && lexequ (q+1, adr_fulldmn)))
  182.         {
  183.         *p = '\0';
  184.         if (adr[0] == '~')
  185.             auth_rcvr.a_addr = strdup (&adr[1]);
  186.         else
  187.             auth_rcvr.a_addr = strdup (adr);
  188.         *p= '@';
  189.         }
  190.         else
  191.         auth_rcvr.a_addr = strdup (adr);
  192.     }
  193.     else
  194.         auth_rcvr.a_addr = strdup (adr);
  195.     }
  196.     else
  197.     auth_rcvr.a_addr = strdup (adr);
  198.  
  199.  
  200.                 /* Do not look up until needed - just mark */
  201.     auth_rcvr.a_nchans = -1;
  202.     auth_rcvr.a_reason = (char *) 0;
  203. }
  204.  
  205.                 /* clean up user structures             */
  206. auth_uend ()
  207. {
  208. #ifdef DEBUG
  209.     ll_log (logptr, LLOGBTR, "auth_uend (), %d", authtable);
  210. #endif
  211.     free (auth_rcvr.a_addr);
  212.     if (authtable != (Table *) NOTOK)
  213.     {
  214.     if (auth_rcvr.a_reason != (char *) 0)
  215.         free (auth_rcvr.a_reason);
  216.     }
  217.     if (route_out != (char *) 0)
  218.     free (route_out);
  219. }
  220.  
  221.  
  222. /* */
  223.                 /* Perform checks for a given address  */
  224. LOCVAR char *a_fmt = "i='%s' o='%s' a='%s' r='%s' r='%s'";
  225. LOCVAR char *h_fmt = "i='%s' o='%s' a='%s' r='%s' hi='%s' ho='%s'";
  226.  
  227. #define AOKNUM 50
  228.  
  229. auth_user (h_in, h_out, chan_in, chan_out)
  230. char *h_in;                     /* host (not domain) directly from      */
  231. char *h_out;                    /* host (not domain) being connected to */
  232. Chan *chan_in;                  /* incoming channel                     */
  233. Chan *chan_out;                 /* outgoing channel                     */
  234. {
  235.     char ch_in_auth;            /* user auth needed for incomin chan    */
  236.     char ch_out_auth;           /* ditto for outgoing chan              */
  237.     char in_hostanduser;         /* flag if both host AND user auth needed */
  238.     char out_hostanduser;        /* flag if both host AND user auth needed */
  239.     int gotinbound;
  240.     int gotoutbound;
  241.     char linebuf [LINESIZE];
  242.     int argc;
  243.     char *argv[AOKNUM];
  244.     int ind;
  245.     char *in_auth_str;
  246.     char *out_auth_str;
  247.     char *host_in;
  248.     char *host_out;
  249.  
  250. #ifdef DEBUG
  251.     ll_log (logptr, LLOGBTR, "auth_user (hin='%s', hout='%s', cin='%s', cout='%s'",
  252.         h_in, h_out, chan_in -> ch_show, chan_out -> ch_show);
  253. #endif
  254.     ch_in_auth = chan_in -> ch_auth & CH_IN_AUTH;
  255.     ch_out_auth = chan_out -> ch_auth & CH_OUT_AUTH;
  256.  
  257.     /* return immediately if no checks needed */
  258.     if ((ch_in_auth == 0) && (ch_out_auth == 0))
  259.     return (TRUE);
  260.  
  261.     cn_in = chan_in -> ch_name;
  262.     cn_out = chan_out -> ch_name;
  263.     in_hostanduser = FALSE;
  264.     out_hostanduser = FALSE;
  265.  
  266.     if ((chan_out -> ch_auth & CH_DHO) == CH_DHO)
  267.     {
  268.     if (route_out == (char*) 0)
  269.         route_out = get_route (auth_rcvr.a_addr);
  270.     host_out = route_out;
  271.     }
  272.     else
  273.     host_out = h_out;
  274.  
  275.     if ((chan_in -> ch_auth & CH_DHO) == CH_DHO)
  276.     host_in = route_in;
  277.     else
  278.     host_in = h_in;
  279.  
  280.     if ((chan_out -> ch_auth & CH_HAU) == CH_HAU)
  281.     out_hostanduser = TRUE;
  282.     if ((chan_in -> ch_auth & CH_HAU) == CH_HAU)
  283.     in_hostanduser = TRUE;
  284.  
  285.                 /* initallialy check hostwise agreements */
  286.                 /* log any messages so authorized        */
  287.  
  288.                 /* 1 outbound host, ch_out              */
  289.                 /* h_out:c_in/h_in                      */
  290.     if (chan_out -> ch_outdest != (Table *) 0)
  291.     {
  292.     if (tb_k2val (chan_out -> ch_outdest, TRUE, host_out, linebuf)==OK)
  293.     {                         /* this destination is listed         */
  294.         argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
  295.         if (argc == 0)        /* authorized for all senders         */
  296.         {
  297.         auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  298.             auth_rcvr.a_addr, "OH", "", host_out);
  299.         if (out_hostanduser)
  300.             goto douser;
  301.         return (TRUE);
  302.         }
  303.         for (ind = 0; ind < argc; ind++)
  304.                   /* all hosts on channel authorized?  */
  305.         if (lexequ (chan_in -> ch_name, argv[ind]))
  306.         {
  307.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  308.                 auth_rcvr.a_addr, "CH", "", host_out);
  309.             if (out_hostanduser)
  310.             goto douser;
  311.             return (TRUE); /*  this pair is authorized      */
  312.         }
  313.         for (ind = 0; ind < argc; ind++)
  314.                        /* host, itself, authorized?    */
  315.         if (lexequ (host_in, argv[ind]))
  316.         {
  317.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  318.             auth_rcvr.a_addr, "HH", host_in, host_out);
  319.             if (out_hostanduser)
  320.             goto douser;
  321.             return (TRUE);
  322.         }
  323.     }
  324.     }
  325.  
  326.                 /* 2 inbound hosts, ch_in               */
  327.                 /* h_in:c_out/h_out                     */
  328.  
  329.     if (chan_in -> ch_insource != (Table *) 0)
  330.     {
  331.     if (tb_k2val (chan_in -> ch_insource, TRUE, host_in, linebuf)==OK)
  332.     {                         /* this destination is listed         */
  333.         argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
  334.         if (argc == 0)        /* authorized for all senders         */
  335.         {
  336.         auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  337.             auth_rcvr.a_addr, "IH", host_in, "");
  338.         if (in_hostanduser)
  339.             goto douser;
  340.         return (TRUE);
  341.         }
  342.         for (ind = 0; ind < argc; ind++)
  343.                   /* all hosts on channel authorized?  */
  344.         if (lexequ (chan_out -> ch_name, argv[ind]))
  345.         {
  346.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  347.                 auth_rcvr.a_addr, "HC", host_in, "");
  348.             if (in_hostanduser)
  349.             goto douser;
  350.             return (TRUE); /*  this pair is authorized      */
  351.         }
  352.         for (ind = 0; ind < argc; ind++)
  353.                        /* host, itself, authorized?    */
  354.         if (lexequ (host_out, argv[ind]))
  355.         {
  356.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  357.             auth_rcvr.a_addr, "HH", host_in, host_out);
  358.             if (in_hostanduser)
  359.             goto douser;
  360.             return (TRUE);
  361.         }
  362.     }
  363.     }
  364.  
  365.  
  366.                     /* 3 inbound hosts, ch_out      */
  367.                     /* c_in:h_out                   */
  368.                     /* h_in:h_out                   */
  369.  
  370.  
  371.     if (chan_out -> ch_outsource != (Table *) 0)
  372.     {
  373.     if (tb_k2val (chan_out -> ch_outsource, TRUE,
  374.                     chan_in -> ch_name, linebuf)==OK)
  375.     {                         /* source channel is listed           */
  376.         argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
  377.         if (argc == 0)        /* authorized for all receivers       */
  378.         {
  379.         auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  380.                 auth_rcvr.a_addr, "CC", "", "");
  381.         if (out_hostanduser)
  382.             goto douser;
  383.         return (TRUE);
  384.         }
  385.         for (ind = 0; ind < argc; ind++)
  386.         if (lexequ (host_out, argv[ind]))
  387.         {
  388.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  389.             auth_rcvr.a_addr, "CH", "", host_out);
  390.             if (out_hostanduser)
  391.             goto douser;
  392.             return (TRUE); /* this channel is authorized        */
  393.         }
  394.     }
  395.     if (tb_k2val (chan_out -> ch_outsource, TRUE,
  396.                 host_in, linebuf)==OK)
  397.     {                         /* this source is listed              */
  398.         argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
  399.         if (argc == 0)        /* authorized for all receivers       */
  400.         {
  401.         auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  402.             auth_rcvr.a_addr, "IH", host_in, "");
  403.         if (out_hostanduser)
  404.             goto douser;
  405.         return (TRUE);
  406.         }
  407.         for (ind = 0; ind < argc; ind++)
  408.         if (lexequ (host_out, argv[ind]))
  409.         {
  410.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  411.             auth_rcvr.a_addr, "HH", host_in, host_out);
  412.             if (out_hostanduser)
  413.             goto douser;
  414.             return (TRUE); /* this pair is authorized           */
  415.         }
  416.     }
  417.     }
  418.  
  419.                 /* 4, outbound hosts, ch_in               */
  420.                 /* h_out:h_in                             */
  421.                 /* c_out:h_in                             */
  422.  
  423.     if (chan_in -> ch_indest != (Table *) 0)
  424.     {
  425.     if (tb_k2val (chan_in -> ch_indest, TRUE,
  426.                     chan_out -> ch_name, linebuf)==OK)
  427.     {                         /* source channel is listed           */
  428.         argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
  429.         if (argc == 0)        /* authorized for all receivers       */
  430.         {
  431.         auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  432.                 auth_rcvr.a_addr, "CC", "", "");
  433.         if (in_hostanduser)
  434.             goto douser;
  435.         return (TRUE);
  436.         }
  437.         for (ind = 0; ind < argc; ind++)
  438.         if (lexequ (host_in, argv[ind]))
  439.         {
  440.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  441.             auth_rcvr.a_addr, "HC", host_in, "");
  442.             if (in_hostanduser)
  443.             goto douser;
  444.             return (TRUE); /* this channel is authorized        */
  445.         }
  446.     }
  447.     if (tb_k2val (chan_in -> ch_indest, TRUE,
  448.                 host_out, linebuf)==OK)
  449.     {                         /* this source is listed              */
  450.         argc = str2arg (linebuf, AOKNUM, argv, (char *)0);
  451.         if (argc == 0)        /* authorized for all receivers       */
  452.         {
  453.         auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  454.             auth_rcvr.a_addr, "OH", "", host_out);
  455.         if (in_hostanduser)
  456.             goto douser;
  457.         return (TRUE);
  458.         }
  459.         for (ind = 0; ind < argc; ind++)
  460.         if (lexequ (host_in, argv[ind]))
  461.         {
  462.             auth_log (h_fmt, chan_in -> ch_name, chan_out -> ch_name,
  463.             auth_rcvr.a_addr, "HH", host_in, host_out);
  464.             if (in_hostanduser)
  465.             goto douser;
  466.             return (TRUE); /* this pair is authorized           */
  467.         }
  468.     }
  469.     }
  470.  
  471. #ifdef DEBUG
  472.     ll_log (logptr, LLOGFTR, "Checking auth:  need in =%o out =%o",
  473.         ch_in_auth, ch_out_auth);
  474. #endif
  475.  
  476.     if (in_hostanduser || out_hostanduser)
  477.     {
  478.     auth_log ("NO HOST AUTH i='%s' o='%s' s='%s' r='%s' msg='%s'",
  479.        cn_in, cn_out, auth_sender.a_addr, auth_rcvr.a_addr, auth_msg);
  480.     return (FALSE);
  481.     }
  482.  
  483.  
  484. douser:
  485.     in_auth_str = "";
  486.     out_auth_str = "";
  487.  
  488.     if (ch_in_auth == 0)
  489.     gotinbound = TRUE;
  490.     else
  491.     gotinbound = FALSE;
  492.  
  493.     if (ch_out_auth ==  0)
  494.     gotoutbound = TRUE;
  495.     else
  496.     gotoutbound = FALSE;
  497.  
  498.  
  499.             /* lookup value if needed               */
  500.     if ((auth_rcvr.a_nchans < 0) && (authtable != (Table *) NOTOK))
  501.     {
  502.     auth_rcvr.a_nchans = 0;
  503.     auth_fetch (&auth_rcvr);
  504.     }
  505.  
  506.  
  507.             /* now see if we can find any user authorization */
  508.             /* if recipeint is authorized list, charge by pref */
  509.     if (auth_rcvr.a_type == AUTH_LIST)
  510.     {
  511.     if (!gotinbound)
  512.         if (gotinbound = auth_ok (chan_in, &auth_rcvr, AUTH_RECV))
  513.         {
  514.         in_auth_str = "IL";
  515.         if (gotoutbound)
  516.         {
  517.              auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  518.             auth_rcvr.a_addr, in_auth_str, out_auth_str);
  519.             return (TRUE);
  520.         }
  521.         }
  522.     if (!gotoutbound)
  523.         if (gotoutbound = auth_ok (chan_out, &auth_rcvr, AUTH_RECV))
  524.         {
  525.         out_auth_str ="OL";
  526.         if (gotinbound)
  527.         {
  528.              auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  529.             auth_rcvr.a_addr, in_auth_str, out_auth_str);
  530.             return (TRUE);
  531.         }
  532.         }
  533.     }
  534.             /* Now  check sender                            */
  535.     if (!gotinbound)
  536.     if (gotinbound = auth_ok (chan_in, &auth_sender, AUTH_SEND))
  537.     {
  538.         in_auth_str = "IS";
  539.         if (gotoutbound)
  540.         {
  541.          auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  542.             auth_rcvr.a_addr, in_auth_str, out_auth_str);
  543.         return (TRUE);
  544.         }
  545.     }
  546.     else if (auth_rcvr.a_type == AUTH_LIST)
  547.         switch (ch_in_auth)
  548.         {
  549.         case  CH_IN_BLOCK:
  550.             return (FALSE);
  551.         case  CH_IN_WARN:
  552.             auth_warn ();
  553.         default:
  554.             in_auth_str = "*I";
  555.             if (gotoutbound)
  556.             {
  557.             auth_log (a_fmt, chan_in -> ch_name,
  558.                 chan_out -> ch_name,
  559.                 auth_rcvr.a_addr, in_auth_str, out_auth_str);
  560.             return (TRUE);
  561.             }
  562.             gotinbound = TRUE;
  563.         }
  564.  
  565.     if (!gotoutbound)
  566.     if (gotoutbound = auth_ok (chan_out, &auth_sender, AUTH_SEND))
  567.     {
  568.         out_auth_str ="OS";
  569.         if (gotinbound)
  570.         {
  571.          auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  572.             auth_rcvr.a_addr, in_auth_str, out_auth_str);
  573.         return (TRUE);
  574.         }
  575.     }
  576.     else if (auth_rcvr.a_type == AUTH_LIST)
  577.         switch (ch_out_auth)
  578.         {
  579.         case  CH_OUT_BLOCK:
  580.             return (FALSE);
  581.         case  CH_OUT_WARN:
  582.             auth_warn ();
  583.         default:
  584.             out_auth_str = "*O";
  585.             auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  586.             auth_rcvr.a_addr, in_auth_str, out_auth_str);
  587.             return (TRUE);
  588.         }
  589.  
  590.                 /* if not done aready, check receiver   */
  591.     if (auth_rcvr.a_type == AUTH_LIST)
  592.      return (FALSE);
  593.  
  594.  
  595.     if (!gotinbound)
  596.     if (gotinbound = auth_ok (chan_in, &auth_rcvr, AUTH_RECV))
  597.     {
  598.         in_auth_str = "IR";
  599.         if (gotoutbound)
  600.         {
  601.          auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  602.             auth_rcvr.a_addr, in_auth_str, out_auth_str);
  603.         return (TRUE);
  604.         }
  605.     }
  606.     else
  607.         switch (ch_in_auth)
  608.         {
  609.         case  CH_IN_BLOCK:
  610.             return (FALSE);
  611.         case  CH_IN_WARN:
  612.             auth_warn ();
  613.         default:
  614.             in_auth_str = "*I";
  615.             if (gotoutbound)
  616.             {
  617.               auth_log (a_fmt, chan_in -> ch_name,
  618.                 chan_out -> ch_name,
  619.                 auth_rcvr.a_addr, in_auth_str, out_auth_str);
  620.               return (TRUE);
  621.             }
  622.             gotinbound = TRUE;
  623.         }
  624.  
  625.     if (!gotoutbound)
  626.     if (gotoutbound = auth_ok (chan_out, &auth_rcvr, AUTH_RECV))
  627.     {
  628.         out_auth_str  = "OR";
  629.         if (gotinbound)
  630.         {
  631.          auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  632.             auth_rcvr.a_addr, in_auth_str, out_auth_str);
  633.          return (TRUE);
  634.         }
  635.     }
  636.     else
  637.         switch (ch_out_auth)
  638.         {
  639.         case  CH_OUT_BLOCK:
  640.             return (FALSE);
  641.         case  CH_OUT_WARN:
  642.             auth_warn ();
  643.         default:
  644.             auth_log (a_fmt, chan_in -> ch_name, chan_out -> ch_name,
  645.             auth_rcvr.a_addr, in_auth_str, "*O");
  646.             return (TRUE);
  647.         }
  648.  
  649.             /* SEK shouldn't get here - I hope              */
  650. #ifdef DEBUG
  651.     ll_log (logptr, LLOGTMP,  "Auth_user - did the impossible");
  652. #endif
  653.     return (FALSE);
  654. }
  655. /* */
  656. LOCFUN auth_warn ()
  657. {
  658.     FILE *fp;
  659.     char buf [LINESIZE];
  660. #ifdef DEBUG
  661.     ll_log (logptr, LLOGBTR, "auth_warn ()");
  662. #endif
  663.     if (!isstr(mgt_return))
  664.     return;
  665.      sprintf (buf, "Authorization Warning Daemon <%s>", authrequest);
  666.      ml_1adr (NO, YES, buf, "Authorization Warning",
  667.         mgt_return);
  668.      ml_txt ("\nNot authorized to send mail to address: ");
  669.      ml_txt (auth_rcvr.a_addr);
  670.      ml_txt ("\n\n");
  671.      if ((fp = fopen (authfile, "r")) == 0)
  672.      {
  673.     ml_txt ("Message  sent anyhow\n\n");
  674.     ll_log (logptr, LLOGTMP,  "Auth warning file '%s' not found",
  675.         authfile);
  676.      }
  677.      else
  678.      ml_file (fp);
  679.      if (ml_end (OK) != OK)
  680.     ll_log (logptr, LLOGTMP, "Failed to send auth warning to '%s'",
  681.         auth_sender.a_addr);
  682. }
  683. /* */
  684.                 /* what to do if bad address            */
  685. auth_bad ()
  686. {
  687. #ifdef DEBUG
  688.     ll_log (logptr, LLOGBTR, "auth_bad()");
  689. #endif
  690.                 /* build string for submit to pass up */
  691.     if (auth_sender.a_type == AUTH_EXPIRE)
  692.     {
  693.     if (auth_sender.a_reason  == (char *) 0)
  694.         sprintf (auth_msg, "sender '%s' no longer authorized for address '%s'",
  695.         auth_sender.a_addr, auth_rcvr.a_addr);
  696.     else
  697.         sprintf (auth_msg, "sender '%s' no authorization for address '%s' for reason: (%s)",
  698.         auth_sender.a_addr,
  699.         auth_rcvr.a_addr,
  700.         auth_sender.a_reason);
  701.     }
  702.     else if (auth_rcvr.a_type == AUTH_EXPIRE)
  703.     {
  704.     if (auth_rcvr.a_reason == (char *) 0)
  705.         sprintf (auth_msg, "recipient '%s' no longer authorized",
  706.             auth_rcvr.a_addr);
  707.     else
  708.         sprintf (auth_msg, "recipient '%s' no authorization for reason: (%s)",
  709.         auth_rcvr.a_addr,
  710.         auth_rcvr.a_reason);
  711.     }
  712.     else
  713. #ifdef  UCL
  714.     sprintf (auth_msg, "  Sender '%s' not authorized.",
  715.                             auth_sender.a_addr);
  716. #else /* UCL */
  717.     sprintf (auth_msg, "sender '%s' not authorized to send to address '%s'",
  718.              auth_sender.a_addr, auth_rcvr.a_addr);
  719. #endif /* UCL */
  720.  
  721.     auth_log ("BAD AUTH i='%s' o='%s' s='%s' r='%s' msg='%s'",
  722.     cn_in, cn_out, auth_sender.a_addr, auth_rcvr.a_addr, auth_msg);
  723. #ifdef  UCL
  724.     strcat (auth_msg, " Mail ");
  725.     strcat (auth_msg, authrequest);
  726.     strcat (auth_msg, " (with an empty message) for help.");
  727. #else /* UCL */
  728.     strcat (auth_msg, " : send queries to ");
  729.     strcat (auth_msg, authrequest);
  730. #endif
  731. }
  732.  
  733.  
  734. /* */
  735.                 /* Perform any authorization ending policy */
  736.  
  737. auth_end ()
  738. {
  739. #ifdef DEBUG
  740.     ll_log (logptr, LLOGBTR, "auth_end()");
  741. #endif
  742.     if (auth_do)
  743.     auth_log ("END size='%ld', sender='%s'", tx_msize, auth_sender.a_addr);
  744.     if (auth_sender.a_addr != (char *)0)
  745.     free (auth_sender.a_addr);
  746.     if (auth_sender.a_reason != (char *) 0)
  747.     free (auth_sender.a_reason);
  748.     if (route_in != (char *)0)
  749.     free (route_in);
  750. }
  751.  
  752. /* */
  753.  
  754.                 /* check if chan matches auth           */
  755. LOCFUN
  756. auth_ok (chan, auth, direction)
  757. Chan    *chan;
  758. struct auth_struct *auth;
  759. int     direction;              /* send or receive                      */
  760. {
  761.     int i;
  762.  
  763. #ifdef DEBUG
  764.     ll_log (logptr, LLOGFTR, "auth_ok (c='%s', u='%s', d='%s')",
  765.     chan -> ch_name, auth -> a_addr,
  766.     (direction == AUTH_RECV) ? "receive" : "send");
  767. #endif
  768.  
  769.     if (auth  -> a_type < 0)
  770.     return (FALSE);
  771.  
  772.     if (direction == AUTH_RECV)
  773.     {
  774.     switch (auth -> a_type)
  775.     {
  776.         case AUTH_SEND:
  777.         return (FALSE);
  778.     }
  779.     }
  780.     else
  781.     {
  782.     switch (auth -> a_type)
  783.     {
  784.         case AUTH_RECV:
  785.         case AUTH_LIST:
  786.         return (FALSE);
  787.     }
  788.     }
  789.  
  790.     for (i = 0; i < auth -> a_nchans; i++)
  791.     if (chan == auth -> a_chans [i])
  792.     {
  793. #ifdef DEBUG
  794.         ll_log (logptr,  LLOGFTR, "Got valid authorization");
  795. #endif
  796.         return (TRUE);
  797.     }
  798.     return (FALSE);
  799. }
  800.  
  801. /* */
  802.  
  803. LOCVAR Cmd
  804.     authmap [] =
  805. {
  806.     "both", AUTH_BOTH,      0,
  807.     "send", AUTH_SEND,      0,
  808.     "recv", AUTH_RECV,      0,
  809.     "list", AUTH_LIST,      0,
  810.     "expire", AUTH_EXPIRE,  0,
  811.     0,      0,              0,
  812. };
  813.  
  814.  
  815.                 /* Get user authorization from table        */
  816. LOCFUN
  817. auth_fetch (auth)
  818. struct auth_struct *auth;       /* where to put the data                    */
  819. {
  820.     char        buf [LINESIZE];
  821.     char        *argv [AUTH_NCHANS + 1];
  822.     int         i,
  823.         argc;
  824. #ifdef DEBUG
  825.     ll_log (logptr, LLOGBTR, "auth_fetch (%s)", auth -> a_addr);
  826. #endif
  827.                 /* implictly auth table exists             */
  828.     if (tb_k2val (authtable, TRUE, auth -> a_addr, buf)!=OK)
  829.     {
  830.     auth -> a_type = AUTH_BAD;
  831.     return;
  832.     }
  833.  
  834. #ifdef DEBUG
  835.     ll_log (logptr, LLOGFTR, "user '%s' has auth '%s'", auth -> a_addr, buf);
  836. #endif
  837.                 /* authorization ha form of type  */
  838.                 /* followed by a list of channels */
  839.     if ((argc = str2arg (buf, AUTH_NCHANS + 1, argv, (char *) 0))
  840.         == NOTOK)
  841.     {
  842.     ll_log (logptr, LLOGTMP, "User '%s' has more that %d chans",
  843.             auth -> a_addr, AUTH_NCHANS);
  844.     auth -> a_type = AUTH_BAD;
  845.     return;
  846.     }
  847.                 /* get auth type                */
  848.     switch (auth -> a_type = cmdsrch (argv[0], 0, authmap))
  849.     {
  850.     case AUTH_BOTH:
  851.     case AUTH_SEND:
  852.     case AUTH_RECV:
  853.     case AUTH_LIST:
  854.         break;
  855.     case  AUTH_EXPIRE:
  856.         break;
  857.     default:
  858.         auth -> a_type = AUTH_EXPIRE;
  859.         auth -> a_reason = strdup (argv [0]);
  860. #ifdef DEBUG
  861.         ll_log (logptr, LLOGFTR, "User '%s' expire reason '%s'",
  862.             auth -> a_addr, argv[0]);
  863. #endif
  864.         break;
  865.     }
  866.  
  867.  
  868.             /* now fill in the chans                */
  869.     auth -> a_nchans = 0;
  870.     for (i = 1; i < argc; i++)
  871.     {
  872.     if ((auth -> a_chans [auth -> a_nchans] = ch_nm2struct (argv[i]))
  873.         == (Chan *) NOTOK)
  874.         ll_log (logptr, LLOGBTR,
  875.         "Unknown channel name '%s' for user '%s'", argv[i], auth -> a_addr);
  876.     else
  877.          auth -> a_nchans++;
  878.     }
  879. #ifdef  DEBUG
  880.     ll_log (logptr, LLOGFTR, "%d channels in total type = %d",
  881.         auth ->  a_nchans, auth -> a_type);
  882. #endif
  883. }
  884.  
  885. /* */
  886.  
  887.                 /* this loggin might be done differnetly */
  888.                 /* later                                 */
  889.  
  890. extern char *mq_munique;
  891.  
  892.                 /* Log authorization info                  */
  893. /*VARARGS1*/
  894. LOCFUN
  895. auth_log (format, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  896. char *format,
  897.     *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
  898. {
  899.     char fbuf [LINESIZE];
  900.  
  901.     auth_do = TRUE;         /* we now care about this message       */
  902.     sprintf (fbuf, "%%s: %s", format);
  903.     ll_log (&authlog, LLOGFST, fbuf, mq_munique, a1, a2, a3, a4, a5,
  904.         a6, a7, a8, a9);
  905. }
  906.  
  907. /* */
  908.  
  909. /*
  910.  * get_route is used to determine the route assocaited with
  911.  * a given address.  This allows authorization on the whole
  912.  * route and not just the connect host.
  913.  * It works by:
  914.  * 1) breaking the address into parts
  915.  * 2) remove the username from the local part, assiming a mix of percent
  916.  *      and UUCP routes.
  917.  *      The username starts right of the rightmost "!", and is
  918.  *      terminated by "%".
  919.  * 3) Put it all back together again
  920.  */
  921. char *get_route (adr)
  922. char *adr;
  923. {
  924.     char        *p, *q, *r;
  925.     AP_ptr      local,          /* pointers for parse coponents         */
  926.         domain,
  927.         route;
  928.     AP_ptr      ap;
  929.  
  930. #ifdef DEBUG
  931.     ll_log (logptr, LLOGBTR, "get_route (%s)", adr);
  932. #endif
  933.  
  934.     ap = ap_s2tree (adr);
  935.  
  936.     ap_t2parts (ap, (AP_ptr *) 0, (AP_ptr *) 0, &local, &domain, &route);
  937.  
  938. #ifdef DEBUG
  939.    ll_log (logptr, LLOGFTR, "local part = '%s'", local -> ap_obvalue);
  940. #endif
  941.                 /* jiggle the local part                */
  942.     if ((p = rindex (local -> ap_obvalue, '!')) == (char *) 0)
  943.     {
  944.     if ((p = index (local -> ap_obvalue, '%')) != (char *) 0)
  945.     {
  946.          q = multcat (p, user_string, (char *)0);
  947.          free (local -> ap_obvalue);
  948.          local -> ap_obvalue = q;
  949.     }
  950.     else
  951.     {
  952.                 /* local part really sseems to be user */
  953.         free (local -> ap_obvalue);
  954.         local -> ap_obvalue = strdup (user_string);
  955.     }
  956.     }
  957.     else
  958.     {
  959.                 /* p points to last "!"                 */
  960.     q = index (p, '%');
  961.     p++;
  962.     *p = '\0';
  963.     if (q != (char *) 0)
  964.         r = multcat (local -> ap_obvalue, user_string, q, (char *)0);
  965.     else
  966.         r  = multcat (local -> ap_obvalue, user_string, (char *)0);
  967.     *p =  '%';
  968.     free (local -> ap_obvalue);
  969.     local -> ap_obvalue = r;
  970.     }
  971.  
  972. #ifdef DEBUG
  973.    ll_log (logptr, LLOGFTR, "Munged local part = '%s'", local -> ap_obvalue);
  974. #endif
  975.  
  976.     p = ap_p2s ((AP_ptr) 0, (AP_ptr) 0, local, domain, route);
  977.  
  978.     ap_sqdelete (ap, (AP_ptr)0);
  979.     ap_free (ap);
  980.  
  981. #ifdef DEBUG
  982.     ll_log (logptr,LLOGFTR, "Auth ROUTE is '%s'",(p==(char*)MAYBE)?"MAYBE":p);
  983. #endif
  984.     return (p);
  985. }
  986.