0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20 /*.** Copyright
0010: 28 63 29 20 32 30 30 37 20 44 2e 20 52 69 63 68 (c) 2007 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54 ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66 his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75 u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20 te it and/or.**
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20 modify it under
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65 the terms of the
0090: 20 53 69 6d 70 6c 69 66 69 65 64 20 42 53 44 20 Simplified BSD
00a0: 4c 69 63 65 6e 73 65 20 28 61 6c 73 6f 0a 2a 2a License (also.**
00b0: 20 6b 6e 6f 77 6e 20 61 73 20 74 68 65 20 22 32 known as the "2
00c0: 2d 43 6c 61 75 73 65 20 4c 69 63 65 6e 73 65 22 -Clause License"
00d0: 20 6f 72 20 22 46 72 65 65 42 53 44 20 4c 69 63 or "FreeBSD Lic
00e0: 65 6e 73 65 22 2e 29 0a 0a 2a 2a 20 54 68 69 73 ense".)..** This
00f0: 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73 74 program is dist
0100: 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20 68 ributed in the h
0110: 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c 6c ope that it will
0120: 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20 62 be useful,.** b
0130: 75 74 20 77 69 74 68 6f 75 74 20 61 6e 79 20 77 ut without any w
0140: 61 72 72 61 6e 74 79 3b 20 77 69 74 68 6f 75 74 arranty; without
0150: 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 65 even the implie
0160: 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a 2a d warranty of.**
0170: 20 6d 65 72 63 68 61 6e 74 61 62 69 6c 69 74 79 merchantability
0180: 20 6f 72 20 66 69 74 6e 65 73 73 20 66 6f 72 20 or fitness for
0190: 61 20 70 61 72 74 69 63 75 6c 61 72 20 70 75 72 a particular pur
01a0: 70 6f 73 65 2e 0a 2a 2a 0a 2a 2a 20 41 75 74 68 pose..**.** Auth
01b0: 6f 72 20 63 6f 6e 74 61 63 74 20 69 6e 66 6f 72 or contact infor
01c0: 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20 20 64 72 68 mation:.** drh
01d0: 40 68 77 61 63 69 2e 63 6f 6d 0a 2a 2a 20 20 20 @hwaci.com.**
01e0: 68 74 74 70 3a 2f 2f 77 77 77 2e 68 77 61 63 69 http://www.hwaci
01f0: 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a 0a 2a 2a 2a .com/drh/.**.***
0200: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a ************.**.
0250: 2a 2a 20 54 68 69 73 20 66 69 6c 65 20 63 6f 6e ** This file con
0260: 74 61 69 6e 73 20 63 6f 64 65 20 66 6f 72 20 67 tains code for g
0270: 65 6e 65 72 61 74 69 6e 67 20 74 68 65 20 6c 6f enerating the lo
0280: 67 69 6e 20 61 6e 64 20 6c 6f 67 6f 75 74 20 73 gin and logout s
0290: 63 72 65 65 6e 73 2e 0a 2a 2a 0a 2a 2a 20 4e 6f creens..**.** No
02a0: 74 65 73 3a 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 tes:.**.** There
02b0: 20 61 72 65 20 66 6f 75 72 20 73 70 65 63 69 61 are four specia
02c0: 6c 2d 63 61 73 65 20 75 73 65 72 2d 69 64 73 3a l-case user-ids:
02d0: 20 20 22 61 6e 6f 6e 79 6d 6f 75 73 22 2c 20 22 "anonymous", "
02e0: 6e 6f 62 6f 64 79 22 2c 0a 2a 2a 20 22 64 65 76 nobody",.** "dev
02f0: 65 6c 6f 70 65 72 22 20 61 6e 64 20 22 72 65 61 eloper" and "rea
0300: 64 65 72 22 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 der"..**.** The
0310: 63 61 70 61 62 69 6c 69 74 69 65 73 20 6f 66 20 capabilities of
0320: 74 68 65 20 6e 6f 62 6f 64 79 20 75 73 65 72 20 the nobody user
0330: 61 72 65 20 61 76 61 69 6c 61 62 6c 65 20 74 6f are available to
0340: 20 61 6e 79 6f 6e 65 2c 0a 2a 2a 20 72 65 67 61 anyone,.** rega
0350: 72 64 6c 65 73 73 20 6f 66 20 77 68 65 74 68 65 rdless of whethe
0360: 72 20 6f 72 20 6e 6f 74 20 74 68 65 79 20 61 72 r or not they ar
0370: 65 20 6c 6f 67 67 65 64 20 69 6e 2e 20 20 54 68 e logged in. Th
0380: 65 20 63 61 70 61 62 69 6c 69 74 69 65 73 0a 2a e capabilities.*
0390: 2a 20 6f 66 20 61 6e 6f 6e 79 6d 6f 75 73 20 61 * of anonymous a
03a0: 72 65 20 6f 6e 6c 79 20 61 76 61 69 6c 61 62 6c re only availabl
03b0: 65 20 61 66 74 65 72 20 6c 6f 67 67 69 6e 67 20 e after logging
03c0: 69 6e 2c 20 62 75 74 20 74 68 65 20 6c 6f 67 69 in, but the logi
03d0: 6e 0a 2a 2a 20 73 63 72 65 65 6e 20 64 69 73 70 n.** screen disp
03e0: 6c 61 79 73 20 74 68 65 20 70 61 73 73 77 6f 72 lays the passwor
03f0: 64 20 66 6f 72 20 74 68 65 20 61 6e 6f 6e 79 6d d for the anonym
0400: 6f 75 73 20 6c 6f 67 69 6e 2c 20 73 6f 20 74 68 ous login, so th
0410: 69 73 0a 2a 2a 20 73 68 6f 75 6c 64 20 6e 6f 74 is.** should not
0420: 20 70 72 65 76 65 6e 74 20 61 20 68 75 6d 61 6e prevent a human
0430: 20 75 73 65 72 20 66 72 6f 6d 20 64 6f 69 6e 67 user from doing
0440: 20 73 6f 2e 20 20 54 68 65 20 63 61 70 61 62 69 so. The capabi
0450: 6c 69 74 69 65 73 0a 2a 2a 20 6f 66 20 64 65 76 lities.** of dev
0460: 65 6c 6f 70 65 72 20 61 6e 64 20 72 65 61 64 65 eloper and reade
0470: 72 20 61 72 65 20 69 6e 68 65 72 69 74 65 64 20 r are inherited
0480: 62 79 20 61 6e 79 20 75 73 65 72 20 74 68 61 74 by any user that
0490: 20 68 61 73 20 74 68 65 0a 2a 2a 20 22 76 22 20 has the.** "v"
04a0: 61 6e 64 20 22 75 22 20 63 61 70 61 62 69 6c 69 and "u" capabili
04b0: 74 69 65 73 2c 20 72 65 73 70 65 63 74 69 76 65 ties, respective
04c0: 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6e 6f ly..**.** The no
04d0: 62 6f 64 79 20 75 73 65 72 20 68 61 73 20 63 61 body user has ca
04e0: 70 61 62 69 6c 69 74 69 65 73 20 74 68 61 74 20 pabilities that
04f0: 79 6f 75 20 77 61 6e 74 20 73 70 69 64 65 72 73 you want spiders
0500: 20 74 6f 20 68 61 76 65 2e 0a 2a 2a 20 54 68 65 to have..** The
0510: 20 61 6e 6f 6e 79 6d 6f 75 73 20 75 73 65 72 20 anonymous user
0520: 68 61 73 20 63 61 70 61 62 69 6c 69 74 69 65 73 has capabilities
0530: 20 74 68 61 74 20 79 6f 75 20 77 61 6e 74 20 70 that you want p
0540: 65 6f 70 6c 65 20 77 69 74 68 6f 75 74 0a 2a 2a eople without.**
0550: 20 6c 6f 67 69 6e 73 20 74 6f 20 68 61 76 65 2e logins to have.
0560: 0a 2a 2a 0a 2a 2a 20 4f 66 20 63 6f 75 72 73 65 .**.** Of course
0570: 2c 20 61 20 73 6f 70 68 69 73 74 69 63 61 74 65 , a sophisticate
0580: 64 20 73 70 69 64 65 72 20 63 6f 75 6c 64 20 65 d spider could e
0590: 61 73 69 6c 79 20 63 69 72 63 75 6d 76 65 6e 74 asily circumvent
05a0: 20 74 68 65 0a 2a 2a 20 61 6e 6f 6e 79 6d 6f 75 the.** anonymou
05b0: 73 20 6c 6f 67 69 6e 20 72 65 71 75 69 72 65 6d s login requirem
05c0: 65 6e 74 20 61 6e 64 20 77 61 6c 6b 20 74 68 65 ent and walk the
05d0: 20 77 65 62 73 69 74 65 2e 20 20 42 75 74 20 74 website. But t
05e0: 68 61 74 20 69 73 0a 2a 2a 20 6e 6f 74 20 72 65 hat is.** not re
05f0: 61 6c 6c 79 20 74 68 65 20 70 6f 69 6e 74 2e 20 ally the point.
0600: 20 54 68 65 20 61 6e 6f 6e 79 6d 6f 75 73 20 6c The anonymous l
0610: 6f 67 69 6e 20 6b 65 65 70 73 20 73 65 61 72 63 ogin keeps searc
0620: 68 2d 65 6e 67 69 6e 65 0a 2a 2a 20 63 72 61 77 h-engine.** craw
0630: 6c 65 72 73 20 61 6e 64 20 73 69 74 65 20 64 6f lers and site do
0640: 77 6e 6c 6f 61 64 20 74 6f 6f 6c 73 20 6c 69 6b wnload tools lik
0650: 65 20 77 67 65 74 20 66 72 6f 6d 20 77 61 6c 6b e wget from walk
0660: 69 6e 67 20 63 68 61 6e 67 65 0a 2a 2a 20 6c 6f ing change.** lo
0670: 67 73 20 61 6e 64 20 64 6f 77 6e 6c 6f 61 64 69 gs and downloadi
0680: 6e 67 20 64 69 66 66 73 20 6f 66 20 76 65 72 79 ng diffs of very
0690: 20 76 65 72 73 69 6f 6e 20 6f 66 20 74 68 65 20 version of the
06a0: 61 72 63 68 69 76 65 20 74 68 61 74 0a 2a 2a 20 archive that.**
06b0: 68 61 73 20 65 76 65 72 20 65 78 69 73 74 65 64 has ever existed
06c0: 2c 20 61 6e 64 20 74 68 69 6e 67 73 20 6c 69 6b , and things lik
06d0: 65 20 74 68 61 74 2e 0a 2a 2f 0a 23 69 6e 63 6c e that..*/.#incl
06e0: 75 64 65 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 ude "config.h".#
06f0: 69 6e 63 6c 75 64 65 20 22 6c 6f 67 69 6e 2e 68 include "login.h
0700: 22 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f 57 ".#if defined(_W
0710: 49 4e 33 32 29 0a 23 20 20 69 6e 63 6c 75 64 65 IN32).# include
0720: 20 3c 77 69 6e 64 6f 77 73 2e 68 3e 20 20 20 20 <windows.h>
0730: 20 20 20 20 20 20 20 2f 2a 20 66 6f 72 20 53 6c /* for Sl
0740: 65 65 70 20 2a 2f 0a 23 20 20 69 66 20 64 65 66 eep */.# if def
0750: 69 6e 65 64 28 5f 5f 4d 49 4e 47 57 33 32 5f 5f ined(__MINGW32__
0760: 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 5f 4d 53 ) || defined(_MS
0770: 43 5f 56 45 52 29 0a 23 20 20 20 20 64 65 66 69 C_VER).# defi
0780: 6e 65 20 73 6c 65 65 70 20 53 6c 65 65 70 20 20 ne sleep Sleep
0790: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 77 69 6e /* win
07a0: 64 6f 77 73 20 64 6f 65 73 20 6e 6f 74 20 68 61 dows does not ha
07b0: 76 65 20 73 6c 65 65 70 2c 20 62 75 74 20 53 6c ve sleep, but Sl
07c0: 65 65 70 20 2a 2f 0a 23 20 20 65 6e 64 69 66 0a eep */.# endif.
07d0: 23 65 6e 64 69 66 0a 23 69 6e 63 6c 75 64 65 20 #endif.#include
07e0: 3c 74 69 6d 65 2e 68 3e 0a 0a 0a 2f 2a 0a 2a 2a <time.h>.../*.**
07f0: 20 52 65 74 75 72 6e 20 74 68 65 20 6c 6f 67 69 Return the logi
0800: 6e 2d 67 72 6f 75 70 20 6e 61 6d 65 2e 20 20 4f n-group name. O
0810: 72 20 72 65 74 75 72 6e 20 30 20 69 66 20 74 68 r return 0 if th
0820: 69 73 20 72 65 70 6f 73 69 74 6f 72 79 20 69 73 is repository is
0830: 0a 2a 2a 20 6e 6f 74 20 61 20 6d 65 6d 62 65 72 .** not a member
0840: 20 6f 66 20 61 20 6c 6f 67 69 6e 2d 67 72 6f 75 of a login-grou
0850: 70 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 p..*/.const char
0860: 20 2a 6c 6f 67 69 6e 5f 67 72 6f 75 70 5f 6e 61 *login_group_na
0870: 6d 65 28 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 me(void){. stat
0880: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a ic const char *z
0890: 47 72 6f 75 70 20 3d 20 30 3b 0a 20 20 73 74 61 Group = 0;. sta
08a0: 74 69 63 20 69 6e 74 20 6f 6e 63 65 20 3d 20 31 tic int once = 1
08b0: 3b 0a 20 20 69 66 28 20 6f 6e 63 65 20 29 7b 0a ;. if( once ){.
08c0: 20 20 20 20 7a 47 72 6f 75 70 20 3d 20 64 62 5f zGroup = db_
08d0: 67 65 74 28 22 6c 6f 67 69 6e 2d 67 72 6f 75 70 get("login-group
08e0: 2d 6e 61 6d 65 22 2c 20 30 29 3b 0a 20 20 20 20 -name", 0);.
08f0: 6f 6e 63 65 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 once = 0;. }.
0900: 72 65 74 75 72 6e 20 7a 47 72 6f 75 70 3b 0a 7d return zGroup;.}
0910: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 ../*.** Return a
0920: 20 70 61 74 68 20 61 70 70 72 6f 70 72 69 61 74 path appropriat
0930: 65 20 66 6f 72 20 73 65 74 74 69 6e 67 20 61 20 e for setting a
0940: 63 6f 6f 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 cookie..**.** Th
0950: 65 20 70 61 74 68 20 69 73 20 67 2e 7a 54 6f 70 e path is g.zTop
0960: 20 66 6f 72 20 73 69 6e 67 6c 65 2d 72 65 70 6f for single-repo
0970: 20 63 6f 6f 6b 69 65 73 2e 20 20 49 74 20 69 73 cookies. It is
0980: 20 22 2f 22 20 66 6f 72 0a 2a 2a 20 63 6f 6f 6b "/" for.** cook
0990: 69 65 73 20 6f 66 20 61 20 6c 6f 67 69 6e 2d 67 ies of a login-g
09a0: 72 6f 75 70 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 roup..*/.const c
09b0: 68 61 72 20 2a 6c 6f 67 69 6e 5f 63 6f 6f 6b 69 har *login_cooki
09c0: 65 5f 70 61 74 68 28 76 6f 69 64 29 7b 0a 20 20 e_path(void){.
09d0: 69 66 28 20 6c 6f 67 69 6e 5f 67 72 6f 75 70 5f if( login_group_
09e0: 6e 61 6d 65 28 29 3d 3d 30 20 29 7b 0a 20 20 20 name()==0 ){.
09f0: 20 72 65 74 75 72 6e 20 67 2e 7a 54 6f 70 3b 0a return g.zTop;.
0a00: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 }else{. ret
0a10: 75 72 6e 20 22 2f 22 3b 0a 20 20 7d 0a 7d 0a 0a urn "/";. }.}..
0a20: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 /*.** Return the
0a30: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 6c 6f 67 name of the log
0a40: 69 6e 20 63 6f 6f 6b 69 65 2e 0a 2a 2a 0a 2a 2a in cookie..**.**
0a50: 20 54 68 65 20 6c 6f 67 69 6e 20 63 6f 6f 6b 69 The login cooki
0a60: 65 20 6e 61 6d 65 20 69 73 20 61 6c 77 61 79 73 e name is always
0a70: 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 20 20 66 of the form: f
0a80: 6f 73 73 69 6c 2d 58 58 58 58 58 58 58 58 58 58 ossil-XXXXXXXXXX
0a90: 58 58 58 58 58 58 0a 2a 2a 20 77 68 65 72 65 20 XXXXXX.** where
0aa0: 74 68 65 20 58 73 20 61 72 65 20 74 68 65 20 66 the Xs are the f
0ab0: 69 72 73 74 20 31 36 20 63 68 61 72 61 63 74 65 irst 16 characte
0ac0: 72 73 20 6f 66 20 74 68 65 20 6c 6f 67 69 6e 2d rs of the login-
0ad0: 67 72 6f 75 70 2d 63 6f 64 65 20 6f 72 0a 2a 2a group-code or.**
0ae0: 20 6f 66 20 74 68 65 20 70 72 6f 6a 65 63 74 2d of the project-
0af0: 63 6f 64 65 20 69 66 20 77 65 20 61 72 65 20 6e code if we are n
0b00: 6f 74 20 61 20 6d 65 6d 62 65 72 20 6f 66 20 61 ot a member of a
0b10: 6e 79 20 6c 6f 67 69 6e 2d 67 72 6f 75 70 2e 0a ny login-group..
0b20: 2a 2f 0a 63 68 61 72 20 2a 6c 6f 67 69 6e 5f 63 */.char *login_c
0b30: 6f 6f 6b 69 65 5f 6e 61 6d 65 28 76 6f 69 64 29 ookie_name(void)
0b40: 7b 0a 20 20 73 74 61 74 69 63 20 63 68 61 72 20 {. static char
0b50: 2a 7a 43 6f 6f 6b 69 65 4e 61 6d 65 20 3d 20 30 *zCookieName = 0
0b60: 3b 0a 20 20 69 66 28 20 7a 43 6f 6f 6b 69 65 4e ;. if( zCookieN
0b70: 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 7a 43 ame==0 ){. zC
0b80: 6f 6f 6b 69 65 4e 61 6d 65 20 3d 20 64 62 5f 74 ookieName = db_t
0b90: 65 78 74 28 30 2c 0a 20 20 20 20 20 20 20 22 53 ext(0,. "S
0ba0: 45 4c 45 43 54 20 27 66 6f 73 73 69 6c 2d 27 20 ELECT 'fossil-'
0bb0: 7c 7c 20 73 75 62 73 74 72 28 76 61 6c 75 65 2c || substr(value,
0bc0: 31 2c 31 36 29 22 0a 20 20 20 20 20 20 20 22 20 1,16)". "
0bd0: 20 46 52 4f 4d 20 63 6f 6e 66 69 67 22 0a 20 20 FROM config".
0be0: 20 20 20 20 20 22 20 57 48 45 52 45 20 6e 61 6d " WHERE nam
0bf0: 65 20 49 4e 20 28 27 70 72 6f 6a 65 63 74 2d 63 e IN ('project-c
0c00: 6f 64 65 27 2c 27 6c 6f 67 69 6e 2d 67 72 6f 75 ode','login-grou
0c10: 70 2d 63 6f 64 65 27 29 22 0a 20 20 20 20 20 20 p-code')".
0c20: 20 22 20 4f 52 44 45 52 20 42 59 20 6e 61 6d 65 " ORDER BY name
0c30: 20 2f 2a 73 6f 72 74 2a 2f 22 0a 20 20 20 20 29 /*sort*/". )
0c40: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 7a ;. }. return z
0c50: 43 6f 6f 6b 69 65 4e 61 6d 65 3b 0a 7d 0a 0a 2f CookieName;.}../
0c60: 2a 0a 2a 2a 20 52 65 64 69 72 65 63 74 20 74 6f *.** Redirect to
0c70: 20 74 68 65 20 70 61 67 65 20 73 70 65 63 69 66 the page specif
0c80: 69 65 64 20 62 79 20 74 68 65 20 22 67 22 20 71 ied by the "g" q
0c90: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 2e 0a uery parameter..
0ca0: 2a 2a 20 4f 72 20 69 66 20 74 68 65 72 65 20 69 ** Or if there i
0cb0: 73 20 6e 6f 20 22 67 22 20 71 75 65 72 79 20 70 s no "g" query p
0cc0: 61 72 61 6d 65 74 65 72 2c 20 72 65 64 69 72 65 arameter, redire
0cd0: 63 74 20 74 6f 20 74 68 65 20 68 6f 6d 65 70 61 ct to the homepa
0ce0: 67 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f ge..*/.static vo
0cf0: 69 64 20 72 65 64 69 72 65 63 74 5f 74 6f 5f 67 id redirect_to_g
0d00: 28 76 6f 69 64 29 7b 0a 20 20 63 6f 6e 73 74 20 (void){. const
0d10: 63 68 61 72 20 2a 7a 47 6f 74 6f 20 3d 20 50 28 char *zGoto = P(
0d20: 22 67 22 29 3b 0a 20 20 69 66 28 20 7a 47 6f 74 "g");. if( zGot
0d30: 6f 20 29 7b 0a 20 20 20 20 63 67 69 5f 72 65 64 o ){. cgi_red
0d40: 69 72 65 63 74 28 7a 47 6f 74 6f 29 3b 0a 20 20 irect(zGoto);.
0d50: 7d 65 6c 73 65 7b 0a 20 20 20 20 66 6f 73 73 69 }else{. fossi
0d60: 6c 5f 72 65 64 69 72 65 63 74 5f 68 6f 6d 65 28 l_redirect_home(
0d70: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 );. }.}../*.**
0d80: 54 68 65 20 49 50 20 61 64 64 72 65 73 73 20 6f The IP address o
0d90: 66 20 74 68 65 20 63 6c 69 65 6e 74 20 69 73 20 f the client is
0da0: 73 74 6f 72 65 64 20 61 73 20 70 61 72 74 20 6f stored as part o
0db0: 66 20 6c 6f 67 69 6e 20 63 6f 6f 6b 69 65 73 2e f login cookies.
0dc0: 0a 2a 2a 20 42 75 74 20 73 6f 6d 65 20 63 6c 69 .** But some cli
0dd0: 65 6e 74 73 20 61 72 65 20 62 65 68 69 6e 64 20 ents are behind
0de0: 66 69 72 65 77 61 6c 6c 73 20 74 68 61 74 20 73 firewalls that s
0df0: 68 69 66 74 20 74 68 65 20 49 50 20 61 64 64 72 hift the IP addr
0e00: 65 73 73 0a 2a 2a 20 77 69 74 68 20 65 61 63 68 ess.** with each
0e10: 20 48 54 54 50 20 72 65 71 75 65 73 74 2e 20 20 HTTP request.
0e20: 54 6f 20 61 6c 6c 6f 77 20 73 75 63 68 20 28 62 To allow such (b
0e30: 72 6f 6b 65 6e 29 20 63 6c 69 65 6e 74 73 20 74 roken) clients t
0e40: 6f 20 6c 6f 67 20 69 6e 2c 0a 2a 2a 20 65 78 74 o log in,.** ext
0e50: 72 61 63 74 20 6a 75 73 74 20 61 20 70 72 65 66 ract just a pref
0e60: 69 78 20 6f 66 20 74 68 65 20 49 50 20 61 64 64 ix of the IP add
0e70: 72 65 73 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 ress..*/.static
0e80: 63 68 61 72 20 2a 69 70 50 72 65 66 69 78 28 63 char *ipPrefix(c
0e90: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 50 29 7b onst char *zIP){
0ea0: 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 73 . int i, j;. s
0eb0: 74 61 74 69 63 20 69 6e 74 20 69 70 5f 70 72 65 tatic int ip_pre
0ec0: 66 69 78 5f 74 65 72 6d 73 20 3d 20 2d 31 3b 0a fix_terms = -1;.
0ed0: 20 20 69 66 28 20 69 70 5f 70 72 65 66 69 78 5f if( ip_prefix_
0ee0: 74 65 72 6d 73 3c 30 20 29 7b 0a 20 20 20 20 69 terms<0 ){. i
0ef0: 70 5f 70 72 65 66 69 78 5f 74 65 72 6d 73 20 3d p_prefix_terms =
0f00: 20 64 62 5f 67 65 74 5f 69 6e 74 28 22 69 70 2d db_get_int("ip-
0f10: 70 72 65 66 69 78 2d 74 65 72 6d 73 22 2c 32 29 prefix-terms",2)
0f20: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 70 5f 70 ;. }. if( ip_p
0f30: 72 65 66 69 78 5f 74 65 72 6d 73 3d 3d 30 20 29 refix_terms==0 )
0f40: 20 72 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 28 return mprintf(
0f50: 22 30 22 29 3b 0a 20 20 66 6f 72 28 69 3d 6a 3d "0");. for(i=j=
0f60: 30 3b 20 7a 49 50 5b 69 5d 3b 20 69 2b 2b 29 7b 0; zIP[i]; i++){
0f70: 0a 20 20 20 20 69 66 28 20 7a 49 50 5b 69 5d 3d . if( zIP[i]=
0f80: 3d 27 2e 27 20 29 7b 0a 20 20 20 20 20 20 6a 2b ='.' ){. j+
0f90: 2b 3b 0a 20 20 20 20 20 20 69 66 28 20 6a 3d 3d +;. if( j==
0fa0: 69 70 5f 70 72 65 66 69 78 5f 74 65 72 6d 73 20 ip_prefix_terms
0fb0: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 ) break;. }.
0fc0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 6d 70 72 69 }. return mpri
0fd0: 6e 74 66 28 22 25 2e 2a 73 22 2c 20 69 2c 20 7a ntf("%.*s", i, z
0fe0: 49 50 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 IP);.}../*.** Re
0ff0: 74 75 72 6e 20 61 6e 20 61 62 62 72 65 76 69 61 turn an abbrevia
1000: 74 65 64 20 70 72 6f 6a 65 63 74 20 63 6f 64 65 ted project code
1010: 2e 20 20 54 68 65 20 61 62 62 72 65 76 69 61 74 . The abbreviat
1020: 69 6f 6e 20 69 73 20 74 68 65 20 66 69 72 73 74 ion is the first
1030: 0a 2a 2a 20 31 36 20 63 68 61 72 61 63 74 65 72 .** 16 character
1040: 73 20 6f 66 20 74 68 65 20 70 72 6f 6a 65 63 74 s of the project
1050: 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 4d 65 6d code..**.** Mem
1060: 6f 72 79 20 69 73 20 6f 62 74 61 69 6e 65 64 20 ory is obtained
1070: 66 72 6f 6d 20 6d 61 6c 6c 6f 63 2e 0a 2a 2f 0a from malloc..*/.
1080: 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 62 62 static char *abb
1090: 72 65 76 69 61 74 65 64 5f 70 72 6f 6a 65 63 74 reviated_project
10a0: 5f 63 6f 64 65 28 63 6f 6e 73 74 20 63 68 61 72 _code(const char
10b0: 20 2a 7a 46 75 6c 6c 43 6f 64 65 29 7b 0a 20 20 *zFullCode){.
10c0: 72 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 28 22 return mprintf("
10d0: 25 2e 31 36 73 22 2c 20 7a 46 75 6c 6c 43 6f 64 %.16s", zFullCod
10e0: 65 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 68 e);.}.../*.** Ch
10f0: 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74 68 eck to see if th
1100: 65 20 61 6e 6f 6e 79 6d 6f 75 73 20 6c 6f 67 69 e anonymous logi
1110: 6e 20 69 73 20 76 61 6c 69 64 2e 20 20 49 66 20 n is valid. If
1120: 69 74 20 69 73 20 76 61 6c 69 64 2c 20 72 65 74 it is valid, ret
1130: 75 72 6e 0a 2a 2a 20 74 68 65 20 75 73 65 72 69 urn.** the useri
1140: 64 20 6f 66 20 74 68 65 20 61 6e 6f 6e 79 6d 6f d of the anonymo
1150: 75 73 20 75 73 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 us user..**.** T
1160: 68 65 20 7a 43 53 20 70 61 72 61 6d 65 74 65 72 he zCS parameter
1170: 20 69 73 20 74 68 65 20 22 63 61 70 74 63 68 61 is the "captcha
1180: 20 73 65 65 64 22 20 75 73 65 64 20 66 6f 72 20 seed" used for
1190: 61 20 73 70 65 63 69 66 69 63 0a 2a 2a 20 61 6e a specific.** an
11a0: 6f 6e 79 6d 6f 75 73 20 6c 6f 67 69 6e 20 72 65 onymous login re
11b0: 71 75 65 73 74 2e 0a 2a 2f 0a 69 6e 74 20 6c 6f quest..*/.int lo
11c0: 67 69 6e 5f 69 73 5f 76 61 6c 69 64 5f 61 6e 6f gin_is_valid_ano
11d0: 6e 79 6d 6f 75 73 28 0a 20 20 63 6f 6e 73 74 20 nymous(. const
11e0: 63 68 61 72 20 2a 7a 55 73 65 72 6e 61 6d 65 2c char *zUsername,
11f0: 20 20 2f 2a 20 54 68 65 20 75 73 65 72 6e 61 6d /* The usernam
1200: 65 2e 20 20 4d 75 73 74 20 62 65 20 22 61 6e 6f e. Must be "ano
1210: 6e 79 6d 6f 75 73 22 20 2a 2f 0a 20 20 63 6f 6e nymous" */. con
1220: 73 74 20 63 68 61 72 20 2a 7a 50 61 73 73 77 6f st char *zPasswo
1230: 72 64 2c 20 20 2f 2a 20 54 68 65 20 73 75 70 70 rd, /* The supp
1240: 6c 69 65 64 20 70 61 73 73 77 6f 72 64 20 2a 2f lied password */
1250: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a . const char *z
1260: 43 53 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 CS /* Th
1270: 65 20 63 61 70 74 63 68 61 20 73 65 65 64 20 76 e captcha seed v
1280: 61 6c 75 65 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e alue */.){. con
1290: 73 74 20 63 68 61 72 20 2a 7a 50 77 3b 20 20 20 st char *zPw;
12a0: 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 72 72 /* The corr
12b0: 65 63 74 20 70 61 73 73 77 6f 72 64 20 73 68 6f ect password sho
12c0: 77 6e 20 69 6e 20 74 68 65 20 63 61 70 74 63 68 wn in the captch
12d0: 61 20 2a 2f 0a 20 20 69 6e 74 20 75 69 64 3b 20 a */. int uid;
12e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
12f0: 2a 20 54 68 65 20 75 73 65 72 20 49 44 20 6f 66 * The user ID of
1300: 20 61 6e 6f 6e 79 6d 6f 75 73 20 2a 2f 0a 0a 20 anonymous */..
1310: 20 69 66 28 20 7a 55 73 65 72 6e 61 6d 65 3d 3d if( zUsername==
1320: 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 0 ) return 0;.
1330: 65 6c 73 65 20 69 66 28 20 7a 50 61 73 73 77 6f else if( zPasswo
1340: 72 64 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 rd==0 ) return 0
1350: 3b 0a 20 20 65 6c 73 65 20 69 66 28 20 7a 43 53 ;. else if( zCS
1360: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a ==0 ) return 0;.
1370: 20 20 65 6c 73 65 20 69 66 28 20 66 6f 73 73 69 else if( fossi
1380: 6c 5f 73 74 72 63 6d 70 28 7a 55 73 65 72 6e 61 l_strcmp(zUserna
1390: 6d 65 2c 22 61 6e 6f 6e 79 6d 6f 75 73 22 29 21 me,"anonymous")!
13a0: 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 =0 ) return 0;.
13b0: 20 7a 50 77 20 3d 20 63 61 70 74 63 68 61 5f 64 zPw = captcha_d
13c0: 65 63 6f 64 65 28 28 75 6e 73 69 67 6e 65 64 20 ecode((unsigned
13d0: 69 6e 74 29 61 74 6f 69 28 7a 43 53 29 29 3b 0a int)atoi(zCS));.
13e0: 20 20 69 66 28 20 66 6f 73 73 69 6c 5f 73 74 72 if( fossil_str
13f0: 69 63 6d 70 28 7a 50 77 2c 20 7a 50 61 73 73 77 icmp(zPw, zPassw
1400: 6f 72 64 29 21 3d 30 20 29 20 72 65 74 75 72 6e ord)!=0 ) return
1410: 20 30 3b 0a 20 20 75 69 64 20 3d 20 64 62 5f 69 0;. uid = db_i
1420: 6e 74 28 30 2c 20 22 53 45 4c 45 43 54 20 75 69 nt(0, "SELECT ui
1430: 64 20 46 52 4f 4d 20 75 73 65 72 20 57 48 45 52 d FROM user WHER
1440: 45 20 6c 6f 67 69 6e 3d 27 61 6e 6f 6e 79 6d 6f E login='anonymo
1450: 75 73 27 22 0a 20 20 20 20 20 20 20 20 20 20 20 us'".
1460: 20 20 20 20 20 20 20 22 20 41 4e 44 20 6c 65 6e " AND len
1470: 67 74 68 28 70 77 29 3e 30 20 41 4e 44 20 6c 65 gth(pw)>0 AND le
1480: 6e 67 74 68 28 63 61 70 29 3e 30 22 29 3b 0a 20 ngth(cap)>0");.
1490: 20 72 65 74 75 72 6e 20 75 69 64 3b 0a 7d 0a 0a return uid;.}..
14a0: 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20 /*.** Make sure
14b0: 74 68 65 20 61 63 63 65 73 73 6c 6f 67 20 74 61 the accesslog ta
14c0: 62 6c 65 20 65 78 69 73 74 73 2e 20 20 43 72 65 ble exists. Cre
14d0: 61 74 65 20 69 74 20 69 66 20 69 74 20 64 6f 65 ate it if it doe
14e0: 73 20 6e 6f 74 0a 2a 2f 0a 76 6f 69 64 20 63 72 s not.*/.void cr
14f0: 65 61 74 65 5f 61 63 63 65 73 73 6c 6f 67 5f 74 eate_accesslog_t
1500: 61 62 6c 65 28 76 6f 69 64 29 7b 0a 20 20 64 62 able(void){. db
1510: 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20 20 _multi_exec(.
1520: 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 49 "CREATE TABLE I
1530: 46 20 4e 4f 54 20 45 58 49 53 54 53 20 72 65 70 F NOT EXISTS rep
1540: 6f 73 69 74 6f 72 79 2e 61 63 63 65 73 73 6c 6f ository.accesslo
1550: 67 28 22 0a 20 20 20 20 22 20 20 75 6e 61 6d 65 g(". " uname
1560: 20 54 45 58 54 2c 22 0a 20 20 20 20 22 20 20 69 TEXT,". " i
1570: 70 61 64 64 72 20 54 45 58 54 2c 22 0a 20 20 20 paddr TEXT,".
1580: 20 22 20 20 73 75 63 63 65 73 73 20 42 4f 4f 4c " success BOOL
1590: 45 41 4e 2c 22 0a 20 20 20 20 22 20 20 6d 74 69 EAN,". " mti
15a0: 6d 65 20 54 49 4d 45 53 54 41 4d 50 22 0a 20 20 me TIMESTAMP".
15b0: 20 20 22 29 3b 22 0a 20 20 29 3b 0a 7d 0a 0a 2f ");". );.}../
15c0: 2a 0a 2a 2a 20 4d 61 6b 65 20 61 20 72 65 63 6f *.** Make a reco
15d0: 72 64 20 6f 66 20 61 20 6c 6f 67 69 6e 20 61 74 rd of a login at
15e0: 74 65 6d 70 74 2c 20 69 66 20 6c 6f 67 69 6e 20 tempt, if login
15f0: 72 65 63 6f 72 64 20 6b 65 65 70 69 6e 67 20 69 record keeping i
1600: 73 20 65 6e 61 62 6c 65 64 2e 0a 2a 2f 0a 73 74 s enabled..*/.st
1610: 61 74 69 63 20 76 6f 69 64 20 72 65 63 6f 72 64 atic void record
1620: 5f 6c 6f 67 69 6e 5f 61 74 74 65 6d 70 74 28 0a _login_attempt(.
1630: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 const char *zU
1640: 73 65 72 6e 61 6d 65 2c 20 20 20 20 20 2f 2a 20 sername, /*
1650: 4e 61 6d 65 20 6f 66 20 75 73 65 72 20 6c 6f 67 Name of user log
1660: 67 69 6e 67 20 69 6e 20 2a 2f 0a 20 20 63 6f 6e ging in */. con
1670: 73 74 20 63 68 61 72 20 2a 7a 49 70 41 64 64 72 st char *zIpAddr
1680: 2c 20 20 20 20 20 20 20 2f 2a 20 49 50 20 61 64 , /* IP ad
1690: 64 72 65 73 73 20 66 72 6f 6d 20 77 68 69 63 68 dress from which
16a0: 20 74 68 65 79 20 6c 6f 67 67 65 64 20 69 6e 20 they logged in
16b0: 2a 2f 0a 20 20 69 6e 74 20 62 53 75 63 63 65 73 */. int bSucces
16c0: 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 s
16d0: 2f 2a 20 54 72 75 65 20 69 66 20 74 68 65 20 61 /* True if the a
16e0: 74 74 65 6d 70 74 20 77 61 73 20 61 20 73 75 63 ttempt was a suc
16f0: 63 65 73 73 20 2a 2f 0a 29 7b 0a 20 20 69 66 28 cess */.){. if(
1700: 20 21 64 62 5f 67 65 74 5f 62 6f 6f 6c 65 61 6e !db_get_boolean
1710: 28 22 61 63 63 65 73 73 2d 6c 6f 67 22 2c 20 30 ("access-log", 0
1720: 29 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 63 72 ) ) return;. cr
1730: 65 61 74 65 5f 61 63 63 65 73 73 6c 6f 67 5f 74 eate_accesslog_t
1740: 61 62 6c 65 28 29 3b 0a 20 20 64 62 5f 6d 75 6c able();. db_mul
1750: 74 69 5f 65 78 65 63 28 0a 20 20 20 20 22 49 4e ti_exec(. "IN
1760: 53 45 52 54 20 49 4e 54 4f 20 61 63 63 65 73 73 SERT INTO access
1770: 6c 6f 67 28 75 6e 61 6d 65 2c 69 70 61 64 64 72 log(uname,ipaddr
1780: 2c 73 75 63 63 65 73 73 2c 6d 74 69 6d 65 29 22 ,success,mtime)"
1790: 0a 20 20 20 20 22 56 41 4c 55 45 53 28 25 51 2c . "VALUES(%Q,
17a0: 25 51 2c 25 64 2c 6a 75 6c 69 61 6e 64 61 79 28 %Q,%d,julianday(
17b0: 27 6e 6f 77 27 29 29 3b 22 2c 0a 20 20 20 20 7a 'now'));",. z
17c0: 55 73 65 72 6e 61 6d 65 2c 20 7a 49 70 41 64 64 Username, zIpAdd
17d0: 72 2c 20 62 53 75 63 63 65 73 73 0a 20 20 29 3b r, bSuccess. );
17e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 .}../*.** Search
17f0: 65 73 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 es for the user
1800: 49 44 20 6d 61 74 63 68 69 6e 67 20 74 68 65 20 ID matching the
1810: 67 69 76 65 6e 20 6e 61 6d 65 20 61 6e 64 20 70 given name and p
1820: 61 73 73 77 6f 72 64 2e 0a 2a 2a 20 4f 6e 20 73 assword..** On s
1830: 75 63 63 65 73 73 20 69 74 20 72 65 74 75 72 6e uccess it return
1840: 73 20 61 20 70 6f 73 69 74 69 76 65 20 76 61 6c s a positive val
1850: 75 65 2e 20 4f 6e 20 65 72 72 6f 72 20 69 74 20 ue. On error it
1860: 72 65 74 75 72 6e 73 20 30 2e 0a 2a 2a 20 4f 6e returns 0..** On
1870: 20 73 65 72 69 6f 75 73 20 28 44 42 2d 6c 65 76 serious (DB-lev
1880: 65 6c 29 20 65 72 72 6f 72 20 69 74 20 77 69 6c el) error it wil
1890: 6c 20 70 72 6f 62 61 62 6c 79 20 65 78 69 74 2e l probably exit.
18a0: 0a 2a 2a 0a 2a 2a 20 7a 50 61 73 73 77 6f 72 64 .**.** zPassword
18b0: 20 6d 61 79 20 62 65 20 65 69 74 68 65 72 20 74 may be either t
18c0: 68 65 20 70 6c 61 69 6e 2d 74 65 78 74 20 66 6f he plain-text fo
18d0: 72 6d 20 6f 72 20 74 68 65 20 65 6e 63 72 79 70 rm or the encryp
18e0: 74 65 64 0a 2a 2a 20 66 6f 72 6d 20 6f 66 20 74 ted.** form of t
18f0: 68 65 20 75 73 65 72 27 73 20 70 61 73 73 77 6f he user's passwo
1900: 72 64 2e 0a 2a 2f 0a 69 6e 74 20 6c 6f 67 69 6e rd..*/.int login
1910: 5f 73 65 61 72 63 68 5f 75 69 64 28 63 6f 6e 73 _search_uid(cons
1920: 74 20 63 68 61 72 20 2a 7a 55 73 65 72 6e 61 6d t char *zUsernam
1930: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a e, const char *z
1940: 50 61 73 73 77 64 29 7b 0a 20 20 63 68 61 72 20 Passwd){. char
1950: 2a 7a 53 68 61 31 50 77 20 3d 20 73 68 61 31 5f *zSha1Pw = sha1_
1960: 73 68 61 72 65 64 5f 73 65 63 72 65 74 28 7a 50 shared_secret(zP
1970: 61 73 73 77 64 2c 20 7a 55 73 65 72 6e 61 6d 65 asswd, zUsername
1980: 2c 20 30 29 3b 0a 20 20 69 6e 74 20 75 69 64 20 , 0);. int uid
1990: 3d 20 64 62 5f 69 6e 74 28 30 2c 0a 20 20 20 20 = db_int(0,.
19a0: 22 53 45 4c 45 43 54 20 75 69 64 20 46 52 4f 4d "SELECT uid FROM
19b0: 20 75 73 65 72 22 0a 20 20 20 20 22 20 57 48 45 user". " WHE
19c0: 52 45 20 6c 6f 67 69 6e 3d 25 51 22 0a 20 20 20 RE login=%Q".
19d0: 20 22 20 20 20 41 4e 44 20 6c 65 6e 67 74 68 28 " AND length(
19e0: 63 61 70 29 3e 30 20 41 4e 44 20 6c 65 6e 67 74 cap)>0 AND lengt
19f0: 68 28 70 77 29 3e 30 22 0a 20 20 20 20 22 20 20 h(pw)>0". "
1a00: 20 41 4e 44 20 6c 6f 67 69 6e 20 4e 4f 54 20 49 AND login NOT I
1a10: 4e 20 28 27 61 6e 6f 6e 79 6d 6f 75 73 27 2c 27 N ('anonymous','
1a20: 6e 6f 62 6f 64 79 27 2c 27 64 65 76 65 6c 6f 70 nobody','develop
1a30: 65 72 27 2c 27 72 65 61 64 65 72 27 29 22 0a 20 er','reader')".
1a40: 20 20 20 22 20 20 20 41 4e 44 20 28 70 77 3d 25 " AND (pw=%
1a50: 51 20 4f 52 20 28 6c 65 6e 67 74 68 28 70 77 29 Q OR (length(pw)
1a60: 3c 3e 34 30 20 41 4e 44 20 70 77 3d 25 51 29 29 <>40 AND pw=%Q))
1a70: 22 0a 20 20 20 20 22 20 20 20 41 4e 44 20 28 69 ". " AND (i
1a80: 6e 66 6f 20 4e 4f 54 20 4c 49 4b 45 20 27 25 25 nfo NOT LIKE '%%
1a90: 65 78 70 69 72 65 73 20 32 30 25 25 27 22 0a 20 expires 20%%'".
1aa0: 20 20 20 22 20 20 20 20 20 20 4f 52 20 73 75 62 " OR sub
1ab0: 73 74 72 28 69 6e 66 6f 2c 69 6e 73 74 72 28 6c str(info,instr(l
1ac0: 6f 77 65 72 28 69 6e 66 6f 29 2c 27 65 78 70 69 ower(info),'expi
1ad0: 72 65 73 27 29 2b 38 2c 31 30 29 3e 64 61 74 65 res')+8,10)>date
1ae0: 74 69 6d 65 28 27 6e 6f 77 27 29 29 22 2c 0a 20 time('now'))",.
1af0: 20 20 20 7a 55 73 65 72 6e 61 6d 65 2c 20 7a 53 zUsername, zS
1b00: 68 61 31 50 77 2c 20 7a 50 61 73 73 77 64 0a 20 ha1Pw, zPasswd.
1b10: 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 77 65 20 );.. /* If we
1b20: 64 69 64 20 6e 6f 74 20 66 69 6e 64 20 61 20 6c did not find a l
1b30: 6f 67 69 6e 20 6f 6e 20 74 68 65 20 66 69 72 73 ogin on the firs
1b40: 74 20 61 74 74 65 6d 70 74 2c 20 61 6e 64 20 74 t attempt, and t
1b50: 68 65 20 75 73 65 72 6e 61 6d 65 0a 20 20 2a 2a he username. **
1b60: 20 6c 6f 6f 6b 73 20 6c 69 6b 65 20 61 6e 20 65 looks like an e
1b70: 6d 61 69 6c 20 61 64 64 72 65 73 73 2c 20 74 68 mail address, th
1b80: 65 20 70 65 72 68 61 70 73 20 74 68 65 20 75 73 e perhaps the us
1b90: 65 72 20 65 6e 74 69 72 65 64 20 74 68 65 69 72 er entired their
1ba0: 0a 20 20 2a 2a 20 65 6d 61 69 6c 20 61 64 64 72 . ** email addr
1bb0: 65 73 73 20 69 6e 73 74 65 61 64 20 6f 66 20 74 ess instead of t
1bc0: 68 65 69 72 20 6c 6f 67 69 6e 2e 20 20 54 72 79 heir login. Try
1bd0: 20 61 67 61 69 6e 20 74 6f 20 6d 61 74 63 68 20 again to match
1be0: 74 68 65 20 75 73 65 72 0a 20 20 2a 2a 20 61 67 the user. ** ag
1bf0: 61 69 6e 73 74 20 65 6d 61 69 6c 20 61 64 64 72 ainst email addr
1c00: 65 73 73 65 73 20 63 6f 6e 74 61 69 6e 65 64 20 esses contained
1c10: 69 6e 20 74 68 65 20 22 69 6e 66 6f 22 20 66 69 in the "info" fi
1c20: 65 6c 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 eld.. */. if(
1c30: 75 69 64 3d 3d 30 20 26 26 20 73 74 72 63 68 72 uid==0 && strchr
1c40: 28 7a 55 73 65 72 6e 61 6d 65 2c 27 40 27 29 21 (zUsername,'@')!
1c50: 3d 30 20 29 7b 0a 20 20 20 20 53 74 6d 74 20 71 =0 ){. Stmt q
1c60: 3b 0a 20 20 20 20 64 62 5f 70 72 65 70 61 72 65 ;. db_prepare
1c70: 28 26 71 2c 0a 20 20 20 20 20 20 22 53 45 4c 45 (&q,. "SELE
1c80: 43 54 20 6c 6f 67 69 6e 20 46 52 4f 4d 20 75 73 CT login FROM us
1c90: 65 72 22 0a 20 20 20 20 20 20 22 20 57 48 45 52 er". " WHER
1ca0: 45 20 66 69 6e 64 5f 65 6d 61 69 6c 61 64 64 72 E find_emailaddr
1cb0: 28 69 6e 66 6f 29 3d 25 51 22 0a 20 20 20 20 20 (info)=%Q".
1cc0: 20 22 20 20 20 41 4e 44 20 69 6e 73 74 72 28 6c " AND instr(l
1cd0: 6f 67 69 6e 2c 27 40 27 29 3d 3d 30 22 2c 0a 20 ogin,'@')==0",.
1ce0: 20 20 20 20 20 7a 55 73 65 72 6e 61 6d 65 0a 20 zUsername.
1cf0: 20 20 20 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 );. while(
1d00: 20 75 69 64 3d 3d 30 20 26 26 20 64 62 5f 73 74 uid==0 && db_st
1d10: 65 70 28 26 71 29 3d 3d 53 51 4c 49 54 45 5f 52 ep(&q)==SQLITE_R
1d20: 4f 57 20 29 7b 0a 20 20 20 20 20 20 20 75 69 64 OW ){. uid
1d30: 20 3d 20 6c 6f 67 69 6e 5f 73 65 61 72 63 68 5f = login_search_
1d40: 75 69 64 28 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 uid(db_column_te
1d50: 78 74 28 26 71 2c 30 29 2c 7a 50 61 73 73 77 64 xt(&q,0),zPasswd
1d60: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 5f );. }. db_
1d70: 66 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20 finalize(&q);.
1d80: 7d 20 20 20 20 0a 20 20 66 72 65 65 28 7a 53 68 } . free(zSh
1d90: 61 31 50 77 29 3b 0a 20 20 72 65 74 75 72 6e 20 a1Pw);. return
1da0: 75 69 64 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 65 uid;.}../*.** Ge
1db0: 6e 65 72 61 74 65 73 20 61 20 6c 6f 67 69 6e 20 nerates a login
1dc0: 63 6f 6f 6b 69 65 20 76 61 6c 75 65 20 66 6f 72 cookie value for
1dd0: 20 61 20 6e 6f 6e 2d 61 6e 6f 6e 79 6d 6f 75 73 a non-anonymous
1de0: 20 75 73 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 user..**.** The
1df0: 20 7a 48 61 73 68 20 70 61 72 61 6d 65 74 65 72 zHash parameter
1e00: 20 6d 75 73 74 20 62 65 20 61 20 72 61 6e 64 6f must be a rando
1e10: 6d 20 76 61 6c 75 65 20 77 68 69 63 68 20 6d 75 m value which mu
1e20: 73 74 20 62 65 0a 2a 2a 20 73 75 62 73 65 71 75 st be.** subsequ
1e30: 65 6e 74 6c 79 20 73 74 6f 72 65 64 20 69 6e 20 ently stored in
1e40: 75 73 65 72 2e 63 6f 6f 6b 69 65 20 66 6f 72 20 user.cookie for
1e50: 6c 61 74 65 72 20 76 61 6c 69 64 61 74 69 6f 6e later validation
1e60: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 72 65 74 75 ..**.** The retu
1e70: 72 6e 65 64 20 6d 65 6d 6f 72 79 20 73 68 6f 75 rned memory shou
1e80: 6c 64 20 62 65 20 66 72 65 65 28 29 64 20 61 66 ld be free()d af
1e90: 74 65 72 20 75 73 65 2e 0a 2a 2f 0a 63 68 61 72 ter use..*/.char
1ea0: 20 2a 6c 6f 67 69 6e 5f 67 65 6e 5f 75 73 65 72 *login_gen_user
1eb0: 5f 63 6f 6f 6b 69 65 5f 76 61 6c 75 65 28 63 6f _cookie_value(co
1ec0: 6e 73 74 20 63 68 61 72 20 2a 7a 55 73 65 72 6e nst char *zUsern
1ed0: 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 ame, const char
1ee0: 2a 7a 48 61 73 68 29 7b 0a 20 20 63 68 61 72 20 *zHash){. char
1ef0: 2a 7a 50 72 6f 6a 43 6f 64 65 20 3d 20 64 62 5f *zProjCode = db_
1f00: 67 65 74 28 22 70 72 6f 6a 65 63 74 2d 63 6f 64 get("project-cod
1f10: 65 22 2c 4e 55 4c 4c 29 3b 0a 20 20 63 68 61 72 e",NULL);. char
1f20: 20 2a 7a 43 6f 64 65 20 3d 20 61 62 62 72 65 76 *zCode = abbrev
1f30: 69 61 74 65 64 5f 70 72 6f 6a 65 63 74 5f 63 6f iated_project_co
1f40: 64 65 28 7a 50 72 6f 6a 43 6f 64 65 29 3b 0a 20 de(zProjCode);.
1f50: 20 66 72 65 65 28 7a 50 72 6f 6a 43 6f 64 65 29 free(zProjCode)
1f60: 3b 0a 20 20 61 73 73 65 72 74 28 28 7a 55 73 65 ;. assert((zUse
1f70: 72 6e 61 6d 65 20 26 26 20 2a 7a 55 73 65 72 6e rname && *zUsern
1f80: 61 6d 65 29 20 26 26 20 22 49 6e 76 61 6c 69 64 ame) && "Invalid
1f90: 20 75 73 65 72 20 64 61 74 61 2e 22 29 3b 0a 20 user data.");.
1fa0: 20 72 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 28 return mprintf(
1fb0: 22 25 73 2f 25 7a 2f 25 73 22 2c 20 7a 48 61 73 "%s/%z/%s", zHas
1fc0: 68 2c 20 7a 43 6f 64 65 2c 20 7a 55 73 65 72 6e h, zCode, zUsern
1fd0: 61 6d 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 ame);.}../*.** G
1fe0: 65 6e 65 72 61 74 65 73 20 61 20 6c 6f 67 69 6e enerates a login
1ff0: 20 63 6f 6f 6b 69 65 20 66 6f 72 20 4e 4f 4e 2d cookie for NON-
2000: 41 4e 4f 4e 59 4d 4f 55 53 20 75 73 65 72 73 2e ANONYMOUS users.
2010: 20 20 4e 6f 74 65 20 74 68 61 74 20 74 68 69 73 Note that this
2020: 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 22 63 6f .** function "co
2030: 75 6c 64 22 20 66 69 67 75 72 65 20 6f 75 74 20 uld" figure out
2040: 74 68 65 20 75 69 64 20 62 79 20 69 74 73 65 6c the uid by itsel
2050: 66 20 62 75 74 20 69 74 20 63 75 72 72 65 6e 74 f but it current
2060: 6c 79 0a 2a 2a 20 64 6f 65 73 6e 27 74 20 62 65 ly.** doesn't be
2070: 63 61 75 73 65 20 74 68 65 20 63 6f 64 65 20 77 cause the code w
2080: 68 69 63 68 20 63 61 6c 6c 73 20 74 68 69 73 20 hich calls this
2090: 61 6c 72 65 61 64 79 20 68 61 73 20 74 68 65 20 already has the
20a0: 75 69 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 uid..**.** This
20b0: 66 75 6e 63 74 69 6f 6e 20 61 6c 73 6f 20 75 70 function also up
20c0: 64 61 74 65 73 20 74 68 65 20 75 73 65 72 2e 63 dates the user.c
20d0: 6f 6f 6b 69 65 2c 20 75 73 65 72 2e 69 70 61 64 ookie, user.ipad
20e0: 64 72 2c 0a 2a 2a 20 61 6e 64 20 75 73 65 72 2e dr,.** and user.
20f0: 63 65 78 70 69 72 65 20 66 69 65 6c 64 73 20 66 cexpire fields f
2100: 6f 72 20 74 68 65 20 67 69 76 65 6e 20 75 73 65 or the given use
2110: 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 7a 44 65 73 r..**.** If zDes
2120: 74 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 20 74 68 t is not NULL th
2130: 65 6e 20 74 68 65 20 67 65 6e 65 72 61 74 65 64 en the generated
2140: 20 63 6f 6f 6b 69 65 20 69 73 20 63 6f 70 69 65 cookie is copie
2150: 64 20 74 6f 0a 2a 2a 20 2a 7a 44 64 65 73 74 20 d to.** *zDdest
2160: 61 6e 64 20 6f 77 6e 65 72 73 68 69 70 20 69 73 and ownership is
2170: 20 74 72 61 6e 73 66 65 72 65 64 20 74 6f 20 74 transfered to t
2180: 68 65 20 63 61 6c 6c 65 72 20 28 77 68 6f 20 73 he caller (who s
2190: 68 6f 75 6c 64 0a 2a 2a 20 65 76 65 6e 74 75 61 hould.** eventua
21a0: 6c 6c 79 20 70 61 73 73 20 69 74 20 74 6f 20 66 lly pass it to f
21b0: 72 65 65 28 29 29 2e 0a 2a 2f 0a 76 6f 69 64 20 ree())..*/.void
21c0: 6c 6f 67 69 6e 5f 73 65 74 5f 75 73 65 72 5f 63 login_set_user_c
21d0: 6f 6f 6b 69 65 28 0a 20 20 63 6f 6e 73 74 20 63 ookie(. const c
21e0: 68 61 72 20 2a 7a 55 73 65 72 6e 61 6d 65 2c 20 har *zUsername,
21f0: 20 2f 2a 20 55 73 65 72 27 73 20 6e 61 6d 65 20 /* User's name
2200: 2a 2f 0a 20 20 69 6e 74 20 75 69 64 2c 20 20 20 */. int uid,
2210: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
2220: 55 73 65 72 27 73 20 49 44 20 2a 2f 0a 20 20 63 User's ID */. c
2230: 68 61 72 20 2a 2a 7a 44 65 73 74 20 20 20 20 20 har **zDest
2240: 20 20 20 20 20 20 20 2f 2a 20 4f 70 74 69 6f 6e /* Option
2250: 61 6c 3a 20 73 74 6f 72 65 20 67 65 6e 65 72 61 al: store genera
2260: 74 65 64 20 63 6f 6f 6b 69 65 20 76 61 6c 75 65 ted cookie value
2270: 2e 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 . */.){. const
2280: 63 68 61 72 20 2a 7a 43 6f 6f 6b 69 65 4e 61 6d char *zCookieNam
2290: 65 20 3d 20 6c 6f 67 69 6e 5f 63 6f 6f 6b 69 65 e = login_cookie
22a0: 5f 6e 61 6d 65 28 29 3b 0a 20 20 63 6f 6e 73 74 _name();. const
22b0: 20 63 68 61 72 20 2a 7a 45 78 70 69 72 65 20 3d char *zExpire =
22c0: 20 64 62 5f 67 65 74 28 22 63 6f 6f 6b 69 65 2d db_get("cookie-
22d0: 65 78 70 69 72 65 22 2c 22 38 37 36 36 22 29 3b expire","8766");
22e0: 0a 20 20 69 6e 74 20 65 78 70 69 72 65 73 20 3d . int expires =
22f0: 20 61 74 6f 69 28 7a 45 78 70 69 72 65 29 2a 33 atoi(zExpire)*3
2300: 36 30 30 3b 0a 20 20 63 68 61 72 20 2a 7a 48 61 600;. char *zHa
2310: 73 68 3b 0a 20 20 63 68 61 72 20 2a 7a 43 6f 6f sh;. char *zCoo
2320: 6b 69 65 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 kie;. const cha
2330: 72 20 2a 7a 49 70 41 64 64 72 20 3d 20 50 44 28 r *zIpAddr = PD(
2340: 22 52 45 4d 4f 54 45 5f 41 44 44 52 22 2c 22 6e "REMOTE_ADDR","n
2350: 69 6c 22 29 3b 20 2f 2a 20 49 50 20 61 64 64 72 il"); /* IP addr
2360: 65 73 73 20 6f 66 20 75 73 65 72 20 2a 2f 0a 20 ess of user */.
2370: 20 63 68 61 72 20 2a 7a 52 65 6d 6f 74 65 41 64 char *zRemoteAd
2380: 64 72 20 3d 20 69 70 50 72 65 66 69 78 28 7a 49 dr = ipPrefix(zI
2390: 70 41 64 64 72 29 3b 20 20 20 20 20 20 20 20 20 pAddr);
23a0: 2f 2a 20 41 62 62 72 65 76 69 61 74 65 64 20 49 /* Abbreviated I
23b0: 50 20 61 64 64 72 65 73 73 20 2a 2f 0a 0a 20 20 P address */..
23c0: 61 73 73 65 72 74 28 28 7a 55 73 65 72 6e 61 6d assert((zUsernam
23d0: 65 20 26 26 20 2a 7a 55 73 65 72 6e 61 6d 65 29 e && *zUsername)
23e0: 20 26 26 20 28 75 69 64 20 3e 20 30 29 20 26 26 && (uid > 0) &&
23f0: 20 22 49 6e 76 61 6c 69 64 20 75 73 65 72 20 64 "Invalid user d
2400: 61 74 61 2e 22 29 3b 0a 20 20 7a 48 61 73 68 20 ata.");. zHash
2410: 3d 20 64 62 5f 74 65 78 74 28 30 2c 0a 20 20 20 = db_text(0,.
2420: 20 20 20 22 53 45 4c 45 43 54 20 63 6f 6f 6b 69 "SELECT cooki
2430: 65 20 46 52 4f 4d 20 75 73 65 72 22 0a 20 20 20 e FROM user".
2440: 20 20 20 22 20 57 48 45 52 45 20 75 69 64 3d 25 " WHERE uid=%
2450: 64 22 0a 20 20 20 20 20 20 22 20 20 20 41 4e 44 d". " AND
2460: 20 69 70 61 64 64 72 3d 25 51 22 0a 20 20 20 20 ipaddr=%Q".
2470: 20 20 22 20 20 20 41 4e 44 20 63 65 78 70 69 72 " AND cexpir
2480: 65 3e 6a 75 6c 69 61 6e 64 61 79 28 27 6e 6f 77 e>julianday('now
2490: 27 29 22 0a 20 20 20 20 20 20 22 20 20 20 41 4e ')". " AN
24a0: 44 20 6c 65 6e 67 74 68 28 63 6f 6f 6b 69 65 29 D length(cookie)
24b0: 3e 33 30 22 2c 0a 20 20 20 20 20 20 75 69 64 2c >30",. uid,
24c0: 20 7a 52 65 6d 6f 74 65 41 64 64 72 29 3b 0a 20 zRemoteAddr);.
24d0: 20 69 66 28 20 7a 48 61 73 68 3d 3d 30 20 29 20 if( zHash==0 )
24e0: 7a 48 61 73 68 20 3d 20 64 62 5f 74 65 78 74 28 zHash = db_text(
24f0: 30 2c 20 22 53 45 4c 45 43 54 20 68 65 78 28 72 0, "SELECT hex(r
2500: 61 6e 64 6f 6d 62 6c 6f 62 28 32 35 29 29 22 29 andomblob(25))")
2510: 3b 0a 20 20 7a 43 6f 6f 6b 69 65 20 3d 20 6c 6f ;. zCookie = lo
2520: 67 69 6e 5f 67 65 6e 5f 75 73 65 72 5f 63 6f 6f gin_gen_user_coo
2530: 6b 69 65 5f 76 61 6c 75 65 28 7a 55 73 65 72 6e kie_value(zUsern
2540: 61 6d 65 2c 20 7a 48 61 73 68 29 3b 0a 20 20 63 ame, zHash);. c
2550: 67 69 5f 73 65 74 5f 63 6f 6f 6b 69 65 28 7a 43 gi_set_cookie(zC
2560: 6f 6f 6b 69 65 4e 61 6d 65 2c 20 7a 43 6f 6f 6b ookieName, zCook
2570: 69 65 2c 20 6c 6f 67 69 6e 5f 63 6f 6f 6b 69 65 ie, login_cookie
2580: 5f 70 61 74 68 28 29 2c 20 65 78 70 69 72 65 73 _path(), expires
2590: 29 3b 0a 20 20 72 65 63 6f 72 64 5f 6c 6f 67 69 );. record_logi
25a0: 6e 5f 61 74 74 65 6d 70 74 28 7a 55 73 65 72 6e n_attempt(zUsern
25b0: 61 6d 65 2c 20 7a 49 70 41 64 64 72 2c 20 31 29 ame, zIpAddr, 1)
25c0: 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65 ;. db_multi_exe
25d0: 63 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 c(.
25e0: 20 20 20 22 55 50 44 41 54 45 20 75 73 65 72 20 "UPDATE user
25f0: 53 45 54 20 63 6f 6f 6b 69 65 3d 25 51 2c 20 69 SET cookie=%Q, i
2600: 70 61 64 64 72 3d 25 51 2c 20 22 0a 20 20 20 20 paddr=%Q, ".
2610: 20 20 20 20 20 20 20 20 20 20 20 20 22 20 20 63 " c
2620: 65 78 70 69 72 65 3d 6a 75 6c 69 61 6e 64 61 79 expire=julianday
2630: 28 27 6e 6f 77 27 29 2b 25 64 2f 38 36 34 30 30 ('now')+%d/86400
2640: 2e 30 20 57 48 45 52 45 20 75 69 64 3d 25 64 22 .0 WHERE uid=%d"
2650: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ,.
2660: 20 20 7a 48 61 73 68 2c 20 7a 52 65 6d 6f 74 65 zHash, zRemote
2670: 41 64 64 72 2c 20 65 78 70 69 72 65 73 2c 20 75 Addr, expires, u
2680: 69 64 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 id.
2690: 20 20 20 29 3b 0a 20 20 66 72 65 65 28 7a 52 65 );. free(zRe
26a0: 6d 6f 74 65 41 64 64 72 29 3b 0a 20 20 66 72 65 moteAddr);. fre
26b0: 65 28 7a 48 61 73 68 29 3b 0a 20 20 69 66 28 20 e(zHash);. if(
26c0: 7a 44 65 73 74 20 29 7b 0a 20 20 20 20 2a 7a 44 zDest ){. *zD
26d0: 65 73 74 20 3d 20 7a 43 6f 6f 6b 69 65 3b 0a 20 est = zCookie;.
26e0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 72 65 65 }else{. free
26f0: 28 7a 43 6f 6f 6b 69 65 29 3b 0a 20 20 7d 0a 7d (zCookie);. }.}
2700: 0a 0a 2f 2a 20 53 65 74 73 20 61 20 63 6f 6f 6b ../* Sets a cook
2710: 69 65 20 66 6f 72 20 61 6e 20 61 6e 6f 6e 79 6d ie for an anonym
2720: 6f 75 73 20 75 73 65 72 20 6c 6f 67 69 6e 2c 20 ous user login,
2730: 77 68 69 63 68 20 6c 6f 6f 6b 73 20 6c 69 6b 65 which looks like
2740: 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 this:.**.**
2750: 48 41 53 48 2f 54 49 4d 45 2f 61 6e 6f 6e 79 6d HASH/TIME/anonym
2760: 6f 75 73 0a 2a 2a 0a 2a 2a 20 57 68 65 72 65 20 ous.**.** Where
2770: 48 41 53 48 20 69 73 20 74 68 65 20 73 68 61 31 HASH is the sha1
2780: 73 75 6d 20 6f 66 20 54 49 4d 45 2f 49 50 41 44 sum of TIME/IPAD
2790: 44 52 2f 53 45 43 52 45 54 2c 20 69 6e 20 77 68 DR/SECRET, in wh
27a0: 69 63 68 20 49 50 41 44 44 52 0a 2a 2a 20 69 73 ich IPADDR.** is
27b0: 20 74 68 65 20 61 62 62 72 65 76 69 61 74 65 64 the abbreviated
27c0: 20 49 50 20 61 64 64 72 65 73 73 20 61 6e 64 20 IP address and
27d0: 53 45 43 52 45 54 20 69 73 20 63 61 70 74 63 68 SECRET is captch
27e0: 61 2d 73 65 63 72 65 74 2e 0a 2a 2a 0a 2a 2a 20 a-secret..**.**
27f0: 49 66 20 65 69 74 68 65 72 20 7a 49 70 41 64 64 If either zIpAdd
2800: 72 20 6f 72 20 7a 52 65 6d 6f 74 65 41 64 64 72 r or zRemoteAddr
2810: 20 61 72 65 20 4e 55 4c 4c 20 74 68 65 6e 20 52 are NULL then R
2820: 45 4d 4f 54 45 5f 41 44 44 52 0a 2a 2a 20 69 73 EMOTE_ADDR.** is
2830: 20 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 used..**.** If
2840: 7a 43 6f 6f 6b 69 65 44 65 73 74 20 69 73 20 6e zCookieDest is n
2850: 6f 74 20 4e 55 4c 4c 20 74 68 65 6e 20 74 68 65 ot NULL then the
2860: 20 67 65 6e 65 72 61 74 65 64 20 63 6f 6f 6b 69 generated cooki
2870: 65 20 69 73 20 61 73 73 69 67 6e 65 64 20 74 6f e is assigned to
2880: 0a 2a 2a 20 2a 7a 43 6f 6f 6b 69 65 44 65 73 74 .** *zCookieDest
2890: 20 61 6e 64 20 74 68 65 20 63 61 6c 6c 65 72 20 and the caller
28a0: 6d 75 73 74 20 65 76 65 6e 74 75 61 6c 6c 79 20 must eventually
28b0: 66 72 65 65 28 29 20 69 74 2e 0a 2a 2f 0a 76 6f free() it..*/.vo
28c0: 69 64 20 6c 6f 67 69 6e 5f 73 65 74 5f 61 6e 6f id login_set_ano
28d0: 6e 5f 63 6f 6f 6b 69 65 28 63 6f 6e 73 74 20 63 n_cookie(const c
28e0: 68 61 72 20 2a 7a 49 70 41 64 64 72 2c 20 63 68 har *zIpAddr, ch
28f0: 61 72 20 2a 2a 7a 43 6f 6f 6b 69 65 44 65 73 74 ar **zCookieDest
2900: 20 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 ){. const char
2910: 20 2a 7a 4e 6f 77 3b 20 20 20 20 20 20 20 20 20 *zNow;
2920: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 74 69 /* Current ti
2930: 6d 65 20 28 6a 75 6c 69 61 6e 20 64 61 79 20 6e me (julian day n
2940: 75 6d 62 65 72 29 20 2a 2f 0a 20 20 63 68 61 72 umber) */. char
2950: 20 2a 7a 43 6f 6f 6b 69 65 3b 20 20 20 20 20 20 *zCookie;
2960: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 /* The
2970: 6c 6f 67 69 6e 20 63 6f 6f 6b 69 65 20 2a 2f 0a login cookie */.
2980: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 const char *zC
2990: 6f 6f 6b 69 65 4e 61 6d 65 3b 20 20 20 20 20 2f ookieName; /
29a0: 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 6c 6f * Name of the lo
29b0: 67 69 6e 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 gin cookie */.
29c0: 42 6c 6f 62 20 62 3b 20 20 20 20 20 20 20 20 20 Blob b;
29d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
29e0: 42 6c 6f 62 20 75 73 65 64 20 64 75 72 69 6e 67 Blob used during
29f0: 20 63 6f 6f 6b 69 65 20 63 6f 6e 73 74 72 75 63 cookie construc
2a00: 74 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a tion */. char *
2a10: 7a 52 65 6d 6f 74 65 41 64 64 72 3b 20 20 20 20 zRemoteAddr;
2a20: 20 20 20 20 20 20 20 2f 2a 20 41 62 62 72 65 76 /* Abbrev
2a30: 69 61 74 65 64 20 49 50 20 61 64 64 72 65 73 73 iated IP address
2a40: 20 2a 2f 0a 20 20 69 66 28 21 7a 49 70 41 64 64 */. if(!zIpAdd
2a50: 72 29 7b 0a 20 20 20 20 7a 49 70 41 64 64 72 20 r){. zIpAddr
2a60: 3d 20 50 44 28 22 52 45 4d 4f 54 45 5f 41 44 44 = PD("REMOTE_ADD
2a70: 52 22 2c 22 6e 69 6c 22 29 3b 0a 20 20 7d 0a 20 R","nil");. }.
2a80: 20 7a 52 65 6d 6f 74 65 41 64 64 72 20 3d 20 69 zRemoteAddr = i
2a90: 70 50 72 65 66 69 78 28 7a 49 70 41 64 64 72 29 pPrefix(zIpAddr)
2aa0: 3b 0a 20 20 7a 43 6f 6f 6b 69 65 4e 61 6d 65 20 ;. zCookieName
2ab0: 3d 20 6c 6f 67 69 6e 5f 63 6f 6f 6b 69 65 5f 6e = login_cookie_n
2ac0: 61 6d 65 28 29 3b 0a 20 20 7a 4e 6f 77 20 3d 20 ame();. zNow =
2ad0: 64 62 5f 74 65 78 74 28 22 30 22 2c 20 22 53 45 db_text("0", "SE
2ae0: 4c 45 43 54 20 6a 75 6c 69 61 6e 64 61 79 28 27 LECT julianday('
2af0: 6e 6f 77 27 29 22 29 3b 0a 20 20 61 73 73 65 72 now')");. asser
2b00: 74 28 20 7a 43 6f 6f 6b 69 65 4e 61 6d 65 20 26 t( zCookieName &
2b10: 26 20 7a 52 65 6d 6f 74 65 41 64 64 72 20 26 26 & zRemoteAddr &&
2b20: 20 7a 49 70 41 64 64 72 20 26 26 20 7a 4e 6f 77 zIpAddr && zNow
2b30: 20 29 3b 0a 20 20 62 6c 6f 62 5f 69 6e 69 74 28 );. blob_init(
2b40: 26 62 2c 20 7a 4e 6f 77 2c 20 2d 31 29 3b 0a 20 &b, zNow, -1);.
2b50: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 62 blob_appendf(&b
2b60: 2c 20 22 2f 25 73 2f 25 73 22 2c 20 7a 52 65 6d , "/%s/%s", zRem
2b70: 6f 74 65 41 64 64 72 2c 20 64 62 5f 67 65 74 28 oteAddr, db_get(
2b80: 22 63 61 70 74 63 68 61 2d 73 65 63 72 65 74 22 "captcha-secret"
2b90: 2c 22 22 29 29 3b 0a 20 20 73 68 61 31 73 75 6d ,""));. sha1sum
2ba0: 5f 62 6c 6f 62 28 26 62 2c 20 26 62 29 3b 0a 20 _blob(&b, &b);.
2bb0: 20 7a 43 6f 6f 6b 69 65 20 3d 20 6d 70 72 69 6e zCookie = mprin
2bc0: 74 66 28 22 25 73 2f 25 73 2f 61 6e 6f 6e 79 6d tf("%s/%s/anonym
2bd0: 6f 75 73 22 2c 20 62 6c 6f 62 5f 62 75 66 66 65 ous", blob_buffe
2be0: 72 28 26 62 29 2c 20 7a 4e 6f 77 29 3b 0a 20 20 r(&b), zNow);.
2bf0: 62 6c 6f 62 5f 72 65 73 65 74 28 26 62 29 3b 0a blob_reset(&b);.
2c00: 20 20 63 67 69 5f 73 65 74 5f 63 6f 6f 6b 69 65 cgi_set_cookie
2c10: 28 7a 43 6f 6f 6b 69 65 4e 61 6d 65 2c 20 7a 43 (zCookieName, zC
2c20: 6f 6f 6b 69 65 2c 20 6c 6f 67 69 6e 5f 63 6f 6f ookie, login_coo
2c30: 6b 69 65 5f 70 61 74 68 28 29 2c 20 36 2a 33 36 kie_path(), 6*36
2c40: 30 30 29 3b 0a 20 20 69 66 28 20 7a 43 6f 6f 6b 00);. if( zCook
2c50: 69 65 44 65 73 74 20 29 7b 0a 20 20 20 20 2a 7a ieDest ){. *z
2c60: 43 6f 6f 6b 69 65 44 65 73 74 20 3d 20 7a 43 6f CookieDest = zCo
2c70: 6f 6b 69 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 okie;. }else{.
2c80: 20 20 20 66 72 65 65 28 7a 43 6f 6f 6b 69 65 29 free(zCookie)
2c90: 3b 0a 20 20 7d 0a 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 ;. }..}../*.**
2ca0: 22 55 6e 73 65 74 73 22 20 74 68 65 20 6c 6f 67 "Unsets" the log
2cb0: 69 6e 20 63 6f 6f 6b 69 65 20 28 69 6e 73 6f 66 in cookie (insof
2cc0: 61 72 20 61 73 20 63 6f 6f 6b 69 65 73 20 63 61 ar as cookies ca
2cd0: 6e 20 62 65 20 75 6e 73 65 74 29 20 61 6e 64 0a n be unset) and.
2ce0: 2a 2a 20 63 6c 65 61 72 73 20 74 68 65 20 63 75 ** clears the cu
2cf0: 72 72 65 6e 74 20 75 73 65 72 27 73 20 28 67 2e rrent user's (g.
2d00: 75 73 65 72 55 69 64 29 20 6c 6f 67 69 6e 20 69 userUid) login i
2d10: 6e 66 6f 72 6d 61 74 69 6f 6e 20 66 72 6f 6d 20 nformation from
2d20: 74 68 65 0a 2a 2a 20 75 73 65 72 20 74 61 62 6c the.** user tabl
2d30: 65 2e 20 53 65 74 73 3a 20 75 73 65 72 2e 63 6f e. Sets: user.co
2d40: 6f 6b 69 65 2c 20 75 73 65 72 2e 69 70 61 64 64 okie, user.ipadd
2d50: 72 2c 20 75 73 65 72 2e 63 65 78 70 69 72 65 2e r, user.cexpire.
2d60: 0a 2a 2a 0a 2a 2a 20 57 65 20 63 6f 75 6c 64 2f .**.** We could/
2d70: 73 68 6f 75 6c 64 20 61 72 67 75 61 62 6c 79 20 should arguably
2d80: 63 6c 65 61 72 20 6f 75 74 20 67 2e 75 73 65 72 clear out g.user
2d90: 55 69 64 20 61 6e 64 20 67 2e 70 65 72 6d 20 68 Uid and g.perm h
2da0: 65 72 65 2c 20 62 75 74 0a 2a 2a 20 77 65 20 64 ere, but.** we d
2db0: 6f 6e 27 74 20 63 75 72 72 65 6e 74 6c 79 20 64 on't currently d
2dc0: 6f 20 6e 6f 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 o not..**.** Thi
2dd0: 73 20 69 73 20 61 20 6e 6f 2d 6f 70 20 69 66 20 s is a no-op if
2de0: 67 2e 75 73 65 72 55 69 64 20 69 73 20 30 2e 0a g.userUid is 0..
2df0: 2a 2f 0a 76 6f 69 64 20 6c 6f 67 69 6e 5f 63 6c */.void login_cl
2e00: 65 61 72 5f 6c 6f 67 69 6e 5f 64 61 74 61 28 29 ear_login_data()
2e10: 7b 0a 20 20 69 66 28 21 67 2e 75 73 65 72 55 69 {. if(!g.userUi
2e20: 64 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a d){. return;.
2e30: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 63 6f 6e }else{. con
2e40: 73 74 20 63 68 61 72 20 2a 63 6f 6f 6b 69 65 20 st char *cookie
2e50: 3d 20 6c 6f 67 69 6e 5f 63 6f 6f 6b 69 65 5f 6e = login_cookie_n
2e60: 61 6d 65 28 29 3b 0a 20 20 20 20 2f 2a 20 54 6f ame();. /* To
2e70: 20 6c 6f 67 6f 75 74 2c 20 63 68 61 6e 67 65 20 logout, change
2e80: 74 68 65 20 63 6f 6f 6b 69 65 20 76 61 6c 75 65 the cookie value
2e90: 20 74 6f 20 61 6e 20 65 6d 70 74 79 20 73 74 72 to an empty str
2ea0: 69 6e 67 20 2a 2f 0a 20 20 20 20 63 67 69 5f 73 ing */. cgi_s
2eb0: 65 74 5f 63 6f 6f 6b 69 65 28 63 6f 6f 6b 69 65 et_cookie(cookie
2ec0: 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 20 20 , "",.
2ed0: 20 20 20 20 20 20 20 20 20 6c 6f 67 69 6e 5f 63 login_c
2ee0: 6f 6f 6b 69 65 5f 70 61 74 68 28 29 2c 20 2d 38 ookie_path(), -8
2ef0: 36 34 30 30 29 3b 0a 20 20 20 20 64 62 5f 6d 75 6400);. db_mu
2f00: 6c 74 69 5f 65 78 65 63 28 22 55 50 44 41 54 45 lti_exec("UPDATE
2f10: 20 75 73 65 72 20 53 45 54 20 63 6f 6f 6b 69 65 user SET cookie
2f20: 3d 4e 55 4c 4c 2c 20 69 70 61 64 64 72 3d 4e 55 =NULL, ipaddr=NU
2f30: 4c 4c 2c 20 22 0a 20 20 20 20 20 20 20 20 20 20 LL, ".
2f40: 20 20 20 20 20 20 20 20 22 20 20 63 65 78 70 69 " cexpi
2f50: 72 65 3d 30 20 57 48 45 52 45 20 75 69 64 3d 25 re=0 WHERE uid=%
2f60: 64 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 d".
2f70: 20 20 20 20 20 22 20 20 41 4e 44 20 6c 6f 67 69 " AND logi
2f80: 6e 20 4e 4f 54 20 49 4e 20 28 27 61 6e 6f 6e 79 n NOT IN ('anony
2f90: 6d 6f 75 73 27 2c 27 6e 6f 62 6f 64 79 27 2c 22 mous','nobody',"
2fa0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
2fb0: 20 20 20 22 20 20 27 64 65 76 65 6c 6f 70 65 72 " 'developer
2fc0: 27 2c 27 72 65 61 64 65 72 27 29 22 2c 20 67 2e ','reader')", g.
2fd0: 75 73 65 72 55 69 64 29 3b 0a 20 20 20 20 63 67 userUid);. cg
2fe0: 69 5f 72 65 70 6c 61 63 65 5f 70 61 72 61 6d 65 i_replace_parame
2ff0: 74 65 72 28 63 6f 6f 6b 69 65 2c 20 4e 55 4c 4c ter(cookie, NULL
3000: 29 3b 0a 20 20 20 20 63 67 69 5f 72 65 70 6c 61 );. cgi_repla
3010: 63 65 5f 70 61 72 61 6d 65 74 65 72 28 22 61 6e ce_parameter("an
3020: 6f 6e 22 2c 20 4e 55 4c 4c 29 3b 0a 20 20 7d 0a on", NULL);. }.
3030: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 }../*.** Return
3040: 74 72 75 65 20 69 66 20 74 68 65 20 70 72 65 66 true if the pref
3050: 69 78 20 6f 66 20 7a 53 74 72 20 6d 61 74 63 68 ix of zStr match
3060: 65 73 20 7a 50 61 74 74 65 72 6e 2e 20 20 52 65 es zPattern. Re
3070: 74 75 72 6e 20 66 61 6c 73 65 20 69 66 0a 2a 2a turn false if.**
3080: 20 74 68 65 79 20 61 72 65 20 64 69 66 66 65 72 they are differ
3090: 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 41 20 6c 6f 77 ent..**.** A low
30a0: 65 72 63 61 73 65 20 63 68 61 72 61 63 74 65 72 ercase character
30b0: 20 69 6e 20 7a 50 61 74 74 65 72 6e 20 77 69 6c in zPattern wil
30c0: 6c 20 6d 61 74 63 68 20 65 69 74 68 65 72 20 75 l match either u
30d0: 70 70 65 72 20 6f 72 20 6c 6f 77 65 72 0a 2a 2a pper or lower.**
30e0: 20 63 61 73 65 20 69 6e 20 7a 53 74 72 2e 20 20 case in zStr.
30f0: 42 75 74 20 61 6e 20 75 70 70 65 72 63 61 73 65 But an uppercase
3100: 20 69 6e 20 7a 50 61 74 74 65 72 6e 20 77 69 6c in zPattern wil
3110: 6c 20 6f 6e 6c 79 20 6d 61 74 63 68 20 61 6e 0a l only match an.
3120: 2a 2a 20 75 70 70 65 72 63 61 73 65 20 69 6e 20 ** uppercase in
3130: 7a 53 74 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 zStr..*/.static
3140: 69 6e 74 20 70 72 65 66 69 78 5f 6d 61 74 63 68 int prefix_match
3150: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 (const char *zPa
3160: 74 74 65 72 6e 2c 20 63 6f 6e 73 74 20 63 68 61 ttern, const cha
3170: 72 20 2a 7a 53 74 72 29 7b 0a 20 20 69 6e 74 20 r *zStr){. int
3180: 69 3b 0a 20 20 63 68 61 72 20 63 3b 0a 20 20 66 i;. char c;. f
3190: 6f 72 28 69 3d 30 3b 20 28 63 20 3d 20 7a 50 61 or(i=0; (c = zPa
31a0: 74 74 65 72 6e 5b 69 5d 29 21 3d 30 3b 20 69 2b ttern[i])!=0; i+
31b0: 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 53 74 72 +){. if( zStr
31c0: 5b 69 5d 21 3d 63 20 26 26 20 66 6f 73 73 69 6c [i]!=c && fossil
31d0: 5f 74 6f 6c 6f 77 65 72 28 7a 53 74 72 5b 69 5d _tolower(zStr[i]
31e0: 29 21 3d 63 20 29 20 72 65 74 75 72 6e 20 30 3b )!=c ) return 0;
31f0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 31 3b . }. return 1;
3200: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 6f 6b 20 61 .}../*.** Look a
3210: 74 20 74 68 65 20 48 54 54 50 5f 55 53 45 52 5f t the HTTP_USER_
3220: 41 47 45 4e 54 20 70 61 72 61 6d 65 74 65 72 20 AGENT parameter
3230: 61 6e 64 20 74 72 79 20 74 6f 20 64 65 74 65 72 and try to deter
3240: 6d 69 6e 65 20 69 66 20 74 68 65 20 75 73 65 72 mine if the user
3250: 20 61 67 65 6e 74 0a 2a 2a 20 69 73 20 61 20 6d agent.** is a m
3260: 61 6e 75 61 6c 6c 79 20 6f 70 65 72 61 74 65 64 anually operated
3270: 20 62 72 6f 77 73 65 72 20 6f 72 20 61 20 62 6f browser or a bo
3280: 74 2e 20 20 57 68 65 6e 20 69 6e 20 64 6f 75 62 t. When in doub
3290: 74 2c 20 61 73 73 75 6d 65 20 61 20 62 6f 74 2e t, assume a bot.
32a0: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 .** Return true
32b0: 69 66 20 77 65 20 62 65 6c 69 65 76 65 20 74 68 if we believe th
32c0: 65 20 61 67 65 6e 74 20 69 73 20 61 20 72 65 61 e agent is a rea
32d0: 6c 20 70 65 72 73 6f 6e 2e 0a 2a 2f 0a 73 74 61 l person..*/.sta
32e0: 74 69 63 20 69 6e 74 20 69 73 48 75 6d 61 6e 28 tic int isHuman(
32f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 67 65 const char *zAge
3300: 6e 74 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 nt){. int i;.
3310: 69 66 28 20 7a 41 67 65 6e 74 3d 3d 30 20 29 20 if( zAgent==0 )
3320: 72 65 74 75 72 6e 20 30 3b 20 20 2f 2a 20 49 66 return 0; /* If
3330: 20 6e 6f 20 55 73 65 72 41 67 65 6e 74 2c 20 74 no UserAgent, t
3340: 68 65 6e 20 70 72 6f 62 61 62 6c 79 20 61 20 62 hen probably a b
3350: 6f 74 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b ot */. for(i=0;
3360: 20 7a 41 67 65 6e 74 5b 69 5d 3b 20 69 2b 2b 29 zAgent[i]; i++)
3370: 7b 0a 20 20 20 20 69 66 28 20 70 72 65 66 69 78 {. if( prefix
3380: 5f 6d 61 74 63 68 28 22 62 6f 74 22 2c 20 7a 41 _match("bot", zA
3390: 67 65 6e 74 2b 69 29 20 29 20 72 65 74 75 72 6e gent+i) ) return
33a0: 20 30 3b 0a 20 20 20 20 69 66 28 20 70 72 65 66 0;. if( pref
33b0: 69 78 5f 6d 61 74 63 68 28 22 73 70 69 64 65 72 ix_match("spider
33c0: 22 2c 20 7a 41 67 65 6e 74 2b 69 29 20 29 20 72 ", zAgent+i) ) r
33d0: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 69 66 28 eturn 0;. if(
33e0: 20 70 72 65 66 69 78 5f 6d 61 74 63 68 28 22 63 prefix_match("c
33f0: 72 61 77 6c 22 2c 20 7a 41 67 65 6e 74 2b 69 29 rawl", zAgent+i)
3400: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 ) return 0;.
3410: 20 2f 2a 20 49 66 20 61 20 55 52 49 20 61 70 70 /* If a URI app
3420: 65 61 72 73 20 69 6e 20 74 68 65 20 55 73 65 72 ears in the User
3430: 2d 41 67 65 6e 74 2c 20 69 74 20 69 73 20 70 72 -Agent, it is pr
3440: 6f 62 61 62 6c 79 20 61 20 62 6f 74 20 2a 2f 0a obably a bot */.
3450: 20 20 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28 if( strncmp(
3460: 22 68 74 74 70 22 2c 20 7a 41 67 65 6e 74 2b 69 "http", zAgent+i
3470: 2c 34 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 ,4)==0 ) return
3480: 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73 74 72 0;. }. if( str
3490: 6e 63 6d 70 28 7a 41 67 65 6e 74 2c 20 22 4d 6f ncmp(zAgent, "Mo
34a0: 7a 69 6c 6c 61 2f 22 2c 20 38 29 3d 3d 30 20 29 zilla/", 8)==0 )
34b0: 7b 0a 20 20 20 20 69 66 28 20 61 74 6f 69 28 26 {. if( atoi(&
34c0: 7a 41 67 65 6e 74 5b 38 5d 29 3c 34 20 29 20 72 zAgent[8])<4 ) r
34d0: 65 74 75 72 6e 20 30 3b 20 20 2f 2a 20 4d 61 6e eturn 0; /* Man
34e0: 79 20 62 6f 74 73 20 61 64 76 65 72 74 69 73 65 y bots advertise
34f0: 20 61 73 20 4d 6f 7a 69 6c 6c 61 2f 33 20 2a 2f as Mozilla/3 */
3500: 0a 0a 20 20 20 20 2f 2a 20 32 30 31 36 2d 30 35 .. /* 2016-05
3510: 2d 33 30 3a 20 20 41 20 70 65 72 6e 69 63 69 6f -30: A pernicio
3520: 75 73 20 73 70 69 64 65 72 20 74 68 61 74 20 6c us spider that l
3530: 69 6b 65 73 20 74 6f 20 77 61 6c 6b 20 46 6f 73 ikes to walk Fos
3540: 73 69 6c 20 74 69 6d 65 6c 69 6e 65 73 20 68 61 sil timelines ha
3550: 73 0a 20 20 20 20 2a 2a 20 62 65 65 6e 20 64 65 s. ** been de
3560: 74 65 63 74 65 64 20 6f 6e 20 74 68 65 20 53 51 tected on the SQ
3570: 4c 69 74 65 20 77 65 62 73 69 74 65 2e 20 20 54 Lite website. T
3580: 68 65 20 73 70 69 64 65 72 20 63 68 61 6e 67 65 he spider change
3590: 73 20 69 74 73 20 75 73 65 72 2d 61 67 65 6e 74 s its user-agent
35a0: 0a 20 20 20 20 2a 2a 20 73 74 72 69 6e 67 20 66 . ** string f
35b0: 72 65 71 75 65 6e 74 6c 79 2c 20 62 75 74 20 69 requently, but i
35c0: 74 20 61 6c 77 61 79 73 20 73 65 65 6d 73 20 74 t always seems t
35d0: 6f 20 69 6e 63 6c 75 64 65 20 74 68 65 20 66 6f o include the fo
35e0: 6c 6c 6f 77 69 6e 67 20 74 65 78 74 3a 0a 20 20 llowing text:.
35f0: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 71 6c */. if( sql
3600: 69 74 65 33 5f 73 74 72 67 6c 6f 62 28 22 2a 53 ite3_strglob("*S
3610: 61 66 61 72 69 2f 35 33 37 2e 33 36 4d 6f 7a 69 afari/537.36Mozi
3620: 6c 6c 61 2f 35 2e 30 2a 22 2c 20 7a 41 67 65 6e lla/5.0*", zAgen
3630: 74 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 t)==0 ) return 0
3640: 3b 0a 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 ;.. if( sqlit
3650: 65 33 5f 73 74 72 67 6c 6f 62 28 22 2a 46 69 72 e3_strglob("*Fir
3660: 65 66 6f 78 2f 5b 31 2d 39 5d 2a 22 2c 20 7a 41 efox/[1-9]*", zA
3670: 67 65 6e 74 29 3d 3d 30 20 29 20 72 65 74 75 72 gent)==0 ) retur
3680: 6e 20 31 3b 0a 20 20 20 20 69 66 28 20 73 71 6c n 1;. if( sql
3690: 69 74 65 33 5f 73 74 72 67 6c 6f 62 28 22 2a 43 ite3_strglob("*C
36a0: 68 72 6f 6d 65 2f 5b 31 2d 39 5d 2a 22 2c 20 7a hrome/[1-9]*", z
36b0: 41 67 65 6e 74 29 3d 3d 30 20 29 20 72 65 74 75 Agent)==0 ) retu
36c0: 72 6e 20 31 3b 0a 20 20 20 20 69 66 28 20 73 71 rn 1;. if( sq
36d0: 6c 69 74 65 33 5f 73 74 72 67 6c 6f 62 28 22 2a lite3_strglob("*
36e0: 28 63 6f 6d 70 61 74 69 62 6c 65 3b 3f 4d 53 49 (compatible;?MSI
36f0: 45 3f 5b 31 37 38 39 5d 2a 22 2c 20 7a 41 67 65 E?[1789]*", zAge
3700: 6e 74 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 nt)==0 ) return
3710: 31 3b 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 1;. if( sqlit
3720: 65 33 5f 73 74 72 67 6c 6f 62 28 22 2a 54 72 69 e3_strglob("*Tri
3730: 64 65 6e 74 2f 5b 31 2d 39 5d 2a 3b 3f 72 76 3a dent/[1-9]*;?rv:
3740: 5b 31 2d 39 5d 2a 22 2c 20 7a 41 67 65 6e 74 29 [1-9]*", zAgent)
3750: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b 20 ==0 ) return 1;
3760: 2f 2a 20 49 45 31 31 2b 20 2a 2f 0a 20 20 20 20 /* IE11+ */.
3770: 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72 67 if( sqlite3_strg
3780: 6c 6f 62 28 22 2a 41 70 70 6c 65 57 65 62 4b 69 lob("*AppleWebKi
3790: 74 2f 5b 31 2d 39 5d 2a 28 4b 48 54 4d 4c 2a 22 t/[1-9]*(KHTML*"
37a0: 2c 20 7a 41 67 65 6e 74 29 3d 3d 30 20 29 20 72 , zAgent)==0 ) r
37b0: 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 72 65 74 eturn 1;. ret
37c0: 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 urn 0;. }. if(
37d0: 20 73 74 72 6e 63 6d 70 28 7a 41 67 65 6e 74 2c strncmp(zAgent,
37e0: 20 22 4f 70 65 72 61 2f 22 2c 20 36 29 3d 3d 30 "Opera/", 6)==0
37f0: 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 69 ) return 1;. i
3800: 66 28 20 73 74 72 6e 63 6d 70 28 7a 41 67 65 6e f( strncmp(zAgen
3810: 74 2c 20 22 53 61 66 61 72 69 2f 22 2c 20 37 29 t, "Safari/", 7)
3820: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a ==0 ) return 1;.
3830: 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28 7a 41 if( strncmp(zA
3840: 67 65 6e 74 2c 20 22 4c 79 6e 78 2f 22 2c 20 35 gent, "Lynx/", 5
3850: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b )==0 ) return 1;
3860: 0a 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28 7a . if( strncmp(z
3870: 41 67 65 6e 74 2c 20 22 4e 65 74 53 75 72 66 2f Agent, "NetSurf/
3880: 22 2c 20 38 29 3d 3d 30 20 29 20 72 65 74 75 72 ", 8)==0 ) retur
3890: 6e 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b n 1;. return 0;
38a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e .}../*.** COMMAN
38b0: 44 3a 20 74 65 73 74 2d 69 73 68 75 6d 61 6e 0a D: test-ishuman.
38c0: 2a 2a 0a 2a 2a 20 52 65 61 64 20 6c 69 6e 65 73 **.** Read lines
38d0: 20 6f 66 20 74 65 78 74 20 66 72 6f 6d 20 73 74 of text from st
38e0: 61 6e 64 61 72 64 20 69 6e 70 75 74 2e 20 20 49 andard input. I
38f0: 6e 74 65 72 70 72 65 74 20 65 61 63 68 20 6c 69 nterpret each li
3900: 6e 65 20 6f 66 20 74 65 78 74 0a 2a 2a 20 61 73 ne of text.** as
3910: 20 61 20 55 73 65 72 2d 41 67 65 6e 74 20 73 74 a User-Agent st
3920: 72 69 6e 67 20 66 72 6f 6d 20 61 6e 20 48 54 54 ring from an HTT
3930: 50 20 68 65 61 64 65 72 2e 20 20 4c 61 62 65 6c P header. Label
3940: 20 65 61 63 68 20 6c 69 6e 65 20 61 73 20 48 55 each line as HU
3950: 4d 41 4e 0a 2a 2a 20 6f 72 20 52 4f 42 4f 54 2e MAN.** or ROBOT.
3960: 0a 2a 2f 0a 76 6f 69 64 20 74 65 73 74 5f 69 73 .*/.void test_is
3970: 68 75 6d 61 6e 28 76 6f 69 64 29 7b 0a 20 20 63 human(void){. c
3980: 68 61 72 20 7a 4c 69 6e 65 5b 33 30 30 30 5d 3b har zLine[3000];
3990: 0a 20 20 77 68 69 6c 65 28 20 66 67 65 74 73 28 . while( fgets(
39a0: 7a 4c 69 6e 65 2c 20 73 69 7a 65 6f 66 28 7a 4c zLine, sizeof(zL
39b0: 69 6e 65 29 2c 20 73 74 64 69 6e 29 20 29 7b 0a ine), stdin) ){.
39c0: 20 20 20 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 fossil_print
39d0: 28 22 25 73 20 25 73 22 2c 20 69 73 48 75 6d 61 ("%s %s", isHuma
39e0: 6e 28 7a 4c 69 6e 65 29 20 3f 20 22 48 55 4d 41 n(zLine) ? "HUMA
39f0: 4e 22 20 3a 20 22 52 4f 42 4f 54 22 2c 20 7a 4c N" : "ROBOT", zL
3a00: 69 6e 65 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a ine);. }.}../*.
3a10: 2a 2a 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20 ** SQL function
3a20: 66 6f 72 20 63 6f 6e 73 74 61 6e 74 20 74 69 6d for constant tim
3a30: 65 20 63 6f 6d 70 61 72 69 73 6f 6e 20 6f 66 20 e comparison of
3a40: 74 77 6f 20 76 61 6c 75 65 73 2e 0a 2a 2a 20 53 two values..** S
3a50: 65 74 73 20 72 65 73 75 6c 74 20 74 6f 20 30 20 ets result to 0
3a60: 69 66 20 74 77 6f 20 76 61 6c 75 65 73 20 61 72 if two values ar
3a70: 65 20 65 71 75 61 6c 2e 0a 2a 2f 0a 73 74 61 74 e equal..*/.stat
3a80: 69 63 20 76 6f 69 64 20 63 6f 6e 73 74 61 6e 74 ic void constant
3a90: 5f 74 69 6d 65 5f 63 6d 70 5f 66 75 6e 63 74 69 _time_cmp_functi
3aa0: 6f 6e 28 0a 20 73 71 6c 69 74 65 33 5f 63 6f 6e on(. sqlite3_con
3ab0: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 text *context,.
3ac0: 69 6e 74 20 61 72 67 63 2c 0a 20 73 71 6c 69 74 int argc,. sqlit
3ad0: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a e3_value **argv.
3ae0: 29 7b 0a 20 20 63 6f 6e 73 74 20 75 6e 73 69 67 ){. const unsig
3af0: 6e 65 64 20 63 68 61 72 20 2a 62 75 66 31 2c 20 ned char *buf1,
3b00: 2a 62 75 66 32 3b 0a 20 20 69 6e 74 20 6c 65 6e *buf2;. int len
3b10: 2c 20 69 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 , i;. unsigned
3b20: 63 68 61 72 20 72 63 20 3d 20 30 3b 0a 0a 20 20 char rc = 0;..
3b30: 61 73 73 65 72 74 28 20 61 72 67 63 3d 3d 32 20 assert( argc==2
3b40: 29 3b 0a 20 20 6c 65 6e 20 3d 20 73 71 6c 69 74 );. len = sqlit
3b50: 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61 e3_value_bytes(a
3b60: 72 67 76 5b 30 5d 29 3b 0a 20 20 69 66 28 20 6c rgv[0]);. if( l
3b70: 65 6e 3d 3d 30 20 7c 7c 20 6c 65 6e 21 3d 73 71 en==0 || len!=sq
3b80: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 lite3_value_byte
3b90: 73 28 61 72 67 76 5b 31 5d 29 20 29 7b 0a 20 20 s(argv[1]) ){.
3ba0: 20 20 72 63 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 rc = 1;. }els
3bb0: 65 7b 0a 20 20 20 20 62 75 66 31 20 3d 20 73 71 e{. buf1 = sq
3bc0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 lite3_value_text
3bd0: 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 20 20 62 (argv[0]);. b
3be0: 75 66 32 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 uf2 = sqlite3_va
3bf0: 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 31 5d lue_text(argv[1]
3c00: 29 3b 0a 20 20 20 20 66 6f 72 28 20 69 3d 30 3b );. for( i=0;
3c10: 20 69 3c 6c 65 6e 3b 20 69 2b 2b 20 29 7b 0a 20 i<len; i++ ){.
3c20: 20 20 20 20 20 72 63 20 3d 20 72 63 20 7c 20 28 rc = rc | (
3c30: 62 75 66 31 5b 69 5d 20 5e 20 62 75 66 32 5b 69 buf1[i] ^ buf2[i
3c40: 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 ]);. }. }.
3c50: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 69 sqlite3_result_i
3c60: 6e 74 28 63 6f 6e 74 65 78 74 2c 20 72 63 29 3b nt(context, rc);
3c70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e .}../*.** Return
3c80: 20 74 72 75 65 20 69 66 20 74 68 65 20 63 75 72 true if the cur
3c90: 72 65 6e 74 20 70 61 67 65 20 77 61 73 20 72 65 rent page was re
3ca0: 61 63 68 65 64 20 62 79 20 61 20 72 65 64 69 72 ached by a redir
3cb0: 65 63 74 20 66 72 6f 6d 20 74 68 65 20 2f 6c 6f ect from the /lo
3cc0: 67 69 6e 0a 2a 2a 20 70 61 67 65 2e 0a 2a 2f 0a gin.** page..*/.
3cd0: 69 6e 74 20 72 65 66 65 72 72 65 64 5f 66 72 6f int referred_fro
3ce0: 6d 5f 6c 6f 67 69 6e 28 76 6f 69 64 29 7b 0a 20 m_login(void){.
3cf0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 65 const char *zRe
3d00: 66 65 72 65 72 20 3d 20 50 28 22 48 54 54 50 5f ferer = P("HTTP_
3d10: 52 45 46 45 52 45 52 22 29 3b 0a 20 20 63 68 61 REFERER");. cha
3d20: 72 20 2a 7a 50 61 74 74 65 72 6e 3b 0a 20 20 69 r *zPattern;. i
3d30: 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 7a 52 65 nt rc;. if( zRe
3d40: 66 65 72 65 72 3d 3d 30 20 29 20 72 65 74 75 72 ferer==0 ) retur
3d50: 6e 20 30 3b 0a 20 20 7a 50 61 74 74 65 72 6e 20 n 0;. zPattern
3d60: 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 2f 6c 6f = mprintf("%s/lo
3d70: 67 69 6e 2a 22 2c 20 67 2e 7a 42 61 73 65 55 52 gin*", g.zBaseUR
3d80: 4c 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 L);. rc = sqlit
3d90: 65 33 5f 73 74 72 67 6c 6f 62 28 7a 50 61 74 74 e3_strglob(zPatt
3da0: 65 72 6e 2c 20 7a 52 65 66 65 72 65 72 29 3d 3d ern, zReferer)==
3db0: 30 3b 0a 20 20 66 6f 73 73 69 6c 5f 66 72 65 65 0;. fossil_free
3dc0: 28 7a 50 61 74 74 65 72 6e 29 3b 0a 20 20 72 65 (zPattern);. re
3dd0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a turn rc;.}../*.*
3de0: 2a 20 52 65 74 75 72 6e 20 54 52 55 45 20 69 66 * Return TRUE if
3df0: 20 73 65 6c 66 2d 72 65 67 69 73 74 72 61 74 69 self-registrati
3e00: 6f 6e 20 69 73 20 61 76 61 69 6c 61 62 6c 65 2e on is available.
3e10: 20 20 49 66 20 74 68 65 20 7a 4e 65 65 64 65 64 If the zNeeded
3e20: 0a 2a 2a 20 61 72 67 75 6d 65 6e 74 20 69 73 20 .** argument is
3e30: 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 6f not NULL, then o
3e40: 6e 6c 79 20 72 65 74 75 72 6e 20 74 72 75 65 20 nly return true
3e50: 69 66 20 73 65 6c 66 2d 72 65 67 69 73 74 72 61 if self-registra
3e60: 74 69 6f 6e 20 69 73 0a 2a 2a 20 61 76 61 69 6c tion is.** avail
3e70: 61 62 6c 65 20 61 6e 64 20 61 6e 79 20 6f 66 20 able and any of
3e80: 74 68 65 20 63 61 70 61 62 69 6c 69 74 69 65 73 the capabilities
3e90: 20 6e 61 6d 65 64 20 69 6e 20 7a 4e 65 65 64 65 named in zNeede
3ea0: 64 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65 0a d are available.
3eb0: 2a 2a 20 74 6f 20 73 65 6c 66 2d 72 65 67 69 73 ** to self-regis
3ec0: 74 65 72 65 64 20 75 73 65 72 73 2e 0a 2a 2f 0a tered users..*/.
3ed0: 69 6e 74 20 6c 6f 67 69 6e 5f 73 65 6c 66 5f 72 int login_self_r
3ee0: 65 67 69 73 74 65 72 5f 61 76 61 69 6c 61 62 6c egister_availabl
3ef0: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e e(const char *zN
3f00: 65 65 64 65 64 29 7b 0a 20 20 43 61 70 61 62 69 eeded){. Capabi
3f10: 6c 69 74 79 53 74 72 69 6e 67 20 2a 70 43 61 70 lityString *pCap
3f20: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 ;. int rc;. if
3f30: 28 20 21 64 62 5f 67 65 74 5f 62 6f 6f 6c 65 61 ( !db_get_boolea
3f40: 6e 28 22 73 65 6c 66 2d 72 65 67 69 73 74 65 72 n("self-register
3f50: 22 2c 30 29 20 29 20 72 65 74 75 72 6e 20 30 3b ",0) ) return 0;
3f60: 0a 20 20 69 66 28 20 7a 4e 65 65 64 65 64 3d 3d . if( zNeeded==
3f70: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 0 ) return 1;.
3f80: 70 43 61 70 20 3d 20 63 61 70 61 62 69 6c 69 74 pCap = capabilit
3f90: 79 5f 61 64 64 28 30 2c 20 64 62 5f 67 65 74 28 y_add(0, db_get(
3fa0: 22 64 65 66 61 75 6c 74 2d 70 65 72 6d 73 22 2c "default-perms",
3fb0: 22 22 29 29 3b 0a 20 20 63 61 70 61 62 69 6c 69 ""));. capabili
3fc0: 74 79 5f 65 78 70 61 6e 64 28 70 43 61 70 29 3b ty_expand(pCap);
3fd0: 0a 20 20 72 63 20 3d 20 63 61 70 61 62 69 6c 69 . rc = capabili
3fe0: 74 79 5f 68 61 73 5f 61 6e 79 28 70 43 61 70 2c ty_has_any(pCap,
3ff0: 20 7a 4e 65 65 64 65 64 29 3b 0a 20 20 63 61 70 zNeeded);. cap
4000: 61 62 69 6c 69 74 79 5f 66 72 65 65 28 70 43 61 ability_free(pCa
4010: 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b p);. return rc;
4020: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 72 65 20 .}../*.** There
4030: 75 73 65 64 20 74 6f 20 62 65 20 61 20 70 61 67 used to be a pag
4040: 65 20 6e 61 6d 65 64 20 22 6d 79 22 20 74 68 61 e named "my" tha
4050: 74 20 77 61 73 20 64 65 73 69 67 6e 65 64 20 74 t was designed t
4060: 6f 20 73 68 6f 77 20 69 6e 66 6f 72 6d 61 74 69 o show informati
4070: 6f 6e 0a 2a 2a 20 61 62 6f 75 74 20 61 20 73 70 on.** about a sp
4080: 65 63 69 66 69 63 20 75 73 65 72 2e 20 20 54 68 ecific user. Th
4090: 65 20 22 6d 79 22 20 70 61 67 65 20 77 61 73 20 e "my" page was
40a0: 6c 69 6e 6b 65 64 20 66 72 6f 6d 20 74 68 65 20 linked from the
40b0: 22 4c 6f 67 67 65 64 20 69 6e 20 61 73 20 55 53 "Logged in as US
40c0: 45 52 22 0a 2a 2a 20 6c 69 6e 65 20 6f 6e 20 74 ER".** line on t
40d0: 68 65 20 74 69 74 6c 65 20 62 61 72 2e 20 20 54 he title bar. T
40e0: 68 65 20 22 6d 79 22 20 70 61 67 65 20 77 61 73 he "my" page was
40f0: 20 6e 65 76 65 72 20 63 6f 6d 70 6c 65 74 65 64 never completed
4100: 20 73 6f 20 69 74 20 69 73 20 6e 6f 77 0a 2a 2a so it is now.**
4110: 20 72 65 6d 6f 76 65 64 2e 20 20 55 73 65 20 74 removed. Use t
4120: 68 69 73 20 70 61 67 65 20 61 73 20 61 20 70 6c his page as a pl
4130: 61 63 65 68 6f 6c 64 65 72 20 69 6e 20 6f 6c 64 aceholder in old
4140: 65 72 20 69 6e 73 74 61 6c 6c 61 74 69 6f 6e 73 er installations
4150: 2e 0a 2a 2a 0a 2a 2a 20 57 45 42 50 41 47 45 3a ..**.** WEBPAGE:
4160: 20 6c 6f 67 69 6e 0a 2a 2a 20 57 45 42 50 41 47 login.** WEBPAG
4170: 45 3a 20 6c 6f 67 6f 75 74 0a 2a 2a 20 57 45 42 E: logout.** WEB
4180: 50 41 47 45 3a 20 6d 79 0a 2a 2a 0a 2a 2a 20 54 PAGE: my.**.** T
4190: 68 65 20 6c 6f 67 69 6e 2f 6c 6f 67 6f 75 74 20 he login/logout
41a0: 70 61 67 65 2e 20 20 50 61 72 61 6d 65 74 65 72 page. Parameter
41b0: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 67 3d 55 52 s:.**.** g=UR
41c0: 4c 20 20 20 20 20 20 20 20 20 20 20 20 20 4a 75 L Ju
41d0: 6d 70 20 62 61 63 6b 20 74 6f 20 74 68 69 73 20 mp back to this
41e0: 55 52 4c 20 61 66 74 65 72 20 6c 6f 67 69 6e 20 URL after login
41f0: 63 6f 6d 70 6c 65 74 65 73 0a 2a 2a 20 20 20 20 completes.**
4200: 61 6e 6f 6e 20 20 20 20 20 20 20 20 20 20 20 20 anon
4210: 20 20 54 68 65 20 67 3d 55 52 4c 20 69 73 20 6e The g=URL is n
4220: 6f 74 20 61 63 63 65 73 73 69 62 6c 65 20 62 79 ot accessible by
4230: 20 22 6e 6f 62 6f 64 79 22 20 62 75 74 20 69 73 "nobody" but is
4240: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 .**
4250: 20 20 20 20 20 20 20 20 20 61 63 63 65 73 73 69 accessi
4260: 62 6c 65 20 62 79 20 22 61 6e 6f 6e 79 6d 6f 75 ble by "anonymou
4270: 73 22 0a 2a 2f 0a 76 6f 69 64 20 6c 6f 67 69 6e s".*/.void login
4280: 5f 70 61 67 65 28 76 6f 69 64 29 7b 0a 20 20 63 _page(void){. c
4290: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 73 65 72 onst char *zUser
42a0: 6e 61 6d 65 2c 20 2a 7a 50 61 73 73 77 64 3b 0a name, *zPasswd;.
42b0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e const char *zN
42c0: 65 77 31 2c 20 2a 7a 4e 65 77 32 3b 0a 20 20 63 ew1, *zNew2;. c
42d0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 6e 6f 6e onst char *zAnon
42e0: 50 77 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20 Pw = 0;. const
42f0: 63 68 61 72 20 2a 7a 47 6f 74 6f 20 3d 20 50 28 char *zGoto = P(
4300: 22 67 22 29 3b 0a 20 20 69 6e 74 20 61 6e 6f 6e "g");. int anon
4310: 46 6c 61 67 3b 20 20 20 20 20 20 20 20 20 20 20 Flag;
4320: 20 20 20 20 20 2f 2a 20 4c 6f 67 69 6e 20 61 73 /* Login as
4330: 20 22 61 6e 6f 6e 79 6d 6f 75 73 22 20 77 6f 75 "anonymous" wou
4340: 6c 64 20 62 65 20 75 73 65 66 75 6c 20 2a 2f 0a ld be useful */.
4350: 20 20 63 68 61 72 20 2a 7a 45 72 72 4d 73 67 20 char *zErrMsg
4360: 3d 20 22 22 3b 0a 20 20 69 6e 74 20 75 69 64 3b = "";. int uid;
4370: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4380: 20 20 20 20 20 2f 2a 20 55 73 65 72 20 69 64 20 /* User id
4390: 6c 6f 67 67 65 64 20 69 6e 20 75 73 65 72 20 2a logged in user *
43a0: 2f 0a 20 20 63 68 61 72 20 2a 7a 53 68 61 31 50 /. char *zSha1P
43b0: 77 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 w;. const char
43c0: 2a 7a 49 70 41 64 64 72 3b 20 20 20 20 20 20 20 *zIpAddr;
43d0: 20 20 2f 2a 20 49 50 20 61 64 64 72 65 73 73 20 /* IP address
43e0: 6f 66 20 72 65 71 75 65 73 74 6f 72 20 2a 2f 0a of requestor */.
43f0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 const char *zR
4400: 65 66 65 72 65 72 3b 0a 20 20 69 6e 74 20 6e 6f eferer;. int no
4410: 41 6e 6f 6e 20 3d 20 50 28 22 6e 6f 61 6e 6f 6e Anon = P("noanon
4420: 22 29 21 3d 30 3b 0a 0a 20 20 6c 6f 67 69 6e 5f ")!=0;.. login_
4430: 63 68 65 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c check_credential
4440: 73 28 29 3b 0a 20 20 69 66 28 20 6c 6f 67 69 6e s();. if( login
4450: 5f 77 61 6e 74 73 5f 68 74 74 70 73 5f 72 65 64 _wants_https_red
4460: 69 72 65 63 74 28 29 20 29 7b 0a 20 20 20 20 63 irect() ){. c
4470: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 51 53 20 3d onst char *zQS =
4480: 20 50 28 22 51 55 45 52 59 5f 53 54 52 49 4e 47 P("QUERY_STRING
4490: 22 29 3b 0a 20 20 20 20 69 66 28 20 50 28 22 72 ");. if( P("r
44a0: 65 64 69 72 22 29 21 3d 30 20 29 7b 0a 20 20 20 edir")!=0 ){.
44b0: 20 20 20 73 74 79 6c 65 5f 68 65 61 64 65 72 28 style_header(
44c0: 22 49 6e 73 65 63 75 72 65 20 43 6f 6e 6e 65 63 "Insecure Connec
44d0: 74 69 6f 6e 22 29 3b 0a 20 20 20 20 20 20 40 20 tion");. @
44e0: 3c 68 31 3e 55 6e 61 62 6c 65 20 54 6f 20 45 73 <h1>Unable To Es
44f0: 74 61 62 6c 69 73 68 20 41 6e 20 45 6e 63 72 79 tablish An Encry
4500: 70 74 65 64 20 43 6f 6e 6e 65 63 74 69 6f 6e 3c pted Connection<
4510: 2f 68 31 3e 0a 20 20 20 20 20 20 40 20 3c 70 3e /h1>. @ <p>
4520: 54 68 69 73 20 77 65 62 73 69 74 65 20 72 65 71 This website req
4530: 75 69 72 65 73 20 74 68 61 74 20 6c 6f 67 69 6e uires that login
4540: 20 63 72 65 64 65 6e 74 69 61 6c 73 20 62 65 20 credentials be
4550: 73 65 6e 74 20 6f 76 65 72 0a 20 20 20 20 20 20 sent over.
4560: 40 20 61 6e 20 65 6e 63 72 79 70 74 65 64 20 63 @ an encrypted c
4570: 6f 6e 6e 65 63 74 69 6f 6e 2e 20 20 54 68 65 20 onnection. The
4580: 63 75 72 72 65 6e 74 20 63 6f 6e 6e 65 63 74 69 current connecti
4590: 6f 6e 20 69 73 20 6e 6f 74 20 65 6e 63 72 79 70 on is not encryp
45a0: 74 65 64 0a 20 20 20 20 20 20 40 20 61 63 72 6f ted. @ acro
45b0: 73 73 20 74 68 65 20 65 6e 74 69 72 65 20 72 6f ss the entire ro
45c0: 75 74 65 20 62 65 74 77 65 65 6e 20 79 6f 75 72 ute between your
45d0: 20 62 72 6f 77 73 65 72 20 61 6e 64 20 74 68 65 browser and the
45e0: 20 73 65 72 76 65 72 2e 0a 20 20 20 20 20 20 40 server.. @
45f0: 20 41 6e 20 61 74 74 65 6d 70 74 20 77 61 73 20 An attempt was
4600: 6d 61 64 65 20 74 6f 20 72 65 64 69 72 65 63 74 made to redirect
4610: 20 74 6f 20 25 68 28 67 2e 7a 48 74 74 70 73 55 to %h(g.zHttpsU
4620: 52 4c 29 20 62 75 74 0a 20 20 20 20 20 20 40 20 RL) but. @
4630: 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 the connection i
4640: 73 20 73 74 69 6c 6c 20 69 6e 73 65 63 75 72 65 s still insecure
4650: 20 65 76 65 6e 20 61 66 74 65 72 20 74 68 65 20 even after the
4660: 72 65 64 69 72 65 63 74 2e 3c 2f 70 3e 0a 20 20 redirect.</p>.
4670: 20 20 20 20 40 20 3c 70 3e 54 68 69 73 20 69 73 @ <p>This is
4680: 20 70 72 6f 62 61 62 6c 79 20 73 6f 6d 65 20 6b probably some k
4690: 69 6e 64 20 6f 66 20 63 6f 6e 66 69 67 75 72 61 ind of configura
46a0: 74 69 6f 6e 20 70 72 6f 62 6c 65 6d 2e 20 20 50 tion problem. P
46b0: 6c 65 61 73 65 0a 20 20 20 20 20 20 40 20 63 6f lease. @ co
46c0: 6e 74 61 63 74 20 79 6f 75 72 20 73 79 73 61 64 ntact your sysad
46d0: 6d 69 6e 2e 3c 2f 70 3e 0a 20 20 20 20 20 20 40 min.</p>. @
46e0: 20 3c 70 3e 53 6f 72 72 79 20 69 74 20 64 69 64 <p>Sorry it did
46f0: 20 6e 6f 74 20 77 6f 72 6b 20 6f 75 74 2e 3c 2f not work out.</
4700: 70 3e 0a 20 20 20 20 20 20 73 74 79 6c 65 5f 66 p>. style_f
4710: 6f 6f 74 65 72 28 29 3b 0a 20 20 20 20 20 20 72 ooter();. r
4720: 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 eturn;. }.
4730: 20 69 66 28 20 7a 51 53 3d 3d 30 20 29 7b 0a 20 if( zQS==0 ){.
4740: 20 20 20 20 20 7a 51 53 20 3d 20 22 3f 72 65 64 zQS = "?red
4750: 69 72 3d 31 22 3b 0a 20 20 20 20 7d 65 6c 73 65 ir=1";. }else
4760: 20 69 66 28 20 7a 51 53 5b 30 5d 21 3d 30 20 29 if( zQS[0]!=0 )
4770: 7b 0a 20 20 20 20 20 20 7a 51 53 20 3d 20 6d 70 {. zQS = mp
4780: 72 69 6e 74 66 28 22 3f 25 73 26 72 65 64 69 72 rintf("?%s&redir
4790: 3d 31 22 2c 20 7a 51 53 29 3b 0a 20 20 20 20 7d =1", zQS);. }
47a0: 0a 20 20 20 20 63 67 69 5f 72 65 64 69 72 65 63 . cgi_redirec
47b0: 74 66 28 22 25 73 25 54 25 73 22 2c 20 67 2e 7a tf("%s%T%s", g.z
47c0: 48 74 74 70 73 55 52 4c 2c 20 50 28 22 50 41 54 HttpsURL, P("PAT
47d0: 48 5f 49 4e 46 4f 22 29 2c 20 7a 51 53 29 3b 0a H_INFO"), zQS);.
47e0: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a return;. }.
47f0: 20 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 sqlite3_create
4800: 5f 66 75 6e 63 74 69 6f 6e 28 67 2e 64 62 2c 20 _function(g.db,
4810: 22 63 6f 6e 73 74 61 6e 74 5f 74 69 6d 65 5f 63 "constant_time_c
4820: 6d 70 22 2c 20 32 2c 20 53 51 4c 49 54 45 5f 55 mp", 2, SQLITE_U
4830: 54 46 38 2c 20 30 2c 0a 20 20 20 20 20 20 20 20 TF8, 0,.
4840: 20 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 61 consta
4850: 6e 74 5f 74 69 6d 65 5f 63 6d 70 5f 66 75 6e 63 nt_time_cmp_func
4860: 74 69 6f 6e 2c 20 30 2c 20 30 29 3b 0a 20 20 7a tion, 0, 0);. z
4870: 55 73 65 72 6e 61 6d 65 20 3d 20 50 28 22 75 22 Username = P("u"
4880: 29 3b 0a 20 20 7a 50 61 73 73 77 64 20 3d 20 50 );. zPasswd = P
4890: 28 22 70 22 29 3b 0a 20 20 61 6e 6f 6e 46 6c 61 ("p");. anonFla
48a0: 67 20 3d 20 67 2e 7a 4c 6f 67 69 6e 3d 3d 30 20 g = g.zLogin==0
48b0: 26 26 20 50 42 28 22 61 6e 6f 6e 22 29 3b 0a 0a && PB("anon");..
48c0: 20 20 2f 2a 20 48 61 6e 64 6c 65 20 6c 6f 67 2d /* Handle log-
48d0: 6f 75 74 20 72 65 71 75 65 73 74 73 20 2a 2f 0a out requests */.
48e0: 20 20 69 66 28 20 50 28 22 6f 75 74 22 29 20 29 if( P("out") )
48f0: 7b 0a 20 20 20 20 6c 6f 67 69 6e 5f 63 6c 65 61 {. login_clea
4900: 72 5f 6c 6f 67 69 6e 5f 64 61 74 61 28 29 3b 0a r_login_data();.
4910: 20 20 20 20 72 65 64 69 72 65 63 74 5f 74 6f 5f redirect_to_
4920: 67 28 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b g();. return;
4930: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 64 69 72 . }.. /* Redir
4940: 65 63 74 20 66 6f 72 20 63 72 65 61 74 65 2d 6e ect for create-n
4950: 65 77 2d 61 63 63 6f 75 6e 74 20 72 65 71 75 65 ew-account reque
4960: 73 74 73 20 2a 2f 0a 20 20 69 66 28 20 50 28 22 sts */. if( P("
4970: 73 65 6c 66 22 29 20 29 7b 0a 20 20 20 20 63 67 self") ){. cg
4980: 69 5f 72 65 64 69 72 65 63 74 66 28 22 25 52 2f i_redirectf("%R/
4990: 72 65 67 69 73 74 65 72 22 29 3b 0a 20 20 20 20 register");.
49a0: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 2f return;. }.. /
49b0: 2a 20 44 65 61 6c 20 77 69 74 68 20 70 61 73 73 * Deal with pass
49c0: 77 6f 72 64 2d 63 68 61 6e 67 65 20 72 65 71 75 word-change requ
49d0: 65 73 74 73 20 2a 2f 0a 20 20 69 66 28 20 67 2e ests */. if( g.
49e0: 70 65 72 6d 2e 50 61 73 73 77 6f 72 64 20 26 26 perm.Password &&
49f0: 20 7a 50 61 73 73 77 64 0a 20 20 20 26 26 20 28 zPasswd. && (
4a00: 7a 4e 65 77 31 20 3d 20 50 28 22 6e 31 22 29 29 zNew1 = P("n1"))
4a10: 21 3d 30 20 26 26 20 28 7a 4e 65 77 32 20 3d 20 !=0 && (zNew2 =
4a20: 50 28 22 6e 32 22 29 29 21 3d 30 0a 20 20 29 7b P("n2"))!=0. ){
4a30: 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72 65 . /* If there
4a40: 20 69 73 20 6e 6f 74 20 61 20 22 72 65 61 6c 22 is not a "real"
4a50: 20 6c 6f 67 69 6e 2c 20 77 65 20 63 61 6e 6e 6f login, we canno
4a60: 74 20 63 68 61 6e 67 65 20 61 6e 79 20 70 61 73 t change any pas
4a70: 73 77 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 69 66 sword. */. if
4a80: 28 20 67 2e 7a 4c 6f 67 69 6e 20 29 7b 0a 20 20 ( g.zLogin ){.
4a90: 20 20 20 20 2f 2a 20 54 68 65 20 75 73 65 72 20 /* The user
4aa0: 72 65 71 75 65 73 74 73 20 61 20 70 61 73 73 77 requests a passw
4ab0: 6f 72 64 20 63 68 61 6e 67 65 20 2a 2f 0a 20 20 ord change */.
4ac0: 20 20 20 20 7a 53 68 61 31 50 77 20 3d 20 73 68 zSha1Pw = sh
4ad0: 61 31 5f 73 68 61 72 65 64 5f 73 65 63 72 65 74 a1_shared_secret
4ae0: 28 7a 50 61 73 73 77 64 2c 20 67 2e 7a 4c 6f 67 (zPasswd, g.zLog
4af0: 69 6e 2c 20 30 29 3b 0a 20 20 20 20 20 20 69 66 in, 0);. if
4b00: 28 20 64 62 5f 69 6e 74 28 31 2c 20 22 53 45 4c ( db_int(1, "SEL
4b10: 45 43 54 20 30 20 46 52 4f 4d 20 75 73 65 72 22 ECT 0 FROM user"
4b20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
4b30: 20 20 20 20 20 22 20 57 48 45 52 45 20 75 69 64 " WHERE uid
4b40: 3d 25 64 22 0a 20 20 20 20 20 20 20 20 20 20 20 =%d".
4b50: 20 20 20 20 20 20 20 20 20 22 20 41 4e 44 20 28 " AND (
4b60: 63 6f 6e 73 74 61 6e 74 5f 74 69 6d 65 5f 63 6d constant_time_cm
4b70: 70 28 70 77 2c 25 51 29 3d 30 22 0a 20 20 20 20 p(pw,%Q)=0".
4b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4b90: 22 20 20 20 20 20 20 4f 52 20 63 6f 6e 73 74 61 " OR consta
4ba0: 6e 74 5f 74 69 6d 65 5f 63 6d 70 28 70 77 2c 25 nt_time_cmp(pw,%
4bb0: 51 29 3d 30 29 22 2c 0a 20 20 20 20 20 20 20 20 Q)=0)",.
4bc0: 20 20 20 20 20 20 20 20 20 20 20 20 67 2e 75 73 g.us
4bd0: 65 72 55 69 64 2c 20 7a 53 68 61 31 50 77 2c 20 erUid, zSha1Pw,
4be0: 7a 50 61 73 73 77 64 29 20 29 7b 0a 20 20 20 20 zPasswd) ){.
4bf0: 20 20 20 20 73 6c 65 65 70 28 31 29 3b 0a 20 20 sleep(1);.
4c00: 20 20 20 20 20 20 7a 45 72 72 4d 73 67 20 3d 0a zErrMsg =.
4c10: 20 20 20 20 20 20 20 20 20 20 20 40 20 3c 70 3e @ <p>
4c20: 3c 73 70 61 6e 20 63 6c 61 73 73 3d 22 6c 6f 67 <span class="log
4c30: 69 6e 45 72 72 6f 72 22 3e 0a 20 20 20 20 20 20 inError">.
4c40: 20 20 20 20 20 40 20 59 6f 75 20 65 6e 74 65 72 @ You enter
4c50: 65 64 20 61 6e 20 69 6e 63 6f 72 72 65 63 74 20 ed an incorrect
4c60: 6f 6c 64 20 70 61 73 73 77 6f 72 64 20 77 68 69 old password whi
4c70: 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20 74 6f le attempting to
4c80: 20 63 68 61 6e 67 65 0a 20 20 20 20 20 20 20 20 change.
4c90: 20 20 20 40 20 79 6f 75 72 20 70 61 73 73 77 6f @ your passwo
4ca0: 72 64 2e 20 20 59 6f 75 72 20 70 61 73 73 77 6f rd. Your passwo
4cb0: 72 64 20 69 73 20 75 6e 63 68 61 6e 67 65 64 2e rd is unchanged.
4cc0: 0a 20 20 20 20 20 20 20 20 20 20 20 40 20 3c 2f . @ </
4cd0: 73 70 61 6e 3e 3c 2f 70 3e 0a 20 20 20 20 20 20 span></p>.
4ce0: 20 20 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 ;. }else
4cf0: 69 66 28 20 66 6f 73 73 69 6c 5f 73 74 72 63 6d if( fossil_strcm
4d00: 70 28 7a 4e 65 77 31 2c 7a 4e 65 77 32 29 21 3d p(zNew1,zNew2)!=
4d10: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 45 72 0 ){. zEr
4d20: 72 4d 73 67 20 3d 0a 20 20 20 20 20 20 20 20 20 rMsg =.
4d30: 20 20 40 20 3c 70 3e 3c 73 70 61 6e 20 63 6c 61 @ <p><span cla
4d40: 73 73 3d 22 6c 6f 67 69 6e 45 72 72 6f 72 22 3e ss="loginError">
4d50: 0a 20 20 20 20 20 20 20 20 20 20 20 40 20 54 68 . @ Th
4d60: 65 20 74 77 6f 20 63 6f 70 69 65 73 20 6f 66 20 e two copies of
4d70: 79 6f 75 72 20 6e 65 77 20 70 61 73 73 77 6f 72 your new passwor
4d80: 64 73 20 64 6f 20 6e 6f 74 20 6d 61 74 63 68 2e ds do not match.
4d90: 0a 20 20 20 20 20 20 20 20 20 20 20 40 20 59 6f . @ Yo
4da0: 75 72 20 70 61 73 73 77 6f 72 64 20 69 73 20 75 ur password is u
4db0: 6e 63 68 61 6e 67 65 64 2e 0a 20 20 20 20 20 20 nchanged..
4dc0: 20 20 20 20 20 40 20 3c 2f 73 70 61 6e 3e 3c 2f @ </span></
4dd0: 70 3e 0a 20 20 20 20 20 20 20 20 3b 0a 20 20 20 p>. ;.
4de0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
4df0: 20 20 63 68 61 72 20 2a 7a 4e 65 77 50 77 20 3d char *zNewPw =
4e00: 20 73 68 61 31 5f 73 68 61 72 65 64 5f 73 65 63 sha1_shared_sec
4e10: 72 65 74 28 7a 4e 65 77 31 2c 20 67 2e 7a 4c 6f ret(zNew1, g.zLo
4e20: 67 69 6e 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 gin, 0);.
4e30: 20 63 68 61 72 20 2a 7a 43 68 6e 67 50 77 3b 0a char *zChngPw;.
4e40: 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a 45 char *zE
4e50: 72 72 3b 0a 20 20 20 20 20 20 20 20 64 62 5f 6d rr;. db_m
4e60: 75 6c 74 69 5f 65 78 65 63 28 0a 20 20 20 20 20 ulti_exec(.
4e70: 20 20 20 20 20 20 22 55 50 44 41 54 45 20 75 73 "UPDATE us
4e80: 65 72 20 53 45 54 20 70 77 3d 25 51 20 57 48 45 er SET pw=%Q WHE
4e90: 52 45 20 75 69 64 3d 25 64 22 2c 20 7a 4e 65 77 RE uid=%d", zNew
4ea0: 50 77 2c 20 67 2e 75 73 65 72 55 69 64 0a 20 20 Pw, g.userUid.
4eb0: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 );.
4ec0: 20 66 6f 73 73 69 6c 5f 66 72 65 65 28 7a 4e 65 fossil_free(zNe
4ed0: 77 50 77 29 3b 0a 20 20 20 20 20 20 20 20 7a 43 wPw);. zC
4ee0: 68 6e 67 50 77 20 3d 20 6d 70 72 69 6e 74 66 28 hngPw = mprintf(
4ef0: 0a 20 20 20 20 20 20 20 20 20 20 20 22 55 50 44 . "UPD
4f00: 41 54 45 20 75 73 65 72 22 0a 20 20 20 20 20 20 ATE user".
4f10: 20 20 20 20 20 22 20 20 20 53 45 54 20 70 77 3d " SET pw=
4f20: 73 68 61 72 65 64 5f 73 65 63 72 65 74 28 25 51 shared_secret(%Q
4f30: 2c 25 51 2c 22 0a 20 20 20 20 20 20 20 20 20 20 ,%Q,".
4f40: 20 22 20 20 20 20 20 20 20 20 28 53 45 4c 45 43 " (SELEC
4f50: 54 20 76 61 6c 75 65 20 46 52 4f 4d 20 63 6f 6e T value FROM con
4f60: 66 69 67 20 57 48 45 52 45 20 6e 61 6d 65 3d 27 fig WHERE name='
4f70: 70 72 6f 6a 65 63 74 2d 63 6f 64 65 27 29 29 22 project-code'))"
4f80: 0a 20 20 20 20 20 20 20 20 20 20 20 22 20 57 48 . " WH
4f90: 45 52 45 20 6c 6f 67 69 6e 3d 25 51 22 2c 0a 20 ERE login=%Q",.
4fa0: 20 20 20 20 20 20 20 20 20 20 7a 4e 65 77 31 2c zNew1,
4fb0: 20 67 2e 7a 4c 6f 67 69 6e 2c 20 67 2e 7a 4c 6f g.zLogin, g.zLo
4fc0: 67 69 6e 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 gin. );.
4fd0: 20 20 20 20 20 20 20 69 66 28 20 6c 6f 67 69 6e if( login
4fe0: 5f 67 72 6f 75 70 5f 73 71 6c 28 7a 43 68 6e 67 _group_sql(zChng
4ff0: 50 77 2c 20 22 3c 70 3e 22 2c 20 22 3c 2f 70 3e Pw, "<p>", "</p>
5000: 5c 6e 22 2c 20 26 7a 45 72 72 29 20 29 7b 0a 20 \n", &zErr) ){.
5010: 20 20 20 20 20 20 20 20 20 7a 45 72 72 4d 73 67 zErrMsg
5020: 20 3d 20 6d 70 72 69 6e 74 66 28 22 3c 73 70 61 = mprintf("<spa
5030: 6e 20 63 6c 61 73 73 3d 5c 22 6c 6f 67 69 6e 45 n class=\"loginE
5040: 72 72 6f 72 5c 22 3e 25 73 3c 2f 73 70 61 6e 3e rror\">%s</span>
5050: 22 2c 20 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 ", zErr);.
5060: 20 20 20 20 66 6f 73 73 69 6c 5f 66 72 65 65 28 fossil_free(
5070: 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 20 20 7d zErr);. }
5080: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 else{.
5090: 72 65 64 69 72 65 63 74 5f 74 6f 5f 67 28 29 3b redirect_to_g();
50a0: 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 . retur
50b0: 6e 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 n;. }.
50c0: 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a }. }else{.
50d0: 20 20 20 20 20 20 7a 45 72 72 4d 73 67 20 3d 0a zErrMsg =.
50e0: 20 20 20 20 20 20 20 20 20 40 20 3c 70 3e 3c 73 @ <p><s
50f0: 70 61 6e 20 63 6c 61 73 73 3d 22 6c 6f 67 69 6e pan class="login
5100: 45 72 72 6f 72 22 3e 0a 20 20 20 20 20 20 20 20 Error">.
5110: 20 40 20 54 68 65 20 70 61 73 73 77 6f 72 64 20 @ The password
5120: 63 61 6e 6e 6f 74 20 62 65 20 63 68 61 6e 67 65 cannot be change
5130: 64 20 66 6f 72 20 74 68 69 73 20 74 79 70 65 20 d for this type
5140: 6f 66 20 6c 6f 67 69 6e 2e 0a 20 20 20 20 20 20 of login..
5150: 20 20 20 40 20 54 68 65 20 70 61 73 73 77 6f 72 @ The passwor
5160: 64 20 69 73 20 75 6e 63 68 61 6e 67 65 64 2e 0a d is unchanged..
5170: 20 20 20 20 20 20 20 20 20 40 20 3c 2f 73 70 61 @ </spa
5180: 6e 3e 3c 2f 70 3e 0a 20 20 20 20 20 20 3b 0a 20 n></p>. ;.
5190: 20 20 20 7d 0a 20 20 7d 0a 20 20 7a 49 70 41 64 }. }. zIpAd
51a0: 64 72 20 3d 20 50 44 28 22 52 45 4d 4f 54 45 5f dr = PD("REMOTE_
51b0: 41 44 44 52 22 2c 22 6e 69 6c 22 29 3b 20 20 20 ADDR","nil");
51c0: 2f 2a 20 43 6f 6d 70 6c 65 74 65 20 49 50 20 61 /* Complete IP a
51d0: 64 64 72 65 73 73 20 66 6f 72 20 6c 6f 67 67 69 ddress for loggi
51e0: 6e 67 20 2a 2f 0a 20 20 7a 52 65 66 65 72 65 72 ng */. zReferer
51f0: 20 3d 20 50 28 22 48 54 54 50 5f 52 45 46 45 52 = P("HTTP_REFER
5200: 45 52 22 29 3b 0a 20 20 75 69 64 20 3d 20 6c 6f ER");. uid = lo
5210: 67 69 6e 5f 69 73 5f 76 61 6c 69 64 5f 61 6e 6f gin_is_valid_ano
5220: 6e 79 6d 6f 75 73 28 7a 55 73 65 72 6e 61 6d 65 nymous(zUsername
5230: 2c 20 7a 50 61 73 73 77 64 2c 20 50 28 22 63 73 , zPasswd, P("cs
5240: 22 29 29 3b 0a 20 20 69 66 28 20 75 69 64 3e 30 "));. if( uid>0
5250: 20 29 7b 0a 20 20 20 20 6c 6f 67 69 6e 5f 73 65 ){. login_se
5260: 74 5f 61 6e 6f 6e 5f 63 6f 6f 6b 69 65 28 7a 49 t_anon_cookie(zI
5270: 70 41 64 64 72 2c 20 4e 55 4c 4c 29 3b 0a 20 20 pAddr, NULL);.
5280: 20 20 72 65 63 6f 72 64 5f 6c 6f 67 69 6e 5f 61 record_login_a
5290: 74 74 65 6d 70 74 28 22 61 6e 6f 6e 79 6d 6f 75 ttempt("anonymou
52a0: 73 22 2c 20 7a 49 70 41 64 64 72 2c 20 31 29 3b s", zIpAddr, 1);
52b0: 0a 20 20 20 20 72 65 64 69 72 65 63 74 5f 74 6f . redirect_to
52c0: 5f 67 28 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 _g();. }. if(
52d0: 7a 55 73 65 72 6e 61 6d 65 21 3d 30 20 26 26 20 zUsername!=0 &&
52e0: 7a 50 61 73 73 77 64 21 3d 30 20 26 26 20 7a 50 zPasswd!=0 && zP
52f0: 61 73 73 77 64 5b 30 5d 21 3d 30 20 29 7b 0a 20 asswd[0]!=0 ){.
5300: 20 20 20 2f 2a 20 41 74 74 65 6d 70 74 69 6e 67 /* Attempting
5310: 20 74 6f 20 6c 6f 67 20 69 6e 20 61 73 20 61 20 to log in as a
5320: 75 73 65 72 20 6f 74 68 65 72 20 74 68 61 6e 20 user other than
5330: 61 6e 6f 6e 79 6d 6f 75 73 2e 0a 20 20 20 20 2a anonymous.. *
5340: 2f 0a 20 20 20 20 75 69 64 20 3d 20 6c 6f 67 69 /. uid = logi
5350: 6e 5f 73 65 61 72 63 68 5f 75 69 64 28 7a 55 73 n_search_uid(zUs
5360: 65 72 6e 61 6d 65 2c 20 7a 50 61 73 73 77 64 29 ername, zPasswd)
5370: 3b 0a 20 20 20 20 69 66 28 20 75 69 64 3c 3d 30 ;. if( uid<=0
5380: 20 29 7b 0a 20 20 20 20 20 20 73 6c 65 65 70 28 ){. sleep(
5390: 31 29 3b 0a 20 20 20 20 20 20 7a 45 72 72 4d 73 1);. zErrMs
53a0: 67 20 3d 0a 20 20 20 20 20 20 20 20 20 40 20 3c g =. @ <
53b0: 70 3e 3c 73 70 61 6e 20 63 6c 61 73 73 3d 22 6c p><span class="l
53c0: 6f 67 69 6e 45 72 72 6f 72 22 3e 0a 20 20 20 20 oginError">.
53d0: 20 20 20 20 20 40 20 59 6f 75 20 65 6e 74 65 72 @ You enter
53e0: 65 64 20 61 6e 20 75 6e 6b 6e 6f 77 6e 20 75 73 ed an unknown us
53f0: 65 72 20 6f 72 20 61 6e 20 69 6e 63 6f 72 72 65 er or an incorre
5400: 63 74 20 70 61 73 73 77 6f 72 64 2e 0a 20 20 20 ct password..
5410: 20 20 20 20 20 20 40 20 3c 2f 73 70 61 6e 3e 3c @ </span><
5420: 2f 70 3e 0a 20 20 20 20 20 20 3b 0a 20 20 20 20 /p>. ;.
5430: 20 20 72 65 63 6f 72 64 5f 6c 6f 67 69 6e 5f 61 record_login_a
5440: 74 74 65 6d 70 74 28 7a 55 73 65 72 6e 61 6d 65 ttempt(zUsername
5450: 2c 20 7a 49 70 41 64 64 72 2c 20 30 29 3b 0a 20 , zIpAddr, 0);.
5460: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
5470: 2f 2a 20 4e 6f 6e 2d 61 6e 6f 6e 79 6d 6f 75 73 /* Non-anonymous
5480: 20 6c 6f 67 69 6e 20 69 73 20 73 75 63 63 65 73 login is succes
5490: 73 66 75 6c 2e 20 20 53 65 74 20 61 20 63 6f 6f sful. Set a coo
54a0: 6b 69 65 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a kie of the form:
54b0: 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 . **.
54c0: 2a 2a 20 20 20 20 48 41 53 48 2f 50 52 4f 4a 45 ** HASH/PROJE
54d0: 43 54 2f 4c 4f 47 49 4e 0a 20 20 20 20 20 20 2a CT/LOGIN. *
54e0: 2a 0a 20 20 20 20 20 20 2a 2a 20 77 68 65 72 65 *. ** where
54f0: 20 48 41 53 48 20 69 73 20 61 20 72 61 6e 64 6f HASH is a rando
5500: 6d 20 68 65 78 20 6e 75 6d 62 65 72 2c 20 50 52 m hex number, PR
5510: 4f 4a 45 43 54 20 69 73 20 65 69 74 68 65 72 20 OJECT is either
5520: 70 72 6f 6a 65 63 74 0a 20 20 20 20 20 20 2a 2a project. **
5530: 20 63 6f 64 65 20 70 72 65 66 69 78 2c 20 61 6e code prefix, an
5540: 64 20 4c 4f 47 49 4e 20 69 73 20 74 68 65 20 75 d LOGIN is the u
5550: 73 65 72 20 6e 61 6d 65 2e 0a 20 20 20 20 20 20 ser name..
5560: 2a 2f 0a 20 20 20 20 20 20 6c 6f 67 69 6e 5f 73 */. login_s
5570: 65 74 5f 75 73 65 72 5f 63 6f 6f 6b 69 65 28 7a et_user_cookie(z
5580: 55 73 65 72 6e 61 6d 65 2c 20 75 69 64 2c 20 4e Username, uid, N
5590: 55 4c 4c 29 3b 0a 20 20 20 20 20 20 72 65 64 69 ULL);. redi
55a0: 72 65 63 74 5f 74 6f 5f 67 28 29 3b 0a 20 20 20 rect_to_g();.
55b0: 20 7d 0a 20 20 7d 0a 20 20 73 74 79 6c 65 5f 68 }. }. style_h
55c0: 65 61 64 65 72 28 22 4c 6f 67 69 6e 2f 4c 6f 67 eader("Login/Log
55d0: 6f 75 74 22 29 3b 0a 20 20 73 74 79 6c 65 5f 61 out");. style_a
55e0: 64 75 6e 69 74 5f 63 6f 6e 66 69 67 28 41 44 55 dunit_config(ADU
55f0: 4e 49 54 5f 4f 46 46 29 3b 0a 20 20 40 20 25 73 NIT_OFF);. @ %s
5600: 28 7a 45 72 72 4d 73 67 29 0a 20 20 69 66 28 20 (zErrMsg). if(
5610: 7a 47 6f 74 6f 20 26 26 20 21 6e 6f 41 6e 6f 6e zGoto && !noAnon
5620: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 41 ){. char *zA
5630: 62 62 72 65 76 20 3d 20 66 6f 73 73 69 6c 5f 73 bbrev = fossil_s
5640: 74 72 64 75 70 28 7a 47 6f 74 6f 29 3b 0a 20 20 trdup(zGoto);.
5650: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 int i;. for
5660: 28 69 3d 30 3b 20 7a 41 62 62 72 65 76 5b 69 5d (i=0; zAbbrev[i]
5670: 20 26 26 20 7a 41 62 62 72 65 76 5b 69 5d 21 3d && zAbbrev[i]!=
5680: 27 3f 27 3b 20 69 2b 2b 29 7b 7d 0a 20 20 20 20 '?'; i++){}.
5690: 7a 41 62 62 72 65 76 5b 69 5d 20 3d 20 30 3b 0a zAbbrev[i] = 0;.
56a0: 20 20 20 20 69 66 28 20 67 2e 7a 4c 6f 67 69 6e if( g.zLogin
56b0: 20 29 7b 0a 20 20 20 20 20 20 40 20 3c 70 3e 55 ){. @ <p>U
56c0: 73 65 20 61 20 64 69 66 66 65 72 65 6e 74 20 6c se a different l
56d0: 6f 67 69 6e 20 77 69 74 68 20 67 72 65 61 74 65 ogin with greate
56e0: 72 20 70 72 69 76 69 6c 65 67 65 20 74 68 61 6e r privilege than
56f0: 20 3c 62 3e 25 68 28 67 2e 7a 4c 6f 67 69 6e 29 <b>%h(g.zLogin)
5700: 3c 2f 62 3e 0a 20 20 20 20 20 20 40 20 74 6f 20 </b>. @ to
5710: 61 63 63 65 73 73 20 3c 62 3e 25 68 28 7a 41 62 access <b>%h(zAb
5720: 62 72 65 76 29 3c 2f 62 3e 2e 0a 20 20 20 20 7d brev)</b>.. }
5730: 65 6c 73 65 20 69 66 28 20 61 6e 6f 6e 46 6c 61 else if( anonFla
5740: 67 20 29 7b 0a 20 20 20 20 20 20 40 20 3c 70 3e g ){. @ <p>
5750: 4c 6f 67 69 6e 20 61 73 20 3c 62 3e 61 6e 6f 6e Login as <b>anon
5760: 79 6d 6f 75 73 3c 2f 62 3e 20 6f 72 20 61 6e 79 ymous</b> or any
5770: 20 6e 61 6d 65 64 20 75 73 65 72 0a 20 20 20 20 named user.
5780: 20 20 40 20 74 6f 20 61 63 63 65 73 73 20 70 61 @ to access pa
5790: 67 65 20 3c 62 3e 25 68 28 7a 41 62 62 72 65 76 ge <b>%h(zAbbrev
57a0: 29 3c 2f 62 3e 2e 0a 20 20 20 20 7d 65 6c 73 65 )</b>.. }else
57b0: 7b 0a 20 20 20 20 20 20 40 20 3c 70 3e 4c 6f 67 {. @ <p>Log
57c0: 69 6e 20 61 73 20 61 20 6e 61 6d 65 64 20 75 73 in as a named us
57d0: 65 72 20 74 6f 20 61 63 63 65 73 73 20 70 61 67 er to access pag
57e0: 65 20 3c 62 3e 25 68 28 7a 41 62 62 72 65 76 29 e <b>%h(zAbbrev)
57f0: 3c 2f 62 3e 2e 0a 20 20 20 20 7d 0a 20 20 7d 0a </b>.. }. }.
5800: 20 20 69 66 28 20 67 2e 73 73 6c 4e 6f 74 41 76 if( g.sslNotAv
5810: 61 69 6c 61 62 6c 65 3d 3d 30 0a 20 20 20 26 26 ailable==0. &&
5820: 20 73 74 72 6e 63 6d 70 28 67 2e 7a 42 61 73 65 strncmp(g.zBase
5830: 55 52 4c 2c 22 68 74 74 70 73 3a 22 2c 36 29 21 URL,"https:",6)!
5840: 3d 30 0a 20 20 20 26 26 20 64 62 5f 67 65 74 5f =0. && db_get_
5850: 62 6f 6f 6c 65 61 6e 28 22 68 74 74 70 73 2d 6c boolean("https-l
5860: 6f 67 69 6e 22 2c 30 29 0a 20 20 29 7b 0a 20 20 ogin",0). ){.
5870: 20 20 66 6f 72 6d 5f 62 65 67 69 6e 28 30 2c 20 form_begin(0,
5880: 22 68 74 74 70 73 3a 25 73 2f 6c 6f 67 69 6e 22 "https:%s/login"
5890: 2c 20 67 2e 7a 42 61 73 65 55 52 4c 2b 35 29 3b , g.zBaseURL+5);
58a0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 6f . }else{. fo
58b0: 72 6d 5f 62 65 67 69 6e 28 30 2c 20 22 25 52 2f rm_begin(0, "%R/
58c0: 6c 6f 67 69 6e 22 29 3b 0a 20 20 7d 0a 20 20 69 login");. }. i
58d0: 66 28 20 7a 47 6f 74 6f 20 29 7b 0a 20 20 20 20 f( zGoto ){.
58e0: 40 20 3c 69 6e 70 75 74 20 74 79 70 65 3d 22 68 @ <input type="h
58f0: 69 64 64 65 6e 22 20 6e 61 6d 65 3d 22 67 22 20 idden" name="g"
5900: 76 61 6c 75 65 3d 22 25 68 28 7a 47 6f 74 6f 29 value="%h(zGoto)
5910: 22 20 2f 3e 0a 20 20 7d 65 6c 73 65 20 69 66 28 " />. }else if(
5920: 20 7a 52 65 66 65 72 65 72 20 26 26 20 73 74 72 zReferer && str
5930: 6e 63 6d 70 28 67 2e 7a 42 61 73 65 55 52 4c 2c ncmp(g.zBaseURL,
5940: 20 7a 52 65 66 65 72 65 72 2c 20 73 74 72 6c 65 zReferer, strle
5950: 6e 28 67 2e 7a 42 61 73 65 55 52 4c 29 29 3d 3d n(g.zBaseURL))==
5960: 30 20 29 7b 0a 20 20 20 20 40 20 3c 69 6e 70 75 0 ){. @ <inpu
5970: 74 20 74 79 70 65 3d 22 68 69 64 64 65 6e 22 20 t type="hidden"
5980: 6e 61 6d 65 3d 22 67 22 20 76 61 6c 75 65 3d 22 name="g" value="
5990: 25 68 28 7a 52 65 66 65 72 65 72 29 22 20 2f 3e %h(zReferer)" />
59a0: 0a 20 20 7d 0a 20 20 69 66 28 20 61 6e 6f 6e 46 . }. if( anonF
59b0: 6c 61 67 20 29 7b 0a 20 20 20 20 40 20 3c 69 6e lag ){. @ <in
59c0: 70 75 74 20 74 79 70 65 3d 22 68 69 64 64 65 6e put type="hidden
59d0: 22 20 6e 61 6d 65 3d 22 61 6e 6f 6e 22 20 76 61 " name="anon" va
59e0: 6c 75 65 3d 22 31 22 20 2f 3e 0a 20 20 7d 0a 20 lue="1" />. }.
59f0: 20 69 66 28 20 67 2e 7a 4c 6f 67 69 6e 20 29 7b if( g.zLogin ){
5a00: 0a 20 20 20 20 40 20 3c 70 3e 43 75 72 72 65 6e . @ <p>Curren
5a10: 74 6c 79 20 6c 6f 67 67 65 64 20 69 6e 20 61 73 tly logged in as
5a20: 20 3c 62 3e 25 68 28 67 2e 7a 4c 6f 67 69 6e 29 <b>%h(g.zLogin)
5a30: 3c 2f 62 3e 2e 0a 20 20 20 20 40 20 3c 69 6e 70 </b>.. @ <inp
5a40: 75 74 20 74 79 70 65 3d 22 73 75 62 6d 69 74 22 ut type="submit"
5a50: 20 6e 61 6d 65 3d 22 6f 75 74 22 20 76 61 6c 75 name="out" valu
5a60: 65 3d 22 4c 6f 67 6f 75 74 22 3e 3c 2f 70 3e 0a e="Logout"></p>.
5a70: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 40 20 3c }else{. @ <
5a80: 74 61 62 6c 65 20 63 6c 61 73 73 3d 22 6c 6f 67 table class="log
5a90: 69 6e 5f 6f 75 74 22 3e 0a 20 20 20 20 40 20 3c in_out">. @ <
5aa0: 74 72 3e 0a 20 20 20 20 40 20 20 20 3c 74 64 20 tr>. @ <td
5ab0: 63 6c 61 73 73 3d 22 66 6f 72 6d 5f 6c 61 62 65 class="form_labe
5ac0: 6c 22 3e 55 73 65 72 20 49 44 3a 3c 2f 74 64 3e l">User ID:</td>
5ad0: 0a 20 20 20 20 69 66 28 20 61 6e 6f 6e 46 6c 61 . if( anonFla
5ae0: 67 20 29 7b 0a 20 20 20 20 20 20 40 20 3c 74 64 g ){. @ <td
5af0: 3e 3c 69 6e 70 75 74 20 74 79 70 65 3d 22 74 65 ><input type="te
5b00: 78 74 22 20 69 64 3d 22 75 22 20 6e 61 6d 65 3d xt" id="u" name=
5b10: 22 75 22 20 76 61 6c 75 65 3d 22 61 6e 6f 6e 79 "u" value="anony
5b20: 6d 6f 75 73 22 20 73 69 7a 65 3d 22 33 30 22 3e mous" size="30">
5b30: 3c 2f 74 64 3e 0a 20 20 20 20 7d 65 6c 73 65 7b </td>. }else{
5b40: 0a 20 20 20 20 20 20 40 20 3c 74 64 3e 3c 69 6e . @ <td><in
5b50: 70 75 74 20 74 79 70 65 3d 22 74 65 78 74 22 20 put type="text"
5b60: 69 64 3d 22 75 22 20 6e 61 6d 65 3d 22 75 22 20 id="u" name="u"
5b70: 76 61 6c 75 65 3d 22 22 20 73 69 7a 65 3d 22 33 value="" size="3
5b80: 30 22 20 2f 3e 3c 2f 74 64 3e 0a 20 20 20 20 7d 0" /></td>. }
5b90: 0a 20 20 20 20 69 66 28 20 50 28 22 48 54 54 50 . if( P("HTTP
5ba0: 53 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 S")==0 ){.
5bb0: 40 20 3c 74 64 20 77 69 64 74 68 3d 22 31 35 22 @ <td width="15"
5bc0: 3e 3c 74 64 20 72 6f 77 73 70 61 6e 3d 22 32 22 ><td rowspan="2"
5bd0: 3e 0a 20 20 20 20 20 20 40 20 3c 70 20 63 6c 61 >. @ <p cla
5be0: 73 73 3d 27 73 65 63 75 72 69 74 79 57 61 72 6e ss='securityWarn
5bf0: 69 6e 67 27 3e 0a 20 20 20 20 20 20 40 20 57 61 ing'>. @ Wa
5c00: 72 6e 69 6e 67 3a 20 59 6f 75 72 20 70 61 73 73 rning: Your pass
5c10: 77 6f 72 64 20 77 69 6c 6c 20 62 65 20 73 65 6e word will be sen
5c20: 74 20 69 6e 20 74 68 65 20 63 6c 65 61 72 20 6f t in the clear o
5c30: 76 65 72 20 61 6e 0a 20 20 20 20 20 20 40 20 75 ver an. @ u
5c40: 6e 65 6e 63 72 79 70 74 65 64 20 63 6f 6e 6e 65 nencrypted conne
5c50: 63 74 69 6f 6e 2e 0a 20 20 20 20 20 20 69 66 28 ction.. if(
5c60: 20 67 2e 73 73 6c 4e 6f 74 41 76 61 69 6c 61 62 g.sslNotAvailab
5c70: 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20 40 20 le ){. @
5c80: 4e 6f 20 65 6e 63 72 79 70 74 65 64 20 63 6f 6e No encrypted con
5c90: 6e 65 63 74 69 6f 6e 20 69 73 20 61 76 61 69 6c nection is avail
5ca0: 61 62 6c 65 20 6f 6e 20 74 68 69 73 20 73 65 72 able on this ser
5cb0: 76 65 72 2e 0a 20 20 20 20 20 20 7d 65 6c 73 65 ver.. }else
5cc0: 7b 0a 20 20 20 20 20 20 20 20 40 20 43 6f 6e 73 {. @ Cons
5cd0: 69 64 65 72 20 6c 6f 67 67 69 6e 67 20 69 6e 20 ider logging in
5ce0: 61 74 0a 20 20 20 20 20 20 20 20 40 20 3c 61 20 at. @ <a
5cf0: 68 72 65 66 3d 27 25 73 28 67 2e 7a 48 74 74 70 href='%s(g.zHttp
5d00: 73 55 52 4c 29 27 3e 25 68 28 67 2e 7a 48 74 74 sURL)'>%h(g.zHtt
5d10: 70 73 55 52 4c 29 3c 2f 61 3e 20 69 6e 73 74 65 psURL)</a> inste
5d20: 61 64 2e 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 ad.. }.
5d30: 20 20 40 20 3c 2f 70 3e 0a 20 20 20 20 7d 0a 20 @ </p>. }.
5d40: 20 20 20 40 20 3c 2f 74 72 3e 0a 20 20 20 20 40 @ </tr>. @
5d50: 20 3c 74 72 3e 0a 20 20 20 20 40 20 20 3c 74 64 <tr>. @ <td
5d60: 20 63 6c 61 73 73 3d 22 66 6f 72 6d 5f 6c 61 62 class="form_lab
5d70: 65 6c 22 3e 50 61 73 73 77 6f 72 64 3a 3c 2f 74 el">Password:</t
5d80: 64 3e 0a 20 20 20 20 40 20 20 3c 74 64 3e 3c 69 d>. @ <td><i
5d90: 6e 70 75 74 20 74 79 70 65 3d 22 70 61 73 73 77 nput type="passw
5da0: 6f 72 64 22 20 69 64 3d 22 70 22 20 6e 61 6d 65 ord" id="p" name
5db0: 3d 22 70 22 20 76 61 6c 75 65 3d 22 22 20 73 69 ="p" value="" si
5dc0: 7a 65 3d 22 33 30 22 20 2f 3e 3c 2f 74 64 3e 0a ze="30" /></td>.
5dd0: 20 20 20 20 40 20 3c 2f 74 72 3e 0a 20 20 20 20 @ </tr>.
5de0: 69 66 28 20 67 2e 7a 4c 6f 67 69 6e 3d 3d 30 20 if( g.zLogin==0
5df0: 26 26 20 28 61 6e 6f 6e 46 6c 61 67 20 7c 7c 20 && (anonFlag ||
5e00: 7a 47 6f 74 6f 3d 3d 30 29 20 29 7b 0a 20 20 20 zGoto==0) ){.
5e10: 20 20 20 7a 41 6e 6f 6e 50 77 20 3d 20 64 62 5f zAnonPw = db_
5e20: 74 65 78 74 28 30 2c 20 22 53 45 4c 45 43 54 20 text(0, "SELECT
5e30: 70 77 20 46 52 4f 4d 20 75 73 65 72 22 0a 20 20 pw FROM user".
5e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
5e50: 20 20 20 20 20 20 20 20 20 22 20 57 48 45 52 45 " WHERE
5e60: 20 6c 6f 67 69 6e 3d 27 61 6e 6f 6e 79 6d 6f 75 login='anonymou
5e70: 73 27 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 s'".
5e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22 "
5e90: 20 20 20 41 4e 44 20 63 61 70 21 3d 27 27 22 29 AND cap!=''")
5ea0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 40 20 3c 74 ;. }. @ <t
5eb0: 72 3e 0a 20 20 20 20 40 20 20 20 3c 74 64 3e 3c r>. @ <td><
5ec0: 2f 74 64 3e 0a 20 20 20 20 40 20 20 20 3c 74 64 /td>. @ <td
5ed0: 3e 3c 69 6e 70 75 74 20 74 79 70 65 3d 22 73 75 ><input type="su
5ee0: 62 6d 69 74 22 20 6e 61 6d 65 3d 22 69 6e 22 20 bmit" name="in"
5ef0: 76 61 6c 75 65 3d 22 4c 6f 67 69 6e 22 3e 3c 2f value="Login"></
5f00: 74 64 3e 0a 20 20 20 20 40 20 20 20 3c 74 64 20 td>. @ <td
5f10: 63 6f 6c 73 70 61 6e 3d 22 32 22 3e 26 6c 61 72 colspan="2">&lar
5f20: 72 3b 20 50 72 65 73 73 69 6e 67 20 74 68 69 73 r; Pressing this
5f30: 20 62 75 74 74 6f 6e 20 67 72 61 6e 74 73 5c 0a button grants\.
5f40: 20 20 20 20 40 20 20 20 70 65 72 6d 69 73 73 69 @ permissi
5f50: 6f 6e 20 74 6f 20 73 74 6f 72 65 20 61 20 63 6f on to store a co
5f60: 6f 6b 69 65 0a 20 20 20 20 40 20 3c 2f 74 72 3e okie. @ </tr>
5f70: 0a 20 20 20 20 69 66 28 20 21 6e 6f 41 6e 6f 6e . if( !noAnon
5f80: 20 26 26 20 6c 6f 67 69 6e 5f 73 65 6c 66 5f 72 && login_self_r
5f90: 65 67 69 73 74 65 72 5f 61 76 61 69 6c 61 62 6c egister_availabl
5fa0: 65 28 30 29 20 29 7b 0a 20 20 20 20 20 20 40 20 e(0) ){. @
5fb0: 3c 74 72 3e 0a 20 20 20 20 20 20 40 20 20 20 3c <tr>. @ <
5fc0: 74 64 3e 3c 2f 74 64 3e 0a 20 20 20 20 20 20 40 td></td>. @
5fd0: 20 20 20 3c 74 64 3e 3c 69 6e 70 75 74 20 74 79 <td><input ty
5fe0: 70 65 3d 22 73 75 62 6d 69 74 22 20 6e 61 6d 65 pe="submit" name
5ff0: 3d 22 73 65 6c 66 22 20 76 61 6c 75 65 3d 22 43 ="self" value="C
6000: 72 65 61 74 65 20 41 20 4e 65 77 20 41 63 63 6f reate A New Acco
6010: 75 6e 74 22 3e 0a 20 20 20 20 20 20 40 20 20 20 unt">. @
6020: 3c 74 64 20 63 6f 6c 73 70 61 6e 3d 22 32 22 3e <td colspan="2">
6030: 20 5c 0a 20 20 20 20 20 20 40 20 20 20 26 6c 61 \. @ &la
6040: 72 72 3b 20 44 6f 6e 27 74 20 68 61 76 65 20 61 rr; Don't have a
6050: 20 6c 6f 67 69 6e 3f 20 20 43 6c 69 63 6b 20 74 login? Click t
6060: 68 69 73 20 62 75 74 74 6f 6e 20 74 6f 20 63 72 his button to cr
6070: 65 61 74 65 20 6f 6e 65 2e 0a 20 20 20 20 20 20 eate one..
6080: 40 20 3c 2f 74 72 3e 0a 20 20 20 20 7d 0a 20 20 @ </tr>. }.
6090: 20 20 40 20 3c 2f 74 61 62 6c 65 3e 0a 20 20 20 @ </table>.
60a0: 20 69 66 28 20 7a 41 6e 6f 6e 50 77 20 26 26 20 if( zAnonPw &&
60b0: 21 6e 6f 41 6e 6f 6e 20 29 7b 0a 20 20 20 20 20 !noAnon ){.
60c0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 75 53 unsigned int uS
60d0: 65 65 64 20 3d 20 63 61 70 74 63 68 61 5f 73 65 eed = captcha_se
60e0: 65 64 28 29 3b 0a 20 20 20 20 20 20 63 6f 6e 73 ed();. cons
60f0: 74 20 63 68 61 72 20 2a 7a 44 65 63 6f 64 65 64 t char *zDecoded
6100: 20 3d 20 63 61 70 74 63 68 61 5f 64 65 63 6f 64 = captcha_decod
6110: 65 28 75 53 65 65 64 29 3b 0a 20 20 20 20 20 20 e(uSeed);.
6120: 69 6e 74 20 62 41 75 74 6f 43 61 70 74 63 68 61 int bAutoCaptcha
6130: 20 3d 20 64 62 5f 67 65 74 5f 62 6f 6f 6c 65 61 = db_get_boolea
6140: 6e 28 22 61 75 74 6f 2d 63 61 70 74 63 68 61 22 n("auto-captcha"
6150: 2c 20 30 29 3b 0a 20 20 20 20 20 20 63 68 61 72 , 0);. char
6160: 20 2a 7a 43 61 70 74 63 68 61 20 3d 20 63 61 70 *zCaptcha = cap
6170: 74 63 68 61 5f 72 65 6e 64 65 72 28 7a 44 65 63 tcha_render(zDec
6180: 6f 64 65 64 29 3b 0a 20 20 0a 20 20 20 20 20 20 oded);. .
6190: 40 20 3c 70 3e 3c 69 6e 70 75 74 20 74 79 70 65 @ <p><input type
61a0: 3d 22 68 69 64 64 65 6e 22 20 6e 61 6d 65 3d 22 ="hidden" name="
61b0: 63 73 22 20 76 61 6c 75 65 3d 22 25 75 28 75 53 cs" value="%u(uS
61c0: 65 65 64 29 22 20 2f 3e 0a 20 20 20 20 20 20 40 eed)" />. @
61d0: 20 56 69 73 69 74 6f 72 73 20 6d 61 79 20 65 6e Visitors may en
61e0: 74 65 72 20 3c 62 3e 61 6e 6f 6e 79 6d 6f 75 73 ter <b>anonymous
61f0: 3c 2f 62 3e 20 61 73 20 74 68 65 20 75 73 65 72 </b> as the user
6200: 2d 49 44 20 77 69 74 68 0a 20 20 20 20 20 20 40 -ID with. @
6210: 20 74 68 65 20 38 2d 63 68 61 72 61 63 74 65 72 the 8-character
6220: 20 68 65 78 61 64 65 63 69 6d 61 6c 20 70 61 73 hexadecimal pas
6230: 73 77 6f 72 64 20 73 68 6f 77 6e 20 62 65 6c 6f sword shown belo
6240: 77 3a 3c 2f 70 3e 0a 20 20 20 20 20 20 40 20 3c w:</p>. @ <
6250: 64 69 76 20 63 6c 61 73 73 3d 22 63 61 70 74 63 div class="captc
6260: 68 61 22 3e 3c 74 61 62 6c 65 20 63 6c 61 73 73 ha"><table class
6270: 3d 22 63 61 70 74 63 68 61 22 3e 3c 74 72 3e 3c ="captcha"><tr><
6280: 74 64 3e 3c 70 72 65 3e 0a 20 20 20 20 20 20 40 td><pre>. @
6290: 20 25 68 28 7a 43 61 70 74 63 68 61 29 0a 20 20 %h(zCaptcha).
62a0: 20 20 20 20 40 20 3c 2f 70 72 65 3e 3c 2f 74 64 @ </pre></td
62b0: 3e 3c 2f 74 72 3e 3c 2f 74 61 62 6c 65 3e 0a 20 ></tr></table>.
62c0: 20 20 20 20 20 69 66 28 20 62 41 75 74 6f 43 61 if( bAutoCa
62d0: 70 74 63 68 61 20 29 20 7b 0a 20 20 20 20 20 20 ptcha ) {.
62e0: 20 20 20 40 20 3c 69 6e 70 75 74 20 74 79 70 65 @ <input type
62f0: 3d 22 62 75 74 74 6f 6e 22 20 76 61 6c 75 65 3d ="button" value=
6300: 22 46 69 6c 6c 20 6f 75 74 20 63 61 70 74 63 68 "Fill out captch
6310: 61 22 20 69 64 3d 27 61 75 74 6f 66 69 6c 6c 42 a" id='autofillB
6320: 75 74 74 6f 6e 27 20 5c 0a 20 20 20 20 20 20 20 utton' \.
6330: 20 20 40 20 64 61 74 61 2d 61 66 3d 27 25 73 28 @ data-af='%s(
6340: 7a 44 65 63 6f 64 65 64 29 27 20 2f 3e 0a 20 20 zDecoded)' />.
6350: 20 20 20 20 20 20 20 73 74 79 6c 65 5f 6c 6f 61 style_loa
6360: 64 5f 6f 6e 65 5f 6a 73 5f 66 69 6c 65 28 22 6c d_one_js_file("l
6370: 6f 67 69 6e 2e 6a 73 22 29 3b 0a 20 20 20 20 20 ogin.js");.
6380: 20 7d 0a 20 20 20 20 20 20 40 20 3c 2f 64 69 76 }. @ </div
6390: 3e 0a 20 20 20 20 20 20 66 72 65 65 28 7a 43 61 >. free(zCa
63a0: 70 74 63 68 61 29 3b 0a 20 20 20 20 7d 0a 20 20 ptcha);. }.
63b0: 20 20 40 20 3c 2f 66 6f 72 6d 3e 0a 20 20 7d 0a @ </form>. }.
63c0: 20 20 69 66 28 20 6c 6f 67 69 6e 5f 69 73 5f 69 if( login_is_i
63d0: 6e 64 69 76 69 64 75 61 6c 28 29 20 26 26 20 67 ndividual() && g
63e0: 2e 70 65 72 6d 2e 50 61 73 73 77 6f 72 64 20 29 .perm.Password )
63f0: 7b 0a 20 20 20 20 69 66 28 20 65 6d 61 69 6c 5f {. if( email_
6400: 65 6e 61 62 6c 65 64 28 29 20 29 7b 0a 20 20 20 enabled() ){.
6410: 20 20 20 40 20 3c 68 72 3e 0a 20 20 20 20 20 20 @ <hr>.
6420: 40 20 3c 70 3e 43 6f 6e 66 69 67 75 72 65 20 3c @ <p>Configure <
6430: 61 20 68 72 65 66 3d 22 25 52 2f 61 6c 65 72 74 a href="%R/alert
6440: 73 22 3e 45 6d 61 69 6c 20 41 6c 65 72 74 73 3c s">Email Alerts<
6450: 2f 61 3e 0a 20 20 20 20 20 20 40 20 66 6f 72 20 /a>. @ for
6460: 75 73 65 72 20 3c 62 3e 25 68 28 67 2e 7a 4c 6f user <b>%h(g.zLo
6470: 67 69 6e 29 3c 2f 62 3e 3c 2f 70 3e 0a 20 20 20 gin)</b></p>.
6480: 20 7d 0a 20 20 20 20 40 20 3c 68 72 20 2f 3e 0a }. @ <hr />.
6490: 20 20 20 20 40 20 3c 70 3e 43 68 61 6e 67 65 20 @ <p>Change
64a0: 50 61 73 73 77 6f 72 64 20 66 6f 72 20 75 73 65 Password for use
64b0: 72 20 3c 62 3e 25 68 28 67 2e 7a 4c 6f 67 69 6e r <b>%h(g.zLogin
64c0: 29 3c 2f 62 3e 3a 3c 2f 70 3e 0a 20 20 20 20 66 )</b>:</p>. f
64d0: 6f 72 6d 5f 62 65 67 69 6e 28 30 2c 20 22 25 52 orm_begin(0, "%R
64e0: 2f 6c 6f 67 69 6e 22 29 3b 0a 20 20 20 20 40 20 /login");. @
64f0: 3c 74 61 62 6c 65 3e 0a 20 20 20 20 40 20 3c 74 <table>. @ <t
6500: 72 3e 3c 74 64 20 63 6c 61 73 73 3d 22 66 6f 72 r><td class="for
6510: 6d 5f 6c 61 62 65 6c 22 3e 4f 6c 64 20 50 61 73 m_label">Old Pas
6520: 73 77 6f 72 64 3a 3c 2f 74 64 3e 0a 20 20 20 20 sword:</td>.
6530: 40 20 3c 74 64 3e 3c 69 6e 70 75 74 20 74 79 70 @ <td><input typ
6540: 65 3d 22 70 61 73 73 77 6f 72 64 22 20 6e 61 6d e="password" nam
6550: 65 3d 22 70 22 20 73 69 7a 65 3d 22 33 30 22 20 e="p" size="30"
6560: 2f 3e 3c 2f 74 64 3e 3c 2f 74 72 3e 0a 20 20 20 /></td></tr>.
6570: 20 40 20 3c 74 72 3e 3c 74 64 20 63 6c 61 73 73 @ <tr><td class
6580: 3d 22 66 6f 72 6d 5f 6c 61 62 65 6c 22 3e 4e 65 ="form_label">Ne
6590: 77 20 50 61 73 73 77 6f 72 64 3a 3c 2f 74 64 3e w Password:</td>
65a0: 0a 20 20 20 20 40 20 3c 74 64 3e 3c 69 6e 70 75 . @ <td><inpu
65b0: 74 20 74 79 70 65 3d 22 70 61 73 73 77 6f 72 64 t type="password
65c0: 22 20 6e 61 6d 65 3d 22 6e 31 22 20 73 69 7a 65 " name="n1" size
65d0: 3d 22 33 30 22 20 2f 3e 3c 2f 74 64 3e 3c 2f 74 ="30" /></td></t
65e0: 72 3e 0a 20 20 20 20 40 20 3c 74 72 3e 3c 74 64 r>. @ <tr><td
65f0: 20 63 6c 61 73 73 3d 22 66 6f 72 6d 5f 6c 61 62 class="form_lab
6600: 65 6c 22 3e 52 65 70 65 61 74 20 4e 65 77 20 50 el">Repeat New P
6610: 61 73 73 77 6f 72 64 3a 3c 2f 74 64 3e 0a 20 20 assword:</td>.
6620: 20 20 40 20 3c 74 64 3e 3c 69 6e 70 75 74 20 74 @ <td><input t
6630: 79 70 65 3d 22 70 61 73 73 77 6f 72 64 22 20 6e ype="password" n
6640: 61 6d 65 3d 22 6e 32 22 20 73 69 7a 65 3d 22 33 ame="n2" size="3
6650: 30 22 20 2f 3e 3c 2f 74 64 3e 3c 2f 74 72 3e 0a 0" /></td></tr>.
6660: 20 20 20 20 40 20 3c 74 72 3e 3c 74 64 3e 3c 2f @ <tr><td></
6670: 74 64 3e 0a 20 20 20 20 40 20 3c 74 64 3e 3c 69 td>. @ <td><i
6680: 6e 70 75 74 20 74 79 70 65 3d 22 73 75 62 6d 69 nput type="submi
6690: 74 22 20 76 61 6c 75 65 3d 22 43 68 61 6e 67 65 t" value="Change
66a0: 20 50 61 73 73 77 6f 72 64 22 20 2f 3e 3c 2f 74 Password" /></t
66b0: 64 3e 3c 2f 74 72 3e 0a 20 20 20 20 40 20 3c 2f d></tr>. @ </
66c0: 74 61 62 6c 65 3e 0a 20 20 20 20 40 20 3c 2f 66 table>. @ </f
66d0: 6f 72 6d 3e 0a 20 20 7d 0a 20 20 73 74 79 6c 65 orm>. }. style
66e0: 5f 66 6f 6f 74 65 72 28 29 3b 0a 7d 0a 0a 2f 2a _footer();.}../*
66f0: 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 66 .** Attempt to f
6700: 69 6e 64 20 6c 6f 67 69 6e 20 63 72 65 64 65 6e ind login creden
6710: 74 69 61 6c 73 20 66 6f 72 20 75 73 65 72 20 7a tials for user z
6720: 4c 6f 67 69 6e 20 6f 6e 20 61 20 70 65 65 72 20 Login on a peer
6730: 72 65 70 6f 73 69 74 6f 72 79 0a 2a 2a 20 77 69 repository.** wi
6740: 74 68 20 70 72 6f 6a 65 63 74 20 63 6f 64 65 20 th project code
6750: 7a 43 6f 64 65 2e 20 20 54 72 61 6e 73 66 65 72 zCode. Transfer
6760: 20 74 68 6f 73 65 20 63 72 65 64 65 6e 74 69 61 those credentia
6770: 6c 73 20 74 6f 20 74 68 65 20 6c 6f 63 61 6c 0a ls to the local.
6780: 2a 2a 20 72 65 70 6f 73 69 74 6f 72 79 2e 0a 2a ** repository..*
6790: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 *.** Return true
67a0: 20 69 66 20 61 20 74 72 61 6e 73 66 65 72 20 77 if a transfer w
67b0: 61 73 20 6d 61 64 65 20 61 6e 64 20 66 61 6c 73 as made and fals
67c0: 65 20 69 66 20 6e 6f 74 2e 0a 2a 2f 0a 73 74 61 e if not..*/.sta
67d0: 74 69 63 20 69 6e 74 20 6c 6f 67 69 6e 5f 74 72 tic int login_tr
67e0: 61 6e 73 66 65 72 5f 63 72 65 64 65 6e 74 69 61 ansfer_credentia
67f0: 6c 73 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 ls(. const char
6800: 20 2a 7a 4c 6f 67 69 6e 2c 20 20 20 20 20 20 20 *zLogin,
6810: 20 20 20 2f 2a 20 4c 6f 67 69 6e 20 77 65 20 61 /* Login we a
6820: 72 65 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 2a re looking for *
6830: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a /. const char *
6840: 7a 43 6f 64 65 2c 20 20 20 20 20 20 20 20 20 20 zCode,
6850: 20 2f 2a 20 50 72 6f 6a 65 63 74 20 63 6f 64 65 /* Project code
6860: 20 6f 66 20 70 65 65 72 20 72 65 70 6f 73 69 74 of peer reposit
6870: 6f 72 79 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 ory */. const c
6880: 68 61 72 20 2a 7a 48 61 73 68 2c 20 20 20 20 20 har *zHash,
6890: 20 20 20 20 20 20 2f 2a 20 48 41 53 48 20 66 72 /* HASH fr
68a0: 6f 6d 20 6c 6f 67 69 6e 20 63 6f 6f 6b 69 65 20 om login cookie
68b0: 48 41 53 48 2f 43 4f 44 45 2f 4c 4f 47 49 4e 20 HASH/CODE/LOGIN
68c0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 */. const char
68d0: 2a 7a 52 65 6d 6f 74 65 41 64 64 72 20 20 20 20 *zRemoteAddr
68e0: 20 20 2f 2a 20 52 65 71 75 65 73 74 20 63 6f 6d /* Request com
68f0: 65 73 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f 0a es from here */.
6900: 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 70 4f ){. sqlite3 *pO
6910: 74 68 65 72 20 3d 20 30 3b 20 20 20 20 20 20 20 ther = 0;
6920: 20 20 2f 2a 20 54 68 65 20 6f 74 68 65 72 20 72 /* The other r
6930: 65 70 6f 73 69 74 6f 72 79 20 2a 2f 0a 20 20 73 epository */. s
6940: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 qlite3_stmt *pSt
6950: 6d 74 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 51 mt; /* Q
6960: 75 65 72 79 20 61 67 61 69 6e 73 74 20 74 68 65 uery against the
6970: 20 6f 74 68 65 72 20 72 65 70 6f 73 69 74 6f 72 other repositor
6980: 79 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 51 y */. char *zSQ
6990: 4c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 L;
69a0: 20 20 20 20 2f 2a 20 53 51 4c 20 6f 66 20 74 68 /* SQL of th
69b0: 65 20 71 75 65 72 79 20 61 67 61 69 6e 73 74 20 e query against
69c0: 6f 74 68 65 72 20 72 65 70 6f 20 2a 2f 0a 20 20 other repo */.
69d0: 63 68 61 72 20 2a 7a 4f 74 68 65 72 52 65 70 6f char *zOtherRepo
69e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 ; /*
69f0: 46 69 6c 65 6e 61 6d 65 20 6f 66 20 74 68 65 20 Filename of the
6a00: 6f 74 68 65 72 20 72 65 70 6f 73 69 74 6f 72 79 other repository
6a10: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 */. int rc;
6a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6a30: 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 63 6f 64 /* Result cod
6a40: 65 20 66 72 6f 6d 20 53 51 4c 69 74 65 20 6c 69 e from SQLite li
6a50: 62 72 61 72 79 20 66 75 6e 63 74 69 6f 6e 73 20 brary functions
6a60: 2a 2f 0a 20 20 69 6e 74 20 6e 58 66 65 72 20 3d */. int nXfer =
6a70: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 0;
6a80: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 /* Number of c
6a90: 72 65 64 65 6e 74 69 61 6c 73 20 74 72 61 6e 73 redentials trans
6aa0: 66 65 72 72 65 64 20 2a 2f 0a 0a 20 20 7a 4f 74 ferred */.. zOt
6ab0: 68 65 72 52 65 70 6f 20 3d 20 64 62 5f 74 65 78 herRepo = db_tex
6ac0: 74 28 30 2c 0a 20 20 20 20 20 20 20 22 53 45 4c t(0,. "SEL
6ad0: 45 43 54 20 76 61 6c 75 65 20 46 52 4f 4d 20 63 ECT value FROM c
6ae0: 6f 6e 66 69 67 20 57 48 45 52 45 20 6e 61 6d 65 onfig WHERE name
6af0: 3d 27 70 65 65 72 2d 72 65 70 6f 2d 25 71 27 22 ='peer-repo-%q'"
6b00: 2c 0a 20 20 20 20 20 20 20 7a 43 6f 64 65 0a 20 ,. zCode.
6b10: 20 29 3b 0a 20 20 69 66 28 20 7a 4f 74 68 65 72 );. if( zOther
6b20: 52 65 70 6f 3d 3d 30 20 29 20 72 65 74 75 72 6e Repo==0 ) return
6b30: 20 30 3b 20 20 2f 2a 20 4e 6f 20 73 75 63 68 20 0; /* No such
6b40: 70 65 65 72 20 72 65 70 6f 73 69 74 6f 72 79 20 peer repository
6b50: 2a 2f 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 */.. rc = sqlit
6b60: 65 33 5f 6f 70 65 6e 5f 76 32 28 0a 20 20 20 20 e3_open_v2(.
6b70: 20 20 20 7a 4f 74 68 65 72 52 65 70 6f 2c 20 26 zOtherRepo, &
6b80: 70 4f 74 68 65 72 2c 0a 20 20 20 20 20 20 20 53 pOther,. S
6b90: 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 QLITE_OPEN_READW
6ba0: 52 49 54 45 20 7c 20 53 51 4c 49 54 45 5f 4f 50 RITE | SQLITE_OP
6bb0: 45 4e 5f 43 52 45 41 54 45 2c 0a 20 20 20 20 20 EN_CREATE,.
6bc0: 20 20 67 2e 7a 56 66 73 4e 61 6d 65 0a 20 20 29 g.zVfsName. )
6bd0: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 ;. if( rc==SQLI
6be0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c TE_OK ){. sql
6bf0: 69 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 ite3_create_func
6c00: 74 69 6f 6e 28 70 4f 74 68 65 72 2c 22 6e 6f 77 tion(pOther,"now
6c10: 22 2c 30 2c 53 51 4c 49 54 45 5f 55 54 46 38 2c ",0,SQLITE_UTF8,
6c20: 30 2c 64 62 5f 6e 6f 77 5f 66 75 6e 63 74 69 6f 0,db_now_functio
6c30: 6e 2c 30 2c 30 29 3b 0a 20 20 20 20 73 71 6c 69 n,0,0);. sqli
6c40: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 te3_create_funct
6c50: 69 6f 6e 28 70 4f 74 68 65 72 2c 20 22 63 6f 6e ion(pOther, "con
6c60: 73 74 61 6e 74 5f 74 69 6d 65 5f 63 6d 70 22 2c stant_time_cmp",
6c70: 20 32 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c 2, SQLITE_UTF8,
6c80: 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 0,.
6c90: 20 20 20 20 20 20 63 6f 6e 73 74 61 6e 74 5f 74 constant_t
6ca0: 69 6d 65 5f 63 6d 70 5f 66 75 6e 63 74 69 6f 6e ime_cmp_function
6cb0: 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c , 0, 0);. sql
6cc0: 69 74 65 33 5f 62 75 73 79 5f 74 69 6d 65 6f 75 ite3_busy_timeou
6cd0: 74 28 70 4f 74 68 65 72 2c 20 35 30 30 30 29 3b t(pOther, 5000);
6ce0: 0a 20 20 20 20 7a 53 51 4c 20 3d 20 6d 70 72 69 . zSQL = mpri
6cf0: 6e 74 66 28 0a 20 20 20 20 20 20 22 53 45 4c 45 ntf(. "SELE
6d00: 43 54 20 63 65 78 70 69 72 65 20 46 52 4f 4d 20 CT cexpire FROM
6d10: 75 73 65 72 22 0a 20 20 20 20 20 20 22 20 57 48 user". " WH
6d20: 45 52 45 20 6c 6f 67 69 6e 3d 25 51 22 0a 20 20 ERE login=%Q".
6d30: 20 20 20 20 22 20 20 20 41 4e 44 20 69 70 61 64 " AND ipad
6d40: 64 72 3d 25 51 22 0a 20 20 20 20 20 20 22 20 20 dr=%Q". "
6d50: 20 41 4e 44 20 6c 65 6e 67 74 68 28 63 61 70 29 AND length(cap)
6d60: 3e 30 22 0a 20 20 20 20 20 20 22 20 20 20 41 4e >0". " AN
6d70: 44 20 6c 65 6e 67 74 68 28 70 77 29 3e 30 22 0a D length(pw)>0".
6d80: 20 20 20 20 20 20 22 20 20 20 41 4e 44 20 63 65 " AND ce
6d90: 78 70 69 72 65 3e 6a 75 6c 69 61 6e 64 61 79 28 xpire>julianday(
6da0: 27 6e 6f 77 27 29 22 0a 20 20 20 20 20 20 22 20 'now')". "
6db0: 20 20 41 4e 44 20 63 6f 6e 73 74 61 6e 74 5f 74 AND constant_t
6dc0: 69 6d 65 5f 63 6d 70 28 63 6f 6f 6b 69 65 2c 25 ime_cmp(cookie,%
6dd0: 51 29 3d 30 22 2c 0a 20 20 20 20 20 20 7a 4c 6f Q)=0",. zLo
6de0: 67 69 6e 2c 20 7a 52 65 6d 6f 74 65 41 64 64 72 gin, zRemoteAddr
6df0: 2c 20 7a 48 61 73 68 0a 20 20 20 20 29 3b 0a 20 , zHash. );.
6e00: 20 20 20 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 pStmt = 0;.
6e10: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 rc = sqlite3_p
6e20: 72 65 70 61 72 65 5f 76 32 28 70 4f 74 68 65 72 repare_v2(pOther
6e30: 2c 20 7a 53 51 4c 2c 20 2d 31 2c 20 26 70 53 74 , zSQL, -1, &pSt
6e40: 6d 74 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 mt, 0);. if(
6e50: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 rc==SQLITE_OK &&
6e60: 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 sqlite3_step(pS
6e70: 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 tmt)==SQLITE_ROW
6e80: 20 29 7b 0a 20 20 20 20 20 20 64 62 5f 6d 75 6c ){. db_mul
6e90: 74 69 5f 65 78 65 63 28 0a 20 20 20 20 20 20 20 ti_exec(.
6ea0: 20 22 55 50 44 41 54 45 20 75 73 65 72 20 53 45 "UPDATE user SE
6eb0: 54 20 63 6f 6f 6b 69 65 3d 25 51 2c 20 69 70 61 T cookie=%Q, ipa
6ec0: 64 64 72 3d 25 51 2c 20 63 65 78 70 69 72 65 3d ddr=%Q, cexpire=
6ed0: 25 2e 31 37 67 22 0a 20 20 20 20 20 20 20 20 22 %.17g". "
6ee0: 20 57 48 45 52 45 20 6c 6f 67 69 6e 3d 25 51 22 WHERE login=%Q"
6ef0: 2c 0a 20 20 20 20 20 20 20 20 7a 48 61 73 68 2c ,. zHash,
6f00: 20 7a 52 65 6d 6f 74 65 41 64 64 72 2c 0a 20 20 zRemoteAddr,.
6f10: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 63 6f sqlite3_co
6f20: 6c 75 6d 6e 5f 64 6f 75 62 6c 65 28 70 53 74 6d lumn_double(pStm
6f30: 74 2c 20 30 29 2c 20 7a 4c 6f 67 69 6e 0a 20 20 t, 0), zLogin.
6f40: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 6e 58 66 );. nXf
6f50: 65 72 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 er++;. }.
6f60: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 sqlite3_finalize
6f70: 28 70 53 74 6d 74 29 3b 0a 20 20 7d 0a 20 20 73 (pStmt);. }. s
6f80: 71 6c 69 74 65 33 5f 63 6c 6f 73 65 28 70 4f 74 qlite3_close(pOt
6f90: 68 65 72 29 3b 0a 20 20 66 6f 73 73 69 6c 5f 66 her);. fossil_f
6fa0: 72 65 65 28 7a 4f 74 68 65 72 52 65 70 6f 29 3b ree(zOtherRepo);
6fb0: 0a 20 20 72 65 74 75 72 6e 20 6e 58 66 65 72 3b . return nXfer;
6fc0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e .}../*.** Return
6fd0: 20 54 52 55 45 20 69 66 20 7a 4c 6f 67 69 6e 20 TRUE if zLogin
6fe0: 69 73 20 6f 6e 65 20 6f 66 20 74 68 65 20 73 70 is one of the sp
6ff0: 65 63 69 61 6c 20 75 73 65 72 6e 61 6d 65 73 0a ecial usernames.
7000: 2a 2f 0a 69 6e 74 20 6c 6f 67 69 6e 5f 69 73 5f */.int login_is_
7010: 73 70 65 63 69 61 6c 28 63 6f 6e 73 74 20 63 68 special(const ch
7020: 61 72 20 2a 7a 4c 6f 67 69 6e 29 7b 0a 20 20 69 ar *zLogin){. i
7030: 66 28 20 66 6f 73 73 69 6c 5f 73 74 72 63 6d 70 f( fossil_strcmp
7040: 28 7a 4c 6f 67 69 6e 2c 20 22 61 6e 6f 6e 79 6d (zLogin, "anonym
7050: 6f 75 73 22 29 3d 3d 30 20 29 20 72 65 74 75 72 ous")==0 ) retur
7060: 6e 20 31 3b 0a 20 20 69 66 28 20 66 6f 73 73 69 n 1;. if( fossi
7070: 6c 5f 73 74 72 63 6d 70 28 7a 4c 6f 67 69 6e 2c l_strcmp(zLogin,
7080: 20 22 6e 6f 62 6f 64 79 22 29 3d 3d 30 20 29 20 "nobody")==0 )
7090: 72 65 74 75 72 6e 20 31 3b 0a 20 20 69 66 28 20 return 1;. if(
70a0: 66 6f 73 73 69 6c 5f 73 74 72 63 6d 70 28 7a 4c fossil_strcmp(zL
70b0: 6f 67 69 6e 2c 20 22 64 65 76 65 6c 6f 70 65 72 ogin, "developer
70c0: 22 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 31 ")==0 ) return 1
70d0: 3b 0a 20 20 69 66 28 20 66 6f 73 73 69 6c 5f 73 ;. if( fossil_s
70e0: 74 72 63 6d 70 28 7a 4c 6f 67 69 6e 2c 20 22 72 trcmp(zLogin, "r
70f0: 65 61 64 65 72 22 29 3d 3d 30 20 29 20 72 65 74 eader")==0 ) ret
7100: 75 72 6e 20 31 3b 0a 20 20 72 65 74 75 72 6e 20 urn 1;. return
7110: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 6f 6b 0;.}../*.** Look
7120: 75 70 20 74 68 65 20 75 69 64 20 66 6f 72 20 61 up the uid for a
7130: 20 6e 6f 6e 2d 62 75 69 6c 74 2d 69 6e 20 75 73 non-built-in us
7140: 65 72 20 77 69 74 68 20 7a 4c 6f 67 69 6e 20 61 er with zLogin a
7150: 6e 64 20 7a 43 6f 6f 6b 69 65 20 61 6e 64 0a 2a nd zCookie and.*
7160: 2a 20 7a 52 65 6d 6f 74 65 41 64 64 72 2e 20 20 * zRemoteAddr.
7170: 52 65 74 75 72 6e 20 30 20 69 66 20 6e 6f 74 20 Return 0 if not
7180: 66 6f 75 6e 64 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 found..**.** Not
7190: 65 20 74 68 61 74 20 74 68 69 73 20 6f 6e 6c 79 e that this only
71a0: 20 73 65 61 72 63 68 65 73 20 66 6f 72 20 6c 6f searches for lo
71b0: 67 67 65 64 2d 69 6e 20 65 6e 74 72 69 65 73 20 gged-in entries
71c0: 77 69 74 68 20 6d 61 74 63 68 69 6e 67 0a 2a 2a with matching.**
71d0: 20 7a 43 6f 6f 6b 69 65 20 28 64 62 3a 20 75 73 zCookie (db: us
71e0: 65 72 2e 63 6f 6f 6b 69 65 29 20 61 6e 64 20 7a er.cookie) and z
71f0: 52 65 6d 6f 74 65 41 64 64 72 20 28 64 62 3a 20 RemoteAddr (db:
7200: 75 73 65 72 2e 69 70 61 64 64 72 29 0a 2a 2a 20 user.ipaddr).**
7210: 65 6e 74 72 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 entries..*/.stat
7220: 69 63 20 69 6e 74 20 6c 6f 67 69 6e 5f 66 69 6e ic int login_fin
7230: 64 5f 75 73 65 72 28 0a 20 20 63 6f 6e 73 74 20 d_user(. const
7240: 63 68 61 72 20 2a 7a 4c 6f 67 69 6e 2c 20 20 20 char *zLogin,
7250: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 72 /* User
7260: 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 name */. const
7270: 20 63 68 61 72 20 2a 7a 43 6f 6f 6b 69 65 2c 20 char *zCookie,
7280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 67 /* Log
7290: 69 6e 20 63 6f 6f 6b 69 65 20 76 61 6c 75 65 20 in cookie value
72a0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 */. const char
72b0: 2a 7a 52 65 6d 6f 74 65 41 64 64 72 20 20 20 20 *zRemoteAddr
72c0: 20 20 20 20 2f 2a 20 41 62 62 72 65 76 69 61 74 /* Abbreviat
72d0: 65 64 20 49 50 20 61 64 64 72 65 73 73 20 66 6f ed IP address fo
72e0: 72 20 76 61 6c 69 64 20 6c 6f 67 69 6e 20 2a 2f r valid login */
72f0: 0a 29 7b 0a 20 20 69 6e 74 20 75 69 64 3b 0a 20 .){. int uid;.
7300: 20 69 66 28 20 6c 6f 67 69 6e 5f 69 73 5f 73 70 if( login_is_sp
7310: 65 63 69 61 6c 28 7a 4c 6f 67 69 6e 29 20 29 20 ecial(zLogin) )
7320: 72 65 74 75 72 6e 20 30 3b 0a 20 20 75 69 64 20 return 0;. uid
7330: 3d 20 64 62 5f 69 6e 74 28 30 2c 0a 20 20 20 20 = db_int(0,.
7340: 22 53 45 4c 45 43 54 20 75 69 64 20 46 52 4f 4d "SELECT uid FROM
7350: 20 75 73 65 72 22 0a 20 20 20 20 22 20 57 48 45 user". " WHE
7360: 52 45 20 6c 6f 67 69 6e 3d 25 51 22 0a 20 20 20 RE login=%Q".
7370: 20 22 20 20 20 41 4e 44 20 69 70 61 64 64 72 3d " AND ipaddr=
7380: 25 51 22 0a 20 20 20 20 22 20 20 20 41 4e 44 20 %Q". " AND
7390: 63 65 78 70 69 72 65 3e 6a 75 6c 69 61 6e 64 61 cexpire>julianda
73a0: 79 28 27 6e 6f 77 27 29 22 0a 20 20 20 20 22 20 y('now')". "
73b0: 20 20 41 4e 44 20 6c 65 6e 67 74 68 28 63 61 70 AND length(cap
73c0: 29 3e 30 22 0a 20 20 20 20 22 20 20 20 41 4e 44 )>0". " AND
73d0: 20 6c 65 6e 67 74 68 28 70 77 29 3e 30 22 0a 20 length(pw)>0".
73e0: 20 20 20 22 20 20 20 41 4e 44 20 63 6f 6e 73 74 " AND const
73f0: 61 6e 74 5f 74 69 6d 65 5f 63 6d 70 28 63 6f 6f ant_time_cmp(coo
7400: 6b 69 65 2c 25 51 29 3d 30 22 2c 0a 20 20 20 20 kie,%Q)=0",.
7410: 7a 4c 6f 67 69 6e 2c 20 7a 52 65 6d 6f 74 65 41 zLogin, zRemoteA
7420: 64 64 72 2c 20 7a 43 6f 6f 6b 69 65 0a 20 20 29 ddr, zCookie. )
7430: 3b 0a 20 20 72 65 74 75 72 6e 20 75 69 64 3b 0a ;. return uid;.
7440: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 }../*.** Return
7450: 74 72 75 65 20 69 66 20 69 74 20 69 73 20 61 70 true if it is ap
7460: 70 72 6f 70 72 69 61 74 65 20 74 6f 20 72 65 64 propriate to red
7470: 69 72 65 63 74 20 6c 6f 67 69 6e 20 72 65 71 75 irect login requ
7480: 65 73 74 73 20 74 6f 20 48 54 54 50 53 2e 0a 2a ests to HTTPS..*
7490: 2a 0a 2a 2a 20 52 65 64 69 72 65 63 74 20 74 6f *.** Redirect to
74a0: 20 68 74 74 70 73 20 69 73 20 61 70 70 72 6f 70 https is approp
74b0: 72 69 61 74 65 20 69 66 20 61 6c 6c 20 6f 66 20 riate if all of
74c0: 74 68 65 20 61 62 6f 76 65 20 61 72 65 20 74 72 the above are tr
74d0: 75 65 3a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 ue:.** (1) Th
74e0: 65 20 72 65 64 69 72 65 63 74 2d 74 6f 2d 68 74 e redirect-to-ht
74f0: 74 70 73 20 66 6c 61 67 20 69 73 20 73 65 74 0a tps flag is set.
7500: 2a 2a 20 20 20 20 28 32 29 20 54 68 65 20 63 75 ** (2) The cu
7510: 72 72 65 6e 74 20 63 6f 6e 6e 65 63 74 69 6f 6e rrent connection
7520: 20 69 73 20 68 74 74 70 2c 20 6e 6f 74 20 68 74 is http, not ht
7530: 74 70 73 20 6f 72 20 73 73 68 0a 2a 2a 20 20 20 tps or ssh.**
7540: 20 28 33 29 20 54 68 65 20 73 73 6c 4e 6f 74 41 (3) The sslNotA
7550: 76 61 69 6c 61 62 6c 65 20 66 6c 61 67 20 69 73 vailable flag is
7560: 20 63 6c 65 61 72 0a 2a 2f 0a 69 6e 74 20 6c 6f clear.*/.int lo
7570: 67 69 6e 5f 77 61 6e 74 73 5f 68 74 74 70 73 5f gin_wants_https_
7580: 72 65 64 69 72 65 63 74 28 76 6f 69 64 29 7b 0a redirect(void){.
7590: 20 20 69 66 28 20 67 2e 73 73 6c 4e 6f 74 41 76 if( g.sslNotAv
75a0: 61 69 6c 61 62 6c 65 20 29 20 72 65 74 75 72 6e ailable ) return
75b0: 20 30 3b 0a 20 20 69 66 28 20 64 62 5f 67 65 74 0;. if( db_get
75c0: 5f 62 6f 6f 6c 65 61 6e 28 22 72 65 64 69 72 65 _boolean("redire
75d0: 63 74 2d 74 6f 2d 68 74 74 70 73 22 2c 30 29 3d ct-to-https",0)=
75e0: 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 =0 ) return 0;.
75f0: 20 69 66 28 20 50 28 22 48 54 54 50 53 22 29 21 if( P("HTTPS")!
7600: 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 =0 ) return 0;.
7610: 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 0a 2f return 1;.}.../
7620: 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 *.** Attempt to
7630: 75 73 65 20 42 61 73 69 63 20 41 75 74 68 65 6e use Basic Authen
7640: 74 69 63 61 74 69 6f 6e 20 74 6f 20 65 73 74 61 tication to esta
7650: 62 6c 69 73 68 20 74 68 65 20 75 73 65 72 2e 20 blish the user.
7660: 20 52 65 74 75 72 6e 20 74 68 65 0a 2a 2a 20 28 Return the.** (
7670: 6e 6f 6e 2d 7a 65 72 6f 29 20 75 69 64 20 69 66 non-zero) uid if
7680: 20 73 75 63 63 65 73 73 66 75 6c 2e 20 20 52 65 successful. Re
7690: 74 75 72 6e 20 30 20 69 66 20 69 74 20 64 6f 65 turn 0 if it doe
76a0: 73 20 6e 6f 74 20 77 6f 72 6b 2e 0a 2a 2f 0a 73 s not work..*/.s
76b0: 74 61 74 69 63 20 69 6e 74 20 6c 6f 67 69 63 5f tatic int logic_
76c0: 62 61 73 69 63 5f 61 75 74 68 65 6e 74 69 63 61 basic_authentica
76d0: 74 69 6f 6e 28 63 6f 6e 73 74 20 63 68 61 72 20 tion(const char
76e0: 2a 7a 49 70 41 64 64 72 29 7b 0a 20 20 63 6f 6e *zIpAddr){. con
76f0: 73 74 20 63 68 61 72 20 2a 7a 41 75 74 68 20 3d st char *zAuth =
7700: 20 50 44 28 22 48 54 54 50 5f 41 55 54 48 4f 52 PD("HTTP_AUTHOR
7710: 49 5a 41 54 49 4f 4e 22 2c 20 30 29 3b 0a 20 20 IZATION", 0);.
7720: 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 75 69 64 int i;. int uid
7730: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 44 65 63 = 0;. int nDec
7740: 6f 64 65 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 ode = 0;. char
7750: 2a 7a 44 65 63 6f 64 65 20 3d 20 30 3b 0a 20 20 *zDecode = 0;.
7760: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 73 65 const char *zUse
7770: 72 6e 61 6d 65 20 3d 20 30 3b 0a 20 20 63 6f 6e rname = 0;. con
7780: 73 74 20 63 68 61 72 20 2a 7a 50 61 73 73 77 64 st char *zPasswd
7790: 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 7a 41 75 = 0;.. if( zAu
77a0: 74 68 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 th==0 ) return 0
77b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ;
77c0: 20 20 20 20 20 2f 2a 20 46 61 69 6c 3a 20 4e 6f /* Fail: No
77d0: 20 41 75 74 68 65 6e 74 69 63 61 74 69 6f 6e 3a Authentication:
77e0: 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 77 68 69 header */. whi
77f0: 6c 65 28 20 66 6f 73 73 69 6c 5f 69 73 73 70 61 le( fossil_isspa
7800: 63 65 28 7a 41 75 74 68 5b 30 5d 29 20 29 20 7a ce(zAuth[0]) ) z
7810: 41 75 74 68 2b 2b 3b 20 20 2f 2a 20 53 6b 69 70 Auth++; /* Skip
7820: 20 6c 65 61 64 69 6e 67 20 77 68 69 74 65 73 70 leading whitesp
7830: 61 63 65 20 2a 2f 0a 20 20 69 66 28 20 73 74 72 ace */. if( str
7840: 6e 63 6d 70 28 7a 41 75 74 68 2c 20 22 42 61 73 ncmp(zAuth, "Bas
7850: 69 63 20 22 2c 20 36 29 21 3d 30 20 29 20 72 65 ic ", 6)!=0 ) re
7860: 74 75 72 6e 20 30 3b 20 20 2f 2a 20 46 61 69 6c turn 0; /* Fail
7870: 3a 20 4e 6f 74 20 42 61 73 69 63 20 41 75 74 68 : Not Basic Auth
7880: 65 6e 74 69 63 61 74 69 6f 6e 20 2a 2f 0a 0a 20 entication */..
7890: 20 2f 2a 20 50 61 72 73 65 20 6f 75 74 20 74 68 /* Parse out th
78a0: 65 20 75 73 65 72 6e 61 6d 65 20 61 6e 64 20 70 e username and p
78b0: 61 73 73 77 6f 72 64 2c 20 73 65 70 61 72 61 74 assword, separat
78c0: 65 64 20 62 79 20 61 20 22 3a 22 20 2a 2f 0a 20 ed by a ":" */.
78d0: 20 7a 41 75 74 68 20 2b 3d 20 36 3b 0a 20 20 77 zAuth += 6;. w
78e0: 68 69 6c 65 28 20 66 6f 73 73 69 6c 5f 69 73 73 hile( fossil_iss
78f0: 70 61 63 65 28 7a 41 75 74 68 5b 30 5d 29 20 29 pace(zAuth[0]) )
7900: 20 7a 41 75 74 68 2b 2b 3b 0a 20 20 7a 44 65 63 zAuth++;. zDec
7910: 6f 64 65 20 3d 20 64 65 63 6f 64 65 36 34 28 7a ode = decode64(z
7920: 41 75 74 68 2c 20 26 6e 44 65 63 6f 64 65 29 3b Auth, &nDecode);
7930: 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 44 65 .. for(i=0; zDe
7940: 63 6f 64 65 5b 69 5d 20 26 26 20 7a 44 65 63 6f code[i] && zDeco
7950: 64 65 5b 69 5d 21 3d 27 3a 27 3b 20 69 2b 2b 29 de[i]!=':'; i++)
7960: 7b 7d 0a 20 20 69 66 28 20 7a 44 65 63 6f 64 65 {}. if( zDecode
7970: 5b 69 5d 20 29 7b 0a 20 20 20 20 7a 44 65 63 6f [i] ){. zDeco
7980: 64 65 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7a de[i] = 0;. z
7990: 55 73 65 72 6e 61 6d 65 20 3d 20 7a 44 65 63 6f Username = zDeco
79a0: 64 65 3b 0a 20 20 20 20 7a 50 61 73 73 77 64 20 de;. zPasswd
79b0: 3d 20 26 7a 44 65 63 6f 64 65 5b 69 2b 31 5d 3b = &zDecode[i+1];
79c0: 0a 0a 20 20 20 20 2f 2a 20 41 74 74 65 6d 70 74 .. /* Attempt
79d0: 69 6e 67 20 74 6f 20 6c 6f 67 20 69 6e 20 61 73 ing to log in as
79e0: 20 74 68 65 20 75 73 65 72 20 70 72 6f 76 69 64 the user provid
79f0: 65 64 20 62 79 20 48 54 54 50 0a 20 20 20 20 2a ed by HTTP. *
7a00: 2a 20 62 61 73 69 63 20 61 75 74 68 0a 20 20 20 * basic auth.
7a10: 20 2a 2f 0a 20 20 20 20 75 69 64 20 3d 20 6c 6f */. uid = lo
7a20: 67 69 6e 5f 73 65 61 72 63 68 5f 75 69 64 28 7a gin_search_uid(z
7a30: 55 73 65 72 6e 61 6d 65 2c 20 7a 50 61 73 73 77 Username, zPassw
7a40: 64 29 3b 0a 20 20 20 20 69 66 28 20 75 69 64 3e d);. if( uid>
7a50: 30 20 29 7b 0a 20 20 20 20 20 20 72 65 63 6f 72 0 ){. recor
7a60: 64 5f 6c 6f 67 69 6e 5f 61 74 74 65 6d 70 74 28 d_login_attempt(
7a70: 7a 55 73 65 72 6e 61 6d 65 2c 20 7a 49 70 41 64 zUsername, zIpAd
7a80: 64 72 2c 20 31 29 3b 0a 20 20 20 20 7d 65 6c 73 dr, 1);. }els
7a90: 65 7b 0a 20 20 20 20 20 20 72 65 63 6f 72 64 5f e{. record_
7aa0: 6c 6f 67 69 6e 5f 61 74 74 65 6d 70 74 28 7a 55 login_attempt(zU
7ab0: 73 65 72 6e 61 6d 65 2c 20 7a 49 70 41 64 64 72 sername, zIpAddr
7ac0: 2c 20 30 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 , 0);.. /*
7ad0: 54 68 65 20 75 73 65 72 20 61 74 74 65 6d 70 74 The user attempt
7ae0: 65 64 20 74 6f 20 6c 6f 67 69 6e 20 73 70 65 63 ed to login spec
7af0: 69 66 69 63 61 6c 6c 79 20 77 69 74 68 20 48 54 ifically with HT
7b00: 54 50 20 62 61 73 69 63 0a 20 20 20 20 20 20 2a TP basic. *
7b10: 2a 20 61 75 74 68 2c 20 62 75 74 20 70 72 6f 76 * auth, but prov
7b20: 69 64 65 64 20 69 6e 76 61 6c 69 64 20 63 72 65 ided invalid cre
7b30: 64 65 6e 74 69 61 6c 73 2e 20 49 6e 66 6f 72 6d dentials. Inform
7b40: 20 74 68 65 6d 20 6f 66 0a 20 20 20 20 20 20 2a them of. *
7b50: 2a 20 74 68 65 20 66 61 69 6c 65 64 20 6c 6f 67 * the failed log
7b60: 69 6e 20 61 74 74 65 6d 70 74 20 76 69 61 20 34 in attempt via 4
7b70: 30 31 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 01.. */.
7b80: 20 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 cgi_set_statu
7b90: 73 28 34 30 31 2c 20 22 55 6e 61 75 74 68 6f 72 s(401, "Unauthor
7ba0: 69 7a 65 64 22 29 3b 0a 20 20 20 20 20 20 63 67 ized");. cg
7bb0: 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 20 20 20 i_reply();.
7bc0: 20 66 6f 73 73 69 6c 5f 65 78 69 74 28 30 29 3b fossil_exit(0);
7bd0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 66 6f 73 . }. }. fos
7be0: 73 69 6c 5f 66 72 65 65 28 7a 44 65 63 6f 64 65 sil_free(zDecode
7bf0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 75 69 64 3b );. return uid;
7c00: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 .}../*.** This r
7c10: 6f 75 74 69 6e 65 20 65 78 61 6d 69 6e 65 73 20 outine examines
7c20: 74 68 65 20 6c 6f 67 69 6e 20 63 6f 6f 6b 69 65 the login cookie
7c30: 20 74 6f 20 73 65 65 20 69 66 20 69 74 20 65 78 to see if it ex
7c40: 69 73 74 73 20 61 6e 64 0a 2a 2a 20 69 73 20 76 ists and.** is v
7c50: 61 6c 69 64 2e 20 20 49 66 20 74 68 65 20 6c 6f alid. If the lo
7c60: 67 69 6e 20 63 6f 6f 6b 69 65 20 63 68 65 63 6b gin cookie check
7c70: 73 20 6f 75 74 2c 20 69 74 20 74 68 65 6e 20 73 s out, it then s
7c80: 65 74 73 20 67 6c 6f 62 61 6c 0a 2a 2a 20 76 61 ets global.** va
7c90: 72 69 61 62 6c 65 73 20 61 70 70 72 6f 70 72 69 riables appropri
7ca0: 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 ately..**.**
7cb0: 67 2e 75 73 65 72 55 69 64 20 20 20 20 20 20 44 g.userUid D
7cc0: 61 74 61 62 61 73 65 20 55 53 45 52 2e 55 49 44 atabase USER.UID
7cd0: 20 76 61 6c 75 65 2e 20 20 4d 69 67 68 74 20 62 value. Might b
7ce0: 65 20 2d 31 20 66 6f 72 20 22 6e 6f 62 6f 64 79 e -1 for "nobody
7cf0: 22 0a 2a 2a 20 20 20 20 67 2e 7a 4c 6f 67 69 6e ".** g.zLogin
7d00: 20 20 20 20 20 20 20 44 61 74 61 62 61 73 65 20 Database
7d10: 55 53 45 52 2e 4c 4f 47 49 4e 20 76 61 6c 75 65 USER.LOGIN value
7d20: 2e 20 20 4e 55 4c 4c 20 66 6f 72 20 75 73 65 72 . NULL for user
7d30: 20 22 6e 6f 62 6f 64 79 22 0a 2a 2a 20 20 20 20 "nobody".**
7d40: 67 2e 70 65 72 6d 20 20 20 20 20 20 20 20 20 50 g.perm P
7d50: 65 72 6d 69 73 73 69 6f 6e 73 20 67 72 61 6e 74 ermissions grant
7d60: 65 64 20 74 6f 20 74 68 69 73 20 75 73 65 72 0a ed to this user.
7d70: 2a 2a 20 20 20 20 67 2e 61 6e 6f 6e 20 20 20 20 ** g.anon
7d80: 20 20 20 20 20 50 65 72 6d 69 73 73 69 6f 6e 73 Permissions
7d90: 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20 61 that would be a
7da0: 76 61 69 6c 61 62 6c 65 20 74 6f 20 61 6e 6f 6e vailable to anon
7db0: 79 6d 6f 75 73 0a 2a 2a 20 20 20 20 67 2e 69 73 ymous.** g.is
7dc0: 48 75 6d 61 6e 20 20 20 20 20 20 54 72 75 65 20 Human True
7dd0: 69 66 20 74 68 65 20 75 73 65 72 20 69 73 20 68 if the user is h
7de0: 75 6d 61 6e 2c 20 6e 6f 74 20 61 20 73 70 69 64 uman, not a spid
7df0: 65 72 20 6f 72 20 72 6f 62 6f 74 0a 2a 2a 0a 2a er or robot.**.*
7e00: 2f 0a 76 6f 69 64 20 6c 6f 67 69 6e 5f 63 68 65 /.void login_che
7e10: 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c 73 28 76 ck_credentials(v
7e20: 6f 69 64 29 7b 0a 20 20 69 6e 74 20 75 69 64 20 oid){. int uid
7e30: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 = 0;
7e40: 20 20 20 20 20 20 2f 2a 20 55 73 65 72 20 69 64 /* User id
7e50: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 */. const char
7e60: 20 2a 7a 43 6f 6f 6b 69 65 3b 20 20 20 20 20 20 *zCookie;
7e70: 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 74 /* Text of t
7e80: 68 65 20 6c 6f 67 69 6e 20 63 6f 6f 6b 69 65 20 he login cookie
7e90: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 */. const char
7ea0: 2a 7a 49 70 41 64 64 72 3b 20 20 20 20 20 20 20 *zIpAddr;
7eb0: 20 20 20 2f 2a 20 52 61 77 20 49 50 20 61 64 64 /* Raw IP add
7ec0: 72 65 73 73 20 6f 66 20 74 68 65 20 72 65 71 75 ress of the requ
7ed0: 65 73 74 6f 72 20 2a 2f 0a 20 20 63 68 61 72 20 estor */. char
7ee0: 2a 7a 52 65 6d 6f 74 65 41 64 64 72 3b 20 20 20 *zRemoteAddr;
7ef0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 62 62 72 /* Abbr
7f00: 65 76 69 61 74 65 64 20 49 50 20 61 64 64 72 65 eviated IP addre
7f10: 73 73 20 6f 66 20 74 68 65 20 72 65 71 75 65 73 ss of the reques
7f20: 74 6f 72 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 tor */. const c
7f30: 68 61 72 20 2a 7a 43 61 70 20 3d 20 30 3b 20 20 har *zCap = 0;
7f40: 20 20 20 20 20 20 20 2f 2a 20 43 61 70 61 62 69 /* Capabi
7f50: 6c 69 74 79 20 73 74 72 69 6e 67 20 2a 2f 0a 20 lity string */.
7f60: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 75 const char *zPu
7f70: 62 6c 69 63 50 61 67 65 73 20 3d 20 30 3b 20 2f blicPages = 0; /
7f80: 2a 20 47 4c 4f 42 20 70 61 74 74 65 72 6e 73 20 * GLOB patterns
7f90: 6f 66 20 70 75 62 6c 69 63 20 70 61 67 65 73 20 of public pages
7fa0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 */. const char
7fb0: 2a 7a 4c 6f 67 69 6e 20 3d 20 30 3b 20 20 20 20 *zLogin = 0;
7fc0: 20 20 20 2f 2a 20 4c 6f 67 69 6e 20 75 73 65 72 /* Login user
7fd0: 20 66 6f 72 20 63 72 65 64 65 6e 74 69 61 6c 73 for credentials
7fe0: 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20 72 */.. /* Only r
7ff0: 75 6e 20 74 68 69 73 20 63 68 65 63 6b 20 6f 6e un this check on
8000: 63 65 2e 20 20 2a 2f 0a 20 20 69 66 28 20 67 2e ce. */. if( g.
8010: 75 73 65 72 55 69 64 21 3d 30 20 29 20 72 65 74 userUid!=0 ) ret
8020: 75 72 6e 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f urn;.. sqlite3_
8030: 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 create_function(
8040: 67 2e 64 62 2c 20 22 63 6f 6e 73 74 61 6e 74 5f g.db, "constant_
8050: 74 69 6d 65 5f 63 6d 70 22 2c 20 32 2c 20 53 51 time_cmp", 2, SQ
8060: 4c 49 54 45 5f 55 54 46 38 2c 20 30 2c 0a 20 20 LITE_UTF8, 0,.
8070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8080: 63 6f 6e 73 74 61 6e 74 5f 74 69 6d 65 5f 63 6d constant_time_cm
8090: 70 5f 66 75 6e 63 74 69 6f 6e 2c 20 30 2c 20 30 p_function, 0, 0
80a0: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 );.. /* If the
80b0: 48 54 54 50 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 HTTP connection
80c0: 69 73 20 63 6f 6d 69 6e 67 20 6f 76 65 72 20 31 is coming over 1
80d0: 32 37 2e 30 2e 30 2e 31 20 61 6e 64 20 69 66 0a 27.0.0.1 and if.
80e0: 20 20 2a 2a 20 6c 6f 63 61 6c 20 6c 6f 67 69 6e ** local login
80f0: 20 69 73 20 64 69 73 61 62 6c 65 64 20 61 6e 64 is disabled and
8100: 20 69 66 20 77 65 20 61 72 65 20 75 73 69 6e 67 if we are using
8110: 20 48 54 54 50 20 61 6e 64 20 6e 6f 74 20 48 54 HTTP and not HT
8120: 54 50 53 2c 0a 20 20 2a 2a 20 74 68 65 6e 20 74 TPS,. ** then t
8130: 68 65 72 65 20 69 73 20 6e 6f 20 6e 65 65 64 20 here is no need
8140: 74 6f 20 63 68 65 63 6b 20 75 73 65 72 20 63 72 to check user cr
8150: 65 64 65 6e 74 69 61 6c 73 2e 0a 20 20 2a 2a 0a edentials.. **.
8160: 20 20 2a 2a 20 54 68 69 73 20 66 65 61 74 75 72 ** This featur
8170: 65 20 61 6c 6c 6f 77 73 20 74 68 65 20 22 66 6f e allows the "fo
8180: 73 73 69 6c 20 75 69 22 20 63 6f 6d 6d 61 6e 64 ssil ui" command
8190: 20 74 6f 20 67 69 76 65 20 74 68 65 20 75 73 65 to give the use
81a0: 72 0a 20 20 2a 2a 20 66 75 6c 6c 20 61 63 63 65 r. ** full acce
81b0: 73 73 20 72 69 67 68 74 73 20 77 69 74 68 6f 75 ss rights withou
81c0: 74 20 68 61 76 69 6e 67 20 74 6f 20 6c 6f 67 20 t having to log
81d0: 69 6e 2e 0a 20 20 2a 2f 0a 20 20 7a 52 65 6d 6f in.. */. zRemo
81e0: 74 65 41 64 64 72 20 3d 20 69 70 50 72 65 66 69 teAddr = ipPrefi
81f0: 78 28 7a 49 70 41 64 64 72 20 3d 20 50 44 28 22 x(zIpAddr = PD("
8200: 52 45 4d 4f 54 45 5f 41 44 44 52 22 2c 22 6e 69 REMOTE_ADDR","ni
8210: 6c 22 29 29 3b 0a 20 20 69 66 28 20 28 20 63 67 l"));. if( ( cg
8220: 69 5f 69 73 5f 6c 6f 6f 70 62 61 63 6b 28 7a 49 i_is_loopback(zI
8230: 70 41 64 64 72 29 0a 20 20 20 20 20 20 20 7c 7c pAddr). ||
8240: 20 28 67 2e 66 53 73 68 43 6c 69 65 6e 74 20 26 (g.fSshClient &
8250: 20 43 47 49 5f 53 53 48 5f 43 4c 49 45 4e 54 29 CGI_SSH_CLIENT)
8260: 21 3d 30 20 29 0a 20 20 20 26 26 20 67 2e 75 73 !=0 ). && g.us
8270: 65 4c 6f 63 61 6c 61 75 74 68 0a 20 20 20 26 26 eLocalauth. &&
8280: 20 64 62 5f 67 65 74 5f 69 6e 74 28 22 6c 6f 63 db_get_int("loc
8290: 61 6c 61 75 74 68 22 2c 30 29 3d 3d 30 0a 20 20 alauth",0)==0.
82a0: 20 26 26 20 50 28 22 48 54 54 50 53 22 29 3d 3d && P("HTTPS")==
82b0: 30 0a 20 20 29 7b 0a 20 20 20 20 69 66 28 20 67 0. ){. if( g
82c0: 2e 6c 6f 63 61 6c 4f 70 65 6e 20 29 20 7a 4c 6f .localOpen ) zLo
82d0: 67 69 6e 20 3d 20 64 62 5f 6c 67 65 74 28 22 64 gin = db_lget("d
82e0: 65 66 61 75 6c 74 2d 75 73 65 72 22 2c 30 29 3b efault-user",0);
82f0: 0a 20 20 20 20 69 66 28 20 7a 4c 6f 67 69 6e 21 . if( zLogin!
8300: 3d 30 20 29 7b 0a 20 20 20 20 20 20 75 69 64 20 =0 ){. uid
8310: 3d 20 64 62 5f 69 6e 74 28 30 2c 20 22 53 45 4c = db_int(0, "SEL
8320: 45 43 54 20 75 69 64 20 46 52 4f 4d 20 75 73 65 ECT uid FROM use
8330: 72 20 57 48 45 52 45 20 6c 6f 67 69 6e 3d 25 51 r WHERE login=%Q
8340: 22 2c 20 7a 4c 6f 67 69 6e 29 3b 0a 20 20 20 20 ", zLogin);.
8350: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 75 69 64 }else{. uid
8360: 20 3d 20 64 62 5f 69 6e 74 28 30 2c 20 22 53 45 = db_int(0, "SE
8370: 4c 45 43 54 20 75 69 64 20 46 52 4f 4d 20 75 73 LECT uid FROM us
8380: 65 72 20 57 48 45 52 45 20 63 61 70 20 4c 49 4b er WHERE cap LIK
8390: 45 20 27 25 25 73 25 25 27 22 29 3b 0a 20 20 20 E '%%s%%'");.
83a0: 20 7d 0a 20 20 20 20 67 2e 7a 4c 6f 67 69 6e 20 }. g.zLogin
83b0: 3d 20 64 62 5f 74 65 78 74 28 22 3f 22 2c 20 22 = db_text("?", "
83c0: 53 45 4c 45 43 54 20 6c 6f 67 69 6e 20 46 52 4f SELECT login FRO
83d0: 4d 20 75 73 65 72 20 57 48 45 52 45 20 75 69 64 M user WHERE uid
83e0: 3d 25 64 22 2c 20 75 69 64 29 3b 0a 20 20 20 20 =%d", uid);.
83f0: 7a 43 61 70 20 3d 20 22 73 78 22 3b 0a 20 20 20 zCap = "sx";.
8400: 20 67 2e 6e 6f 50 73 77 64 20 3d 20 31 3b 0a 20 g.noPswd = 1;.
8410: 20 20 20 67 2e 69 73 48 75 6d 61 6e 20 3d 20 31 g.isHuman = 1
8420: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 6e ;. sqlite3_sn
8430: 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28 67 2e printf(sizeof(g.
8440: 7a 43 73 72 66 54 6f 6b 65 6e 29 2c 20 67 2e 7a zCsrfToken), g.z
8450: 43 73 72 66 54 6f 6b 65 6e 2c 20 22 6c 6f 63 61 CsrfToken, "loca
8460: 6c 68 6f 73 74 22 29 3b 0a 20 20 7d 0a 0a 20 20 lhost");. }..
8470: 2f 2a 20 43 68 65 63 6b 20 74 68 65 20 6c 6f 67 /* Check the log
8480: 69 6e 20 63 6f 6f 6b 69 65 20 74 6f 20 73 65 65 in cookie to see
8490: 20 69 66 20 69 74 20 6d 61 74 63 68 65 73 20 61 if it matches a
84a0: 20 6b 6e 6f 77 6e 20 76 61 6c 69 64 20 75 73 65 known valid use
84b0: 72 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 75 69 r.. */. if( ui
84c0: 64 3d 3d 30 20 26 26 20 28 7a 43 6f 6f 6b 69 65 d==0 && (zCookie
84d0: 20 3d 20 50 28 6c 6f 67 69 6e 5f 63 6f 6f 6b 69 = P(login_cooki
84e0: 65 5f 6e 61 6d 65 28 29 29 29 21 3d 30 20 29 7b e_name()))!=0 ){
84f0: 0a 20 20 20 20 2f 2a 20 50 61 72 73 65 20 74 68 . /* Parse th
8500: 65 20 63 6f 6f 6b 69 65 20 76 61 6c 75 65 20 75 e cookie value u
8510: 70 20 69 6e 74 6f 20 48 41 53 48 2f 41 52 47 2f p into HASH/ARG/
8520: 55 53 45 52 20 2a 2f 0a 20 20 20 20 63 68 61 72 USER */. char
8530: 20 2a 7a 48 61 73 68 20 3d 20 66 6f 73 73 69 6c *zHash = fossil
8540: 5f 73 74 72 64 75 70 28 7a 43 6f 6f 6b 69 65 29 _strdup(zCookie)
8550: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 41 72 67 ;. char *zArg
8560: 20 3d 20 30 3b 0a 20 20 20 20 63 68 61 72 20 2a = 0;. char *
8570: 7a 55 73 65 72 20 3d 20 30 3b 0a 20 20 20 20 69 zUser = 0;. i
8580: 6e 74 20 69 2c 20 63 3b 0a 20 20 20 20 66 6f 72 nt i, c;. for
8590: 28 69 3d 30 3b 20 28 63 20 3d 20 7a 48 61 73 68 (i=0; (c = zHash
85a0: 5b 69 5d 29 21 3d 30 3b 20 69 2b 2b 29 7b 0a 20 [i])!=0; i++){.
85b0: 20 20 20 20 20 69 66 28 20 63 3d 3d 27 2f 27 20 if( c=='/'
85c0: 29 7b 0a 20 20 20 20 20 20 20 20 7a 48 61 73 68 ){. zHash
85d0: 5b 69 2b 2b 5d 20 3d 20 30 3b 0a 20 20 20 20 20 [i++] = 0;.
85e0: 20 20 20 69 66 28 20 7a 41 72 67 3d 3d 30 20 29 if( zArg==0 )
85f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 41 72 67 {. zArg
8600: 20 3d 20 26 7a 48 61 73 68 5b 69 5d 3b 0a 20 20 = &zHash[i];.
8610: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 }else{.
8620: 20 20 20 20 20 20 20 7a 55 73 65 72 20 3d 20 26 zUser = &
8630: 7a 48 61 73 68 5b 69 5d 3b 0a 20 20 20 20 20 20 zHash[i];.
8640: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 break;.
8650: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 }. }.
8660: 20 7d 0a 20 20 20 20 69 66 28 20 7a 55 73 65 72 }. if( zUser
8670: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 ==0 ){. /*
8680: 49 6e 76 61 6c 69 64 20 63 6f 6f 6b 69 65 20 2a Invalid cookie *
8690: 2f 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 /. }else if(
86a0: 66 6f 73 73 69 6c 5f 73 74 72 63 6d 70 28 7a 55 fossil_strcmp(zU
86b0: 73 65 72 2c 20 22 61 6e 6f 6e 79 6d 6f 75 73 22 ser, "anonymous"
86c0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a )==0 ){. /*
86d0: 20 43 6f 6f 6b 69 65 73 20 6f 66 20 74 68 65 20 Cookies of the
86e0: 66 6f 72 6d 20 22 48 41 53 48 2f 54 49 4d 45 2f form "HASH/TIME/
86f0: 61 6e 6f 6e 79 6d 6f 75 73 22 2e 20 20 54 68 65 anonymous". The
8700: 20 54 49 4d 45 20 6d 75 73 74 20 6e 6f 74 20 62 TIME must not b
8710: 65 0a 20 20 20 20 20 20 2a 2a 20 74 6f 6f 20 6f e. ** too o
8720: 6c 64 20 61 6e 64 20 74 68 65 20 73 68 61 31 20 ld and the sha1
8730: 68 61 73 68 20 6f 66 20 54 49 4d 45 2f 49 50 41 hash of TIME/IPA
8740: 44 44 52 2f 53 45 43 52 45 54 20 6d 75 73 74 20 DDR/SECRET must
8750: 6d 61 74 63 68 20 48 41 53 48 2e 0a 20 20 20 20 match HASH..
8760: 20 20 2a 2a 20 53 45 43 52 45 54 20 69 73 20 74 ** SECRET is t
8770: 68 65 20 22 63 61 70 74 63 68 61 2d 73 65 63 72 he "captcha-secr
8780: 65 74 22 20 76 61 6c 75 65 20 69 6e 20 74 68 65 et" value in the
8790: 20 72 65 70 6f 73 69 74 6f 72 79 2e 0a 20 20 20 repository..
87a0: 20 20 20 2a 2f 0a 20 20 20 20 20 20 64 6f 75 62 */. doub
87b0: 6c 65 20 72 54 69 6d 65 20 3d 20 61 74 6f 66 28 le rTime = atof(
87c0: 7a 41 72 67 29 3b 0a 20 20 20 20 20 20 42 6c 6f zArg);. Blo
87d0: 62 20 62 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f b b;. blob_
87e0: 7a 65 72 6f 28 26 62 29 3b 0a 20 20 20 20 20 20 zero(&b);.
87f0: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 62 2c blob_appendf(&b,
8800: 20 22 25 73 2f 25 73 2f 25 73 22 2c 0a 20 20 20 "%s/%s/%s",.
8810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8820: 7a 41 72 67 2c 20 7a 52 65 6d 6f 74 65 41 64 64 zArg, zRemoteAdd
8830: 72 2c 20 64 62 5f 67 65 74 28 22 63 61 70 74 63 r, db_get("captc
8840: 68 61 2d 73 65 63 72 65 74 22 2c 22 22 29 29 3b ha-secret",""));
8850: 0a 20 20 20 20 20 20 73 68 61 31 73 75 6d 5f 62 . sha1sum_b
8860: 6c 6f 62 28 26 62 2c 20 26 62 29 3b 0a 20 20 20 lob(&b, &b);.
8870: 20 20 20 69 66 28 20 66 6f 73 73 69 6c 5f 73 74 if( fossil_st
8880: 72 63 6d 70 28 7a 48 61 73 68 2c 20 62 6c 6f 62 rcmp(zHash, blob
8890: 5f 73 74 72 28 26 62 29 29 3d 3d 30 20 29 7b 0a _str(&b))==0 ){.
88a0: 20 20 20 20 20 20 20 20 75 69 64 20 3d 20 64 62 uid = db
88b0: 5f 69 6e 74 28 30 2c 0a 20 20 20 20 20 20 20 20 _int(0,.
88c0: 20 20 20 20 22 53 45 4c 45 43 54 20 75 69 64 20 "SELECT uid
88d0: 46 52 4f 4d 20 75 73 65 72 20 57 48 45 52 45 20 FROM user WHERE
88e0: 6c 6f 67 69 6e 3d 27 61 6e 6f 6e 79 6d 6f 75 73 login='anonymous
88f0: 27 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 22 '". "
8900: 20 41 4e 44 20 6c 65 6e 67 74 68 28 63 61 70 29 AND length(cap)
8910: 3e 30 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 >0".
8920: 22 20 41 4e 44 20 6c 65 6e 67 74 68 28 70 77 29 " AND length(pw)
8930: 3e 30 22 0a 20 20 20 20 20 20 20 20 20 20 20 20 >0".
8940: 22 20 41 4e 44 20 25 2e 31 37 67 2b 30 2e 32 35 " AND %.17g+0.25
8950: 3e 6a 75 6c 69 61 6e 64 61 79 28 27 6e 6f 77 27 >julianday('now'
8960: 29 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 )",.
8970: 72 54 69 6d 65 0a 20 20 20 20 20 20 20 20 29 3b rTime. );
8980: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62 . }. b
8990: 6c 6f 62 5f 72 65 73 65 74 28 26 62 29 3b 0a 20 lob_reset(&b);.
89a0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
89b0: 2f 2a 20 43 6f 6f 6b 69 65 73 20 6f 66 20 74 68 /* Cookies of th
89c0: 65 20 66 6f 72 6d 20 22 48 41 53 48 2f 43 4f 44 e form "HASH/COD
89d0: 45 2f 55 53 45 52 22 2e 20 20 53 65 61 72 63 68 E/USER". Search
89e0: 20 66 69 72 73 74 20 69 6e 20 74 68 65 0a 20 20 first in the.
89f0: 20 20 20 20 2a 2a 20 6c 6f 63 61 6c 20 75 73 65 ** local use
8a00: 72 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 74 68 r table, then th
8a10: 65 20 75 73 65 72 20 74 61 62 6c 65 20 66 6f 72 e user table for
8a20: 20 70 72 6f 6a 65 63 74 20 43 4f 44 45 20 69 66 project CODE if
8a30: 20 77 65 0a 20 20 20 20 20 20 2a 2a 20 61 72 65 we. ** are
8a40: 20 70 61 72 74 20 6f 66 20 61 20 6c 6f 67 69 6e part of a login
8a50: 2d 67 72 6f 75 70 2e 0a 20 20 20 20 20 20 2a 2f -group.. */
8a60: 0a 20 20 20 20 20 20 75 69 64 20 3d 20 6c 6f 67 . uid = log
8a70: 69 6e 5f 66 69 6e 64 5f 75 73 65 72 28 7a 55 73 in_find_user(zUs
8a80: 65 72 2c 20 7a 48 61 73 68 2c 20 7a 52 65 6d 6f er, zHash, zRemo
8a90: 74 65 41 64 64 72 29 3b 0a 20 20 20 20 20 20 69 teAddr);. i
8aa0: 66 28 20 75 69 64 3d 3d 30 20 26 26 20 6c 6f 67 f( uid==0 && log
8ab0: 69 6e 5f 74 72 61 6e 73 66 65 72 5f 63 72 65 64 in_transfer_cred
8ac0: 65 6e 74 69 61 6c 73 28 7a 55 73 65 72 2c 7a 41 entials(zUser,zA
8ad0: 72 67 2c 7a 48 61 73 68 2c 7a 52 65 6d 6f 74 65 rg,zHash,zRemote
8ae0: 41 64 64 72 29 20 29 7b 0a 20 20 20 20 20 20 20 Addr) ){.
8af0: 20 75 69 64 20 3d 20 6c 6f 67 69 6e 5f 66 69 6e uid = login_fin
8b00: 64 5f 75 73 65 72 28 7a 55 73 65 72 2c 20 7a 48 d_user(zUser, zH
8b10: 61 73 68 2c 20 7a 52 65 6d 6f 74 65 41 64 64 72 ash, zRemoteAddr
8b20: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 75 );. if( u
8b30: 69 64 20 29 20 72 65 63 6f 72 64 5f 6c 6f 67 69 id ) record_logi
8b40: 6e 5f 61 74 74 65 6d 70 74 28 7a 55 73 65 72 2c n_attempt(zUser,
8b50: 20 7a 49 70 41 64 64 72 2c 20 31 29 3b 0a 20 20 zIpAddr, 1);.
8b60: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 }. }.
8b70: 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 sqlite3_snprintf
8b80: 28 73 69 7a 65 6f 66 28 67 2e 7a 43 73 72 66 54 (sizeof(g.zCsrfT
8b90: 6f 6b 65 6e 29 2c 20 67 2e 7a 43 73 72 66 54 6f oken), g.zCsrfTo
8ba0: 6b 65 6e 2c 20 22 25 2e 31 30 73 22 2c 20 7a 48 ken, "%.10s", zH
8bb0: 61 73 68 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 ash);. }.. /*
8bc0: 49 66 20 6e 6f 20 75 73 65 72 20 66 6f 75 6e 64 If no user found
8bd0: 20 61 6e 64 20 74 68 65 20 52 45 4d 4f 54 45 5f and the REMOTE_
8be0: 55 53 45 52 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 USER environment
8bf0: 20 76 61 72 69 61 62 6c 65 20 69 73 20 73 65 74 variable is set
8c00: 2c 0a 20 20 2a 2a 20 74 68 65 6e 20 61 63 63 65 ,. ** then acce
8c10: 70 74 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 pt the value of
8c20: 52 45 4d 4f 54 45 5f 55 53 45 52 20 61 73 20 74 REMOTE_USER as t
8c30: 68 65 20 75 73 65 72 2e 0a 20 20 2a 2f 0a 20 20 he user.. */.
8c40: 69 66 28 20 75 69 64 3d 3d 30 20 29 7b 0a 20 20 if( uid==0 ){.
8c50: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 const char *zR
8c60: 65 6d 6f 74 65 55 73 65 72 20 3d 20 50 28 22 52 emoteUser = P("R
8c70: 45 4d 4f 54 45 5f 55 53 45 52 22 29 3b 0a 20 20 EMOTE_USER");.
8c80: 20 20 69 66 28 20 7a 52 65 6d 6f 74 65 55 73 65 if( zRemoteUse
8c90: 72 20 26 26 20 64 62 5f 67 65 74 5f 62 6f 6f 6c r && db_get_bool
8ca0: 65 61 6e 28 22 72 65 6d 6f 74 65 5f 75 73 65 72 ean("remote_user
8cb0: 5f 6f 6b 22 2c 30 29 20 29 7b 0a 20 20 20 20 20 _ok",0) ){.
8cc0: 20 75 69 64 20 3d 20 64 62 5f 69 6e 74 28 30 2c uid = db_int(0,
8cd0: 20 22 53 45 4c 45 43 54 20 75 69 64 20 46 52 4f "SELECT uid FRO
8ce0: 4d 20 75 73 65 72 20 57 48 45 52 45 20 6c 6f 67 M user WHERE log
8cf0: 69 6e 3d 25 51 22 0a 20 20 20 20 20 20 20 20 20 in=%Q".
8d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 22 20 41 " A
8d10: 4e 44 20 6c 65 6e 67 74 68 28 63 61 70 29 3e 30 ND length(cap)>0
8d20: 20 41 4e 44 20 6c 65 6e 67 74 68 28 70 77 29 3e AND length(pw)>
8d30: 30 22 2c 20 7a 52 65 6d 6f 74 65 55 73 65 72 29 0", zRemoteUser)
8d40: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f ;. }. }.. /
8d50: 2a 20 49 66 20 74 68 65 20 72 65 71 75 65 73 74 * If the request
8d60: 20 64 69 64 6e 27 74 20 70 72 6f 76 69 64 65 20 didn't provide
8d70: 61 20 6c 6f 67 69 6e 20 63 6f 6f 6b 69 65 20 6f a login cookie o
8d80: 72 20 74 68 65 20 6c 6f 67 69 6e 20 63 6f 6f 6b r the login cook
8d90: 69 65 20 64 69 64 6e 27 74 0a 20 20 2a 2a 20 6d ie didn't. ** m
8da0: 61 74 63 68 20 61 20 6b 6e 6f 77 6e 20 76 61 6c atch a known val
8db0: 69 64 20 75 73 65 72 2c 20 63 68 65 63 6b 20 74 id user, check t
8dc0: 68 65 20 48 54 54 50 20 22 41 75 74 68 6f 72 69 he HTTP "Authori
8dd0: 7a 61 74 69 6f 6e 22 20 68 65 61 64 65 72 20 61 zation" header a
8de0: 6e 64 0a 20 20 2a 2a 20 73 65 65 20 69 66 20 74 nd. ** see if t
8df0: 68 6f 73 65 20 63 72 65 64 65 6e 74 69 61 6c 73 hose credentials
8e00: 20 61 72 65 20 76 61 6c 69 64 20 66 6f 72 20 61 are valid for a
8e10: 20 6b 6e 6f 77 6e 20 75 73 65 72 2e 0a 20 20 2a known user.. *
8e20: 2f 0a 20 20 69 66 28 20 75 69 64 3d 3d 30 20 26 /. if( uid==0 &
8e30: 26 20 64 62 5f 67 65 74 5f 62 6f 6f 6c 65 61 6e & db_get_boolean
8e40: 28 22 68 74 74 70 5f 61 75 74 68 65 6e 74 69 63 ("http_authentic
8e50: 61 74 69 6f 6e 5f 6f 6b 22 2c 30 29 20 29 7b 0a ation_ok",0) ){.
8e60: 20 20 20 20 75 69 64 20 3d 20 6c 6f 67 69 63 5f uid = logic_
8e70: 62 61 73 69 63 5f 61 75 74 68 65 6e 74 69 63 61 basic_authentica
8e80: 74 69 6f 6e 28 7a 49 70 41 64 64 72 29 3b 0a 20 tion(zIpAddr);.
8e90: 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 75 }.. /* If no u
8ea0: 73 65 72 20 66 6f 75 6e 64 20 79 65 74 2c 20 74 ser found yet, t
8eb0: 72 79 20 74 6f 20 6c 6f 67 20 69 6e 20 61 73 20 ry to log in as
8ec0: 22 6e 6f 62 6f 64 79 22 20 2a 2f 0a 20 20 69 66 "nobody" */. if
8ed0: 28 20 75 69 64 3d 3d 30 20 29 7b 0a 20 20 20 20 ( uid==0 ){.
8ee0: 75 69 64 20 3d 20 64 62 5f 69 6e 74 28 30 2c 20 uid = db_int(0,
8ef0: 22 53 45 4c 45 43 54 20 75 69 64 20 46 52 4f 4d "SELECT uid FROM
8f00: 20 75 73 65 72 20 57 48 45 52 45 20 6c 6f 67 69 user WHERE logi
8f10: 6e 3d 27 6e 6f 62 6f 64 79 27 22 29 3b 0a 20 20 n='nobody'");.
8f20: 20 20 69 66 28 20 75 69 64 3d 3d 30 20 29 7b 0a if( uid==0 ){.
8f30: 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72 /* If ther
8f40: 65 20 69 73 20 6e 6f 20 75 73 65 72 20 22 6e 6f e is no user "no
8f50: 62 6f 64 79 22 2c 20 74 68 65 6e 20 6d 61 6b 65 body", then make
8f60: 20 6f 6e 65 20 75 70 20 2d 20 77 69 74 68 20 6e one up - with n
8f70: 6f 20 70 72 69 76 69 6c 65 67 65 73 20 2a 2f 0a o privileges */.
8f80: 20 20 20 20 20 20 75 69 64 20 3d 20 2d 31 3b 0a uid = -1;.
8f90: 20 20 20 20 20 20 7a 43 61 70 20 3d 20 22 22 3b zCap = "";
8fa0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 . }. sqlit
8fb0: 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 e3_snprintf(size
8fc0: 6f 66 28 67 2e 7a 43 73 72 66 54 6f 6b 65 6e 29 of(g.zCsrfToken)
8fd0: 2c 20 67 2e 7a 43 73 72 66 54 6f 6b 65 6e 2c 20 , g.zCsrfToken,
8fe0: 22 6e 6f 6e 65 22 29 3b 0a 20 20 7d 0a 0a 20 20 "none");. }..
8ff0: 2f 2a 20 41 74 20 74 68 69 73 20 70 6f 69 6e 74 /* At this point
9000: 2c 20 77 65 20 6b 6e 6f 77 20 74 68 61 74 20 75 , we know that u
9010: 69 64 21 3d 30 2e 20 20 46 69 6e 64 20 74 68 65 id!=0. Find the
9020: 20 70 72 69 76 69 6c 65 67 65 73 20 61 73 73 6f privileges asso
9030: 63 69 61 74 65 64 0a 20 20 2a 2a 20 77 69 74 68 ciated. ** with
9040: 20 75 73 65 72 20 75 69 64 2e 0a 20 20 2a 2f 0a user uid.. */.
9050: 20 20 61 73 73 65 72 74 28 20 75 69 64 21 3d 30 assert( uid!=0
9060: 20 29 3b 0a 20 20 69 66 28 20 7a 43 61 70 3d 3d );. if( zCap==
9070: 30 20 29 7b 0a 20 20 20 20 53 74 6d 74 20 73 3b 0 ){. Stmt s;
9080: 0a 20 20 20 20 64 62 5f 70 72 65 70 61 72 65 28 . db_prepare(
9090: 26 73 2c 20 22 53 45 4c 45 43 54 20 6c 6f 67 69 &s, "SELECT logi
90a0: 6e 2c 20 63 61 70 20 46 52 4f 4d 20 75 73 65 72 n, cap FROM user
90b0: 20 57 48 45 52 45 20 75 69 64 3d 25 64 22 2c 20 WHERE uid=%d",
90c0: 75 69 64 29 3b 0a 20 20 20 20 69 66 28 20 64 62 uid);. if( db
90d0: 5f 73 74 65 70 28 26 73 29 3d 3d 53 51 4c 49 54 _step(&s)==SQLIT
90e0: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 67 E_ROW ){. g
90f0: 2e 7a 4c 6f 67 69 6e 20 3d 20 64 62 5f 63 6f 6c .zLogin = db_col
9100: 75 6d 6e 5f 6d 61 6c 6c 6f 63 28 26 73 2c 20 30 umn_malloc(&s, 0
9110: 29 3b 0a 20 20 20 20 20 20 7a 43 61 70 20 3d 20 );. zCap =
9120: 64 62 5f 63 6f 6c 75 6d 6e 5f 6d 61 6c 6c 6f 63 db_column_malloc
9130: 28 26 73 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 (&s, 1);. }.
9140: 20 20 20 64 62 5f 66 69 6e 61 6c 69 7a 65 28 26 db_finalize(&
9150: 73 29 3b 0a 20 20 20 20 69 66 28 20 7a 43 61 70 s);. if( zCap
9160: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 7a 43 61 ==0 ){. zCa
9170: 70 20 3d 20 22 22 3b 0a 20 20 20 20 7d 0a 20 20 p = "";. }.
9180: 7d 0a 20 20 69 66 28 20 67 2e 66 48 74 74 70 54 }. if( g.fHttpT
9190: 72 61 63 65 20 26 26 20 67 2e 7a 4c 6f 67 69 6e race && g.zLogin
91a0: 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 ){. fprintf(
91b0: 73 74 64 65 72 72 2c 20 22 23 20 6c 6f 67 69 6e stderr, "# login
91c0: 3a 20 5b 25 73 5d 20 77 69 74 68 20 63 61 70 61 : [%s] with capa
91d0: 62 69 6c 69 74 69 65 73 20 5b 25 73 5d 5c 6e 22 bilities [%s]\n"
91e0: 2c 20 67 2e 7a 4c 6f 67 69 6e 2c 20 7a 43 61 70 , g.zLogin, zCap
91f0: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 74 );. }.. /* Set
9200: 20 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72 69 the global vari
9210: 61 62 6c 65 73 20 72 65 63 6f 72 64 69 6e 67 20 ables recording
9220: 74 68 65 20 75 73 65 72 69 64 20 61 6e 64 20 6c the userid and l
9230: 6f 67 69 6e 2e 20 20 54 68 65 0a 20 20 2a 2a 20 ogin. The. **
9240: 22 6e 6f 62 6f 64 79 22 20 75 73 65 72 20 69 73 "nobody" user is
9250: 20 61 20 73 70 65 63 69 61 6c 20 63 61 73 65 20 a special case
9260: 69 6e 20 74 68 61 74 20 67 2e 7a 4c 6f 67 69 6e in that g.zLogin
9270: 3d 3d 30 2e 0a 20 20 2a 2f 0a 20 20 67 2e 75 73 ==0.. */. g.us
9280: 65 72 55 69 64 20 3d 20 75 69 64 3b 0a 20 20 69 erUid = uid;. i
9290: 66 28 20 66 6f 73 73 69 6c 5f 73 74 72 63 6d 70 f( fossil_strcmp
92a0: 28 67 2e 7a 4c 6f 67 69 6e 2c 22 6e 6f 62 6f 64 (g.zLogin,"nobod
92b0: 79 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 67 2e y")==0 ){. g.
92c0: 7a 4c 6f 67 69 6e 20 3d 20 30 3b 0a 20 20 7d 0a zLogin = 0;. }.
92d0: 20 20 69 66 28 20 50 42 28 22 69 73 72 6f 62 6f if( PB("isrobo
92e0: 74 22 29 20 29 7b 0a 20 20 20 20 67 2e 69 73 48 t") ){. g.isH
92f0: 75 6d 61 6e 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 uman = 0;. }els
9300: 65 20 69 66 28 20 67 2e 7a 4c 6f 67 69 6e 3d 3d e if( g.zLogin==
9310: 30 20 29 7b 0a 20 20 20 20 67 2e 69 73 48 75 6d 0 ){. g.isHum
9320: 61 6e 20 3d 20 69 73 48 75 6d 61 6e 28 50 28 22 an = isHuman(P("
9330: 48 54 54 50 5f 55 53 45 52 5f 41 47 45 4e 54 22 HTTP_USER_AGENT"
9340: 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 ));. }else{.
9350: 20 67 2e 69 73 48 75 6d 61 6e 20 3d 20 31 3b 0a g.isHuman = 1;.
9360: 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 74 20 74 68 }.. /* Set th
9370: 65 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 2a e capabilities *
9380: 2f 0a 20 20 6c 6f 67 69 6e 5f 72 65 70 6c 61 63 /. login_replac
9390: 65 5f 63 61 70 61 62 69 6c 69 74 69 65 73 28 7a e_capabilities(z
93a0: 43 61 70 2c 20 30 29 3b 0a 0a 20 20 2f 2a 20 54 Cap, 0);.. /* T
93b0: 68 65 20 61 75 74 6f 2d 68 79 70 65 72 6c 69 6e he auto-hyperlin
93c0: 6b 20 73 65 74 74 69 6e 67 20 61 6c 6c 6f 77 73 k setting allows
93d0: 20 68 79 70 65 72 6c 69 6e 6b 73 20 74 6f 20 62 hyperlinks to b
93e0: 65 20 64 69 73 70 6c 61 79 65 64 20 66 6f 72 20 e displayed for
93f0: 75 73 65 72 73 0a 20 20 2a 2a 20 77 68 6f 20 64 users. ** who d
9400: 6f 20 6e 6f 74 20 68 61 76 65 20 74 68 65 20 22 o not have the "
9410: 68 22 20 70 65 72 6d 69 73 73 69 6f 6e 20 61 73 h" permission as
9420: 20 6c 6f 6e 67 20 61 73 20 74 68 65 69 72 20 55 long as their U
9430: 73 65 72 41 67 65 6e 74 20 73 74 72 69 6e 67 0a serAgent string.
9440: 20 20 2a 2a 20 6d 61 6b 65 73 20 69 74 20 61 70 ** makes it ap
9450: 70 65 61 72 20 74 68 61 74 20 74 68 65 79 20 61 pear that they a
9460: 72 65 20 68 75 6d 61 6e 2e 20 20 43 68 65 63 6b re human. Check
9470: 20 74 6f 20 73 65 65 20 69 66 20 61 75 74 6f 2d to see if auto-
9480: 68 79 70 65 72 6c 69 6e 6b 20 69 73 0a 20 20 2a hyperlink is. *
9490: 2a 20 65 6e 61 62 6c 65 64 20 66 6f 72 20 74 68 * enabled for th
94a0: 69 73 20 72 65 70 6f 73 69 74 6f 72 79 20 61 6e is repository an
94b0: 64 20 6d 61 6b 65 20 61 70 70 72 6f 70 72 69 61 d make appropria
94c0: 74 65 20 61 64 6a 75 73 74 6d 65 6e 74 73 20 74 te adjustments t
94d0: 6f 20 74 68 65 0a 20 20 2a 2a 20 70 65 72 6d 69 o the. ** permi
94e0: 73 73 69 6f 6e 20 66 6c 61 67 73 20 69 66 20 69 ssion flags if i
94f0: 74 20 69 73 2e 20 20 54 68 69 73 20 73 68 6f 75 t is. This shou
9500: 6c 64 20 62 65 20 64 6f 6e 65 20 62 65 66 6f 72 ld be done befor
9510: 65 20 74 68 65 20 70 65 72 6d 69 73 73 69 6f 6e e the permission
9520: 73 0a 20 20 2a 2a 20 61 72 65 20 28 70 6f 74 65 s. ** are (pote
9530: 6e 74 69 61 6c 6c 79 29 20 63 6f 70 69 65 64 20 ntially) copied
9540: 74 6f 20 74 68 65 20 61 6e 6f 6e 79 6d 6f 75 73 to the anonymous
9550: 20 70 65 72 6d 69 73 73 69 6f 6e 20 73 65 74 3b permission set;
9560: 20 6f 74 68 65 72 77 69 73 65 2c 0a 20 20 2a 2a otherwise,. **
9570: 20 74 68 6f 73 65 20 77 69 6c 6c 20 62 65 20 6f those will be o
9580: 75 74 2d 6f 66 2d 73 79 6e 63 2e 0a 20 20 2a 2f ut-of-sync.. */
9590: 0a 20 20 69 66 28 20 7a 43 61 70 5b 30 5d 0a 20 . if( zCap[0].
95a0: 20 20 26 26 20 21 67 2e 70 65 72 6d 2e 48 79 70 && !g.perm.Hyp
95b0: 65 72 6c 69 6e 6b 0a 20 20 20 26 26 20 67 2e 69 erlink. && g.i
95c0: 73 48 75 6d 61 6e 0a 20 20 20 26 26 20 64 62 5f sHuman. && db_
95d0: 67 65 74 5f 62 6f 6f 6c 65 61 6e 28 22 61 75 74 get_boolean("aut
95e0: 6f 2d 68 79 70 65 72 6c 69 6e 6b 22 2c 31 29 0a o-hyperlink",1).
95f0: 20 20 29 7b 0a 20 20 20 20 67 2e 70 65 72 6d 2e ){. g.perm.
9600: 48 79 70 65 72 6c 69 6e 6b 20 3d 20 31 3b 0a 20 Hyperlink = 1;.
9610: 20 20 20 67 2e 6a 61 76 61 73 63 72 69 70 74 48 g.javascriptH
9620: 79 70 65 72 6c 69 6e 6b 20 3d 20 31 3b 0a 20 20 yperlink = 1;.
9630: 7d 0a 0a 20 20 2f 2a 0a 20 20 2a 2a 20 41 74 20 }.. /*. ** At
9640: 74 68 69 73 20 70 6f 69 6e 74 2c 20 74 68 65 20 this point, the
9650: 63 61 70 61 62 69 6c 69 74 69 65 73 20 66 6f 72 capabilities for
9660: 20 74 68 65 20 6c 6f 67 67 65 64 20 69 6e 20 75 the logged in u
9670: 73 65 72 20 61 72 65 20 6e 6f 74 20 67 6f 69 6e ser are not goin
9680: 67 0a 20 20 2a 2a 20 74 6f 20 62 65 20 6d 6f 64 g. ** to be mod
9690: 69 66 69 65 64 20 61 6e 79 6d 6f 72 65 3b 20 74 ified anymore; t
96a0: 68 65 72 65 66 6f 72 65 2c 20 77 65 20 63 61 6e herefore, we can
96b0: 20 63 6f 70 79 20 74 68 65 6d 20 6f 76 65 72 20 copy them over
96c0: 74 6f 20 74 68 65 20 6f 6e 65 73 0a 20 20 2a 2a to the ones. **
96d0: 20 66 6f 72 20 74 68 65 20 61 6e 6f 6e 79 6d 6f for the anonymo
96e0: 75 73 20 75 73 65 72 2e 0a 20 20 2a 2a 0a 20 20 us user.. **.
96f0: 2a 2a 20 57 41 52 4e 49 4e 47 3a 20 49 6e 20 74 ** WARNING: In t
9700: 68 65 20 66 75 74 75 72 65 2c 20 70 6c 65 61 73 he future, pleas
9710: 65 20 64 6f 20 6e 6f 74 20 61 64 64 20 63 6f 64 e do not add cod
9720: 65 20 61 66 74 65 72 20 74 68 69 73 20 70 6f 69 e after this poi
9730: 6e 74 20 74 68 61 74 0a 20 20 2a 2a 20 20 20 20 nt that. **
9740: 20 20 20 20 20 20 6d 6f 64 69 66 69 65 73 20 74 modifies t
9750: 68 65 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 he capabilities
9760: 66 6f 72 20 74 68 65 20 6c 6f 67 67 65 64 20 69 for the logged i
9770: 6e 20 75 73 65 72 2e 0a 20 20 2a 2f 0a 20 20 6c n user.. */. l
9780: 6f 67 69 6e 5f 73 65 74 5f 61 6e 6f 6e 5f 6e 6f ogin_set_anon_no
9790: 62 6f 64 79 5f 63 61 70 61 62 69 6c 69 74 69 65 body_capabilitie
97a0: 73 28 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 s();.. /* If th
97b0: 65 20 70 75 62 6c 69 63 2d 70 61 67 65 73 20 67 e public-pages g
97c0: 6c 6f 62 20 70 61 74 74 65 72 6e 20 69 73 20 64 lob pattern is d
97d0: 65 66 69 6e 65 64 20 61 6e 64 20 52 45 51 55 45 efined and REQUE
97e0: 53 54 5f 55 52 49 20 6d 61 74 63 68 65 73 0a 20 ST_URI matches.
97f0: 20 2a 2a 20 6f 6e 65 20 6f 66 20 74 68 65 20 67 ** one of the g
9800: 6c 6f 62 73 20 69 6e 20 70 75 62 6c 69 63 2d 70 lobs in public-p
9810: 61 67 65 73 2c 20 74 68 65 6e 20 61 6c 73 6f 20 ages, then also
9820: 61 64 64 20 69 6e 20 61 6c 6c 20 64 65 66 61 75 add in all defau
9830: 6c 74 2d 70 65 72 6d 73 0a 20 20 2a 2a 20 70 65 lt-perms. ** pe
9840: 72 6d 69 73 73 69 6f 6e 73 2e 0a 20 20 2a 2f 0a rmissions.. */.
9850: 20 20 7a 50 75 62 6c 69 63 50 61 67 65 73 20 3d zPublicPages =
9860: 20 64 62 5f 67 65 74 28 22 70 75 62 6c 69 63 2d db_get("public-
9870: 70 61 67 65 73 22 2c 30 29 3b 0a 20 20 69 66 28 pages",0);. if(
9880: 20 7a 50 75 62 6c 69 63 50 61 67 65 73 21 3d 30 zPublicPages!=0
9890: 20 29 7b 0a 20 20 20 20 47 6c 6f 62 20 2a 70 47 ){. Glob *pG
98a0: 6c 6f 62 20 3d 20 67 6c 6f 62 5f 63 72 65 61 74 lob = glob_creat
98b0: 65 28 7a 50 75 62 6c 69 63 50 61 67 65 73 29 3b e(zPublicPages);
98c0: 0a 20 20 20 20 69 66 28 20 67 6c 6f 62 5f 6d 61 . if( glob_ma
98d0: 74 63 68 28 70 47 6c 6f 62 2c 20 50 44 28 22 52 tch(pGlob, PD("R
98e0: 45 51 55 45 53 54 5f 55 52 49 22 2c 22 6e 6f 2d EQUEST_URI","no-
98f0: 6d 61 74 63 68 22 29 29 20 29 7b 0a 20 20 20 20 match")) ){.
9900: 20 20 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70 61 login_set_capa
9910: 62 69 6c 69 74 69 65 73 28 64 62 5f 67 65 74 28 bilities(db_get(
9920: 22 64 65 66 61 75 6c 74 2d 70 65 72 6d 73 22 2c "default-perms",
9930: 22 75 22 29 2c 20 30 29 3b 0a 20 20 20 20 7d 0a "u"), 0);. }.
9940: 20 20 20 20 67 6c 6f 62 5f 66 72 65 65 28 70 47 glob_free(pG
9950: 6c 6f 62 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a lob);. }.}../*.
9960: 2a 2a 20 4d 65 6d 6f 72 79 20 6f 66 20 73 65 74 ** Memory of set
9970: 74 69 6e 67 73 0a 2a 2f 0a 73 74 61 74 69 63 20 tings.*/.static
9980: 69 6e 74 20 6c 6f 67 69 6e 5f 61 6e 6f 6e 5f 6f int login_anon_o
9990: 6e 63 65 20 3d 20 31 3b 0a 0a 2f 2a 0a 2a 2a 20 nce = 1;../*.**
99a0: 41 64 64 20 74 6f 20 67 2e 70 65 72 6d 20 74 68 Add to g.perm th
99b0: 65 20 64 65 66 61 75 6c 74 20 70 72 69 76 69 6c e default privil
99c0: 65 67 65 73 20 6f 66 20 75 73 65 72 73 20 22 6e eges of users "n
99d0: 6f 62 6f 64 79 22 20 61 6e 64 2f 6f 72 20 22 61 obody" and/or "a
99e0: 6e 6f 6e 79 6d 6f 75 73 22 0a 2a 2a 20 61 73 20 nonymous".** as
99f0: 61 70 70 72 6f 70 72 69 61 74 65 20 66 6f 72 20 appropriate for
9a00: 74 68 65 20 75 73 65 72 20 67 2e 7a 4c 6f 67 69 the user g.zLogi
9a10: 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f n..**.** This ro
9a20: 75 74 69 6e 65 20 61 6c 73 6f 20 73 65 74 73 20 utine also sets
9a30: 75 70 20 67 2e 61 6e 6f 6e 20 74 6f 20 62 65 20 up g.anon to be
9a40: 65 69 74 68 65 72 20 61 20 63 6f 70 79 20 6f 66 either a copy of
9a50: 20 67 2e 70 65 72 6d 20 66 6f 72 0a 2a 2a 20 61 g.perm for.** a
9a60: 6c 6c 20 6c 6f 67 67 65 64 20 69 6e 20 75 73 65 ll logged in use
9a70: 73 2c 20 6f 72 20 74 68 65 20 70 72 69 76 69 6c s, or the privil
9a80: 65 67 65 73 20 74 68 61 74 20 77 6f 75 6c 64 20 eges that would
9a90: 62 65 20 61 76 61 69 6c 61 62 6c 65 20 74 6f 20 be available to
9aa0: 22 61 6e 6f 6e 79 6d 6f 75 73 22 0a 2a 2a 20 69 "anonymous".** i
9ab0: 66 20 67 2e 7a 4c 6f 67 69 6e 3d 3d 30 20 28 6d f g.zLogin==0 (m
9ac0: 65 61 6e 69 6e 67 20 74 68 61 74 20 74 68 65 20 eaning that the
9ad0: 75 73 65 72 20 69 73 20 22 6e 6f 62 6f 64 79 22 user is "nobody"
9ae0: 29 2e 0a 2a 2f 0a 76 6f 69 64 20 6c 6f 67 69 6e )..*/.void login
9af0: 5f 73 65 74 5f 61 6e 6f 6e 5f 6e 6f 62 6f 64 79 _set_anon_nobody
9b00: 5f 63 61 70 61 62 69 6c 69 74 69 65 73 28 76 6f _capabilities(vo
9b10: 69 64 29 7b 0a 20 20 69 66 28 20 6c 6f 67 69 6e id){. if( login
9b20: 5f 61 6e 6f 6e 5f 6f 6e 63 65 20 29 7b 0a 20 20 _anon_once ){.
9b30: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 const char *zC
9b40: 61 70 3b 0a 20 20 20 20 2f 2a 20 41 6c 6c 20 75 ap;. /* All u
9b50: 73 65 72 73 20 67 65 74 20 70 72 69 76 69 6c 65 sers get privile
9b60: 67 65 73 20 66 72 6f 6d 20 22 6e 6f 62 6f 64 79 ges from "nobody
9b70: 22 20 2a 2f 0a 20 20 20 20 7a 43 61 70 20 3d 20 " */. zCap =
9b80: 64 62 5f 74 65 78 74 28 22 22 2c 20 22 53 45 4c db_text("", "SEL
9b90: 45 43 54 20 63 61 70 20 46 52 4f 4d 20 75 73 65 ECT cap FROM use
9ba0: 72 20 57 48 45 52 45 20 6c 6f 67 69 6e 20 3d 20 r WHERE login =
9bb0: 27 6e 6f 62 6f 64 79 27 22 29 3b 0a 20 20 20 20 'nobody'");.
9bc0: 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70 61 62 69 login_set_capabi
9bd0: 6c 69 74 69 65 73 28 7a 43 61 70 2c 20 30 29 3b lities(zCap, 0);
9be0: 0a 20 20 20 20 7a 43 61 70 20 3d 20 64 62 5f 74 . zCap = db_t
9bf0: 65 78 74 28 22 22 2c 20 22 53 45 4c 45 43 54 20 ext("", "SELECT
9c00: 63 61 70 20 46 52 4f 4d 20 75 73 65 72 20 57 48 cap FROM user WH
9c10: 45 52 45 20 6c 6f 67 69 6e 20 3d 20 27 61 6e 6f ERE login = 'ano
9c20: 6e 79 6d 6f 75 73 27 22 29 3b 0a 20 20 20 20 69 nymous'");. i
9c30: 66 28 20 67 2e 7a 4c 6f 67 69 6e 20 26 26 20 66 f( g.zLogin && f
9c40: 6f 73 73 69 6c 5f 73 74 72 63 6d 70 28 67 2e 7a ossil_strcmp(g.z
9c50: 4c 6f 67 69 6e 2c 20 22 6e 6f 62 6f 64 79 22 29 Login, "nobody")
9c60: 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 !=0 ){. /*
9c70: 41 6c 6c 20 6c 6f 67 67 65 64 2d 69 6e 20 75 73 All logged-in us
9c80: 65 72 73 20 69 6e 68 65 72 69 74 20 70 72 69 76 ers inherit priv
9c90: 69 6c 65 67 65 73 20 66 72 6f 6d 20 22 61 6e 6f ileges from "ano
9ca0: 6e 79 6d 6f 75 73 22 20 2a 2f 0a 20 20 20 20 20 nymous" */.
9cb0: 20 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70 61 62 login_set_capab
9cc0: 69 6c 69 74 69 65 73 28 7a 43 61 70 2c 20 30 29 ilities(zCap, 0)
9cd0: 3b 0a 20 20 20 20 20 20 67 2e 61 6e 6f 6e 20 3d ;. g.anon =
9ce0: 20 67 2e 70 65 72 6d 3b 0a 20 20 20 20 7d 65 6c g.perm;. }el
9cf0: 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 52 65 63 se{. /* Rec
9d00: 6f 72 64 20 74 68 65 20 70 72 69 76 69 6c 65 67 ord the privileg
9d10: 65 73 20 6f 66 20 61 6e 6f 6e 79 6d 6f 75 73 20 es of anonymous
9d20: 69 6e 20 67 2e 61 6e 6f 6e 20 2a 2f 0a 20 20 20 in g.anon */.
9d30: 20 20 20 67 2e 61 6e 6f 6e 20 3d 20 67 2e 70 65 g.anon = g.pe
9d40: 72 6d 3b 0a 20 20 20 20 20 20 6c 6f 67 69 6e 5f rm;. login_
9d50: 73 65 74 5f 63 61 70 61 62 69 6c 69 74 69 65 73 set_capabilities
9d60: 28 7a 43 61 70 2c 20 4c 4f 47 49 4e 5f 41 4e 4f (zCap, LOGIN_ANO
9d70: 4e 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6c 6f N);. }. lo
9d80: 67 69 6e 5f 61 6e 6f 6e 5f 6f 6e 63 65 20 3d 20 gin_anon_once =
9d90: 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 0;. }.}../*.**
9da0: 46 6c 61 67 73 20 70 61 73 73 65 64 20 69 6e 74 Flags passed int
9db0: 6f 20 74 68 65 20 32 6e 64 20 61 72 67 75 6d 65 o the 2nd argume
9dc0: 6e 74 20 6f 66 20 6c 6f 67 69 6e 5f 73 65 74 2f nt of login_set/
9dd0: 72 65 70 6c 61 63 65 5f 63 61 70 61 62 69 6c 69 replace_capabili
9de0: 74 69 65 73 28 29 2e 0a 2a 2f 0a 23 69 66 20 49 ties()..*/.#if I
9df0: 4e 54 45 52 46 41 43 45 0a 23 64 65 66 69 6e 65 NTERFACE.#define
9e00: 20 4c 4f 47 49 4e 5f 49 47 4e 4f 52 45 5f 55 56 LOGIN_IGNORE_UV
9e10: 20 20 30 78 30 31 20 20 20 20 20 20 20 20 20 2f 0x01 /
9e20: 2a 20 49 67 6e 6f 72 65 20 22 75 22 20 61 6e 64 * Ignore "u" and
9e30: 20 22 76 22 20 2a 2f 0a 23 64 65 66 69 6e 65 20 "v" */.#define
9e40: 4c 4f 47 49 4e 5f 41 4e 4f 4e 20 20 20 20 20 20 LOGIN_ANON
9e50: 20 30 78 30 32 20 20 20 20 20 20 20 20 20 2f 2a 0x02 /*
9e60: 20 55 73 65 20 67 2e 61 6e 6f 6e 20 69 6e 73 74 Use g.anon inst
9e70: 65 61 64 20 6f 66 20 67 2e 70 65 72 6d 20 2a 2f ead of g.perm */
9e80: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 .#endif../*.** A
9e90: 64 64 73 20 61 6c 6c 20 63 61 70 61 62 69 6c 69 dds all capabili
9ea0: 74 79 20 66 6c 61 67 73 20 69 6e 20 7a 43 61 70 ty flags in zCap
9eb0: 20 74 6f 20 67 2e 70 65 72 6d 20 6f 72 20 67 2e to g.perm or g.
9ec0: 61 6e 6f 6e 2e 0a 2a 2f 0a 76 6f 69 64 20 6c 6f anon..*/.void lo
9ed0: 67 69 6e 5f 73 65 74 5f 63 61 70 61 62 69 6c 69 gin_set_capabili
9ee0: 74 69 65 73 28 63 6f 6e 73 74 20 63 68 61 72 20 ties(const char
9ef0: 2a 7a 43 61 70 2c 20 75 6e 73 69 67 6e 65 64 20 *zCap, unsigned
9f00: 66 6c 61 67 73 29 7b 0a 20 20 69 6e 74 20 69 3b flags){. int i;
9f10: 0a 20 20 46 6f 73 73 69 6c 55 73 65 72 50 65 72 . FossilUserPer
9f20: 6d 73 20 2a 70 20 3d 20 28 66 6c 61 67 73 20 26 ms *p = (flags &
9f30: 20 4c 4f 47 49 4e 5f 41 4e 4f 4e 29 20 3f 20 26 LOGIN_ANON) ? &
9f40: 67 2e 61 6e 6f 6e 20 3a 20 26 67 2e 70 65 72 6d g.anon : &g.perm
9f50: 3b 0a 20 20 69 66 28 4e 55 4c 4c 3d 3d 7a 43 61 ;. if(NULL==zCa
9f60: 70 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a p){. return;.
9f70: 20 20 7d 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a }. for(i=0; z
9f80: 43 61 70 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 Cap[i]; i++){.
9f90: 20 20 73 77 69 74 63 68 28 20 7a 43 61 70 5b 69 switch( zCap[i
9fa0: 5d 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20 ] ){. case
9fb0: 27 73 27 3a 20 20 20 70 2d 3e 53 65 74 75 70 20 's': p->Setup
9fc0: 3d 20 31 3b 20 2f 2a 20 46 61 6c 6c 20 74 68 72 = 1; /* Fall thr
9fd0: 75 20 69 6e 74 6f 20 41 64 6d 69 6e 20 2a 2f 0a u into Admin */.
9fe0: 20 20 20 20 20 20 63 61 73 65 20 27 61 27 3a 20 case 'a':
9ff0: 20 20 70 2d 3e 41 64 6d 69 6e 20 3d 20 70 2d 3e p->Admin = p->
a000: 52 64 54 6b 74 20 3d 20 70 2d 3e 57 72 54 6b 74 RdTkt = p->WrTkt
a010: 20 3d 20 70 2d 3e 5a 69 70 20 3d 0a 20 20 20 20 = p->Zip =.
a020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a030: 20 20 20 20 20 20 20 20 20 70 2d 3e 52 64 57 69 p->RdWi
a040: 6b 69 20 3d 20 70 2d 3e 57 72 57 69 6b 69 20 3d ki = p->WrWiki =
a050: 20 70 2d 3e 4e 65 77 57 69 6b 69 20 3d 0a 20 20 p->NewWiki =.
a060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a070: 20 20 20 20 20 20 20 20 20 20 20 70 2d 3e 41 70 p->Ap
a080: 6e 64 57 69 6b 69 20 3d 20 70 2d 3e 48 79 70 65 ndWiki = p->Hype
a090: 72 6c 69 6e 6b 20 3d 20 70 2d 3e 43 6c 6f 6e 65 rlink = p->Clone
a0a0: 20 3d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 =.
a0b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a0c0: 70 2d 3e 4e 65 77 54 6b 74 20 3d 20 70 2d 3e 50 p->NewTkt = p->P
a0d0: 61 73 73 77 6f 72 64 20 3d 20 70 2d 3e 52 64 41 assword = p->RdA
a0e0: 64 64 72 20 3d 0a 20 20 20 20 20 20 20 20 20 20 ddr =.
a0f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a100: 20 20 20 70 2d 3e 54 6b 74 46 6d 74 20 3d 20 70 p->TktFmt = p
a110: 2d 3e 41 74 74 61 63 68 20 3d 20 70 2d 3e 41 70 ->Attach = p->Ap
a120: 6e 64 54 6b 74 20 3d 0a 20 20 20 20 20 20 20 20 ndTkt =.
a130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a140: 20 20 20 20 20 70 2d 3e 4d 6f 64 57 69 6b 69 20 p->ModWiki
a150: 3d 20 70 2d 3e 4d 6f 64 54 6b 74 20 3d 20 70 2d = p->ModTkt = p-
a160: 3e 44 65 6c 65 74 65 20 3d 0a 20 20 20 20 20 20 >Delete =.
a170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a180: 20 20 20 20 20 20 20 70 2d 3e 52 64 46 6f 72 75 p->RdForu
a190: 6d 20 3d 20 70 2d 3e 57 72 46 6f 72 75 6d 20 3d m = p->WrForum =
a1a0: 20 70 2d 3e 4d 6f 64 46 6f 72 75 6d 20 3d 0a 20 p->ModForum =.
a1b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a1c0: 20 20 20 20 20 20 20 20 20 20 20 20 70 2d 3e 57 p->W
a1d0: 72 54 46 6f 72 75 6d 20 3d 20 70 2d 3e 41 64 6d rTForum = p->Adm
a1e0: 69 6e 46 6f 72 75 6d 20 3d 0a 20 20 20 20 20 20 inForum =.
a1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a200: 20 20 20 20 20 20 20 70 2d 3e 45 6d 61 69 6c 41 p->EmailA
a210: 6c 65 72 74 20 3d 20 70 2d 3e 41 6e 6e 6f 75 6e lert = p->Announ
a220: 63 65 20 3d 0a 20 20 20 20 20 20 20 20 20 20 20 ce =.
a230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a240: 20 20 70 2d 3e 57 72 55 6e 76 65 72 20 3d 20 70 p->WrUnver = p
a250: 2d 3e 50 72 69 76 61 74 65 20 3d 20 31 3b 0a 20 ->Private = 1;.
a260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a270: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 /* F
a280: 61 6c 6c 20 74 68 72 75 20 69 6e 74 6f 20 52 65 all thru into Re
a290: 61 64 2f 57 72 69 74 65 20 2a 2f 0a 20 20 20 20 ad/Write */.
a2a0: 20 20 63 61 73 65 20 27 69 27 3a 20 20 20 70 2d case 'i': p-
a2b0: 3e 52 65 61 64 20 3d 20 70 2d 3e 57 72 69 74 65 >Read = p->Write
a2c0: 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 = 1;
a2d0: 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b break
a2e0: 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 6f 27 ;. case 'o'
a2f0: 3a 20 20 20 70 2d 3e 52 65 61 64 20 3d 20 31 3b : p->Read = 1;
a300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a320: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 break;. ca
a330: 73 65 20 27 7a 27 3a 20 20 20 70 2d 3e 5a 69 70 se 'z': p->Zip
a340: 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 = 1;
a350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a360: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 break;..
a370: 20 20 20 20 20 63 61 73 65 20 27 64 27 3a 20 20 case 'd':
a380: 20 70 2d 3e 44 65 6c 65 74 65 20 3d 20 31 3b 20 p->Delete = 1;
a390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62 72 br
a3b0: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 eak;. case
a3c0: 27 68 27 3a 20 20 20 70 2d 3e 48 79 70 65 72 6c 'h': p->Hyperl
a3d0: 69 6e 6b 20 3d 20 31 3b 20 20 20 20 20 20 20 20 ink = 1;
a3e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a3f0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 break;.
a400: 20 63 61 73 65 20 27 67 27 3a 20 20 20 70 2d 3e case 'g': p->
a410: 43 6c 6f 6e 65 20 3d 20 31 3b 20 20 20 20 20 20 Clone = 1;
a420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a430: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b break;
a440: 0a 20 20 20 20 20 20 63 61 73 65 20 27 70 27 3a . case 'p':
a450: 20 20 20 70 2d 3e 50 61 73 73 77 6f 72 64 20 3d p->Password =
a460: 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 1;
a470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a480: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 break;.. ca
a490: 73 65 20 27 6a 27 3a 20 20 20 70 2d 3e 52 64 57 se 'j': p->RdW
a4a0: 69 6b 69 20 3d 20 31 3b 20 20 20 20 20 20 20 20 iki = 1;
a4b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a4c0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 break;.
a4d0: 20 20 20 20 63 61 73 65 20 27 6b 27 3a 20 20 20 case 'k':
a4e0: 70 2d 3e 57 72 57 69 6b 69 20 3d 20 70 2d 3e 52 p->WrWiki = p->R
a4f0: 64 57 69 6b 69 20 3d 20 70 2d 3e 41 70 6e 64 57 dWiki = p->ApndW
a500: 69 6b 69 20 3d 31 3b 20 20 20 20 20 20 62 72 65 iki =1; bre
a510: 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 ak;. case '
a520: 6d 27 3a 20 20 20 70 2d 3e 41 70 6e 64 57 69 6b m': p->ApndWik
a530: 69 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 i = 1;
a540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a550: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 break;.
a560: 63 61 73 65 20 27 66 27 3a 20 20 20 70 2d 3e 4e case 'f': p->N
a570: 65 77 57 69 6b 69 20 3d 20 31 3b 20 20 20 20 20 ewWiki = 1;
a580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a590: 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a break;.
a5a0: 20 20 20 20 20 20 63 61 73 65 20 27 6c 27 3a 20 case 'l':
a5b0: 20 20 70 2d 3e 4d 6f 64 57 69 6b 69 20 3d 20 31 p->ModWiki = 1
a5c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ;
a5d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62 b
a5e0: 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 reak;.. cas
a5f0: 65 20 27 65 27 3a 20 20 20 70 2d 3e 52 64 41 64 e 'e': p->RdAd
a600: 64 72 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 dr = 1;
a610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a620: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 break;.
a630: 20 20 20 63 61 73 65 20 27 72 27 3a 20 20 20 70 case 'r': p
a640: 2d 3e 52 64 54 6b 74 20 3d 20 31 3b 20 20 20 20 ->RdTkt = 1;
a650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a660: 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 brea
a670: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 6e k;. case 'n
a680: 27 3a 20 20 20 70 2d 3e 4e 65 77 54 6b 74 20 3d ': p->NewTkt =
a690: 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 1;
a6a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a6b0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 break;. c
a6c0: 61 73 65 20 27 77 27 3a 20 20 20 70 2d 3e 57 72 ase 'w': p->Wr
a6d0: 54 6b 74 20 3d 20 70 2d 3e 52 64 54 6b 74 20 3d Tkt = p->RdTkt =
a6e0: 20 70 2d 3e 4e 65 77 54 6b 74 20 3d 0a 20 20 20 p->NewTkt =.
a6f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 p
a700: 2d 3e 41 70 6e 64 54 6b 74 20 3d 20 31 3b 20 20 ->ApndTkt = 1;
a710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a720: 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 brea
a730: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 63 k;. case 'c
a740: 27 3a 20 20 20 70 2d 3e 41 70 6e 64 54 6b 74 20 ': p->ApndTkt
a750: 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 = 1;
a760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a770: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 break;. c
a780: 61 73 65 20 27 71 27 3a 20 20 20 70 2d 3e 4d 6f ase 'q': p->Mo
a790: 64 54 6b 74 20 3d 20 31 3b 20 20 20 20 20 20 20 dTkt = 1;
a7a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a7b0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 break;.
a7c0: 20 20 20 20 20 63 61 73 65 20 27 74 27 3a 20 20 case 't':
a7d0: 20 70 2d 3e 54 6b 74 46 6d 74 20 3d 20 31 3b 20 p->TktFmt = 1;
a7e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a7f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62 72 br
a800: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 eak;. case
a810: 27 62 27 3a 20 20 20 70 2d 3e 41 74 74 61 63 68 'b': p->Attach
a820: 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 = 1;
a830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a840: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 break;.
a850: 20 63 61 73 65 20 27 78 27 3a 20 20 20 70 2d 3e case 'x': p->
a860: 50 72 69 76 61 74 65 20 3d 20 31 3b 20 20 20 20 Private = 1;
a870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a880: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b break;
a890: 0a 20 20 20 20 20 20 63 61 73 65 20 27 79 27 3a . case 'y':
a8a0: 20 20 20 70 2d 3e 57 72 55 6e 76 65 72 20 3d 20 p->WrUnver =
a8b0: 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 1;
a8c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a8d0: 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 break;.. ca
a8e0: 73 65 20 27 36 27 3a 20 20 20 70 2d 3e 41 64 6d se '6': p->Adm
a8f0: 69 6e 46 6f 72 75 6d 20 3d 20 31 3b 0a 20 20 20 inForum = 1;.
a900: 20 20 20 63 61 73 65 20 27 35 27 3a 20 20 20 70 case '5': p
a910: 2d 3e 4d 6f 64 46 6f 72 75 6d 20 3d 20 31 3b 0a ->ModForum = 1;.
a920: 20 20 20 20 20 20 63 61 73 65 20 27 34 27 3a 20 case '4':
a930: 20 20 70 2d 3e 57 72 54 46 6f 72 75 6d 20 3d 20 p->WrTForum =
a940: 31 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 33 1;. case '3
a950: 27 3a 20 20 20 70 2d 3e 57 72 46 6f 72 75 6d 20 ': p->WrForum
a960: 3d 20 31 3b 0a 20 20 20 20 20 20 63 61 73 65 20 = 1;. case
a970: 27 32 27 3a 20 20 20 70 2d 3e 52 64 46 6f 72 75 '2': p->RdForu
a980: 6d 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 m = 1;
a990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a9a0: 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 break;..
a9b0: 20 20 63 61 73 65 20 27 37 27 3a 20 20 20 70 2d case '7': p-
a9c0: 3e 45 6d 61 69 6c 41 6c 65 72 74 20 3d 20 31 3b >EmailAlert = 1;
a9d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
a9e0: 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b break
a9f0: 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 41 27 ;. case 'A'
aa00: 3a 20 20 20 70 2d 3e 41 6e 6e 6f 75 6e 63 65 20 : p->Announce
aa10: 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 = 1;
aa20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
aa30: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 break;. ca
aa40: 73 65 20 27 44 27 3a 20 20 20 70 2d 3e 44 65 62 se 'D': p->Deb
aa50: 75 67 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 ug = 1;
aa60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
aa70: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 break;..
aa80: 20 20 20 20 20 2f 2a 20 54 68 65 20 22 75 22 20 /* The "u"
aa90: 70 72 69 76 69 6c 65 67 65 73 20 69 73 20 61 20 privileges is a
aaa0: 6c 69 74 74 6c 65 20 64 69 66 66 65 72 65 6e 74 little different
aab0: 2e 20 20 49 74 20 72 65 63 75 72 73 69 76 65 6c . It recursivel
aac0: 79 0a 20 20 20 20 20 20 2a 2a 20 69 6e 68 65 72 y. ** inher
aad0: 69 74 73 20 61 6c 6c 20 70 72 69 76 69 6c 65 67 its all privileg
aae0: 65 73 20 6f 66 20 74 68 65 20 75 73 65 72 20 6e es of the user n
aaf0: 61 6d 65 64 20 22 72 65 61 64 65 72 22 20 2a 2f amed "reader" */
ab00: 0a 20 20 20 20 20 20 63 61 73 65 20 27 75 27 3a . case 'u':
ab10: 20 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 28 {. if( (
ab20: 66 6c 61 67 73 20 26 20 4c 4f 47 49 4e 5f 49 47 flags & LOGIN_IG
ab30: 4e 4f 52 45 5f 55 56 29 3d 3d 30 20 29 7b 0a 20 NORE_UV)==0 ){.
ab40: 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 const c
ab50: 68 61 72 20 2a 7a 55 73 65 72 3b 0a 20 20 20 20 har *zUser;.
ab60: 20 20 20 20 20 20 7a 55 73 65 72 20 3d 20 64 62 zUser = db
ab70: 5f 74 65 78 74 28 22 22 2c 20 22 53 45 4c 45 43 _text("", "SELEC
ab80: 54 20 63 61 70 20 46 52 4f 4d 20 75 73 65 72 20 T cap FROM user
ab90: 57 48 45 52 45 20 6c 6f 67 69 6e 3d 27 72 65 61 WHERE login='rea
aba0: 64 65 72 27 22 29 3b 0a 20 20 20 20 20 20 20 20 der'");.
abb0: 20 20 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70 61 login_set_capa
abc0: 62 69 6c 69 74 69 65 73 28 7a 55 73 65 72 2c 20 bilities(zUser,
abd0: 66 6c 61 67 73 20 7c 20 4c 4f 47 49 4e 5f 49 47 flags | LOGIN_IG
abe0: 4e 4f 52 45 5f 55 56 29 3b 0a 20 20 20 20 20 20 NORE_UV);.
abf0: 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 }. brea
ac00: 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 k;. }..
ac10: 20 20 2f 2a 20 54 68 65 20 22 76 22 20 70 72 69 /* The "v" pri
ac20: 76 69 6c 65 67 65 73 20 69 73 20 61 20 6c 69 74 vileges is a lit
ac30: 74 6c 65 20 64 69 66 66 65 72 65 6e 74 2e 20 20 tle different.
ac40: 49 74 20 72 65 63 75 72 73 69 76 65 6c 79 0a 20 It recursively.
ac50: 20 20 20 20 20 2a 2a 20 69 6e 68 65 72 69 74 73 ** inherits
ac60: 20 61 6c 6c 20 70 72 69 76 69 6c 65 67 65 73 20 all privileges
ac70: 6f 66 20 74 68 65 20 75 73 65 72 20 6e 61 6d 65 of the user name
ac80: 64 20 22 64 65 76 65 6c 6f 70 65 72 22 20 2a 2f d "developer" */
ac90: 0a 20 20 20 20 20 20 63 61 73 65 20 27 76 27 3a . case 'v':
aca0: 20 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 28 {. if( (
acb0: 66 6c 61 67 73 20 26 20 4c 4f 47 49 4e 5f 49 47 flags & LOGIN_IG
acc0: 4e 4f 52 45 5f 55 56 29 3d 3d 30 20 29 7b 0a 20 NORE_UV)==0 ){.
acd0: 20 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63 const c
ace0: 68 61 72 20 2a 7a 44 65 76 3b 0a 20 20 20 20 20 har *zDev;.
acf0: 20 20 20 20 20 7a 44 65 76 20 3d 20 64 62 5f 74 zDev = db_t
ad00: 65 78 74 28 22 22 2c 20 22 53 45 4c 45 43 54 20 ext("", "SELECT
ad10: 63 61 70 20 46 52 4f 4d 20 75 73 65 72 20 57 48 cap FROM user WH
ad20: 45 52 45 20 6c 6f 67 69 6e 3d 27 64 65 76 65 6c ERE login='devel
ad30: 6f 70 65 72 27 22 29 3b 0a 20 20 20 20 20 20 20 oper'");.
ad40: 20 20 20 6c 6f 67 69 6e 5f 73 65 74 5f 63 61 70 login_set_cap
ad50: 61 62 69 6c 69 74 69 65 73 28 7a 44 65 76 2c 20 abilities(zDev,
ad60: 66 6c 61 67 73 20 7c 20 4c 4f 47 49 4e 5f 49 47 flags | LOGIN_IG
ad70: 4e 4f 52 45 5f 55 56 29 3b 0a 20 20 20 20 20 20 NORE_UV);.
ad80: 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 }. brea
ad90: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d k;. }. }
ada0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 5a 65 . }.}../*.** Ze
adb0: 72 6f 65 73 20 6f 75 74 20 67 2e 70 65 72 6d 20 roes out g.perm
adc0: 61 6e 64 20 63 61 6c 6c 73 20 6c 6f 67 69 6e 5f and calls login_
add0: 73 65 74 5f 63 61 70 61 62 69 6c 69 74 69 65 73 set_capabilities
ade0: 28 7a 43 61 70 2c 66 6c 61 67 73 29 2e 0a 2a 2f (zCap,flags)..*/
adf0: 0a 76 6f 69 64 20 6c 6f 67 69 6e 5f 72 65 70 6c .void login_repl
ae00: 61 63 65 5f 63 61 70 61 62 69 6c 69 74 69 65 73 ace_capabilities
ae10: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 61 (const char *zCa
ae20: 70 2c 20 75 6e 73 69 67 6e 65 64 20 66 6c 61 67 p, unsigned flag
ae30: 73 29 7b 0a 20 20 6d 65 6d 73 65 74 28 26 67 2e s){. memset(&g.
ae40: 70 65 72 6d 2c 20 30 2c 20 73 69 7a 65 6f 66 28 perm, 0, sizeof(
ae50: 67 2e 70 65 72 6d 29 29 3b 0a 20 20 6c 6f 67 69 g.perm));. logi
ae60: 6e 5f 73 65 74 5f 63 61 70 61 62 69 6c 69 74 69 n_set_capabiliti
ae70: 65 73 28 7a 43 61 70 2c 20 66 6c 61 67 73 29 3b es(zCap, flags);
ae80: 0a 20 20 6c 6f 67 69 6e 5f 61 6e 6f 6e 5f 6f 6e . login_anon_on
ae90: 63 65 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a ce = 1;.}../*.**
aea0: 20 49 66 20 74 68 65 20 63 75 72 72 65 6e 74 20 If the current
aeb0: 6c 6f 67 69 6e 20 6c 61 63 6b 73 20 61 6e 79 20 login lacks any
aec0: 6f 66 20 74 68 65 20 63 61 70 61 62 69 6c 69 74 of the capabilit
aed0: 69 65 73 20 6c 69 73 74 65 64 20 69 6e 0a 2a 2a ies listed in.**
aee0: 20 74 68 65 20 69 6e 70 75 74 2c 20 74 68 65 6e the input, then
aef0: 20 72 65 74 75 72 6e 20 30 2e 20 20 49 66 20 61 return 0. If a
af00: 6c 6c 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 ll capabilities
af10: 61 72 65 20 70 72 65 73 65 6e 74 2c 20 74 68 65 are present, the
af20: 6e 0a 2a 2a 20 72 65 74 75 72 6e 20 31 2e 0a 2a n.** return 1..*
af30: 2f 0a 69 6e 74 20 6c 6f 67 69 6e 5f 68 61 73 5f /.int login_has_
af40: 63 61 70 61 62 69 6c 69 74 79 28 63 6f 6e 73 74 capability(const
af50: 20 63 68 61 72 20 2a 7a 43 61 70 2c 20 69 6e 74 char *zCap, int
af60: 20 6e 43 61 70 2c 20 75 33 32 20 66 6c 67 73 29 nCap, u32 flgs)
af70: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 {. int i;. int
af80: 20 72 63 20 3d 20 31 3b 0a 20 20 46 6f 73 73 69 rc = 1;. Fossi
af90: 6c 55 73 65 72 50 65 72 6d 73 20 2a 70 20 3d 20 lUserPerms *p =
afa0: 28 66 6c 67 73 20 26 20 4c 4f 47 49 4e 5f 41 4e (flgs & LOGIN_AN
afb0: 4f 4e 29 20 3f 20 26 67 2e 61 6e 6f 6e 20 3a 20 ON) ? &g.anon :
afc0: 26 67 2e 70 65 72 6d 3b 0a 20 20 69 66 28 20 6e &g.perm;. if( n
afd0: 43 61 70 3c 30 20 29 20 6e 43 61 70 20 3d 20 73 Cap<0 ) nCap = s
afe0: 74 72 6c 65 6e 28 7a 43 61 70 29 3b 0a 20 20 66 trlen(zCap);. f
aff0: 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 61 70 20 26 or(i=0; i<nCap &
b000: 26 20 72 63 20 26 26 20 7a 43 61 70 5b 69 5d 3b & rc && zCap[i];
b010: 20 69 2b 2b 29 7b 0a 20 20 20 20 73 77 69 74 63 i++){. switc
b020: 68 28 20 7a 43 61 70 5b 69 5d 20 29 7b 0a 20 20 h( zCap[i] ){.
b030: 20 20 20 20 63 61 73 65 20 27 61 27 3a 20 20 72 case 'a': r
b040: 63 20 3d 20 70 2d 3e 41 64 6d 69 6e 3b 20 20 20 c = p->Admin;
b050: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 break;. c
b060: 61 73 65 20 27 62 27 3a 20 20 72 63 20 3d 20 70 ase 'b': rc = p
b070: 2d 3e 41 74 74 61 63 68 3b 20 20 20 20 62 72 65 ->Attach; bre
b080: 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 ak;. case '
b090: 63 27 3a 20 20 72 63 20 3d 20 70 2d 3e 41 70 6e c': rc = p->Apn
b0a0: 64 54 6b 74 3b 20 20 20 62 72 65 61 6b 3b 0a 20 dTkt; break;.
b0b0: 20 20 20 20 20 63 61 73 65 20 27 64 27 3a 20 20 case 'd':
b0c0: 72 63 20 3d 20 70 2d 3e 44 65 6c 65 74 65 3b 20 rc = p->Delete;
b0d0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 break;.
b0e0: 63 61 73 65 20 27 65 27 3a 20 20 72 63 20 3d 20 case 'e': rc =
b0f0: 70 2d 3e 52 64 41 64 64 72 3b 20 20 20 20 62 72 p->RdAddr; br
b100: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 eak;. case
b110: 27 66 27 3a 20 20 72 63 20 3d 20 70 2d 3e 4e 65 'f': rc = p->Ne
b120: 77 57 69 6b 69 3b 20 20 20 62 72 65 61 6b 3b 0a wWiki; break;.
b130: 20 20 20 20 20 20 63 61 73 65 20 27 67 27 3a 20 case 'g':
b140: 20 72 63 20 3d 20 70 2d 3e 43 6c 6f 6e 65 3b 20 rc = p->Clone;
b150: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 break;.
b160: 20 63 61 73 65 20 27 68 27 3a 20 20 72 63 20 3d case 'h': rc =
b170: 20 70 2d 3e 48 79 70 65 72 6c 69 6e 6b 3b 20 62 p->Hyperlink; b
b180: 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 reak;. case
b190: 20 27 69 27 3a 20 20 72 63 20 3d 20 70 2d 3e 57 'i': rc = p->W
b1a0: 72 69 74 65 3b 20 20 20 20 20 62 72 65 61 6b 3b rite; break;
b1b0: 0a 20 20 20 20 20 20 63 61 73 65 20 27 6a 27 3a . case 'j':
b1c0: 20 20 72 63 20 3d 20 70 2d 3e 52 64 57 69 6b 69 rc = p->RdWiki
b1d0: 3b 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 ; break;.
b1e0: 20 20 63 61 73 65 20 27 6b 27 3a 20 20 72 63 20 case 'k': rc
b1f0: 3d 20 70 2d 3e 57 72 57 69 6b 69 3b 20 20 20 20 = p->WrWiki;
b200: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 break;. cas
b210: 65 20 27 6c 27 3a 20 20 72 63 20 3d 20 70 2d 3e e 'l': rc = p->
b220: 4d 6f 64 57 69 6b 69 3b 20 20 20 62 72 65 61 6b ModWiki; break
b230: 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 6d 27 ;. case 'm'
b240: 3a 20 20 72 63 20 3d 20 70 2d 3e 41 70 6e 64 57 : rc = p->ApndW
b250: 69 6b 69 3b 20 20 62 72 65 61 6b 3b 0a 20 20 20 iki; break;.
b260: 20 20 20 63 61 73 65 20 27 6e 27 3a 20 20 72 63 case 'n': rc
b270: 20 3d 20 70 2d 3e 4e 65 77 54 6b 74 3b 20 20 20 = p->NewTkt;
b280: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 break;. ca
b290: 73 65 20 27 6f 27 3a 20 20 72 63 20 3d 20 70 2d se 'o': rc = p-
b2a0: 3e 52 65 61 64 3b 20 20 20 20 20 20 62 72 65 61 >Read; brea
b2b0: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 70 k;. case 'p
b2c0: 27 3a 20 20 72 63 20 3d 20 70 2d 3e 50 61 73 73 ': rc = p->Pass
b2d0: 77 6f 72 64 3b 20 20 62 72 65 61 6b 3b 0a 20 20 word; break;.
b2e0: 20 20 20 20 63 61 73 65 20 27 71 27 3a 20 20 72 case 'q': r
b2f0: 63 20 3d 20 70 2d 3e 4d 6f 64 54 6b 74 3b 20 20 c = p->ModTkt;
b300: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 break;. c
b310: 61 73 65 20 27 72 27 3a 20 20 72 63 20 3d 20 70 ase 'r': rc = p
b320: 2d 3e 52 64 54 6b 74 3b 20 20 20 20 20 62 72 65 ->RdTkt; bre
b330: 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 ak;. case '
b340: 73 27 3a 20 20 72 63 20 3d 20 70 2d 3e 53 65 74 s': rc = p->Set
b350: 75 70 3b 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 up; break;.
b360: 20 20 20 20 20 63 61 73 65 20 27 74 27 3a 20 20 case 't':
b370: 72 63 20 3d 20 70 2d 3e 54 6b 74 46 6d 74 3b 20 rc = p->TktFmt;
b380: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 break;.
b390: 2f 2a 20 63 61 73 65 20 27 75 27 3a 20 52 45 41 /* case 'u': REA
b3a0: 44 45 52 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 DER */.
b3b0: 2f 2a 20 63 61 73 65 20 27 76 27 3a 20 44 45 56 /* case 'v': DEV
b3c0: 45 4c 4f 50 45 52 20 2a 2f 0a 20 20 20 20 20 20 ELOPER */.
b3d0: 63 61 73 65 20 27 77 27 3a 20 20 72 63 20 3d 20 case 'w': rc =
b3e0: 70 2d 3e 57 72 54 6b 74 3b 20 20 20 20 20 62 72 p->WrTkt; br
b3f0: 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 eak;. case
b400: 27 78 27 3a 20 20 72 63 20 3d 20 70 2d 3e 50 72 'x': rc = p->Pr
b410: 69 76 61 74 65 3b 20 20 20 62 72 65 61 6b 3b 0a ivate; break;.
b420: 20 20 20 20 20 20 63 61 73 65 20 27 79 27 3a 20 case 'y':
b430: 20 72 63 20 3d 20 70 2d 3e 57 72 55 6e 76 65 72 rc = p->WrUnver
b440: 3b 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 ; break;.
b450: 20 63 61 73 65 20 27 7a 27 3a 20 20 72 63 20 3d case 'z': rc =
b460: 20 70 2d 3e 5a 69 70 3b 20 20 20 20 20 20 20 62 p->Zip; b
b470: 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 reak;. case
b480: 20 27 32 27 3a 20 20 72 63 20 3d 20 70 2d 3e 52 '2': rc = p->R
b490: 64 46 6f 72 75 6d 3b 20 20 20 62 72 65 61 6b 3b dForum; break;
b4a0: 0a 20 20 20 20 20 20 63 61 73 65 20 27 33 27 3a . case '3':
b4b0: 20 20 72 63 20 3d 20 70 2d 3e 57 72 46 6f 72 75 rc = p->WrForu
b4c0: 6d 3b 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 m; break;.
b4d0: 20 20 63 61 73 65 20 27 34 27 3a 20 20 72 63 20 case '4': rc
b4e0: 3d 20 70 2d 3e 57 72 54 46 6f 72 75 6d 3b 20 20 = p->WrTForum;
b4f0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 break;. cas
b500: 65 20 27 35 27 3a 20 20 72 63 20 3d 20 70 2d 3e e '5': rc = p->
b510: 4d 6f 64 46 6f 72 75 6d 3b 20 20 62 72 65 61 6b ModForum; break
b520: 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 36 27 ;. case '6'
b530: 3a 20 20 72 63 20 3d 20 70 2d 3e 41 64 6d 69 6e : rc = p->Admin
b540: 46 6f 72 75 6d 3b 62 72 65 61 6b 3b 0a 20 20 20 Forum;break;.
b550: 20 20 20 63 61 73 65 20 27 37 27 3a 20 20 72 63 case '7': rc
b560: 20 3d 20 70 2d 3e 45 6d 61 69 6c 41 6c 65 72 74 = p->EmailAlert
b570: 3b 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 ;break;. ca
b580: 73 65 20 27 41 27 3a 20 20 72 63 20 3d 20 70 2d se 'A': rc = p-
b590: 3e 41 6e 6e 6f 75 6e 63 65 3b 20 20 62 72 65 61 >Announce; brea
b5a0: 6b 3b 0a 20 20 20 20 20 20 63 61 73 65 20 27 44 k;. case 'D
b5b0: 27 3a 20 20 72 63 20 3d 20 70 2d 3e 44 65 62 75 ': rc = p->Debu
b5c0: 67 3b 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 g; break;.
b5d0: 20 20 20 20 64 65 66 61 75 6c 74 3a 20 20 20 72 default: r
b5e0: 63 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 c = 0;
b5f0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 break;. }.
b600: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a }. return rc;.
b610: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20 }../*.** Change
b620: 74 68 65 20 6c 6f 67 69 6e 20 74 6f 20 7a 55 73 the login to zUs
b630: 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 6c 6f 67 69 er..*/.void logi
b640: 6e 5f 61 73 5f 75 73 65 72 28 63 6f 6e 73 74 20 n_as_user(const
b650: 63 68 61 72 20 2a 7a 55 73 65 72 29 7b 0a 20 20 char *zUser){.
b660: 63 68 61 72 20 2a 7a 43 61 70 20 3d 20 22 22 3b char *zCap = "";
b670: 20 20 20 2f 2a 20 4e 65 77 20 63 61 70 61 62 69 /* New capabi
b680: 6c 69 74 69 65 73 20 2a 2f 0a 0a 20 20 2f 2a 20 lities */.. /*
b690: 54 75 72 6e 20 6f 66 66 20 61 6c 6c 20 63 61 70 Turn off all cap
b6a0: 61 62 69 6c 69 74 69 65 73 20 66 72 6f 6d 20 70 abilities from p
b6b0: 72 69 6f 72 20 6c 6f 67 69 6e 73 20 2a 2f 0a 20 rior logins */.
b6c0: 20 6d 65 6d 73 65 74 28 20 26 67 2e 70 65 72 6d memset( &g.perm
b6d0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 67 2e 70 65 , 0, sizeof(g.pe
b6e0: 72 6d 29 20 29 3b 0a 0a 20 20 2f 2a 20 53 65 74 rm) );.. /* Set
b6f0: 20 74 68 65 20 67 6c 6f 62 61 6c 20 76 61 72 69 the global vari
b700: 61 62 6c 65 73 20 72 65 63 6f 72 64 69 6e 67 20 ables recording
b710: 74 68 65 20 75 73 65 72 69 64 20 61 6e 64 20 6c the userid and l
b720: 6f 67 69 6e 2e 20 20 54 68 65 0a 20 20 2a 2a 20 ogin. The. **
b730: 22 6e 6f 62 6f 64 79 22 20 75 73 65 72 20 69 73 "nobody" user is
b740: 20 61 20 73 70 65 63 69 61 6c 20 63 61 73 65 20 a special case
b750: 69 6e 20 74 68 61 74 20 67 2e 7a 4c 6f 67 69 6e in that g.zLogin
b760: 3d 3d 30 2e 0a 20 20 2a 2f 0a 20 20 67 2e 75 73 ==0.. */. g.us
b770: 65 72 55 69 64 20 3d 20 64 62 5f 69 6e 74 28 30 erUid = db_int(0
b780: 2c 20 22 53 45 4c 45 43 54 20 75 69 64 20 46 52 , "SELECT uid FR
b790: 4f 4d 20 75 73 65 72 20 57 48 45 52 45 20 6c 6f OM user WHERE lo
b7a0: 67 69 6e 3d 25 51 22 2c 20 7a 55 73 65 72 29 3b gin=%Q", zUser);
b7b0: 0a 20 20 69 66 28 20 67 2e 75 73 65 72 55 69 64 . if( g.userUid
b7c0: 3d 3d 30 20 29 7b 0a 20 20 20 20 7a 55 73 65 72 ==0 ){. zUser
b7d0: 20 3d 20 30 3b 0a 20 20 20 20 67 2e 75 73 65 72 = 0;. g.user
b7e0: 55 69 64 20 3d 20 64 62 5f 69 6e 74 28 30 2c 20 Uid = db_int(0,
b7f0: 22 53 45 4c 45 43 54 20 75 69 64 20 46 52 4f 4d "SELECT uid FROM
b800: 20 75 73 65 72 20 57 48 45 52 45 20 6c 6f 67 69 user WHERE logi
b810: 6e 3d 27 6e 6f 62 6f 64 79 27 22 29 3b 0a 20 20 n='nobody'");.
b820: 7d 0a 20 20 69 66 28 20 67 2e 75 73 65 72 55 69 }. if( g.userUi
b830: 64 20 29 7b 0a 20 20 20 20 7a 43 61 70 20 3d 20 d ){. zCap =
b840: 64 62 5f 74 65 78 74 28 22 22 2c 20 22 53 45 4c db_text("", "SEL
b850: 45 43 54 20 63 61 70 20 46 52 4f 4d 20 75 73 65 ECT cap FROM use
b860: 72 20 57 48 45 52 45 20 75 69 64 3d 25 64 22 2c r WHERE uid=%d",
b870: 20 67 2e 75 73 65 72 55 69 64 29 3b 0a 20 20 7d g.userUid);. }
b880: 0a 20 20 69 66 28 20 66 6f 73 73 69 6c 5f 73 74 . if( fossil_st
b890: 72 63 6d 70 28 7a 55 73 65 72 2c 22 6e 6f 62 6f rcmp(zUser,"nobo
b8a0: 64 79 22 29 3d 3d 30 20 29 20 7a 55 73 65 72 20 dy")==0 ) zUser
b8b0: 3d 20 30 3b 0a 20 20 67 2e 7a 4c 6f 67 69 6e 20 = 0;. g.zLogin
b8c0: 3d 20 66 6f 73 73 69 6c 5f 73 74 72 64 75 70 28 = fossil_strdup(
b8d0: 7a 55 73 65 72 29 3b 0a 0a 20 20 2f 2a 20 53 65 zUser);.. /* Se
b8e0: 74 20 74 68 65 20 63 61 70 61 62 69 6c 69 74 69 t the capabiliti
b8f0: 65 73 20 2a 2f 0a 20 20 6c 6f 67 69 6e 5f 73 65 es */. login_se
b900: 74 5f 63 61 70 61 62 69 6c 69 74 69 65 73 28 7a t_capabilities(z
b910: 43 61 70 2c 20 30 29 3b 0a 20 20 6c 6f 67 69 6e Cap, 0);. login
b920: 5f 61 6e 6f 6e 5f 6f 6e 63 65 20 3d 20 31 3b 0a _anon_once = 1;.
b930: 20 20 6c 6f 67 69 6e 5f 73 65 74 5f 61 6e 6f 6e login_set_anon
b940: 5f 6e 6f 62 6f 64 79 5f 63 61 70 61 62 69 6c 69 _nobody_capabili
b950: 74 69 65 73 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a ties();.}../*.**
b960: 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 Return true if
b970: 74 68 65 20 75 73 65 72 20 69 73 20 22 6e 6f 62 the user is "nob
b980: 6f 64 79 22 0a 2a 2f 0a 69 6e 74 20 6c 6f 67 69 ody".*/.int logi
b990: 6e 5f 69 73 5f 6e 6f 62 6f 64 79 28 76 6f 69 64 n_is_nobody(void
b9a0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 67 2e 7a 4c ){. return g.zL
b9b0: 6f 67 69 6e 3d 3d 30 20 7c 7c 20 67 2e 7a 4c 6f ogin==0 || g.zLo
b9c0: 67 69 6e 5b 30 5d 3d 3d 30 20 7c 7c 20 66 6f 73 gin[0]==0 || fos
b9d0: 73 69 6c 5f 73 74 72 63 6d 70 28 67 2e 7a 4c 6f sil_strcmp(g.zLo
b9e0: 67 69 6e 2c 22 6e 6f 62 6f 64 79 22 29 3d 3d 30 gin,"nobody")==0
b9f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 ;.}../*.** Retur
ba00: 6e 20 74 72 75 65 20 69 66 20 74 68 65 20 75 73 n true if the us
ba10: 65 72 20 69 73 20 61 20 73 70 65 63 69 66 69 63 er is a specific
ba20: 20 69 6e 64 69 76 69 64 75 61 6c 2c 20 6e 6f 74 individual, not
ba30: 20 22 6e 6f 62 6f 64 79 22 20 6f 72 0a 2a 2a 20 "nobody" or.**
ba40: 22 61 6e 6f 6e 79 6d 6f 75 73 22 2e 0a 2a 2f 0a "anonymous"..*/.
ba50: 69 6e 74 20 6c 6f 67 69 6e 5f 69 73 5f 69 6e 64 int login_is_ind
ba60: 69 76 69 64 75 61 6c 28 76 6f 69 64 29 7b 0a 20 ividual(void){.
ba70: 20 72 65 74 75 72 6e 20 67 2e 7a 4c 6f 67 69 6e return g.zLogin
ba80: 21 3d 30 20 26 26 20 67 2e 7a 4c 6f 67 69 6e 5b !=0 && g.zLogin[
ba90: 30 5d 21 3d 30 20 26 26 20 66 6f 73 73 69 6c 5f 0]!=0 && fossil_
baa0: 73 74 72 63 6d 70 28 67 2e 7a 4c 6f 67 69 6e 2c strcmp(g.zLogin,
bab0: 22 6e 6f 62 6f 64 79 22 29 21 3d 30 0a 20 20 20 "nobody")!=0.
bac0: 20 20 20 20 20 20 20 20 26 26 20 66 6f 73 73 69 && fossi
bad0: 6c 5f 73 74 72 63 6d 70 28 67 2e 7a 4c 6f 67 69 l_strcmp(g.zLogi
bae0: 6e 2c 22 61 6e 6f 6e 79 6d 6f 75 73 22 29 21 3d n,"anonymous")!=
baf0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 0;.}../*.** Retu
bb00: 72 6e 20 74 68 65 20 6c 6f 67 69 6e 20 6e 61 6d rn the login nam
bb10: 65 2e 20 20 49 66 20 6e 6f 20 6c 6f 67 69 6e 20 e. If no login
bb20: 6e 61 6d 65 20 69 73 20 73 70 65 63 69 66 69 65 name is specifie
bb30: 64 2c 20 72 65 74 75 72 6e 20 22 6e 6f 62 6f 64 d, return "nobod
bb40: 79 22 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 y"..*/.const cha
bb50: 72 20 2a 6c 6f 67 69 6e 5f 6e 61 6d 65 28 76 6f r *login_name(vo
bb60: 69 64 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 67 id){. return (g
bb70: 2e 7a 4c 6f 67 69 6e 20 26 26 20 67 2e 7a 4c 6f .zLogin && g.zLo
bb80: 67 69 6e 5b 30 5d 29 20 3f 20 67 2e 7a 4c 6f 67 gin[0]) ? g.zLog
bb90: 69 6e 20 3a 20 22 6e 6f 62 6f 64 79 22 3b 0a 7d in : "nobody";.}
bba0: 0a 0a 2f 2a 0a 2a 2a 20 43 61 6c 6c 20 74 68 69 ../*.** Call thi
bbb0: 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 20 74 s routine when t
bbc0: 68 65 20 63 72 65 64 65 6e 74 69 61 6c 20 63 68 he credential ch
bbd0: 65 63 6b 20 66 61 69 6c 73 2e 20 20 49 74 20 63 eck fails. It c
bbe0: 61 75 73 65 73 0a 2a 2a 20 61 20 72 65 64 69 72 auses.** a redir
bbf0: 65 63 74 20 74 6f 20 74 68 65 20 22 6c 6f 67 69 ect to the "logi
bc00: 6e 22 20 70 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64 n" page..*/.void
bc10: 20 6c 6f 67 69 6e 5f 6e 65 65 64 65 64 28 69 6e login_needed(in
bc20: 74 20 61 6e 6f 6e 4f 6b 29 7b 0a 23 69 66 64 65 t anonOk){.#ifde
bc30: 66 20 46 4f 53 53 49 4c 5f 45 4e 41 42 4c 45 5f f FOSSIL_ENABLE_
bc40: 4a 53 4f 4e 0a 20 20 69 66 28 67 2e 6a 73 6f 6e JSON. if(g.json
bc50: 2e 69 73 4a 73 6f 6e 4d 6f 64 65 29 7b 0a 20 20 .isJsonMode){.
bc60: 20 20 6a 73 6f 6e 5f 65 72 72 28 20 46 53 4c 5f json_err( FSL_
bc70: 4a 53 4f 4e 5f 45 5f 44 45 4e 49 45 44 2c 20 4e JSON_E_DENIED, N
bc80: 55 4c 4c 2c 20 31 20 29 3b 0a 20 20 20 20 66 6f ULL, 1 );. fo
bc90: 73 73 69 6c 5f 65 78 69 74 28 30 29 3b 0a 20 20 ssil_exit(0);.
bca0: 20 20 2f 2a 20 4e 4f 54 52 45 41 43 48 45 44 20 /* NOTREACHED
bcb0: 2a 2f 0a 20 20 20 20 61 73 73 65 72 74 28 30 29 */. assert(0)
bcc0: 3b 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 ;. }else.#endif
bcd0: 20 2f 2a 20 46 4f 53 53 49 4c 5f 45 4e 41 42 4c /* FOSSIL_ENABL
bce0: 45 5f 4a 53 4f 4e 20 2a 2f 0a 20 20 7b 0a 20 20 E_JSON */. {.
bcf0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 const char *zU
bd00: 72 6c 20 3d 20 50 44 28 22 52 45 51 55 45 53 54 rl = PD("REQUEST
bd10: 5f 55 52 49 22 2c 20 22 69 6e 64 65 78 22 29 3b _URI", "index");
bd20: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 . const char
bd30: 2a 7a 51 53 20 3d 20 50 28 22 51 55 45 52 59 5f *zQS = P("QUERY_
bd40: 53 54 52 49 4e 47 22 29 3b 0a 20 20 20 20 42 6c STRING");. Bl
bd50: 6f 62 20 72 65 64 69 72 3b 0a 20 20 20 20 62 6c ob redir;. bl
bd60: 6f 62 5f 69 6e 69 74 28 26 72 65 64 69 72 2c 20 ob_init(&redir,
bd70: 30 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 6c 0, 0);. if( l
bd80: 6f 67 69 6e 5f 77 61 6e 74 73 5f 68 74 74 70 73 ogin_wants_https
bd90: 5f 72 65 64 69 72 65 63 74 28 29 20 26 26 20 21 _redirect() && !
bda0: 67 2e 73 73 6c 4e 6f 74 41 76 61 69 6c 61 62 6c g.sslNotAvailabl
bdb0: 65 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f e ){. blob_
bdc0: 61 70 70 65 6e 64 66 28 26 72 65 64 69 72 2c 20 appendf(&redir,
bdd0: 22 25 73 2f 6c 6f 67 69 6e 3f 67 3d 25 54 22 2c "%s/login?g=%T",
bde0: 20 67 2e 7a 48 74 74 70 73 55 52 4c 2c 20 7a 55 g.zHttpsURL, zU
bdf0: 72 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a rl);. }else{.
be00: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e blob_appen
be10: 64 66 28 26 72 65 64 69 72 2c 20 22 25 52 2f 6c df(&redir, "%R/l
be20: 6f 67 69 6e 3f 67 3d 25 54 22 2c 20 7a 55 72 6c ogin?g=%T", zUrl
be30: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 );. }. if(
be40: 20 61 6e 6f 6e 4f 6b 20 29 20 62 6c 6f 62 5f 61 anonOk ) blob_a
be50: 70 70 65 6e 64 28 26 72 65 64 69 72 2c 20 22 26 ppend(&redir, "&
be60: 61 6e 6f 6e 22 2c 20 35 29 3b 0a 20 20 20 20 69 anon", 5);. i
be70: 66 28 20 7a 51 53 20 26 26 20 7a 51 53 5b 30 5d f( zQS && zQS[0]
be80: 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61 ){. blob_a
be90: 70 70 65 6e 64 66 28 26 72 65 64 69 72 2c 20 22 ppendf(&redir, "
bea0: 26 25 73 22 2c 20 7a 51 53 29 3b 0a 20 20 20 20 &%s", zQS);.
beb0: 7d 0a 20 20 20 20 63 67 69 5f 72 65 64 69 72 65 }. cgi_redire
bec0: 63 74 28 62 6c 6f 62 5f 73 74 72 28 26 72 65 64 ct(blob_str(&red
bed0: 69 72 29 29 3b 0a 20 20 20 20 2f 2a 20 4e 4f 54 ir));. /* NOT
bee0: 52 45 41 43 48 45 44 20 2a 2f 0a 20 20 20 20 61 REACHED */. a
bef0: 73 73 65 72 74 28 30 29 3b 0a 20 20 7d 0a 7d 0a ssert(0);. }.}.
bf00: 0a 2f 2a 0a 2a 2a 20 43 61 6c 6c 20 74 68 69 73 ./*.** Call this
bf10: 20 72 6f 75 74 69 6e 65 20 69 66 20 74 68 65 20 routine if the
bf20: 75 73 65 72 20 6c 61 63 6b 73 20 67 2e 70 65 72 user lacks g.per
bf30: 6d 2e 48 79 70 65 72 6c 69 6e 6b 20 70 65 72 6d m.Hyperlink perm
bf40: 69 73 73 69 6f 6e 2e 20 20 49 66 0a 2a 2a 20 74 ission. If.** t
bf50: 68 65 20 61 6e 6f 6e 79 6d 6f 75 73 20 75 73 65 he anonymous use
bf60: 72 20 68 61 73 20 48 79 70 65 72 6c 69 6e 6b 20 r has Hyperlink
bf70: 70 65 72 6d 69 73 73 69 6f 6e 2c 20 74 68 65 6e permission, then
bf80: 20 70 61 69 6e 74 20 61 20 6d 65 73 61 67 65 0a paint a mesage.
bf90: 2a 2a 20 74 6f 20 69 6e 66 6f 72 6d 20 74 68 65 ** to inform the
bfa0: 20 75 73 65 72 20 74 68 61 74 20 6d 75 63 68 20 user that much
bfb0: 6d 6f 72 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e more information
bfc0: 20 69 73 20 61 76 61 69 6c 61 62 6c 65 20 62 79 is available by
bfd0: 0a 2a 2a 20 6c 6f 67 67 69 6e 67 20 69 6e 20 61 .** logging in a
bfe0: 73 20 61 6e 6f 6e 79 6d 6f 75 73 2e 0a 2a 2f 0a s anonymous..*/.
bff0: 76 6f 69 64 20 6c 6f 67 69 6e 5f 61 6e 6f 6e 79 void login_anony
c000: 6d 6f 75 73 5f 61 76 61 69 6c 61 62 6c 65 28 76 mous_available(v
c010: 6f 69 64 29 7b 0a 20 20 69 66 28 20 21 67 2e 70 oid){. if( !g.p
c020: 65 72 6d 2e 48 79 70 65 72 6c 69 6e 6b 20 26 26 erm.Hyperlink &&
c030: 20 67 2e 61 6e 6f 6e 2e 48 79 70 65 72 6c 69 6e g.anon.Hyperlin
c040: 6b 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 k ){. const c
c050: 68 61 72 20 2a 7a 55 72 6c 20 3d 20 50 44 28 22 har *zUrl = PD("
c060: 52 45 51 55 45 53 54 5f 55 52 49 22 2c 20 22 69 REQUEST_URI", "i
c070: 6e 64 65 78 22 29 3b 0a 20 20 20 20 40 20 3c 70 ndex");. @ <p
c080: 3e 4d 61 6e 79 20 3c 73 70 61 6e 20 63 6c 61 73 >Many <span clas
c090: 73 3d 22 64 69 73 61 62 6c 65 64 22 3e 68 79 70 s="disabled">hyp
c0a0: 65 72 6c 69 6e 6b 73 20 61 72 65 20 64 69 73 61 erlinks are disa
c0b0: 62 6c 65 64 2e 3c 2f 73 70 61 6e 3e 3c 62 72 20 bled.</span><br
c0c0: 2f 3e 0a 20 20 20 20 40 20 55 73 65 20 3c 61 20 />. @ Use <a
c0d0: 68 72 65 66 3d 22 25 52 2f 6c 6f 67 69 6e 3f 61 href="%R/login?a
c0e0: 6e 6f 6e 3d 31 26 61 6d 70 3b 67 3d 25 54 28 7a non=1&g=%T(z
c0f0: 55 72 6c 29 22 3e 61 6e 6f 6e 79 6d 6f 75 73 20 Url)">anonymous
c100: 6c 6f 67 69 6e 3c 2f 61 3e 0a 20 20 20 20 40 20 login</a>. @
c110: 74 6f 20 65 6e 61 62 6c 65 20 68 79 70 65 72 6c to enable hyperl
c120: 69 6e 6b 73 2e 3c 2f 70 3e 0a 20 20 7d 0a 7d 0a inks.</p>. }.}.
c130: 0a 2f 2a 0a 2a 2a 20 57 68 69 6c 65 20 72 65 6e ./*.** While ren
c140: 64 65 72 69 6e 67 20 61 20 66 6f 72 6d 2c 20 63 dering a form, c
c150: 61 6c 6c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 all this routine
c160: 20 74 6f 20 61 64 64 20 74 68 65 20 41 6e 74 69 to add the Anti
c170: 2d 43 53 52 46 20 74 6f 6b 65 6e 0a 2a 2a 20 61 -CSRF token.** a
c180: 73 20 61 20 68 69 64 64 65 6e 20 65 6c 65 6d 65 s a hidden eleme
c190: 6e 74 20 6f 66 20 74 68 65 20 66 6f 72 6d 2e 0a nt of the form..
c1a0: 2a 2f 0a 76 6f 69 64 20 6c 6f 67 69 6e 5f 69 6e */.void login_in
c1b0: 73 65 72 74 5f 63 73 72 66 5f 73 65 63 72 65 74 sert_csrf_secret
c1c0: 28 76 6f 69 64 29 7b 0a 20 20 40 20 3c 69 6e 70 (void){. @ <inp
c1d0: 75 74 20 74 79 70 65 3d 22 68 69 64 64 65 6e 22 ut type="hidden"
c1e0: 20 6e 61 6d 65 3d 22 63 73 72 66 22 20 76 61 6c name="csrf" val
c1f0: 75 65 3d 22 25 73 28 67 2e 7a 43 73 72 66 54 6f ue="%s(g.zCsrfTo
c200: 6b 65 6e 29 22 20 2f 3e 0a 7d 0a 0a 2f 2a 0a 2a ken)" />.}../*.*
c210: 2a 20 42 65 66 6f 72 65 20 75 73 69 6e 67 20 74 * Before using t
c220: 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 61 20 he results of a
c230: 66 6f 72 6d 2c 20 66 69 72 73 74 20 63 61 6c 6c form, first call
c240: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 74 6f this routine to
c250: 20 76 65 72 69 66 79 0a 2a 2a 20 74 68 61 74 20 verify.** that
c260: 74 68 69 73 20 41 6e 74 69 2d 43 53 52 46 20 74 this Anti-CSRF t
c270: 6f 6b 65 6e 20 69 73 20 70 72 65 73 65 6e 74 20 oken is present
c280: 61 6e 64 20 69 73 20 76 61 6c 69 64 2e 20 20 49 and is valid. I
c290: 66 20 74 68 65 20 41 6e 74 69 2d 43 53 52 46 20 f the Anti-CSRF
c2a0: 74 6f 6b 65 6e 0a 2a 2a 20 69 73 20 6d 69 73 73 token.** is miss
c2b0: 69 6e 67 20 6f 72 20 69 73 20 69 6e 63 6f 72 72 ing or is incorr
c2c0: 65 63 74 2c 20 74 68 61 74 20 69 6e 64 69 63 61 ect, that indica
c2d0: 74 65 73 20 61 20 63 72 6f 73 73 2d 73 69 74 65 tes a cross-site
c2e0: 20 73 63 72 69 70 74 69 6e 67 20 61 74 74 61 63 scripting attac
c2f0: 6b 2e 0a 2a 2a 20 49 66 20 74 68 65 20 65 76 65 k..** If the eve
c300: 6e 74 20 6f 66 20 61 6e 20 61 74 74 61 63 6b 20 nt of an attack
c310: 69 73 20 64 65 74 65 63 74 65 64 2c 20 61 6e 20 is detected, an
c320: 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20 69 73 error message is
c330: 20 67 65 6e 65 72 61 74 65 64 20 61 6e 64 0a 2a generated and.*
c340: 2a 20 61 6c 6c 20 66 75 72 74 68 65 72 20 70 72 * all further pr
c350: 6f 63 65 73 73 69 6e 67 20 69 73 20 61 62 6f 72 ocessing is abor
c360: 74 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 6c 6f 67 ted..*/.void log
c370: 69 6e 5f 76 65 72 69 66 79 5f 63 73 72 66 5f 73 in_verify_csrf_s
c380: 65 63 72 65 74 28 76 6f 69 64 29 7b 0a 20 20 69 ecret(void){. i
c390: 66 28 20 67 2e 6f 6b 43 73 72 66 20 29 20 72 65 f( g.okCsrf ) re
c3a0: 74 75 72 6e 3b 0a 20 20 69 66 28 20 66 6f 73 73 turn;. if( foss
c3b0: 69 6c 5f 73 74 72 63 6d 70 28 50 28 22 63 73 72 il_strcmp(P("csr
c3c0: 66 22 29 2c 20 67 2e 7a 43 73 72 66 54 6f 6b 65 f"), g.zCsrfToke
c3d0: 6e 29 3d 3d 30 20 29 7b 0a 20 20 20 20 67 2e 6f n)==0 ){. g.o
c3e0: 6b 43 73 72 66 20 3d 20 31 3b 0a 20 20 20 20 72 kCsrf = 1;. r
c3f0: 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 66 6f 73 eturn;. }. fos
c400: 73 69 6c 5f 66 61 74 61 6c 28 22 43 72 6f 73 73 sil_fatal("Cross
c410: 2d 73 69 74 65 20 72 65 71 75 65 73 74 20 66 6f -site request fo
c420: 72 67 65 72 79 20 61 74 74 65 6d 70 74 22 29 3b rgery attempt");
c430: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 45 42 50 41 47 .}../*.** WEBPAG
c440: 45 3a 20 72 65 67 69 73 74 65 72 0a 2a 2a 0a 2a E: register.**.*
c450: 2a 20 50 61 67 65 20 74 6f 20 61 6c 6c 6f 77 20 * Page to allow
c460: 75 73 65 72 73 20 74 6f 20 73 65 6c 66 2d 72 65 users to self-re
c470: 67 69 73 74 65 72 2e 20 20 54 68 65 20 22 73 65 gister. The "se
c480: 6c 66 2d 72 65 67 69 73 74 65 72 22 20 73 65 74 lf-register" set
c490: 74 69 6e 67 0a 2a 2a 20 6d 75 73 74 20 62 65 20 ting.** must be
c4a0: 65 6e 61 62 6c 65 64 20 66 6f 72 20 74 68 69 73 enabled for this
c4b0: 20 70 61 67 65 20 74 6f 20 6f 70 65 72 61 74 65 page to operate
c4c0: 2e 0a 2a 2f 0a 76 6f 69 64 20 72 65 67 69 73 74 ..*/.void regist
c4d0: 65 72 5f 70 61 67 65 28 76 6f 69 64 29 7b 0a 20 er_page(void){.
c4e0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 73 const char *zUs
c4f0: 65 72 49 44 2c 20 2a 7a 50 61 73 73 77 64 2c 20 erID, *zPasswd,
c500: 2a 7a 43 6f 6e 66 69 72 6d 2c 20 2a 7a 45 41 64 *zConfirm, *zEAd
c510: 64 72 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 dr;. const char
c520: 20 2a 7a 44 4e 61 6d 65 3b 0a 20 20 75 6e 73 69 *zDName;. unsi
c530: 67 6e 65 64 20 69 6e 74 20 75 53 65 65 64 3b 0a gned int uSeed;.
c540: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 const char *zD
c550: 65 63 6f 64 65 64 3b 0a 20 20 63 68 61 72 20 2a ecoded;. char *
c560: 7a 43 61 70 74 63 68 61 3b 0a 20 20 69 6e 74 20 zCaptcha;. int
c570: 69 45 72 72 4c 69 6e 65 20 3d 20 2d 31 3b 0a 20 iErrLine = -1;.
c580: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 72 const char *zEr
c590: 72 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a r = 0;. char *z
c5a0: 50 65 72 6d 73 3b 20 20 20 20 20 20 20 20 20 20 Perms;
c5b0: 20 20 20 2f 2a 20 50 65 72 6d 69 73 73 69 6f 6e /* Permission
c5c0: 73 20 66 6f 72 20 74 68 65 20 64 65 66 61 75 6c s for the defaul
c5d0: 74 20 75 73 65 72 20 2a 2f 0a 20 20 69 6e 74 20 t user */. int
c5e0: 63 61 6e 44 6f 41 6c 65 72 74 73 20 3d 20 30 3b canDoAlerts = 0;
c5f0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 /* True if
c600: 20 72 65 63 65 69 76 69 6e 67 20 65 6d 61 69 6c receiving email
c610: 20 61 6c 65 72 74 73 20 69 73 20 70 6f 73 73 69 alerts is possi
c620: 62 6c 65 20 2a 2f 0a 20 20 69 66 28 20 21 64 62 ble */. if( !db
c630: 5f 67 65 74 5f 62 6f 6f 6c 65 61 6e 28 22 73 65 _get_boolean("se
c640: 6c 66 2d 72 65 67 69 73 74 65 72 22 2c 20 30 29 lf-register", 0)
c650: 20 29 7b 0a 20 20 20 20 73 74 79 6c 65 5f 68 65 ){. style_he
c660: 61 64 65 72 28 22 52 65 67 69 73 74 72 61 74 69 ader("Registrati
c670: 6f 6e 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 22 on not possible"
c680: 29 3b 0a 20 20 20 20 40 20 3c 70 3e 54 68 69 73 );. @ <p>This
c690: 20 70 72 6f 6a 65 63 74 20 64 6f 65 73 20 6e 6f project does no
c6a0: 74 20 61 6c 6c 6f 77 20 75 73 65 72 20 73 65 6c t allow user sel
c6b0: 66 2d 72 65 67 69 73 74 72 61 74 69 6f 6e 2e 20 f-registration.
c6c0: 50 6c 65 61 73 65 20 63 6f 6e 74 61 63 74 20 74 Please contact t
c6d0: 68 65 0a 20 20 20 20 40 20 70 72 6f 6a 65 63 74 he. @ project
c6e0: 20 61 64 6d 69 6e 69 73 74 72 61 74 6f 72 20 74 administrator t
c6f0: 6f 20 6f 62 74 61 69 6e 20 61 6e 20 61 63 63 6f o obtain an acco
c700: 75 6e 74 2e 3c 2f 70 3e 0a 20 20 20 20 73 74 79 unt.</p>. sty
c710: 6c 65 5f 66 6f 6f 74 65 72 28 29 3b 0a 20 20 20 le_footer();.
c720: 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 7a return;. }. z
c730: 50 65 72 6d 73 20 3d 20 64 62 5f 67 65 74 28 22 Perms = db_get("
c740: 64 65 66 61 75 6c 74 2d 70 65 72 6d 73 22 2c 22 default-perms","
c750: 75 22 29 3b 0a 0a 20 20 2f 2a 20 50 72 6f 6d 70 u");.. /* Promp
c760: 74 20 74 68 65 20 75 73 65 72 20 66 6f 72 20 65 t the user for e
c770: 6d 61 69 6c 20 61 6c 65 72 74 73 20 69 66 20 74 mail alerts if t
c780: 68 69 73 20 72 65 70 6f 73 69 74 6f 72 79 20 69 his repository i
c790: 73 20 63 6f 6e 66 69 67 75 72 65 64 20 66 6f 72 s configured for
c7a0: 0a 20 20 2a 2a 20 65 6d 61 69 6c 20 61 6c 65 72 . ** email aler
c7b0: 74 73 20 61 6e 64 20 69 66 20 74 68 65 20 64 65 ts and if the de
c7c0: 66 61 75 6c 74 20 70 65 72 6d 69 73 73 69 6f 6e fault permission
c7d0: 73 20 69 6e 63 6c 75 64 65 20 22 37 22 20 2a 2f s include "7" */
c7e0: 0a 20 20 63 61 6e 44 6f 41 6c 65 72 74 73 20 3d . canDoAlerts =
c7f0: 20 65 6d 61 69 6c 5f 74 61 62 6c 65 73 5f 65 78 email_tables_ex
c800: 69 73 74 28 29 20 26 26 20 64 62 5f 69 6e 74 28 ist() && db_int(
c810: 30 2c 0a 20 20 20 20 22 53 45 4c 45 43 54 20 66 0,. "SELECT f
c820: 75 6c 6c 63 61 70 28 25 51 29 20 47 4c 4f 42 20 ullcap(%Q) GLOB
c830: 27 2a 37 2a 27 22 2c 20 7a 50 65 72 6d 73 0a 20 '*7*'", zPerms.
c840: 20 29 3b 0a 0a 20 20 7a 55 73 65 72 49 44 20 3d );.. zUserID =
c850: 20 50 44 54 28 22 75 22 2c 22 22 29 3b 0a 20 20 PDT("u","");.
c860: 7a 50 61 73 73 77 64 20 3d 20 50 44 54 28 22 70 zPasswd = PDT("p
c870: 22 2c 22 22 29 3b 0a 20 20 7a 43 6f 6e 66 69 72 ","");. zConfir
c880: 6d 20 3d 20 50 44 54 28 22 63 70 22 2c 22 22 29 m = PDT("cp","")
c890: 3b 0a 20 20 7a 45 41 64 64 72 20 3d 20 50 44 54 ;. zEAddr = PDT
c8a0: 28 22 65 61 22 2c 22 22 29 3b 0a 20 20 7a 44 4e ("ea","");. zDN
c8b0: 61 6d 65 20 3d 20 50 44 54 28 22 64 6e 22 2c 22 ame = PDT("dn","
c8c0: 22 29 3b 0a 0a 20 20 2f 2a 20 54 72 79 20 74 6f ");.. /* Try to
c8d0: 20 6d 61 6b 65 20 61 6e 79 20 73 65 6e 73 65 20 make any sense
c8e0: 66 72 6f 6d 20 75 73 65 72 20 69 6e 70 75 74 2e from user input.
c8f0: 20 2a 2f 0a 20 20 69 66 28 20 50 28 22 6e 65 77 */. if( P("new
c900: 22 29 3d 3d 30 20 7c 7c 20 21 63 67 69 5f 63 73 ")==0 || !cgi_cs
c910: 72 66 5f 73 61 66 65 28 31 29 20 29 7b 0a 20 20 rf_safe(1) ){.
c920: 20 20 2f 2a 20 54 68 69 73 20 69 73 20 6e 6f 74 /* This is not
c930: 20 61 20 76 61 6c 69 64 20 66 6f 72 6d 20 73 75 a valid form su
c940: 62 6d 69 73 73 69 6f 6e 2e 20 20 46 61 6c 6c 20 bmission. Fall
c950: 74 68 72 6f 75 67 68 20 69 6e 74 6f 0a 20 20 20 through into.
c960: 20 2a 2a 20 74 68 65 20 66 6f 72 6d 20 64 69 73 ** the form dis
c970: 70 6c 61 79 20 2a 2f 0a 20 20 7d 65 6c 73 65 20 play */. }else
c980: 69 66 28 20 21 63 61 70 74 63 68 61 5f 69 73 5f if( !captcha_is_
c990: 63 6f 72 72 65 63 74 28 31 29 20 29 7b 0a 20 20 correct(1) ){.
c9a0: 20 20 69 45 72 72 4c 69 6e 65 20 3d 20 36 3b 0a iErrLine = 6;.
c9b0: 20 20 20 20 7a 45 72 72 20 3d 20 22 49 6e 63 6f zErr = "Inco
c9c0: 72 72 65 63 74 20 43 41 50 54 43 48 41 22 3b 0a rrect CAPTCHA";.
c9d0: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 6c }else if( strl
c9e0: 65 6e 28 7a 55 73 65 72 49 44 29 3c 33 20 29 7b en(zUserID)<3 ){
c9f0: 0a 20 20 20 20 69 45 72 72 4c 69 6e 65 20 3d 20 . iErrLine =
ca00: 31 3b 0a 20 20 20 20 7a 45 72 72 20 3d 20 22 55 1;. zErr = "U
ca10: 73 65 72 20 49 44 20 74 6f 6f 20 73 68 6f 72 74 ser ID too short
ca20: 2e 20 4d 75 73 74 20 62 65 20 61 74 20 6c 65 61 . Must be at lea
ca30: 73 74 20 33 20 63 68 61 72 61 63 74 65 72 73 2e st 3 characters.
ca40: 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 73 ";. }else if( s
ca50: 71 6c 69 74 65 33 5f 73 74 72 67 6c 6f 62 28 22 qlite3_strglob("
ca60: 2a 5b 5e 2d 61 2d 7a 41 2d 5a 30 2d 39 5f 2e 5d *[^-a-zA-Z0-9_.]
ca70: 2a 22 2c 7a 55 73 65 72 49 44 29 3d 3d 30 20 29 *",zUserID)==0 )
ca80: 7b 0a 20 20 20 20 69 45 72 72 4c 69 6e 65 20 3d {. iErrLine =
ca90: 20 31 3b 0a 20 20 20 20 7a 45 72 72 20 3d 20 22 1;. zErr = "
caa0: 55 73 65 72 20 49 44 20 6d 61 79 20 6e 6f 74 20 User ID may not
cab0: 63 6f 6e 74 61 69 6e 20 73 70 61 63 65 73 20 6f contain spaces o
cac0: 72 20 73 70 65 63 69 61 6c 20 63 68 61 72 61 63 r special charac
cad0: 74 65 72 73 2e 22 3b 0a 20 20 7d 65 6c 73 65 20 ters.";. }else
cae0: 69 66 28 20 7a 44 4e 61 6d 65 5b 30 5d 3d 3d 30 if( zDName[0]==0
caf0: 20 29 7b 0a 20 20 20 20 69 45 72 72 4c 69 6e 65 ){. iErrLine
cb00: 20 3d 20 32 3b 0a 20 20 20 20 7a 45 72 72 20 3d = 2;. zErr =
cb10: 20 22 52 65 71 75 69 72 65 64 22 3b 0a 20 20 7d "Required";. }
cb20: 65 6c 73 65 20 69 66 28 20 7a 45 41 64 64 72 5b else if( zEAddr[
cb30: 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 69 45 72 0]==0 ){. iEr
cb40: 72 4c 69 6e 65 20 3d 20 33 3b 0a 20 20 20 20 7a rLine = 3;. z
cb50: 45 72 72 20 3d 20 22 52 65 71 75 69 72 65 64 22 Err = "Required"
cb60: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 65 6d ;. }else if( em
cb70: 61 69 6c 5f 63 6f 70 79 5f 61 64 64 72 28 7a 45 ail_copy_addr(zE
cb80: 41 64 64 72 2c 30 29 3d 3d 30 20 29 7b 0a 20 20 Addr,0)==0 ){.
cb90: 20 20 69 45 72 72 4c 69 6e 65 20 3d 20 33 3b 0a iErrLine = 3;.
cba0: 20 20 20 20 7a 45 72 72 20 3d 20 22 4e 6f 74 20 zErr = "Not
cbb0: 61 20 76 61 6c 69 64 20 65 6d 61 69 6c 20 61 64 a valid email ad
cbc0: 64 72 65 73 73 22 3b 0a 20 20 7d 65 6c 73 65 20 dress";. }else
cbd0: 69 66 28 20 73 74 72 6c 65 6e 28 7a 50 61 73 73 if( strlen(zPass
cbe0: 77 64 29 3c 36 20 29 7b 0a 20 20 20 20 69 45 72 wd)<6 ){. iEr
cbf0: 72 4c 69 6e 65 20 3d 20 34 3b 0a 20 20 20 20 7a rLine = 4;. z
cc00: 45 72 72 20 3d 20 22 50 61 73 73 77 6f 72 64 20 Err = "Password
cc10: 6d 75 73 74 20 62 65 20 61 74 20 6c 65 61 73 74 must be at least
cc20: 20 36 20 63 68 61 72 61 63 74 65 72 73 20 6c 6f 6 characters lo
cc30: 6e 67 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 ng";. }else if(
cc40: 20 66 6f 73 73 69 6c 5f 73 74 72 63 6d 70 28 7a fossil_strcmp(z
cc50: 50 61 73 73 77 64 2c 7a 43 6f 6e 66 69 72 6d 29 Passwd,zConfirm)
cc60: 21 3d 30 20 29 7b 0a 20 20 20 20 69 45 72 72 4c !=0 ){. iErrL
cc70: 69 6e 65 20 3d 20 35 3b 0a 20 20 20 20 7a 45 72 ine = 5;. zEr
cc80: 72 20 3d 20 22 50 61 73 73 77 6f 72 64 73 20 64 r = "Passwords d
cc90: 6f 20 6e 6f 74 20 6d 61 74 63 68 22 3b 0a 20 20 o not match";.
cca0: 7d 65 6c 73 65 20 69 66 28 20 64 62 5f 65 78 69 }else if( db_exi
ccb0: 73 74 73 28 22 53 45 4c 45 43 54 20 31 20 46 52 sts("SELECT 1 FR
ccc0: 4f 4d 20 75 73 65 72 20 57 48 45 52 45 20 6c 6f OM user WHERE lo
ccd0: 67 69 6e 3d 25 51 22 2c 20 7a 55 73 65 72 49 44 gin=%Q", zUserID
cce0: 29 20 29 7b 0a 20 20 20 20 69 45 72 72 4c 69 6e ) ){. iErrLin
ccf0: 65 20 3d 20 31 3b 0a 20 20 20 20 7a 45 72 72 20 e = 1;. zErr
cd00: 3d 20 22 54 68 69 73 20 55 73 65 72 20 49 44 20 = "This User ID
cd10: 69 73 20 61 6c 72 65 61 64 79 20 74 61 6b 65 6e is already taken
cd20: 2e 20 43 68 6f 6f 73 65 20 73 6f 6d 65 74 68 69 . Choose somethi
cd30: 6e 67 20 64 69 66 66 65 72 65 6e 74 2e 22 3b 0a ng different.";.
cd40: 20 20 7d 65 6c 73 65 20 69 66 28 20 64 62 5f 65 }else if( db_e
cd50: 78 69 73 74 73 28 22 53 45 4c 45 43 54 20 31 20 xists("SELECT 1
cd60: 46 52 4f 4d 20 75 73 65 72 20 57 48 45 52 45 20 FROM user WHERE
cd70: 69 6e 66 6f 20 4c 49 4b 45 20 27 25 25 25 71 25 info LIKE '%%%q%
cd80: 25 27 22 2c 20 7a 45 41 64 64 72 29 20 29 7b 0a %'", zEAddr) ){.
cd90: 20 20 20 20 69 45 72 72 4c 69 6e 65 20 3d 20 33 iErrLine = 3
cda0: 3b 0a 20 20 20 20 7a 45 72 72 20 3d 20 22 54 68 ;. zErr = "Th
cdb0: 69 73 20 61 64 64 72 65 73 73 20 69 73 20 61 6c is address is al
cdc0: 72 65 61 64 79 20 75 73 65 64 2e 22 3b 0a 20 20 ready used.";.
cdd0: 7d 65 6c 73 65 7b 0a 20 20 20 20 42 6c 6f 62 20 }else{. Blob
cde0: 73 71 6c 3b 0a 20 20 20 20 69 6e 74 20 75 69 64 sql;. int uid
cdf0: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 50 61 73 ;. char *zPas
ce00: 73 20 3d 20 73 68 61 31 5f 73 68 61 72 65 64 5f s = sha1_shared_
ce10: 73 65 63 72 65 74 28 7a 50 61 73 73 77 64 2c 20 secret(zPasswd,
ce20: 7a 55 73 65 72 49 44 2c 20 30 29 3b 0a 20 20 20 zUserID, 0);.
ce30: 20 62 6c 6f 62 5f 69 6e 69 74 28 26 73 71 6c 2c blob_init(&sql,
ce40: 20 30 2c 20 30 29 3b 0a 20 20 20 20 62 6c 6f 62 0, 0);. blob
ce50: 5f 61 70 70 65 6e 64 5f 73 71 6c 28 26 73 71 6c _append_sql(&sql
ce60: 2c 0a 20 20 20 20 20 20 20 22 49 4e 53 45 52 54 ,. "INSERT
ce70: 20 49 4e 54 4f 20 75 73 65 72 28 6c 6f 67 69 6e INTO user(login
ce80: 2c 70 77 2c 63 61 70 2c 69 6e 66 6f 2c 6d 74 69 ,pw,cap,info,mti
ce90: 6d 65 29 5c 6e 22 0a 20 20 20 20 20 20 20 22 56 me)\n". "V
cea0: 41 4c 55 45 53 28 25 51 2c 25 51 2c 25 51 2c 22 ALUES(%Q,%Q,%Q,"
ceb0: 0a 20 20 20 20 20 20 20 22 27 25 71 20 3c 25 71 . "'%q <%q
cec0: 3e 5c 6e 73 65 6c 66 2d 72 65 67 69 73 74 65 72 >\nself-register
ced0: 20 66 72 6f 6d 20 69 70 20 25 71 20 6f 6e 20 27 from ip %q on '
cee0: 7c 7c 64 61 74 65 74 69 6d 65 28 27 6e 6f 77 27 ||datetime('now'
cef0: 29 2c 6e 6f 77 28 29 29 22 2c 0a 20 20 20 20 20 ),now())",.
cf00: 20 20 7a 55 73 65 72 49 44 2c 20 7a 50 61 73 73 zUserID, zPass
cf10: 2c 20 7a 50 65 72 6d 73 2c 20 7a 44 4e 61 6d 65 , zPerms, zDName
cf20: 2c 20 7a 45 41 64 64 72 2c 20 67 2e 7a 49 70 41 , zEAddr, g.zIpA
cf30: 64 64 72 29 3b 0a 20 20 20 20 66 6f 73 73 69 6c ddr);. fossil
cf40: 5f 66 72 65 65 28 7a 50 61 73 73 29 3b 0a 20 20 _free(zPass);.
cf50: 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 db_multi_exec(
cf60: 22 25 73 22 2c 20 62 6c 6f 62 5f 73 71 6c 5f 74 "%s", blob_sql_t
cf70: 65 78 74 28 26 73 71 6c 29 29 3b 0a 20 20 20 20 ext(&sql));.
cf80: 75 69 64 20 3d 20 64 62 5f 69 6e 74 28 30 2c 20 uid = db_int(0,
cf90: 22 53 45 4c 45 43 54 20 75 69 64 20 46 52 4f 4d "SELECT uid FROM
cfa0: 20 75 73 65 72 20 57 48 45 52 45 20 6c 6f 67 69 user WHERE logi
cfb0: 6e 3d 25 51 22 2c 20 7a 55 73 65 72 49 44 29 3b n=%Q", zUserID);
cfc0: 0a 20 20 20 20 6c 6f 67 69 6e 5f 73 65 74 5f 75 . login_set_u
cfd0: 73 65 72 5f 63 6f 6f 6b 69 65 28 7a 55 73 65 72 ser_cookie(zUser
cfe0: 49 44 2c 20 75 69 64 2c 20 4e 55 4c 4c 29 3b 0a ID, uid, NULL);.
cff0: 20 20 20 20 69 66 28 20 63 61 6e 44 6f 41 6c 65 if( canDoAle
d000: 72 74 73 20 26 26 20 61 74 6f 69 28 50 44 28 22 rts && atoi(PD("
d010: 61 6c 65 72 74 73 22 2c 22 31 22 29 29 21 3d 30 alerts","1"))!=0
d020: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c 73 ){. /* Als
d030: 6f 20 6d 61 6b 65 20 74 68 65 20 6e 65 77 20 75 o make the new u
d040: 73 65 72 20 61 20 73 75 62 73 63 72 69 62 65 72 ser a subscriber
d050: 2e 20 2a 2f 0a 20 20 20 20 20 20 42 6c 6f 62 20 . */. Blob
d060: 68 64 72 2c 20 62 6f 64 79 3b 0a 20 20 20 20 20 hdr, body;.
d070: 20 45 6d 61 69 6c 53 65 6e 64 65 72 20 2a 70 53 EmailSender *pS
d080: 65 6e 64 65 72 3b 0a 20 20 20 20 20 20 73 71 6c ender;. sql
d090: 69 74 65 33 5f 69 6e 74 36 34 20 69 64 3b 20 20 ite3_int64 id;
d0a0: 20 2f 2a 20 4e 65 77 20 73 75 62 73 63 72 69 62 /* New subscrib
d0b0: 65 72 20 49 64 20 2a 2f 0a 20 20 20 20 20 20 63 er Id */. c
d0c0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 6f 64 65 onst char *zCode
d0d0: 3b 20 20 2f 2a 20 4e 65 77 20 73 75 62 73 63 72 ; /* New subscr
d0e0: 69 62 65 72 20 63 6f 64 65 20 28 69 6e 20 68 65 iber code (in he
d0f0: 78 29 20 2a 2f 0a 20 20 20 20 20 20 63 6f 6e 73 x) */. cons
d100: 74 20 63 68 61 72 20 2a 7a 47 6f 74 6f 20 3d 20 t char *zGoto =
d110: 50 28 22 67 22 29 3b 0a 20 20 20 20 20 20 69 6e P("g");. in
d120: 74 20 6e 73 75 62 20 3d 20 30 3b 0a 20 20 20 20 t nsub = 0;.
d130: 20 20 63 68 61 72 20 73 73 75 62 5b 32 30 5d 3b char ssub[20];
d140: 0a 20 20 20 20 20 20 73 73 75 62 5b 6e 73 75 62 . ssub[nsub
d150: 2b 2b 5d 20 3d 20 27 61 27 3b 0a 20 20 20 20 20 ++] = 'a';.
d160: 20 69 66 28 20 67 2e 70 65 72 6d 2e 52 65 61 64 if( g.perm.Read
d170: 20 29 20 20 20 20 73 73 75 62 5b 6e 73 75 62 2b ) ssub[nsub+
d180: 2b 5d 20 3d 20 27 63 27 3b 0a 20 20 20 20 20 20 +] = 'c';.
d190: 69 66 28 20 67 2e 70 65 72 6d 2e 52 64 46 6f 72 if( g.perm.RdFor
d1a0: 75 6d 20 29 20 73 73 75 62 5b 6e 73 75 62 2b 2b um ) ssub[nsub++
d1b0: 5d 20 3d 20 27 66 27 3b 0a 20 20 20 20 20 20 69 ] = 'f';. i
d1c0: 66 28 20 67 2e 70 65 72 6d 2e 52 64 54 6b 74 20 f( g.perm.RdTkt
d1d0: 29 20 20 20 73 73 75 62 5b 6e 73 75 62 2b 2b 5d ) ssub[nsub++]
d1e0: 20 3d 20 27 74 27 3b 0a 20 20 20 20 20 20 69 66 = 't';. if
d1f0: 28 20 67 2e 70 65 72 6d 2e 52 64 57 69 6b 69 20 ( g.perm.RdWiki
d200: 29 20 20 73 73 75 62 5b 6e 73 75 62 2b 2b 5d 20 ) ssub[nsub++]
d210: 3d 20 27 77 27 3b 0a 20 20 20 20 20 20 73 73 75 = 'w';. ssu
d220: 62 5b 6e 73 75 62 5d 20 3d 20 30 3b 0a 20 20 20 b[nsub] = 0;.
d230: 20 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 65 63 db_multi_exec
d240: 28 0a 20 20 20 20 20 20 20 20 22 49 4e 53 45 52 (. "INSER
d250: 54 20 49 4e 54 4f 20 73 75 62 73 63 72 69 62 65 T INTO subscribe
d260: 72 28 73 65 6d 61 69 6c 2c 73 75 6e 61 6d 65 2c r(semail,suname,
d270: 22 0a 20 20 20 20 20 20 20 20 22 20 20 73 76 65 ". " sve
d280: 72 69 66 69 65 64 2c 73 64 6f 6e 6f 74 63 61 6c rified,sdonotcal
d290: 6c 2c 73 64 69 67 65 73 74 2c 73 73 75 62 2c 73 l,sdigest,ssub,s
d2a0: 63 74 69 6d 65 2c 6d 74 69 6d 65 2c 73 6d 69 70 ctime,mtime,smip
d2b0: 29 22 0a 20 20 20 20 20 20 20 20 22 56 41 4c 55 )". "VALU
d2c0: 45 53 28 25 51 2c 25 51 2c 25 64 2c 30 2c 25 64 ES(%Q,%Q,%d,0,%d
d2d0: 2c 25 51 2c 6e 6f 77 28 29 2c 6e 6f 77 28 29 2c ,%Q,now(),now(),
d2e0: 25 51 29 22 2c 0a 20 20 20 20 20 20 20 20 2f 2a %Q)",. /*
d2f0: 20 73 65 6d 61 69 6c 20 2a 2f 20 20 20 20 7a 45 semail */ zE
d300: 41 64 64 72 2c 0a 20 20 20 20 20 20 20 20 2f 2a Addr,. /*
d310: 20 73 75 6e 61 6d 65 20 2a 2f 20 20 20 20 7a 55 suname */ zU
d320: 73 65 72 49 44 2c 0a 20 20 20 20 20 20 20 20 2f serID,. /
d330: 2a 20 73 76 65 72 69 66 69 65 64 20 2a 2f 20 30 * sverified */ 0
d340: 2c 0a 20 20 20 20 20 20 20 20 2f 2a 20 73 64 69 ,. /* sdi
d350: 67 65 73 74 20 2a 2f 20 20 20 30 2c 0a 20 20 20 gest */ 0,.
d360: 20 20 20 20 20 2f 2a 20 73 73 75 62 20 2a 2f 20 /* ssub */
d370: 20 20 20 20 20 73 73 75 62 2c 0a 20 20 20 20 20 ssub,.
d380: 20 20 20 2f 2a 20 73 6d 69 70 20 2a 2f 20 20 20 /* smip */
d390: 20 20 20 67 2e 7a 49 70 41 64 64 72 0a 20 20 20 g.zIpAddr.
d3a0: 20 20 20 29 3b 0a 20 20 20 20 20 20 69 64 20 3d );. id =
d3b0: 20 64 62 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f db_last_insert_
d3c0: 72 6f 77 69 64 28 29 3b 0a 20 20 20 20 20 20 7a rowid();. z
d3d0: 43 6f 64 65 20 3d 20 64 62 5f 74 65 78 74 28 30 Code = db_text(0
d3e0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 22 53 45 ,. "SE
d3f0: 4c 45 43 54 20 68 65 78 28 73 75 62 73 63 72 69 LECT hex(subscri
d400: 62 65 72 43 6f 64 65 29 20 46 52 4f 4d 20 73 75 berCode) FROM su
d410: 62 73 63 72 69 62 65 72 20 57 48 45 52 45 20 73 bscriber WHERE s
d420: 75 62 73 63 72 69 62 65 72 49 64 3d 25 6c 6c 64 ubscriberId=%lld
d430: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 69 64 ",. id
d440: 29 3b 0a 20 20 20 20 20 20 2f 2a 20 41 20 76 65 );. /* A ve
d450: 72 69 66 69 63 61 74 69 6f 6e 20 65 6d 61 69 6c rification email
d460: 20 2a 2f 0a 20 20 20 20 20 20 70 53 65 6e 64 65 */. pSende
d470: 72 20 3d 20 65 6d 61 69 6c 5f 73 65 6e 64 65 72 r = email_sender
d480: 5f 6e 65 77 28 30 2c 30 29 3b 0a 20 20 20 20 20 _new(0,0);.
d490: 20 62 6c 6f 62 5f 69 6e 69 74 28 26 68 64 72 2c blob_init(&hdr,
d4a0: 30 2c 30 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62 0,0);. blob
d4b0: 5f 69 6e 69 74 28 26 62 6f 64 79 2c 30 2c 30 29 _init(&body,0,0)
d4c0: 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 ;. blob_app
d4d0: 65 6e 64 66 28 26 68 64 72 2c 20 22 54 6f 3a 20 endf(&hdr, "To:
d4e0: 3c 25 73 3e 5c 6e 22 2c 20 7a 45 41 64 64 72 29 <%s>\n", zEAddr)
d4f0: 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 ;. blob_app
d500: 65 6e 64 66 28 26 68 64 72 2c 20 22 53 75 62 6a endf(&hdr, "Subj
d510: 65 63 74 3a 20 53 75 62 73 63 72 69 70 74 69 6f ect: Subscriptio
d520: 6e 20 76 65 72 69 66 69 63 61 74 69 6f 6e 5c 6e n verification\n
d530: 22 29 3b 0a 20 20 20 20 20 20 65 6d 61 69 6c 5f ");. email_
d540: 61 70 70 65 6e 64 5f 63 6f 6e 66 69 72 6d 61 74 append_confirmat
d550: 69 6f 6e 5f 6d 65 73 73 61 67 65 28 26 62 6f 64 ion_message(&bod
d560: 79 2c 20 7a 43 6f 64 65 29 3b 0a 20 20 20 20 20 y, zCode);.
d570: 20 65 6d 61 69 6c 5f 73 65 6e 64 28 70 53 65 6e email_send(pSen
d580: 64 65 72 2c 20 26 68 64 72 2c 20 26 62 6f 64 79 der, &hdr, &body
d590: 2c 20 30 29 3b 0a 20 20 20 20 20 20 73 74 79 6c , 0);. styl
d5a0: 65 5f 68 65 61 64 65 72 28 22 45 6d 61 69 6c 20 e_header("Email
d5b0: 56 65 72 69 66 69 63 61 74 69 6f 6e 22 29 3b 0a Verification");.
d5c0: 20 20 20 20 20 20 69 66 28 20 70 53 65 6e 64 65 if( pSende
d5d0: 72 2d 3e 7a 45 72 72 20 29 7b 0a 20 20 20 20 20 r->zErr ){.
d5e0: 20 20 20 40 20 3c 68 31 3e 49 6e 74 65 72 6e 61 @ <h1>Interna
d5f0: 6c 20 45 72 72 6f 72 3c 2f 68 31 3e 0a 20 20 20 l Error</h1>.
d600: 20 20 20 20 20 40 20 3c 70 3e 54 68 65 20 66 6f @ <p>The fo
d610: 6c 6c 6f 77 69 6e 67 20 69 6e 74 65 72 6e 61 6c llowing internal
d620: 20 65 72 72 6f 72 20 77 61 73 20 65 6e 63 6f 75 error was encou
d630: 6e 74 65 72 65 64 20 77 68 69 6c 65 20 74 72 79 ntered while try
d640: 69 6e 67 0a 20 20 20 20 20 20 20 20 40 20 74 6f ing. @ to
d650: 20 73 65 6e 64 20 74 68 65 20 63 6f 6e 66 69 72 send the confir
d660: 6d 61 74 69 6f 6e 20 65 6d 61 69 6c 3a 0a 20 20 mation email:.
d670: 20 20 20 20 20 20 40 20 3c 62 6c 6f 63 6b 71 75 @ <blockqu
d680: 6f 74 65 3e 3c 70 72 65 3e 0a 20 20 20 20 20 20 ote><pre>.
d690: 20 20 40 20 25 68 28 70 53 65 6e 64 65 72 2d 3e @ %h(pSender->
d6a0: 7a 45 72 72 29 0a 20 20 20 20 20 20 20 20 40 20 zErr). @
d6b0: 3c 2f 70 72 65 3e 3c 2f 62 6c 6f 63 6b 71 75 6f </pre></blockquo
d6c0: 74 65 3e 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b te>. }else{
d6d0: 0a 20 20 20 20 20 20 20 20 40 20 3c 70 3e 41 6e . @ <p>An
d6e0: 20 65 6d 61 69 6c 20 68 61 73 20 62 65 65 6e 20 email has been
d6f0: 73 65 6e 74 20 74 6f 20 22 25 68 28 7a 45 41 64 sent to "%h(zEAd
d700: 64 72 29 22 2e 20 54 68 61 74 20 65 6d 61 69 6c dr)". That email
d710: 20 63 6f 6e 74 61 69 6e 73 20 61 0a 20 20 20 20 contains a.
d720: 20 20 20 20 40 20 68 79 70 65 72 6c 69 6e 6b 20 @ hyperlink
d730: 74 68 61 74 20 79 6f 75 20 6d 75 73 74 20 63 6c that you must cl
d740: 69 63 6b 20 6f 6e 20 69 6e 20 6f 72 64 65 72 20 ick on in order
d750: 74 6f 20 61 63 74 69 76 61 74 65 20 79 6f 75 72 to activate your
d760: 0a 20 20 20 20 20 20 20 20 40 20 73 75 62 73 63 . @ subsc
d770: 72 69 70 74 69 6f 6e 2e 3c 2f 70 3e 0a 20 20 20 ription.</p>.
d780: 20 20 20 7d 0a 20 20 20 20 20 20 65 6d 61 69 6c }. email
d790: 5f 73 65 6e 64 65 72 5f 66 72 65 65 28 70 53 65 _sender_free(pSe
d7a0: 6e 64 65 72 29 3b 0a 20 20 20 20 20 20 69 66 28 nder);. if(
d7b0: 20 7a 47 6f 74 6f 20 29 7b 0a 20 20 20 20 20 20 zGoto ){.
d7c0: 20 20 40 20 3c 70 3e 3c 61 20 68 72 65 66 3d 27 @ <p><a href='
d7d0: 25 68 28 7a 47 6f 74 6f 29 27 3e 43 6f 6e 74 69 %h(zGoto)'>Conti
d7e0: 6e 75 65 3c 2f 61 3e 0a 20 20 20 20 20 20 7d 0a nue</a>. }.
d7f0: 20 20 20 20 20 20 73 74 79 6c 65 5f 66 6f 6f 74 style_foot
d800: 65 72 28 29 3b 0a 20 20 20 20 20 20 72 65 74 75 er();. retu
d810: 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 rn;. }. re
d820: 64 69 72 65 63 74 5f 74 6f 5f 67 28 29 3b 0a 20 direct_to_g();.
d830: 20 7d 0a 0a 20 20 2f 2a 20 50 72 65 70 61 72 65 }.. /* Prepare
d840: 20 74 68 65 20 63 61 70 74 63 68 61 2e 20 2a 2f the captcha. */
d850: 0a 20 20 75 53 65 65 64 20 3d 20 63 61 70 74 63 . uSeed = captc
d860: 68 61 5f 73 65 65 64 28 29 3b 0a 20 20 7a 44 65 ha_seed();. zDe
d870: 63 6f 64 65 64 20 3d 20 63 61 70 74 63 68 61 5f coded = captcha_
d880: 64 65 63 6f 64 65 28 75 53 65 65 64 29 3b 0a 20 decode(uSeed);.
d890: 20 7a 43 61 70 74 63 68 61 20 3d 20 63 61 70 74 zCaptcha = capt
d8a0: 63 68 61 5f 72 65 6e 64 65 72 28 7a 44 65 63 6f cha_render(zDeco
d8b0: 64 65 64 29 3b 0a 0a 20 20 73 74 79 6c 65 5f 68 ded);.. style_h
d8c0: 65 61 64 65 72 28 22 52 65 67 69 73 74 65 72 22 eader("Register"
d8d0: 29 3b 0a 20 20 2f 2a 20 50 72 69 6e 74 20 6f 75 );. /* Print ou
d8e0: 74 20 74 68 65 20 72 65 67 69 73 74 72 61 74 69 t the registrati
d8f0: 6f 6e 20 66 6f 72 6d 2e 20 2a 2f 0a 20 20 66 6f on form. */. fo
d900: 72 6d 5f 62 65 67 69 6e 28 30 2c 20 22 25 52 2f rm_begin(0, "%R/
d910: 72 65 67 69 73 74 65 72 22 29 3b 0a 20 20 69 66 register");. if
d920: 28 20 50 28 22 67 22 29 20 29 7b 0a 20 20 20 20 ( P("g") ){.
d930: 40 20 3c 69 6e 70 75 74 20 74 79 70 65 3d 22 68 @ <input type="h
d940: 69 64 64 65 6e 22 20 6e 61 6d 65 3d 22 67 22 20 idden" name="g"
d950: 76 61 6c 75 65 3d 22 25 68 28 50 28 22 67 22 29 value="%h(P("g")
d960: 29 22 20 2f 3e 0a 20 20 7d 0a 20 20 40 20 3c 70 )" />. }. @ <p
d970: 3e 3c 69 6e 70 75 74 20 74 79 70 65 3d 22 68 69 ><input type="hi
d980: 64 64 65 6e 22 20 6e 61 6d 65 3d 22 63 61 70 74 dden" name="capt
d990: 63 68 61 73 65 65 64 22 20 76 61 6c 75 65 3d 22 chaseed" value="
d9a0: 25 75 28 75 53 65 65 64 29 22 20 2f 3e 0a 20 20 %u(uSeed)" />.
d9b0: 40 20 3c 74 61 62 6c 65 20 63 6c 61 73 73 3d 22 @ <table class="
d9c0: 6c 6f 67 69 6e 5f 6f 75 74 22 3e 0a 20 20 40 20 login_out">. @
d9d0: 3c 74 72 3e 0a 20 20 40 20 20 20 3c 74 64 20 63 <tr>. @ <td c
d9e0: 6c 61 73 73 3d 22 66 6f 72 6d 5f 6c 61 62 65 6c lass="form_label
d9f0: 22 20 61 6c 69 67 6e 3d 22 72 69 67 68 74 22 3e " align="right">
da00: 55 73 65 72 20 49 44 3a 3c 2f 74 64 3e 0a 20 20 User ID:</td>.
da10: 40 20 20 20 3c 74 64 3e 3c 69 6e 70 75 74 20 74 @ <td><input t
da20: 79 70 65 3d 22 74 65 78 74 22 20 6e 61 6d 65 3d ype="text" name=
da30: 22 75 22 20 76 61 6c 75 65 3d 22 25 68 28 7a 55 "u" value="%h(zU
da40: 73 65 72 49 44 29 22 20 73 69 7a 65 3d 22 33 30 serID)" size="30
da50: 22 3e 3c 2f 74 64 3e 0a 20 20 69 66 28 20 69 45 "></td>. if( iE
da60: 72 72 4c 69 6e 65 3d 3d 31 20 29 7b 0a 20 20 20 rrLine==1 ){.
da70: 20 40 20 20 20 3c 74 64 3e 3c 73 70 61 6e 20 63 @ <td><span c
da80: 6c 61 73 73 3d 27 6c 6f 67 69 6e 45 72 72 6f 72 lass='loginError
da90: 27 3e 26 6c 61 72 72 3b 20 25 68 28 7a 45 72 72 '>← %h(zErr
daa0: 29 3c 2f 73 70 61 6e 3e 3c 2f 74 64 3e 0a 20 20 )</span></td>.
dab0: 7d 0a 20 20 40 20 3c 2f 74 72 3e 0a 20 20 40 20 }. @ </tr>. @
dac0: 3c 74 72 3e 0a 20 20 40 20 20 20 3c 74 64 20 63 <tr>. @ <td c
dad0: 6c 61 73 73 3d 22 66 6f 72 6d 5f 6c 61 62 65 6c lass="form_label
dae0: 22 20 61 6c 69 67 6e 3d 22 72 69 67 68 74 22 3e " align="right">
daf0: 44 69 73 70 6c 61 79 20 4e 61 6d 65 3a 3c 2f 74 Display Name:</t
db00: 64 3e 0a 20 20 40 20 20 20 3c 74 64 3e 3c 69 6e d>. @ <td><in
db10: 70 75 74 20 74 79 70 65 3d 22 74 65 78 74 22 20 put type="text"
db20: 6e 61 6d 65 3d 22 64 6e 22 20 76 61 6c 75 65 3d name="dn" value=
db30: 22 25 68 28 7a 44 4e 61 6d 65 29 22 20 73 69 7a "%h(zDName)" siz
db40: 65 3d 22 33 30 22 3e 3c 2f 74 64 3e 0a 20 20 69 e="30"></td>. i
db50: 66 28 20 69 45 72 72 4c 69 6e 65 3d 3d 32 20 29 f( iErrLine==2 )
db60: 7b 0a 20 20 20 20 40 20 20 20 3c 74 64 3e 3c 73 {. @ <td><s
db70: 70 61 6e 20 63 6c 61 73 73 3d 27 6c 6f 67 69 6e pan class='login
db80: 45 72 72 6f 72 27 3e 26 6c 61 72 72 3b 20 25 68 Error'>← %h
db90: 28 7a 45 72 72 29 3c 2f 73 70 61 6e 3e 3c 2f 74 (zErr)</span></t
dba0: 64 3e 0a 20 20 7d 0a 20 20 40 20 3c 2f 74 72 3e d>. }. @ </tr>
dbb0: 0a 20 20 40 20 3c 74 72 3e 0a 20 20 40 20 20 20 . @ <tr>. @
dbc0: 3c 74 64 20 63 6c 61 73 73 3d 22 66 6f 72 6d 5f <td class="form_
dbd0: 6c 61 62 65 6c 22 20 61 6c 69 67 6e 3d 22 72 69 label" align="ri
dbe0: 67 68 74 22 3e 45 6d 61 69 6c 20 41 64 64 72 65 ght">Email Addre
dbf0: 73 73 3a 3c 2f 74 64 3e 0a 20 20 40 20 20 20 3c ss:</td>. @ <
dc00: 74 64 3e 3c 69 6e 70 75 74 20 74 79 70 65 3d 22 td><input type="
dc10: 74 65 78 74 22 20 6e 61 6d 65 3d 22 65 61 22 20 text" name="ea"
dc20: 76 61 6c 75 65 3d 22 25 68 28 7a 45 41 64 64 72 value="%h(zEAddr
dc30: 29 22 20 73 69 7a 65 3d 22 33 30 22 3e 3c 2f 74 )" size="30"></t
dc40: 64 3e 0a 20 20 69 66 28 20 69 45 72 72 4c 69 6e d>. if( iErrLin
dc50: 65 3d 3d 33 20 29 7b 0a 20 20 20 20 40 20 20 20 e==3 ){. @
dc60: 3c 74 64 3e 3c 73 70 61 6e 20 63 6c 61 73 73 3d <td><span class=
dc70: 27 6c 6f 67 69 6e 45 72 72 6f 72 27 3e 26 6c 61 'loginError'>&la
dc80: 72 72 3b 20 25 68 28 7a 45 72 72 29 3c 2f 73 70 rr; %h(zErr)</sp
dc90: 61 6e 3e 3c 2f 74 64 3e 0a 20 20 7d 0a 20 20 40 an></td>. }. @
dca0: 20 3c 2f 74 72 3e 0a 20 20 69 66 28 20 63 61 6e </tr>. if( can
dcb0: 44 6f 41 6c 65 72 74 73 20 29 7b 0a 20 20 20 20 DoAlerts ){.
dcc0: 69 6e 74 20 61 20 3d 20 61 74 6f 69 28 50 44 28 int a = atoi(PD(
dcd0: 22 61 6c 65 72 74 73 22 2c 22 31 22 29 29 3b 0a "alerts","1"));.
dce0: 20 20 20 20 40 20 3c 74 72 3e 0a 20 20 20 20 40 @ <tr>. @
dcf0: 20 20 20 3c 74 64 20 63 6c 61 73 73 3d 22 66 6f <td class="fo
dd00: 72 6d 5f 6c 61 62 65 6c 22 20 61 6c 69 67 6e 3d rm_label" align=
dd10: 22 72 69 67 68 74 22 3e 52 65 63 65 69 76 65 20 "right">Receive
dd20: 45 6d 61 69 6c 20 41 6c 65 72 74 73 3f 3c 2f 74 Email Alerts?</t
dd30: 64 3e 0a 20 20 20 20 40 20 20 20 3c 74 64 3e 3c d>. @ <td><
dd40: 73 65 6c 65 63 74 20 73 69 7a 65 3d 27 31 27 20 select size='1'
dd50: 6e 61 6d 65 3d 27 61 6c 65 72 74 73 27 3e 0a 20 name='alerts'>.
dd60: 20 20 20 40 20 20 20 20 20 20 20 3c 6f 70 74 69 @ <opti
dd70: 6f 6e 20 76 61 6c 75 65 3d 22 31 22 20 25 73 28 on value="1" %s(
dd80: 61 3f 22 73 65 6c 65 63 74 65 64 22 3a 22 22 29 a?"selected":"")
dd90: 3e 59 65 73 3c 2f 6f 70 74 69 6f 6e 3e 0a 20 20 >Yes</option>.
dda0: 20 20 40 20 20 20 20 20 20 20 3c 6f 70 74 69 6f @ <optio
ddb0: 6e 20 76 61 6c 75 65 3d 22 30 22 20 25 73 28 21 n value="0" %s(!
ddc0: 61 3f 22 73 65 6c 65 63 74 65 64 22 3a 22 22 29 a?"selected":"")
ddd0: 3e 4e 6f 3c 2f 6f 70 74 69 6f 6e 3e 0a 20 20 20 >No</option>.
dde0: 20 40 20 20 20 3c 2f 73 65 6c 65 63 74 3e 3c 2f @ </select></
ddf0: 74 64 3e 3c 2f 74 72 3e 0a 20 20 7d 0a 20 20 40 td></tr>. }. @
de00: 20 3c 74 72 3e 0a 20 20 40 20 20 20 3c 74 64 20 <tr>. @ <td
de10: 63 6c 61 73 73 3d 22 66 6f 72 6d 5f 6c 61 62 65 class="form_labe
de20: 6c 22 20 61 6c 69 67 6e 3d 22 72 69 67 68 74 22 l" align="right"
de30: 3e 50 61 73 73 77 6f 72 64 3a 3c 2f 74 64 3e 0a >Password:</td>.
de40: 20 20 40 20 20 20 3c 74 64 3e 3c 69 6e 70 75 74 @ <td><input
de50: 20 74 79 70 65 3d 22 70 61 73 73 77 6f 72 64 22 type="password"
de60: 20 6e 61 6d 65 3d 22 70 22 20 76 61 6c 75 65 3d name="p" value=
de70: 22 25 68 28 7a 50 61 73 73 77 64 29 22 20 73 69 "%h(zPasswd)" si
de80: 7a 65 3d 22 33 30 22 3e 3c 2f 74 64 3e 0a 20 20 ze="30"></td>.
de90: 69 66 28 20 69 45 72 72 4c 69 6e 65 3d 3d 34 20 if( iErrLine==4
dea0: 29 7b 0a 20 20 20 20 40 20 20 20 3c 74 64 3e 3c ){. @ <td><
deb0: 73 70 61 6e 20 63 6c 61 73 73 3d 27 6c 6f 67 69 span class='logi
dec0: 6e 45 72 72 6f 72 27 3e 26 6c 61 72 72 3b 20 25 nError'>← %
ded0: 68 28 7a 45 72 72 29 3c 2f 73 70 61 6e 3e 3c 2f h(zErr)</span></
dee0: 74 64 3e 0a 20 20 7d 0a 20 20 40 20 3c 2f 74 72 td>. }. @ </tr
def0: 3e 0a 20 20 40 20 3c 74 72 3e 0a 20 20 40 20 20 >. @ <tr>. @
df00: 20 3c 74 64 20 63 6c 61 73 73 3d 22 66 6f 72 6d <td class="form
df10: 5f 6c 61 62 65 6c 22 20 61 6c 69 67 6e 3d 22 72 _label" align="r
df20: 69 67 68 74 22 3e 43 6f 6e 66 69 72 6d 20 70 61 ight">Confirm pa
df30: 73 73 77 6f 72 64 3a 3c 2f 74 64 3e 0a 20 20 40 ssword:</td>. @
df40: 20 20 20 3c 74 64 3e 3c 69 6e 70 75 74 20 74 79 <td><input ty
df50: 70 65 3d 22 70 61 73 73 77 6f 72 64 22 20 6e 61 pe="password" na
df60: 6d 65 3d 22 63 70 22 20 76 61 6c 75 65 3d 22 25 me="cp" value="%
df70: 68 28 7a 43 6f 6e 66 69 72 6d 29 22 20 73 69 7a h(zConfirm)" siz
df80: 65 3d 22 33 30 22 3e 3c 2f 74 64 3e 0a 20 20 69 e="30"></td>. i
df90: 66 28 20 69 45 72 72 4c 69 6e 65 3d 3d 35 20 29 f( iErrLine==5 )
dfa0: 7b 0a 20 20 20 20 40 20 20 20 3c 74 64 3e 3c 73 {. @ <td><s
dfb0: 70 61 6e 20 63 6c 61 73 73 3d 27 6c 6f 67 69 6e pan class='login
dfc0: 45 72 72 6f 72 27 3e 26 6c 61 72 72 3b 20 25 68 Error'>← %h
dfd0: 28 7a 45 72 72 29 3c 2f 73 70 61 6e 3e 3c 2f 74 (zErr)</span></t
dfe0: 64 3e 0a 20 20 7d 0a 20 20 40 20 3c 2f 74 72 3e d>. }. @ </tr>
dff0: 0a 20 20 40 20 3c 74 72 3e 0a 20 20 40 20 20 20 . @ <tr>. @
e000: 3c 74 64 20 63 6c 61 73 73 3d 22 66 6f 72 6d 5f <td class="form_
e010: 6c 61 62 65 6c 22 20 61 6c 69 67 6e 3d 22 72 69 label" align="ri
e020: 67 68 74 22 3e 43 61 70 74 63 68 61 20 74 65 78 ght">Captcha tex
e030: 74 20 28 62 65 6c 6f 77 29 3a 3c 2f 74 64 3e 0a t (below):</td>.
e040: 20 20 40 20 20 20 3c 74 64 3e 3c 69 6e 70 75 74 @ <td><input
e050: 20 74 79 70 65 3d 22 74 65 78 74 22 20 6e 61 6d type="text" nam
e060: 65 3d 22 63 61 70 74 63 68 61 22 20 76 61 6c 75 e="captcha" valu
e070: 65 3d 22 22 20 73 69 7a 65 3d 22 33 30 22 3e 3c e="" size="30"><
e080: 2f 74 64 3e 0a 20 20 69 66 28 20 69 45 72 72 4c /td>. if( iErrL
e090: 69 6e 65 3d 3d 36 20 29 7b 0a 20 20 20 20 40 20 ine==6 ){. @
e0a0: 20 20 3c 74 64 3e 3c 73 70 61 6e 20 63 6c 61 73 <td><span clas
e0b0: 73 3d 27 6c 6f 67 69 6e 45 72 72 6f 72 27 3e 26 s='loginError'>&
e0c0: 6c 61 72 72 3b 20 25 68 28 7a 45 72 72 29 3c 2f larr; %h(zErr)</
e0d0: 73 70 61 6e 3e 3c 2f 74 64 3e 0a 20 20 7d 0a 20 span></td>. }.
e0e0: 20 40 20 3c 2f 74 72 3e 0a 20 20 40 20 3c 74 72 @ </tr>. @ <tr
e0f0: 3e 3c 74 64 3e 3c 2f 74 64 3e 0a 20 20 40 20 3c ><td></td>. @ <
e100: 74 64 3e 3c 69 6e 70 75 74 20 74 79 70 65 3d 22 td><input type="
e110: 73 75 62 6d 69 74 22 20 6e 61 6d 65 3d 22 6e 65 submit" name="ne
e120: 77 22 20 76 61 6c 75 65 3d 22 52 65 67 69 73 74 w" value="Regist
e130: 65 72 22 20 2f 3e 3c 2f 74 64 3e 3c 2f 74 72 3e er" /></td></tr>
e140: 0a 20 20 40 20 3c 2f 74 61 62 6c 65 3e 0a 20 20 . @ </table>.
e150: 40 20 3c 64 69 76 20 63 6c 61 73 73 3d 22 63 61 @ <div class="ca
e160: 70 74 63 68 61 22 3e 3c 74 61 62 6c 65 20 63 6c ptcha"><table cl
e170: 61 73 73 3d 22 63 61 70 74 63 68 61 22 3e 3c 74 ass="captcha"><t
e180: 72 3e 3c 74 64 3e 3c 70 72 65 3e 0a 20 20 40 20 r><td><pre>. @
e190: 25 68 28 7a 43 61 70 74 63 68 61 29 0a 20 20 40 %h(zCaptcha). @
e1a0: 20 3c 2f 70 72 65 3e 3c 2f 74 64 3e 3c 2f 74 72 </pre></td></tr
e1b0: 3e 3c 2f 74 61 62 6c 65 3e 3c 2f 64 69 76 3e 0a ></table></div>.
e1c0: 20 20 40 20 3c 2f 66 6f 72 6d 3e 0a 20 20 73 74 @ </form>. st
e1d0: 79 6c 65 5f 66 6f 6f 74 65 72 28 29 3b 0a 0a 20 yle_footer();..
e1e0: 20 66 72 65 65 28 7a 43 61 70 74 63 68 61 29 3b free(zCaptcha);
e1f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 75 6e 20 53 51 .}../*.** Run SQ
e200: 4c 20 6f 6e 20 74 68 65 20 72 65 70 6f 73 69 74 L on the reposit
e210: 6f 72 79 20 64 61 74 61 62 61 73 65 20 66 6f 72 ory database for
e220: 20 65 76 65 72 79 20 72 65 70 6f 73 69 74 6f 72 every repositor
e230: 79 20 69 6e 20 6f 75 72 0a 2a 2a 20 6c 6f 67 69 y in our.** logi
e240: 6e 20 67 72 6f 75 70 2e 20 20 54 68 65 20 53 51 n group. The SQ
e250: 4c 20 69 73 20 72 75 6e 20 69 6e 20 61 20 73 65 L is run in a se
e260: 70 61 72 61 74 65 20 64 61 74 61 62 61 73 65 20 parate database
e270: 63 6f 6e 6e 65 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a connection..**.*
e280: 2a 20 41 6e 79 20 6d 65 6d 62 65 72 73 20 6f 66 * Any members of
e290: 20 74 68 65 20 6c 6f 67 69 6e 20 67 72 6f 75 70 the login group
e2a0: 20 77 68 6f 73 65 20 72 65 70 6f 73 69 74 6f 72 whose repositor
e2b0: 79 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 0a y database file.
e2c0: 2a 2a 20 63 61 6e 6e 6f 74 20 62 65 20 66 6f 75 ** cannot be fou
e2d0: 6e 64 20 69 73 20 73 69 6c 65 6e 74 6c 79 20 72 nd is silently r
e2e0: 65 6d 6f 76 65 64 20 66 72 6f 6d 20 74 68 65 20 emoved from the
e2f0: 67 72 6f 75 70 2e 0a 2a 2a 0a 2a 2a 20 45 72 72 group..**.** Err
e300: 6f 72 20 6d 65 73 73 61 67 65 73 20 61 63 63 75 or messages accu
e310: 6d 75 6c 61 74 65 20 61 6e 64 20 61 72 65 20 72 mulate and are r
e320: 65 74 75 72 6e 65 64 20 69 6e 20 2a 70 7a 45 72 eturned in *pzEr
e330: 72 6f 72 4d 73 67 2e 20 20 54 68 65 0a 2a 2a 20 rorMsg. The.**
e340: 6d 65 6d 6f 72 79 20 75 73 65 64 20 74 6f 20 68 memory used to h
e350: 6f 6c 64 20 74 68 65 73 65 20 6d 65 73 73 61 67 old these messag
e360: 65 73 20 73 68 6f 75 6c 64 20 62 65 20 66 72 65 es should be fre
e370: 65 64 20 75 73 69 6e 67 0a 2a 2a 20 66 6f 73 73 ed using.** foss
e380: 69 6c 5f 66 72 65 65 28 29 20 69 66 20 6f 6e 65 il_free() if one
e390: 20 64 65 73 69 72 65 64 20 74 6f 20 61 76 6f 69 desired to avoi
e3a0: 64 20 61 20 6d 65 6d 6f 72 79 20 6c 65 61 6b 2e d a memory leak.
e3b0: 20 20 54 68 65 0a 2a 2a 20 7a 50 72 65 66 69 78 The.** zPrefix
e3c0: 20 61 6e 64 20 7a 53 75 66 66 69 78 20 73 74 72 and zSuffix str
e3d0: 69 6e 67 73 20 73 75 72 72 6f 75 6e 64 20 65 61 ings surround ea
e3e0: 63 68 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 ch error message
e3f0: 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 ..**.** Return t
e400: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 72 72 he number of err
e410: 6f 72 73 2e 0a 2a 2f 0a 69 6e 74 20 6c 6f 67 69 ors..*/.int logi
e420: 6e 5f 67 72 6f 75 70 5f 73 71 6c 28 0a 20 20 63 n_group_sql(. c
e430: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 71 6c 2c onst char *zSql,
e440: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 53 /* The S
e450: 51 4c 20 74 6f 20 72 75 6e 20 2a 2f 0a 20 20 63 QL to run */. c
e460: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 72 65 66 onst char *zPref
e470: 69 78 2c 20 20 20 20 20 2f 2a 20 50 72 65 66 69 ix, /* Prefi
e480: 78 20 74 6f 20 65 61 63 68 20 65 72 72 6f 72 20 x to each error
e490: 6d 65 73 73 61 67 65 20 2a 2f 0a 20 20 63 6f 6e message */. con
e4a0: 73 74 20 63 68 61 72 20 2a 7a 53 75 66 66 69 78 st char *zSuffix
e4b0: 2c 20 20 20 20 20 2f 2a 20 53 75 66 66 69 78 20 , /* Suffix
e4c0: 74 6f 20 65 61 63 68 20 65 72 72 6f 72 20 6d 65 to each error me
e4d0: 73 73 61 67 65 20 2a 2f 0a 20 20 63 68 61 72 20 ssage */. char
e4e0: 2a 2a 70 7a 45 72 72 6f 72 4d 73 67 20 20 20 20 **pzErrorMsg
e4f0: 20 20 20 20 2f 2a 20 57 72 69 74 65 20 65 72 72 /* Write err
e500: 6f 72 20 6d 65 73 73 61 67 65 20 68 65 72 65 2c or message here,
e510: 20 69 66 20 6e 6f 74 20 4e 55 4c 4c 20 2a 2f 0a if not NULL */.
e520: 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 70 50 ){. sqlite3 *pP
e530: 65 65 72 3b 20 20 20 20 20 20 20 20 20 20 2f 2a eer; /*
e540: 20 43 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61 Connection to a
e550: 6e 6f 74 68 65 72 20 64 61 74 61 62 61 73 65 20 nother database
e560: 2a 2f 0a 20 20 69 6e 74 20 6e 45 72 72 20 3d 20 */. int nErr =
e570: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 0; /*
e580: 20 4e 75 6d 62 65 72 20 6f 66 20 65 72 72 6f 72 Number of error
e590: 73 20 73 65 65 6e 20 73 6f 20 66 61 72 20 2a 2f s seen so far */
e5a0: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 . int rc;
e5b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 /* R
e5c0: 65 73 75 6c 74 20 63 6f 64 65 20 66 72 6f 6d 20 esult code from
e5d0: 73 75 62 72 6f 75 74 69 6e 65 20 63 61 6c 6c 73 subroutine calls
e5e0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 72 72 */. char *zErr
e5f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f ; /
e600: 2a 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 74 * SQLite error t
e610: 65 78 74 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a ext */. char *z
e620: 53 65 6c 66 43 6f 64 65 3b 20 20 20 20 20 20 20 SelfCode;
e630: 20 20 2f 2a 20 50 72 6f 6a 65 63 74 20 63 6f 64 /* Project cod
e640: 65 20 66 6f 72 20 6f 75 72 73 65 6c 66 20 2a 2f e for ourself */
e650: 0a 20 20 42 6c 6f 62 20 65 72 72 3b 20 20 20 20 . Blob err;
e660: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 /* A
e670: 63 63 75 6d 75 6c 61 74 65 20 65 72 72 6f 72 73 ccumulate errors
e680: 20 68 65 72 65 20 2a 2f 0a 20 20 53 74 6d 74 20 here */. Stmt
e690: 71 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 q;
e6a0: 20 20 20 20 2f 2a 20 51 75 65 72 79 20 6f 66 20 /* Query of
e6b0: 61 6c 6c 20 70 65 65 72 2d 2a 20 65 6e 74 72 69 all peer-* entri
e6c0: 65 73 20 69 6e 20 43 4f 4e 46 49 47 20 2a 2f 0a es in CONFIG */.
e6d0: 0a 20 20 69 66 28 20 7a 50 72 65 66 69 78 3d 3d . if( zPrefix==
e6e0: 30 20 29 20 7a 50 72 65 66 69 78 20 3d 20 22 22 0 ) zPrefix = ""
e6f0: 3b 0a 20 20 69 66 28 20 7a 53 75 66 66 69 78 3d ;. if( zSuffix=
e700: 3d 30 20 29 20 7a 53 75 66 66 69 78 20 3d 20 22 =0 ) zSuffix = "
e710: 22 3b 0a 20 20 69 66 28 20 70 7a 45 72 72 6f 72 ";. if( pzError
e720: 4d 73 67 20 29 20 2a 70 7a 45 72 72 6f 72 4d 73 Msg ) *pzErrorMs
e730: 67 20 3d 20 30 3b 0a 20 20 7a 53 65 6c 66 43 6f g = 0;. zSelfCo
e740: 64 65 20 3d 20 61 62 62 72 65 76 69 61 74 65 64 de = abbreviated
e750: 5f 70 72 6f 6a 65 63 74 5f 63 6f 64 65 28 64 62 _project_code(db
e760: 5f 67 65 74 28 22 70 72 6f 6a 65 63 74 2d 63 6f _get("project-co
e770: 64 65 22 2c 20 22 78 22 29 29 3b 0a 20 20 62 6c de", "x"));. bl
e780: 6f 62 5f 7a 65 72 6f 28 26 65 72 72 29 3b 0a 20 ob_zero(&err);.
e790: 20 64 62 5f 70 72 65 70 61 72 65 28 26 71 2c 0a db_prepare(&q,.
e7a0: 20 20 20 20 22 53 45 4c 45 43 54 20 6e 61 6d 65 "SELECT name
e7b0: 2c 20 76 61 6c 75 65 20 46 52 4f 4d 20 63 6f 6e , value FROM con
e7c0: 66 69 67 22 0a 20 20 20 20 22 20 57 48 45 52 45 fig". " WHERE
e7d0: 20 6e 61 6d 65 20 47 4c 4f 42 20 27 70 65 65 72 name GLOB 'peer
e7e0: 2d 72 65 70 6f 2d 2a 27 22 0a 20 20 20 20 22 20 -repo-*'". "
e7f0: 20 20 41 4e 44 20 6e 61 6d 65 20 3c 3e 20 27 70 AND name <> 'p
e800: 65 65 72 2d 72 65 70 6f 2d 25 71 27 22 0a 20 20 eer-repo-%q'".
e810: 20 20 22 20 4f 52 44 45 52 20 42 59 20 2b 76 61 " ORDER BY +va
e820: 6c 75 65 22 2c 0a 20 20 20 20 7a 53 65 6c 66 43 lue",. zSelfC
e830: 6f 64 65 0a 20 20 29 3b 0a 20 20 77 68 69 6c 65 ode. );. while
e840: 28 20 64 62 5f 73 74 65 70 28 26 71 29 3d 3d 53 ( db_step(&q)==S
e850: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 QLITE_ROW ){.
e860: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 65 const char *zRe
e870: 70 6f 4e 61 6d 65 20 3d 20 64 62 5f 63 6f 6c 75 poName = db_colu
e880: 6d 6e 5f 74 65 78 74 28 26 71 2c 20 31 29 3b 0a mn_text(&q, 1);.
e890: 20 20 20 20 69 66 28 20 66 69 6c 65 5f 73 69 7a if( file_siz
e8a0: 65 28 7a 52 65 70 6f 4e 61 6d 65 2c 20 45 78 74 e(zRepoName, Ext
e8b0: 46 49 4c 45 29 3c 30 20 29 7b 0a 20 20 20 20 20 FILE)<0 ){.
e8c0: 20 2f 2a 20 53 69 6c 65 6e 74 6c 79 20 72 65 6d /* Silently rem
e8d0: 6f 76 65 20 6e 6f 6e 2d 65 78 69 73 74 65 6e 74 ove non-existent
e8e0: 20 72 65 70 6f 73 69 74 6f 72 69 65 73 20 66 72 repositories fr
e8f0: 6f 6d 20 74 68 65 20 6c 6f 67 69 6e 20 67 72 6f om the login gro
e900: 75 70 2e 20 2a 2f 0a 20 20 20 20 20 20 63 6f 6e up. */. con
e910: 73 74 20 63 68 61 72 20 2a 7a 4c 61 62 65 6c 20 st char *zLabel
e920: 3d 20 64 62 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 = db_column_text
e930: 28 26 71 2c 20 30 29 3b 0a 20 20 20 20 20 20 64 (&q, 0);. d
e940: 62 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20 b_multi_exec(.
e950: 20 20 20 20 20 20 20 22 44 45 4c 45 54 45 20 46 "DELETE F
e960: 52 4f 4d 20 63 6f 6e 66 69 67 20 57 48 45 52 45 ROM config WHERE
e970: 20 6e 61 6d 65 20 47 4c 4f 42 20 27 70 65 65 72 name GLOB 'peer
e980: 2d 2a 2d 25 71 27 22 2c 0a 20 20 20 20 20 20 20 -*-%q'",.
e990: 20 20 26 7a 4c 61 62 65 6c 5b 31 30 5d 0a 20 20 &zLabel[10].
e9a0: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 63 6f 6e );. con
e9b0: 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20 tinue;. }.
e9c0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 6f 70 rc = sqlite3_op
e9d0: 65 6e 5f 76 32 28 0a 20 20 20 20 20 20 20 20 20 en_v2(.
e9e0: 7a 52 65 70 6f 4e 61 6d 65 2c 20 26 70 50 65 65 zRepoName, &pPee
e9f0: 72 2c 0a 20 20 20 20 20 20 20 20 20 53 51 4c 49 r,. SQLI
ea00: 54 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 TE_OPEN_READWRIT
ea10: 45 2c 0a 20 20 20 20 20 20 20 20 20 67 2e 7a 56 E,. g.zV
ea20: 66 73 4e 61 6d 65 0a 20 20 20 20 29 3b 0a 20 20 fsName. );.
ea30: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 if( rc!=SQLITE
ea40: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f _OK ){. blo
ea50: 62 5f 61 70 70 65 6e 64 66 28 26 65 72 72 2c 20 b_appendf(&err,
ea60: 22 25 73 25 73 3a 20 25 73 25 73 22 2c 20 7a 50 "%s%s: %s%s", zP
ea70: 72 65 66 69 78 2c 20 7a 52 65 70 6f 4e 61 6d 65 refix, zRepoName
ea80: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ,.
ea90: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 65 72 72 sqlite3_err
eaa0: 6d 73 67 28 70 50 65 65 72 29 2c 20 7a 53 75 66 msg(pPeer), zSuf
eab0: 66 69 78 29 3b 0a 20 20 20 20 20 20 6e 45 72 72 fix);. nErr
eac0: 2b 2b 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 ++;. sqlite
ead0: 33 5f 63 6c 6f 73 65 28 70 50 65 65 72 29 3b 0a 3_close(pPeer);.
eae0: 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a continue;.
eaf0: 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 }. sqlite
eb00: 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 3_create_functio
eb10: 6e 28 70 50 65 65 72 2c 20 22 73 68 61 72 65 64 n(pPeer, "shared
eb20: 5f 73 65 63 72 65 74 22 2c 20 33 2c 20 53 51 4c _secret", 3, SQL
eb30: 49 54 45 5f 55 54 46 38 2c 0a 20 20 20 20 20 20 ITE_UTF8,.
eb40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
eb50: 20 20 20 20 20 20 30 2c 20 73 68 61 31 5f 73 68 0, sha1_sh
eb60: 61 72 65 64 5f 73 65 63 72 65 74 5f 73 71 6c 5f ared_secret_sql_
eb70: 66 75 6e 63 74 69 6f 6e 2c 20 30 2c 20 30 29 3b function, 0, 0);
eb80: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 63 72 65 . sqlite3_cre
eb90: 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28 70 50 65 ate_function(pPe
eba0: 65 72 2c 20 22 6e 6f 77 22 2c 20 30 2c 53 51 4c er, "now", 0,SQL
ebb0: 49 54 45 5f 55 54 46 38 2c 30 2c 64 62 5f 6e 6f ITE_UTF8,0,db_no
ebc0: 77 5f 66 75 6e 63 74 69 6f 6e 2c 30 2c 30 29 3b w_function,0,0);
ebd0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 62 75 73 . sqlite3_bus
ebe0: 79 5f 74 69 6d 65 6f 75 74 28 70 50 65 65 72 2c y_timeout(pPeer,
ebf0: 20 35 30 30 30 29 3b 0a 20 20 20 20 7a 45 72 72 5000);. zErr
ec00: 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 73 = 0;. rc = s
ec10: 71 6c 69 74 65 33 5f 65 78 65 63 28 70 50 65 65 qlite3_exec(pPee
ec20: 72 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 26 r, zSql, 0, 0, &
ec30: 7a 45 72 72 29 3b 0a 20 20 20 20 69 66 28 20 7a zErr);. if( z
ec40: 45 72 72 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f Err ){. blo
ec50: 62 5f 61 70 70 65 6e 64 66 28 26 65 72 72 2c 20 b_appendf(&err,
ec60: 22 25 73 25 73 3a 20 25 73 25 73 22 2c 20 7a 50 "%s%s: %s%s", zP
ec70: 72 65 66 69 78 2c 20 7a 52 65 70 6f 4e 61 6d 65 refix, zRepoName
ec80: 2c 20 7a 45 72 72 2c 20 7a 53 75 66 66 69 78 29 , zErr, zSuffix)
ec90: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f ;. sqlite3_
eca0: 66 72 65 65 28 7a 45 72 72 29 3b 0a 20 20 20 20 free(zErr);.
ecb0: 20 20 6e 45 72 72 2b 2b 3b 0a 20 20 20 20 7d 65 nErr++;. }e
ecc0: 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51 4c 49 lse if( rc!=SQLI
ecd0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 62 TE_OK ){. b
ece0: 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 72 72 lob_appendf(&err
ecf0: 2c 20 22 25 73 25 73 3a 20 25 73 25 73 22 2c 20 , "%s%s: %s%s",
ed00: 7a 50 72 65 66 69 78 2c 20 7a 52 65 70 6f 4e 61 zPrefix, zRepoNa
ed10: 6d 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 me,.
ed20: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 65 sqlite3_e
ed30: 72 72 6d 73 67 28 70 50 65 65 72 29 2c 20 7a 53 rrmsg(pPeer), zS
ed40: 75 66 66 69 78 29 3b 0a 20 20 20 20 20 20 6e 45 uffix);. nE
ed50: 72 72 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 rr++;. }.
ed60: 73 71 6c 69 74 65 33 5f 63 6c 6f 73 65 28 70 50 sqlite3_close(pP
ed70: 65 65 72 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 66 eer);. }. db_f
ed80: 69 6e 61 6c 69 7a 65 28 26 71 29 3b 0a 20 20 69 inalize(&q);. i
ed90: 66 28 20 70 7a 45 72 72 6f 72 4d 73 67 20 26 26 f( pzErrorMsg &&
eda0: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 65 72 72 29 blob_size(&err)
edb0: 3e 30 20 29 7b 0a 20 20 20 20 2a 70 7a 45 72 72 >0 ){. *pzErr
edc0: 6f 72 4d 73 67 20 3d 20 66 6f 73 73 69 6c 5f 73 orMsg = fossil_s
edd0: 74 72 64 75 70 28 62 6c 6f 62 5f 73 74 72 28 26 trdup(blob_str(&
ede0: 65 72 72 29 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f err));. }. blo
edf0: 62 5f 72 65 73 65 74 28 26 65 72 72 29 3b 0a 20 b_reset(&err);.
ee00: 20 66 6f 73 73 69 6c 5f 66 72 65 65 28 7a 53 65 fossil_free(zSe
ee10: 6c 66 43 6f 64 65 29 3b 0a 20 20 72 65 74 75 72 lfCode);. retur
ee20: 6e 20 6e 45 72 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a n nErr;.}../*.**
ee30: 20 41 74 74 65 6d 70 74 20 74 6f 20 6a 6f 69 6e Attempt to join
ee40: 20 61 20 6c 6f 67 69 6e 2d 67 72 6f 75 70 2e 0a a login-group..
ee50: 2a 2a 0a 2a 2a 20 49 66 20 70 72 6f 62 6c 65 6d **.** If problem
ee60: 73 20 61 72 69 73 65 2c 20 6c 65 61 76 65 20 61 s arise, leave a
ee70: 6e 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20 n error message
ee80: 69 6e 20 2a 70 7a 45 72 72 4d 73 67 2e 0a 2a 2f in *pzErrMsg..*/
ee90: 0a 76 6f 69 64 20 6c 6f 67 69 6e 5f 67 72 6f 75 .void login_grou
eea0: 70 5f 6a 6f 69 6e 28 0a 20 20 63 6f 6e 73 74 20 p_join(. const
eeb0: 63 68 61 72 20 2a 7a 52 65 70 6f 2c 20 20 20 20 char *zRepo,
eec0: 20 20 20 20 20 2f 2a 20 52 65 70 6f 73 69 74 6f /* Reposito
eed0: 72 79 20 66 69 6c 65 20 69 6e 20 74 68 65 20 6c ry file in the l
eee0: 6f 67 69 6e 20 67 72 6f 75 70 20 2a 2f 0a 20 20 ogin group */.
eef0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4c 6f 67 const char *zLog
ef00: 69 6e 2c 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f in, /* Lo
ef10: 67 69 6e 20 6e 61 6d 65 20 66 6f 72 20 74 68 65 gin name for the
ef20: 20 6f 74 68 65 72 20 72 65 70 6f 20 2a 2f 0a 20 other repo */.
ef30: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 const char *zPa
ef40: 73 73 77 6f 72 64 2c 20 20 20 20 20 2f 2a 20 50 ssword, /* P
ef50: 61 73 73 77 6f 72 64 20 74 6f 20 70 72 6f 76 65 assword to prove
ef60: 20 77 65 20 61 72 65 20 61 75 74 68 6f 72 69 7a we are authoriz
ef70: 65 64 20 74 6f 20 6a 6f 69 6e 20 2a 2f 0a 20 20 ed to join */.
ef80: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 65 77 const char *zNew
ef90: 4e 61 6d 65 2c 20 20 20 20 20 20 2f 2a 20 4e 61 Name, /* Na
efa0: 6d 65 20 6f 66 20 6e 65 77 20 6c 6f 67 69 6e 20 me of new login
efb0: 67 72 6f 75 70 20 69 66 20 6d 61 6b 69 6e 67 20 group if making
efc0: 61 20 6e 65 77 20 6f 6e 65 20 2a 2f 0a 20 20 63 a new one */. c
efd0: 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 20 20 har **pzErrMsg
efe0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 61 /* Lea
eff0: 76 65 20 61 6e 20 65 72 72 6f 72 20 6d 65 73 73 ve an error mess
f000: 61 67 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 age here */.){.
f010: 20 42 6c 6f 62 20 66 75 6c 6c 4e 61 6d 65 3b 20 Blob fullName;
f020: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 /* B
f030: 6c 6f 62 20 66 6f 72 20 66 69 6e 64 69 6e 67 20 lob for finding
f040: 66 75 6c 6c 20 70 61 74 68 6e 61 6d 65 73 20 2a full pathnames *
f050: 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 70 4f 74 /. sqlite3 *pOt
f060: 68 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f her; /
f070: 2a 20 54 68 65 20 6f 74 68 65 72 20 72 65 70 6f * The other repo
f080: 73 69 74 6f 72 79 20 2a 2f 0a 20 20 69 6e 74 20 sitory */. int
f090: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 rc;
f0a0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e /* Return
f0b0: 20 63 6f 64 65 20 66 72 6f 6d 20 73 71 6c 69 74 code from sqlit
f0c0: 65 33 20 66 75 6e 63 74 69 6f 6e 73 20 2a 2f 0a e3 functions */.
f0d0: 20 20 63 68 61 72 20 2a 7a 4f 74 68 65 72 50 72 char *zOtherPr
f0e0: 6f 6a 43 6f 64 65 3b 20 20 20 20 20 20 2f 2a 20 ojCode; /*
f0f0: 50 72 6f 6a 65 63 74 20 63 6f 64 65 20 66 6f 72 Project code for
f100: 20 70 4f 74 68 65 72 20 2a 2f 0a 20 20 63 68 61 pOther */. cha
f110: 72 20 2a 7a 50 77 48 61 73 68 3b 20 20 20 20 20 r *zPwHash;
f120: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 73 73 77 /* Passw
f130: 6f 72 64 20 68 61 73 68 20 6f 6e 20 70 4f 74 68 ord hash on pOth
f140: 65 72 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 er */. char *zS
f150: 65 6c 66 52 65 70 6f 3b 20 20 20 20 20 20 20 20 elfRepo;
f160: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 6f 75 /* Name of ou
f170: 72 20 72 65 70 6f 73 69 74 6f 72 79 20 2a 2f 0a r repository */.
f180: 20 20 63 68 61 72 20 2a 7a 53 65 6c 66 4c 61 62 char *zSelfLab
f190: 65 6c 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 el; /*
f1a0: 50 72 6f 6a 65 63 74 2d 6e 61 6d 65 20 66 6f 72 Project-name for
f1b0: 20 6f 75 72 20 72 65 70 6f 73 69 74 6f 72 79 20 our repository
f1c0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 65 6c 66 */. char *zSelf
f1d0: 50 72 6f 6a 43 6f 64 65 3b 20 20 20 20 20 20 20 ProjCode;
f1e0: 2f 2a 20 4f 75 72 20 70 72 6f 6a 65 63 74 2d 63 /* Our project-c
f1f0: 6f 64 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a ode */. char *z
f200: 53 71 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 Sql;
f210: 20 20 20 20 2f 2a 20 53 51 4c 20 74 6f 20 72 75 /* SQL to ru
f220: 6e 20 6f 6e 20 61 6c 6c 20 70 65 65 72 73 20 2a n on all peers *
f230: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a /. const char *
f240: 7a 53 65 6c 66 3b 20 20 20 20 20 20 20 20 20 2f zSelf; /
f250: 2a 20 54 68 65 20 41 54 54 41 43 48 20 6e 61 6d * The ATTACH nam
f260: 65 20 6f 66 20 6f 75 72 20 72 65 70 6f 73 69 74 e of our reposit
f270: 6f 72 79 20 2a 2f 0a 0a 20 20 2a 70 7a 45 72 72 ory */.. *pzErr
f280: 4d 73 67 20 3d 20 30 3b 20 20 20 2f 2a 20 44 65 Msg = 0; /* De
f290: 66 61 75 6c 74 20 74 6f 20 6e 6f 20 65 72 72 6f fault to no erro
f2a0: 72 73 20 2a 2f 0a 20 20 7a 53 65 6c 66 20 3d 20 rs */. zSelf =
f2b0: 22 72 65 70 6f 73 69 74 6f 72 79 22 3b 0a 0a 20 "repository";..
f2c0: 20 2f 2a 20 47 65 74 20 74 68 65 20 66 75 6c 6c /* Get the full
f2d0: 20 70 61 74 68 6e 61 6d 65 20 6f 66 20 74 68 65 pathname of the
f2e0: 20 6f 74 68 65 72 20 72 65 70 6f 73 69 74 6f 72 other repositor
f2f0: 79 20 2a 2f 0a 20 20 66 69 6c 65 5f 63 61 6e 6f y */. file_cano
f300: 6e 69 63 61 6c 5f 6e 61 6d 65 28 7a 52 65 70 6f nical_name(zRepo
f310: 2c 20 26 66 75 6c 6c 4e 61 6d 65 2c 20 30 29 3b , &fullName, 0);
f320: 0a 20 20 7a 52 65 70 6f 20 3d 20 66 6f 73 73 69 . zRepo = fossi
f330: 6c 5f 73 74 72 64 75 70 28 62 6c 6f 62 5f 73 74 l_strdup(blob_st
f340: 72 28 26 66 75 6c 6c 4e 61 6d 65 29 29 3b 0a 20 r(&fullName));.
f350: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 75 6c blob_reset(&ful
f360: 6c 4e 61 6d 65 29 3b 0a 0a 20 20 2f 2a 20 47 65 lName);.. /* Ge
f370: 74 20 74 68 65 20 66 75 6c 6c 20 70 61 74 68 6e t the full pathn
f380: 61 6d 65 20 66 6f 72 20 6f 75 72 20 72 65 70 6f ame for our repo
f390: 73 69 74 6f 72 79 2e 20 20 41 6c 73 6f 20 74 68 sitory. Also th
f3a0: 65 20 70 72 6f 6a 65 63 74 20 63 6f 64 65 0a 20 e project code.
f3b0: 20 2a 2a 20 61 6e 64 20 70 72 6f 6a 65 63 74 20 ** and project
f3c0: 6e 61 6d 65 20 66 6f 72 20 6f 75 72 73 65 6c 66 name for ourself
f3d0: 2e 20 2a 2f 0a 20 20 66 69 6c 65 5f 63 61 6e 6f . */. file_cano
f3e0: 6e 69 63 61 6c 5f 6e 61 6d 65 28 67 2e 7a 52 65 nical_name(g.zRe
f3f0: 70 6f 73 69 74 6f 72 79 4e 61 6d 65 2c 20 26 66 positoryName, &f
f400: 75 6c 6c 4e 61 6d 65 2c 20 30 29 3b 0a 20 20 7a ullName, 0);. z
f410: 53 65 6c 66 52 65 70 6f 20 3d 20 66 6f 73 73 69 SelfRepo = fossi
f420: 6c 5f 73 74 72 64 75 70 28 62 6c 6f 62 5f 73 74 l_strdup(blob_st
f430: 72 28 26 66 75 6c 6c 4e 61 6d 65 29 29 3b 0a 20 r(&fullName));.
f440: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 75 6c blob_reset(&ful
f450: 6c 4e 61 6d 65 29 3b 0a 20 20 7a 53 65 6c 66 50 lName);. zSelfP
f460: 72 6f 6a 43 6f 64 65 20 3d 20 64 62 5f 67 65 74 rojCode = db_get
f470: 28 22 70 72 6f 6a 65 63 74 2d 63 6f 64 65 22 2c ("project-code",
f480: 20 22 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 20 20 7a "unknown");. z
f490: 53 65 6c 66 4c 61 62 65 6c 20 3d 20 64 62 5f 67 SelfLabel = db_g
f4a0: 65 74 28 22 70 72 6f 6a 65 63 74 2d 6e 61 6d 65 et("project-name
f4b0: 22 2c 20 30 29 3b 0a 20 20 69 66 28 20 7a 53 65 ", 0);. if( zSe
f4c0: 6c 66 4c 61 62 65 6c 3d 3d 30 20 29 7b 0a 20 20 lfLabel==0 ){.
f4d0: 20 20 7a 53 65 6c 66 4c 61 62 65 6c 20 3d 20 7a zSelfLabel = z
f4e0: 53 65 6c 66 50 72 6f 6a 43 6f 64 65 3b 0a 20 20 SelfProjCode;.
f4f0: 7d 0a 0a 20 20 2f 2a 20 4d 61 6b 65 20 73 75 72 }.. /* Make sur
f500: 65 20 77 65 20 61 72 65 20 6e 6f 74 20 74 72 79 e we are not try
f510: 69 6e 67 20 74 6f 20 6a 6f 69 6e 20 6f 75 72 73 ing to join ours
f520: 65 6c 76 65 73 20 2a 2f 0a 20 20 69 66 28 20 66 elves */. if( f
f530: 6f 73 73 69 6c 5f 73 74 72 63 6d 70 28 7a 52 65 ossil_strcmp(zRe
f540: 70 6f 2c 20 7a 53 65 6c 66 52 65 70 6f 29 3d 3d po, zSelfRepo)==
f550: 30 20 29 7b 0a 20 20 20 20 2a 70 7a 45 72 72 4d 0 ){. *pzErrM
f560: 73 67 20 3d 20 6d 70 72 69 6e 74 66 28 22 54 68 sg = mprintf("Th
f570: 65 20 5c 22 6f 74 68 65 72 5c 22 20 72 65 70 6f e \"other\" repo
f580: 73 69 74 6f 72 79 20 69 73 20 74 68 65 20 73 61 sitory is the sa
f590: 6d 65 20 61 73 20 74 68 69 73 20 6f 6e 65 2e 22 me as this one."
f5a0: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 );. return;.
f5b0: 20 7d 0a 0a 20 20 2f 2a 20 4d 61 6b 65 20 73 75 }.. /* Make su
f5c0: 72 65 20 74 68 65 20 6f 74 68 65 72 20 72 65 70 re the other rep
f5d0: 6f 73 69 74 6f 72 79 20 69 73 20 61 20 76 61 6c ository is a val
f5e0: 69 64 20 46 6f 73 73 69 6c 20 64 61 74 61 62 61 id Fossil databa
f5f0: 73 65 20 2a 2f 0a 20 20 69 66 28 20 66 69 6c 65 se */. if( file
f600: 5f 73 69 7a 65 28 7a 52 65 70 6f 2c 20 45 78 74 _size(zRepo, Ext
f610: 46 49 4c 45 29 3c 30 20 29 7b 0a 20 20 20 20 2a FILE)<0 ){. *
f620: 70 7a 45 72 72 4d 73 67 20 3d 20 6d 70 72 69 6e pzErrMsg = mprin
f630: 74 66 28 22 72 65 70 6f 73 69 74 6f 72 79 20 66 tf("repository f
f640: 69 6c 65 20 5c 22 25 73 5c 22 20 64 6f 65 73 20 ile \"%s\" does
f650: 6e 6f 74 20 65 78 69 73 74 22 2c 20 7a 52 65 70 not exist", zRep
f660: 6f 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a o);. return;.
f670: 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 }. rc = sqlit
f680: 65 33 5f 6f 70 65 6e 5f 76 32 28 0a 20 20 20 20 e3_open_v2(.
f690: 20 20 20 7a 52 65 70 6f 2c 20 26 70 4f 74 68 65 zRepo, &pOthe
f6a0: 72 2c 0a 20 20 20 20 20 20 20 53 51 4c 49 54 45 r,. SQLITE
f6b0: 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 20 _OPEN_READWRITE
f6c0: 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 | SQLITE_OPEN_CR
f6d0: 45 41 54 45 2c 0a 20 20 20 20 20 20 20 67 2e 7a EATE,. g.z
f6e0: 56 66 73 4e 61 6d 65 0a 20 20 29 3b 0a 20 20 69 VfsName. );. i
f6f0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b f( rc!=SQLITE_OK
f700: 20 29 7b 0a 20 20 20 20 2a 70 7a 45 72 72 4d 73 ){. *pzErrMs
f710: 67 20 3d 20 66 6f 73 73 69 6c 5f 73 74 72 64 75 g = fossil_strdu
f720: 70 28 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 p(sqlite3_errmsg
f730: 28 70 4f 74 68 65 72 29 29 3b 0a 20 20 7d 65 6c (pOther));. }el
f740: 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c se{. rc = sql
f750: 69 74 65 33 5f 65 78 65 63 28 70 4f 74 68 65 72 ite3_exec(pOther
f760: 2c 20 22 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 , "SELECT count(
f770: 2a 29 20 46 52 4f 4d 20 75 73 65 72 22 2c 20 30 *) FROM user", 0
f780: 2c 20 30 2c 20 70 7a 45 72 72 4d 73 67 29 3b 0a , 0, pzErrMsg);.
f790: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 63 6c }. sqlite3_cl
f7a0: 6f 73 65 28 70 4f 74 68 65 72 29 3b 0a 20 20 69 ose(pOther);. i
f7b0: 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 3b 0a f( rc ) return;.
f7c0: 0a 20 20 2f 2a 20 41 74 74 61 63 68 20 74 68 65 . /* Attach the
f7d0: 20 6f 74 68 65 72 20 72 65 70 6f 73 69 74 6f 72 other repositor
f7e0: 79 2e 20 20 4d 61 6b 65 20 73 75 72 65 20 74 68 y. Make sure th
f7f0: 65 20 75 73 65 72 6e 61 6d 65 2f 70 61 73 73 77 e username/passw
f800: 6f 72 64 20 69 73 0a 20 20 2a 2a 20 76 61 6c 69 ord is. ** vali
f810: 64 20 61 6e 64 20 68 61 73 20 53 65 74 75 70 20 d and has Setup
f820: 70 65 72 6d 69 73 73 69 6f 6e 2e 0a 20 20 2a 2f permission.. */
f830: 0a 20 20 64 62 5f 61 74 74 61 63 68 28 7a 52 65 . db_attach(zRe
f840: 70 6f 2c 20 22 6f 74 68 65 72 22 29 3b 0a 20 20 po, "other");.
f850: 7a 4f 74 68 65 72 50 72 6f 6a 43 6f 64 65 20 3d zOtherProjCode =
f860: 20 64 62 5f 74 65 78 74 28 22 78 22 2c 20 22 53 db_text("x", "S
f870: 45 4c 45 43 54 20 76 61 6c 75 65 20 46 52 4f 4d ELECT value FROM
f880: 20 6f 74 68 65 72 2e 63 6f 6e 66 69 67 22 0a 20 other.config".
f890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
f8a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22 "
f8b0: 20 57 48 45 52 45 20 6e 61 6d 65 3d 27 70 72 6f WHERE name='pro
f8c0: 6a 65 63 74 2d 63 6f 64 65 27 22 29 3b 0a 20 20 ject-code'");.
f8d0: 7a 50 77 48 61 73 68 20 3d 20 73 68 61 31 5f 73 zPwHash = sha1_s
f8e0: 68 61 72 65 64 5f 73 65 63 72 65 74 28 7a 50 61 hared_secret(zPa
f8f0: 73 73 77 6f 72 64 2c 20 7a 4c 6f 67 69 6e 2c 20 ssword, zLogin,
f900: 7a 4f 74 68 65 72 50 72 6f 6a 43 6f 64 65 29 3b zOtherProjCode);
f910: 0a 20 20 69 66 28 20 21 64 62 5f 65 78 69 73 74 . if( !db_exist
f920: 73 28 0a 20 20 20 20 22 53 45 4c 45 43 54 20 31 s(. "SELECT 1
f930: 20 46 52 4f 4d 20 6f 74 68 65 72 2e 75 73 65 72 FROM other.user
f940: 22 0a 20 20 20 20 22 20 57 48 45 52 45 20 6c 6f ". " WHERE lo
f950: 67 69 6e 3d 25 51 20 41 4e 44 20 63 61 70 20 47 gin=%Q AND cap G
f960: 4c 4f 42 20 27 2a 73 2a 27 22 0a 20 20 20 20 22 LOB '*s*'". "
f970: 20 20 20 41 4e 44 20 28 70 77 3d 25 51 20 4f 52 AND (pw=%Q OR
f980: 20 70 77 3d 25 51 29 22 2c 0a 20 20 20 20 7a 4c pw=%Q)",. zL
f990: 6f 67 69 6e 2c 20 7a 50 61 73 73 77 6f 72 64 2c ogin, zPassword,
f9a0: 20 7a 50 77 48 61 73 68 29 0a 20 20 29 7b 0a 20 zPwHash). ){.
f9b0: 20 20 20 64 62 5f 64 65 74 61 63 68 28 22 6f 74 db_detach("ot
f9c0: 68 65 72 22 29 3b 0a 20 20 20 20 2a 70 7a 45 72 her");. *pzEr
f9d0: 72 4d 73 67 20 3d 20 22 54 68 65 20 73 75 70 70 rMsg = "The supp
f9e0: 6c 69 65 64 20 75 73 65 72 6e 61 6d 65 2f 70 61 lied username/pa
f9f0: 73 73 77 6f 72 64 20 64 6f 65 73 20 6e 6f 74 20 ssword does not
fa00: 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20 61 22 correspond to a"
fa10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
fa20: 20 22 20 75 73 65 72 20 53 65 74 75 70 20 70 65 " user Setup pe
fa30: 72 6d 69 73 73 69 6f 6e 20 6f 6e 20 74 68 65 20 rmission on the
fa40: 6f 74 68 65 72 20 72 65 70 6f 73 69 74 6f 72 79 other repository
fa50: 2e 22 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a .";. return;.
fa60: 20 20 7d 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 }.. /* Create
fa70: 20 61 6c 6c 20 74 68 65 20 6e 65 63 65 73 73 61 all the necessa
fa80: 72 79 20 43 4f 4e 46 49 47 20 74 61 62 6c 65 20 ry CONFIG table
fa90: 65 6e 74 72 69 65 73 20 6f 6e 20 62 6f 74 68 20 entries on both
faa0: 74 68 65 0a 20 20 2a 2a 20 6f 74 68 65 72 20 72 the. ** other r
fab0: 65 70 6f 73 69 74 6f 72 79 20 61 6e 64 20 6f 6e epository and on
fac0: 20 6f 75 72 20 6f 77 6e 20 72 65 70 6f 73 69 74 our own reposit
fad0: 6f 72 79 2e 0a 20 20 2a 2f 0a 20 20 7a 53 65 6c ory.. */. zSel
fae0: 66 50 72 6f 6a 43 6f 64 65 20 3d 20 61 62 62 72 fProjCode = abbr
faf0: 65 76 69 61 74 65 64 5f 70 72 6f 6a 65 63 74 5f eviated_project_
fb00: 63 6f 64 65 28 7a 53 65 6c 66 50 72 6f 6a 43 6f code(zSelfProjCo
fb10: 64 65 29 3b 0a 20 20 7a 4f 74 68 65 72 50 72 6f de);. zOtherPro
fb20: 6a 43 6f 64 65 20 3d 20 61 62 62 72 65 76 69 61 jCode = abbrevia
fb30: 74 65 64 5f 70 72 6f 6a 65 63 74 5f 63 6f 64 65 ted_project_code
fb40: 28 7a 4f 74 68 65 72 50 72 6f 6a 43 6f 64 65 29 (zOtherProjCode)
fb50: 3b 0a 20 20 64 62 5f 62 65 67 69 6e 5f 74 72 61 ;. db_begin_tra
fb60: 6e 73 61 63 74 69 6f 6e 28 29 3b 0a 20 20 64 62 nsaction();. db
fb70: 5f 6d 75 6c 74 69 5f 65 78 65 63 28 0a 20 20 20 _multi_exec(.
fb80: 20 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 5c 22 "DELETE FROM \"
fb90: 25 77 5c 22 2e 63 6f 6e 66 69 67 20 57 48 45 52 %w\".config WHER
fba0: 45 20 6e 61 6d 65 20 47 4c 4f 42 20 27 70 65 65 E name GLOB 'pee
fbb0: 72 2d 2a 27 3b 22 0a 20 20 20 20 22 49 4e 53 45 r-*';". "INSE
fbc0: 52 54 20 49 4e 54 4f 20 5c 22 25 77 5c 22 2e 63 RT INTO \"%w\".c
fbd0: 6f 6e 66 69 67 28 6e 61 6d 65 2c 76 61 6c 75 65 onfig(name,value
fbe0: 29 20 56 41 4c 55 45 53 28 27 70 65 65 72 2d 72 ) VALUES('peer-r
fbf0: 65 70 6f 2d 25 71 27 2c 25 51 29 3b 22 0a 20 20 epo-%q',%Q);".
fc00: 20 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 5c "INSERT INTO \
fc10: 22 25 77 5c 22 2e 63 6f 6e 66 69 67 28 6e 61 6d "%w\".config(nam
fc20: 65 2c 76 61 6c 75 65 29 20 22 0a 20 20 20 20 22 e,value) ". "
fc30: 20 20 53 45 4c 45 43 54 20 27 70 65 65 72 2d 6e SELECT 'peer-n
fc40: 61 6d 65 2d 25 71 27 2c 20 76 61 6c 75 65 20 46 ame-%q', value F
fc50: 52 4f 4d 20 6f 74 68 65 72 2e 63 6f 6e 66 69 67 ROM other.config
fc60: 22 0a 20 20 20 20 22 20 20 20 57 48 45 52 45 20 ". " WHERE
fc70: 6e 61 6d 65 3d 27 70 72 6f 6a 65 63 74 2d 6e 61 name='project-na
fc80: 6d 65 27 3b 22 2c 0a 20 20 20 20 7a 53 65 6c 66 me';",. zSelf
fc90: 2c 0a 20 20 20 20 7a 53 65 6c 66 2c 20 7a 4f 74 ,. zSelf, zOt
fca0: 68 65 72 50 72 6f 6a 43 6f 64 65 2c 20 7a 52 65 herProjCode, zRe
fcb0: 70 6f 2c 0a 20 20 20 20 7a 53 65 6c 66 2c 20 7a po,. zSelf, z
fcc0: 4f 74 68 65 72 50 72 6f 6a 43 6f 64 65 0a 20 20 OtherProjCode.
fcd0: 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f 65 78 );. db_multi_ex
fce0: 65 63 28 0a 20 20 20 20 22 49 4e 53 45 52 54 20 ec(. "INSERT
fcf0: 4f 52 20 49 47 4e 4f 52 45 20 49 4e 54 4f 20 6f OR IGNORE INTO o
fd00: 74 68 65 72 2e 63 6f 6e 66 69 67 28 6e 61 6d 65 ther.config(name
fd10: 2c 76 61 6c 75 65 29 22 0a 20 20 20 20 22 20 56 ,value)". " V
fd20: 41 4c 55 45 53 28 27 6c 6f 67 69 6e 2d 67 72 6f ALUES('login-gro
fd30: 75 70 2d 6e 61 6d 65 27 2c 25 51 29 3b 22 0a 20 up-name',%Q);".
fd40: 20 20 20 22 49 4e 53 45 52 54 20 4f 52 20 49 47 "INSERT OR IG
fd50: 4e 4f 52 45 20 49 4e 54 4f 20 6f 74 68 65 72 2e NORE INTO other.
fd60: 63 6f 6e 66 69 67 28 6e 61 6d 65 2c 76 61 6c 75 config(name,valu
fd70: 65 29 22 0a 20 20 20 20 22 20 56 41 4c 55 45 53 e)". " VALUES
fd80: 28 27 6c 6f 67 69 6e 2d 67 72 6f 75 70 2d 63 6f ('login-group-co
fd90: 64 65 27 2c 6c 6f 77 65 72 28 68 65 78 28 72 61 de',lower(hex(ra
fda0: 6e 64 6f 6d 62 6c 6f 62 28 38 29 29 29 29 3b 22 ndomblob(8))));"
fdb0: 2c 0a 20 20 20 20 7a 4e 65 77 4e 61 6d 65 0a 20 ,. zNewName.
fdc0: 20 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f 65 );. db_multi_e
fdd0: 78 65 63 28 0a 20 20 20 20 22 52 45 50 4c 41 43 xec(. "REPLAC
fde0: 45 20 49 4e 54 4f 20 5c 22 25 77 5c 22 2e 63 6f E INTO \"%w\".co
fdf0: 6e 66 69 67 28 6e 61 6d 65 2c 76 61 6c 75 65 29 nfig(name,value)
fe00: 22 0a 20 20 20 20 22 20 20 53 45 4c 45 43 54 20 ". " SELECT
fe10: 6e 61 6d 65 2c 20 76 61 6c 75 65 20 46 52 4f 4d name, value FROM
fe20: 20 6f 74 68 65 72 2e 63 6f 6e 66 69 67 22 0a 20 other.config".
fe30: 20 20 20 22 20 20 20 57 48 45 52 45 20 6e 61 6d " WHERE nam
fe40: 65 20 47 4c 4f 42 20 27 70 65 65 72 2d 2a 27 20 e GLOB 'peer-*'
fe50: 4f 52 20 6e 61 6d 65 20 47 4c 4f 42 20 27 6c 6f OR name GLOB 'lo
fe60: 67 69 6e 2d 67 72 6f 75 70 2d 2a 27 22 2c 0a 20 gin-group-*'",.
fe70: 20 20 20 7a 53 65 6c 66 0a 20 20 29 3b 0a 20 20 zSelf. );.
fe80: 64 62 5f 65 6e 64 5f 74 72 61 6e 73 61 63 74 69 db_end_transacti
fe90: 6f 6e 28 30 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 on(0);. db_mult
fea0: 69 5f 65 78 65 63 28 22 44 45 54 41 43 48 20 6f i_exec("DETACH o
feb0: 74 68 65 72 22 29 3b 0a 0a 20 20 2f 2a 20 50 72 ther");.. /* Pr
fec0: 6f 70 61 67 61 74 65 20 74 68 65 20 63 68 61 6e opagate the chan
fed0: 67 65 73 20 74 6f 20 61 6c 6c 20 6f 74 68 65 72 ges to all other
fee0: 20 6d 65 6d 62 65 72 73 20 6f 66 20 74 68 65 20 members of the
fef0: 6c 6f 67 69 6e 2d 67 72 6f 75 70 20 2a 2f 0a 20 login-group */.
ff00: 20 7a 53 71 6c 20 3d 20 6d 70 72 69 6e 74 66 28 zSql = mprintf(
ff10: 0a 20 20 20 20 22 42 45 47 49 4e 3b 22 0a 20 20 . "BEGIN;".
ff20: 20 20 22 52 45 50 4c 41 43 45 20 49 4e 54 4f 20 "REPLACE INTO
ff30: 63 6f 6e 66 69 67 28 6e 61 6d 65 2c 76 61 6c 75 config(name,valu
ff40: 65 2c 6d 74 69 6d 65 29 20 56 41 4c 55 45 53 28 e,mtime) VALUES(
ff50: 27 70 65 65 72 2d 6e 61 6d 65 2d 25 71 27 2c 25 'peer-name-%q',%
ff60: 51 2c 6e 6f 77 28 29 29 3b 22 0a 20 20 20 20 22 Q,now());". "
ff70: 52 45 50 4c 41 43 45 20 49 4e 54 4f 20 63 6f 6e REPLACE INTO con
ff80: 66 69 67 28 6e 61 6d 65 2c 76 61 6c 75 65 2c 6d fig(name,value,m
ff90: 74 69 6d 65 29 20 56 41 4c 55 45 53 28 27 70 65 time) VALUES('pe
ffa0: 65 72 2d 72 65 70 6f 2d 25 71 27 2c 25 51 2c 6e er-repo-%q',%Q,n
ffb0: 6f 77 28 29 29 3b 22 0a 20 20 20 20 22 43 4f 4d ow());". "COM
ffc0: 4d 49 54 3b 22 2c 0a 20 20 20 20 7a 53 65 6c 66 MIT;",. zSelf
ffd0: 50 72 6f 6a 43 6f 64 65 2c 20 7a 53 65 6c 66 4c ProjCode, zSelfL
ffe0: 61 62 65 6c 2c 20 7a 53 65 6c 66 50 72 6f 6a 43 abel, zSelfProjC
fff0: 6f 64 65 2c 20 7a 53 65 6c 66 52 65 70 6f 0a 20 ode, zSelfRepo.
10000 20 29 3b 0a 20 20 6c 6f 67 69 6e 5f 67 72 6f 75 );. login_grou
10010 70 5f 73 71 6c 28 7a 53 71 6c 2c 20 22 3c 6c 69 p_sql(zSql, "<li
10020 3e 20 22 2c 20 22 3c 2f 6c 69 3e 22 2c 20 70 7a > ", "</li>", pz
10030 45 72 72 4d 73 67 29 3b 0a 20 20 66 6f 73 73 69 ErrMsg);. fossi
10040 6c 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 7d 0a l_free(zSql);.}.
10050 0a 2f 2a 0a 2a 2a 20 4c 65 61 76 65 20 74 68 65 ./*.** Leave the
10060 20 6c 6f 67 69 6e 20 67 72 6f 75 70 20 74 68 61 login group tha
10070 74 20 77 65 20 61 72 65 20 63 75 72 72 65 6e 74 t we are current
10080 6c 79 20 70 61 72 74 20 6f 66 2e 0a 2a 2f 0a 76 ly part of..*/.v
10090 6f 69 64 20 6c 6f 67 69 6e 5f 67 72 6f 75 70 5f oid login_group_
100a0 6c 65 61 76 65 28 63 68 61 72 20 2a 2a 70 7a 45 leave(char **pzE
100b0 72 72 4d 73 67 29 7b 0a 20 20 63 68 61 72 20 2a rrMsg){. char *
100c0 7a 50 72 6f 6a 43 6f 64 65 3b 0a 20 20 63 68 61 zProjCode;. cha
100d0 72 20 2a 7a 53 71 6c 3b 0a 0a 20 20 2a 70 7a 45 r *zSql;.. *pzE
100e0 72 72 4d 73 67 20 3d 20 30 3b 0a 20 20 7a 50 72 rrMsg = 0;. zPr
100f0 6f 6a 43 6f 64 65 20 3d 20 61 62 62 72 65 76 69 ojCode = abbrevi
10100 61 74 65 64 5f 70 72 6f 6a 65 63 74 5f 63 6f 64 ated_project_cod
10110 65 28 64 62 5f 67 65 74 28 22 70 72 6f 6a 65 63 e(db_get("projec
10120 74 2d 63 6f 64 65 22 2c 22 78 22 29 29 3b 0a 20 t-code","x"));.
10130 20 7a 53 71 6c 20 3d 20 6d 70 72 69 6e 74 66 28 zSql = mprintf(
10140 0a 20 20 20 20 22 44 45 4c 45 54 45 20 46 52 4f . "DELETE FRO
10150 4d 20 63 6f 6e 66 69 67 20 57 48 45 52 45 20 6e M config WHERE n
10160 61 6d 65 20 47 4c 4f 42 20 27 70 65 65 72 2d 2a ame GLOB 'peer-*
10170 2d 25 71 27 3b 22 0a 20 20 20 20 22 44 45 4c 45 -%q';". "DELE
10180 54 45 20 46 52 4f 4d 20 63 6f 6e 66 69 67 22 0a TE FROM config".
10190 20 20 20 20 22 20 57 48 45 52 45 20 6e 61 6d 65 " WHERE name
101a0 3d 27 6c 6f 67 69 6e 2d 67 72 6f 75 70 2d 6e 61 ='login-group-na
101b0 6d 65 27 22 0a 20 20 20 20 22 20 20 20 41 4e 44 me'". " AND
101c0 20 28 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a (SELECT count(*
101d0 29 20 46 52 4f 4d 20 63 6f 6e 66 69 67 20 57 48 ) FROM config WH
101e0 45 52 45 20 6e 61 6d 65 20 47 4c 4f 42 20 27 70 ERE name GLOB 'p
101f0 65 65 72 2d 2a 27 29 3d 3d 30 3b 22 2c 0a 20 20 eer-*')==0;",.
10200 20 20 7a 50 72 6f 6a 43 6f 64 65 0a 20 20 29 3b zProjCode. );
10210 0a 20 20 66 6f 73 73 69 6c 5f 66 72 65 65 28 7a . fossil_free(z
10220 50 72 6f 6a 43 6f 64 65 29 3b 0a 20 20 6c 6f 67 ProjCode);. log
10230 69 6e 5f 67 72 6f 75 70 5f 73 71 6c 28 7a 53 71 in_group_sql(zSq
10240 6c 2c 20 22 3c 6c 69 3e 20 22 2c 20 22 3c 2f 6c l, "<li> ", "</l
10250 69 3e 22 2c 20 70 7a 45 72 72 4d 73 67 29 3b 0a i>", pzErrMsg);.
10260 20 20 66 6f 73 73 69 6c 5f 66 72 65 65 28 7a 53 fossil_free(zS
10270 71 6c 29 3b 0a 20 20 64 62 5f 6d 75 6c 74 69 5f ql);. db_multi_
10280 65 78 65 63 28 0a 20 20 20 20 22 44 45 4c 45 54 exec(. "DELET
10290 45 20 46 52 4f 4d 20 63 6f 6e 66 69 67 20 22 0a E FROM config ".
102a0 20 20 20 20 22 20 57 48 45 52 45 20 6e 61 6d 65 " WHERE name
102b0 20 47 4c 4f 42 20 27 70 65 65 72 2d 2a 27 22 0a GLOB 'peer-*'".
102c0 20 20 20 20 22 20 20 20 20 4f 52 20 6e 61 6d 65 " OR name
102d0 20 47 4c 4f 42 20 27 6c 6f 67 69 6e 2d 67 72 6f GLOB 'login-gro
102e0 75 70 2d 2a 27 3b 22 0a 20 20 29 3b 0a 7d 0a up-*';". );.}.