~ubuntu-branches/ubuntu/karmic/dante/karmic

« back to all changes in this revision

Viewing changes to sockd/serverconfig.c

  • Committer: Bazaar Package Importer
  • Author(s): Thijs Kinkhorst
  • Date: 2006-10-19 12:09:39 UTC
  • mfrom: (3.1.1 dapper)
  • Revision ID: james.westby@ubuntu.com-20061019120939-t818x24e2tn8be5k
Tags: 1.1.18-2.1
* Non-maintainer upload for RC bug.
* Make sure changelogs are installed into all packages (Closes: #393568).

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
#include "config_parse.h"
46
46
 
47
47
static const char rcsid[] =
48
 
"$Id: serverconfig.c,v 1.182 2003/07/01 13:21:41 michaels Exp $";
 
48
"$Id: serverconfig.c,v 1.201 2005/09/14 10:37:24 michaels Exp $";
49
49
 
50
50
__BEGIN_DECLS
51
51
 
126
126
{
127
127
 
128
128
        if (sockscf.state.init) {
129
 
#if 0 /* don't know how to do this now, seems like too much work. */
 
129
#if 0 /* XXX don't know how to do this now, seems like too much work. */
130
130
                int i;
131
131
 
132
132
                for (i = 0; i < sockscf.internalc; ++i)
460
460
        slog(LOG_DEBUG, "userid:\n%s",
461
461
        userids2string(&sockscf->uid, "", buf, sizeof(buf)));
462
462
 
463
 
        slog(LOG_DEBUG, "child.maxidlenumber: %d",
464
 
        sockscf->child.maxidlenumber);
 
463
        slog(LOG_DEBUG, "child.maxidle: %d",
 
464
        sockscf->child.maxidle);
465
465
 
466
466
        bufused = snprintfn(buf, sizeof(buf), "method(s): ");
467
467
        for (i = 0; (size_t)i < sockscf->methodc; ++i)
566
566
 
567
567
        /* stat: keep it. */
568
568
 
569
 
        /* state; keep it. */
 
569
        /* state; keep most of it. */
 
570
#if HAVE_PAM
 
571
        sockscf.state.pamservicename = DEFAULT_PAMSERVICENAME;
 
572
#endif
570
573
 
571
574
        /* methods, read from configfile. */
572
575
        bzero(sockscf.methodv, sizeof(sockscf.methodv));
582
585
        /* uid, read from configfile. */
583
586
        bzero(&sockscf.uid, sizeof(sockscf.uid));
584
587
 
585
 
        /* childstate, some read from configfile, some not. */
586
 
        sockscf.child.maxidlenumber = 0;
 
588
        /* childstate, most read from configfile, but some not. */
 
589
        sockscf.child.maxidle = 0;
587
590
}
588
591
 
589
592
void
735
738
        if (msgsize > 0)
736
739
                *msg = NUL;
737
740
 
738
 
        /* what rulebase to use.  XXX nicer way to do this. */
 
741
        /* what rulebase to use. */
739
742
        switch (state->command) {
740
743
                case SOCKS_ACCEPT:
741
744
                        /* only set by negotiate children so must be clientrule. */
763
766
 
764
767
                /* current rule covers desired command? */
765
768
                switch (state->command) {
 
769
                        /* client-rule commands. */
 
770
                        case SOCKS_ACCEPT:
 
771
                                break;
 
772
 
 
773
                        /* socks-rule commands. */
766
774
                        case SOCKS_BIND:
767
775
                                if (!rule->state.command.bind)
768
776
                                        continue;
790
798
                                        continue;
791
799
                                break;
792
800
 
793
 
                        /* client-rule commands. */
794
 
                        case SOCKS_ACCEPT:
795
 
                                break;
796
 
 
797
801
                        default:
798
802
                                SERRX(state->command);
799
803
                }
830
834
                                SERRX(state->version);
831
835
                }
832
836
 
833
 
                /* current rule allows for selected authentication? */
 
837
                /*
 
838
                 * This is a little tricky.  For some commands we may not
 
839
                 * have all info at time of (preliminary) rulechecks.
 
840
                 * What we want to do if there is no (complete) address given is
 
841
                 * to see if there's any chance at all the rules will permit this
 
842
                 * request when the address (later) becomes available.
 
843
                 * We therefore continue to scan the rules until we either get
 
844
                 * a pass (ignoring peer with missing info), or the default block
 
845
                 * is triggered. 
 
846
                 *
 
847
                 * This is the case for e.g. bindreply and udp, where we will
 
848
                 * have to call this function again when we get the addresses
 
849
                 * in question.
 
850
                 */
 
851
 
 
852
                if (src != NULL) {
 
853
                        if (!addressmatch(&rule->src, src, state->protocol, 0))
 
854
                                continue;
 
855
                }
 
856
                else
 
857
                        if (rule->verdict == VERDICT_BLOCK)
 
858
                                continue; /* continue scan.  It's possible we will get a pass. */
 
859
 
 
860
                if (dst != NULL) {
 
861
                         if (!addressmatch(&rule->dst, dst, state->protocol, 0))
 
862
                                continue;
 
863
                }
 
864
                else
 
865
                        if (rule->verdict == VERDICT_BLOCK)
 
866
                                continue; /* continue scan.  It's possible we will get a pass. */
 
867
 
 
868
                /* current rule authentication matches selected authentication? */
834
869
                if (!methodisset(state->auth.method, rule->state.methodv,
835
870
                rule->state.methodc)) {
836
 
                        size_t methodisok;
837
 
 
838
871
                        /*
839
 
                         * There are some "extra" (non-standard) methods that are independent
840
 
                         * of socks protocol negotiation and it's thus possible
841
 
                         * to get a match on them even if above check failed, i.e.
842
 
                         * it's possible to "upgrade" the method.
 
872
                         * There are some "extra" (non-standard) methods that are 
 
873
                         * independent of socks protocol negotiation, and it's possible
 
874
                         * to get a match on them, even if above check failed.  I.e.
 
875
                         * it's possible to change the method.  E.g. PAM is based 
 
876
                         * on UNAME; if we have UNAME, we can also get PAM.
843
877
                         *
844
878
                         * We therefor look at what methods this rule wants and see
845
 
                         * if can match it with what we have, or get it.
846
 
                         *
 
879
                         * if can match it with what the client _can_ provide, if we
 
880
                         * do some extra work to get the information.
847
881
                         * Currently these methods are: rfc931 and pam.
848
882
                         */
849
883
 
850
 
                        for (i = methodisok = 0; i < methodc; ++i) {
 
884
                        /* 
 
885
                         * This variable only says if current client has provided the
 
886
                         * neccessary information to to check it's access with
 
887
                         * one of the methods required by the current rule.
 
888
                         *
 
889
                         * XXX would be nice to cache this, so we don't have to
 
890
                         * copy memory around each time.
 
891
                         */
 
892
                        size_t methodischeckable = 0;
 
893
 
 
894
                        for (i = 0; i < methodc; ++i) {
851
895
                                if (methodisset(methodv[i], rule->state.methodv,
852
896
                                rule->state.methodc)) {
853
897
                                        switch (methodv[i]) {
861
905
                                                        if (strcmp((char *)state->auth.mdata.rfc931.name,
862
906
                                                        STRING_UNKNOWN) == 0)
863
907
                                                                *state->auth.mdata.rfc931.name = NUL;
864
 
 
865
 
                                                        if (state->auth.mdata.rfc931.name[
 
908
                                                        else if (state->auth.mdata.rfc931.name[
866
909
                                                        sizeof(state->auth.mdata.rfc931.name) - 1] != NUL) {
867
 
                                                                slog(LOG_NOTICE, "%s: rfc931 name truncated", function);
868
910
                                                                state->auth.mdata.rfc931.name[
869
911
                                                                sizeof(state->auth.mdata.rfc931.name) - 1] = NUL;
 
912
                                                                swarnx("%s: rfc931 name \"%s\" truncated", function,
 
913
                                                                state->auth.mdata.rfc931.name);
870
914
 
871
 
                                                                /* better safe than sorry. */
872
915
                                                                *state->auth.mdata.rfc931.name = NUL;
873
916
                                                        }
874
917
 
875
918
                                                        if (*state->auth.mdata.rfc931.name != NUL)
876
 
                                                                methodisok = 1;
 
919
                                                                methodischeckable = 1;
877
920
                                                        break;
878
921
#endif /* HAVE_LIBWRAP */
879
922
 
880
923
#if HAVE_PAM
881
924
                                                case AUTHMETHOD_PAM:
 
925
                                                        /*
 
926
                                                         * PAM can support username/password, just username,
 
927
                                                         * or neither username nor password.
 
928
                                                         */
 
929
 
882
930
                                                        slog(LOG_DEBUG, "%s: trying to find match for pam ...",
883
931
                                                        function);
884
932
 
885
933
                                                        switch (state->auth.method) {
886
934
                                                                case AUTHMETHOD_UNAME: {
887
 
                                                                        /* it's a union, make a copy first. */
888
 
                                                                        const struct authmethod_uname_t uname
889
 
                                                                        = state->auth.mdata.uname;
890
 
 
891
 
                                                                        /* similar enough, just copy name/password. */
892
 
 
893
 
                                                                        strcpy((char *)state->auth.mdata.pam.name,
894
 
                                                                        (const char *)uname.name);
895
 
                                                                        strcpy((char *)state->auth.mdata.pam.password,
896
 
                                                                        (const char *)uname.password);
897
 
 
898
 
                                                                        methodisok = 1;
 
935
                                /* it's a union, make a copy first. */
 
936
                                const struct authmethod_uname_t uname
 
937
                                = state->auth.mdata.uname;
 
938
 
 
939
                                /* similar enough, just copy name/password. */
 
940
                                strcpy((char *)state->auth.mdata.pam.name,
 
941
                                (const char *)uname.name);
 
942
                                strcpy((char *)state->auth.mdata.pam.password,
 
943
                                (const char *)uname.password);
 
944
 
 
945
                                                                        methodischeckable = 1;
899
946
                                                                        break;
900
947
                                                                }
901
948
 
902
949
                                                                case AUTHMETHOD_RFC931: {
903
 
                                                                        /* it's a union, make a copy first. */
904
 
                                                                        const struct authmethod_rfc931_t rfc931
905
 
                                                                        = state->auth.mdata.rfc931;
906
 
 
907
 
                                                                        strcpy((char *)state->auth.mdata.pam.name,
908
 
                                                                        (const char *)rfc931.name);
 
950
                                /* it's a union, make a copy first. */
 
951
                                const struct authmethod_rfc931_t rfc931
 
952
                                = state->auth.mdata.rfc931;
 
953
 
 
954
                                                                        /*
 
955
                                                                         * no password, but we can check for the username 
 
956
                                                                         * we got from ident, with an empty password.
 
957
                                                                         */
 
958
 
 
959
                                strcpy((char *)state->auth.mdata.pam.name,
 
960
                                (const char *)rfc931.name);
 
961
 
909
962
                                                                        *state->auth.mdata.pam.password = NUL;
910
 
                                                                        methodisok = 1;
 
963
 
 
964
                                                                        methodischeckable = 1;
911
965
                                                                        break;
912
966
                                                                }
913
967
 
914
968
                                                                case AUTHMETHOD_NONE:
 
969
                                                                        /*
 
970
                                                                         * PAM can also support no username/password.
 
971
                                                                         */
 
972
 
915
973
                                                                        *state->auth.mdata.pam.name             = NUL;
916
974
                                                                        *state->auth.mdata.pam.password = NUL;
917
 
                                                                        methodisok = 1;
 
975
 
 
976
                                                                        methodischeckable = 1;
918
977
                                                                        break;
919
978
 
920
979
                                                        }
924
983
#endif /* HAVE_PAM */
925
984
                                        }
926
985
 
927
 
                                        if (methodisok) {
928
 
                                                state->auth.method = methodv[i];
 
986
                                        if (methodischeckable) {
 
987
                                                state->auth.method = methodv[i]; /* chainging method. */
929
988
                                                break;
930
989
                                        }
931
990
                                }
932
991
                        }
933
992
 
934
993
                        if (i == methodc)
935
 
                                continue;       /* no usable method found. */
 
994
                                /* 
 
995
                                 * current rules methods differs from what client can
 
996
                                 * provide us with.  Go to next rule.
 
997
                                 */
 
998
                                continue;
 
999
                        /* else; XXX should try other methods if acccess fails on this. */
936
1000
                }
937
1001
 
938
 
 
939
1002
                SASSERTX(methodisset(state->auth.method, rule->state.methodv,
940
1003
                rule->state.methodc));
941
1004
 
942
 
                i = accessmatch(s, &state->auth, peer, local, rule->user, msg, msgsize);
943
 
 
944
 
                /* two fields we want to copy. */
 
1005
                /* rule requires a user, and covers current user? */
 
1006
                if (rule->user != NULL)
 
1007
                        if (!usermatch(&state->auth, rule->user))
 
1008
                                continue; /* no match. */
 
1009
 
 
1010
                /* last step.  Does the authentication match? */
 
1011
                i = accesscheck(s, &state->auth, peer, local, msg, msgsize);
 
1012
 
 
1013
                /*
 
1014
                 * two fields we want to copy.  This is to speed things up so
 
1015
                 * we don't re-check the same method.
 
1016
                */
945
1017
                memcpy(ostate.auth.methodv, state->auth.methodv,
946
1018
                state->auth.methodc * sizeof(*state->auth.methodv));
947
1019
                ostate.auth.methodc = state->auth.methodc;
949
1021
                state->auth.badmethodc * sizeof(*state->auth.badmethodv));
950
1022
                ostate.auth.badmethodc = state->auth.badmethodc;
951
1023
 
952
 
                if (!i)
953
 
                        /*
954
 
                         * The reason for the continue is the fact that we can
955
 
                         * "upgrade" the method if we have a rule specifying a
956
 
                         * non-socks method.  That means "name" and "password"
957
 
                         * gotten for this method/rule need not be the same as gotten
958
 
                         * for other methods.
959
 
                         */
960
 
                        continue;
961
 
 
962
 
                /*
963
 
                 * This is a little tricky.  For some commands we may not
964
 
                 * have all info at time of (preliminary) rulechecks.
965
 
                 * What we want to do if there is no (complete) address given is
966
 
                 * to see if there's any chance at all the rules will permit this
967
 
                 * request when the address (later) becomes available.
968
 
                 * We therefore continue to scan the rules until we either get
969
 
                 * a pass (ignoring peer with missing info), or the default block
970
 
                 * is triggered.
971
 
                 */
972
 
 
973
 
                if (src != NULL) {
974
 
                        if (!addressmatch(&rule->src, src, state->protocol, 0))
975
 
                                continue;
976
 
                }
977
 
                else
978
 
                        if (rule->verdict == VERDICT_BLOCK)
979
 
                                continue; /* continue scan. */
980
 
 
981
 
                if (dst != NULL) {
982
 
                         if (!addressmatch(&rule->dst, dst, state->protocol, 0))
983
 
                                continue;
984
 
                }
985
 
                else
986
 
                        if (rule->verdict == VERDICT_BLOCK)
987
 
                                continue; /* continue scan. */
 
1024
                if (!i) {
 
1025
                        match->verdict = VERDICT_BLOCK;
 
1026
                        return 0;
 
1027
                }       
988
1028
 
989
1029
                break;
990
1030
        }
1045
1085
                                authname = (const char *)auth->mdata.rfc931.name;
1046
1086
                                break;
1047
1087
 
 
1088
#if HAVE_PAM
1048
1089
                        case AUTHMETHOD_PAM:
1049
1090
                                authname = (const char *)auth->mdata.pam.name;
1050
1091
                                break;
 
1092
#endif
1051
1093
 
1052
1094
                        default:
1053
1095
                                SERRX(auth->method);
1070
1112
{
1071
1113
        const char *function = "addressisbindable()";
1072
1114
        struct sockaddr saddr;
 
1115
        /* CONSTCOND */
1073
1116
        char saddrs[MAX(MAXSOCKSHOSTSTRING, MAXSOCKADDRSTRING)];
1074
1117
        int s;
1075
1118
 
1181
1224
                        yywarn("method \"%s\" set in rule but not in global methodline",
1182
1225
                        method2string(rule->state.methodv[i]));
1183
1226
 
1184
 
        /* if no protocol set, set all. */
 
1227
        /* if no protocol set, set all for socks-rules, tcp for client-rules. */
1185
1228
        if (memcmp(&state.protocol, &rule->state.protocol, sizeof(state.protocol))
1186
1229
        == 0)
1187
 
                memset(&rule->state.protocol, UCHAR_MAX, sizeof(rule->state.protocol));
 
1230
                if (client)
 
1231
                        rule->state.protocol.tcp = 1;
 
1232
                else
 
1233
                        memset(&rule->state.protocol, UCHAR_MAX, sizeof(rule->state.protocol));
1188
1234
 
1189
1235
        /* if no proxyprotocol set, set all socks protocols. */
1190
1236
        if (memcmp(&state.proxyprotocol, &rule->state.proxyprotocol,
1255
1301
        }
1256
1302
 
1257
1303
        if (rule->rdr_to.atype == SOCKS_ADDR_IFNAME)
1258
 
                yyerror("redirect to an interface (%s) is not supported "
1259
 
                "(or meaningful?)",
 
1304
                yyerror("redirect to an interface (%s) is not supported (or meaningful?)",
1260
1305
                rule->rdr_to.addr.ifname);
1261
1306
 
1262
1307
#if HAVE_PAM
1265
1310
                rule->state.methodc))
1266
1311
                        yyerror("pamservicename set for rule but not method pam");
1267
1312
                else
1268
 
                        if (strcmp(rule->pamservicename, DEFAULT_PAMSERVICENAME) != 0)
1269
 
                                sockscf.state.unfixedpamdata = 1; /* pamservicename varies. */
 
1313
                        if (sockscf.state.pamservicename != NULL
 
1314
                        && strcmp(rule->pamservicename, sockscf.state.pamservicename) != 0)
 
1315
                                sockscf.state.pamservicename = NULL; /* pamservicename varies. */
1270
1316
#endif /* HAVE_PAM */
1271
1317
}
1272
1318
 
1297
1343
        int s;
1298
1344
        struct request_info *request;
1299
1345
{
 
1346
        const int errno_s = errno;
1300
1347
 
1301
1348
        request_init(request, RQ_FILE, s, RQ_DAEMON, __progname, 0);
1302
1349
        fromhost(request);
 
1350
 
 
1351
        errno = errno_s;
1303
1352
}
1304
1353
#endif /* HAVE_LIBWRAP */
1305
1354